]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
[media] move the dvb/frontends to drivers/media/dvb-frontends
authorMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:13:41 +0000 (23:13 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:13:41 +0000 (23:13 -0300)
Raise the DVB frontends one level up, as the intention is to remove
the drivers/media/dvb directory.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
510 files changed:
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/tuners/Makefile
drivers/media/dvb-frontends/Kconfig [new file with mode: 0644]
drivers/media/dvb-frontends/Makefile [new file with mode: 0644]
drivers/media/dvb-frontends/a8293.c [new file with mode: 0644]
drivers/media/dvb-frontends/a8293.h [new file with mode: 0644]
drivers/media/dvb-frontends/af9013.c [new file with mode: 0644]
drivers/media/dvb-frontends/af9013.h [new file with mode: 0644]
drivers/media/dvb-frontends/af9013_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/af9033.c [new file with mode: 0644]
drivers/media/dvb-frontends/af9033.h [new file with mode: 0644]
drivers/media/dvb-frontends/af9033_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/atbm8830.c [new file with mode: 0644]
drivers/media/dvb-frontends/atbm8830.h [new file with mode: 0644]
drivers/media/dvb-frontends/atbm8830_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/au8522.h [new file with mode: 0644]
drivers/media/dvb-frontends/au8522_common.c [new file with mode: 0644]
drivers/media/dvb-frontends/au8522_decoder.c [new file with mode: 0644]
drivers/media/dvb-frontends/au8522_dig.c [new file with mode: 0644]
drivers/media/dvb-frontends/au8522_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/bcm3510.c [new file with mode: 0644]
drivers/media/dvb-frontends/bcm3510.h [new file with mode: 0644]
drivers/media/dvb-frontends/bcm3510_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/bsbe1-d01a.h [new file with mode: 0644]
drivers/media/dvb-frontends/bsbe1.h [new file with mode: 0644]
drivers/media/dvb-frontends/bsru6.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx22700.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx22700.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx22702.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx22702.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx24110.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx24110.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx24113.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx24113.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx24116.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx24116.h [new file with mode: 0644]
drivers/media/dvb-frontends/cx24123.c [new file with mode: 0644]
drivers/media/dvb-frontends/cx24123.h [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r.h [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r_c.c [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r_core.c [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r_t.c [new file with mode: 0644]
drivers/media/dvb-frontends/cxd2820r_t2.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib0070.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib0070.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib0090.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib0090.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib3000.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib3000mb.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib3000mb_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib3000mc.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib3000mc.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib7000m.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib7000m.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib7000p.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib7000p.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib8000.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib8000.h [new file with mode: 0644]
drivers/media/dvb-frontends/dib9000.c [new file with mode: 0644]
drivers/media/dvb-frontends/dib9000.h [new file with mode: 0644]
drivers/media/dvb-frontends/dibx000_common.c [new file with mode: 0644]
drivers/media/dvb-frontends/dibx000_common.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxd.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxd_firm.c [new file with mode: 0644]
drivers/media/dvb-frontends/drxd_firm.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxd_hard.c [new file with mode: 0644]
drivers/media/dvb-frontends/drxd_map_firm.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxk.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxk_hard.c [new file with mode: 0644]
drivers/media/dvb-frontends/drxk_hard.h [new file with mode: 0644]
drivers/media/dvb-frontends/drxk_map.h [new file with mode: 0644]
drivers/media/dvb-frontends/ds3000.c [new file with mode: 0644]
drivers/media/dvb-frontends/ds3000.h [new file with mode: 0644]
drivers/media/dvb-frontends/dvb-pll.c [new file with mode: 0644]
drivers/media/dvb-frontends/dvb-pll.h [new file with mode: 0644]
drivers/media/dvb-frontends/dvb_dummy_fe.c [new file with mode: 0644]
drivers/media/dvb-frontends/dvb_dummy_fe.h [new file with mode: 0644]
drivers/media/dvb-frontends/ec100.c [new file with mode: 0644]
drivers/media/dvb-frontends/ec100.h [new file with mode: 0644]
drivers/media/dvb-frontends/ec100_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/eds1547.h [new file with mode: 0644]
drivers/media/dvb-frontends/hd29l2.c [new file with mode: 0644]
drivers/media/dvb-frontends/hd29l2.h [new file with mode: 0644]
drivers/media/dvb-frontends/hd29l2_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/isl6405.c [new file with mode: 0644]
drivers/media/dvb-frontends/isl6405.h [new file with mode: 0644]
drivers/media/dvb-frontends/isl6421.c [new file with mode: 0644]
drivers/media/dvb-frontends/isl6421.h [new file with mode: 0644]
drivers/media/dvb-frontends/isl6423.c [new file with mode: 0644]
drivers/media/dvb-frontends/isl6423.h [new file with mode: 0644]
drivers/media/dvb-frontends/it913x-fe-priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/it913x-fe.c [new file with mode: 0644]
drivers/media/dvb-frontends/it913x-fe.h [new file with mode: 0644]
drivers/media/dvb-frontends/itd1000.c [new file with mode: 0644]
drivers/media/dvb-frontends/itd1000.h [new file with mode: 0644]
drivers/media/dvb-frontends/itd1000_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/ix2505v.c [new file with mode: 0644]
drivers/media/dvb-frontends/ix2505v.h [new file with mode: 0644]
drivers/media/dvb-frontends/l64781.c [new file with mode: 0644]
drivers/media/dvb-frontends/l64781.h [new file with mode: 0644]
drivers/media/dvb-frontends/lg2160.c [new file with mode: 0644]
drivers/media/dvb-frontends/lg2160.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgdt3305.c [new file with mode: 0644]
drivers/media/dvb-frontends/lgdt3305.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgdt330x.c [new file with mode: 0644]
drivers/media/dvb-frontends/lgdt330x.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgdt330x_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgs8gl5.c [new file with mode: 0644]
drivers/media/dvb-frontends/lgs8gl5.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgs8gxx.c [new file with mode: 0644]
drivers/media/dvb-frontends/lgs8gxx.h [new file with mode: 0644]
drivers/media/dvb-frontends/lgs8gxx_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/lnbh24.h [new file with mode: 0644]
drivers/media/dvb-frontends/lnbp21.c [new file with mode: 0644]
drivers/media/dvb-frontends/lnbp21.h [new file with mode: 0644]
drivers/media/dvb-frontends/lnbp22.c [new file with mode: 0644]
drivers/media/dvb-frontends/lnbp22.h [new file with mode: 0644]
drivers/media/dvb-frontends/m88rs2000.c [new file with mode: 0644]
drivers/media/dvb-frontends/m88rs2000.h [new file with mode: 0644]
drivers/media/dvb-frontends/mb86a16.c [new file with mode: 0644]
drivers/media/dvb-frontends/mb86a16.h [new file with mode: 0644]
drivers/media/dvb-frontends/mb86a16_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/mb86a20s.c [new file with mode: 0644]
drivers/media/dvb-frontends/mb86a20s.h [new file with mode: 0644]
drivers/media/dvb-frontends/mt312.c [new file with mode: 0644]
drivers/media/dvb-frontends/mt312.h [new file with mode: 0644]
drivers/media/dvb-frontends/mt312_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/mt352.c [new file with mode: 0644]
drivers/media/dvb-frontends/mt352.h [new file with mode: 0644]
drivers/media/dvb-frontends/mt352_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/nxt200x.c [new file with mode: 0644]
drivers/media/dvb-frontends/nxt200x.h [new file with mode: 0644]
drivers/media/dvb-frontends/nxt6000.c [new file with mode: 0644]
drivers/media/dvb-frontends/nxt6000.h [new file with mode: 0644]
drivers/media/dvb-frontends/nxt6000_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/or51132.c [new file with mode: 0644]
drivers/media/dvb-frontends/or51132.h [new file with mode: 0644]
drivers/media/dvb-frontends/or51211.c [new file with mode: 0644]
drivers/media/dvb-frontends/or51211.h [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2830.c [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2830.h [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2830_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2832.c [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2832.h [new file with mode: 0644]
drivers/media/dvb-frontends/rtl2832_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1409.c [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1409.h [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1411.c [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1411.h [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1420.c [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1420.h [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1420_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1432.c [new file with mode: 0644]
drivers/media/dvb-frontends/s5h1432.h [new file with mode: 0644]
drivers/media/dvb-frontends/s921.c [new file with mode: 0644]
drivers/media/dvb-frontends/s921.h [new file with mode: 0644]
drivers/media/dvb-frontends/si21xx.c [new file with mode: 0644]
drivers/media/dvb-frontends/si21xx.h [new file with mode: 0644]
drivers/media/dvb-frontends/sp8870.c [new file with mode: 0644]
drivers/media/dvb-frontends/sp8870.h [new file with mode: 0644]
drivers/media/dvb-frontends/sp887x.c [new file with mode: 0644]
drivers/media/dvb-frontends/sp887x.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_algo.c [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_cfg.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_drv.c [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_drv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb0899_reg.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb6000.c [new file with mode: 0644]
drivers/media/dvb-frontends/stb6000.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb6100.c [new file with mode: 0644]
drivers/media/dvb-frontends/stb6100.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb6100_cfg.h [new file with mode: 0644]
drivers/media/dvb-frontends/stb6100_proc.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0288.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv0288.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0297.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv0297.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0299.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv0299.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0367.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv0367.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0367_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0367_regs.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900_core.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900_init.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900_reg.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv0900_sw.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv090x.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv090x.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv090x_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv090x_reg.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110x.c [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110x.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110x_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/stv6110x_reg.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda10021.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda10023.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda1002x.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda10048.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda10048.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda1004x.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda1004x.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda10071.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda10071.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda10071_priv.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda10086.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda10086.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda18271c2dd.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda18271c2dd.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda18271c2dd_maps.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda665x.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda665x.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda8083.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda8083.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda8261.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda8261.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda8261_cfg.h [new file with mode: 0644]
drivers/media/dvb-frontends/tda826x.c [new file with mode: 0644]
drivers/media/dvb-frontends/tda826x.h [new file with mode: 0644]
drivers/media/dvb-frontends/tdhd1.h [new file with mode: 0644]
drivers/media/dvb-frontends/tua6100.c [new file with mode: 0644]
drivers/media/dvb-frontends/tua6100.h [new file with mode: 0644]
drivers/media/dvb-frontends/ves1820.c [new file with mode: 0644]
drivers/media/dvb-frontends/ves1820.h [new file with mode: 0644]
drivers/media/dvb-frontends/ves1x93.c [new file with mode: 0644]
drivers/media/dvb-frontends/ves1x93.h [new file with mode: 0644]
drivers/media/dvb-frontends/z0194a.h [new file with mode: 0644]
drivers/media/dvb-frontends/zl10036.c [new file with mode: 0644]
drivers/media/dvb-frontends/zl10036.h [new file with mode: 0644]
drivers/media/dvb-frontends/zl10039.c [new file with mode: 0644]
drivers/media/dvb-frontends/zl10039.h [new file with mode: 0644]
drivers/media/dvb-frontends/zl10353.c [new file with mode: 0644]
drivers/media/dvb-frontends/zl10353.h [new file with mode: 0644]
drivers/media/dvb-frontends/zl10353_priv.h [new file with mode: 0644]
drivers/media/dvb/Kconfig
drivers/media/dvb/Makefile
drivers/media/dvb/b2c2/Makefile
drivers/media/dvb/bt8xx/Makefile
drivers/media/dvb/ddbridge/Makefile
drivers/media/dvb/dm1105/Makefile
drivers/media/dvb/dvb-usb-v2/Makefile
drivers/media/dvb/dvb-usb/Makefile
drivers/media/dvb/frontends/Kconfig [deleted file]
drivers/media/dvb/frontends/Makefile [deleted file]
drivers/media/dvb/frontends/a8293.c [deleted file]
drivers/media/dvb/frontends/a8293.h [deleted file]
drivers/media/dvb/frontends/af9013.c [deleted file]
drivers/media/dvb/frontends/af9013.h [deleted file]
drivers/media/dvb/frontends/af9013_priv.h [deleted file]
drivers/media/dvb/frontends/af9033.c [deleted file]
drivers/media/dvb/frontends/af9033.h [deleted file]
drivers/media/dvb/frontends/af9033_priv.h [deleted file]
drivers/media/dvb/frontends/atbm8830.c [deleted file]
drivers/media/dvb/frontends/atbm8830.h [deleted file]
drivers/media/dvb/frontends/atbm8830_priv.h [deleted file]
drivers/media/dvb/frontends/au8522.h [deleted file]
drivers/media/dvb/frontends/au8522_common.c [deleted file]
drivers/media/dvb/frontends/au8522_decoder.c [deleted file]
drivers/media/dvb/frontends/au8522_dig.c [deleted file]
drivers/media/dvb/frontends/au8522_priv.h [deleted file]
drivers/media/dvb/frontends/bcm3510.c [deleted file]
drivers/media/dvb/frontends/bcm3510.h [deleted file]
drivers/media/dvb/frontends/bcm3510_priv.h [deleted file]
drivers/media/dvb/frontends/bsbe1-d01a.h [deleted file]
drivers/media/dvb/frontends/bsbe1.h [deleted file]
drivers/media/dvb/frontends/bsru6.h [deleted file]
drivers/media/dvb/frontends/cx22700.c [deleted file]
drivers/media/dvb/frontends/cx22700.h [deleted file]
drivers/media/dvb/frontends/cx22702.c [deleted file]
drivers/media/dvb/frontends/cx22702.h [deleted file]
drivers/media/dvb/frontends/cx24110.c [deleted file]
drivers/media/dvb/frontends/cx24110.h [deleted file]
drivers/media/dvb/frontends/cx24113.c [deleted file]
drivers/media/dvb/frontends/cx24113.h [deleted file]
drivers/media/dvb/frontends/cx24116.c [deleted file]
drivers/media/dvb/frontends/cx24116.h [deleted file]
drivers/media/dvb/frontends/cx24123.c [deleted file]
drivers/media/dvb/frontends/cx24123.h [deleted file]
drivers/media/dvb/frontends/cxd2820r.h [deleted file]
drivers/media/dvb/frontends/cxd2820r_c.c [deleted file]
drivers/media/dvb/frontends/cxd2820r_core.c [deleted file]
drivers/media/dvb/frontends/cxd2820r_priv.h [deleted file]
drivers/media/dvb/frontends/cxd2820r_t.c [deleted file]
drivers/media/dvb/frontends/cxd2820r_t2.c [deleted file]
drivers/media/dvb/frontends/dib0070.c [deleted file]
drivers/media/dvb/frontends/dib0070.h [deleted file]
drivers/media/dvb/frontends/dib0090.c [deleted file]
drivers/media/dvb/frontends/dib0090.h [deleted file]
drivers/media/dvb/frontends/dib3000.h [deleted file]
drivers/media/dvb/frontends/dib3000mb.c [deleted file]
drivers/media/dvb/frontends/dib3000mb_priv.h [deleted file]
drivers/media/dvb/frontends/dib3000mc.c [deleted file]
drivers/media/dvb/frontends/dib3000mc.h [deleted file]
drivers/media/dvb/frontends/dib7000m.c [deleted file]
drivers/media/dvb/frontends/dib7000m.h [deleted file]
drivers/media/dvb/frontends/dib7000p.c [deleted file]
drivers/media/dvb/frontends/dib7000p.h [deleted file]
drivers/media/dvb/frontends/dib8000.c [deleted file]
drivers/media/dvb/frontends/dib8000.h [deleted file]
drivers/media/dvb/frontends/dib9000.c [deleted file]
drivers/media/dvb/frontends/dib9000.h [deleted file]
drivers/media/dvb/frontends/dibx000_common.c [deleted file]
drivers/media/dvb/frontends/dibx000_common.h [deleted file]
drivers/media/dvb/frontends/drxd.h [deleted file]
drivers/media/dvb/frontends/drxd_firm.c [deleted file]
drivers/media/dvb/frontends/drxd_firm.h [deleted file]
drivers/media/dvb/frontends/drxd_hard.c [deleted file]
drivers/media/dvb/frontends/drxd_map_firm.h [deleted file]
drivers/media/dvb/frontends/drxk.h [deleted file]
drivers/media/dvb/frontends/drxk_hard.c [deleted file]
drivers/media/dvb/frontends/drxk_hard.h [deleted file]
drivers/media/dvb/frontends/drxk_map.h [deleted file]
drivers/media/dvb/frontends/ds3000.c [deleted file]
drivers/media/dvb/frontends/ds3000.h [deleted file]
drivers/media/dvb/frontends/dvb-pll.c [deleted file]
drivers/media/dvb/frontends/dvb-pll.h [deleted file]
drivers/media/dvb/frontends/dvb_dummy_fe.c [deleted file]
drivers/media/dvb/frontends/dvb_dummy_fe.h [deleted file]
drivers/media/dvb/frontends/ec100.c [deleted file]
drivers/media/dvb/frontends/ec100.h [deleted file]
drivers/media/dvb/frontends/ec100_priv.h [deleted file]
drivers/media/dvb/frontends/eds1547.h [deleted file]
drivers/media/dvb/frontends/hd29l2.c [deleted file]
drivers/media/dvb/frontends/hd29l2.h [deleted file]
drivers/media/dvb/frontends/hd29l2_priv.h [deleted file]
drivers/media/dvb/frontends/isl6405.c [deleted file]
drivers/media/dvb/frontends/isl6405.h [deleted file]
drivers/media/dvb/frontends/isl6421.c [deleted file]
drivers/media/dvb/frontends/isl6421.h [deleted file]
drivers/media/dvb/frontends/isl6423.c [deleted file]
drivers/media/dvb/frontends/isl6423.h [deleted file]
drivers/media/dvb/frontends/it913x-fe-priv.h [deleted file]
drivers/media/dvb/frontends/it913x-fe.c [deleted file]
drivers/media/dvb/frontends/it913x-fe.h [deleted file]
drivers/media/dvb/frontends/itd1000.c [deleted file]
drivers/media/dvb/frontends/itd1000.h [deleted file]
drivers/media/dvb/frontends/itd1000_priv.h [deleted file]
drivers/media/dvb/frontends/ix2505v.c [deleted file]
drivers/media/dvb/frontends/ix2505v.h [deleted file]
drivers/media/dvb/frontends/l64781.c [deleted file]
drivers/media/dvb/frontends/l64781.h [deleted file]
drivers/media/dvb/frontends/lg2160.c [deleted file]
drivers/media/dvb/frontends/lg2160.h [deleted file]
drivers/media/dvb/frontends/lgdt3305.c [deleted file]
drivers/media/dvb/frontends/lgdt3305.h [deleted file]
drivers/media/dvb/frontends/lgdt330x.c [deleted file]
drivers/media/dvb/frontends/lgdt330x.h [deleted file]
drivers/media/dvb/frontends/lgdt330x_priv.h [deleted file]
drivers/media/dvb/frontends/lgs8gl5.c [deleted file]
drivers/media/dvb/frontends/lgs8gl5.h [deleted file]
drivers/media/dvb/frontends/lgs8gxx.c [deleted file]
drivers/media/dvb/frontends/lgs8gxx.h [deleted file]
drivers/media/dvb/frontends/lgs8gxx_priv.h [deleted file]
drivers/media/dvb/frontends/lnbh24.h [deleted file]
drivers/media/dvb/frontends/lnbp21.c [deleted file]
drivers/media/dvb/frontends/lnbp21.h [deleted file]
drivers/media/dvb/frontends/lnbp22.c [deleted file]
drivers/media/dvb/frontends/lnbp22.h [deleted file]
drivers/media/dvb/frontends/m88rs2000.c [deleted file]
drivers/media/dvb/frontends/m88rs2000.h [deleted file]
drivers/media/dvb/frontends/mb86a16.c [deleted file]
drivers/media/dvb/frontends/mb86a16.h [deleted file]
drivers/media/dvb/frontends/mb86a16_priv.h [deleted file]
drivers/media/dvb/frontends/mb86a20s.c [deleted file]
drivers/media/dvb/frontends/mb86a20s.h [deleted file]
drivers/media/dvb/frontends/mt312.c [deleted file]
drivers/media/dvb/frontends/mt312.h [deleted file]
drivers/media/dvb/frontends/mt312_priv.h [deleted file]
drivers/media/dvb/frontends/mt352.c [deleted file]
drivers/media/dvb/frontends/mt352.h [deleted file]
drivers/media/dvb/frontends/mt352_priv.h [deleted file]
drivers/media/dvb/frontends/nxt200x.c [deleted file]
drivers/media/dvb/frontends/nxt200x.h [deleted file]
drivers/media/dvb/frontends/nxt6000.c [deleted file]
drivers/media/dvb/frontends/nxt6000.h [deleted file]
drivers/media/dvb/frontends/nxt6000_priv.h [deleted file]
drivers/media/dvb/frontends/or51132.c [deleted file]
drivers/media/dvb/frontends/or51132.h [deleted file]
drivers/media/dvb/frontends/or51211.c [deleted file]
drivers/media/dvb/frontends/or51211.h [deleted file]
drivers/media/dvb/frontends/rtl2830.c [deleted file]
drivers/media/dvb/frontends/rtl2830.h [deleted file]
drivers/media/dvb/frontends/rtl2830_priv.h [deleted file]
drivers/media/dvb/frontends/rtl2832.c [deleted file]
drivers/media/dvb/frontends/rtl2832.h [deleted file]
drivers/media/dvb/frontends/rtl2832_priv.h [deleted file]
drivers/media/dvb/frontends/s5h1409.c [deleted file]
drivers/media/dvb/frontends/s5h1409.h [deleted file]
drivers/media/dvb/frontends/s5h1411.c [deleted file]
drivers/media/dvb/frontends/s5h1411.h [deleted file]
drivers/media/dvb/frontends/s5h1420.c [deleted file]
drivers/media/dvb/frontends/s5h1420.h [deleted file]
drivers/media/dvb/frontends/s5h1420_priv.h [deleted file]
drivers/media/dvb/frontends/s5h1432.c [deleted file]
drivers/media/dvb/frontends/s5h1432.h [deleted file]
drivers/media/dvb/frontends/s921.c [deleted file]
drivers/media/dvb/frontends/s921.h [deleted file]
drivers/media/dvb/frontends/si21xx.c [deleted file]
drivers/media/dvb/frontends/si21xx.h [deleted file]
drivers/media/dvb/frontends/sp8870.c [deleted file]
drivers/media/dvb/frontends/sp8870.h [deleted file]
drivers/media/dvb/frontends/sp887x.c [deleted file]
drivers/media/dvb/frontends/sp887x.h [deleted file]
drivers/media/dvb/frontends/stb0899_algo.c [deleted file]
drivers/media/dvb/frontends/stb0899_cfg.h [deleted file]
drivers/media/dvb/frontends/stb0899_drv.c [deleted file]
drivers/media/dvb/frontends/stb0899_drv.h [deleted file]
drivers/media/dvb/frontends/stb0899_priv.h [deleted file]
drivers/media/dvb/frontends/stb0899_reg.h [deleted file]
drivers/media/dvb/frontends/stb6000.c [deleted file]
drivers/media/dvb/frontends/stb6000.h [deleted file]
drivers/media/dvb/frontends/stb6100.c [deleted file]
drivers/media/dvb/frontends/stb6100.h [deleted file]
drivers/media/dvb/frontends/stb6100_cfg.h [deleted file]
drivers/media/dvb/frontends/stb6100_proc.h [deleted file]
drivers/media/dvb/frontends/stv0288.c [deleted file]
drivers/media/dvb/frontends/stv0288.h [deleted file]
drivers/media/dvb/frontends/stv0297.c [deleted file]
drivers/media/dvb/frontends/stv0297.h [deleted file]
drivers/media/dvb/frontends/stv0299.c [deleted file]
drivers/media/dvb/frontends/stv0299.h [deleted file]
drivers/media/dvb/frontends/stv0367.c [deleted file]
drivers/media/dvb/frontends/stv0367.h [deleted file]
drivers/media/dvb/frontends/stv0367_priv.h [deleted file]
drivers/media/dvb/frontends/stv0367_regs.h [deleted file]
drivers/media/dvb/frontends/stv0900.h [deleted file]
drivers/media/dvb/frontends/stv0900_core.c [deleted file]
drivers/media/dvb/frontends/stv0900_init.h [deleted file]
drivers/media/dvb/frontends/stv0900_priv.h [deleted file]
drivers/media/dvb/frontends/stv0900_reg.h [deleted file]
drivers/media/dvb/frontends/stv0900_sw.c [deleted file]
drivers/media/dvb/frontends/stv090x.c [deleted file]
drivers/media/dvb/frontends/stv090x.h [deleted file]
drivers/media/dvb/frontends/stv090x_priv.h [deleted file]
drivers/media/dvb/frontends/stv090x_reg.h [deleted file]
drivers/media/dvb/frontends/stv6110.c [deleted file]
drivers/media/dvb/frontends/stv6110.h [deleted file]
drivers/media/dvb/frontends/stv6110x.c [deleted file]
drivers/media/dvb/frontends/stv6110x.h [deleted file]
drivers/media/dvb/frontends/stv6110x_priv.h [deleted file]
drivers/media/dvb/frontends/stv6110x_reg.h [deleted file]
drivers/media/dvb/frontends/tda10021.c [deleted file]
drivers/media/dvb/frontends/tda10023.c [deleted file]
drivers/media/dvb/frontends/tda1002x.h [deleted file]
drivers/media/dvb/frontends/tda10048.c [deleted file]
drivers/media/dvb/frontends/tda10048.h [deleted file]
drivers/media/dvb/frontends/tda1004x.c [deleted file]
drivers/media/dvb/frontends/tda1004x.h [deleted file]
drivers/media/dvb/frontends/tda10071.c [deleted file]
drivers/media/dvb/frontends/tda10071.h [deleted file]
drivers/media/dvb/frontends/tda10071_priv.h [deleted file]
drivers/media/dvb/frontends/tda10086.c [deleted file]
drivers/media/dvb/frontends/tda10086.h [deleted file]
drivers/media/dvb/frontends/tda18271c2dd.c [deleted file]
drivers/media/dvb/frontends/tda18271c2dd.h [deleted file]
drivers/media/dvb/frontends/tda18271c2dd_maps.h [deleted file]
drivers/media/dvb/frontends/tda665x.c [deleted file]
drivers/media/dvb/frontends/tda665x.h [deleted file]
drivers/media/dvb/frontends/tda8083.c [deleted file]
drivers/media/dvb/frontends/tda8083.h [deleted file]
drivers/media/dvb/frontends/tda8261.c [deleted file]
drivers/media/dvb/frontends/tda8261.h [deleted file]
drivers/media/dvb/frontends/tda8261_cfg.h [deleted file]
drivers/media/dvb/frontends/tda826x.c [deleted file]
drivers/media/dvb/frontends/tda826x.h [deleted file]
drivers/media/dvb/frontends/tdhd1.h [deleted file]
drivers/media/dvb/frontends/tua6100.c [deleted file]
drivers/media/dvb/frontends/tua6100.h [deleted file]
drivers/media/dvb/frontends/ves1820.c [deleted file]
drivers/media/dvb/frontends/ves1820.h [deleted file]
drivers/media/dvb/frontends/ves1x93.c [deleted file]
drivers/media/dvb/frontends/ves1x93.h [deleted file]
drivers/media/dvb/frontends/z0194a.h [deleted file]
drivers/media/dvb/frontends/zl10036.c [deleted file]
drivers/media/dvb/frontends/zl10036.h [deleted file]
drivers/media/dvb/frontends/zl10039.c [deleted file]
drivers/media/dvb/frontends/zl10039.h [deleted file]
drivers/media/dvb/frontends/zl10353.c [deleted file]
drivers/media/dvb/frontends/zl10353.h [deleted file]
drivers/media/dvb/frontends/zl10353_priv.h [deleted file]
drivers/media/dvb/mantis/Makefile
drivers/media/dvb/ngene/Makefile
drivers/media/dvb/pluto2/Makefile
drivers/media/dvb/pt1/Makefile
drivers/media/dvb/ttpci/Makefile
drivers/media/dvb/ttusb-budget/Makefile
drivers/media/v4l2-core/Makefile
drivers/media/video/Makefile
drivers/media/video/au0828/Makefile
drivers/media/video/cx18/Makefile
drivers/media/video/cx231xx/Makefile
drivers/media/video/cx23885/Makefile
drivers/media/video/cx25821/Makefile
drivers/media/video/cx88/Makefile
drivers/media/video/em28xx/Makefile
drivers/media/video/ivtv/Makefile
drivers/media/video/pvrusb2/Makefile
drivers/media/video/saa7134/Makefile
drivers/media/video/saa7164/Makefile
drivers/media/video/tlg2300/Makefile
drivers/media/video/tm6000/Makefile
drivers/staging/media/cxd2099/Makefile
drivers/staging/media/go7007/Makefile

index bda568af986f56ac8ff4281404f4fbaa37616a7f..180fb1394c467f1e37738a714dd8e262fed64bf0 100644 (file)
@@ -164,4 +164,8 @@ source "drivers/media/radio/Kconfig"
 source "drivers/media/dvb-core/Kconfig"
 source "drivers/media/dvb/Kconfig"
 
+comment "Supported DVB Frontends"
+        depends on DVB_CORE
+source "drivers/media/dvb-frontends/Kconfig"
+
 endif # MEDIA_SUPPORT
index 7f9f99ab6ccc31e3e92259df11671f0a072578c1..f95b9e3204c1ba9bba0bf123e1967b8e3517e2ba 100644 (file)
@@ -11,4 +11,4 @@ endif
 obj-y += v4l2-core/ common/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB_CORE)  += dvb-core/ dvb/
+obj-$(CONFIG_DVB_CORE)  += dvb-core/ dvb/ dvb-frontends/
index 2ddbb2cf0e2ca25de42a2618493d4b3b1cf22a59..112aeee902025306bf564bbd26dc43c4497a018d 100644 (file)
@@ -34,4 +34,4 @@ obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
 obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
new file mode 100644 (file)
index 0000000..a08c215
--- /dev/null
@@ -0,0 +1,756 @@
+config DVB_FE_CUSTOMISE
+       bool "Customise the frontend modules to build"
+       depends on DVB_CORE
+       depends on EXPERT
+       default y if EXPERT
+       help
+         This allows the user to select/deselect frontend drivers for their
+         hardware from the build.
+
+         Use this option with care as deselecting frontends which are in fact
+         necessary will result in DVB devices which cannot be tuned due to lack
+         of driver support.
+
+         If unsure say N.
+
+menu "Customise DVB Frontends"
+       visible if DVB_FE_CUSTOMISE
+
+comment "Multistandard (satellite) frontends"
+       depends on DVB_CORE
+
+config DVB_STB0899
+       tristate "STB0899 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
+         to support this demodulator based frontends
+
+config DVB_STB6100
+       tristate "STB6100 based tuners"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A Silicon tuner from ST used in conjunction with the STB0899
+         demodulator. Say Y when you want to support this tuner.
+
+config DVB_STV090x
+       tristate "STV0900/STV0903(A/B) based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
+         Say Y when you want to support these frontends.
+
+config DVB_STV6110x
+       tristate "STV6110/(A) based tuners"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A Silicon tuner that supports DVB-S and DVB-S2 modes
+
+comment "Multistandard (cable + terrestrial) frontends"
+       depends on DVB_CORE
+
+config DVB_DRXK
+       tristate "Micronas DRXK based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Micronas DRX-K DVB-C/T demodulator.
+
+         Say Y when you want to support this frontend.
+
+config DVB_TDA18271C2DD
+       tristate "NXP TDA18271C2 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         NXP TDA18271 silicon tuner.
+
+         Say Y when you want to support this tuner.
+
+comment "DVB-S (satellite) frontends"
+       depends on DVB_CORE
+
+config DVB_CX24110
+       tristate "Conexant CX24110 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_CX24123
+       tristate "Conexant CX24123 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_MT312
+       tristate "Zarlink VP310/MT312/ZL10313 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_ZL10036
+       tristate "Zarlink ZL10036 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_ZL10039
+       tristate "Zarlink ZL10039 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_S5H1420
+       tristate "Samsung S5H1420 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_STV0288
+       tristate "ST STV0288 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_STB6000
+       tristate "ST STB6000 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+         help
+         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_STV0299
+       tristate "ST STV0299 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_STV6110
+       tristate "ST STV6110 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+         help
+         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_STV0900
+       tristate "ST STV0900 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
+
+config DVB_TDA8083
+       tristate "Philips TDA8083 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA10086
+       tristate "Philips TDA10086 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA8261
+       tristate "Philips TDA8261 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_VES1X93
+       tristate "VLSI VES1893 or VES1993 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_TUNER_ITD1000
+       tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_TUNER_CX24113
+       tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+
+config DVB_TDA826X
+       tristate "Philips TDA826X silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_TUA6100
+       tristate "Infineon TUA6100 PLL"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S PLL chip.
+
+config DVB_CX24116
+       tristate "Conexant CX24116 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
+
+config DVB_SI21XX
+       tristate "Silicon Labs SI21XX based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_DS3000
+       tristate "Montage Tehnology DS3000 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
+
+config DVB_MB86A16
+       tristate "Fujitsu MB86A16 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S/DSS Direct Conversion reveiver.
+         Say Y when you want to support this frontend.
+
+config DVB_TDA10071
+       tristate "NXP TDA10071"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+comment "DVB-T (terrestrial) frontends"
+       depends on DVB_CORE
+
+config DVB_SP8870
+       tristate "Spase sp8870 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+         This driver needs external firmware. Please use the command
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
+         download/extract it, and then copy it to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+config DVB_SP887X
+       tristate "Spase sp887x based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+         This driver needs external firmware. Please use the command
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
+         download/extract it, and then copy it to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+config DVB_CX22700
+       tristate "Conexant CX22700 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_CX22702
+       tristate "Conexant cx22702 demodulator (OFDM)"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_S5H1432
+       tristate "Samsung s5h1432 demodulator (OFDM)"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_DRXD
+       tristate "Micronas DRXD driver"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+         Note: this driver was based on vendor driver reference code (released
+         under the GPL) as opposed to the existing drx397xd driver, which
+         was written via reverse engineering.
+
+config DVB_L64781
+       tristate "LSI L64781"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA1004X
+       tristate "Philips TDA10045H/TDA10046H based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+         This driver needs external firmware. Please use the commands
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
+         download/extract them, and then copy them to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+config DVB_NXT6000
+       tristate "NxtWave Communications NXT6000 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_MT352
+       tristate "Zarlink MT352 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_ZL10353
+       tristate "Zarlink ZL10353 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_DIB3000MB
+       tristate "DiBcom 3000M-B"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+         to support this frontend.
+
+config DVB_DIB3000MC
+       tristate "DiBcom 3000P/M-C"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+         to support this frontend.
+
+config DVB_DIB7000M
+       tristate "DiBcom 7000MA/MB/PA/PB/MC"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+         to support this frontend.
+
+config DVB_DIB7000P
+       tristate "DiBcom 7000PC"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+         to support this frontend.
+
+config DVB_DIB9000
+       tristate "DiBcom 9000"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
+         to support this frontend.
+
+config DVB_TDA10048
+       tristate "Philips TDA10048HN based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
+config DVB_AF9013
+       tristate "Afatech AF9013 demodulator"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+config DVB_EC100
+       tristate "E3C EC100"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+config DVB_HD29L2
+       tristate "HDIC HD29L2"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+config DVB_STV0367
+       tristate "ST STV0367 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T/C tuner module. Say Y when you want to support this frontend.
+
+config DVB_CXD2820R
+       tristate "Sony CXD2820R"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+config DVB_RTL2830
+       tristate "Realtek RTL2830 DVB-T"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+config DVB_RTL2832
+       tristate "Realtek RTL2832 DVB-T"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y when you want to support this frontend.
+
+comment "DVB-C (cable) frontends"
+       depends on DVB_CORE
+
+config DVB_VES1820
+       tristate "VLSI VES1820 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-C tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA10021
+       tristate "Philips TDA10021 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-C tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA10023
+       tristate "Philips TDA10023 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-C tuner module. Say Y when you want to support this frontend.
+
+config DVB_STV0297
+       tristate "ST STV0297 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-C tuner module. Say Y when you want to support this frontend.
+
+comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
+       depends on DVB_CORE
+
+config DVB_NXT200X
+       tristate "NxtWave Communications NXT2002/NXT2004 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+         This driver needs external firmware. Please use the commands
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
+         download/extract them, and then copy them to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+config DVB_OR51211
+       tristate "Oren OR51211 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
+
+         This driver needs external firmware. Please use the command
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
+         download it, and then copy it to /usr/lib/hotplug/firmware
+         or /lib/firmware (depending on configuration of firmware hotplug).
+
+config DVB_OR51132
+       tristate "Oren OR51132 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+         This driver needs external firmware. Please use the commands
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
+         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
+         download firmwares for 8VSB and QAM64/256, respectively. Copy them to
+         /usr/lib/hotplug/firmware or /lib/firmware (depending on
+         configuration of firmware hotplug).
+
+config DVB_BCM3510
+       tristate "Broadcom BCM3510"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
+         support this frontend.
+
+config DVB_LGDT330X
+       tristate "LG Electronics LGDT3302/LGDT3303 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+config DVB_LGDT3305
+       tristate "LG Electronics LGDT3304 and LGDT3305 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+config DVB_LG2160
+       tristate "LG Electronics LG216x based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC/MH demodulator module. Say Y when you want
+         to support this frontend.
+
+config DVB_S5H1409
+       tristate "Samsung S5H1409 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+config DVB_AU8522
+       depends on I2C
+       tristate
+
+config DVB_AU8522_DTV
+       tristate "Auvitek AU8522 based DTV demod"
+       depends on DVB_CORE && I2C
+       select DVB_AU8522
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
+         you want to enable DTV demodulation support for this frontend.
+
+config DVB_AU8522_V4L
+       tristate "Auvitek AU8522 based ATV demod"
+       depends on VIDEO_V4L2 && I2C
+       select DVB_AU8522
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
+         you want to enable ATV demodulation support for this frontend.
+
+config DVB_S5H1411
+       tristate "Samsung S5H1411 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
+comment "ISDB-T (terrestrial) frontends"
+       depends on DVB_CORE
+
+config DVB_S921
+       tristate "Sharp S921 frontend"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
+         Say Y when you want to support this frontend.
+
+config DVB_DIB8000
+       tristate "DiBcom 8000MB/MC"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
+         Say Y when you want to support this frontend.
+
+config DVB_MB86A20S
+       tristate "Fujitsu mb86a20s"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
+         Say Y when you want to support this frontend.
+
+comment "Digital terrestrial only tuners/PLL"
+       depends on DVB_CORE
+
+config DVB_PLL
+       tristate "Generic I2C PLL based tuners"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         This module drives a number of tuners based on PLL chips with a
+         common I2C interface. Say Y when you want to support these tuners.
+
+config DVB_TUNER_DIB0070
+       tristate "DiBcom DiB0070 silicon base-band tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner DiB0070 from DiBcom.
+         This device is only used inside a SiP called together with a
+         demodulator for now.
+
+config DVB_TUNER_DIB0090
+       tristate "DiBcom DiB0090 silicon base-band tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner DiB0090 from DiBcom.
+         This device is only used inside a SiP called together with a
+         demodulator for now.
+
+comment "SEC control devices for DVB-S"
+       depends on DVB_CORE
+
+config DVB_LNBP21
+       tristate "LNBP21/LNBH24 SEC controllers"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An SEC control chips.
+
+config DVB_LNBP22
+       tristate "LNBP22 SEC controllers"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         LNB power supply and control voltage
+         regulator chip with step-up converter
+         and I2C interface.
+         Say Y when you want to support this chip.
+
+config DVB_ISL6405
+       tristate "ISL6405 SEC controller"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An SEC control chip.
+
+config DVB_ISL6421
+       tristate "ISL6421 SEC controller"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An SEC control chip.
+
+config DVB_ISL6423
+       tristate "ISL6423 SEC controller"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A SEC controller chip from Intersil
+
+config DVB_A8293
+       tristate "Allegro A8293"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+
+config DVB_LGS8GL5
+       tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DMB-TH tuner module. Say Y when you want to support this frontend.
+
+config DVB_LGS8GXX
+       tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
+       depends on DVB_CORE && I2C
+       select FW_LOADER
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DMB-TH tuner module. Say Y when you want to support this frontend.
+
+config DVB_ATBM8830
+       tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DMB-TH tuner module. Say Y when you want to support this frontend.
+
+config DVB_TDA665x
+       tristate "TDA665x tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Support for tuner modules based on Philips TDA6650/TDA6651 chips.
+         Say Y when you want to support this chip.
+
+         Currently supported tuners:
+         * Panasonic ENV57H12D5 (ET-50DT)
+
+config DVB_IX2505V
+       tristate "Sharp IX2505V silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_IT913X_FE
+       tristate "it913x frontend and it9137 tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-T tuner module.
+         Say Y when you want to support this frontend.
+
+config DVB_M88RS2000
+       tristate "M88RS2000 DVB-S demodulator and tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A DVB-S tuner module.
+         Say Y when you want to support this frontend.
+
+config DVB_AF9033
+       tristate "Afatech AF9033 DVB-T demodulator"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+
+comment "Tools to develop new frontends"
+
+config DVB_DUMMY_FE
+       tristate "Dummy frontend driver"
+       default n
+endmenu
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
new file mode 100644 (file)
index 0000000..a378c52
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Makefile for the kernel DVB frontend device drivers.
+#
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core/
+ccflags-y += -I$(srctree)/drivers/media/common/tuners/
+
+stb0899-objs = stb0899_drv.o stb0899_algo.o
+stv0900-objs = stv0900_core.o stv0900_sw.o
+drxd-objs = drxd_firm.o drxd_hard.o
+cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
+drxk-objs := drxk_hard.o
+
+obj-$(CONFIG_DVB_PLL) += dvb-pll.o
+obj-$(CONFIG_DVB_STV0299) += stv0299.o
+obj-$(CONFIG_DVB_STB0899) += stb0899.o
+obj-$(CONFIG_DVB_STB6100) += stb6100.o
+obj-$(CONFIG_DVB_SP8870) += sp8870.o
+obj-$(CONFIG_DVB_CX22700) += cx22700.o
+obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
+obj-$(CONFIG_DVB_CX24110) += cx24110.o
+obj-$(CONFIG_DVB_TDA8083) += tda8083.o
+obj-$(CONFIG_DVB_L64781) += l64781.o
+obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
+obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
+obj-$(CONFIG_DVB_MT312) += mt312.o
+obj-$(CONFIG_DVB_VES1820) += ves1820.o
+obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
+obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
+obj-$(CONFIG_DVB_SP887X) += sp887x.o
+obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
+obj-$(CONFIG_DVB_MT352) += mt352.o
+obj-$(CONFIG_DVB_ZL10036) += zl10036.o
+obj-$(CONFIG_DVB_ZL10039) += zl10039.o
+obj-$(CONFIG_DVB_ZL10353) += zl10353.o
+obj-$(CONFIG_DVB_CX22702) += cx22702.o
+obj-$(CONFIG_DVB_DRXD) += drxd.o
+obj-$(CONFIG_DVB_TDA10021) += tda10021.o
+obj-$(CONFIG_DVB_TDA10023) += tda10023.o
+obj-$(CONFIG_DVB_STV0297) += stv0297.o
+obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
+obj-$(CONFIG_DVB_OR51211) += or51211.o
+obj-$(CONFIG_DVB_OR51132) += or51132.o
+obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
+obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
+obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
+obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
+obj-$(CONFIG_DVB_LG2160) += lg2160.o
+obj-$(CONFIG_DVB_CX24123) += cx24123.o
+obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
+obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
+obj-$(CONFIG_DVB_ISL6405) += isl6405.o
+obj-$(CONFIG_DVB_ISL6421) += isl6421.o
+obj-$(CONFIG_DVB_TDA10086) += tda10086.o
+obj-$(CONFIG_DVB_TDA826X) += tda826x.o
+obj-$(CONFIG_DVB_TDA8261) += tda8261.o
+obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
+obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
+obj-$(CONFIG_DVB_TUA6100) += tua6100.o
+obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
+obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
+obj-$(CONFIG_DVB_AU8522) += au8522_common.o
+obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
+obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
+obj-$(CONFIG_DVB_TDA10048) += tda10048.o
+obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
+obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
+obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
+obj-$(CONFIG_DVB_TDA665x) += tda665x.o
+obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
+obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
+obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
+obj-$(CONFIG_DVB_AF9013) += af9013.o
+obj-$(CONFIG_DVB_CX24116) += cx24116.o
+obj-$(CONFIG_DVB_SI21XX) += si21xx.o
+obj-$(CONFIG_DVB_STV0288) += stv0288.o
+obj-$(CONFIG_DVB_STB6000) += stb6000.o
+obj-$(CONFIG_DVB_S921) += s921.o
+obj-$(CONFIG_DVB_STV6110) += stv6110.o
+obj-$(CONFIG_DVB_STV0900) += stv0900.o
+obj-$(CONFIG_DVB_STV090x) += stv090x.o
+obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
+obj-$(CONFIG_DVB_ISL6423) += isl6423.o
+obj-$(CONFIG_DVB_EC100) += ec100.o
+obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
+obj-$(CONFIG_DVB_DS3000) += ds3000.o
+obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
+obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
+obj-$(CONFIG_DVB_STV0367) += stv0367.o
+obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
+obj-$(CONFIG_DVB_DRXK) += drxk.o
+obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
+obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
+obj-$(CONFIG_DVB_A8293) += a8293.o
+obj-$(CONFIG_DVB_TDA10071) += tda10071.o
+obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
+obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
+obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
+obj-$(CONFIG_DVB_AF9033) += af9033.o
+
diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c
new file mode 100644 (file)
index 0000000..cff44a3
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Allegro A8293 SEC driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#include "dvb_frontend.h"
+#include "a8293.h"
+
+struct a8293_priv {
+       struct i2c_adapter *i2c;
+       const struct a8293_config *cfg;
+       u8 reg[2];
+};
+
+static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
+{
+       int ret;
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg->i2c_addr,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       if (rd)
+               msg[0].flags = I2C_M_RD;
+       else
+               msg[0].flags = 0;
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
+                               KBUILD_MODNAME, ret, rd);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
+{
+       return a8293_i2c(priv, val, len, 0);
+}
+
+static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
+{
+       return a8293_i2c(priv, val, len, 1);
+}
+
+static int a8293_set_voltage(struct dvb_frontend *fe,
+       fe_sec_voltage_t fe_sec_voltage)
+{
+       struct a8293_priv *priv = fe->sec_priv;
+       int ret;
+
+       dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
+                       fe_sec_voltage);
+
+       switch (fe_sec_voltage) {
+       case SEC_VOLTAGE_OFF:
+               /* ENB=0 */
+               priv->reg[0] = 0x10;
+               break;
+       case SEC_VOLTAGE_13:
+               /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
+               priv->reg[0] = 0x31;
+               break;
+       case SEC_VOLTAGE_18:
+               /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
+               priv->reg[0] = 0x38;
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       };
+
+       ret = a8293_wr(priv, &priv->reg[0], 1);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static void a8293_release_sec(struct dvb_frontend *fe)
+{
+       a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, const struct a8293_config *cfg)
+{
+       int ret;
+       struct a8293_priv *priv = NULL;
+       u8 buf[2];
+
+       /* allocate memory for the internal priv */
+       priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
+       if (priv == NULL) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       /* setup the priv */
+       priv->i2c = i2c;
+       priv->cfg = cfg;
+       fe->sec_priv = priv;
+
+       /* check if the SEC is there */
+       ret = a8293_rd(priv, buf, 2);
+       if (ret)
+               goto err;
+
+       /* ENB=0 */
+       priv->reg[0] = 0x10;
+       ret = a8293_wr(priv, &priv->reg[0], 1);
+       if (ret)
+               goto err;
+
+       /* TMODE=0, TGATE=1 */
+       priv->reg[1] = 0x82;
+       ret = a8293_wr(priv, &priv->reg[1], 1);
+       if (ret)
+               goto err;
+
+       fe->ops.release_sec = a8293_release_sec;
+
+       /* override frontend ops */
+       fe->ops.set_voltage = a8293_set_voltage;
+
+       dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
+                       KBUILD_MODNAME);
+
+       return fe;
+err:
+       dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(a8293_attach);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Allegro A8293 SEC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h
new file mode 100644 (file)
index 0000000..ed29e55
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Allegro A8293 SEC driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef A8293_H
+#define A8293_H
+
+struct a8293_config {
+       u8 i2c_addr;
+};
+
+#if defined(CONFIG_DVB_A8293) || \
+       (defined(CONFIG_DVB_A8293_MODULE) && defined(MODULE))
+extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, const struct a8293_config *cfg);
+#else
+static inline struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, const struct a8293_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* A8293_H */
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
new file mode 100644 (file)
index 0000000..5bc570d
--- /dev/null
@@ -0,0 +1,1524 @@
+/*
+ * Afatech AF9013 demodulator driver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "af9013_priv.h"
+
+int af9013_debug;
+module_param_named(debug, af9013_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+struct af9013_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct af9013_config config;
+
+       /* tuner/demod RF and IF AGC limits used for signal strength calc */
+       u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
+       u16 signal_strength;
+       u32 ber;
+       u32 ucblocks;
+       u16 snr;
+       u32 bandwidth_hz;
+       fe_status_t fe_status;
+       unsigned long set_frontend_jiffies;
+       unsigned long read_status_jiffies;
+       bool first_tune;
+       bool i2c_gate_state;
+       unsigned int statistics_step:3;
+       struct delayed_work statistics_work;
+};
+
+/* write multiple registers */
+static int af9013_wr_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
+       const u8 *val, int len)
+{
+       int ret;
+       u8 buf[3+len];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->config.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = (reg >> 8) & 0xff;
+       buf[1] = (reg >> 0) & 0xff;
+       buf[2] = mbox;
+       memcpy(&buf[3], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed=%d reg=%04x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple registers */
+static int af9013_rd_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
+       u8 *val, int len)
+{
+       int ret;
+       u8 buf[3];
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->config.i2c_addr,
+                       .flags = 0,
+                       .len = 3,
+                       .buf = buf,
+               }, {
+                       .addr = priv->config.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       buf[0] = (reg >> 8) & 0xff;
+       buf[1] = (reg >> 0) & 0xff;
+       buf[2] = mbox;
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               warn("i2c rd failed=%d reg=%04x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* write multiple registers */
+static int af9013_wr_regs(struct af9013_state *priv, u16 reg, const u8 *val,
+       int len)
+{
+       int ret, i;
+       u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(1 << 0);
+
+       if ((priv->config.ts_mode == AF9013_TS_USB) &&
+               ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) {
+               mbox |= ((len - 1) << 2);
+               ret = af9013_wr_regs_i2c(priv, mbox, reg, val, len);
+       } else {
+               for (i = 0; i < len; i++) {
+                       ret = af9013_wr_regs_i2c(priv, mbox, reg+i, val+i, 1);
+                       if (ret)
+                               goto err;
+               }
+       }
+
+err:
+       return 0;
+}
+
+/* read multiple registers */
+static int af9013_rd_regs(struct af9013_state *priv, u16 reg, u8 *val, int len)
+{
+       int ret, i;
+       u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(0 << 0);
+
+       if ((priv->config.ts_mode == AF9013_TS_USB) &&
+               ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) {
+               mbox |= ((len - 1) << 2);
+               ret = af9013_rd_regs_i2c(priv, mbox, reg, val, len);
+       } else {
+               for (i = 0; i < len; i++) {
+                       ret = af9013_rd_regs_i2c(priv, mbox, reg+i, val+i, 1);
+                       if (ret)
+                               goto err;
+               }
+       }
+
+err:
+       return 0;
+}
+
+/* write single register */
+static int af9013_wr_reg(struct af9013_state *priv, u16 reg, u8 val)
+{
+       return af9013_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int af9013_rd_reg(struct af9013_state *priv, u16 reg, u8 *val)
+{
+       return af9013_rd_regs(priv, reg, val, 1);
+}
+
+static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val,
+       u8 len)
+{
+       u8 mbox = (1 << 7)|(1 << 6)|((len - 1) << 2)|(1 << 1)|(1 << 0);
+       return af9013_wr_regs_i2c(state, mbox, reg, val, len);
+}
+
+static int af9013_wr_reg_bits(struct af9013_state *state, u16 reg, int pos,
+       int len, u8 val)
+{
+       int ret;
+       u8 tmp, mask;
+
+       /* no need for read if whole reg is written */
+       if (len != 8) {
+               ret = af9013_rd_reg(state, reg, &tmp);
+               if (ret)
+                       return ret;
+
+               mask = (0xff >> (8 - len)) << pos;
+               val <<= pos;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return af9013_wr_reg(state, reg, val);
+}
+
+static int af9013_rd_reg_bits(struct af9013_state *state, u16 reg, int pos,
+       int len, u8 *val)
+{
+       int ret;
+       u8 tmp;
+
+       ret = af9013_rd_reg(state, reg, &tmp);
+       if (ret)
+               return ret;
+
+       *val = (tmp >> pos);
+       *val &= (0xff >> (8 - len));
+
+       return 0;
+}
+
+static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
+{
+       int ret;
+       u8 pos;
+       u16 addr;
+
+       dbg("%s: gpio=%d gpioval=%02x", __func__, gpio, gpioval);
+
+       /*
+        * GPIO0 & GPIO1 0xd735
+        * GPIO2 & GPIO3 0xd736
+        */
+
+       switch (gpio) {
+       case 0:
+       case 1:
+               addr = 0xd735;
+               break;
+       case 2:
+       case 3:
+               addr = 0xd736;
+               break;
+
+       default:
+               err("invalid gpio:%d\n", gpio);
+               ret = -EINVAL;
+               goto err;
+       };
+
+       switch (gpio) {
+       case 0:
+       case 2:
+               pos = 0;
+               break;
+       case 1:
+       case 3:
+       default:
+               pos = 4;
+               break;
+       };
+
+       ret = af9013_wr_reg_bits(state, addr, pos, 4, gpioval);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static u32 af913_div(u32 a, u32 b, u32 x)
+{
+       u32 r = 0, c = 0, i;
+
+       dbg("%s: a=%d b=%d x=%d", __func__, a, b, x);
+
+       if (a > b) {
+               c = a / b;
+               a = a - c * b;
+       }
+
+       for (i = 0; i < x; i++) {
+               if (a >= b) {
+                       r += 1;
+                       a -= b;
+               }
+               a <<= 1;
+               r <<= 1;
+       }
+       r = (c << (u32)x) + r;
+
+       dbg("%s: a=%d b=%d x=%d r=%x", __func__, a, b, x, r);
+       return r;
+}
+
+static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
+{
+       int ret, i;
+       u8 tmp;
+
+       dbg("%s: onoff=%d", __func__, onoff);
+
+       /* enable reset */
+       ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 1);
+       if (ret)
+               goto err;
+
+       /* start reset mechanism */
+       ret = af9013_wr_reg(state, 0xaeff, 1);
+       if (ret)
+               goto err;
+
+       /* wait reset performs */
+       for (i = 0; i < 150; i++) {
+               ret = af9013_rd_reg_bits(state, 0xd417, 1, 1, &tmp);
+               if (ret)
+                       goto err;
+
+               if (tmp)
+                       break; /* reset done */
+
+               usleep_range(5000, 25000);
+       }
+
+       if (!tmp)
+               return -ETIMEDOUT;
+
+       if (onoff) {
+               /* clear reset */
+               ret = af9013_wr_reg_bits(state, 0xd417, 1, 1, 0);
+               if (ret)
+                       goto err;
+
+               /* disable reset */
+               ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 0);
+
+               /* power on */
+               ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 0);
+       } else {
+               /* power off */
+               ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 1);
+       }
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+
+       dbg("%s", __func__);
+
+       /* reset and start BER counter */
+       ret = af9013_wr_reg_bits(state, 0xd391, 4, 1, 1);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[5];
+
+       dbg("%s", __func__);
+
+       /* check if error bit count is ready */
+       ret = af9013_rd_reg_bits(state, 0xd391, 4, 1, &buf[0]);
+       if (ret)
+               goto err;
+
+       if (!buf[0]) {
+               dbg("%s: not ready", __func__);
+               return 0;
+       }
+
+       ret = af9013_rd_regs(state, 0xd387, buf, 5);
+       if (ret)
+               goto err;
+
+       state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0];
+       state->ucblocks += (buf[4] << 8) | buf[3];
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_statistics_snr_start(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+
+       dbg("%s", __func__);
+
+       /* start SNR meas */
+       ret = af9013_wr_reg_bits(state, 0xd2e1, 3, 1, 1);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_statistics_snr_result(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret, i, len;
+       u8 buf[3], tmp;
+       u32 snr_val;
+       const struct af9013_snr *uninitialized_var(snr_lut);
+
+       dbg("%s", __func__);
+
+       /* check if SNR ready */
+       ret = af9013_rd_reg_bits(state, 0xd2e1, 3, 1, &tmp);
+       if (ret)
+               goto err;
+
+       if (!tmp) {
+               dbg("%s: not ready", __func__);
+               return 0;
+       }
+
+       /* read value */
+       ret = af9013_rd_regs(state, 0xd2e3, buf, 3);
+       if (ret)
+               goto err;
+
+       snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
+
+       /* read current modulation */
+       ret = af9013_rd_reg(state, 0xd3c1, &tmp);
+       if (ret)
+               goto err;
+
+       switch ((tmp >> 6) & 3) {
+       case 0:
+               len = ARRAY_SIZE(qpsk_snr_lut);
+               snr_lut = qpsk_snr_lut;
+               break;
+       case 1:
+               len = ARRAY_SIZE(qam16_snr_lut);
+               snr_lut = qam16_snr_lut;
+               break;
+       case 2:
+               len = ARRAY_SIZE(qam64_snr_lut);
+               snr_lut = qam64_snr_lut;
+               break;
+       default:
+               goto err;
+               break;
+       }
+
+       for (i = 0; i < len; i++) {
+               tmp = snr_lut[i].snr;
+
+               if (snr_val < snr_lut[i].val)
+                       break;
+       }
+       state->snr = tmp * 10; /* dB/10 */
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_statistics_signal_strength(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret = 0;
+       u8 buf[2], rf_gain, if_gain;
+       int signal_strength;
+
+       dbg("%s", __func__);
+
+       if (!state->signal_strength_en)
+               return 0;
+
+       ret = af9013_rd_regs(state, 0xd07c, buf, 2);
+       if (ret)
+               goto err;
+
+       rf_gain = buf[0];
+       if_gain = buf[1];
+
+       signal_strength = (0xffff / \
+               (9 * (state->rf_50 + state->if_50) - \
+               11 * (state->rf_80 + state->if_80))) * \
+               (10 * (rf_gain + if_gain) - \
+               11 * (state->rf_80 + state->if_80));
+       if (signal_strength < 0)
+               signal_strength = 0;
+       else if (signal_strength > 0xffff)
+               signal_strength = 0xffff;
+
+       state->signal_strength = signal_strength;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static void af9013_statistics_work(struct work_struct *work)
+{
+       struct af9013_state *state = container_of(work,
+               struct af9013_state, statistics_work.work);
+       unsigned int next_msec;
+
+       /* update only signal strength when demod is not locked */
+       if (!(state->fe_status & FE_HAS_LOCK)) {
+               state->statistics_step = 0;
+               state->ber = 0;
+               state->snr = 0;
+       }
+
+       switch (state->statistics_step) {
+       default:
+               state->statistics_step = 0;
+       case 0:
+               af9013_statistics_signal_strength(&state->fe);
+               state->statistics_step++;
+               next_msec = 300;
+               break;
+       case 1:
+               af9013_statistics_snr_start(&state->fe);
+               state->statistics_step++;
+               next_msec = 200;
+               break;
+       case 2:
+               af9013_statistics_ber_unc_start(&state->fe);
+               state->statistics_step++;
+               next_msec = 1000;
+               break;
+       case 3:
+               af9013_statistics_snr_result(&state->fe);
+               state->statistics_step++;
+               next_msec = 400;
+               break;
+       case 4:
+               af9013_statistics_ber_unc_result(&state->fe);
+               state->statistics_step++;
+               next_msec = 100;
+               break;
+       }
+
+       schedule_delayed_work(&state->statistics_work,
+               msecs_to_jiffies(next_msec));
+}
+
+static int af9013_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 800;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+
+       return 0;
+}
+
+static int af9013_set_frontend(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i, sampling_freq;
+       bool auto_mode, spec_inv;
+       u8 buf[6];
+       u32 if_frequency, freq_cw;
+
+       dbg("%s: frequency=%d bandwidth_hz=%d", __func__,
+               c->frequency, c->bandwidth_hz);
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       /* program CFOE coefficients */
+       if (c->bandwidth_hz != state->bandwidth_hz) {
+               for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
+                       if (coeff_lut[i].clock == state->config.clock &&
+                               coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
+                               break;
+                       }
+               }
+
+               ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val,
+                       sizeof(coeff_lut[i].val));
+       }
+
+       /* program frequency control */
+       if (c->bandwidth_hz != state->bandwidth_hz || state->first_tune) {
+               /* get used IF frequency */
+               if (fe->ops.tuner_ops.get_if_frequency)
+                       fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+               else
+                       if_frequency = state->config.if_frequency;
+
+               sampling_freq = if_frequency;
+
+               while (sampling_freq > (state->config.clock / 2))
+                       sampling_freq -= state->config.clock;
+
+               if (sampling_freq < 0) {
+                       sampling_freq *= -1;
+                       spec_inv = state->config.spec_inv;
+               } else {
+                       spec_inv = !state->config.spec_inv;
+               }
+
+               freq_cw = af913_div(sampling_freq, state->config.clock, 23);
+
+               if (spec_inv)
+                       freq_cw = 0x800000 - freq_cw;
+
+               buf[0] = (freq_cw >>  0) & 0xff;
+               buf[1] = (freq_cw >>  8) & 0xff;
+               buf[2] = (freq_cw >> 16) & 0x7f;
+
+               freq_cw = 0x800000 - freq_cw;
+
+               buf[3] = (freq_cw >>  0) & 0xff;
+               buf[4] = (freq_cw >>  8) & 0xff;
+               buf[5] = (freq_cw >> 16) & 0x7f;
+
+               ret = af9013_wr_regs(state, 0xd140, buf, 3);
+               if (ret)
+                       goto err;
+
+               ret = af9013_wr_regs(state, 0x9be7, buf, 6);
+               if (ret)
+                       goto err;
+       }
+
+       /* clear TPS lock flag */
+       ret = af9013_wr_reg_bits(state, 0xd330, 3, 1, 1);
+       if (ret)
+               goto err;
+
+       /* clear MPEG2 lock flag */
+       ret = af9013_wr_reg_bits(state, 0xd507, 6, 1, 0);
+       if (ret)
+               goto err;
+
+       /* empty channel function */
+       ret = af9013_wr_reg_bits(state, 0x9bfe, 0, 1, 0);
+       if (ret)
+               goto err;
+
+       /* empty DVB-T channel function */
+       ret = af9013_wr_reg_bits(state, 0x9bc2, 0, 1, 0);
+       if (ret)
+               goto err;
+
+       /* transmission parameters */
+       auto_mode = false;
+       memset(buf, 0, 3);
+
+       switch (c->transmission_mode) {
+       case TRANSMISSION_MODE_AUTO:
+               auto_mode = 1;
+               break;
+       case TRANSMISSION_MODE_2K:
+               break;
+       case TRANSMISSION_MODE_8K:
+               buf[0] |= (1 << 0);
+               break;
+       default:
+               dbg("%s: invalid transmission_mode", __func__);
+               auto_mode = 1;
+       }
+
+       switch (c->guard_interval) {
+       case GUARD_INTERVAL_AUTO:
+               auto_mode = 1;
+               break;
+       case GUARD_INTERVAL_1_32:
+               break;
+       case GUARD_INTERVAL_1_16:
+               buf[0] |= (1 << 2);
+               break;
+       case GUARD_INTERVAL_1_8:
+               buf[0] |= (2 << 2);
+               break;
+       case GUARD_INTERVAL_1_4:
+               buf[0] |= (3 << 2);
+               break;
+       default:
+               dbg("%s: invalid guard_interval", __func__);
+               auto_mode = 1;
+       }
+
+       switch (c->hierarchy) {
+       case HIERARCHY_AUTO:
+               auto_mode = 1;
+               break;
+       case HIERARCHY_NONE:
+               break;
+       case HIERARCHY_1:
+               buf[0] |= (1 << 4);
+               break;
+       case HIERARCHY_2:
+               buf[0] |= (2 << 4);
+               break;
+       case HIERARCHY_4:
+               buf[0] |= (3 << 4);
+               break;
+       default:
+               dbg("%s: invalid hierarchy", __func__);
+               auto_mode = 1;
+       };
+
+       switch (c->modulation) {
+       case QAM_AUTO:
+               auto_mode = 1;
+               break;
+       case QPSK:
+               break;
+       case QAM_16:
+               buf[1] |= (1 << 6);
+               break;
+       case QAM_64:
+               buf[1] |= (2 << 6);
+               break;
+       default:
+               dbg("%s: invalid modulation", __func__);
+               auto_mode = 1;
+       }
+
+       /* Use HP. How and which case we can switch to LP? */
+       buf[1] |= (1 << 4);
+
+       switch (c->code_rate_HP) {
+       case FEC_AUTO:
+               auto_mode = 1;
+               break;
+       case FEC_1_2:
+               break;
+       case FEC_2_3:
+               buf[2] |= (1 << 0);
+               break;
+       case FEC_3_4:
+               buf[2] |= (2 << 0);
+               break;
+       case FEC_5_6:
+               buf[2] |= (3 << 0);
+               break;
+       case FEC_7_8:
+               buf[2] |= (4 << 0);
+               break;
+       default:
+               dbg("%s: invalid code_rate_HP", __func__);
+               auto_mode = 1;
+       }
+
+       switch (c->code_rate_LP) {
+       case FEC_AUTO:
+               auto_mode = 1;
+               break;
+       case FEC_1_2:
+               break;
+       case FEC_2_3:
+               buf[2] |= (1 << 3);
+               break;
+       case FEC_3_4:
+               buf[2] |= (2 << 3);
+               break;
+       case FEC_5_6:
+               buf[2] |= (3 << 3);
+               break;
+       case FEC_7_8:
+               buf[2] |= (4 << 3);
+               break;
+       case FEC_NONE:
+               break;
+       default:
+               dbg("%s: invalid code_rate_LP", __func__);
+               auto_mode = 1;
+       }
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               break;
+       case 7000000:
+               buf[1] |= (1 << 2);
+               break;
+       case 8000000:
+               buf[1] |= (2 << 2);
+               break;
+       default:
+               dbg("%s: invalid bandwidth_hz", __func__);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       ret = af9013_wr_regs(state, 0xd3c0, buf, 3);
+       if (ret)
+               goto err;
+
+       if (auto_mode) {
+               /* clear easy mode flag */
+               ret = af9013_wr_reg(state, 0xaefd, 0);
+               if (ret)
+                       goto err;
+
+               dbg("%s: auto params", __func__);
+       } else {
+               /* set easy mode flag */
+               ret = af9013_wr_reg(state, 0xaefd, 1);
+               if (ret)
+                       goto err;
+
+               ret = af9013_wr_reg(state, 0xaefe, 0);
+               if (ret)
+                       goto err;
+
+               dbg("%s: manual params", __func__);
+       }
+
+       /* tune */
+       ret = af9013_wr_reg(state, 0xffff, 0);
+       if (ret)
+               goto err;
+
+       state->bandwidth_hz = c->bandwidth_hz;
+       state->set_frontend_jiffies = jiffies;
+       state->first_tune = false;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[3];
+
+       dbg("%s", __func__);
+
+       ret = af9013_rd_regs(state, 0xd3c0, buf, 3);
+       if (ret)
+               goto err;
+
+       switch ((buf[1] >> 6) & 3) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       }
+
+       switch ((buf[0] >> 0) & 3) {
+       case 0:
+               c->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               c->transmission_mode = TRANSMISSION_MODE_8K;
+       }
+
+       switch ((buf[0] >> 2) & 3) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       switch ((buf[0] >> 4) & 7) {
+       case 0:
+               c->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               c->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               c->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               c->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+       switch ((buf[2] >> 0) & 7) {
+       case 0:
+               c->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_HP = FEC_7_8;
+               break;
+       }
+
+       switch ((buf[2] >> 3) & 7) {
+       case 0:
+               c->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       switch ((buf[1] >> 2) & 3) {
+       case 0:
+               c->bandwidth_hz = 6000000;
+               break;
+       case 1:
+               c->bandwidth_hz = 7000000;
+               break;
+       case 2:
+               c->bandwidth_hz = 8000000;
+               break;
+       }
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+
+       /*
+        * Return status from the cache if it is younger than 2000ms with the
+        * exception of last tune is done during 4000ms.
+        */
+       if (time_is_after_jiffies(
+               state->read_status_jiffies + msecs_to_jiffies(2000)) &&
+               time_is_before_jiffies(
+               state->set_frontend_jiffies + msecs_to_jiffies(4000))
+       ) {
+                       *status = state->fe_status;
+                       return 0;
+       } else {
+               *status = 0;
+       }
+
+       /* MPEG2 lock */
+       ret = af9013_rd_reg_bits(state, 0xd507, 6, 1, &tmp);
+       if (ret)
+               goto err;
+
+       if (tmp)
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+                       FE_HAS_SYNC | FE_HAS_LOCK;
+
+       if (!*status) {
+               /* TPS lock */
+               ret = af9013_rd_reg_bits(state, 0xd330, 3, 1, &tmp);
+               if (ret)
+                       goto err;
+
+               if (tmp)
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI;
+       }
+
+       state->fe_status = *status;
+       state->read_status_jiffies = jiffies;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       *snr = state->snr;
+       return 0;
+}
+
+static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       *strength = state->signal_strength;
+       return 0;
+}
+
+static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       *ber = state->ber;
+       return 0;
+}
+
+static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       *ucblocks = state->ucblocks;
+       return 0;
+}
+
+static int af9013_init(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret, i, len;
+       u8 buf[3], tmp;
+       u32 adc_cw;
+       const struct af9013_reg_bit *init;
+
+       dbg("%s", __func__);
+
+       /* power on */
+       ret = af9013_power_ctrl(state, 1);
+       if (ret)
+               goto err;
+
+       /* enable ADC */
+       ret = af9013_wr_reg(state, 0xd73a, 0xa4);
+       if (ret)
+               goto err;
+
+       /* write API version to firmware */
+       ret = af9013_wr_regs(state, 0x9bf2, state->config.api_version, 4);
+       if (ret)
+               goto err;
+
+       /* program ADC control */
+       switch (state->config.clock) {
+       case 28800000: /* 28.800 MHz */
+               tmp = 0;
+               break;
+       case 20480000: /* 20.480 MHz */
+               tmp = 1;
+               break;
+       case 28000000: /* 28.000 MHz */
+               tmp = 2;
+               break;
+       case 25000000: /* 25.000 MHz */
+               tmp = 3;
+               break;
+       default:
+               err("invalid clock");
+               return -EINVAL;
+       }
+
+       adc_cw = af913_div(state->config.clock, 1000000ul, 19);
+       buf[0] = (adc_cw >>  0) & 0xff;
+       buf[1] = (adc_cw >>  8) & 0xff;
+       buf[2] = (adc_cw >> 16) & 0xff;
+
+       ret = af9013_wr_regs(state, 0xd180, buf, 3);
+       if (ret)
+               goto err;
+
+       ret = af9013_wr_reg_bits(state, 0x9bd2, 0, 4, tmp);
+       if (ret)
+               goto err;
+
+       /* set I2C master clock */
+       ret = af9013_wr_reg(state, 0xd416, 0x14);
+       if (ret)
+               goto err;
+
+       /* set 16 embx */
+       ret = af9013_wr_reg_bits(state, 0xd700, 1, 1, 1);
+       if (ret)
+               goto err;
+
+       /* set no trigger */
+       ret = af9013_wr_reg_bits(state, 0xd700, 2, 1, 0);
+       if (ret)
+               goto err;
+
+       /* set read-update bit for constellation */
+       ret = af9013_wr_reg_bits(state, 0xd371, 1, 1, 1);
+       if (ret)
+               goto err;
+
+       /* settings for mp2if */
+       if (state->config.ts_mode == AF9013_TS_USB) {
+               /* AF9015 split PSB to 1.5k + 0.5k */
+               ret = af9013_wr_reg_bits(state, 0xd50b, 2, 1, 1);
+               if (ret)
+                       goto err;
+       } else {
+               /* AF9013 change the output bit to data7 */
+               ret = af9013_wr_reg_bits(state, 0xd500, 3, 1, 1);
+               if (ret)
+                       goto err;
+
+               /* AF9013 set mpeg to full speed */
+               ret = af9013_wr_reg_bits(state, 0xd502, 4, 1, 1);
+               if (ret)
+                       goto err;
+       }
+
+       ret = af9013_wr_reg_bits(state, 0xd520, 4, 1, 1);
+       if (ret)
+               goto err;
+
+       /* load OFSM settings */
+       dbg("%s: load ofsm settings", __func__);
+       len = ARRAY_SIZE(ofsm_init);
+       init = ofsm_init;
+       for (i = 0; i < len; i++) {
+               ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos,
+                       init[i].len, init[i].val);
+               if (ret)
+                       goto err;
+       }
+
+       /* load tuner specific settings */
+       dbg("%s: load tuner specific settings", __func__);
+       switch (state->config.tuner) {
+       case AF9013_TUNER_MXL5003D:
+               len = ARRAY_SIZE(tuner_init_mxl5003d);
+               init = tuner_init_mxl5003d;
+               break;
+       case AF9013_TUNER_MXL5005D:
+       case AF9013_TUNER_MXL5005R:
+       case AF9013_TUNER_MXL5007T:
+               len = ARRAY_SIZE(tuner_init_mxl5005);
+               init = tuner_init_mxl5005;
+               break;
+       case AF9013_TUNER_ENV77H11D5:
+               len = ARRAY_SIZE(tuner_init_env77h11d5);
+               init = tuner_init_env77h11d5;
+               break;
+       case AF9013_TUNER_MT2060:
+               len = ARRAY_SIZE(tuner_init_mt2060);
+               init = tuner_init_mt2060;
+               break;
+       case AF9013_TUNER_MC44S803:
+               len = ARRAY_SIZE(tuner_init_mc44s803);
+               init = tuner_init_mc44s803;
+               break;
+       case AF9013_TUNER_QT1010:
+       case AF9013_TUNER_QT1010A:
+               len = ARRAY_SIZE(tuner_init_qt1010);
+               init = tuner_init_qt1010;
+               break;
+       case AF9013_TUNER_MT2060_2:
+               len = ARRAY_SIZE(tuner_init_mt2060_2);
+               init = tuner_init_mt2060_2;
+               break;
+       case AF9013_TUNER_TDA18271:
+       case AF9013_TUNER_TDA18218:
+               len = ARRAY_SIZE(tuner_init_tda18271);
+               init = tuner_init_tda18271;
+               break;
+       case AF9013_TUNER_UNKNOWN:
+       default:
+               len = ARRAY_SIZE(tuner_init_unknown);
+               init = tuner_init_unknown;
+               break;
+       }
+
+       for (i = 0; i < len; i++) {
+               ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos,
+                       init[i].len, init[i].val);
+               if (ret)
+                       goto err;
+       }
+
+       /* TS mode */
+       ret = af9013_wr_reg_bits(state, 0xd500, 1, 2, state->config.ts_mode);
+       if (ret)
+               goto err;
+
+       /* enable lock led */
+       ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 1);
+       if (ret)
+               goto err;
+
+       /* check if we support signal strength */
+       if (!state->signal_strength_en) {
+               ret = af9013_rd_reg_bits(state, 0x9bee, 0, 1,
+                       &state->signal_strength_en);
+               if (ret)
+                       goto err;
+       }
+
+       /* read values needed for signal strength calculation */
+       if (state->signal_strength_en && !state->rf_50) {
+               ret = af9013_rd_reg(state, 0x9bbd, &state->rf_50);
+               if (ret)
+                       goto err;
+
+               ret = af9013_rd_reg(state, 0x9bd0, &state->rf_80);
+               if (ret)
+                       goto err;
+
+               ret = af9013_rd_reg(state, 0x9be2, &state->if_50);
+               if (ret)
+                       goto err;
+
+               ret = af9013_rd_reg(state, 0x9be4, &state->if_80);
+               if (ret)
+                       goto err;
+       }
+
+       /* SNR */
+       ret = af9013_wr_reg(state, 0xd2e2, 1);
+       if (ret)
+               goto err;
+
+       /* BER / UCB */
+       buf[0] = (10000 >> 0) & 0xff;
+       buf[1] = (10000 >> 8) & 0xff;
+       ret = af9013_wr_regs(state, 0xd385, buf, 2);
+       if (ret)
+               goto err;
+
+       /* enable FEC monitor */
+       ret = af9013_wr_reg_bits(state, 0xd392, 1, 1, 1);
+       if (ret)
+               goto err;
+
+       state->first_tune = true;
+       schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400));
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_sleep(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       int ret;
+
+       dbg("%s", __func__);
+
+       /* stop statistics polling */
+       cancel_delayed_work_sync(&state->statistics_work);
+
+       /* disable lock led */
+       ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 0);
+       if (ret)
+               goto err;
+
+       /* power off */
+       ret = af9013_power_ctrl(state, 0);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       int ret;
+       struct af9013_state *state = fe->demodulator_priv;
+
+       dbg("%s: enable=%d", __func__, enable);
+
+       /* gate already open or close */
+       if (state->i2c_gate_state == enable)
+               return 0;
+
+       if (state->config.ts_mode == AF9013_TS_USB)
+               ret = af9013_wr_reg_bits(state, 0xd417, 3, 1, enable);
+       else
+               ret = af9013_wr_reg_bits(state, 0xd607, 2, 1, enable);
+       if (ret)
+               goto err;
+
+       state->i2c_gate_state = enable;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static void af9013_release(struct dvb_frontend *fe)
+{
+       struct af9013_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops af9013_ops;
+
+static int af9013_download_firmware(struct af9013_state *state)
+{
+       int i, len, remaining, ret;
+       const struct firmware *fw;
+       u16 checksum = 0;
+       u8 val;
+       u8 fw_params[4];
+       u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
+
+       msleep(100);
+       /* check whether firmware is already running */
+       ret = af9013_rd_reg(state, 0x98be, &val);
+       if (ret)
+               goto err;
+       else
+               dbg("%s: firmware status=%02x", __func__, val);
+
+       if (val == 0x0c) /* fw is running, no need for download */
+               goto exit;
+
+       info("found a '%s' in cold state, will try to load a firmware",
+               af9013_ops.info.name);
+
+       /* request the firmware, this will block and timeout */
+       ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
+       if (ret) {
+               err("did not find the firmware file. (%s) "
+                       "Please see linux/Documentation/dvb/ for more details" \
+                       " on firmware-problems. (%d)",
+                       fw_file, ret);
+               goto err;
+       }
+
+       info("downloading firmware from file '%s'", fw_file);
+
+       /* calc checksum */
+       for (i = 0; i < fw->size; i++)
+               checksum += fw->data[i];
+
+       fw_params[0] = checksum >> 8;
+       fw_params[1] = checksum & 0xff;
+       fw_params[2] = fw->size >> 8;
+       fw_params[3] = fw->size & 0xff;
+
+       /* write fw checksum & size */
+       ret = af9013_write_ofsm_regs(state, 0x50fc,
+               fw_params, sizeof(fw_params));
+       if (ret)
+               goto err_release;
+
+       #define FW_ADDR 0x5100 /* firmware start address */
+       #define LEN_MAX 16 /* max packet size */
+       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+               len = remaining;
+               if (len > LEN_MAX)
+                       len = LEN_MAX;
+
+               ret = af9013_write_ofsm_regs(state,
+                       FW_ADDR + fw->size - remaining,
+                       (u8 *) &fw->data[fw->size - remaining], len);
+               if (ret) {
+                       err("firmware download failed:%d", ret);
+                       goto err_release;
+               }
+       }
+
+       /* request boot firmware */
+       ret = af9013_wr_reg(state, 0xe205, 1);
+       if (ret)
+               goto err_release;
+
+       for (i = 0; i < 15; i++) {
+               msleep(100);
+
+               /* check firmware status */
+               ret = af9013_rd_reg(state, 0x98be, &val);
+               if (ret)
+                       goto err_release;
+
+               dbg("%s: firmware status=%02x", __func__, val);
+
+               if (val == 0x0c || val == 0x04) /* success or fail */
+                       break;
+       }
+
+       if (val == 0x04) {
+               err("firmware did not run");
+               ret = -ENODEV;
+       } else if (val != 0x0c) {
+               err("firmware boot timeout");
+               ret = -ENODEV;
+       }
+
+err_release:
+       release_firmware(fw);
+err:
+exit:
+       if (!ret)
+               info("found a '%s' in warm state.", af9013_ops.info.name);
+       return ret;
+}
+
+struct dvb_frontend *af9013_attach(const struct af9013_config *config,
+       struct i2c_adapter *i2c)
+{
+       int ret;
+       struct af9013_state *state = NULL;
+       u8 buf[4], i;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);
+       if (state == NULL)
+               goto err;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config, config, sizeof(struct af9013_config));
+
+       /* download firmware */
+       if (state->config.ts_mode != AF9013_TS_USB) {
+               ret = af9013_download_firmware(state);
+               if (ret)
+                       goto err;
+       }
+
+       /* firmware version */
+       ret = af9013_rd_regs(state, 0x5103, buf, 4);
+       if (ret)
+               goto err;
+
+       info("firmware version %d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
+
+       /* set GPIOs */
+       for (i = 0; i < sizeof(state->config.gpio); i++) {
+               ret = af9013_set_gpio(state, i, state->config.gpio[i]);
+               if (ret)
+                       goto err;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->fe.ops, &af9013_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->fe.demodulator_priv = state;
+
+       INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work);
+
+       return &state->fe;
+err:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(af9013_attach);
+
+static struct dvb_frontend_ops af9013_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Afatech AF9013",
+               .frequency_min = 174000000,
+               .frequency_max = 862000000,
+               .frequency_stepsize = 250000,
+               .frequency_tolerance = 0,
+               .caps = FE_CAN_FEC_1_2 |
+                       FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = af9013_release,
+
+       .init = af9013_init,
+       .sleep = af9013_sleep,
+
+       .get_tune_settings = af9013_get_tune_settings,
+       .set_frontend = af9013_set_frontend,
+       .get_frontend = af9013_get_frontend,
+
+       .read_status = af9013_read_status,
+       .read_snr = af9013_read_snr,
+       .read_signal_strength = af9013_read_signal_strength,
+       .read_ber = af9013_read_ber,
+       .read_ucblocks = af9013_read_ucblocks,
+
+       .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h
new file mode 100644 (file)
index 0000000..b973fc5
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Afatech AF9013 demodulator driver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef AF9013_H
+#define AF9013_H
+
+#include <linux/dvb/frontend.h>
+
+/* AF9013/5 GPIOs (mostly guessed)
+   demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
+   demod#1-gpio#1 - xtal setting (?)
+   demod#1-gpio#3 - tuner#1
+   demod#2-gpio#0 - tuner#2
+   demod#2-gpio#1 - xtal setting (?)
+*/
+
+struct af9013_config {
+       /*
+        * I2C address
+        */
+       u8 i2c_addr;
+
+       /*
+        * clock
+        * 20480000, 25000000, 28000000, 28800000
+        */
+       u32 clock;
+
+       /*
+        * tuner
+        */
+#define AF9013_TUNER_MXL5003D      3 /* MaxLinear */
+#define AF9013_TUNER_MXL5005D     13 /* MaxLinear */
+#define AF9013_TUNER_MXL5005R     30 /* MaxLinear */
+#define AF9013_TUNER_ENV77H11D5  129 /* Panasonic */
+#define AF9013_TUNER_MT2060      130 /* Microtune */
+#define AF9013_TUNER_MC44S803    133 /* Freescale */
+#define AF9013_TUNER_QT1010      134 /* Quantek */
+#define AF9013_TUNER_UNKNOWN     140 /* for can tuners ? */
+#define AF9013_TUNER_MT2060_2    147 /* Microtune */
+#define AF9013_TUNER_TDA18271    156 /* NXP */
+#define AF9013_TUNER_QT1010A     162 /* Quantek */
+#define AF9013_TUNER_MXL5007T    177 /* MaxLinear */
+#define AF9013_TUNER_TDA18218    179 /* NXP */
+       u8 tuner;
+
+       /*
+        * IF frequency
+        */
+       u32 if_frequency;
+
+       /*
+        * TS settings
+        */
+#define AF9013_TS_USB       0
+#define AF9013_TS_PARALLEL  1
+#define AF9013_TS_SERIAL    2
+       u8 ts_mode:2;
+
+       /*
+        * input spectrum inversion
+        */
+       bool spec_inv;
+
+       /*
+        * firmware API version
+        */
+       u8 api_version[4];
+
+       /*
+        * GPIOs
+        */
+#define AF9013_GPIO_ON (1 << 0)
+#define AF9013_GPIO_EN (1 << 1)
+#define AF9013_GPIO_O  (1 << 2)
+#define AF9013_GPIO_I  (1 << 3)
+#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN)
+#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
+#define AF9013_GPIO_TUNER_ON  (AF9013_GPIO_ON|AF9013_GPIO_EN)
+#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
+       u8 gpio[4];
+};
+
+#if defined(CONFIG_DVB_AF9013) || \
+       (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
+extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *af9013_attach(
+const struct af9013_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_AF9013 */
+
+#endif /* AF9013_H */
diff --git a/drivers/media/dvb-frontends/af9013_priv.h b/drivers/media/dvb-frontends/af9013_priv.h
new file mode 100644 (file)
index 0000000..fa848af
--- /dev/null
@@ -0,0 +1,922 @@
+/*
+ * Afatech AF9013 demodulator driver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef AF9013_PRIV_H
+#define AF9013_PRIV_H
+
+#include "dvb_frontend.h"
+#include "af9013.h"
+#include <linux/firmware.h>
+
+#define LOG_PREFIX "af9013"
+
+#undef dbg
+#define dbg(f, arg...) \
+       if (af9013_debug) \
+               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#define AF9013_DEFAULT_FIRMWARE     "dvb-fe-af9013.fw"
+
+struct af9013_reg_bit {
+       u16 addr;
+       u8  pos:4;
+       u8  len:4;
+       u8  val;
+};
+
+struct af9013_snr {
+       u32 val;
+       u8 snr;
+};
+
+struct af9013_coeff {
+       u32 clock;
+       u32 bandwidth_hz;
+       u8 val[24];
+};
+
+/* pre-calculated coeff lookup table */
+static const struct af9013_coeff coeff_lut[] = {
+       /* 28.800 MHz */
+       { 28800000, 8000000, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14,
+               0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a,
+               0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } },
+       { 28800000, 7000000, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71,
+               0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38,
+               0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } },
+       { 28800000, 6000000, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf,
+               0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7,
+               0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } },
+       /* 20.480 MHz */
+       { 20480000, 8000000, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24,
+               0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92,
+               0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } },
+       { 20480000, 7000000, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40,
+               0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00,
+               0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } },
+       { 20480000, 6000000, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b,
+               0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d,
+               0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } },
+       /* 28.000 MHz */
+       { 28000000, 8000000, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39,
+               0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f,
+               0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } },
+       { 28000000, 7000000, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92,
+               0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49,
+               0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } },
+       { 28000000, 6000000, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb,
+               0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63,
+               0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } },
+       /* 25.000 MHz */
+       { 25000000, 8000000, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9,
+               0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e,
+               0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } },
+       { 25000000, 7000000, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e,
+               0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7,
+               0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } },
+       { 25000000, 6000000, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63,
+               0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f,
+               0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } },
+};
+
+/* QPSK SNR lookup table */
+static const struct af9013_snr qpsk_snr_lut[] = {
+       { 0x000000,  0 },
+       { 0x0b4771,  0 },
+       { 0x0c1aed,  1 },
+       { 0x0d0d27,  2 },
+       { 0x0e4d19,  3 },
+       { 0x0e5da8,  4 },
+       { 0x107097,  5 },
+       { 0x116975,  6 },
+       { 0x1252d9,  7 },
+       { 0x131fa4,  8 },
+       { 0x13d5e1,  9 },
+       { 0x148e53, 10 },
+       { 0x15358b, 11 },
+       { 0x15dd29, 12 },
+       { 0x168112, 13 },
+       { 0x170b61, 14 },
+       { 0xffffff, 15 },
+};
+
+/* QAM16 SNR lookup table */
+static const struct af9013_snr qam16_snr_lut[] = {
+       { 0x000000,  0 },
+       { 0x05eb62,  5 },
+       { 0x05fecf,  6 },
+       { 0x060b80,  7 },
+       { 0x062501,  8 },
+       { 0x064865,  9 },
+       { 0x069604, 10 },
+       { 0x06f356, 11 },
+       { 0x07706a, 12 },
+       { 0x0804d3, 13 },
+       { 0x089d1a, 14 },
+       { 0x093e3d, 15 },
+       { 0x09e35d, 16 },
+       { 0x0a7c3c, 17 },
+       { 0x0afaf8, 18 },
+       { 0x0b719d, 19 },
+       { 0xffffff, 20 },
+};
+
+/* QAM64 SNR lookup table */
+static const struct af9013_snr qam64_snr_lut[] = {
+       { 0x000000,  0 },
+       { 0x03109b, 12 },
+       { 0x0310d4, 13 },
+       { 0x031920, 14 },
+       { 0x0322d0, 15 },
+       { 0x0339fc, 16 },
+       { 0x0364a1, 17 },
+       { 0x038bcc, 18 },
+       { 0x03c7d3, 19 },
+       { 0x0408cc, 20 },
+       { 0x043bed, 21 },
+       { 0x048061, 22 },
+       { 0x04be95, 23 },
+       { 0x04fa7d, 24 },
+       { 0x052405, 25 },
+       { 0x05570d, 26 },
+       { 0xffffff, 27 },
+};
+
+static const struct af9013_reg_bit ofsm_init[] = {
+       { 0xd73a, 0, 8, 0xa1 },
+       { 0xd73b, 0, 8, 0x1f },
+       { 0xd73c, 4, 4, 0x0a },
+       { 0xd732, 3, 1, 0x00 },
+       { 0xd731, 4, 2, 0x03 },
+       { 0xd73d, 7, 1, 0x01 },
+       { 0xd740, 0, 1, 0x00 },
+       { 0xd740, 1, 1, 0x00 },
+       { 0xd740, 2, 1, 0x00 },
+       { 0xd740, 3, 1, 0x01 },
+       { 0xd3c1, 4, 1, 0x01 },
+       { 0x9124, 0, 8, 0x58 },
+       { 0x9125, 0, 2, 0x02 },
+       { 0xd3a2, 0, 8, 0x00 },
+       { 0xd3a3, 0, 8, 0x04 },
+       { 0xd305, 0, 8, 0x32 },
+       { 0xd306, 0, 8, 0x10 },
+       { 0xd304, 0, 8, 0x04 },
+       { 0x9112, 0, 1, 0x01 },
+       { 0x911d, 0, 1, 0x01 },
+       { 0x911a, 0, 1, 0x01 },
+       { 0x911b, 0, 1, 0x01 },
+       { 0x9bce, 0, 4, 0x02 },
+       { 0x9116, 0, 1, 0x01 },
+       { 0x9122, 0, 8, 0xd0 },
+       { 0xd2e0, 0, 8, 0xd0 },
+       { 0xd2e9, 0, 4, 0x0d },
+       { 0xd38c, 0, 8, 0xfc },
+       { 0xd38d, 0, 8, 0x00 },
+       { 0xd38e, 0, 8, 0x7e },
+       { 0xd38f, 0, 8, 0x00 },
+       { 0xd390, 0, 8, 0x2f },
+       { 0xd145, 4, 1, 0x01 },
+       { 0xd1a9, 4, 1, 0x01 },
+       { 0xd158, 5, 3, 0x01 },
+       { 0xd159, 0, 6, 0x06 },
+       { 0xd167, 0, 8, 0x00 },
+       { 0xd168, 0, 4, 0x07 },
+       { 0xd1c3, 5, 3, 0x00 },
+       { 0xd1c4, 0, 6, 0x00 },
+       { 0xd1c5, 0, 7, 0x10 },
+       { 0xd1c6, 0, 3, 0x02 },
+       { 0xd080, 2, 5, 0x03 },
+       { 0xd081, 4, 4, 0x09 },
+       { 0xd098, 4, 4, 0x0f },
+       { 0xd098, 0, 4, 0x03 },
+       { 0xdbc0, 4, 1, 0x01 },
+       { 0xdbc7, 0, 8, 0x08 },
+       { 0xdbc8, 4, 4, 0x00 },
+       { 0xdbc9, 0, 5, 0x01 },
+       { 0xd280, 0, 8, 0xe0 },
+       { 0xd281, 0, 8, 0xff },
+       { 0xd282, 0, 8, 0xff },
+       { 0xd283, 0, 8, 0xc3 },
+       { 0xd284, 0, 8, 0xff },
+       { 0xd285, 0, 4, 0x01 },
+       { 0xd0f0, 0, 7, 0x1a },
+       { 0xd0f1, 4, 1, 0x01 },
+       { 0xd0f2, 0, 8, 0x0c },
+       { 0xd101, 5, 3, 0x06 },
+       { 0xd103, 0, 4, 0x08 },
+       { 0xd0f8, 0, 7, 0x20 },
+       { 0xd111, 5, 1, 0x00 },
+       { 0xd111, 6, 1, 0x00 },
+       { 0x910b, 0, 8, 0x0a },
+       { 0x9115, 0, 8, 0x02 },
+       { 0x910c, 0, 8, 0x02 },
+       { 0x910d, 0, 8, 0x08 },
+       { 0x910e, 0, 8, 0x0a },
+       { 0x9bf6, 0, 8, 0x06 },
+       { 0x9bf8, 0, 8, 0x02 },
+       { 0x9bf7, 0, 8, 0x05 },
+       { 0x9bf9, 0, 8, 0x0f },
+       { 0x9bfc, 0, 8, 0x13 },
+       { 0x9bd3, 0, 8, 0xff },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+};
+
+/* Panasonic ENV77H11D5 tuner init
+   AF9013_TUNER_ENV77H11D5 = 129 */
+static const struct af9013_reg_bit tuner_init_env77h11d5[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x03 },
+       { 0x9bbe, 0, 8, 0x01 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x00 },
+       { 0x9be3, 0, 8, 0x00 },
+       { 0xd015, 0, 8, 0x50 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0xdf },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x44 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0xeb },
+       { 0xd00d, 0, 2, 0x02 },
+       { 0xd00a, 0, 8, 0xf4 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bba, 0, 8, 0xf9 },
+       { 0x9bc3, 0, 8, 0xdf },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0xeb },
+       { 0x9bc6, 0, 8, 0x02 },
+       { 0x9bc9, 0, 8, 0x52 },
+       { 0xd011, 0, 8, 0x3c },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0xf7 },
+       { 0xd014, 0, 2, 0x02 },
+       { 0xd040, 0, 8, 0x0b },
+       { 0xd041, 0, 2, 0x02 },
+       { 0xd042, 0, 8, 0x4d },
+       { 0xd043, 0, 2, 0x00 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+};
+
+/* Microtune MT2060 tuner init
+   AF9013_TUNER_MT2060     = 130 */
+static const struct af9013_reg_bit tuner_init_mt2060[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x07 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x00 },
+       { 0x9be3, 0, 8, 0x00 },
+       { 0x9bbe, 0, 1, 0x00 },
+       { 0x9bcc, 0, 1, 0x00 },
+       { 0x9bb9, 0, 8, 0x75 },
+       { 0x9bcd, 0, 8, 0x24 },
+       { 0x9bff, 0, 8, 0x30 },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0x0f },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x32 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0x36 },
+       { 0xd00d, 0, 2, 0x03 },
+       { 0xd00a, 0, 8, 0x35 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x07 },
+       { 0x9bc8, 0, 8, 0x90 },
+       { 0x9bc3, 0, 8, 0x0f },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x36 },
+       { 0x9bc6, 0, 8, 0x03 },
+       { 0x9bba, 0, 8, 0xc9 },
+       { 0x9bc9, 0, 8, 0x79 },
+       { 0xd011, 0, 8, 0x10 },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0x45 },
+       { 0xd014, 0, 2, 0x03 },
+       { 0xd040, 0, 8, 0x98 },
+       { 0xd041, 0, 2, 0x00 },
+       { 0xd042, 0, 8, 0xcf },
+       { 0xd043, 0, 2, 0x03 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+       { 0x9bd0, 0, 8, 0xcc },
+       { 0x9be4, 0, 8, 0xa0 },
+       { 0x9bbd, 0, 8, 0x8e },
+       { 0x9be2, 0, 8, 0x4d },
+       { 0x9bee, 0, 1, 0x01 },
+};
+
+/* Microtune MT2060 tuner init
+   AF9013_TUNER_MT2060_2   = 147 */
+static const struct af9013_reg_bit tuner_init_mt2060_2[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x06 },
+       { 0x9bbe, 0, 8, 0x01 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0x0f },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x32 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0x36 },
+       { 0xd00d, 0, 2, 0x03 },
+       { 0xd00a, 0, 8, 0x35 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x07 },
+       { 0x9bc8, 0, 8, 0x90 },
+       { 0x9bc3, 0, 8, 0x0f },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x36 },
+       { 0x9bc6, 0, 8, 0x03 },
+       { 0x9bba, 0, 8, 0xc9 },
+       { 0x9bc9, 0, 8, 0x79 },
+       { 0xd011, 0, 8, 0x10 },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0x45 },
+       { 0xd014, 0, 2, 0x03 },
+       { 0xd040, 0, 8, 0x98 },
+       { 0xd041, 0, 2, 0x00 },
+       { 0xd042, 0, 8, 0xcf },
+       { 0xd043, 0, 2, 0x03 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 8, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x96 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0xd045, 7, 1, 0x00 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+};
+
+/* MaxLinear MXL5003 tuner init
+   AF9013_TUNER_MXL5003D   =   3 */
+static const struct af9013_reg_bit tuner_init_mxl5003d[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x09 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x00 },
+       { 0x9be3, 0, 8, 0x00 },
+       { 0x9bfc, 0, 8, 0x0f },
+       { 0x9bf6, 0, 8, 0x01 },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0xd015, 0, 8, 0x33 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x40 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0x0f },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x6c },
+       { 0xd007, 0, 2, 0x00 },
+       { 0xd00c, 0, 8, 0x3d },
+       { 0xd00d, 0, 2, 0x00 },
+       { 0xd00a, 0, 8, 0x45 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x07 },
+       { 0x9bc8, 0, 8, 0x52 },
+       { 0x9bc3, 0, 8, 0x0f },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x3d },
+       { 0x9bc6, 0, 8, 0x00 },
+       { 0x9bba, 0, 8, 0xa2 },
+       { 0x9bc9, 0, 8, 0xa0 },
+       { 0xd011, 0, 8, 0x56 },
+       { 0xd012, 0, 2, 0x00 },
+       { 0xd013, 0, 8, 0x50 },
+       { 0xd014, 0, 2, 0x00 },
+       { 0xd040, 0, 8, 0x56 },
+       { 0xd041, 0, 2, 0x00 },
+       { 0xd042, 0, 8, 0x50 },
+       { 0xd043, 0, 2, 0x00 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 8, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+};
+
+/* MaxLinear MXL5005S & MXL5007T tuner init
+   AF9013_TUNER_MXL5005D   =  13
+   AF9013_TUNER_MXL5005R   =  30
+   AF9013_TUNER_MXL5007T   = 177 */
+static const struct af9013_reg_bit tuner_init_mxl5005[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x07 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x01 },
+       { 0x9be3, 0, 8, 0x01 },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+       { 0x9bb9, 0, 8, 0x00 },
+       { 0x9bcd, 0, 8, 0x28 },
+       { 0x9bff, 0, 8, 0x24 },
+       { 0xd015, 0, 8, 0x40 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x40 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0x0f },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x73 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0xfa },
+       { 0xd00d, 0, 2, 0x01 },
+       { 0xd00a, 0, 8, 0xff },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x23 },
+       { 0x9bc8, 0, 8, 0x55 },
+       { 0x9bc3, 0, 8, 0x01 },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0xfa },
+       { 0x9bc6, 0, 8, 0x01 },
+       { 0x9bba, 0, 8, 0xff },
+       { 0x9bc9, 0, 8, 0xff },
+       { 0x9bd3, 0, 8, 0x95 },
+       { 0xd011, 0, 8, 0x70 },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0xfb },
+       { 0xd014, 0, 2, 0x01 },
+       { 0xd040, 0, 8, 0x70 },
+       { 0xd041, 0, 2, 0x01 },
+       { 0xd042, 0, 8, 0xfb },
+       { 0xd043, 0, 2, 0x01 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+       { 0x9bd0, 0, 8, 0x93 },
+       { 0x9be4, 0, 8, 0xfe },
+       { 0x9bbd, 0, 8, 0x63 },
+       { 0x9be2, 0, 8, 0xfe },
+       { 0x9bee, 0, 1, 0x01 },
+};
+
+/* Quantek QT1010 tuner init
+   AF9013_TUNER_QT1010     = 134
+   AF9013_TUNER_QT1010A    = 162 */
+static const struct af9013_reg_bit tuner_init_qt1010[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x09 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x01 },
+       { 0x9be3, 0, 8, 0x01 },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+       { 0x9bb9, 0, 8, 0x00 },
+       { 0x9bcd, 0, 8, 0x28 },
+       { 0x9bff, 0, 8, 0x20 },
+       { 0xd008, 0, 8, 0x0f },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x99 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0x0f },
+       { 0xd00d, 0, 2, 0x02 },
+       { 0xd00a, 0, 8, 0x50 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x00 },
+       { 0x9bc8, 0, 8, 0x00 },
+       { 0x9bc3, 0, 8, 0x0f },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x0f },
+       { 0x9bc6, 0, 8, 0x02 },
+       { 0x9bba, 0, 8, 0xc5 },
+       { 0x9bc9, 0, 8, 0xff },
+       { 0xd011, 0, 8, 0x58 },
+       { 0xd012, 0, 2, 0x02 },
+       { 0xd013, 0, 8, 0x89 },
+       { 0xd014, 0, 2, 0x01 },
+       { 0xd040, 0, 8, 0x58 },
+       { 0xd041, 0, 2, 0x02 },
+       { 0xd042, 0, 8, 0x89 },
+       { 0xd043, 0, 2, 0x01 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+       { 0x9bd0, 0, 8, 0xcd },
+       { 0x9be4, 0, 8, 0xbb },
+       { 0x9bbd, 0, 8, 0x93 },
+       { 0x9be2, 0, 8, 0x80 },
+       { 0x9bee, 0, 1, 0x01 },
+};
+
+/* Freescale MC44S803 tuner init
+   AF9013_TUNER_MC44S803   = 133 */
+static const struct af9013_reg_bit tuner_init_mc44s803[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x06 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x00 },
+       { 0x9be3, 0, 8, 0x00 },
+       { 0x9bf6, 0, 8, 0x01 },
+       { 0x9bf8, 0, 8, 0x02 },
+       { 0x9bf9, 0, 8, 0x02 },
+       { 0x9bfc, 0, 8, 0x1f },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+       { 0x9bb9, 0, 8, 0x00 },
+       { 0x9bcd, 0, 8, 0x24 },
+       { 0x9bff, 0, 8, 0x24 },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0x01 },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x7b },
+       { 0xd007, 0, 2, 0x00 },
+       { 0xd00c, 0, 8, 0x7c },
+       { 0xd00d, 0, 2, 0x02 },
+       { 0xd00a, 0, 8, 0xfe },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bc7, 0, 8, 0x08 },
+       { 0x9bc8, 0, 8, 0x9a },
+       { 0x9bc3, 0, 8, 0x01 },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x7c },
+       { 0x9bc6, 0, 8, 0x02 },
+       { 0x9bba, 0, 8, 0xfc },
+       { 0x9bc9, 0, 8, 0xaa },
+       { 0xd011, 0, 8, 0x6b },
+       { 0xd012, 0, 2, 0x00 },
+       { 0xd013, 0, 8, 0x88 },
+       { 0xd014, 0, 2, 0x02 },
+       { 0xd040, 0, 8, 0x6b },
+       { 0xd041, 0, 2, 0x00 },
+       { 0xd042, 0, 8, 0x7c },
+       { 0xd043, 0, 2, 0x02 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+       { 0x9bd0, 0, 8, 0x9e },
+       { 0x9be4, 0, 8, 0xff },
+       { 0x9bbd, 0, 8, 0x9e },
+       { 0x9be2, 0, 8, 0x25 },
+       { 0x9bee, 0, 1, 0x01 },
+       { 0xd73b, 3, 1, 0x00 },
+};
+
+/* unknown, probably for tin can tuner, tuner init
+   AF9013_TUNER_UNKNOWN   = 140 */
+static const struct af9013_reg_bit tuner_init_unknown[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x02 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x01 },
+       { 0x9be3, 0, 8, 0x01 },
+       { 0xd1a0, 1, 1, 0x00 },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+       { 0x9bb9, 0, 8, 0x00 },
+       { 0x9bcd, 0, 8, 0x18 },
+       { 0x9bff, 0, 8, 0x2c },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0xdf },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x44 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0x00 },
+       { 0xd00d, 0, 2, 0x02 },
+       { 0xd00a, 0, 8, 0xf6 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bba, 0, 8, 0xf9 },
+       { 0x9bc8, 0, 8, 0xaa },
+       { 0x9bc3, 0, 8, 0xdf },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x00 },
+       { 0x9bc6, 0, 8, 0x02 },
+       { 0x9bc9, 0, 8, 0xf0 },
+       { 0xd011, 0, 8, 0x3c },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0xf7 },
+       { 0xd014, 0, 2, 0x02 },
+       { 0xd040, 0, 8, 0x0b },
+       { 0xd041, 0, 2, 0x02 },
+       { 0xd042, 0, 8, 0x4d },
+       { 0xd043, 0, 2, 0x00 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+};
+
+/* NXP TDA18271 & TDA18218 tuner init
+   AF9013_TUNER_TDA18271   = 156
+   AF9013_TUNER_TDA18218   = 179 */
+static const struct af9013_reg_bit tuner_init_tda18271[] = {
+       { 0x9bd5, 0, 8, 0x01 },
+       { 0x9bd6, 0, 8, 0x04 },
+       { 0xd1a0, 1, 1, 0x01 },
+       { 0xd000, 0, 1, 0x01 },
+       { 0xd000, 1, 1, 0x00 },
+       { 0xd001, 1, 1, 0x01 },
+       { 0xd001, 0, 1, 0x00 },
+       { 0xd001, 5, 1, 0x00 },
+       { 0xd002, 0, 5, 0x19 },
+       { 0xd003, 0, 5, 0x1a },
+       { 0xd004, 0, 5, 0x19 },
+       { 0xd005, 0, 5, 0x1a },
+       { 0xd00e, 0, 5, 0x10 },
+       { 0xd00f, 0, 3, 0x04 },
+       { 0xd00f, 3, 3, 0x05 },
+       { 0xd010, 0, 3, 0x04 },
+       { 0xd010, 3, 3, 0x05 },
+       { 0xd016, 4, 4, 0x03 },
+       { 0xd01f, 0, 6, 0x0a },
+       { 0xd020, 0, 6, 0x0a },
+       { 0x9bda, 0, 8, 0x01 },
+       { 0x9be3, 0, 8, 0x01 },
+       { 0xd1a0, 1, 1, 0x00 },
+       { 0x9bbe, 0, 1, 0x01 },
+       { 0x9bcc, 0, 1, 0x01 },
+       { 0x9bb9, 0, 8, 0x00 },
+       { 0x9bcd, 0, 8, 0x18 },
+       { 0x9bff, 0, 8, 0x2c },
+       { 0xd015, 0, 8, 0x46 },
+       { 0xd016, 0, 1, 0x00 },
+       { 0xd044, 0, 8, 0x46 },
+       { 0xd045, 0, 1, 0x00 },
+       { 0xd008, 0, 8, 0xdf },
+       { 0xd009, 0, 2, 0x02 },
+       { 0xd006, 0, 8, 0x44 },
+       { 0xd007, 0, 2, 0x01 },
+       { 0xd00c, 0, 8, 0x00 },
+       { 0xd00d, 0, 2, 0x02 },
+       { 0xd00a, 0, 8, 0xf6 },
+       { 0xd00b, 0, 2, 0x01 },
+       { 0x9bba, 0, 8, 0xf9 },
+       { 0x9bc8, 0, 8, 0xaa },
+       { 0x9bc3, 0, 8, 0xdf },
+       { 0x9bc4, 0, 8, 0x02 },
+       { 0x9bc5, 0, 8, 0x00 },
+       { 0x9bc6, 0, 8, 0x02 },
+       { 0x9bc9, 0, 8, 0xf0 },
+       { 0xd011, 0, 8, 0x3c },
+       { 0xd012, 0, 2, 0x01 },
+       { 0xd013, 0, 8, 0xf7 },
+       { 0xd014, 0, 2, 0x02 },
+       { 0xd040, 0, 8, 0x0b },
+       { 0xd041, 0, 2, 0x02 },
+       { 0xd042, 0, 8, 0x4d },
+       { 0xd043, 0, 2, 0x00 },
+       { 0xd045, 1, 1, 0x00 },
+       { 0x9bcf, 0, 1, 0x01 },
+       { 0xd045, 2, 1, 0x01 },
+       { 0xd04f, 0, 8, 0x9a },
+       { 0xd050, 0, 1, 0x01 },
+       { 0xd051, 0, 8, 0x5a },
+       { 0xd052, 0, 1, 0x01 },
+       { 0xd053, 0, 8, 0x50 },
+       { 0xd054, 0, 8, 0x46 },
+       { 0x9bd7, 0, 8, 0x0a },
+       { 0x9bd8, 0, 8, 0x14 },
+       { 0x9bd9, 0, 8, 0x08 },
+       { 0x9bd0, 0, 8, 0xa8 },
+       { 0x9be4, 0, 8, 0x7f },
+       { 0x9bbd, 0, 8, 0xa8 },
+       { 0x9be2, 0, 8, 0x20 },
+       { 0x9bee, 0, 1, 0x01 },
+};
+
+#endif /* AF9013_PRIV_H */
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
new file mode 100644 (file)
index 0000000..a389982
--- /dev/null
@@ -0,0 +1,980 @@
+/*
+ * Afatech AF9033 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#include "af9033_priv.h"
+
+struct af9033_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct af9033_config cfg;
+
+       u32 bandwidth_hz;
+       bool ts_mode_parallel;
+       bool ts_mode_serial;
+
+       u32 ber;
+       u32 ucb;
+       unsigned long last_stat_check;
+};
+
+/* write multiple registers */
+static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
+               int len)
+{
+       int ret;
+       u8 buf[3 + len];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = state->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = (reg >> 16) & 0xff;
+       buf[1] = (reg >>  8) & 0xff;
+       buf[2] = (reg >>  0) & 0xff;
+       memcpy(&buf[3], val, len);
+
+       ret = i2c_transfer(state->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n",
+                               __func__, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* read multiple registers */
+static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
+{
+       int ret;
+       u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
+                       (reg >> 0) & 0xff };
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = state->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf
+               }, {
+                       .addr = state->cfg.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n",
+                               __func__, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+
+/* write single register */
+static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
+{
+       return af9033_wr_regs(state, reg, &val, 1);
+}
+
+/* read single register */
+static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
+{
+       return af9033_rd_regs(state, reg, val, 1);
+}
+
+/* write single register with mask */
+static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
+               u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = af9033_rd_regs(state, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return af9033_wr_regs(state, reg, &val, 1);
+}
+
+/* read single register with mask */
+static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
+               u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = af9033_rd_regs(state, reg, &tmp, 1);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+static u32 af9033_div(u32 a, u32 b, u32 x)
+{
+       u32 r = 0, c = 0, i;
+
+       pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x);
+
+       if (a > b) {
+               c = a / b;
+               a = a - c * b;
+       }
+
+       for (i = 0; i < x; i++) {
+               if (a >= b) {
+                       r += 1;
+                       a -= b;
+               }
+               a <<= 1;
+               r <<= 1;
+       }
+       r = (c << (u32)x) + r;
+
+       pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r);
+
+       return r;
+}
+
+static void af9033_release(struct dvb_frontend *fe)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+
+       kfree(state);
+}
+
+static int af9033_init(struct dvb_frontend *fe)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret, i, len;
+       const struct reg_val *init;
+       u8 buf[4];
+       u32 adc_cw, clock_cw;
+       struct reg_val_mask tab[] = {
+               { 0x80fb24, 0x00, 0x08 },
+               { 0x80004c, 0x00, 0xff },
+               { 0x00f641, state->cfg.tuner, 0xff },
+               { 0x80f5ca, 0x01, 0x01 },
+               { 0x80f715, 0x01, 0x01 },
+               { 0x00f41f, 0x04, 0x04 },
+               { 0x00f41a, 0x01, 0x01 },
+               { 0x80f731, 0x00, 0x01 },
+               { 0x00d91e, 0x00, 0x01 },
+               { 0x00d919, 0x00, 0x01 },
+               { 0x80f732, 0x00, 0x01 },
+               { 0x00d91f, 0x00, 0x01 },
+               { 0x00d91a, 0x00, 0x01 },
+               { 0x80f730, 0x00, 0x01 },
+               { 0x80f778, 0x00, 0xff },
+               { 0x80f73c, 0x01, 0x01 },
+               { 0x80f776, 0x00, 0x01 },
+               { 0x00d8fd, 0x01, 0xff },
+               { 0x00d830, 0x01, 0xff },
+               { 0x00d831, 0x00, 0xff },
+               { 0x00d832, 0x00, 0xff },
+               { 0x80f985, state->ts_mode_serial, 0x01 },
+               { 0x80f986, state->ts_mode_parallel, 0x01 },
+               { 0x00d827, 0x00, 0xff },
+               { 0x00d829, 0x00, 0xff },
+       };
+
+       /* program clock control */
+       clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul);
+       buf[0] = (clock_cw >>  0) & 0xff;
+       buf[1] = (clock_cw >>  8) & 0xff;
+       buf[2] = (clock_cw >> 16) & 0xff;
+       buf[3] = (clock_cw >> 24) & 0xff;
+
+       pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock,
+                       clock_cw);
+
+       ret = af9033_wr_regs(state, 0x800025, buf, 4);
+       if (ret < 0)
+               goto err;
+
+       /* program ADC control */
+       for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
+               if (clock_adc_lut[i].clock == state->cfg.clock)
+                       break;
+       }
+
+       adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul);
+       buf[0] = (adc_cw >>  0) & 0xff;
+       buf[1] = (adc_cw >>  8) & 0xff;
+       buf[2] = (adc_cw >> 16) & 0xff;
+
+       pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc,
+                       adc_cw);
+
+       ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
+       if (ret < 0)
+               goto err;
+
+       /* program register table */
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
+                               tab[i].mask);
+               if (ret < 0)
+                       goto err;
+       }
+
+       /* settings for TS interface */
+       if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
+               ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+       } else {
+               ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+       }
+
+       /* load OFSM settings */
+       pr_debug("%s: load ofsm settings\n", __func__);
+       len = ARRAY_SIZE(ofsm_init);
+       init = ofsm_init;
+       for (i = 0; i < len; i++) {
+               ret = af9033_wr_reg(state, init[i].reg, init[i].val);
+               if (ret < 0)
+                       goto err;
+       }
+
+       /* load tuner specific settings */
+       pr_debug("%s: load tuner specific settings\n",
+                       __func__);
+       switch (state->cfg.tuner) {
+       case AF9033_TUNER_TUA9001:
+               len = ARRAY_SIZE(tuner_init_tua9001);
+               init = tuner_init_tua9001;
+               break;
+       case AF9033_TUNER_FC0011:
+               len = ARRAY_SIZE(tuner_init_fc0011);
+               init = tuner_init_fc0011;
+               break;
+       case AF9033_TUNER_MXL5007T:
+               len = ARRAY_SIZE(tuner_init_mxl5007t);
+               init = tuner_init_mxl5007t;
+               break;
+       case AF9033_TUNER_TDA18218:
+               len = ARRAY_SIZE(tuner_init_tda18218);
+               init = tuner_init_tda18218;
+               break;
+       default:
+               pr_debug("%s: unsupported tuner ID=%d\n", __func__,
+                               state->cfg.tuner);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       for (i = 0; i < len; i++) {
+               ret = af9033_wr_reg(state, init[i].reg, init[i].val);
+               if (ret < 0)
+                       goto err;
+       }
+
+       state->bandwidth_hz = 0; /* force to program all parameters */
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_sleep(struct dvb_frontend *fe)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret, i;
+       u8 tmp;
+
+       ret = af9033_wr_reg(state, 0x80004c, 1);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x800000, 0);
+       if (ret < 0)
+               goto err;
+
+       for (i = 100, tmp = 1; i && tmp; i--) {
+               ret = af9033_rd_reg(state, 0x80004c, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               usleep_range(200, 10000);
+       }
+
+       pr_debug("%s: loop=%d\n", __func__, i);
+
+       if (i == 0) {
+               ret = -ETIMEDOUT;
+               goto err;
+       }
+
+       ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
+       if (ret < 0)
+               goto err;
+
+       /* prevent current leak (?) */
+       if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
+               /* enable parallel TS */
+               ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
+               if (ret < 0)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_get_tune_settings(struct dvb_frontend *fe,
+               struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 800;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+
+       return 0;
+}
+
+static int af9033_set_frontend(struct dvb_frontend *fe)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i, spec_inv;
+       u8 tmp, buf[3], bandwidth_reg_val;
+       u32 if_frequency, freq_cw, adc_freq;
+
+       pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency,
+                       c->bandwidth_hz);
+
+       /* check bandwidth */
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               bandwidth_reg_val = 0x00;
+               break;
+       case 7000000:
+               bandwidth_reg_val = 0x01;
+               break;
+       case 8000000:
+               bandwidth_reg_val = 0x02;
+               break;
+       default:
+               pr_debug("%s: invalid bandwidth_hz\n", __func__);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       /* program CFOE coefficients */
+       if (c->bandwidth_hz != state->bandwidth_hz) {
+               for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
+                       if (coeff_lut[i].clock == state->cfg.clock &&
+                               coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
+                               break;
+                       }
+               }
+               ret =  af9033_wr_regs(state, 0x800001,
+                               coeff_lut[i].val, sizeof(coeff_lut[i].val));
+       }
+
+       /* program frequency control */
+       if (c->bandwidth_hz != state->bandwidth_hz) {
+               spec_inv = state->cfg.spec_inv ? -1 : 1;
+
+               for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
+                       if (clock_adc_lut[i].clock == state->cfg.clock)
+                               break;
+               }
+               adc_freq = clock_adc_lut[i].adc;
+
+               /* get used IF frequency */
+               if (fe->ops.tuner_ops.get_if_frequency)
+                       fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+               else
+                       if_frequency = 0;
+
+               while (if_frequency > (adc_freq / 2))
+                       if_frequency -= adc_freq;
+
+               if (if_frequency >= 0)
+                       spec_inv *= -1;
+               else
+                       if_frequency *= -1;
+
+               freq_cw = af9033_div(if_frequency, adc_freq, 23ul);
+
+               if (spec_inv == -1)
+                       freq_cw *= -1;
+
+               /* get adc multiplies */
+               ret = af9033_rd_reg(state, 0x800045, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               if (tmp == 1)
+                       freq_cw /= 2;
+
+               buf[0] = (freq_cw >>  0) & 0xff;
+               buf[1] = (freq_cw >>  8) & 0xff;
+               buf[2] = (freq_cw >> 16) & 0x7f;
+               ret = af9033_wr_regs(state, 0x800029, buf, 3);
+               if (ret < 0)
+                       goto err;
+
+               state->bandwidth_hz = c->bandwidth_hz;
+       }
+
+       ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x800040, 0x00);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x800047, 0x00);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
+       if (ret < 0)
+               goto err;
+
+       if (c->frequency <= 230000000)
+               tmp = 0x00; /* VHF */
+       else
+               tmp = 0x01; /* UHF */
+
+       ret = af9033_wr_reg(state, 0x80004b, tmp);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_wr_reg(state, 0x800000, 0x00);
+       if (ret < 0)
+               goto err;
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_get_frontend(struct dvb_frontend *fe)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u8 buf[8];
+
+       pr_debug("%s\n", __func__);
+
+       /* read all needed registers */
+       ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
+       if (ret < 0)
+               goto err;
+
+       switch ((buf[0] >> 0) & 3) {
+       case 0:
+               c->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               c->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+
+       switch ((buf[1] >> 0) & 3) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       switch ((buf[2] >> 0) & 7) {
+       case 0:
+               c->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               c->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               c->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               c->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+       switch ((buf[3] >> 0) & 3) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       }
+
+       switch ((buf[4] >> 0) & 3) {
+       case 0:
+               c->bandwidth_hz = 6000000;
+               break;
+       case 1:
+               c->bandwidth_hz = 7000000;
+               break;
+       case 2:
+               c->bandwidth_hz = 8000000;
+               break;
+       }
+
+       switch ((buf[6] >> 0) & 7) {
+       case 0:
+               c->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_HP = FEC_7_8;
+               break;
+       case 5:
+               c->code_rate_HP = FEC_NONE;
+               break;
+       }
+
+       switch ((buf[7] >> 0) & 7) {
+       case 0:
+               c->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_LP = FEC_7_8;
+               break;
+       case 5:
+               c->code_rate_LP = FEC_NONE;
+               break;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+
+       *status = 0;
+
+       /* radio channel status, 0=no result, 1=has signal, 2=no signal */
+       ret = af9033_rd_reg(state, 0x800047, &tmp);
+       if (ret < 0)
+               goto err;
+
+       /* has signal */
+       if (tmp == 0x01)
+               *status |= FE_HAS_SIGNAL;
+
+       if (tmp != 0x02) {
+               /* TPS lock */
+               ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               if (tmp)
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                                       FE_HAS_VITERBI;
+
+               /* full lock */
+               ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
+               if (ret < 0)
+                       goto err;
+
+               if (tmp)
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                                       FE_HAS_VITERBI | FE_HAS_SYNC |
+                                       FE_HAS_LOCK;
+       }
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret, i, len;
+       u8 buf[3], tmp;
+       u32 snr_val;
+       const struct val_snr *uninitialized_var(snr_lut);
+
+       /* read value */
+       ret = af9033_rd_regs(state, 0x80002c, buf, 3);
+       if (ret < 0)
+               goto err;
+
+       snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
+
+       /* read current modulation */
+       ret = af9033_rd_reg(state, 0x80f903, &tmp);
+       if (ret < 0)
+               goto err;
+
+       switch ((tmp >> 0) & 3) {
+       case 0:
+               len = ARRAY_SIZE(qpsk_snr_lut);
+               snr_lut = qpsk_snr_lut;
+               break;
+       case 1:
+               len = ARRAY_SIZE(qam16_snr_lut);
+               snr_lut = qam16_snr_lut;
+               break;
+       case 2:
+               len = ARRAY_SIZE(qam64_snr_lut);
+               snr_lut = qam64_snr_lut;
+               break;
+       default:
+               goto err;
+       }
+
+       for (i = 0; i < len; i++) {
+               tmp = snr_lut[i].snr;
+
+               if (snr_val < snr_lut[i].val)
+                       break;
+       }
+
+       *snr = tmp * 10; /* dB/10 */
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+       u8 strength2;
+
+       /* read signal strength of 0-100 scale */
+       ret = af9033_rd_reg(state, 0x800048, &strength2);
+       if (ret < 0)
+               goto err;
+
+       /* scale value to 0x0000-0xffff */
+       *strength = strength2 * 0xffff / 100;
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int af9033_update_ch_stat(struct af9033_state *state)
+{
+       int ret = 0;
+       u32 err_cnt, bit_cnt;
+       u16 abort_cnt;
+       u8 buf[7];
+
+       /* only update data every half second */
+       if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
+               ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
+               if (ret < 0)
+                       goto err;
+               /* in 8 byte packets? */
+               abort_cnt = (buf[1] << 8) + buf[0];
+               /* in bits */
+               err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
+               /* in 8 byte packets? always(?) 0x2710 = 10000 */
+               bit_cnt = (buf[6] << 8) + buf[5];
+
+               if (bit_cnt < abort_cnt) {
+                       abort_cnt = 1000;
+                       state->ber = 0xffffffff;
+               } else {
+                       /* 8 byte packets, that have not been rejected already */
+                       bit_cnt -= (u32)abort_cnt;
+                       if (bit_cnt == 0) {
+                               state->ber = 0xffffffff;
+                       } else {
+                               err_cnt -= (u32)abort_cnt * 8 * 8;
+                               bit_cnt *= 8 * 8;
+                               state->ber = err_cnt * (0xffffffff / bit_cnt);
+                       }
+               }
+               state->ucb += abort_cnt;
+               state->last_stat_check = jiffies;
+       }
+
+       return 0;
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+
+       ret = af9033_update_ch_stat(state);
+       if (ret < 0)
+               return ret;
+
+       *ber = state->ber;
+
+       return 0;
+}
+
+static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+
+       ret = af9033_update_ch_stat(state);
+       if (ret < 0)
+               return ret;
+
+       *ucblocks = state->ucb;
+
+       return 0;
+}
+
+static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct af9033_state *state = fe->demodulator_priv;
+       int ret;
+
+       pr_debug("%s: enable=%d\n", __func__, enable);
+
+       ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
+       if (ret < 0)
+               goto err;
+
+       return 0;
+
+err:
+       pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static struct dvb_frontend_ops af9033_ops;
+
+struct dvb_frontend *af9033_attach(const struct af9033_config *config,
+               struct i2c_adapter *i2c)
+{
+       int ret;
+       struct af9033_state *state;
+       u8 buf[8];
+
+       pr_debug("%s:\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
+       if (state == NULL)
+               goto err;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->cfg, config, sizeof(struct af9033_config));
+
+       if (state->cfg.clock != 12000000) {
+               printk(KERN_INFO "af9033: unsupported clock=%d, only " \
+                               "12000000 Hz is supported currently\n",
+                               state->cfg.clock);
+               goto err;
+       }
+
+       /* firmware version */
+       ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
+       if (ret < 0)
+               goto err;
+
+       ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
+       if (ret < 0)
+               goto err;
+
+       printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \
+                       "OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3],
+                       buf[4], buf[5], buf[6], buf[7]);
+
+       /* configure internal TS mode */
+       switch (state->cfg.ts_mode) {
+       case AF9033_TS_MODE_PARALLEL:
+               state->ts_mode_parallel = true;
+               break;
+       case AF9033_TS_MODE_SERIAL:
+               state->ts_mode_serial = true;
+               break;
+       case AF9033_TS_MODE_USB:
+               /* usb mode for AF9035 */
+       default:
+               break;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
+       state->fe.demodulator_priv = state;
+
+       return &state->fe;
+
+err:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(af9033_attach);
+
+static struct dvb_frontend_ops af9033_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Afatech AF9033 (DVB-T)",
+               .frequency_min = 174000000,
+               .frequency_max = 862000000,
+               .frequency_stepsize = 250000,
+               .frequency_tolerance = 0,
+               .caps = FE_CAN_FEC_1_2 |
+                       FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = af9033_release,
+
+       .init = af9033_init,
+       .sleep = af9033_sleep,
+
+       .get_tune_settings = af9033_get_tune_settings,
+       .set_frontend = af9033_set_frontend,
+       .get_frontend = af9033_get_frontend,
+
+       .read_status = af9033_read_status,
+       .read_snr = af9033_read_snr,
+       .read_signal_strength = af9033_read_signal_strength,
+       .read_ber = af9033_read_ber,
+       .read_ucblocks = af9033_read_ucblocks,
+
+       .i2c_gate_ctrl = af9033_i2c_gate_ctrl,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/af9033.h b/drivers/media/dvb-frontends/af9033.h
new file mode 100644 (file)
index 0000000..9e302c3
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Afatech AF9033 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef AF9033_H
+#define AF9033_H
+
+struct af9033_config {
+       /*
+        * I2C address
+        */
+       u8 i2c_addr;
+
+       /*
+        * clock Hz
+        * 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
+        * 30000000, 36000000, 20480000, 16384000
+        */
+       u32 clock;
+
+       /*
+        * tuner
+        */
+#define AF9033_TUNER_TUA9001     0x27 /* Infineon TUA 9001 */
+#define AF9033_TUNER_FC0011      0x28 /* Fitipower FC0011 */
+#define AF9033_TUNER_MXL5007T    0xa0 /* MaxLinear MxL5007T */
+#define AF9033_TUNER_TDA18218    0xa1 /* NXP TDA 18218HN */
+       u8 tuner;
+
+       /*
+        * TS settings
+        */
+#define AF9033_TS_MODE_USB       0
+#define AF9033_TS_MODE_PARALLEL  1
+#define AF9033_TS_MODE_SERIAL    2
+       u8 ts_mode:2;
+
+       /*
+        * input spectrum inversion
+        */
+       bool spec_inv;
+};
+
+
+#if defined(CONFIG_DVB_AF9033) || \
+       (defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE))
+extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *af9033_attach(
+       const struct af9033_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* AF9033_H */
diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
new file mode 100644 (file)
index 0000000..0b783b9
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * Afatech AF9033 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef AF9033_PRIV_H
+#define AF9033_PRIV_H
+
+#include "dvb_frontend.h"
+#include "af9033.h"
+
+struct reg_val {
+       u32 reg;
+       u8  val;
+};
+
+struct reg_val_mask {
+       u32 reg;
+       u8  val;
+       u8  mask;
+};
+
+struct coeff {
+       u32 clock;
+       u32 bandwidth_hz;
+       u8 val[36];
+};
+
+struct clock_adc {
+       u32 clock;
+       u32 adc;
+};
+
+struct val_snr {
+       u32 val;
+       u8 snr;
+};
+
+/* Xtal clock vs. ADC clock lookup table */
+static const struct clock_adc clock_adc_lut[] = {
+       { 16384000, 20480000 },
+       { 20480000, 20480000 },
+       { 36000000, 20250000 },
+       { 30000000, 20156250 },
+       { 26000000, 20583333 },
+       { 28000000, 20416667 },
+       { 32000000, 20500000 },
+       { 34000000, 20187500 },
+       { 24000000, 20500000 },
+       { 22000000, 20625000 },
+       { 12000000, 20250000 },
+};
+
+/* pre-calculated coeff lookup table */
+static const struct coeff coeff_lut[] = {
+       /* 12.000 MHz */
+       { 12000000, 8000000, {
+               0x01, 0xce, 0x55, 0xc9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
+               0x99, 0x0f, 0x00, 0x73, 0x95, 0x72, 0x00, 0x73, 0x91, 0xd5,
+               0x00, 0x39, 0xca, 0xb9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
+               0x95, 0x72, 0x37, 0x02, 0xce, 0x01 }
+       },
+       { 12000000, 7000000, {
+               0x01, 0x94, 0x8b, 0x10, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
+               0x25, 0xed, 0x00, 0x65, 0x22, 0xc4, 0x00, 0x65, 0x1f, 0x9b,
+               0x00, 0x32, 0x91, 0x62, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
+               0x22, 0xc4, 0x88, 0x02, 0x95, 0x01 }
+       },
+       { 12000000, 6000000, {
+               0x01, 0x5a, 0xc0, 0x56, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
+               0xb2, 0xcb, 0x00, 0x56, 0xb0, 0x15, 0x00, 0x56, 0xad, 0x60,
+               0x00, 0x2b, 0x58, 0x0b, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
+               0xb0, 0x15, 0xf4, 0x02, 0x5b, 0x01 }
+       },
+};
+
+/* QPSK SNR lookup table */
+static const struct val_snr qpsk_snr_lut[] = {
+       { 0x0b4771,  0 },
+       { 0x0c1aed,  1 },
+       { 0x0d0d27,  2 },
+       { 0x0e4d19,  3 },
+       { 0x0e5da8,  4 },
+       { 0x107097,  5 },
+       { 0x116975,  6 },
+       { 0x1252d9,  7 },
+       { 0x131fa4,  8 },
+       { 0x13d5e1,  9 },
+       { 0x148e53, 10 },
+       { 0x15358b, 11 },
+       { 0x15dd29, 12 },
+       { 0x168112, 13 },
+       { 0x170b61, 14 },
+       { 0x17a532, 15 },
+       { 0x180f94, 16 },
+       { 0x186ed2, 17 },
+       { 0x18b271, 18 },
+       { 0x18e118, 19 },
+       { 0x18ff4b, 20 },
+       { 0x190af1, 21 },
+       { 0x191451, 22 },
+       { 0xffffff, 23 },
+};
+
+/* QAM16 SNR lookup table */
+static const struct val_snr qam16_snr_lut[] = {
+       { 0x04f0d5,  0 },
+       { 0x05387a,  1 },
+       { 0x0573a4,  2 },
+       { 0x05a99e,  3 },
+       { 0x05cc80,  4 },
+       { 0x05eb62,  5 },
+       { 0x05fecf,  6 },
+       { 0x060b80,  7 },
+       { 0x062501,  8 },
+       { 0x064865,  9 },
+       { 0x069604, 10 },
+       { 0x06f356, 11 },
+       { 0x07706a, 12 },
+       { 0x0804d3, 13 },
+       { 0x089d1a, 14 },
+       { 0x093e3d, 15 },
+       { 0x09e35d, 16 },
+       { 0x0a7c3c, 17 },
+       { 0x0afaf8, 18 },
+       { 0x0b719d, 19 },
+       { 0x0bda6a, 20 },
+       { 0x0c0c75, 21 },
+       { 0x0c3f7d, 22 },
+       { 0x0c5e62, 23 },
+       { 0x0c6c31, 24 },
+       { 0x0c7925, 25 },
+       { 0xffffff, 26 },
+};
+
+/* QAM64 SNR lookup table */
+static const struct val_snr qam64_snr_lut[] = {
+       { 0x0256d0,  0 },
+       { 0x027a65,  1 },
+       { 0x029873,  2 },
+       { 0x02b7fe,  3 },
+       { 0x02cf1e,  4 },
+       { 0x02e234,  5 },
+       { 0x02f409,  6 },
+       { 0x030046,  7 },
+       { 0x030844,  8 },
+       { 0x030a02,  9 },
+       { 0x030cde, 10 },
+       { 0x031031, 11 },
+       { 0x03144c, 12 },
+       { 0x0315dd, 13 },
+       { 0x031920, 14 },
+       { 0x0322d0, 15 },
+       { 0x0339fc, 16 },
+       { 0x0364a1, 17 },
+       { 0x038bcc, 18 },
+       { 0x03c7d3, 19 },
+       { 0x0408cc, 20 },
+       { 0x043bed, 21 },
+       { 0x048061, 22 },
+       { 0x04be95, 23 },
+       { 0x04fa7d, 24 },
+       { 0x052405, 25 },
+       { 0x05570d, 26 },
+       { 0x059feb, 27 },
+       { 0x05bf38, 28 },
+       { 0xffffff, 29 },
+};
+
+static const struct reg_val ofsm_init[] = {
+       { 0x800051, 0x01 },
+       { 0x800070, 0x0a },
+       { 0x80007e, 0x04 },
+       { 0x800081, 0x0a },
+       { 0x80008a, 0x01 },
+       { 0x80008e, 0x01 },
+       { 0x800092, 0x06 },
+       { 0x800099, 0x01 },
+       { 0x80009f, 0xe1 },
+       { 0x8000a0, 0xcf },
+       { 0x8000a3, 0x01 },
+       { 0x8000a5, 0x01 },
+       { 0x8000a6, 0x01 },
+       { 0x8000a9, 0x00 },
+       { 0x8000aa, 0x01 },
+       { 0x8000ab, 0x01 },
+       { 0x8000b0, 0x01 },
+       { 0x8000c0, 0x05 },
+       { 0x8000c4, 0x19 },
+       { 0x80f000, 0x0f },
+       { 0x80f016, 0x10 },
+       { 0x80f017, 0x04 },
+       { 0x80f018, 0x05 },
+       { 0x80f019, 0x04 },
+       { 0x80f01a, 0x05 },
+       { 0x80f021, 0x03 },
+       { 0x80f022, 0x0a },
+       { 0x80f023, 0x0a },
+       { 0x80f02b, 0x00 },
+       { 0x80f02c, 0x01 },
+       { 0x80f064, 0x03 },
+       { 0x80f065, 0xf9 },
+       { 0x80f066, 0x03 },
+       { 0x80f067, 0x01 },
+       { 0x80f06f, 0xe0 },
+       { 0x80f070, 0x03 },
+       { 0x80f072, 0x0f },
+       { 0x80f073, 0x03 },
+       { 0x80f078, 0x00 },
+       { 0x80f087, 0x00 },
+       { 0x80f09b, 0x3f },
+       { 0x80f09c, 0x00 },
+       { 0x80f09d, 0x20 },
+       { 0x80f09e, 0x00 },
+       { 0x80f09f, 0x0c },
+       { 0x80f0a0, 0x00 },
+       { 0x80f130, 0x04 },
+       { 0x80f132, 0x04 },
+       { 0x80f144, 0x1a },
+       { 0x80f146, 0x00 },
+       { 0x80f14a, 0x01 },
+       { 0x80f14c, 0x00 },
+       { 0x80f14d, 0x00 },
+       { 0x80f14f, 0x04 },
+       { 0x80f158, 0x7f },
+       { 0x80f15a, 0x00 },
+       { 0x80f15b, 0x08 },
+       { 0x80f15d, 0x03 },
+       { 0x80f15e, 0x05 },
+       { 0x80f163, 0x05 },
+       { 0x80f166, 0x01 },
+       { 0x80f167, 0x40 },
+       { 0x80f168, 0x0f },
+       { 0x80f17a, 0x00 },
+       { 0x80f17b, 0x00 },
+       { 0x80f183, 0x01 },
+       { 0x80f19d, 0x40 },
+       { 0x80f1bc, 0x36 },
+       { 0x80f1bd, 0x00 },
+       { 0x80f1cb, 0xa0 },
+       { 0x80f1cc, 0x01 },
+       { 0x80f204, 0x10 },
+       { 0x80f214, 0x00 },
+       { 0x80f40e, 0x0a },
+       { 0x80f40f, 0x40 },
+       { 0x80f410, 0x08 },
+       { 0x80f55f, 0x0a },
+       { 0x80f561, 0x15 },
+       { 0x80f562, 0x20 },
+       { 0x80f5df, 0xfb },
+       { 0x80f5e0, 0x00 },
+       { 0x80f5e3, 0x09 },
+       { 0x80f5e4, 0x01 },
+       { 0x80f5e5, 0x01 },
+       { 0x80f5f8, 0x01 },
+       { 0x80f5fd, 0x01 },
+       { 0x80f600, 0x05 },
+       { 0x80f601, 0x08 },
+       { 0x80f602, 0x0b },
+       { 0x80f603, 0x0e },
+       { 0x80f604, 0x11 },
+       { 0x80f605, 0x14 },
+       { 0x80f606, 0x17 },
+       { 0x80f607, 0x1f },
+       { 0x80f60e, 0x00 },
+       { 0x80f60f, 0x04 },
+       { 0x80f610, 0x32 },
+       { 0x80f611, 0x10 },
+       { 0x80f707, 0xfc },
+       { 0x80f708, 0x00 },
+       { 0x80f709, 0x37 },
+       { 0x80f70a, 0x00 },
+       { 0x80f78b, 0x01 },
+       { 0x80f80f, 0x40 },
+       { 0x80f810, 0x54 },
+       { 0x80f811, 0x5a },
+       { 0x80f905, 0x01 },
+       { 0x80fb06, 0x03 },
+       { 0x80fd8b, 0x00 },
+};
+
+/* Infineon TUA 9001 tuner init
+   AF9033_TUNER_TUA9001    = 0x27 */
+static const struct reg_val tuner_init_tua9001[] = {
+       { 0x800046, 0x27 },
+       { 0x800057, 0x00 },
+       { 0x800058, 0x01 },
+       { 0x80005f, 0x00 },
+       { 0x800060, 0x00 },
+       { 0x80006d, 0x00 },
+       { 0x800071, 0x05 },
+       { 0x800072, 0x02 },
+       { 0x800074, 0x01 },
+       { 0x800075, 0x03 },
+       { 0x800076, 0x02 },
+       { 0x800077, 0x00 },
+       { 0x800078, 0x01 },
+       { 0x800079, 0x00 },
+       { 0x80007a, 0x7e },
+       { 0x80007b, 0x3e },
+       { 0x800093, 0x00 },
+       { 0x800094, 0x01 },
+       { 0x800095, 0x02 },
+       { 0x800096, 0x01 },
+       { 0x800098, 0x0a },
+       { 0x80009b, 0x05 },
+       { 0x80009c, 0x80 },
+       { 0x8000b3, 0x00 },
+       { 0x8000c1, 0x01 },
+       { 0x8000c2, 0x00 },
+       { 0x80f007, 0x00 },
+       { 0x80f01f, 0x82 },
+       { 0x80f020, 0x00 },
+       { 0x80f029, 0x82 },
+       { 0x80f02a, 0x00 },
+       { 0x80f047, 0x00 },
+       { 0x80f054, 0x00 },
+       { 0x80f055, 0x00 },
+       { 0x80f077, 0x01 },
+       { 0x80f1e6, 0x00 },
+};
+
+/* Fitipower fc0011 tuner init
+   AF9033_TUNER_FC0011    = 0x28 */
+static const struct reg_val tuner_init_fc0011[] = {
+       { 0x800046, AF9033_TUNER_FC0011 },
+       { 0x800057, 0x00 },
+       { 0x800058, 0x01 },
+       { 0x80005f, 0x00 },
+       { 0x800060, 0x00 },
+       { 0x800068, 0xa5 },
+       { 0x80006e, 0x01 },
+       { 0x800071, 0x0A },
+       { 0x800072, 0x02 },
+       { 0x800074, 0x01 },
+       { 0x800079, 0x01 },
+       { 0x800093, 0x00 },
+       { 0x800094, 0x00 },
+       { 0x800095, 0x00 },
+       { 0x800096, 0x00 },
+       { 0x80009b, 0x2D },
+       { 0x80009c, 0x60 },
+       { 0x80009d, 0x23 },
+       { 0x8000a4, 0x50 },
+       { 0x8000ad, 0x50 },
+       { 0x8000b3, 0x01 },
+       { 0x8000b7, 0x88 },
+       { 0x8000b8, 0xa6 },
+       { 0x8000c3, 0x01 },
+       { 0x8000c4, 0x01 },
+       { 0x8000c7, 0x69 },
+       { 0x80F007, 0x00 },
+       { 0x80F00A, 0x1B },
+       { 0x80F00B, 0x1B },
+       { 0x80F00C, 0x1B },
+       { 0x80F00D, 0x1B },
+       { 0x80F00E, 0xFF },
+       { 0x80F00F, 0x01 },
+       { 0x80F010, 0x00 },
+       { 0x80F011, 0x02 },
+       { 0x80F012, 0xFF },
+       { 0x80F013, 0x01 },
+       { 0x80F014, 0x00 },
+       { 0x80F015, 0x02 },
+       { 0x80F01B, 0xEF },
+       { 0x80F01C, 0x01 },
+       { 0x80F01D, 0x0f },
+       { 0x80F01E, 0x02 },
+       { 0x80F01F, 0x6E },
+       { 0x80F020, 0x00 },
+       { 0x80F025, 0xDE },
+       { 0x80F026, 0x00 },
+       { 0x80F027, 0x0A },
+       { 0x80F028, 0x03 },
+       { 0x80F029, 0x6E },
+       { 0x80F02A, 0x00 },
+       { 0x80F047, 0x00 },
+       { 0x80F054, 0x00 },
+       { 0x80F055, 0x00 },
+       { 0x80F077, 0x01 },
+       { 0x80F1E6, 0x00 },
+};
+
+/* MaxLinear MxL5007T tuner init
+   AF9033_TUNER_MXL5007T    = 0xa0 */
+static const struct reg_val tuner_init_mxl5007t[] = {
+       { 0x800046, 0x1b },
+       { 0x800057, 0x01 },
+       { 0x800058, 0x01 },
+       { 0x80005f, 0x00 },
+       { 0x800060, 0x00 },
+       { 0x800068, 0x96 },
+       { 0x800071, 0x05 },
+       { 0x800072, 0x02 },
+       { 0x800074, 0x01 },
+       { 0x800079, 0x01 },
+       { 0x800093, 0x00 },
+       { 0x800094, 0x00 },
+       { 0x800095, 0x00 },
+       { 0x800096, 0x00 },
+       { 0x8000b3, 0x01 },
+       { 0x8000c1, 0x01 },
+       { 0x8000c2, 0x00 },
+       { 0x80f007, 0x00 },
+       { 0x80f00c, 0x19 },
+       { 0x80f00d, 0x1a },
+       { 0x80f012, 0xda },
+       { 0x80f013, 0x00 },
+       { 0x80f014, 0x00 },
+       { 0x80f015, 0x02 },
+       { 0x80f01f, 0x82 },
+       { 0x80f020, 0x00 },
+       { 0x80f029, 0x82 },
+       { 0x80f02a, 0x00 },
+       { 0x80f077, 0x02 },
+       { 0x80f1e6, 0x00 },
+};
+
+/* NXP TDA 18218HN tuner init
+   AF9033_TUNER_TDA18218    = 0xa1 */
+static const struct reg_val tuner_init_tda18218[] = {
+       {0x800046, 0xa1},
+       {0x800057, 0x01},
+       {0x800058, 0x01},
+       {0x80005f, 0x00},
+       {0x800060, 0x00},
+       {0x800071, 0x05},
+       {0x800072, 0x02},
+       {0x800074, 0x01},
+       {0x800079, 0x01},
+       {0x800093, 0x00},
+       {0x800094, 0x00},
+       {0x800095, 0x00},
+       {0x800096, 0x00},
+       {0x8000b3, 0x01},
+       {0x8000c3, 0x01},
+       {0x8000c4, 0x00},
+       {0x80f007, 0x00},
+       {0x80f00c, 0x19},
+       {0x80f00d, 0x1a},
+       {0x80f012, 0xda},
+       {0x80f013, 0x00},
+       {0x80f014, 0x00},
+       {0x80f015, 0x02},
+       {0x80f01f, 0x82},
+       {0x80f020, 0x00},
+       {0x80f029, 0x82},
+       {0x80f02a, 0x00},
+       {0x80f077, 0x02},
+       {0x80f1e6, 0x00},
+};
+
+#endif /* AF9033_PRIV_H */
+
diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c
new file mode 100644 (file)
index 0000000..4e11dc4
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/div64.h>
+#include "dvb_frontend.h"
+
+#include "atbm8830.h"
+#include "atbm8830_priv.h"
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "atbm8830: " args); \
+       } while (0)
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
+{
+       int ret = 0;
+       u8 dev_addr;
+       u8 buf1[] = { reg >> 8, reg & 0xFF };
+       u8 buf2[] = { data };
+       struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+       struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
+
+       dev_addr = priv->config->demod_address;
+       msg1.addr = dev_addr;
+       msg2.addr = dev_addr;
+
+       if (debug >= 2)
+               dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
+
+       ret = i2c_transfer(priv->i2c, &msg1, 1);
+       if (ret != 1)
+               return -EIO;
+
+       ret = i2c_transfer(priv->i2c, &msg2, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
+static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
+{
+       int ret;
+       u8 dev_addr;
+
+       u8 buf1[] = { reg >> 8, reg & 0xFF };
+       u8 buf2[] = { 0 };
+       struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
+       struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
+
+       dev_addr = priv->config->demod_address;
+       msg1.addr = dev_addr;
+       msg2.addr = dev_addr;
+
+       ret = i2c_transfer(priv->i2c, &msg1, 1);
+       if (ret != 1) {
+               dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
+               return -EIO;
+       }
+
+       ret = i2c_transfer(priv->i2c, &msg2, 1);
+       if (ret != 1)
+               return -EIO;
+
+       *p_data = buf2[0];
+       if (debug >= 2)
+               dprintk("%s: reg=0x%04X, data=0x%02X\n",
+                       __func__, reg, buf2[0]);
+
+       return 0;
+}
+
+/* Lock register latch so that multi-register read is atomic */
+static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
+{
+       return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
+}
+
+static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+       u32 val;
+       u64 t;
+
+       /* 0x100000 * freq / 30.4MHz */
+       t = (u64)0x100000 * freq;
+       do_div(t, 30400);
+       val = t;
+
+       atbm8830_write_reg(priv, REG_OSC_CLK, val);
+       atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
+       atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
+
+       return 0;
+}
+
+static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
+{
+
+       u32 fs = priv->config->osc_clk_freq;
+       u64 t;
+       u32 val;
+       u8 dat;
+
+       if (freq != 0) {
+               /* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
+               t = (u64) 2 * 31416 * (freq - fs);
+               t <<= 22;
+               do_div(t, fs);
+               do_div(t, 1000);
+               val = t;
+
+               atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
+               atbm8830_write_reg(priv, REG_IF_FREQ, val);
+               atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
+               atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
+
+               atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+               dat &= 0xFC;
+               atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+       } else {
+               /* Zero IF */
+               atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
+
+               atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
+               dat &= 0xFC;
+               dat |= 0x02;
+               atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
+
+               if (priv->config->zif_swap_iq)
+                       atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
+               else
+                       atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
+       }
+
+       return 0;
+}
+
+static int is_locked(struct atbm_state *priv, u8 *locked)
+{
+       u8 status;
+
+       atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
+
+       if (locked != NULL)
+               *locked = (status == 1);
+       return 0;
+}
+
+static int set_agc_config(struct atbm_state *priv,
+       u8 min, u8 max, u8 hold_loop)
+{
+       /* no effect if both min and max are zero */
+       if (!min && !max)
+           return 0;
+
+       atbm8830_write_reg(priv, REG_AGC_MIN, min);
+       atbm8830_write_reg(priv, REG_AGC_MAX, max);
+       atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
+
+       return 0;
+}
+
+static int set_static_channel_mode(struct atbm_state *priv)
+{
+       int i;
+
+       for (i = 0; i < 5; i++)
+               atbm8830_write_reg(priv, 0x099B + i, 0x08);
+
+       atbm8830_write_reg(priv, 0x095B, 0x7F);
+       atbm8830_write_reg(priv, 0x09CB, 0x01);
+       atbm8830_write_reg(priv, 0x09CC, 0x7F);
+       atbm8830_write_reg(priv, 0x09CD, 0x7F);
+       atbm8830_write_reg(priv, 0x0E01, 0x20);
+
+       /* For single carrier */
+       atbm8830_write_reg(priv, 0x0B03, 0x0A);
+       atbm8830_write_reg(priv, 0x0935, 0x10);
+       atbm8830_write_reg(priv, 0x0936, 0x08);
+       atbm8830_write_reg(priv, 0x093E, 0x08);
+       atbm8830_write_reg(priv, 0x096E, 0x06);
+
+       /* frame_count_max0 */
+       atbm8830_write_reg(priv, 0x0B09, 0x00);
+       /* frame_count_max1 */
+       atbm8830_write_reg(priv, 0x0B0A, 0x08);
+
+       return 0;
+}
+
+static int set_ts_config(struct atbm_state *priv)
+{
+       const struct atbm8830_config *cfg = priv->config;
+
+       /*Set parallel/serial ts mode*/
+       atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
+       atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
+       /*Set ts sampling edge*/
+       atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
+               cfg->ts_sampling_edge ? 1 : 0);
+       /*Set ts clock freerun*/
+       atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
+               cfg->ts_clk_gated ? 0 : 1);
+
+       return 0;
+}
+
+static int atbm8830_init(struct dvb_frontend *fe)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+       const struct atbm8830_config *cfg = priv->config;
+
+       /*Set oscillator frequency*/
+       set_osc_freq(priv, cfg->osc_clk_freq);
+
+       /*Set IF frequency*/
+       set_if_freq(priv, cfg->if_freq);
+
+       /*Set AGC Config*/
+       set_agc_config(priv, cfg->agc_min, cfg->agc_max,
+               cfg->agc_hold_loop);
+
+       /*Set static channel mode*/
+       set_static_channel_mode(priv);
+
+       set_ts_config(priv);
+       /*Turn off DSP reset*/
+       atbm8830_write_reg(priv, 0x000A, 0);
+
+       /*SW version test*/
+       atbm8830_write_reg(priv, 0x020C, 11);
+
+       /* Run */
+       atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
+
+       return 0;
+}
+
+
+static void atbm8830_release(struct dvb_frontend *fe)
+{
+       struct atbm_state *state = fe->demodulator_priv;
+       dprintk("%s\n", __func__);
+
+       kfree(state);
+}
+
+static int atbm8830_set_fe(struct dvb_frontend *fe)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+       int i;
+       u8 locked = 0;
+       dprintk("%s\n", __func__);
+
+       /* set frequency */
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* start auto lock */
+       for (i = 0; i < 10; i++) {
+               mdelay(100);
+               dprintk("Try %d\n", i);
+               is_locked(priv, &locked);
+               if (locked != 0) {
+                       dprintk("ATBM8830 locked!\n");
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int atbm8830_get_fe(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       dprintk("%s\n", __func__);
+
+       /* TODO: get real readings from device */
+       /* inversion status */
+       c->inversion = INVERSION_OFF;
+
+       /* bandwidth */
+       c->bandwidth_hz = 8000000;
+
+       c->code_rate_HP = FEC_AUTO;
+       c->code_rate_LP = FEC_AUTO;
+
+       c->modulation = QAM_AUTO;
+
+       /* transmission mode */
+       c->transmission_mode = TRANSMISSION_MODE_AUTO;
+
+       /* guard interval */
+       c->guard_interval = GUARD_INTERVAL_AUTO;
+
+       /* hierarchy */
+       c->hierarchy = HIERARCHY_NONE;
+
+       return 0;
+}
+
+static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 0;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+       u8 locked = 0;
+       u8 agc_locked = 0;
+
+       dprintk("%s\n", __func__);
+       *fe_status = 0;
+
+       is_locked(priv, &locked);
+       if (locked) {
+               *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                       FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       }
+       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+
+       atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
+       dprintk("AGC Lock: %d\n", agc_locked);
+
+       return 0;
+}
+
+static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+       u32 frame_err;
+       u8 t;
+
+       dprintk("%s\n", __func__);
+
+       atbm8830_reglatch_lock(priv, 1);
+
+       atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
+       frame_err = t & 0x7F;
+       frame_err <<= 8;
+       atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
+       frame_err |= t;
+
+       atbm8830_reglatch_lock(priv, 0);
+
+       *ber = frame_err * 100 / 32767;
+
+       dprintk("%s: ber=0x%x\n", __func__, *ber);
+       return 0;
+}
+
+static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+       u32 pwm;
+       u8 t;
+
+       dprintk("%s\n", __func__);
+       atbm8830_reglatch_lock(priv, 1);
+
+       atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
+       pwm = t & 0x03;
+       pwm <<= 8;
+       atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
+       pwm |= t;
+
+       atbm8830_reglatch_lock(priv, 0);
+
+       dprintk("AGC PWM = 0x%02X\n", pwm);
+       pwm = 0x400 - pwm;
+
+       *signal = pwm * 0x10000 / 0x400;
+
+       return 0;
+}
+
+static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       dprintk("%s\n", __func__);
+       *snr = 0;
+       return 0;
+}
+
+static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       dprintk("%s\n", __func__);
+       *ucblocks = 0;
+       return 0;
+}
+
+static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct atbm_state *priv = fe->demodulator_priv;
+
+       return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
+}
+
+static struct dvb_frontend_ops atbm8830_ops = {
+       .delsys = { SYS_DTMB },
+       .info = {
+               .name = "AltoBeam ATBM8830/8831 DMB-TH",
+               .frequency_min = 474000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 10000,
+               .caps =
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO
+       },
+
+       .release = atbm8830_release,
+
+       .init = atbm8830_init,
+       .sleep = NULL,
+       .write = NULL,
+       .i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
+
+       .set_frontend = atbm8830_set_fe,
+       .get_frontend = atbm8830_get_fe,
+       .get_tune_settings = atbm8830_get_tune_settings,
+
+       .read_status = atbm8830_read_status,
+       .read_ber = atbm8830_read_ber,
+       .read_signal_strength = atbm8830_read_signal_strength,
+       .read_snr = atbm8830_read_snr,
+       .read_ucblocks = atbm8830_read_ucblocks,
+};
+
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+       struct i2c_adapter *i2c)
+{
+       struct atbm_state *priv = NULL;
+       u8 data = 0;
+
+       dprintk("%s()\n", __func__);
+
+       if (config == NULL || i2c == NULL)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
+       if (priv == NULL)
+               goto error_out;
+
+       priv->config = config;
+       priv->i2c = i2c;
+
+       /* check if the demod is there */
+       if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
+               dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
+                       __func__, priv->config->demod_address);
+               goto error_out;
+       }
+       dprintk("atbm8830 chip id: 0x%02X\n", data);
+
+       memcpy(&priv->frontend.ops, &atbm8830_ops,
+              sizeof(struct dvb_frontend_ops));
+       priv->frontend.demodulator_priv = priv;
+
+       atbm8830_init(&priv->frontend);
+
+       atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
+
+       return &priv->frontend;
+
+error_out:
+       dprintk("%s() error_out\n", __func__);
+       kfree(priv);
+       return NULL;
+
+}
+EXPORT_SYMBOL(atbm8830_attach);
+
+MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/atbm8830.h b/drivers/media/dvb-frontends/atbm8830.h
new file mode 100644 (file)
index 0000000..0242733
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ATBM8830_H__
+#define __ATBM8830_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define ATBM8830_PROD_8830 0
+#define ATBM8830_PROD_8831 1
+
+struct atbm8830_config {
+
+       /* product type */
+       u8 prod;
+
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* parallel or serial transport stream */
+       u8 serial_ts;
+
+       /* transport stream clock output only when receiving valid stream */
+       u8 ts_clk_gated;
+
+       /* Decoder sample TS data at rising edge of clock */
+       u8 ts_sampling_edge;
+
+       /* Oscillator clock frequency */
+       u32 osc_clk_freq; /* in kHz */
+
+       /* IF frequency */
+       u32 if_freq; /* in kHz */
+
+       /* Swap I/Q for zero IF */
+       u8 zif_swap_iq;
+
+       /* Tuner AGC settings */
+       u8 agc_min;
+       u8 agc_max;
+       u8 agc_hold_loop;
+};
+
+#if defined(CONFIG_DVB_ATBM8830) || \
+       (defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
+extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+               struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
+               struct i2c_adapter *i2c) {
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_ATBM8830 */
+
+#endif /* __ATBM8830_H__ */
diff --git a/drivers/media/dvb-frontends/atbm8830_priv.h b/drivers/media/dvb-frontends/atbm8830_priv.h
new file mode 100644 (file)
index 0000000..d460058
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
+ *    ATBM8830, ATBM8831
+ *
+ *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ATBM8830_PRIV_H
+#define __ATBM8830_PRIV_H
+
+struct atbm_state {
+       struct i2c_adapter *i2c;
+       /* configuration settings */
+       const struct atbm8830_config *config;
+       struct dvb_frontend frontend;
+};
+
+#define REG_CHIP_ID    0x0000
+#define REG_TUNER_BASEBAND     0x0001
+#define REG_DEMOD_RUN  0x0004
+#define REG_DSP_RESET  0x0005
+#define REG_RAM_RESET  0x0006
+#define REG_ADC_RESET  0x0007
+#define REG_TSPORT_RESET       0x0008
+#define REG_BLKERR_POL 0x000C
+#define REG_I2C_GATE   0x0103
+#define REG_TS_SAMPLE_EDGE     0x0301
+#define REG_TS_PKT_LEN_204     0x0302
+#define REG_TS_PKT_LEN_AUTO    0x0303
+#define REG_TS_SERIAL  0x0305
+#define REG_TS_CLK_FREERUN     0x0306
+#define REG_TS_VALID_MODE      0x0307
+#define REG_TS_CLK_MODE        0x030B /* 1 for serial, 0 for parallel */
+
+#define REG_TS_ERRBIT_USE      0x030C
+#define REG_LOCK_STATUS        0x030D
+#define REG_ADC_CONFIG 0x0602
+#define REG_CARRIER_OFFSET     0x0827 /* 0x0827-0x0829 little endian */
+#define REG_DETECTED_PN_MODE   0x082D
+#define REG_READ_LATCH 0x084D
+#define REG_IF_FREQ    0x0A00 /* 0x0A00-0x0A02 little endian */
+#define REG_OSC_CLK    0x0A03 /* 0x0A03-0x0A05 little endian */
+#define REG_BYPASS_CCI 0x0A06
+#define REG_ANALOG_LUMA_DETECTED       0x0A25
+#define REG_ANALOG_AUDIO_DETECTED      0x0A26
+#define REG_ANALOG_CHROMA_DETECTED     0x0A39
+#define REG_FRAME_ERR_CNT      0x0B04
+#define REG_USE_EXT_ADC        0x0C00
+#define REG_SWAP_I_Q   0x0C01
+#define REG_TPS_MANUAL 0x0D01
+#define REG_TPS_CONFIG 0x0D02
+#define REG_BYPASS_DEINTERLEAVER       0x0E00
+#define REG_AGC_TARGET 0x1003 /* 0x1003-0x1005 little endian */
+#define REG_AGC_MIN    0x1020
+#define REG_AGC_MAX    0x1023
+#define REG_AGC_LOCK   0x1027
+#define REG_AGC_PWM_VAL        0x1028 /* 0x1028-0x1029 little endian */
+#define REG_AGC_HOLD_LOOP      0x1031
+
+#endif
+
diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
new file mode 100644 (file)
index 0000000..565dcf3
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __AU8522_H__
+#define __AU8522_H__
+
+#include <linux/dvb/frontend.h>
+
+enum au8522_if_freq {
+       AU8522_IF_6MHZ = 0,
+       AU8522_IF_4MHZ,
+       AU8522_IF_3_25MHZ,
+};
+
+struct au8522_led_config {
+       u16 vsb8_strong;
+       u16 qam64_strong;
+       u16 qam256_strong;
+
+       u16 gpio_output;
+       /* unset hi bits, set low bits */
+       u16 gpio_output_enable;
+       u16 gpio_output_disable;
+
+       u16 gpio_leds;
+       u8 *led_states;
+       unsigned int num_led_states;
+};
+
+struct au8522_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* Return lock status based on tuner lock, or demod lock */
+#define AU8522_TUNERLOCKING 0
+#define AU8522_DEMODLOCKING 1
+       u8 status_mode;
+
+       struct au8522_led_config *led_cfg;
+
+       enum au8522_if_freq vsb_if;
+       enum au8522_if_freq qam_if;
+};
+
+#if defined(CONFIG_DVB_AU8522) ||                              \
+           (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
+extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+                                         struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_AU8522 */
+
+/* Other modes may need to be added later */
+enum au8522_video_input {
+       AU8522_COMPOSITE_CH1 = 1,
+       AU8522_COMPOSITE_CH2,
+       AU8522_COMPOSITE_CH3,
+       AU8522_COMPOSITE_CH4,
+       AU8522_COMPOSITE_CH4_SIF,
+       AU8522_SVIDEO_CH13,
+       AU8522_SVIDEO_CH24,
+};
+
+enum au8522_audio_input {
+       AU8522_AUDIO_NONE,
+       AU8522_AUDIO_SIF,
+};
+
+#endif /* __AU8522_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb-frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c
new file mode 100644 (file)
index 0000000..3559ff2
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+    Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+    Copyright (C) 2005-2008 Auvitek International, Ltd.
+    Copyright (C) 2012 Michael Krufky <mkrufky@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522_priv.h"
+
+static int debug;
+
+#define dprintk(arg...)\
+  do { if (debug)\
+        printk(arg);\
+  } while (0)
+
+/* Despite the name "hybrid_tuner", the framework works just as well for
+   hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(au8522_list_mutex);
+
+/* 16 bit registers, 8 bit values */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
+
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+                              .flags = 0, .buf = buf, .len = 3 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+                      "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+EXPORT_SYMBOL(au8522_writereg);
+
+u8 au8522_readreg(struct au8522_state *state, u16 reg)
+{
+       int ret;
+       u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
+       u8 b1[] = { 0 };
+
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0,
+                 .buf = b0, .len = 2 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD,
+                 .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+                      __func__, ret);
+       return b1[0];
+}
+EXPORT_SYMBOL(au8522_readreg);
+
+int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (state->operational_mode == AU8522_ANALOG_MODE) {
+               /* We're being asked to manage the gate even though we're
+                  not in digital mode.  This can occur if we get switched
+                  over to analog mode before the dvb_frontend kernel thread
+                  has completely shutdown */
+               return 0;
+       }
+
+       if (enable)
+               return au8522_writereg(state, 0x106, 1);
+       else
+               return au8522_writereg(state, 0x106, 0);
+}
+EXPORT_SYMBOL(au8522_i2c_gate_ctrl);
+
+int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (enable)
+               return au8522_writereg(state, 0x106, 1);
+       else
+               return au8522_writereg(state, 0x106, 0);
+}
+EXPORT_SYMBOL(au8522_analog_i2c_gate_ctrl);
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+                    u8 client_address)
+{
+       int ret;
+
+       mutex_lock(&au8522_list_mutex);
+       ret = hybrid_tuner_request_state(struct au8522_state, (*state),
+                                        hybrid_tuner_instance_list,
+                                        i2c, client_address, "au8522");
+       mutex_unlock(&au8522_list_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL(au8522_get_state);
+
+void au8522_release_state(struct au8522_state *state)
+{
+       mutex_lock(&au8522_list_mutex);
+       if (state != NULL)
+               hybrid_tuner_release_state(state);
+       mutex_unlock(&au8522_list_mutex);
+}
+EXPORT_SYMBOL(au8522_release_state);
+
+static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
+{
+       struct au8522_led_config *led_config = state->config->led_cfg;
+       u8 val;
+
+       /* bail out if we can't control an LED */
+       if (!led_config || !led_config->gpio_output ||
+           !led_config->gpio_output_enable || !led_config->gpio_output_disable)
+               return 0;
+
+       val = au8522_readreg(state, 0x4000 |
+                            (led_config->gpio_output & ~0xc000));
+       if (onoff) {
+               /* enable GPIO output */
+               val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
+               val |=  (led_config->gpio_output_enable & 0xff);
+       } else {
+               /* disable GPIO output */
+               val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
+               val |=  (led_config->gpio_output_disable & 0xff);
+       }
+       return au8522_writereg(state, 0x8000 |
+                              (led_config->gpio_output & ~0xc000), val);
+}
+
+/* led = 0 | off
+ * led = 1 | signal ok
+ * led = 2 | signal strong
+ * led < 0 | only light led if leds are currently off
+ */
+int au8522_led_ctrl(struct au8522_state *state, int led)
+{
+       struct au8522_led_config *led_config = state->config->led_cfg;
+       int i, ret = 0;
+
+       /* bail out if we can't control an LED */
+       if (!led_config || !led_config->gpio_leds ||
+           !led_config->num_led_states || !led_config->led_states)
+               return 0;
+
+       if (led < 0) {
+               /* if LED is already lit, then leave it as-is */
+               if (state->led_state)
+                       return 0;
+               else
+                       led *= -1;
+       }
+
+       /* toggle LED if changing state */
+       if (state->led_state != led) {
+               u8 val;
+
+               dprintk("%s: %d\n", __func__, led);
+
+               au8522_led_gpio_enable(state, 1);
+
+               val = au8522_readreg(state, 0x4000 |
+                                    (led_config->gpio_leds & ~0xc000));
+
+               /* start with all leds off */
+               for (i = 0; i < led_config->num_led_states; i++)
+                       val &= ~led_config->led_states[i];
+
+               /* set selected LED state */
+               if (led < led_config->num_led_states)
+                       val |= led_config->led_states[led];
+               else if (led_config->num_led_states)
+                       val |=
+                       led_config->led_states[led_config->num_led_states - 1];
+
+               ret = au8522_writereg(state, 0x8000 |
+                                     (led_config->gpio_leds & ~0xc000), val);
+               if (ret < 0)
+                       return ret;
+
+               state->led_state = led;
+
+               if (led == 0)
+                       au8522_led_gpio_enable(state, 0);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(au8522_led_ctrl);
+
+int au8522_init(struct dvb_frontend *fe)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       dprintk("%s()\n", __func__);
+
+       state->operational_mode = AU8522_DIGITAL_MODE;
+
+       /* Clear out any state associated with the digital side of the
+          chip, so that when it gets powered back up it won't think
+          that it is already tuned */
+       state->current_frequency = 0;
+
+       au8522_writereg(state, 0xa4, 1 << 5);
+
+       au8522_i2c_gate_ctrl(fe, 1);
+
+       return 0;
+}
+EXPORT_SYMBOL(au8522_init);
+
+int au8522_sleep(struct dvb_frontend *fe)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       dprintk("%s()\n", __func__);
+
+       /* Only power down if the digital side is currently using the chip */
+       if (state->operational_mode == AU8522_ANALOG_MODE) {
+               /* We're not in one of the expected power modes, which means
+                  that the DVB thread is probably telling us to go to sleep
+                  even though the analog frontend has already started using
+                  the chip.  So ignore the request */
+               return 0;
+       }
+
+       /* turn off led */
+       au8522_led_ctrl(state, 0);
+
+       /* Power down the chip */
+       au8522_writereg(state, 0xa4, 1 << 5);
+
+       state->current_frequency = 0;
+
+       return 0;
+}
+EXPORT_SYMBOL(au8522_sleep);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
new file mode 100644 (file)
index 0000000..5243ba6
--- /dev/null
@@ -0,0 +1,839 @@
+/*
+ * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * 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.
+ */
+
+/* Developer notes:
+ *
+ * VBI support is not yet working
+ * Enough is implemented here for CVBS and S-Video inputs, but the actual
+ *  analog demodulator code isn't implemented (not needed for xc5000 since it
+ *  has its own demodulator and outputs CVBS)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-device.h>
+#include "au8522.h"
+#include "au8522_priv.h"
+
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static int au8522_analog_debug;
+
+
+module_param_named(analog_debug, au8522_analog_debug, int, 0644);
+
+MODULE_PARM_DESC(analog_debug,
+                "Analog debugging messages [0=Off (default) 1=On]");
+
+struct au8522_register_config {
+       u16 reg_name;
+       u8 reg_val[8];
+};
+
+
+/* Video Decoder Filter Coefficients
+   The values are as follows from left to right
+   0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
+*/
+static const struct au8522_register_config filter_coef[] = {
+       {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
+       {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
+       {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
+       {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
+       {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
+       {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
+       {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
+       {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
+       {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
+       {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
+       {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
+       {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
+       {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
+       {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
+       {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
+       {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
+       {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
+       {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
+       {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
+       {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
+       {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
+       {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
+
+};
+#define NUM_FILTER_COEF (sizeof(filter_coef)\
+                        / sizeof(struct au8522_register_config))
+
+
+/* Registers 0x060b through 0x0652 are the LP Filter coefficients
+   The values are as follows from left to right
+   0="SIF" 1="ATVRF/ATVRF13"
+   Note: the "ATVRF/ATVRF13" mode has never been tested
+*/
+static const struct au8522_register_config lpfilter_coef[] = {
+       {0x060b, {0x21, 0x0b} },
+       {0x060c, {0xad, 0xad} },
+       {0x060d, {0x70, 0xf0} },
+       {0x060e, {0xea, 0xe9} },
+       {0x060f, {0xdd, 0xdd} },
+       {0x0610, {0x08, 0x64} },
+       {0x0611, {0x60, 0x60} },
+       {0x0612, {0xf8, 0xb2} },
+       {0x0613, {0x01, 0x02} },
+       {0x0614, {0xe4, 0xb4} },
+       {0x0615, {0x19, 0x02} },
+       {0x0616, {0xae, 0x2e} },
+       {0x0617, {0xee, 0xc5} },
+       {0x0618, {0x56, 0x56} },
+       {0x0619, {0x30, 0x58} },
+       {0x061a, {0xf9, 0xf8} },
+       {0x061b, {0x24, 0x64} },
+       {0x061c, {0x07, 0x07} },
+       {0x061d, {0x30, 0x30} },
+       {0x061e, {0xa9, 0xed} },
+       {0x061f, {0x09, 0x0b} },
+       {0x0620, {0x42, 0xc2} },
+       {0x0621, {0x1d, 0x2a} },
+       {0x0622, {0xd6, 0x56} },
+       {0x0623, {0x95, 0x8b} },
+       {0x0624, {0x2b, 0x2b} },
+       {0x0625, {0x30, 0x24} },
+       {0x0626, {0x3e, 0x3e} },
+       {0x0627, {0x62, 0xe2} },
+       {0x0628, {0xe9, 0xf5} },
+       {0x0629, {0x99, 0x19} },
+       {0x062a, {0xd4, 0x11} },
+       {0x062b, {0x03, 0x04} },
+       {0x062c, {0xb5, 0x85} },
+       {0x062d, {0x1e, 0x20} },
+       {0x062e, {0x2a, 0xea} },
+       {0x062f, {0xd7, 0xd2} },
+       {0x0630, {0x15, 0x15} },
+       {0x0631, {0xa3, 0xa9} },
+       {0x0632, {0x1f, 0x1f} },
+       {0x0633, {0xf9, 0xd1} },
+       {0x0634, {0xc0, 0xc3} },
+       {0x0635, {0x4d, 0x8d} },
+       {0x0636, {0x21, 0x31} },
+       {0x0637, {0x83, 0x83} },
+       {0x0638, {0x08, 0x8c} },
+       {0x0639, {0x19, 0x19} },
+       {0x063a, {0x45, 0xa5} },
+       {0x063b, {0xef, 0xec} },
+       {0x063c, {0x8a, 0x8a} },
+       {0x063d, {0xf4, 0xf6} },
+       {0x063e, {0x8f, 0x8f} },
+       {0x063f, {0x44, 0x0c} },
+       {0x0640, {0xef, 0xf0} },
+       {0x0641, {0x66, 0x66} },
+       {0x0642, {0xcc, 0xd2} },
+       {0x0643, {0x41, 0x41} },
+       {0x0644, {0x63, 0x93} },
+       {0x0645, {0x8e, 0x8e} },
+       {0x0646, {0xa2, 0x42} },
+       {0x0647, {0x7b, 0x7b} },
+       {0x0648, {0x04, 0x04} },
+       {0x0649, {0x00, 0x00} },
+       {0x064a, {0x40, 0x40} },
+       {0x064b, {0x8c, 0x98} },
+       {0x064c, {0x00, 0x00} },
+       {0x064d, {0x63, 0xc3} },
+       {0x064e, {0x04, 0x04} },
+       {0x064f, {0x20, 0x20} },
+       {0x0650, {0x00, 0x00} },
+       {0x0651, {0x40, 0x40} },
+       {0x0652, {0x01, 0x01} },
+};
+#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
+                          / sizeof(struct au8522_register_config))
+
+static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct au8522_state, sd);
+}
+
+static void setup_vbi(struct au8522_state *state, int aud_input)
+{
+       int i;
+
+       /* These are set to zero regardless of what mode we're in */
+       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
+                       0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
+                       0x00);
+       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
+                       0x00);
+
+       /* Setup the VBI registers */
+       for (i = 0x30; i < 0x60; i++)
+               au8522_writereg(state, i, 0x40);
+
+       /* For some reason, every register is 0x40 except register 0x44
+          (confirmed via the HVR-950q USB capture) */
+       au8522_writereg(state, 0x44, 0x60);
+
+       /* Enable VBI (we always do this regardless of whether the user is
+          viewing closed caption info) */
+       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
+                       AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
+
+}
+
+static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+{
+       int i;
+       int filter_coef_type;
+
+       /* Provide reasonable defaults for picture tuning values */
+       au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
+       au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
+       state->brightness = 0xed - 128;
+       au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
+       state->contrast = 0x79;
+       au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
+       au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+       state->saturation = 0x80;
+       au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
+       au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+       state->hue = 0x00;
+
+       /* Other decoder registers */
+       au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
+
+       if (input_mode == 0x23) {
+               /* S-Video input mapping */
+               au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
+       } else {
+               /* All other modes (CVBS/ATVRF etc.) */
+               au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
+       }
+
+       au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
+                       AU8522_TVDEC_PGA_REG012H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
+                       AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
+       au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
+                       AU8522_TVDED_DBG_MODE_REG060H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
+                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
+                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
+       au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+                       AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
+       au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
+                       AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
+                       AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
+                       AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
+                       AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
+                       AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
+                       AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
+                       AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
+                       AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
+                       AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
+       if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+           input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+                               AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
+               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+                               AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
+       } else {
+               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+                               AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+                               AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+       }
+       au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
+                       AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
+                       AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
+                       AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
+       au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
+       au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
+                       AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
+       au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
+       au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
+                       AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
+                       AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
+                       AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
+                       AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
+                       AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
+       au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
+                       AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
+       au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
+                       AU8522_TOREGAAGC_REG0E5H_CVBS);
+       au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
+
+       setup_vbi(state, 0);
+
+       if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+           input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+               /* Despite what the table says, for the HVR-950q we still need
+                  to be in CVBS mode for the S-Video input (reason unknown). */
+               /* filter_coef_type = 3; */
+               filter_coef_type = 5;
+       } else {
+               filter_coef_type = 5;
+       }
+
+       /* Load the Video Decoder Filter Coefficients */
+       for (i = 0; i < NUM_FILTER_COEF; i++) {
+               au8522_writereg(state, filter_coef[i].reg_name,
+                               filter_coef[i].reg_val[filter_coef_type]);
+       }
+
+       /* It's not clear what these registers are for, but they are always
+          set to the same value regardless of what mode we're in */
+       au8522_writereg(state, AU8522_REG42EH, 0x87);
+       au8522_writereg(state, AU8522_REG42FH, 0xa2);
+       au8522_writereg(state, AU8522_REG430H, 0xbf);
+       au8522_writereg(state, AU8522_REG431H, 0xcb);
+       au8522_writereg(state, AU8522_REG432H, 0xa1);
+       au8522_writereg(state, AU8522_REG433H, 0x41);
+       au8522_writereg(state, AU8522_REG434H, 0x88);
+       au8522_writereg(state, AU8522_REG435H, 0xc2);
+       au8522_writereg(state, AU8522_REG436H, 0x3c);
+}
+
+static void au8522_setup_cvbs_mode(struct au8522_state *state)
+{
+       /* here we're going to try the pre-programmed route */
+       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+       /* PGA in automatic mode */
+       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+       /* Enable clamping control */
+       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+                       AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+       setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+{
+       /* here we're going to try the pre-programmed route */
+       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+       /* It's not clear why we have to have the PGA in automatic mode while
+          enabling clamp control, but it's what Windows does */
+       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+       /* Enable clamping control */
+       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+
+       /* Disable automatic PGA (since the CVBS is coming from the tuner) */
+       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+       /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
+       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+                       AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+       setup_decoder_defaults(state,
+                              AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_svideo_mode(struct au8522_state *state)
+{
+       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
+
+       /* Set input to Y on Channe1, C on Channel 3 */
+       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+                       AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+       /* PGA in automatic mode */
+       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+       /* Enable clamping control */
+       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+       setup_decoder_defaults(state,
+                              AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void disable_audio_input(struct au8522_state *state)
+{
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
+       au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
+
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
+}
+
+/* 0=disable, 1=SIF */
+static void set_audio_input(struct au8522_state *state, int aud_input)
+{
+       int i;
+
+       /* Note that this function needs to be used in conjunction with setting
+          the input routing via register 0x81 */
+
+       if (aud_input == AU8522_AUDIO_NONE) {
+               disable_audio_input(state);
+               return;
+       }
+
+       if (aud_input != AU8522_AUDIO_SIF) {
+               /* The caller asked for a mode we don't currently support */
+               printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
+                      aud_input);
+               return;
+       }
+
+       /* Load the Audio Decoder Filter Coefficients */
+       for (i = 0; i < NUM_LPFILTER_COEF; i++) {
+               au8522_writereg(state, lpfilter_coef[i].reg_name,
+                               lpfilter_coef[i].reg_val[0]);
+       }
+
+       /* Setup audio */
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+       au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+       au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+       msleep(150);
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
+       msleep(1);
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+       msleep(50);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
+       msleep(80);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+       au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+       au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
+       msleep(70);
+       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
+       au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+       au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+       struct au8522_state *state = to_state(sd);
+
+       switch (ctrl->id) {
+       case V4L2_CID_BRIGHTNESS:
+               state->brightness = ctrl->value;
+               au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
+                               ctrl->value - 128);
+               break;
+       case V4L2_CID_CONTRAST:
+               state->contrast = ctrl->value;
+               au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
+                               ctrl->value);
+               break;
+       case V4L2_CID_SATURATION:
+               state->saturation = ctrl->value;
+               au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
+                               ctrl->value);
+               au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
+                               ctrl->value);
+               break;
+       case V4L2_CID_HUE:
+               state->hue = ctrl->value;
+               au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
+                               ctrl->value >> 8);
+               au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
+                               ctrl->value & 0xFF);
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+       case V4L2_CID_AUDIO_BASS:
+       case V4L2_CID_AUDIO_TREBLE:
+       case V4L2_CID_AUDIO_BALANCE:
+       case V4L2_CID_AUDIO_MUTE:
+               /* Not yet implemented */
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+       struct au8522_state *state = to_state(sd);
+
+       /* Note that we are using values cached in the state structure instead
+          of reading the registers due to issues with i2c reads not working
+          properly/consistently yet on the HVR-950q */
+
+       switch (ctrl->id) {
+       case V4L2_CID_BRIGHTNESS:
+               ctrl->value = state->brightness;
+               break;
+       case V4L2_CID_CONTRAST:
+               ctrl->value = state->contrast;
+               break;
+       case V4L2_CID_SATURATION:
+               ctrl->value = state->saturation;
+               break;
+       case V4L2_CID_HUE:
+               ctrl->value = state->hue;
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+       case V4L2_CID_AUDIO_BASS:
+       case V4L2_CID_AUDIO_TREBLE:
+       case V4L2_CID_AUDIO_BALANCE:
+       case V4L2_CID_AUDIO_MUTE:
+               /* Not yet supported */
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int au8522_g_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct au8522_state *state = to_state(sd);
+
+       if (!v4l2_chip_match_i2c_client(client, &reg->match))
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       reg->val = au8522_readreg(state, reg->reg & 0xffff);
+       return 0;
+}
+
+static int au8522_s_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct au8522_state *state = to_state(sd);
+
+       if (!v4l2_chip_match_i2c_client(client, &reg->match))
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       au8522_writereg(state, reg->reg, reg->val & 0xff);
+       return 0;
+}
+#endif
+
+static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct au8522_state *state = to_state(sd);
+
+       if (enable) {
+               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                               0x01);
+               msleep(1);
+               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                               AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+       } else {
+               /* This does not completely power down the device
+                  (it only reduces it from around 140ma to 80ma) */
+               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+                               1 << 5);
+       }
+       return 0;
+}
+
+static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+       switch (qc->id) {
+       case V4L2_CID_CONTRAST:
+               return v4l2_ctrl_query_fill(qc, 0, 255, 1,
+                                           AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
+       case V4L2_CID_BRIGHTNESS:
+               return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
+       case V4L2_CID_SATURATION:
+               return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+       case V4L2_CID_HUE:
+               return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
+       default:
+               break;
+       }
+
+       qc->type = 0;
+       return -EINVAL;
+}
+
+static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+{
+       struct au8522_state *state = to_state(sd);
+
+       state->operational_mode = AU8522_ANALOG_MODE;
+
+       /* Clear out any state associated with the digital side of the
+          chip, so that when it gets powered back up it won't think
+          that it is already tuned */
+       state->current_frequency = 0;
+
+       au8522_writereg(state, 0xa4, 1 << 5);
+
+       return 0;
+}
+
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+                                       u32 input, u32 output, u32 config)
+{
+       struct au8522_state *state = to_state(sd);
+
+       au8522_reset(sd, 0);
+
+       if (input == AU8522_COMPOSITE_CH1) {
+               au8522_setup_cvbs_mode(state);
+       } else if (input == AU8522_SVIDEO_CH13) {
+               au8522_setup_svideo_mode(state);
+       } else if (input == AU8522_COMPOSITE_CH4_SIF) {
+               au8522_setup_cvbs_tuner_mode(state);
+       } else {
+               printk(KERN_ERR "au8522 mode not currently supported\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int au8522_s_audio_routing(struct v4l2_subdev *sd,
+                                       u32 input, u32 output, u32 config)
+{
+       struct au8522_state *state = to_state(sd);
+       set_audio_input(state, input);
+       return 0;
+}
+
+static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+       int val = 0;
+       struct au8522_state *state = to_state(sd);
+       u8 lock_status;
+
+       /* Interrogate the decoder to see if we are getting a real signal */
+       lock_status = au8522_readreg(state, 0x00);
+       if (lock_status == 0xa2)
+               vt->signal = 0xffff;
+       else
+               vt->signal = 0x00;
+
+       vt->capability |=
+               V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+               V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+       val = V4L2_TUNER_SUB_MONO;
+       vt->rxsubchans = val;
+       vt->audmode = V4L2_TUNER_MODE_STEREO;
+       return 0;
+}
+
+static int au8522_g_chip_ident(struct v4l2_subdev *sd,
+                              struct v4l2_dbg_chip_ident *chip)
+{
+       struct au8522_state *state = to_state(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
+}
+
+static int au8522_log_status(struct v4l2_subdev *sd)
+{
+       /* FIXME: Add some status info here */
+       return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops au8522_core_ops = {
+       .log_status = au8522_log_status,
+       .g_chip_ident = au8522_g_chip_ident,
+       .g_ctrl = au8522_g_ctrl,
+       .s_ctrl = au8522_s_ctrl,
+       .queryctrl = au8522_queryctrl,
+       .reset = au8522_reset,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register = au8522_g_register,
+       .s_register = au8522_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
+       .g_tuner = au8522_g_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
+       .s_routing = au8522_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops au8522_video_ops = {
+       .s_routing = au8522_s_video_routing,
+       .s_stream = au8522_s_stream,
+};
+
+static const struct v4l2_subdev_ops au8522_ops = {
+       .core = &au8522_core_ops,
+       .tuner = &au8522_tuner_ops,
+       .audio = &au8522_audio_ops,
+       .video = &au8522_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct au8522_state *state;
+       struct v4l2_subdev *sd;
+       int instance;
+       struct au8522_config *demod_config;
+
+       /* Check if the adapter supports the needed features */
+       if (!i2c_check_functionality(client->adapter,
+                                    I2C_FUNC_SMBUS_BYTE_DATA)) {
+               return -EIO;
+       }
+
+       /* allocate memory for the internal state */
+       instance = au8522_get_state(&state, client->adapter, client->addr);
+       switch (instance) {
+       case 0:
+               printk(KERN_ERR "au8522_decoder allocation failed\n");
+               return -EIO;
+       case 1:
+               /* new demod instance */
+               printk(KERN_INFO "au8522_decoder creating new instance...\n");
+               break;
+       default:
+               /* existing demod instance */
+               printk(KERN_INFO "au8522_decoder attach existing instance.\n");
+               break;
+       }
+
+       demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+       if (demod_config == NULL) {
+               if (instance == 1)
+                       kfree(state);
+               return -ENOMEM;
+       }
+       demod_config->demod_address = 0x8e >> 1;
+
+       state->config = demod_config;
+       state->i2c = client->adapter;
+
+       sd = &state->sd;
+       v4l2_i2c_subdev_init(sd, client, &au8522_ops);
+
+       state->c = client;
+       state->vid_input = AU8522_COMPOSITE_CH1;
+       state->aud_input = AU8522_AUDIO_NONE;
+       state->id = 8522;
+       state->rev = 0;
+
+       /* Jam open the i2c gate to the tuner */
+       au8522_writereg(state, 0x106, 1);
+
+       return 0;
+}
+
+static int au8522_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+       au8522_release_state(to_state(sd));
+       return 0;
+}
+
+static const struct i2c_device_id au8522_id[] = {
+       {"au8522", 0},
+       {}
+};
+
+MODULE_DEVICE_TABLE(i2c, au8522_id);
+
+static struct i2c_driver au8522_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "au8522",
+       },
+       .probe          = au8522_probe,
+       .remove         = au8522_remove,
+       .id_table       = au8522_id,
+};
+
+module_i2c_driver(au8522_driver);
diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
new file mode 100644 (file)
index 0000000..a68974f
--- /dev/null
@@ -0,0 +1,828 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "au8522_priv.h"
+
+static int debug;
+
+#define dprintk(arg...)\
+       do { if (debug)\
+               printk(arg);\
+       } while (0)
+
+struct mse2snr_tab {
+       u16 val;
+       u16 data;
+};
+
+/* VSB SNR lookup table */
+static struct mse2snr_tab vsb_mse2snr_tab[] = {
+       {   0, 270 },
+       {   2, 250 },
+       {   3, 240 },
+       {   5, 230 },
+       {   7, 220 },
+       {   9, 210 },
+       {  12, 200 },
+       {  13, 195 },
+       {  15, 190 },
+       {  17, 185 },
+       {  19, 180 },
+       {  21, 175 },
+       {  24, 170 },
+       {  27, 165 },
+       {  31, 160 },
+       {  32, 158 },
+       {  33, 156 },
+       {  36, 152 },
+       {  37, 150 },
+       {  39, 148 },
+       {  40, 146 },
+       {  41, 144 },
+       {  43, 142 },
+       {  44, 140 },
+       {  48, 135 },
+       {  50, 130 },
+       {  43, 142 },
+       {  53, 125 },
+       {  56, 120 },
+       { 256, 115 },
+};
+
+/* QAM64 SNR lookup table */
+static struct mse2snr_tab qam64_mse2snr_tab[] = {
+       {  15,   0 },
+       {  16, 290 },
+       {  17, 288 },
+       {  18, 286 },
+       {  19, 284 },
+       {  20, 282 },
+       {  21, 281 },
+       {  22, 279 },
+       {  23, 277 },
+       {  24, 275 },
+       {  25, 273 },
+       {  26, 271 },
+       {  27, 269 },
+       {  28, 268 },
+       {  29, 266 },
+       {  30, 264 },
+       {  31, 262 },
+       {  32, 260 },
+       {  33, 259 },
+       {  34, 258 },
+       {  35, 256 },
+       {  36, 255 },
+       {  37, 254 },
+       {  38, 252 },
+       {  39, 251 },
+       {  40, 250 },
+       {  41, 249 },
+       {  42, 248 },
+       {  43, 246 },
+       {  44, 245 },
+       {  45, 244 },
+       {  46, 242 },
+       {  47, 241 },
+       {  48, 240 },
+       {  50, 239 },
+       {  51, 238 },
+       {  53, 237 },
+       {  54, 236 },
+       {  56, 235 },
+       {  57, 234 },
+       {  59, 233 },
+       {  60, 232 },
+       {  62, 231 },
+       {  63, 230 },
+       {  65, 229 },
+       {  67, 228 },
+       {  68, 227 },
+       {  70, 226 },
+       {  71, 225 },
+       {  73, 224 },
+       {  74, 223 },
+       {  76, 222 },
+       {  78, 221 },
+       {  80, 220 },
+       {  82, 219 },
+       {  85, 218 },
+       {  88, 217 },
+       {  90, 216 },
+       {  92, 215 },
+       {  93, 214 },
+       {  94, 212 },
+       {  95, 211 },
+       {  97, 210 },
+       {  99, 209 },
+       { 101, 208 },
+       { 102, 207 },
+       { 104, 206 },
+       { 107, 205 },
+       { 111, 204 },
+       { 114, 203 },
+       { 118, 202 },
+       { 122, 201 },
+       { 125, 200 },
+       { 128, 199 },
+       { 130, 198 },
+       { 132, 197 },
+       { 256, 190 },
+};
+
+/* QAM256 SNR lookup table */
+static struct mse2snr_tab qam256_mse2snr_tab[] = {
+       {  15,   0 },
+       {  16, 400 },
+       {  17, 398 },
+       {  18, 396 },
+       {  19, 394 },
+       {  20, 392 },
+       {  21, 390 },
+       {  22, 388 },
+       {  23, 386 },
+       {  24, 384 },
+       {  25, 382 },
+       {  26, 380 },
+       {  27, 379 },
+       {  28, 378 },
+       {  29, 377 },
+       {  30, 376 },
+       {  31, 375 },
+       {  32, 374 },
+       {  33, 373 },
+       {  34, 372 },
+       {  35, 371 },
+       {  36, 370 },
+       {  37, 362 },
+       {  38, 354 },
+       {  39, 346 },
+       {  40, 338 },
+       {  41, 330 },
+       {  42, 328 },
+       {  43, 326 },
+       {  44, 324 },
+       {  45, 322 },
+       {  46, 320 },
+       {  47, 319 },
+       {  48, 318 },
+       {  49, 317 },
+       {  50, 316 },
+       {  51, 315 },
+       {  52, 314 },
+       {  53, 313 },
+       {  54, 312 },
+       {  55, 311 },
+       {  56, 310 },
+       {  57, 308 },
+       {  58, 306 },
+       {  59, 304 },
+       {  60, 302 },
+       {  61, 300 },
+       {  62, 298 },
+       {  65, 295 },
+       {  68, 294 },
+       {  70, 293 },
+       {  73, 292 },
+       {  76, 291 },
+       {  78, 290 },
+       {  79, 289 },
+       {  81, 288 },
+       {  82, 287 },
+       {  83, 286 },
+       {  84, 285 },
+       {  85, 284 },
+       {  86, 283 },
+       {  88, 282 },
+       {  89, 281 },
+       { 256, 280 },
+};
+
+static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
+                                u16 *snr)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < sz; i++) {
+               if (mse < tab[i].val) {
+                       *snr = tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       dprintk("%s() snr=%d\n", __func__, *snr);
+       return ret;
+}
+
+static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       u8 r0b5, r0b6, r0b7;
+       char *ifmhz;
+
+       switch (if_freq) {
+       case AU8522_IF_3_25MHZ:
+               ifmhz = "3.25";
+               r0b5 = 0x00;
+               r0b6 = 0x3d;
+               r0b7 = 0xa0;
+               break;
+       case AU8522_IF_4MHZ:
+               ifmhz = "4.00";
+               r0b5 = 0x00;
+               r0b6 = 0x4b;
+               r0b7 = 0xd9;
+               break;
+       case AU8522_IF_6MHZ:
+               ifmhz = "6.00";
+               r0b5 = 0xfb;
+               r0b6 = 0x8e;
+               r0b7 = 0x39;
+               break;
+       default:
+               dprintk("%s() IF Frequency not supported\n", __func__);
+               return -EINVAL;
+       }
+       dprintk("%s() %s MHz\n", __func__, ifmhz);
+       au8522_writereg(state, 0x80b5, r0b5);
+       au8522_writereg(state, 0x80b6, r0b6);
+       au8522_writereg(state, 0x80b7, r0b7);
+
+       return 0;
+}
+
+/* VSB Modulation table */
+static struct {
+       u16 reg;
+       u16 data;
+} VSB_mod_tab[] = {
+       { 0x8090, 0x84 },
+       { 0x4092, 0x11 },
+       { 0x2005, 0x00 },
+       { 0x8091, 0x80 },
+       { 0x80a3, 0x0c },
+       { 0x80a4, 0xe8 },
+       { 0x8081, 0xc4 },
+       { 0x80a5, 0x40 },
+       { 0x80a7, 0x40 },
+       { 0x80a6, 0x67 },
+       { 0x8262, 0x20 },
+       { 0x821c, 0x30 },
+       { 0x80d8, 0x1a },
+       { 0x8227, 0xa0 },
+       { 0x8121, 0xff },
+       { 0x80a8, 0xf0 },
+       { 0x80a9, 0x05 },
+       { 0x80aa, 0x77 },
+       { 0x80ab, 0xf0 },
+       { 0x80ac, 0x05 },
+       { 0x80ad, 0x77 },
+       { 0x80ae, 0x41 },
+       { 0x80af, 0x66 },
+       { 0x821b, 0xcc },
+       { 0x821d, 0x80 },
+       { 0x80a4, 0xe8 },
+       { 0x8231, 0x13 },
+};
+
+/* QAM64 Modulation table */
+static struct {
+       u16 reg;
+       u16 data;
+} QAM64_mod_tab[] = {
+       { 0x00a3, 0x09 },
+       { 0x00a4, 0x00 },
+       { 0x0081, 0xc4 },
+       { 0x00a5, 0x40 },
+       { 0x00aa, 0x77 },
+       { 0x00ad, 0x77 },
+       { 0x00a6, 0x67 },
+       { 0x0262, 0x20 },
+       { 0x021c, 0x30 },
+       { 0x00b8, 0x3e },
+       { 0x00b9, 0xf0 },
+       { 0x00ba, 0x01 },
+       { 0x00bb, 0x18 },
+       { 0x00bc, 0x50 },
+       { 0x00bd, 0x00 },
+       { 0x00be, 0xea },
+       { 0x00bf, 0xef },
+       { 0x00c0, 0xfc },
+       { 0x00c1, 0xbd },
+       { 0x00c2, 0x1f },
+       { 0x00c3, 0xfc },
+       { 0x00c4, 0xdd },
+       { 0x00c5, 0xaf },
+       { 0x00c6, 0x00 },
+       { 0x00c7, 0x38 },
+       { 0x00c8, 0x30 },
+       { 0x00c9, 0x05 },
+       { 0x00ca, 0x4a },
+       { 0x00cb, 0xd0 },
+       { 0x00cc, 0x01 },
+       { 0x00cd, 0xd9 },
+       { 0x00ce, 0x6f },
+       { 0x00cf, 0xf9 },
+       { 0x00d0, 0x70 },
+       { 0x00d1, 0xdf },
+       { 0x00d2, 0xf7 },
+       { 0x00d3, 0xc2 },
+       { 0x00d4, 0xdf },
+       { 0x00d5, 0x02 },
+       { 0x00d6, 0x9a },
+       { 0x00d7, 0xd0 },
+       { 0x0250, 0x0d },
+       { 0x0251, 0xcd },
+       { 0x0252, 0xe0 },
+       { 0x0253, 0x05 },
+       { 0x0254, 0xa7 },
+       { 0x0255, 0xff },
+       { 0x0256, 0xed },
+       { 0x0257, 0x5b },
+       { 0x0258, 0xae },
+       { 0x0259, 0xe6 },
+       { 0x025a, 0x3d },
+       { 0x025b, 0x0f },
+       { 0x025c, 0x0d },
+       { 0x025d, 0xea },
+       { 0x025e, 0xf2 },
+       { 0x025f, 0x51 },
+       { 0x0260, 0xf5 },
+       { 0x0261, 0x06 },
+       { 0x021a, 0x00 },
+       { 0x0546, 0x40 },
+       { 0x0210, 0xc7 },
+       { 0x0211, 0xaa },
+       { 0x0212, 0xab },
+       { 0x0213, 0x02 },
+       { 0x0502, 0x00 },
+       { 0x0121, 0x04 },
+       { 0x0122, 0x04 },
+       { 0x052e, 0x10 },
+       { 0x00a4, 0xca },
+       { 0x00a7, 0x40 },
+       { 0x0526, 0x01 },
+};
+
+/* QAM256 Modulation table */
+static struct {
+       u16 reg;
+       u16 data;
+} QAM256_mod_tab[] = {
+       { 0x80a3, 0x09 },
+       { 0x80a4, 0x00 },
+       { 0x8081, 0xc4 },
+       { 0x80a5, 0x40 },
+       { 0x80aa, 0x77 },
+       { 0x80ad, 0x77 },
+       { 0x80a6, 0x67 },
+       { 0x8262, 0x20 },
+       { 0x821c, 0x30 },
+       { 0x80b8, 0x3e },
+       { 0x80b9, 0xf0 },
+       { 0x80ba, 0x01 },
+       { 0x80bb, 0x18 },
+       { 0x80bc, 0x50 },
+       { 0x80bd, 0x00 },
+       { 0x80be, 0xea },
+       { 0x80bf, 0xef },
+       { 0x80c0, 0xfc },
+       { 0x80c1, 0xbd },
+       { 0x80c2, 0x1f },
+       { 0x80c3, 0xfc },
+       { 0x80c4, 0xdd },
+       { 0x80c5, 0xaf },
+       { 0x80c6, 0x00 },
+       { 0x80c7, 0x38 },
+       { 0x80c8, 0x30 },
+       { 0x80c9, 0x05 },
+       { 0x80ca, 0x4a },
+       { 0x80cb, 0xd0 },
+       { 0x80cc, 0x01 },
+       { 0x80cd, 0xd9 },
+       { 0x80ce, 0x6f },
+       { 0x80cf, 0xf9 },
+       { 0x80d0, 0x70 },
+       { 0x80d1, 0xdf },
+       { 0x80d2, 0xf7 },
+       { 0x80d3, 0xc2 },
+       { 0x80d4, 0xdf },
+       { 0x80d5, 0x02 },
+       { 0x80d6, 0x9a },
+       { 0x80d7, 0xd0 },
+       { 0x8250, 0x0d },
+       { 0x8251, 0xcd },
+       { 0x8252, 0xe0 },
+       { 0x8253, 0x05 },
+       { 0x8254, 0xa7 },
+       { 0x8255, 0xff },
+       { 0x8256, 0xed },
+       { 0x8257, 0x5b },
+       { 0x8258, 0xae },
+       { 0x8259, 0xe6 },
+       { 0x825a, 0x3d },
+       { 0x825b, 0x0f },
+       { 0x825c, 0x0d },
+       { 0x825d, 0xea },
+       { 0x825e, 0xf2 },
+       { 0x825f, 0x51 },
+       { 0x8260, 0xf5 },
+       { 0x8261, 0x06 },
+       { 0x821a, 0x00 },
+       { 0x8546, 0x40 },
+       { 0x8210, 0x26 },
+       { 0x8211, 0xf6 },
+       { 0x8212, 0x84 },
+       { 0x8213, 0x02 },
+       { 0x8502, 0x01 },
+       { 0x8121, 0x04 },
+       { 0x8122, 0x04 },
+       { 0x852e, 0x10 },
+       { 0x80a4, 0xca },
+       { 0x80a7, 0x40 },
+       { 0x8526, 0x01 },
+};
+
+static int au8522_enable_modulation(struct dvb_frontend *fe,
+                                   fe_modulation_t m)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       int i;
+
+       dprintk("%s(0x%08x)\n", __func__, m);
+
+       switch (m) {
+       case VSB_8:
+               dprintk("%s() VSB_8\n", __func__);
+               for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
+                       au8522_writereg(state,
+                               VSB_mod_tab[i].reg,
+                               VSB_mod_tab[i].data);
+               au8522_set_if(fe, state->config->vsb_if);
+               break;
+       case QAM_64:
+               dprintk("%s() QAM 64\n", __func__);
+               for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++)
+                       au8522_writereg(state,
+                               QAM64_mod_tab[i].reg,
+                               QAM64_mod_tab[i].data);
+               au8522_set_if(fe, state->config->qam_if);
+               break;
+       case QAM_256:
+               dprintk("%s() QAM 256\n", __func__);
+               for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
+                       au8522_writereg(state,
+                               QAM256_mod_tab[i].reg,
+                               QAM256_mod_tab[i].data);
+               au8522_set_if(fe, state->config->qam_if);
+               break;
+       default:
+               dprintk("%s() Invalid modulation\n", __func__);
+               return -EINVAL;
+       }
+
+       state->current_modulation = m;
+
+       return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int au8522_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct au8522_state *state = fe->demodulator_priv;
+       int ret = -EINVAL;
+
+       dprintk("%s(frequency=%d)\n", __func__, c->frequency);
+
+       if ((state->current_frequency == c->frequency) &&
+           (state->current_modulation == c->modulation))
+               return 0;
+
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       if (ret < 0)
+               return ret;
+
+       /* Allow the tuner to settle */
+       msleep(100);
+
+       au8522_enable_modulation(fe, c->modulation);
+
+       state->current_frequency = c->frequency;
+
+       return 0;
+}
+
+static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       u8 reg;
+       u32 tuner_status = 0;
+
+       *status = 0;
+
+       if (state->current_modulation == VSB_8) {
+               dprintk("%s() Checking VSB_8\n", __func__);
+               reg = au8522_readreg(state, 0x4088);
+               if ((reg & 0x03) == 0x03)
+                       *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+       } else {
+               dprintk("%s() Checking QAM\n", __func__);
+               reg = au8522_readreg(state, 0x4541);
+               if (reg & 0x80)
+                       *status |= FE_HAS_VITERBI;
+               if (reg & 0x20)
+                       *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+       }
+
+       switch (state->config->status_mode) {
+       case AU8522_DEMODLOCKING:
+               dprintk("%s() DEMODLOCKING\n", __func__);
+               if (*status & FE_HAS_VITERBI)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       case AU8522_TUNERLOCKING:
+               /* Get the tuner status */
+               dprintk("%s() TUNERLOCKING\n", __func__);
+               if (fe->ops.tuner_ops.get_status) {
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 1);
+
+                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               if (tuner_status)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       }
+       state->fe_status = *status;
+
+       if (*status & FE_HAS_LOCK)
+               /* turn on LED, if it isn't on already */
+               au8522_led_ctrl(state, -1);
+       else
+               /* turn off LED */
+               au8522_led_ctrl(state, 0);
+
+       dprintk("%s() status 0x%08x\n", __func__, *status);
+
+       return 0;
+}
+
+static int au8522_led_status(struct au8522_state *state, const u16 *snr)
+{
+       struct au8522_led_config *led_config = state->config->led_cfg;
+       int led;
+       u16 strong;
+
+       /* bail out if we can't control an LED */
+       if (!led_config)
+               return 0;
+
+       if (0 == (state->fe_status & FE_HAS_LOCK))
+               return au8522_led_ctrl(state, 0);
+       else if (state->current_modulation == QAM_256)
+               strong = led_config->qam256_strong;
+       else if (state->current_modulation == QAM_64)
+               strong = led_config->qam64_strong;
+       else /* (state->current_modulation == VSB_8) */
+               strong = led_config->vsb8_strong;
+
+       if (*snr >= strong)
+               led = 2;
+       else
+               led = 1;
+
+       if ((state->led_state) &&
+           (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
+               /* snr didn't change enough to bother
+                * changing the color of the led */
+               return 0;
+
+       return au8522_led_ctrl(state, led);
+}
+
+static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       int ret = -EINVAL;
+
+       dprintk("%s()\n", __func__);
+
+       if (state->current_modulation == QAM_256)
+               ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
+                                           ARRAY_SIZE(qam256_mse2snr_tab),
+                                           au8522_readreg(state, 0x4522),
+                                           snr);
+       else if (state->current_modulation == QAM_64)
+               ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
+                                           ARRAY_SIZE(qam64_mse2snr_tab),
+                                           au8522_readreg(state, 0x4522),
+                                           snr);
+       else /* VSB_8 */
+               ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
+                                           ARRAY_SIZE(vsb_mse2snr_tab),
+                                           au8522_readreg(state, 0x4311),
+                                           snr);
+
+       if (state->config->led_cfg)
+               au8522_led_status(state, snr);
+
+       return ret;
+}
+
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+                                      u16 *signal_strength)
+{
+       /* borrowed from lgdt330x.c
+        *
+        * Calculate strength from SNR up to 35dB
+        * Even though the SNR can go higher than 35dB,
+        * there is some comfort factor in having a range of
+        * strong signals that can show at 100%
+        */
+       u16 snr;
+       u32 tmp;
+       int ret = au8522_read_snr(fe, &snr);
+
+       *signal_strength = 0;
+
+       if (0 == ret) {
+               /* The following calculation method was chosen
+                * purely for the sake of code re-use from the
+                * other demod drivers that use this method */
+
+               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
+               tmp = (snr * ((1 << 24) / 10));
+
+               /* Convert from 8.24 fixed-point to
+                * scale the range 0 - 35*2^24 into 0 - 65535*/
+               if (tmp >= 8960 * 0x10000)
+                       *signal_strength = 0xffff;
+               else
+                       *signal_strength = tmp / 8960;
+       }
+
+       return ret;
+}
+
+static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+
+       if (state->current_modulation == VSB_8)
+               *ucblocks = au8522_readreg(state, 0x4087);
+       else
+               *ucblocks = au8522_readreg(state, 0x4543);
+
+       return 0;
+}
+
+static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       return au8522_read_ucblocks(fe, ber);
+}
+
+static int au8522_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct au8522_state *state = fe->demodulator_priv;
+
+       c->frequency = state->current_frequency;
+       c->modulation = state->current_modulation;
+
+       return 0;
+}
+
+static int au8522_get_tune_settings(struct dvb_frontend *fe,
+                                   struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static struct dvb_frontend_ops au8522_ops;
+
+
+static void au8522_release(struct dvb_frontend *fe)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       au8522_release_state(state);
+}
+
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       struct au8522_state *state = NULL;
+       int instance;
+
+       /* allocate memory for the internal state */
+       instance = au8522_get_state(&state, i2c, config->demod_address);
+       switch (instance) {
+       case 0:
+               dprintk("%s state allocation failed\n", __func__);
+               break;
+       case 1:
+               /* new demod instance */
+               dprintk("%s using new instance\n", __func__);
+               break;
+       default:
+               /* existing demod instance */
+               dprintk("%s using existing instance\n", __func__);
+               break;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->operational_mode = AU8522_DIGITAL_MODE;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &au8522_ops,
+              sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       state->frontend.ops.analog_ops.i2c_gate_ctrl = au8522_analog_i2c_gate_ctrl;
+
+       if (au8522_init(&state->frontend) != 0) {
+               printk(KERN_ERR "%s: Failed to initialize correctly\n",
+                       __func__);
+               goto error;
+       }
+
+       /* Note: Leaving the I2C gate open here. */
+       au8522_i2c_gate_ctrl(&state->frontend, 1);
+
+       return &state->frontend;
+
+error:
+       au8522_release_state(state);
+       return NULL;
+}
+EXPORT_SYMBOL(au8522_attach);
+
+static struct dvb_frontend_ops au8522_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name                   = "Auvitek AU8522 QAM/8VSB Frontend",
+               .frequency_min          = 54000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .init                 = au8522_init,
+       .sleep                = au8522_sleep,
+       .i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
+       .set_frontend         = au8522_set_frontend,
+       .get_frontend         = au8522_get_frontend,
+       .get_tune_settings    = au8522_get_tune_settings,
+       .read_status          = au8522_read_status,
+       .read_ber             = au8522_read_ber,
+       .read_signal_strength = au8522_read_signal_strength,
+       .read_snr             = au8522_read_snr,
+       .read_ucblocks        = au8522_read_ucblocks,
+       .release              = au8522_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
new file mode 100644 (file)
index 0000000..0529699
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+    Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+    Copyright (C) 2005-2008 Auvitek International, Ltd.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "tuner-i2c.h"
+
+#define AU8522_ANALOG_MODE 0
+#define AU8522_DIGITAL_MODE 1
+
+struct au8522_state {
+       struct i2c_client *c;
+       struct i2c_adapter *i2c;
+
+       u8 operational_mode;
+
+       /* Used for sharing of the state between analog and digital mode */
+       struct tuner_i2c_props i2c_props;
+       struct list_head hybrid_tuner_instance_list;
+
+       /* configuration settings */
+       const struct au8522_config *config;
+
+       struct dvb_frontend frontend;
+
+       u32 current_frequency;
+       fe_modulation_t current_modulation;
+
+       u32 fe_status;
+       unsigned int led_state;
+
+       /* Analog settings */
+       struct v4l2_subdev sd;
+       v4l2_std_id std;
+       int vid_input;
+       int aud_input;
+       u32 id;
+       u32 rev;
+       u8 brightness;
+       u8 contrast;
+       u8 saturation;
+       s16 hue;
+};
+
+/* These are routines shared by both the VSB/QAM demodulator and the analog
+   decoder */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
+u8 au8522_readreg(struct au8522_state *state, u16 reg);
+int au8522_init(struct dvb_frontend *fe);
+int au8522_sleep(struct dvb_frontend *fe);
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+                    u8 client_address);
+void au8522_release_state(struct au8522_state *state);
+int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+int au8522_led_ctrl(struct au8522_state *state, int led);
+
+/* REGISTERS */
+#define AU8522_INPUT_CONTROL_REG081H                   0x081
+#define AU8522_PGA_CONTROL_REG082H                     0x082
+#define AU8522_CLAMPING_CONTROL_REG083H                        0x083
+
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H            0x0A3
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H         0x0A4
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H         0x0A5
+#define AU8522_AGC_CONTROL_RANGE_REG0A6H               0x0A6
+#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H             0x0A7
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H               0x0A8
+#define AU8522_TUNER_AGC_RF_START_REG0A9H              0x0A9
+#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH            0x0AA
+#define AU8522_TUNER_AGC_IF_STOP_REG0ABH               0x0AB
+#define AU8522_TUNER_AGC_IF_START_REG0ACH              0x0AC
+#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH            0x0AD
+#define AU8522_TUNER_AGC_STEP_REG0AEH                  0x0AE
+#define AU8522_TUNER_GAIN_STEP_REG0AFH                 0x0AF
+
+/* Receiver registers */
+#define AU8522_FRMREGTHRD1_REG0B0H                     0x0B0
+#define AU8522_FRMREGAGC1H_REG0B1H                     0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H                    0x0B2
+#define AU8522_TOREGAGC1_REG0B3H                       0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H                    0x0B4
+#define AU8522_FRMREGBBH_REG0B5H                       0x0B5
+#define AU8522_FRMREGBBM_REG0B6H                       0x0B6
+#define AU8522_FRMREGBBL_REG0B7H                       0x0B7
+/* 0xB8 TO 0xD7 are the filter coefficients */
+#define AU8522_FRMREGTHRD2_REG0D8H                     0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H                     0x0D9
+#define AU8522_TOREGAGC2_REG0DAH                       0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH                     0x0DB
+#define AU8522_FRMREGPILOTH_REG0DCH                    0x0DC
+#define AU8522_FRMREGPILOTM_REG0DDH                    0x0DD
+#define AU8522_FRMREGPILOTL_REG0DEH                    0x0DE
+#define AU8522_TOREGFREQ_REG0DFH                       0x0DF
+
+#define AU8522_RX_PGA_RFOUT_REG0EBH                    0x0EB
+#define AU8522_RX_PGA_IFOUT_REG0ECH                    0x0EC
+#define AU8522_RX_PGA_PGAOUT_REG0EDH                   0x0ED
+
+#define AU8522_CHIP_MODE_REG0FEH                       0x0FE
+
+/* I2C bus control registers */
+#define AU8522_I2C_CONTROL_REG0_REG090H                0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H                0x091
+#define AU8522_I2C_STATUS_REG092H                      0x092
+#define AU8522_I2C_WR_DATA0_REG093H                    0x093
+#define AU8522_I2C_WR_DATA1_REG094H                    0x094
+#define AU8522_I2C_WR_DATA2_REG095H                    0x095
+#define AU8522_I2C_WR_DATA3_REG096H                    0x096
+#define AU8522_I2C_WR_DATA4_REG097H                    0x097
+#define AU8522_I2C_WR_DATA5_REG098H                    0x098
+#define AU8522_I2C_WR_DATA6_REG099H                    0x099
+#define AU8522_I2C_WR_DATA7_REG09AH                    0x09A
+#define AU8522_I2C_RD_DATA0_REG09BH                    0x09B
+#define AU8522_I2C_RD_DATA1_REG09CH                    0x09C
+#define AU8522_I2C_RD_DATA2_REG09DH                    0x09D
+#define AU8522_I2C_RD_DATA3_REG09EH                    0x09E
+#define AU8522_I2C_RD_DATA4_REG09FH                    0x09F
+#define AU8522_I2C_RD_DATA5_REG0A0H                    0x0A0
+#define AU8522_I2C_RD_DATA6_REG0A1H                    0x0A1
+#define AU8522_I2C_RD_DATA7_REG0A2H                    0x0A2
+
+#define AU8522_ENA_USB_REG101H                         0x101
+
+#define AU8522_I2S_CTRL_0_REG110H                      0x110
+#define AU8522_I2S_CTRL_1_REG111H                      0x111
+#define AU8522_I2S_CTRL_2_REG112H                      0x112
+
+#define AU8522_FRMREGFFECONTROL_REG121H                0x121
+#define AU8522_FRMREGDFECONTROL_REG122H                0x122
+
+#define AU8522_CARRFREQOFFSET0_REG201H                         0x201
+#define AU8522_CARRFREQOFFSET1_REG202H                 0x202
+
+#define AU8522_DECIMATION_GAIN_REG21AH                 0x21A
+#define AU8522_FRMREGIFSLP_REG21BH                     0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH                    0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH                   0x21D
+#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH            0x21E
+#define AU8522_FRMREGPLLMODE_REG21FH                   0x21F
+#define AU8522_FRMREGCSTHRD_REG220H                    0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H                0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H              0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H                0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H                0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H                0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H                0x226
+#define AU_FRMREGPLLACQPHASESCL_REG227H                        0x227
+#define AU8522_FRMREGFREQFBCTRL_REG228H                0x228
+
+/* Analog TV Decoder */
+#define AU8522_TVDEC_STATUS_REG000H                    0x000
+#define AU8522_TVDEC_INT_STATUS_REG001H                        0x001
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H        0x002
+#define AU8522_TVDEC_SHARPNESSREG009H                  0x009
+#define AU8522_TVDEC_BRIGHTNESS_REG00AH                        0x00A
+#define AU8522_TVDEC_CONTRAST_REG00BH                  0x00B
+#define AU8522_TVDEC_SATURATION_CB_REG00CH             0x00C
+#define AU8522_TVDEC_SATURATION_CR_REG00DH             0x00D
+#define AU8522_TVDEC_HUE_H_REG00EH                     0x00E
+#define AU8522_TVDEC_HUE_L_REG00FH                     0x00F
+#define AU8522_TVDEC_INT_MASK_REG010H                  0x010
+#define AU8522_VIDEO_MODE_REG011H                      0x011
+#define AU8522_TVDEC_PGA_REG012H                       0x012
+#define AU8522_TVDEC_COMB_MODE_REG015H                 0x015
+#define AU8522_REG016H                                 0x016
+#define AU8522_TVDED_DBG_MODE_REG060H                  0x060
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H              0x061
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H              0x062
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H              0x063
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H              0x064
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H            0x065
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H            0x066
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H            0x067
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H            0x068
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H            0x069
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH            0x06A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH            0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH           0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH           0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH           0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH                0x06F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H         0x070
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H         0x073
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H                        0x077
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H             0x078
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H            0x079
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH      0x07A
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH                        0x07B
+#define AU8522_TVDEC_PLL_STATUS_REG07EH                        0x07E
+#define AU8522_TVDEC_FSC_FREQ_REG07FH                  0x07F
+
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H             0x0E4
+#define AU8522_TOREGAAGC_REG0E5H                       0x0E5
+
+#define AU8522_TVDEC_CHROMA_AGC_REG401H                0x401
+#define AU8522_TVDEC_CHROMA_SFT_REG402H                0x402
+#define AU8522_FILTER_COEF_R410                0x410
+#define AU8522_FILTER_COEF_R411                0x411
+#define AU8522_FILTER_COEF_R412                0x412
+#define AU8522_FILTER_COEF_R413                0x413
+#define AU8522_FILTER_COEF_R414                0x414
+#define AU8522_FILTER_COEF_R415                0x415
+#define AU8522_FILTER_COEF_R416                0x416
+#define AU8522_FILTER_COEF_R417                0x417
+#define AU8522_FILTER_COEF_R418                0x418
+#define AU8522_FILTER_COEF_R419                0x419
+#define AU8522_FILTER_COEF_R41A                0x41A
+#define AU8522_FILTER_COEF_R41B                0x41B
+#define AU8522_FILTER_COEF_R41C                0x41C
+#define AU8522_FILTER_COEF_R41D                0x41D
+#define AU8522_FILTER_COEF_R41E                0x41E
+#define AU8522_FILTER_COEF_R41F                0x41F
+#define AU8522_FILTER_COEF_R420                0x420
+#define AU8522_FILTER_COEF_R421                0x421
+#define AU8522_FILTER_COEF_R422                0x422
+#define AU8522_FILTER_COEF_R423                0x423
+#define AU8522_FILTER_COEF_R424                0x424
+#define AU8522_FILTER_COEF_R425                0x425
+#define AU8522_FILTER_COEF_R426                0x426
+#define AU8522_FILTER_COEF_R427                0x427
+#define AU8522_FILTER_COEF_R428                0x428
+#define AU8522_FILTER_COEF_R429                0x429
+#define AU8522_FILTER_COEF_R42A                0x42A
+#define AU8522_FILTER_COEF_R42B                0x42B
+#define AU8522_FILTER_COEF_R42C                0x42C
+#define AU8522_FILTER_COEF_R42D                0x42D
+
+/* VBI Control Registers */
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H       0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H       0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H          0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H           0x007
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H                        0x017
+#define AU8522_TVDEC_VBI_CTRL_L_REG018H                        0x018
+#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H       0x019
+#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH          0x01A
+#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH          0x01B
+#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH          0x01C
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH       0x01E
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH       0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H       0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H      0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H      0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H      0x023
+
+#define AU8522_REG071H                                 0x071
+#define AU8522_REG072H                                 0x072
+#define AU8522_REG074H                                 0x074
+#define AU8522_REG075H                                 0x075
+
+/* Digital Demodulator Registers */
+#define AU8522_FRAME_COUNT0_REG084H                    0x084
+#define AU8522_RS_STATUS_G0_REG085H                    0x085
+#define AU8522_RS_STATUS_B0_REG086H                    0x086
+#define AU8522_RS_STATUS_E_REG087H                     0x087
+#define AU8522_DEMODULATION_STATUS_REG088H             0x088
+#define AU8522_TOREGTRESTATUS_REG0E6H                  0x0E6
+#define AU8522_TSPORT_CONTROL_REG10BH                  0x10B
+#define AU8522_TSTHES_REG10CH                          0x10C
+#define AU8522_FRMREGDFEKEEP_REG301H                   0x301
+#define AU8522_DFE_AVERAGE_REG302H                     0x302
+#define AU8522_FRMREGEQLERRWIN_REG303H                 0x303
+#define AU8522_FRMREGFFEKEEP_REG304H                   0x304
+#define AU8522_FRMREGDFECONTROL1_REG305H               0x305
+#define AU8522_FRMREGEQLERRLOW_REG306H                 0x306
+
+#define AU8522_REG42EH                         0x42E
+#define AU8522_REG42FH                         0x42F
+#define AU8522_REG430H                         0x430
+#define AU8522_REG431H                         0x431
+#define AU8522_REG432H                         0x432
+#define AU8522_REG433H                         0x433
+#define AU8522_REG434H                         0x434
+#define AU8522_REG435H                         0x435
+#define AU8522_REG436H                         0x436
+
+/* GPIO Registers */
+#define AU8522_GPIO_CONTROL_REG0E0H                    0x0E0
+#define AU8522_GPIO_STATUS_REG0E1H                     0x0E1
+#define AU8522_GPIO_DATA_REG0E2H                       0x0E2
+
+/* Audio Control Registers */
+#define AU8522_AUDIOAGC_REG0EEH                        0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H                    0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H                      0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H                  0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H                  0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H                    0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H                   0x0F7
+#define AU8522_REG0F9H                                 0x0F9
+
+#define AU8522_AUDIOAGC2_REG605H                       0x605
+#define AU8522_AUDIOFREQ_REG606H                       0x606
+
+
+/**************************************************************/
+
+/* Format control 1 */
+
+/* VCR Mode 7-6 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_YES         0x80
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_NO          0x40
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_AUTO                0x00
+/* Field len 5-4 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_625                0x20
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525                0x10
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_AUTO       0x00
+/* Line len (us) 3-2 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_64_000      0x0b
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492      0x08
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_556      0x04
+/* Subcarrier freq 1-0 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO 0x03
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_443  0x02
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN   0x01
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_50   0x00
+
+/* Format control 2 */
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT       0x00
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC             0x01
+
+
+#define AU8522_INPUT_CONTROL_REG081H_ATSC                      0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF                     0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF13                   0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B64                    0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256                   0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS                      0x20
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1                  0xA2
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2                  0xA0
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3                  0x69
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4                  0x68
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF              0x28
+/* CH1 AS Y,CH3 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13               0x23
+/* CH2 AS Y,CH4 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24               0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC               0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64             0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256                    0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS               0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF              0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13            0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO             0x02
+
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR           0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO          0x9C
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS            0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC            0xE8
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256                 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64                  0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF                   0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13         0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL             0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM              0xDD
+
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC            0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256                 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64                  0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC     0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256  0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64   0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR    0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF           0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13         0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO                  0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS            0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM                     0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS             0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL             0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM              0x01
+
+/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
+#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS                     0x79
+#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS                        0x80
+#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS                        0x80
+#define AU8522_TVDEC_HUE_H_REG00EH_CVBS                                0x00
+#define AU8522_TVDEC_HUE_L_REG00FH_CVBS                                0x00
+#define AU8522_TVDEC_PGA_REG012H_CVBS                          0x0F
+#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS                    0x00
+#define AU8522_REG016H_CVBS                                    0x00
+#define AU8522_TVDED_DBG_MODE_REG060H_CVBS                     0x00
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS                 0x19
+#define AU8522_REG0F9H_AUDIO                                   0x20
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS                 0xA7
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS               0x0A
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS               0x32
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS               0x19
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS               0x23
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS               0x41
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS               0x0A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS               0x32
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS              0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO            0x2a
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS              0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO            0x15
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS              0x6E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS                   0x0F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS            0x80
+#define AU8522_REG071H_CVBS                                    0x18
+#define AU8522_REG072H_CVBS                                    0x30
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS            0xF0
+#define AU8522_REG074H_CVBS                                    0x80
+#define AU8522_REG075H_CVBS                                    0xF0
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS                   0xFB
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS                        0x04
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS               0x00
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS         0x00
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS                   0xEE
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS                        0xFE
+#define AU8522_TOREGAAGC_REG0E5H_CVBS                          0x00
+#define AU8522_TVDEC_VBI6A_REG035H_CVBS                                0x40
+
+/* Enables Closed captioning */
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON                   0x21
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
new file mode 100644 (file)
index 0000000..033cd7a
--- /dev/null
@@ -0,0 +1,856 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ *  This driver is "hard-coded" to be used with the 1st generation of
+ *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
+ *  (Panasonic CT10S) is located here, which is actually wrong. Unless there is
+ *  another device with a BCM3510, this is no problem.
+ *
+ *  The driver works also with QAM64 DVB-C, but had an unreasonable high
+ *  UNC. (Tested with the Air2PC ATSC 1st generation)
+ *
+ *  You'll need a firmware for this driver in order to get it running. It is
+ *  called "dvb-fe-bcm3510-01.fw".
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+
+#include "dvb_frontend.h"
+#include "bcm3510.h"
+#include "bcm3510_priv.h"
+
+struct bcm3510_state {
+
+       struct i2c_adapter* i2c;
+       const struct bcm3510_config* config;
+       struct dvb_frontend frontend;
+
+       /* demodulator private data */
+       struct mutex hab_mutex;
+       u8 firmware_loaded:1;
+
+       unsigned long next_status_check;
+       unsigned long status_check_interval;
+       struct bcm3510_hab_cmd_status1 status1;
+       struct bcm3510_hab_cmd_status2 status2;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
+
+#define dprintk(level,x...) if (level & debug) printk(x)
+#define dbufout(b,l,m) {\
+           int i; \
+           for (i = 0; i < l; i++) \
+               m("%02x ",b[i]); \
+}
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_i2c(args...)  dprintk(0x02,args)
+#define deb_hab(args...)  dprintk(0x04,args)
+
+/* transfer functions */
+static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+       u8 b[256];
+       int err;
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
+
+       b[0] = reg;
+       memcpy(&b[1],buf,len);
+
+       deb_i2c("i2c wr %02x: ",reg);
+       dbufout(buf,len,deb_i2c);
+       deb_i2c("\n");
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+
+               deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
+                       __func__, state->config->demod_address, reg,  err);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf,  .len = len }
+       };
+       int err;
+
+       memset(buf,0,len);
+
+       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+               deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
+                       __func__, state->config->demod_address, reg,  err);
+               return -EREMOTEIO;
+       }
+       deb_i2c("i2c rd %02x: ",reg);
+       dbufout(buf,len,deb_i2c);
+       deb_i2c("\n");
+
+       return 0;
+}
+
+static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
+{
+       return bcm3510_writebytes(state,reg,&v.raw,1);
+}
+
+static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
+{
+       return bcm3510_readbytes(state,reg,&v->raw,1);
+}
+
+/* Host Access Buffer transfers */
+static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
+{
+       bcm3510_register_value v;
+       int ret,i;
+
+       v.HABADR_a6.HABADR = 0;
+       if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
+               return ret;
+
+       for (i = 0; i < len; i++) {
+               if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
+                       return ret;
+               buf[i] = v.HABDATA_a7;
+       }
+       return 0;
+}
+
+static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
+{
+       bcm3510_register_value v,hab;
+       int ret,i;
+       unsigned long t;
+
+/* Check if any previous HAB request still needs to be serviced by the
+ * Acquisition Processor before sending new request */
+       if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+               return ret;
+       if (v.HABSTAT_a8.HABR) {
+               deb_info("HAB is running already - clearing it.\n");
+               v.HABSTAT_a8.HABR = 0;
+               bcm3510_writeB(st,0xa8,v);
+//             return -EBUSY;
+       }
+
+/* Send the start HAB Address (automatically incremented after write of
+ * HABDATA) and write the HAB Data */
+       hab.HABADR_a6.HABADR = 0;
+       if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
+               return ret;
+
+       for (i = 0; i < len; i++) {
+               hab.HABDATA_a7 = buf[i];
+               if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
+                       return ret;
+       }
+
+/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
+ * be written) */
+       v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
+       if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
+               return ret;
+
+/* Polling method: Wait until the AP finishes processing the HAB request */
+       t = jiffies + 1*HZ;
+       while (time_before(jiffies, t)) {
+               deb_info("waiting for HAB to complete\n");
+               msleep(10);
+               if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+                       return ret;
+
+               if (!v.HABSTAT_a8.HABR)
+                       return 0;
+       }
+
+       deb_info("send_request execution timed out.\n");
+       return -ETIMEDOUT;
+}
+
+static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
+{
+       u8 ob[olen+2],ib[ilen+2];
+       int ret = 0;
+
+       ob[0] = cmd;
+       ob[1] = msgid;
+       memcpy(&ob[2],obuf,olen);
+
+       deb_hab("hab snd: ");
+       dbufout(ob,olen+2,deb_hab);
+       deb_hab("\n");
+
+       if (mutex_lock_interruptible(&st->hab_mutex) < 0)
+               return -EAGAIN;
+
+       if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
+               (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
+               goto error;
+
+       deb_hab("hab get: ");
+       dbufout(ib,ilen+2,deb_hab);
+       deb_hab("\n");
+
+       memcpy(ibuf,&ib[2],ilen);
+error:
+       mutex_unlock(&st->hab_mutex);
+       return ret;
+}
+
+#if 0
+/* not needed, we use a semaphore to prevent HAB races */
+static int bcm3510_is_ap_ready(struct bcm3510_state *st)
+{
+       bcm3510_register_value ap,hab;
+       int ret;
+
+       if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
+               (ret = bcm3510_readB(st,0xa2,&ap) < 0))
+               return ret;
+
+       if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
+               deb_info("AP is busy\n");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+#endif
+
+static int bcm3510_bert_reset(struct bcm3510_state *st)
+{
+       bcm3510_register_value b;
+       int ret;
+
+       if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
+               return ret;
+
+       b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+       b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
+       b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+       b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
+
+       /* clear residual bit counter TODO  */
+       return 0;
+}
+
+static int bcm3510_refresh_state(struct bcm3510_state *st)
+{
+       if (time_after(jiffies,st->next_status_check)) {
+               bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
+               bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
+               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+       }
+       return 0;
+}
+
+static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       bcm3510_refresh_state(st);
+
+       *status = 0;
+       if (st->status1.STATUS1.RECEIVER_LOCK)
+               *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+       if (st->status1.STATUS1.FEC_LOCK)
+               *status |= FE_HAS_VITERBI;
+
+       if (st->status1.STATUS1.OUT_PLL_LOCK)
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+       if (*status & FE_HAS_LOCK)
+               st->status_check_interval = 1500;
+       else /* more frequently checks if no lock has been achieved yet */
+               st->status_check_interval = 500;
+
+       deb_info("real_status: %02x\n",*status);
+       return 0;
+}
+
+static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       bcm3510_refresh_state(st);
+
+       *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
+       return 0;
+}
+
+static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       bcm3510_refresh_state(st);
+       *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
+       return 0;
+}
+
+static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       s32 t;
+
+       bcm3510_refresh_state(st);
+       t = st->status2.SIGNAL;
+
+       if (t > 190)
+               t = 190;
+       if (t < 90)
+               t = 90;
+
+       t -= 90;
+       t = t * 0xff / 100;
+       /* normalize if necessary */
+       *strength = (t << 8) | t;
+       return 0;
+}
+
+static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       bcm3510_refresh_state(st);
+
+       *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
+       return 0;
+}
+
+/* tuner frontend programming */
+static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
+{
+       struct bcm3510_hab_cmd_tune c;
+       memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
+
+/* I2C Mode disabled,  set 16 control / Data pairs */
+       c.length = 0x10;
+       c.clock_width = 0;
+/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
+ * logic high (as Configuration) */
+       c.misc = 0x10;
+/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
+       c.TUNCTL_state = 0x40;
+
+/* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
+       c.ctl_dat[0].ctrl.size = BITS_8;
+       c.ctl_dat[0].data      = 0x80 | bc;
+
+/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
+       c.ctl_dat[1].ctrl.size = BITS_8;
+       c.ctl_dat[1].data      = 4;
+
+/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
+       c.ctl_dat[2].ctrl.size = BITS_3;
+       c.ctl_dat[2].data      = 0x20;
+
+/* control CS0 pin, pulse byte ? */
+       c.ctl_dat[3].ctrl.size = BITS_3;
+       c.ctl_dat[3].ctrl.clk_off = 1;
+       c.ctl_dat[3].ctrl.cs0  = 1;
+       c.ctl_dat[3].data      = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+       c.ctl_dat[4].ctrl.size = BITS_8;
+       c.ctl_dat[4].data      = n >> 3;
+
+/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
+       c.ctl_dat[5].ctrl.size = BITS_8;
+       c.ctl_dat[5].data      = ((n & 0x7) << 5) | (a >> 2);
+
+/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
+       c.ctl_dat[6].ctrl.size = BITS_3;
+       c.ctl_dat[6].data      = (a << 6) & 0xdf;
+
+/* control CS0 pin, pulse byte ? */
+       c.ctl_dat[7].ctrl.size = BITS_3;
+       c.ctl_dat[7].ctrl.clk_off = 1;
+       c.ctl_dat[7].ctrl.cs0  = 1;
+       c.ctl_dat[7].data      = 0x40;
+
+/* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
+       c.ctl_dat[8].ctrl.size = BITS_8;
+       c.ctl_dat[8].data      = 0x80;
+
+/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
+       c.ctl_dat[9].ctrl.size = BITS_8;
+       c.ctl_dat[9].data      = 0x10;
+
+/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
+       c.ctl_dat[10].ctrl.size = BITS_3;
+       c.ctl_dat[10].data      = 0x20;
+
+/* pulse byte */
+       c.ctl_dat[11].ctrl.size = BITS_3;
+       c.ctl_dat[11].ctrl.clk_off = 1;
+       c.ctl_dat[11].ctrl.cs1  = 1;
+       c.ctl_dat[11].data      = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+       c.ctl_dat[12].ctrl.size = BITS_8;
+       c.ctl_dat[12].data      = 0x2a;
+
+/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
+       c.ctl_dat[13].ctrl.size = BITS_8;
+       c.ctl_dat[13].data      = 0x8e;
+
+/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
+       c.ctl_dat[14].ctrl.size = BITS_3;
+       c.ctl_dat[14].data      = 0;
+
+/* Pulse Byte */
+       c.ctl_dat[15].ctrl.size = BITS_3;
+       c.ctl_dat[15].ctrl.clk_off = 1;
+       c.ctl_dat[15].ctrl.cs1  = 1;
+       c.ctl_dat[15].data      = 0x40;
+
+       return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
+}
+
+static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
+{
+       u8 bc,a;
+       u16 n;
+       s32 YIntercept,Tfvco1;
+
+       freq /= 1000;
+
+       deb_info("%dkHz:",freq);
+       /* set Band Switch */
+       if (freq <= 168000)
+               bc = 0x1c;
+       else if (freq <= 378000)
+               bc = 0x2c;
+       else
+               bc = 0x30;
+
+       if (freq >= 470000) {
+               freq -= 470001;
+               YIntercept = 18805;
+       } else if (freq >= 90000) {
+               freq -= 90001;
+               YIntercept = 15005;
+       } else if (freq >= 76000){
+               freq -= 76001;
+               YIntercept = 14865;
+       } else {
+               freq -= 54001;
+               YIntercept = 14645;
+       }
+
+       Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
+
+       n = Tfvco1 >> 6;
+       a = Tfvco1 & 0x3f;
+
+       deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
+       if (n >= 16 && n <= 2047)
+               return bcm3510_tuner_cmd(st,bc,n,a);
+
+       return -EINVAL;
+}
+
+static int bcm3510_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct bcm3510_state* st = fe->demodulator_priv;
+       struct bcm3510_hab_cmd_ext_acquire cmd;
+       struct bcm3510_hab_cmd_bert_control bert;
+       int ret;
+
+       memset(&cmd,0,sizeof(cmd));
+       switch (c->modulation) {
+               case QAM_256:
+                       cmd.ACQUIRE0.MODE = 0x1;
+                       cmd.ACQUIRE1.SYM_RATE = 0x1;
+                       cmd.ACQUIRE1.IF_FREQ = 0x1;
+                       break;
+               case QAM_64:
+                       cmd.ACQUIRE0.MODE = 0x2;
+                       cmd.ACQUIRE1.SYM_RATE = 0x2;
+                       cmd.ACQUIRE1.IF_FREQ = 0x1;
+                       break;
+#if 0
+               case QAM_256:
+                       cmd.ACQUIRE0.MODE = 0x3;
+                       break;
+               case QAM_128:
+                       cmd.ACQUIRE0.MODE = 0x4;
+                       break;
+               case QAM_64:
+                       cmd.ACQUIRE0.MODE = 0x5;
+                       break;
+               case QAM_32:
+                       cmd.ACQUIRE0.MODE = 0x6;
+                       break;
+               case QAM_16:
+                       cmd.ACQUIRE0.MODE = 0x7;
+                       break;
+#endif
+               case VSB_8:
+                       cmd.ACQUIRE0.MODE = 0x8;
+                       cmd.ACQUIRE1.SYM_RATE = 0x0;
+                       cmd.ACQUIRE1.IF_FREQ = 0x0;
+                       break;
+               case VSB_16:
+                       cmd.ACQUIRE0.MODE = 0x9;
+                       cmd.ACQUIRE1.SYM_RATE = 0x0;
+                       cmd.ACQUIRE1.IF_FREQ = 0x0;
+               default:
+                       return -EINVAL;
+       };
+       cmd.ACQUIRE0.OFFSET = 0;
+       cmd.ACQUIRE0.NTSCSWEEP = 1;
+       cmd.ACQUIRE0.FA = 1;
+       cmd.ACQUIRE0.BW = 0;
+
+/*     if (enableOffset) {
+               cmd.IF_OFFSET0 = xx;
+               cmd.IF_OFFSET1 = xx;
+
+               cmd.SYM_OFFSET0 = xx;
+               cmd.SYM_OFFSET1 = xx;
+               if (enableNtscSweep) {
+                       cmd.NTSC_OFFSET0;
+                       cmd.NTSC_OFFSET1;
+               }
+       } */
+       bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
+
+/* doing it with different MSGIDs, data book and source differs */
+       bert.BE = 0;
+       bert.unused = 0;
+       bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
+       bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
+
+       bcm3510_bert_reset(st);
+
+       ret = bcm3510_set_freq(st, c->frequency);
+       if (ret < 0)
+               return ret;
+
+       memset(&st->status1,0,sizeof(st->status1));
+       memset(&st->status2,0,sizeof(st->status2));
+       st->status_check_interval = 500;
+
+/* Give the AP some time */
+       msleep(200);
+
+       return 0;
+}
+
+static int bcm3510_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 1000;
+       s->step_size = 0;
+       s->max_drift = 0;
+       return 0;
+}
+
+static void bcm3510_release(struct dvb_frontend* fe)
+{
+       struct bcm3510_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+/* firmware download:
+ * firmware file is build up like this:
+ * 16bit addr, 16bit length, 8byte of length
+ */
+#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
+
+static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
+                            u16 len)
+{
+       int ret = 0,i;
+       bcm3510_register_value vH, vL,vD;
+
+       vH.MADRH_a9 = addr >> 8;
+       vL.MADRL_aa = addr;
+       if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
+       if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
+
+       for (i = 0; i < len; i++) {
+               vD.MDATA_ab = b[i];
+               if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int bcm3510_download_firmware(struct dvb_frontend* fe)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       const struct firmware *fw;
+       u16 addr,len;
+       const u8 *b;
+       int ret,i;
+
+       deb_info("requesting firmware\n");
+       if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
+               err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
+               return ret;
+       }
+       deb_info("got firmware: %zd\n",fw->size);
+
+       b = fw->data;
+       for (i = 0; i < fw->size;) {
+               addr = le16_to_cpu( *( (u16 *)&b[i] ) );
+               len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );
+               deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
+               if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+                       err("firmware download failed: %d\n",ret);
+                       return ret;
+               }
+               i += 4 + len;
+       }
+       release_firmware(fw);
+       deb_info("firmware download successfully completed\n");
+       return 0;
+}
+
+static int bcm3510_check_firmware_version(struct bcm3510_state *st)
+{
+       struct bcm3510_hab_cmd_get_version_info ver;
+       bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
+
+       deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+               ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
+
+       if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
+               ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
+               ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
+               return 0;
+
+       deb_info("version check failed\n");
+       return -ENODEV;
+}
+
+/* (un)resetting the AP */
+static int bcm3510_reset(struct bcm3510_state *st)
+{
+       int ret;
+       unsigned long  t;
+       bcm3510_register_value v;
+
+       bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
+       if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+               return ret;
+
+    t = jiffies + 3*HZ;
+       while (time_before(jiffies, t)) {
+               msleep(10);
+               if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+                       return ret;
+
+               if (v.APSTAT1_a2.RESET)
+                       return 0;
+       }
+       deb_info("reset timed out\n");
+       return -ETIMEDOUT;
+}
+
+static int bcm3510_clear_reset(struct bcm3510_state *st)
+{
+       bcm3510_register_value v;
+       int ret;
+       unsigned long t;
+
+       v.raw = 0;
+       if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+               return ret;
+
+    t = jiffies + 3*HZ;
+       while (time_before(jiffies, t)) {
+               msleep(10);
+               if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+                       return ret;
+
+               /* verify that reset is cleared */
+               if (!v.APSTAT1_a2.RESET)
+                       return 0;
+       }
+       deb_info("reset clear timed out\n");
+       return -ETIMEDOUT;
+}
+
+static int bcm3510_init_cold(struct bcm3510_state *st)
+{
+       int ret;
+       bcm3510_register_value v;
+
+       /* read Acquisation Processor status register and check it is not in RUN mode */
+       if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+               return ret;
+       if (v.APSTAT1_a2.RUN) {
+               deb_info("AP is already running - firmware already loaded.\n");
+               return 0;
+       }
+
+       deb_info("reset?\n");
+       if ((ret = bcm3510_reset(st)) < 0)
+               return ret;
+
+       deb_info("tristate?\n");
+       /* tri-state */
+       v.TSTCTL_2e.CTL = 0;
+       if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
+               return ret;
+
+       deb_info("firmware?\n");
+       if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
+               (ret = bcm3510_clear_reset(st)) < 0)
+               return ret;
+
+       /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
+
+       return 0;
+}
+
+static int bcm3510_init(struct dvb_frontend* fe)
+{
+       struct bcm3510_state* st = fe->demodulator_priv;
+       bcm3510_register_value j;
+       struct bcm3510_hab_cmd_set_agc c;
+       int ret;
+
+       if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
+               return ret;
+
+       deb_info("JDEC: %02x\n",j.raw);
+
+       switch (j.JDEC_ca.JDEC) {
+               case JDEC_WAIT_AT_RAM:
+                       deb_info("attempting to download firmware\n");
+                       if ((ret = bcm3510_init_cold(st)) < 0)
+                               return ret;
+               case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
+                       deb_info("firmware is loaded\n");
+                       bcm3510_check_firmware_version(st);
+                       break;
+               default:
+                       return -ENODEV;
+       }
+
+       memset(&c,0,1);
+       c.SEL = 1;
+       bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
+
+       return 0;
+}
+
+
+static struct dvb_frontend_ops bcm3510_ops;
+
+struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       struct bcm3510_state* state = NULL;
+       int ret;
+       bcm3510_register_value v;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+
+       state->config = config;
+       state->i2c = i2c;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       mutex_init(&state->hab_mutex);
+
+       if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
+               goto error;
+
+       deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+       if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
+               (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
+               goto error;
+
+       info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+       bcm3510_reset(state);
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(bcm3510_attach);
+
+static struct dvb_frontend_ops bcm3510_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name = "Broadcom BCM3510 VSB/QAM frontend",
+               .frequency_min =  54000000,
+               .frequency_max = 803000000,
+               /* stepsize is just a guess */
+               .frequency_stepsize = 0,
+               .caps =
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_8VSB | FE_CAN_16VSB |
+                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
+       },
+
+       .release = bcm3510_release,
+
+       .init = bcm3510_init,
+       .sleep = bcm3510_sleep,
+
+       .set_frontend = bcm3510_set_frontend,
+       .get_tune_settings = bcm3510_get_tune_settings,
+
+       .read_status = bcm3510_read_status,
+       .read_ber = bcm3510_read_ber,
+       .read_signal_strength = bcm3510_read_signal_strength,
+       .read_snr = bcm3510_read_snr,
+       .read_ucblocks = bcm3510_read_unc,
+};
+
+MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/bcm3510.h b/drivers/media/dvb-frontends/bcm3510.h
new file mode 100644 (file)
index 0000000..f4575c0
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef BCM3510_H
+#define BCM3510_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct bcm3510_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* request firmware for device */
+       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE))
+extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
+                                                 struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_BCM3510
+
+#endif
diff --git a/drivers/media/dvb-frontends/bcm3510_priv.h b/drivers/media/dvb-frontends/bcm3510_priv.h
new file mode 100644 (file)
index 0000000..3bb1bc2
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __BCM3510_PRIV_H__
+#define __BCM3510_PRIV_H__
+
+#define PACKED __attribute__((packed))
+
+#undef err
+#define err(format, arg...)  printk(KERN_ERR     "bcm3510: " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    "bcm3510: " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
+
+
+#define PANASONIC_FIRST_IF_BASE_IN_KHz  1407500
+#define BCM3510_SYMBOL_RATE             5381000
+
+typedef union {
+       u8 raw;
+
+       struct {
+               u8 CTL   :8;
+       } TSTCTL_2e;
+
+       u8 LDCERC_4e;
+       u8 LDUERC_4f;
+       u8 LD_BER0_65;
+       u8 LD_BER1_66;
+       u8 LD_BER2_67;
+       u8 LD_BER3_68;
+
+       struct {
+               u8 RESET :1;
+               u8 IDLE  :1;
+               u8 STOP  :1;
+               u8 HIRQ0 :1;
+               u8 HIRQ1 :1;
+               u8 na0   :1;
+               u8 HABAV :1;
+               u8 na1   :1;
+       } HCTL1_a0;
+
+       struct {
+               u8 na0    :1;
+               u8 IDLMSK :1;
+               u8 STMSK  :1;
+               u8 I0MSK  :1;
+               u8 I1MSK  :1;
+               u8 na1    :1;
+               u8 HABMSK :1;
+               u8 na2    :1;
+       } HCTLMSK_a1;
+
+       struct {
+               u8 RESET  :1;
+               u8 IDLE   :1;
+               u8 STOP   :1;
+               u8 RUN    :1;
+               u8 HABAV  :1;
+               u8 MEMAV  :1;
+               u8 ALDONE :1;
+               u8 REIRQ  :1;
+       } APSTAT1_a2;
+
+       struct {
+               u8 RSTMSK :1;
+               u8 IMSK   :1;
+               u8 SMSK   :1;
+               u8 RMSK   :1;
+               u8 HABMSK :1;
+               u8 MAVMSK :1;
+               u8 ALDMSK :1;
+               u8 REMSK  :1;
+       } APMSK1_a3;
+
+       u8 APSTAT2_a4;
+       u8 APMSK2_a5;
+
+       struct {
+               u8 HABADR :7;
+               u8 na     :1;
+       } HABADR_a6;
+
+       u8 HABDATA_a7;
+
+       struct {
+               u8 HABR   :1;
+               u8 LDHABR :1;
+               u8 APMSK  :1;
+               u8 HMSK   :1;
+               u8 LDMSK  :1;
+               u8 na     :3;
+       } HABSTAT_a8;
+
+       u8 MADRH_a9;
+       u8 MADRL_aa;
+       u8 MDATA_ab;
+
+       struct {
+#define JDEC_WAIT_AT_RAM      0x7
+#define JDEC_EEPROM_LOAD_WAIT 0x4
+               u8 JDEC   :3;
+               u8 na     :5;
+       } JDEC_ca;
+
+       struct {
+               u8 REV   :4;
+               u8 LAYER :4;
+       } REVID_e0;
+
+       struct {
+               u8 unk0   :1;
+               u8 CNTCTL :1;
+               u8 BITCNT :1;
+               u8 unk1   :1;
+               u8 RESYNC :1;
+               u8 unk2   :3;
+       } BERCTL_fa;
+
+       struct {
+               u8 CSEL0  :1;
+               u8 CLKED0 :1;
+               u8 CSEL1  :1;
+               u8 CLKED1 :1;
+               u8 CLKLEV :1;
+               u8 SPIVAR :1;
+               u8 na     :2;
+       } TUNSET_fc;
+
+       struct {
+               u8 CLK    :1;
+               u8 DATA   :1;
+               u8 CS0    :1;
+               u8 CS1    :1;
+               u8 AGCSEL :1;
+               u8 na0    :1;
+               u8 TUNSEL :1;
+               u8 na1    :1;
+       } TUNCTL_fd;
+
+       u8 TUNSEL0_fe;
+       u8 TUNSEL1_ff;
+
+} bcm3510_register_value;
+
+/* HAB commands */
+
+/* version */
+#define CMD_GET_VERSION_INFO   0x3D
+#define MSGID_GET_VERSION_INFO 0x15
+struct bcm3510_hab_cmd_get_version_info {
+       u8 microcode_version;
+       u8 script_version;
+       u8 config_version;
+       u8 demod_version;
+} PACKED;
+
+#define BCM3510_DEF_MICROCODE_VERSION 0x0E
+#define BCM3510_DEF_SCRIPT_VERSION    0x06
+#define BCM3510_DEF_CONFIG_VERSION    0x01
+#define BCM3510_DEF_DEMOD_VERSION     0xB1
+
+/* acquire */
+#define CMD_ACQUIRE            0x38
+
+#define MSGID_EXT_TUNER_ACQUIRE 0x0A
+struct bcm3510_hab_cmd_ext_acquire {
+       struct {
+               u8 MODE      :4;
+               u8 BW        :1;
+               u8 FA        :1;
+               u8 NTSCSWEEP :1;
+               u8 OFFSET    :1;
+       } PACKED ACQUIRE0; /* control_byte */
+
+       struct {
+               u8 IF_FREQ  :3;
+               u8 zero0    :1;
+               u8 SYM_RATE :3;
+               u8 zero1    :1;
+       } PACKED ACQUIRE1; /* sym_if */
+
+       u8 IF_OFFSET0;   /* IF_Offset_10hz */
+       u8 IF_OFFSET1;
+       u8 SYM_OFFSET0;  /* SymbolRateOffset */
+       u8 SYM_OFFSET1;
+       u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+       u8 NTSC_OFFSET1;
+} PACKED;
+
+#define MSGID_INT_TUNER_ACQUIRE 0x0B
+struct bcm3510_hab_cmd_int_acquire {
+       struct {
+               u8 MODE      :4;
+               u8 BW        :1;
+               u8 FA        :1;
+               u8 NTSCSWEEP :1;
+               u8 OFFSET    :1;
+       } PACKED ACQUIRE0; /* control_byte */
+
+       struct {
+               u8 IF_FREQ  :3;
+               u8 zero0    :1;
+               u8 SYM_RATE :3;
+               u8 zero1    :1;
+       } PACKED ACQUIRE1; /* sym_if */
+
+       u8 TUNER_FREQ0;
+       u8 TUNER_FREQ1;
+       u8 TUNER_FREQ2;
+       u8 TUNER_FREQ3;
+       u8 IF_OFFSET0;   /* IF_Offset_10hz */
+       u8 IF_OFFSET1;
+       u8 SYM_OFFSET0;  /* SymbolRateOffset */
+       u8 SYM_OFFSET1;
+       u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+       u8 NTSC_OFFSET1;
+} PACKED;
+
+/* modes */
+#define BCM3510_QAM16           =   0x01
+#define BCM3510_QAM32           =   0x02
+#define BCM3510_QAM64           =   0x03
+#define BCM3510_QAM128          =   0x04
+#define BCM3510_QAM256          =   0x05
+#define BCM3510_8VSB            =   0x0B
+#define BCM3510_16VSB           =   0x0D
+
+/* IF_FREQS */
+#define BCM3510_IF_TERRESTRIAL 0x0
+#define BCM3510_IF_CABLE       0x1
+#define BCM3510_IF_USE_CMD     0x7
+
+/* SYM_RATE */
+#define BCM3510_SR_8VSB        0x0 /* 5381119 s/sec */
+#define BCM3510_SR_256QAM      0x1 /* 5360537 s/sec */
+#define BCM3510_SR_16QAM       0x2 /* 5056971 s/sec */
+#define BCM3510_SR_MISC        0x3 /* 5000000 s/sec */
+#define BCM3510_SR_USE_CMD     0x7
+
+/* special symbol rate */
+#define CMD_SET_VALUE_NOT_LISTED  0x2d
+#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
+struct bcm3510_hab_cmd_set_sr_not_listed {
+       u8 HOST_SYM_RATE0;
+       u8 HOST_SYM_RATE1;
+       u8 HOST_SYM_RATE2;
+       u8 HOST_SYM_RATE3;
+} PACKED;
+
+/* special IF */
+#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
+struct bcm3510_hab_cmd_set_if_freq_not_listed {
+       u8 HOST_IF_FREQ0;
+       u8 HOST_IF_FREQ1;
+       u8 HOST_IF_FREQ2;
+       u8 HOST_IF_FREQ3;
+} PACKED;
+
+/* auto reacquire */
+#define CMD_AUTO_PARAM       0x2a
+#define MSGID_AUTO_REACQUIRE 0x0e
+struct bcm3510_hab_cmd_auto_reacquire {
+       u8 ACQ    :1; /* on/off*/
+       u8 unused :7;
+} PACKED;
+
+#define MSGID_SET_RF_AGC_SEL 0x12
+struct bcm3510_hab_cmd_set_agc {
+       u8 LVL    :1;
+       u8 unused :6;
+       u8 SEL    :1;
+} PACKED;
+
+#define MSGID_SET_AUTO_INVERSION 0x14
+struct bcm3510_hab_cmd_auto_inversion {
+       u8 AI     :1;
+       u8 unused :7;
+} PACKED;
+
+
+/* bert control */
+#define CMD_STATE_CONTROL  0x12
+#define MSGID_BERT_CONTROL 0x0e
+#define MSGID_BERT_SET     0xfa
+struct bcm3510_hab_cmd_bert_control {
+       u8 BE     :1;
+       u8 unused :7;
+} PACKED;
+
+#define MSGID_TRI_STATE 0x2e
+struct bcm3510_hab_cmd_tri_state {
+       u8 RE :1; /* a/d ram port pins */
+       u8 PE :1; /* baud clock pin */
+       u8 AC :1; /* a/d clock pin */
+       u8 BE :1; /* baud clock pin */
+       u8 unused :4;
+} PACKED;
+
+
+/* tune */
+#define CMD_TUNE   0x38
+#define MSGID_TUNE 0x16
+struct bcm3510_hab_cmd_tune_ctrl_data_pair {
+       struct {
+#define BITS_8 0x07
+#define BITS_7 0x06
+#define BITS_6 0x05
+#define BITS_5 0x04
+#define BITS_4 0x03
+#define BITS_3 0x02
+#define BITS_2 0x01
+#define BITS_1 0x00
+               u8 size    :3;
+               u8 unk     :2;
+               u8 clk_off :1;
+               u8 cs0     :1;
+               u8 cs1     :1;
+
+       } PACKED ctrl;
+
+       u8 data;
+} PACKED;
+
+struct bcm3510_hab_cmd_tune {
+       u8 length;
+       u8 clock_width;
+       u8 misc;
+       u8 TUNCTL_state;
+
+       struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
+} PACKED;
+
+#define CMD_STATUS    0x38
+#define MSGID_STATUS1 0x08
+struct bcm3510_hab_cmd_status1 {
+       struct {
+               u8 EQ_MODE       :4;
+               u8 reserved      :2;
+               u8 QRE           :1; /* if QSE and the spectrum is inversed */
+               u8 QSE           :1; /* automatic spectral inversion */
+       } PACKED STATUS0;
+
+       struct {
+               u8 RECEIVER_LOCK :1;
+               u8 FEC_LOCK      :1;
+               u8 OUT_PLL_LOCK  :1;
+               u8 reserved      :5;
+       } PACKED STATUS1;
+
+       struct {
+               u8 reserved      :2;
+               u8 BW            :1;
+               u8 NTE           :1; /* NTSC filter sweep enabled */
+               u8 AQI           :1; /* currently acquiring */
+               u8 FA            :1; /* fast acquisition */
+               u8 ARI           :1; /* auto reacquire */
+               u8 TI            :1; /* programming the tuner */
+       } PACKED STATUS2;
+       u8 STATUS3;
+       u8 SNR_EST0;
+       u8 SNR_EST1;
+       u8 TUNER_FREQ0;
+       u8 TUNER_FREQ1;
+       u8 TUNER_FREQ2;
+       u8 TUNER_FREQ3;
+       u8 SYM_RATE0;
+       u8 SYM_RATE1;
+       u8 SYM_RATE2;
+       u8 SYM_RATE3;
+       u8 SYM_OFFSET0;
+       u8 SYM_OFFSET1;
+       u8 SYM_ERROR0;
+       u8 SYM_ERROR1;
+       u8 IF_FREQ0;
+       u8 IF_FREQ1;
+       u8 IF_FREQ2;
+       u8 IF_FREQ3;
+       u8 IF_OFFSET0;
+       u8 IF_OFFSET1;
+       u8 IF_ERROR0;
+       u8 IF_ERROR1;
+       u8 NTSC_FILTER0;
+       u8 NTSC_FILTER1;
+       u8 NTSC_FILTER2;
+       u8 NTSC_FILTER3;
+       u8 NTSC_OFFSET0;
+       u8 NTSC_OFFSET1;
+       u8 NTSC_ERROR0;
+       u8 NTSC_ERROR1;
+       u8 INT_AGC_LEVEL0;
+       u8 INT_AGC_LEVEL1;
+       u8 EXT_AGC_LEVEL0;
+       u8 EXT_AGC_LEVEL1;
+} PACKED;
+
+#define MSGID_STATUS2 0x14
+struct bcm3510_hab_cmd_status2 {
+       struct {
+               u8 EQ_MODE  :4;
+               u8 reserved :2;
+               u8 QRE      :1;
+               u8 QSR      :1;
+       } PACKED STATUS0;
+       struct {
+               u8 RL       :1;
+               u8 FL       :1;
+               u8 OL       :1;
+               u8 reserved :5;
+       } PACKED STATUS1;
+       u8 SYMBOL_RATE0;
+       u8 SYMBOL_RATE1;
+       u8 SYMBOL_RATE2;
+       u8 SYMBOL_RATE3;
+       u8 LDCERC0;
+       u8 LDCERC1;
+       u8 LDCERC2;
+       u8 LDCERC3;
+       u8 LDUERC0;
+       u8 LDUERC1;
+       u8 LDUERC2;
+       u8 LDUERC3;
+       u8 LDBER0;
+       u8 LDBER1;
+       u8 LDBER2;
+       u8 LDBER3;
+       struct {
+               u8 MODE_TYPE :4; /* acquire mode 0 */
+               u8 reservd   :4;
+       } MODE_TYPE;
+       u8 SNR_EST0;
+       u8 SNR_EST1;
+       u8 SIGNAL;
+} PACKED;
+
+#define CMD_SET_RF_BW_NOT_LISTED   0x3f
+#define MSGID_SET_RF_BW_NOT_LISTED 0x11
+/* TODO */
+
+#endif
diff --git a/drivers/media/dvb-frontends/bsbe1-d01a.h b/drivers/media/dvb-frontends/bsbe1-d01a.h
new file mode 100644 (file)
index 0000000..7ed3c42
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * bsbe1-d01a.h - ALPS BSBE1-D01A tuner support
+ *
+ * Copyright (C) 2011 Oliver Endriss <o.endriss@gmx.de>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSBE1_D01A_H
+#define BSBE1_D01A_H
+
+#include "stb6000.h"
+#include "stv0288.h"
+
+static u8 stv0288_bsbe1_d01a_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x20,
+       0x09, 0x0,
+       0x0a, 0x4,
+       0x0b, 0x0,
+       0x0c, 0x0,
+       0x0d, 0x0,
+       0x0e, 0xd4,
+       0x0f, 0x30,
+       0x11, 0x80,
+       0x12, 0x03,
+       0x13, 0x48,
+       0x14, 0x84,
+       0x15, 0x45,
+       0x16, 0xb7,
+       0x17, 0x9c,
+       0x18, 0x0,
+       0x19, 0xa6,
+       0x1a, 0x88,
+       0x1b, 0x8f,
+       0x1c, 0xf0,
+       0x20, 0x0b,
+       0x21, 0x54,
+       0x22, 0x0,
+       0x23, 0x0,
+       0x2b, 0xff,
+       0x2c, 0xf7,
+       0x30, 0x0,
+       0x31, 0x1e,
+       0x32, 0x14,
+       0x33, 0x0f,
+       0x34, 0x09,
+       0x35, 0x0c,
+       0x36, 0x05,
+       0x37, 0x2f,
+       0x38, 0x16,
+       0x39, 0xbd,
+       0x3a, 0x03,
+       0x3b, 0x13,
+       0x3c, 0x11,
+       0x3d, 0x30,
+       0x40, 0x63,
+       0x41, 0x04,
+       0x42, 0x60,
+       0x43, 0x00,
+       0x44, 0x00,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x47, 0x00,
+       0x4a, 0x00,
+       0x50, 0x10,
+       0x51, 0x36,
+       0x52, 0x09,
+       0x53, 0x94,
+       0x54, 0x62,
+       0x55, 0x29,
+       0x56, 0x64,
+       0x57, 0x2b,
+       0x58, 0x54,
+       0x59, 0x86,
+       0x5a, 0x0,
+       0x5b, 0x9b,
+       0x5c, 0x08,
+       0x5d, 0x7f,
+       0x5e, 0x0,
+       0x5f, 0xff,
+       0x70, 0x0,
+       0x71, 0x0,
+       0x72, 0x0,
+       0x74, 0x0,
+       0x75, 0x0,
+       0x76, 0x0,
+       0x81, 0x0,
+       0x82, 0x3f,
+       0x83, 0x3f,
+       0x84, 0x0,
+       0x85, 0x0,
+       0x88, 0x0,
+       0x89, 0x0,
+       0x8a, 0x0,
+       0x8b, 0x0,
+       0x8c, 0x0,
+       0x90, 0x0,
+       0x91, 0x0,
+       0x92, 0x0,
+       0x93, 0x0,
+       0x94, 0x1c,
+       0x97, 0x0,
+       0xa0, 0x48,
+       0xa1, 0x0,
+       0xb0, 0xb8,
+       0xb1, 0x3a,
+       0xb2, 0x10,
+       0xb3, 0x82,
+       0xb4, 0x80,
+       0xb5, 0x82,
+       0xb6, 0x82,
+       0xb7, 0x82,
+       0xb8, 0x20,
+       0xb9, 0x0,
+       0xf0, 0x0,
+       0xf1, 0x0,
+       0xf2, 0xc0,
+       0xff, 0xff,
+};
+
+static struct stv0288_config stv0288_bsbe1_d01a_config = {
+       .demod_address = 0x68,
+       .min_delay_ms = 100,
+       .inittab = stv0288_bsbe1_d01a_inittab,
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/bsbe1.h b/drivers/media/dvb-frontends/bsbe1.h
new file mode 100644 (file)
index 0000000..53e4d0d
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * bsbe1.h - ALPS BSBE1 tuner support
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSBE1_H
+#define BSBE1_H
+
+static u8 alps_bsbe1_inittab[] = {
+       0x01, 0x15,   /* XTAL = 4MHz, VCO = 352 MHz */
+       0x02, 0x30,   /* MCLK = 88 MHz */
+       0x03, 0x00,   /* ACR output 0 */
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x05,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x00,   /* DAC output 0 */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1/OP0 normal, val = 1 (LNB power on) */
+       0x0d, 0x82,   /* DC offset compensation = on, beta_agc1 = 2 */
+       0x0f, 0x92,   /* AGC1R */
+       0x10, 0x34,   /* AGC2O */
+       0x11, 0x84,   /* TLSR */
+       0x12, 0xb9,   /* CFD */
+       0x15, 0xc9,   /* lock detector threshold */
+       0x28, 0x00,   /* out imp: normal, type: parallel, FEC mode: QPSK */
+       0x33, 0xfc,   /* RS control */
+       0x34, 0x93,   /* count viterbi bit errors per 2E18 bytes */
+       0xff, 0xff
+};
+
+
+static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
+       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
+       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
+       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
+       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
+       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio      ) & 0xf0);
+
+       return 0;
+}
+
+static int alps_bsbe1_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       int ret;
+       u8 data[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+       struct i2c_adapter *i2c = fe->tuner_priv;
+
+       if ((p->frequency < 950000) || (p->frequency > 2150000))
+               return -EINVAL;
+
+       div = p->frequency / 1000;
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1;
+       data[3] = 0xe0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer(i2c, &msg, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
+static struct stv0299_config alps_bsbe1_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsbe1_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/bsru6.h b/drivers/media/dvb-frontends/bsru6.h
new file mode 100644 (file)
index 0000000..c2a578e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c)
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSRU6_H
+#define BSRU6_H
+
+static u8 alps_bsru6_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,   // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,  // 1/2 threshold
+       0x2a, 0x14,  // 2/3 threshold
+       0x2b, 0x0f,  // 3/4 threshold
+       0x2c, 0x09,  // 5/6 threshold
+       0x2d, 0x05,  // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,  // test all FECs
+       0x32, 0x19,  // viterbi and synchro search
+       0x33, 0xfc,  // rs control
+       0x34, 0x93,  // error control
+       0x0f, 0x52,
+       0xff, 0xff
+};
+
+static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) {
+               aclk = 0xb7;
+               bclk = 0x47;
+       } else if (srate < 3000000) {
+               aclk = 0xb7;
+               bclk = 0x4b;
+       } else if (srate < 7000000) {
+               aclk = 0xb7;
+               bclk = 0x4f;
+       } else if (srate < 14000000) {
+               aclk = 0xb7;
+               bclk = 0x53;
+       } else if (srate < 30000000) {
+               aclk = 0xb6;
+               bclk = 0x53;
+       } else if (srate < 45000000) {
+               aclk = 0xb4;
+               bclk = 0x51;
+       }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, 0x21, ratio & 0xf0);
+
+       return 0;
+}
+
+static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+       struct i2c_adapter *i2c = fe->tuner_priv;
+
+       if ((p->frequency < 950000) || (p->frequency > 2150000))
+               return -EINVAL;
+
+       div = (p->frequency + (125 - 1)) / 125; /* round correctly */
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       buf[3] = 0xC4;
+
+       if (p->frequency > 1530000)
+               buf[3] = 0xc0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(i2c, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct stv0299_config alps_bsru6_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsru6_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .lock_output = STV0299_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsru6_set_symbol_rate,
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c
new file mode 100644 (file)
index 0000000..f2a90f9
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+    Conexant cx22700 DVB OFDM demodulator driver
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+       Holger Waechtler <holger@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "dvb_frontend.h"
+#include "cx22700.h"
+
+
+struct cx22700_state {
+
+       struct i2c_adapter* i2c;
+
+       const struct cx22700_config* config;
+
+       struct dvb_frontend frontend;
+};
+
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "cx22700: " args); \
+       } while (0)
+
+static u8 init_tab [] = {
+       0x04, 0x10,
+       0x05, 0x09,
+       0x06, 0x00,
+       0x08, 0x04,
+       0x09, 0x00,
+       0x0a, 0x01,
+       0x15, 0x40,
+       0x16, 0x10,
+       0x17, 0x87,
+       0x18, 0x17,
+       0x1a, 0x10,
+       0x25, 0x04,
+       0x2e, 0x00,
+       0x39, 0x00,
+       0x3a, 0x04,
+       0x45, 0x08,
+       0x46, 0x02,
+       0x47, 0x05,
+};
+
+
+static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf [] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+
+       dprintk ("%s\n", __func__);
+
+       ret = i2c_transfer (state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+                       __func__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static int cx22700_readreg (struct cx22700_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       dprintk ("%s\n", __func__);
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+
+       if (ret != 2) return -EIO;
+
+       return b1[0];
+}
+
+static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
+{
+       u8 val;
+
+       dprintk ("%s\n", __func__);
+
+       switch (inversion) {
+       case INVERSION_AUTO:
+               return -EOPNOTSUPP;
+       case INVERSION_ON:
+               val = cx22700_readreg (state, 0x09);
+               return cx22700_writereg (state, 0x09, val | 0x01);
+       case INVERSION_OFF:
+               val = cx22700_readreg (state, 0x09);
+               return cx22700_writereg (state, 0x09, val & 0xfe);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int cx22700_set_tps(struct cx22700_state *state,
+                          struct dtv_frontend_properties *p)
+{
+       static const u8 qam_tab [4] = { 0, 1, 0, 2 };
+       static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
+       u8 val;
+
+       dprintk ("%s\n", __func__);
+
+       if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
+               return -EINVAL;
+
+       if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
+               return -EINVAL;
+
+       if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
+               return -EINVAL;
+
+       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
+           p->guard_interval > GUARD_INTERVAL_1_4)
+               return -EINVAL;
+
+       if (p->transmission_mode != TRANSMISSION_MODE_2K &&
+           p->transmission_mode != TRANSMISSION_MODE_8K)
+               return -EINVAL;
+
+       if (p->modulation != QPSK &&
+           p->modulation != QAM_16 &&
+           p->modulation != QAM_64)
+               return -EINVAL;
+
+       if (p->hierarchy < HIERARCHY_NONE ||
+           p->hierarchy > HIERARCHY_4)
+               return -EINVAL;
+
+       if (p->bandwidth_hz > 8000000 || p->bandwidth_hz < 6000000)
+               return -EINVAL;
+
+       if (p->bandwidth_hz == 7000000)
+               cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
+       else
+               cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
+
+       val = qam_tab[p->modulation - QPSK];
+       val |= p->hierarchy - HIERARCHY_NONE;
+
+       cx22700_writereg (state, 0x04, val);
+
+       val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
+       val |= fec_tab[p->code_rate_LP - FEC_1_2];
+
+       cx22700_writereg (state, 0x05, val);
+
+       val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
+       val |= p->transmission_mode - TRANSMISSION_MODE_2K;
+
+       cx22700_writereg (state, 0x06, val);
+
+       cx22700_writereg (state, 0x08, 0x04 | 0x02);  /* use user tps parameters */
+       cx22700_writereg (state, 0x08, 0x04);         /* restart acquisition */
+
+       return 0;
+}
+
+static int cx22700_get_tps(struct cx22700_state *state,
+                          struct dtv_frontend_properties *p)
+{
+       static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
+       static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
+                                                   FEC_5_6, FEC_7_8 };
+       u8 val;
+
+       dprintk ("%s\n", __func__);
+
+       if (!(cx22700_readreg(state, 0x07) & 0x20))  /*  tps valid? */
+               return -EAGAIN;
+
+       val = cx22700_readreg (state, 0x01);
+
+       if ((val & 0x7) > 4)
+               p->hierarchy = HIERARCHY_AUTO;
+       else
+               p->hierarchy = HIERARCHY_NONE + (val & 0x7);
+
+       if (((val >> 3) & 0x3) > 2)
+               p->modulation = QAM_AUTO;
+       else
+               p->modulation = qam_tab[(val >> 3) & 0x3];
+
+       val = cx22700_readreg (state, 0x02);
+
+       if (((val >> 3) & 0x07) > 4)
+               p->code_rate_HP = FEC_AUTO;
+       else
+               p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
+
+       if ((val & 0x07) > 4)
+               p->code_rate_LP = FEC_AUTO;
+       else
+               p->code_rate_LP = fec_tab[val & 0x07];
+
+       val = cx22700_readreg (state, 0x03);
+
+       p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
+       p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
+
+       return 0;
+}
+
+static int cx22700_init (struct dvb_frontend* fe)
+
+{      struct cx22700_state* state = fe->demodulator_priv;
+       int i;
+
+       dprintk("cx22700_init: init chip\n");
+
+       cx22700_writereg (state, 0x00, 0x02);   /*  soft reset */
+       cx22700_writereg (state, 0x00, 0x00);
+
+       msleep(10);
+
+       for (i=0; i<sizeof(init_tab); i+=2)
+               cx22700_writereg (state, init_tab[i], init_tab[i+1]);
+
+       cx22700_writereg (state, 0x00, 0x01);
+
+       return 0;
+}
+
+static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
+                  | (cx22700_readreg (state, 0x0e) << 1);
+       u8 sync = cx22700_readreg (state, 0x07);
+
+       *status = 0;
+
+       if (rs_ber < 0xff00)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 0x20)
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 0x10)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 0x10)
+               *status |= FE_HAS_SYNC;
+
+       if (*status == 0x0f)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       *ber = cx22700_readreg (state, 0x0c) & 0x7f;
+       cx22700_writereg (state, 0x0c, 0x00);
+
+       return 0;
+}
+
+static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
+                  | (cx22700_readreg (state, 0x0e) << 1);
+       *signal_strength = ~rs_ber;
+
+       return 0;
+}
+
+static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
+                  | (cx22700_readreg (state, 0x0e) << 1);
+       *snr = ~rs_ber;
+
+       return 0;
+}
+
+static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       *ucblocks = cx22700_readreg (state, 0x0f);
+       cx22700_writereg (state, 0x0f, 0x00);
+
+       return 0;
+}
+
+static int cx22700_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
+       cx22700_writereg (state, 0x00, 0x00);
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       cx22700_set_inversion(state, c->inversion);
+       cx22700_set_tps(state, c);
+       cx22700_writereg (state, 0x37, 0x01);  /* PAL loop filter off */
+       cx22700_writereg (state, 0x00, 0x01);  /* restart acquire */
+
+       return 0;
+}
+
+static int cx22700_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct cx22700_state* state = fe->demodulator_priv;
+       u8 reg09 = cx22700_readreg (state, 0x09);
+
+       c->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
+       return cx22700_get_tps(state, c);
+}
+
+static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return cx22700_writereg(state, 0x0a, 0x00);
+       } else {
+               return cx22700_writereg(state, 0x0a, 0x01);
+       }
+}
+
+static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 150;
+       fesettings->step_size = 166667;
+       fesettings->max_drift = 166667*2;
+       return 0;
+}
+
+static void cx22700_release(struct dvb_frontend* fe)
+{
+       struct cx22700_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops cx22700_ops;
+
+struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct cx22700_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if (cx22700_readreg(state, 0x07) < 0) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops cx22700_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Conexant CX22700 DVB-T",
+               .frequency_min          = 470000000,
+               .frequency_max          = 860000000,
+               .frequency_stepsize     = 166667,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                     FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                     FE_CAN_RECOVER
+       },
+
+       .release = cx22700_release,
+
+       .init = cx22700_init,
+       .i2c_gate_ctrl = cx22700_i2c_gate_ctrl,
+
+       .set_frontend = cx22700_set_frontend,
+       .get_frontend = cx22700_get_frontend,
+       .get_tune_settings = cx22700_get_tune_settings,
+
+       .read_status = cx22700_read_status,
+       .read_ber = cx22700_read_ber,
+       .read_signal_strength = cx22700_read_signal_strength,
+       .read_snr = cx22700_read_snr,
+       .read_ucblocks = cx22700_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
+MODULE_AUTHOR("Holger Waechtler");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb-frontends/cx22700.h b/drivers/media/dvb-frontends/cx22700.h
new file mode 100644 (file)
index 0000000..4757a93
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Conexant CX22700 DVB OFDM demodulator driver
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+       Holger Waechtler <holger@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef CX22700_H
+#define CX22700_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx22700_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE))
+extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_CX22700
+
+#endif // CX22700_H
diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c
new file mode 100644 (file)
index 0000000..edc8eaf
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+    Conexant 22702 DVB OFDM demodulator driver
+
+    based on:
+       Alps TDMB7 DVB OFDM demodulator driver
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+         Holger Waechtler <holger@convergence.de>
+
+    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "cx22702.h"
+
+struct cx22702_state {
+
+       struct i2c_adapter *i2c;
+
+       /* configuration settings */
+       const struct cx22702_config *config;
+
+       struct dvb_frontend frontend;
+
+       /* previous uncorrected block counter */
+       u8 prevUCBlocks;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+#define dprintk        if (debug) printk
+
+/* Register values to initialise the demod */
+static const u8 init_tab[] = {
+       0x00, 0x00, /* Stop acquisition */
+       0x0B, 0x06,
+       0x09, 0x01,
+       0x0D, 0x41,
+       0x16, 0x32,
+       0x20, 0x0A,
+       0x21, 0x17,
+       0x24, 0x3e,
+       0x26, 0xff,
+       0x27, 0x10,
+       0x28, 0x00,
+       0x29, 0x00,
+       0x2a, 0x10,
+       0x2b, 0x00,
+       0x2c, 0x10,
+       0x2d, 0x00,
+       0x48, 0xd4,
+       0x49, 0x56,
+       0x6b, 0x1e,
+       0xc8, 0x02,
+       0xf9, 0x00,
+       0xfa, 0x00,
+       0xfb, 0x00,
+       0xfc, 0x00,
+       0xfd, 0x00,
+};
+
+static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address, .flags = 0,
+                       .buf = buf, .len = 2 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (unlikely(ret != 1)) {
+               printk(KERN_ERR
+                       "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+                       __func__, reg, data, ret);
+               return -1;
+       }
+
+       return 0;
+}
+
+static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
+{
+       int ret;
+       u8 data;
+
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0,
+                       .buf = &reg, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD,
+                       .buf = &data, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (unlikely(ret != 2)) {
+               printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n",
+                       __func__, reg, ret);
+               return 0;
+       }
+
+       return data;
+}
+
+static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
+{
+       u8 val;
+
+       val = cx22702_readreg(state, 0x0C);
+       switch (inversion) {
+       case INVERSION_AUTO:
+               return -EOPNOTSUPP;
+       case INVERSION_ON:
+               val |= 0x01;
+               break;
+       case INVERSION_OFF:
+               val &= 0xfe;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return cx22702_writereg(state, 0x0C, val);
+}
+
+/* Retrieve the demod settings */
+static int cx22702_get_tps(struct cx22702_state *state,
+                          struct dtv_frontend_properties *p)
+{
+       u8 val;
+
+       /* Make sure the TPS regs are valid */
+       if (!(cx22702_readreg(state, 0x0A) & 0x20))
+               return -EAGAIN;
+
+       val = cx22702_readreg(state, 0x01);
+       switch ((val & 0x18) >> 3) {
+       case 0:
+               p->modulation = QPSK;
+               break;
+       case 1:
+               p->modulation = QAM_16;
+               break;
+       case 2:
+               p->modulation = QAM_64;
+               break;
+       }
+       switch (val & 0x07) {
+       case 0:
+               p->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               p->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               p->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               p->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+
+       val = cx22702_readreg(state, 0x02);
+       switch ((val & 0x38) >> 3) {
+       case 0:
+               p->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_HP = FEC_7_8;
+               break;
+       }
+       switch (val & 0x07) {
+       case 0:
+               p->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       val = cx22702_readreg(state, 0x03);
+       switch ((val & 0x0c) >> 2) {
+       case 0:
+               p->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               p->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               p->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               p->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+       switch (val & 0x03) {
+       case 0:
+               p->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               p->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+
+       return 0;
+}
+
+static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("%s(%d)\n", __func__, enable);
+       val = cx22702_readreg(state, 0x0D);
+       if (enable)
+               val &= 0xfe;
+       else
+               val |= 0x01;
+       return cx22702_writereg(state, 0x0D, val);
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int cx22702_set_tps(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u8 val;
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* set inversion */
+       cx22702_set_inversion(state, p->inversion);
+
+       /* set bandwidth */
+       val = cx22702_readreg(state, 0x0C) & 0xcf;
+       switch (p->bandwidth_hz) {
+       case 6000000:
+               val |= 0x20;
+               break;
+       case 7000000:
+               val |= 0x10;
+               break;
+       case 8000000:
+               break;
+       default:
+               dprintk("%s: invalid bandwidth\n", __func__);
+               return -EINVAL;
+       }
+       cx22702_writereg(state, 0x0C, val);
+
+       p->code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
+
+       /* use auto configuration? */
+       if ((p->hierarchy == HIERARCHY_AUTO) ||
+          (p->modulation == QAM_AUTO) ||
+          (p->code_rate_HP == FEC_AUTO) ||
+          (p->code_rate_LP == FEC_AUTO) ||
+          (p->guard_interval == GUARD_INTERVAL_AUTO) ||
+          (p->transmission_mode == TRANSMISSION_MODE_AUTO)) {
+
+               /* TPS Source - use hardware driven values */
+               cx22702_writereg(state, 0x06, 0x10);
+               cx22702_writereg(state, 0x07, 0x9);
+               cx22702_writereg(state, 0x08, 0xC1);
+               cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
+                       & 0xfc);
+               cx22702_writereg(state, 0x0C,
+                       (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
+               cx22702_writereg(state, 0x00, 0x01); /* Begin acquisition */
+               dprintk("%s: Autodetecting\n", __func__);
+               return 0;
+       }
+
+       /* manually programmed values */
+       switch (p->modulation) {                /* mask 0x18 */
+       case QPSK:
+               val = 0x00;
+               break;
+       case QAM_16:
+               val = 0x08;
+               break;
+       case QAM_64:
+               val = 0x10;
+               break;
+       default:
+               dprintk("%s: invalid modulation\n", __func__);
+               return -EINVAL;
+       }
+       switch (p->hierarchy) { /* mask 0x07 */
+       case HIERARCHY_NONE:
+               break;
+       case HIERARCHY_1:
+               val |= 0x01;
+               break;
+       case HIERARCHY_2:
+               val |= 0x02;
+               break;
+       case HIERARCHY_4:
+               val |= 0x03;
+               break;
+       default:
+               dprintk("%s: invalid hierarchy\n", __func__);
+               return -EINVAL;
+       }
+       cx22702_writereg(state, 0x06, val);
+
+       switch (p->code_rate_HP) {              /* mask 0x38 */
+       case FEC_NONE:
+       case FEC_1_2:
+               val = 0x00;
+               break;
+       case FEC_2_3:
+               val = 0x08;
+               break;
+       case FEC_3_4:
+               val = 0x10;
+               break;
+       case FEC_5_6:
+               val = 0x18;
+               break;
+       case FEC_7_8:
+               val = 0x20;
+               break;
+       default:
+               dprintk("%s: invalid code_rate_HP\n", __func__);
+               return -EINVAL;
+       }
+       switch (p->code_rate_LP) {              /* mask 0x07 */
+       case FEC_NONE:
+       case FEC_1_2:
+               break;
+       case FEC_2_3:
+               val |= 0x01;
+               break;
+       case FEC_3_4:
+               val |= 0x02;
+               break;
+       case FEC_5_6:
+               val |= 0x03;
+               break;
+       case FEC_7_8:
+               val |= 0x04;
+               break;
+       default:
+               dprintk("%s: invalid code_rate_LP\n", __func__);
+               return -EINVAL;
+       }
+       cx22702_writereg(state, 0x07, val);
+
+       switch (p->guard_interval) {            /* mask 0x0c */
+       case GUARD_INTERVAL_1_32:
+               val = 0x00;
+               break;
+       case GUARD_INTERVAL_1_16:
+               val = 0x04;
+               break;
+       case GUARD_INTERVAL_1_8:
+               val = 0x08;
+               break;
+       case GUARD_INTERVAL_1_4:
+               val = 0x0c;
+               break;
+       default:
+               dprintk("%s: invalid guard_interval\n", __func__);
+               return -EINVAL;
+       }
+       switch (p->transmission_mode) {         /* mask 0x03 */
+       case TRANSMISSION_MODE_2K:
+               break;
+       case TRANSMISSION_MODE_8K:
+               val |= 0x1;
+               break;
+       default:
+               dprintk("%s: invalid transmission_mode\n", __func__);
+               return -EINVAL;
+       }
+       cx22702_writereg(state, 0x08, val);
+       cx22702_writereg(state, 0x0B,
+               (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
+       cx22702_writereg(state, 0x0C,
+               (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
+
+       /* Begin channel acquisition */
+       cx22702_writereg(state, 0x00, 0x01);
+
+       return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+static int cx22702_init(struct dvb_frontend *fe)
+{
+       int i;
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       cx22702_writereg(state, 0x00, 0x02);
+
+       msleep(10);
+
+       for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
+               cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
+
+       cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
+               & 0x02);
+
+       cx22702_i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+       u8 reg0A;
+       u8 reg23;
+
+       *status = 0;
+
+       reg0A = cx22702_readreg(state, 0x0A);
+       reg23 = cx22702_readreg(state, 0x23);
+
+       dprintk("%s: status demod=0x%02x agc=0x%02x\n"
+               , __func__, reg0A, reg23);
+
+       if (reg0A & 0x10) {
+               *status |= FE_HAS_LOCK;
+               *status |= FE_HAS_VITERBI;
+               *status |= FE_HAS_SYNC;
+       }
+
+       if (reg0A & 0x20)
+               *status |= FE_HAS_CARRIER;
+
+       if (reg23 < 0xf0)
+               *status |= FE_HAS_SIGNAL;
+
+       return 0;
+}
+
+static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       if (cx22702_readreg(state, 0xE4) & 0x02) {
+               /* Realtime statistics */
+               *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+                       | (cx22702_readreg(state, 0xDF) & 0x7F);
+       } else {
+               /* Averagtine statistics */
+               *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+                       | cx22702_readreg(state, 0xDF);
+       }
+
+       return 0;
+}
+
+static int cx22702_read_signal_strength(struct dvb_frontend *fe,
+       u16 *signal_strength)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+       u8 reg23;
+
+       /*
+        * Experience suggests that the strength signal register works as
+        * follows:
+        * - In the absence of signal, value is 0xff.
+        * - In the presence of a weak signal, bit 7 is set, not sure what
+        *   the lower 7 bits mean.
+        * - In the presence of a strong signal, the register holds a 7-bit
+        *   value (bit 7 is cleared), with greater values standing for
+        *   weaker signals.
+        */
+       reg23 = cx22702_readreg(state, 0x23);
+       if (reg23 & 0x80) {
+               *signal_strength = 0;
+       } else {
+               reg23 = ~reg23 & 0x7f;
+               /* Scale to 16 bit */
+               *signal_strength = (reg23 << 9) | (reg23 << 2) | (reg23 >> 5);
+       }
+
+       return 0;
+}
+
+static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       u16 rs_ber;
+       if (cx22702_readreg(state, 0xE4) & 0x02) {
+               /* Realtime statistics */
+               rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+                       | (cx22702_readreg(state, 0xDF) & 0x7F);
+       } else {
+               /* Averagine statistics */
+               rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
+                       | cx22702_readreg(state, 0xDF);
+       }
+       *snr = ~rs_ber;
+
+       return 0;
+}
+
+static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       u8 _ucblocks;
+
+       /* RS Uncorrectable Packet Count then reset */
+       _ucblocks = cx22702_readreg(state, 0xE3);
+       if (state->prevUCBlocks < _ucblocks)
+               *ucblocks = (_ucblocks - state->prevUCBlocks);
+       else
+               *ucblocks = state->prevUCBlocks - _ucblocks;
+       state->prevUCBlocks = _ucblocks;
+
+       return 0;
+}
+
+static int cx22702_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct cx22702_state *state = fe->demodulator_priv;
+
+       u8 reg0C = cx22702_readreg(state, 0x0C);
+
+       c->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
+       return cx22702_get_tps(state, c);
+}
+
+static int cx22702_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void cx22702_release(struct dvb_frontend *fe)
+{
+       struct cx22702_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static const struct dvb_frontend_ops cx22702_ops;
+
+struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
+       struct i2c_adapter *i2c)
+{
+       struct cx22702_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if (cx22702_readreg(state, 0x1f) != 0x3)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &cx22702_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(cx22702_attach);
+
+static const struct dvb_frontend_ops cx22702_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Conexant CX22702 DVB-T",
+               .frequency_min          = 177000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+               FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+               FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+       },
+
+       .release = cx22702_release,
+
+       .init = cx22702_init,
+       .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
+
+       .set_frontend = cx22702_set_tps,
+       .get_frontend = cx22702_get_frontend,
+       .get_tune_settings = cx22702_get_tune_settings,
+
+       .read_status = cx22702_read_status,
+       .read_ber = cx22702_read_ber,
+       .read_signal_strength = cx22702_read_signal_strength,
+       .read_snr = cx22702_read_snr,
+       .read_ucblocks = cx22702_read_ucblocks,
+};
+
+MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/cx22702.h b/drivers/media/dvb-frontends/cx22702.h
new file mode 100644 (file)
index 0000000..f154e1f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Conexant 22702 DVB OFDM demodulator driver
+
+    based on:
+       Alps TDMB7 DVB OFDM demodulator driver
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+         Holger Waechtler <holger@convergence.de>
+
+    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef CX22702_H
+#define CX22702_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx22702_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* serial/parallel output */
+#define CX22702_PARALLEL_OUTPUT 0
+#define CX22702_SERIAL_OUTPUT   1
+       u8 output_mode;
+};
+
+#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
+       && defined(MODULE))
+extern struct dvb_frontend *cx22702_attach(
+       const struct cx22702_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *cx22702_attach(
+       const struct cx22702_config *config,
+       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
new file mode 100644 (file)
index 0000000..3180f5b
--- /dev/null
@@ -0,0 +1,666 @@
+/*
+    cx24110 - Single Chip Satellite Channel Receiver driver module
+
+    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
+    work
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "dvb_frontend.h"
+#include "cx24110.h"
+
+
+struct cx24110_state {
+
+       struct i2c_adapter* i2c;
+
+       const struct cx24110_config* config;
+
+       struct dvb_frontend frontend;
+
+       u32 lastber;
+       u32 lastbler;
+       u32 lastesn0;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "cx24110: " args); \
+       } while (0)
+
+static struct {u8 reg; u8 data;} cx24110_regdata[]=
+                     /* Comments beginning with @ denote this value should
+                        be the default */
+       {{0x09,0x01}, /* SoftResetAll */
+        {0x09,0x00}, /* release reset */
+        {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
+        {0x02,0x17}, /* middle byte " */
+        {0x03,0x29}, /* LSB         " */
+        {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
+        {0x06,0xa5}, /* @ PLL 60MHz */
+        {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
+        {0x0a,0x00}, /* @ partial chip disables, do not set */
+        {0x0b,0x01}, /* set output clock in gapped mode, start signal low
+                        active for first byte */
+        {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
+        {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
+        {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
+                        to avoid starting the BER counter. Reset the
+                        CRC test bit. Finite counting selected */
+        {0x15,0xff}, /* @ size of the limited time window for RS BER
+                        estimation. It is <value>*256 RS blocks, this
+                        gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
+        {0x16,0x00}, /* @ enable all RS output ports */
+        {0x17,0x04}, /* @ time window allowed for the RS to sync */
+        {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
+                        for automatically */
+                     /* leave the current code rate and normalization
+                        registers as they are after reset... */
+        {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
+                        only once */
+        {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
+                        estimation. It is <value>*65536 channel bits, i.e.
+                        approx. 38ms at 27.5MS/s, rate 3/4 */
+        {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
+                     /* leave front-end AGC parameters at default values */
+                     /* leave decimation AGC parameters at default values */
+        {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
+        {0x36,0xff}, /* clear all interrupt pending flags */
+        {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
+        {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
+                     /* leave the equalizer parameters on their default values */
+                     /* leave the final AGC parameters on their default values */
+        {0x41,0x00}, /* @ MSB of front-end derotator frequency */
+        {0x42,0x00}, /* @ middle bytes " */
+        {0x43,0x00}, /* @ LSB          " */
+                     /* leave the carrier tracking loop parameters on default */
+                     /* leave the bit timing loop parameters at default */
+        {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
+                     /* the cx24108 data sheet for symbol rates above 15MS/s */
+        {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
+        {0x61,0x95}, /* GPIO pins 1-4 have special function */
+        {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
+        {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
+        {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
+        {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
+        {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
+        {0x73,0x00}, /* @ disable several demod bypasses */
+        {0x74,0x00}, /* @  " */
+        {0x75,0x00}  /* @  " */
+                     /* the remaining registers are for SEC */
+       };
+
+
+static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
+{
+       u8 buf [] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+       int err;
+
+       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+               dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
+                        " data == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int cx24110_readreg (struct cx24110_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) return ret;
+
+       return b1[0];
+}
+
+static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
+{
+/* fixme (low): error handling */
+
+       switch (inversion) {
+       case INVERSION_OFF:
+               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
+               /* AcqSpectrInvDis on. No idea why someone should want this */
+               cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
+               /* Initial value 0 at start of acq */
+               cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
+               /* current value 0 */
+               /* The cx24110 manual tells us this reg is read-only.
+                  But what the heck... set it ayways */
+               break;
+       case INVERSION_ON:
+               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
+               /* AcqSpectrInvDis on. No idea why someone should want this */
+               cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
+               /* Initial value 1 at start of acq */
+               cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
+               /* current value 1 */
+               break;
+       case INVERSION_AUTO:
+               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
+               /* AcqSpectrInvDis off. Leave initial & current states as is */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
+{
+/* fixme (low): error handling */
+
+       static const int rate[]={-1,1,2,3,5,7,-1};
+       static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
+       static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
+
+       /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
+          searches all enabled viterbi rates, and can handle non-standard
+          rates as well. */
+
+       if (fec>FEC_AUTO)
+               fec=FEC_AUTO;
+
+       if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
+               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
+               /* clear AcqVitDis bit */
+               cx24110_writereg(state,0x18,0xae);
+               /* allow all DVB standard code rates */
+               cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
+               /* set nominal Viterbi rate 3/4 */
+               cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
+               /* set current Viterbi rate 3/4 */
+               cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
+               /* set the puncture registers for code rate 3/4 */
+               return 0;
+       } else {
+               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
+               /* set AcqVitDis bit */
+               if(rate[fec]>0) {
+                       cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
+                       /* set nominal Viterbi rate */
+                       cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
+                       /* set current Viterbi rate */
+                       cx24110_writereg(state,0x1a,g1[fec]);
+                       cx24110_writereg(state,0x1b,g2[fec]);
+                       /* not sure if this is the right way: I always used AutoAcq mode */
+          } else
+                  return -EOPNOTSUPP;
+/* fixme (low): which is the correct return code? */
+       };
+       return 0;
+}
+
+static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
+{
+       int i;
+
+       i=cx24110_readreg(state,0x22)&0x0f;
+       if(!(i&0x08)) {
+               return FEC_1_2 + i - 1;
+       } else {
+/* fixme (low): a special code rate has been selected. In theory, we need to
+   return a denominator value, a numerator value, and a pair of puncture
+   maps to correctly describe this mode. But this should never happen in
+   practice, because it cannot be set by cx24110_get_fec. */
+          return FEC_NONE;
+       }
+}
+
+static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
+{
+/* fixme (low): add error handling */
+       u32 ratio;
+       u32 tmp, fclk, BDRI;
+
+       static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
+       int i;
+
+       dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
+       if (srate>90999000UL/2)
+               srate=90999000UL/2;
+       if (srate<500000)
+               srate=500000;
+
+       for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++)
+               ;
+       /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
+          and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
+          R06[3:0] PLLphaseDetGain */
+       tmp=cx24110_readreg(state,0x07)&0xfc;
+       if(srate<90999000UL/4) { /* sample rate 45MHz*/
+               cx24110_writereg(state,0x07,tmp);
+               cx24110_writereg(state,0x06,0x78);
+               fclk=90999000UL/2;
+       } else if(srate<60666000UL/2) { /* sample rate 60MHz */
+               cx24110_writereg(state,0x07,tmp|0x1);
+               cx24110_writereg(state,0x06,0xa5);
+               fclk=60666000UL;
+       } else if(srate<80888000UL/2) { /* sample rate 80MHz */
+               cx24110_writereg(state,0x07,tmp|0x2);
+               cx24110_writereg(state,0x06,0x87);
+               fclk=80888000UL;
+       } else { /* sample rate 90MHz */
+               cx24110_writereg(state,0x07,tmp|0x3);
+               cx24110_writereg(state,0x06,0x78);
+               fclk=90999000UL;
+       };
+       dprintk("cx24110 debug: fclk %d Hz\n",fclk);
+       /* we need to divide two integers with approx. 27 bits in 32 bit
+          arithmetic giving a 25 bit result */
+       /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
+          also the most complex divisor. Hence, the dividend has,
+          assuming 32bit unsigned arithmetic, 6 clear bits on top, the
+          divisor 2 unused bits at the bottom. Also, the quotient is
+          always less than 1/2. Borrowed from VES1893.c, of course */
+
+       tmp=srate<<6;
+       BDRI=fclk>>2;
+       ratio=(tmp/BDRI);
+
+       tmp=(tmp%BDRI)<<8;
+       ratio=(ratio<<8)+(tmp/BDRI);
+
+       tmp=(tmp%BDRI)<<8;
+       ratio=(ratio<<8)+(tmp/BDRI);
+
+       tmp=(tmp%BDRI)<<1;
+       ratio=(ratio<<1)+(tmp/BDRI);
+
+       dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
+       dprintk("fclk = %d\n", fclk);
+       dprintk("ratio= %08x\n", ratio);
+
+       cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
+       cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
+       cx24110_writereg(state, 0x3, (ratio)&0xff);
+
+       return 0;
+
+}
+
+static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       if (len != 3)
+               return -EINVAL;
+
+/* tuner data is 21 bits long, must be left-aligned in data */
+/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
+/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
+
+       cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
+       cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
+
+       /* if the auto tuner writer is still busy, clear it out */
+       while (cx24110_readreg(state,0x6d)&0x80)
+               cx24110_writereg(state,0x72,0);
+
+       /* write the topmost 8 bits */
+       cx24110_writereg(state,0x72,buf[0]);
+
+       /* wait for the send to be completed */
+       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+               ;
+
+       /* send another 8 bytes */
+       cx24110_writereg(state,0x72,buf[1]);
+       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+               ;
+
+       /* and the topmost 5 bits of this byte */
+       cx24110_writereg(state,0x72,buf[2]);
+       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+               ;
+
+       /* now strobe the enable line once */
+       cx24110_writereg(state,0x6d,0x32);
+       cx24110_writereg(state,0x6d,0x30);
+
+       return 0;
+}
+
+static int cx24110_initfe(struct dvb_frontend* fe)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+/* fixme (low): error handling */
+       int i;
+
+       dprintk("%s: init chip\n", __func__);
+
+       for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
+               cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
+       };
+
+       return 0;
+}
+
+static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
+       case SEC_VOLTAGE_18:
+               return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
+       default:
+               return -EINVAL;
+       };
+}
+
+static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+       int rv, bit;
+       struct cx24110_state *state = fe->demodulator_priv;
+       unsigned long timeout;
+
+       if (burst == SEC_MINI_A)
+               bit = 0x00;
+       else if (burst == SEC_MINI_B)
+               bit = 0x08;
+       else
+               return -EINVAL;
+
+       rv = cx24110_readreg(state, 0x77);
+       if (!(rv & 0x04))
+               cx24110_writereg(state, 0x77, rv | 0x04);
+
+       rv = cx24110_readreg(state, 0x76);
+       cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
+       timeout = jiffies + msecs_to_jiffies(100);
+       while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
+               ; /* wait for LNB ready */
+
+       return 0;
+}
+
+static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
+                                  struct dvb_diseqc_master_cmd *cmd)
+{
+       int i, rv;
+       struct cx24110_state *state = fe->demodulator_priv;
+       unsigned long timeout;
+
+       if (cmd->msg_len < 3 || cmd->msg_len > 6)
+               return -EINVAL;  /* not implemented */
+
+       for (i = 0; i < cmd->msg_len; i++)
+               cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
+
+       rv = cx24110_readreg(state, 0x77);
+       if (rv & 0x04) {
+               cx24110_writereg(state, 0x77, rv & ~0x04);
+               msleep(30); /* reportedly fixes switching problems */
+       }
+
+       rv = cx24110_readreg(state, 0x76);
+
+       cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
+       timeout = jiffies + msecs_to_jiffies(100);
+       while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
+               ; /* wait for LNB ready */
+
+       return 0;
+}
+
+static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       int sync = cx24110_readreg (state, 0x55);
+
+       *status = 0;
+
+       if (sync & 0x10)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 0x08)
+               *status |= FE_HAS_CARRIER;
+
+       sync = cx24110_readreg (state, 0x08);
+
+       if (sync & 0x40)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 0x20)
+               *status |= FE_HAS_SYNC;
+
+       if ((sync & 0x60) == 0x60)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       /* fixme (maybe): value range is 16 bit. Scale? */
+       if(cx24110_readreg(state,0x24)&0x10) {
+               /* the Viterbi error counter has finished one counting window */
+               cx24110_writereg(state,0x24,0x04); /* select the ber reg */
+               state->lastber=cx24110_readreg(state,0x25)|
+                       (cx24110_readreg(state,0x26)<<8);
+               cx24110_writereg(state,0x24,0x04); /* start new count window */
+               cx24110_writereg(state,0x24,0x14);
+       }
+       *ber = state->lastber;
+
+       return 0;
+}
+
+static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
+       u8 signal = cx24110_readreg (state, 0x27)+128;
+       *signal_strength = (signal << 8) | signal;
+
+       return 0;
+}
+
+static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
+       if(cx24110_readreg(state,0x6a)&0x80) {
+               /* the Es/N0 error counter has finished one counting window */
+               state->lastesn0=cx24110_readreg(state,0x69)|
+                       (cx24110_readreg(state,0x68)<<8);
+               cx24110_writereg(state,0x6a,0x84); /* start new count window */
+       }
+       *snr = state->lastesn0;
+
+       return 0;
+}
+
+static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       if(cx24110_readreg(state,0x10)&0x40) {
+               /* the RS error counter has finished one counting window */
+               cx24110_writereg(state,0x10,0x60); /* select the byer reg */
+               (void)(cx24110_readreg(state, 0x12) |
+                       (cx24110_readreg(state, 0x13) << 8) |
+                       (cx24110_readreg(state, 0x14) << 16));
+               cx24110_writereg(state,0x10,0x70); /* select the bler reg */
+               state->lastbler=cx24110_readreg(state,0x12)|
+                       (cx24110_readreg(state,0x13)<<8)|
+                       (cx24110_readreg(state,0x14)<<16);
+               cx24110_writereg(state,0x10,0x20); /* start new count window */
+       }
+       *ucblocks = state->lastbler;
+
+       return 0;
+}
+
+static int cx24110_set_frontend(struct dvb_frontend *fe)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       cx24110_set_inversion(state, p->inversion);
+       cx24110_set_fec(state, p->fec_inner);
+       cx24110_set_symbolrate(state, p->symbol_rate);
+       cx24110_writereg(state,0x04,0x05); /* start acquisition */
+
+       return 0;
+}
+
+static int cx24110_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct cx24110_state *state = fe->demodulator_priv;
+       s32 afc; unsigned sclk;
+
+/* cannot read back tuner settings (freq). Need to have some private storage */
+
+       sclk = cx24110_readreg (state, 0x07) & 0x03;
+/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
+ * Need 64 bit arithmetic. Is thiss possible in the kernel? */
+       if (sclk==0) sclk=90999000L/2L;
+       else if (sclk==1) sclk=60666000L;
+       else if (sclk==2) sclk=80888000L;
+       else sclk=90999000L;
+       sclk>>=8;
+       afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
+             ((sclk*cx24110_readreg (state, 0x45))>>8)+
+             ((sclk*cx24110_readreg (state, 0x46))>>16);
+
+       p->frequency += afc;
+       p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
+                               INVERSION_ON : INVERSION_OFF;
+       p->fec_inner = cx24110_get_fec(state);
+
+       return 0;
+}
+
+static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
+}
+
+static void cx24110_release(struct dvb_frontend* fe)
+{
+       struct cx24110_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops cx24110_ops;
+
+struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct cx24110_state* state = NULL;
+       int ret;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->lastber = 0;
+       state->lastbler = 0;
+       state->lastesn0 = 0;
+
+       /* check if the demod is there */
+       ret = cx24110_readreg(state, 0x00);
+       if ((ret != 0x5a) && (ret != 0x69)) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops cx24110_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name = "Conexant CX24110 DVB-S",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1011,  /* kHz for QPSK frontends */
+               .frequency_tolerance = 29500,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_RECOVER
+       },
+
+       .release = cx24110_release,
+
+       .init = cx24110_initfe,
+       .write = _cx24110_pll_write,
+       .set_frontend = cx24110_set_frontend,
+       .get_frontend = cx24110_get_frontend,
+       .read_status = cx24110_read_status,
+       .read_ber = cx24110_read_ber,
+       .read_signal_strength = cx24110_read_signal_strength,
+       .read_snr = cx24110_read_snr,
+       .read_ucblocks = cx24110_read_ucblocks,
+
+       .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
+       .set_tone = cx24110_set_tone,
+       .set_voltage = cx24110_set_voltage,
+       .diseqc_send_burst = cx24110_diseqc_send_burst,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
+MODULE_AUTHOR("Peter Hettkamp");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(cx24110_attach);
diff --git a/drivers/media/dvb-frontends/cx24110.h b/drivers/media/dvb-frontends/cx24110.h
new file mode 100644 (file)
index 0000000..fdcceee
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+    cx24110 - Single Chip Satellite Channel Receiver driver module
+
+    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
+    work
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef CX24110_H
+#define CX24110_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx24110_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
+{
+       u8 buf[] = {
+               (u8)((val >> 24) & 0xff),
+               (u8)((val >> 16) & 0xff),
+               (u8)((val >> 8) & 0xff)
+       };
+
+       if (fe->ops.write)
+               return fe->ops.write(fe, buf, 3);
+       return 0;
+}
+
+#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
+extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
+                                                 struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_CX24110
+
+#endif // CX24110_H
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
new file mode 100644 (file)
index 0000000..3883c3b
--- /dev/null
@@ -0,0 +1,618 @@
+/*
+ *  Driver for Conexant CX24113/CX24128 Tuner (Satellite)
+ *
+ *  Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  Developed for BBTI / Technisat
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "dvb_frontend.h"
+#include "cx24113.h"
+
+static int debug;
+
+#define cx_info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0)
+#define cx_err(args...)  do { printk(KERN_ERR  "CX24113: " args); } while (0)
+
+#define dprintk(args...) \
+       do { \
+               if (debug) { \
+                       printk(KERN_DEBUG "CX24113: %s: ", __func__); \
+                       printk(args); \
+               } \
+       } while (0)
+
+struct cx24113_state {
+       struct i2c_adapter *i2c;
+       const struct cx24113_config *config;
+
+#define REV_CX24113 0x23
+       u8 rev;
+       u8 ver;
+
+       u8 icp_mode:1;
+
+#define ICP_LEVEL1 0
+#define ICP_LEVEL2 1
+#define ICP_LEVEL3 2
+#define ICP_LEVEL4 3
+       u8 icp_man:2;
+       u8 icp_auto_low:2;
+       u8 icp_auto_mlow:2;
+       u8 icp_auto_mhi:2;
+       u8 icp_auto_hi:2;
+       u8 icp_dig;
+
+#define LNA_MIN_GAIN 0
+#define LNA_MID_GAIN 1
+#define LNA_MAX_GAIN 2
+       u8 lna_gain:2;
+
+       u8 acp_on:1;
+
+       u8 vco_mode:2;
+       u8 vco_shift:1;
+#define VCOBANDSEL_6 0x80
+#define VCOBANDSEL_5 0x01
+#define VCOBANDSEL_4 0x02
+#define VCOBANDSEL_3 0x04
+#define VCOBANDSEL_2 0x08
+#define VCOBANDSEL_1 0x10
+       u8 vco_band;
+
+#define VCODIV4 4
+#define VCODIV2 2
+       u8 vcodiv;
+
+       u8 bs_delay:4;
+       u16 bs_freqcnt:13;
+       u16 bs_rdiv;
+       u8 prescaler_mode:1;
+
+       u8 rfvga_bias_ctrl;
+
+       s16 tuner_gain_thres;
+       u8  gain_level;
+
+       u32 frequency;
+
+       u8 refdiv;
+
+       u8 Fwindow_enabled;
+};
+
+static int cx24113_writereg(struct cx24113_state *state, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->i2c_addr,
+               .flags = 0, .buf = buf, .len = 2 };
+       int err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x,"
+                        " data == 0x%02x)\n", __func__, err, reg, data);
+               return err;
+       }
+
+       return 0;
+}
+
+static int cx24113_readreg(struct cx24113_state *state, u8 reg)
+{
+       int ret;
+       u8 b;
+       struct i2c_msg msg[] = {
+               { .addr = state->config->i2c_addr,
+                       .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = state->config->i2c_addr,
+                       .flags = I2C_M_RD, .buf = &b, .len = 1 }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n",
+                       __func__, reg, ret);
+               return ret;
+       }
+
+       return b;
+}
+
+static void cx24113_set_parameters(struct cx24113_state *state)
+{
+       u8 r;
+
+       r = cx24113_readreg(state, 0x10) & 0x82;
+       r |= state->icp_mode;
+       r |= state->icp_man << 4;
+       r |= state->icp_dig << 2;
+       r |= state->prescaler_mode << 5;
+       cx24113_writereg(state, 0x10, r);
+
+       r = (state->icp_auto_low  << 0) | (state->icp_auto_mlow << 2)
+               | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6);
+       cx24113_writereg(state, 0x11, r);
+
+       if (state->rev == REV_CX24113) {
+               r = cx24113_readreg(state, 0x20) & 0xec;
+               r |= state->lna_gain;
+               r |= state->rfvga_bias_ctrl << 4;
+               cx24113_writereg(state, 0x20, r);
+       }
+
+       r = cx24113_readreg(state, 0x12) & 0x03;
+       r |= state->acp_on << 2;
+       r |= state->bs_delay << 4;
+       cx24113_writereg(state, 0x12, r);
+
+       r = cx24113_readreg(state, 0x18) & 0x40;
+       r |= state->vco_shift;
+       if (state->vco_band == VCOBANDSEL_6)
+               r |= (1 << 7);
+       else
+               r |= (state->vco_band << 1);
+       cx24113_writereg(state, 0x18, r);
+
+       r  = cx24113_readreg(state, 0x14) & 0x20;
+       r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f);
+       cx24113_writereg(state, 0x14, r);
+       cx24113_writereg(state, 0x15, (state->bs_freqcnt        & 0xff));
+
+       cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff);
+       r = (cx24113_readreg(state, 0x17) & 0x0f) |
+               ((state->bs_rdiv & 0x0f) << 4);
+       cx24113_writereg(state, 0x17, r);
+}
+
+#define VGA_0 0x00
+#define VGA_1 0x04
+#define VGA_2 0x02
+#define VGA_3 0x06
+#define VGA_4 0x01
+#define VGA_5 0x05
+#define VGA_6 0x03
+#define VGA_7 0x07
+
+#define RFVGA_0 0x00
+#define RFVGA_1 0x01
+#define RFVGA_2 0x02
+#define RFVGA_3 0x03
+
+static int cx24113_set_gain_settings(struct cx24113_state *state,
+               s16 power_estimation)
+{
+       u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0,
+          vga    = cx24113_readreg(state, 0x1f) & 0x3f,
+          rfvga  = cx24113_readreg(state, 0x20) & 0xf3;
+       u8 gain_level = power_estimation >= state->tuner_gain_thres;
+
+       dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n",
+                       power_estimation, state->tuner_gain_thres,
+                       state->gain_level, gain_level);
+
+       if (gain_level == state->gain_level)
+               return 0; /* nothing to be done */
+
+       ampout |= 0xf;
+
+       if (gain_level) {
+               rfvga |= RFVGA_0 << 2;
+               vga   |= (VGA_7 << 3) | VGA_7;
+       } else {
+               rfvga |= RFVGA_2 << 2;
+               vga  |= (VGA_6 << 3) | VGA_2;
+       }
+       state->gain_level = gain_level;
+
+       cx24113_writereg(state, 0x1d, ampout);
+       cx24113_writereg(state, 0x1f, vga);
+       cx24113_writereg(state, 0x20, rfvga);
+
+       return 1; /* did something */
+}
+
+static int cx24113_set_Fref(struct cx24113_state *state, u8 high)
+{
+       u8 xtal = cx24113_readreg(state, 0x02);
+       if (state->rev == 0x43 && state->vcodiv == VCODIV4)
+               high = 1;
+
+       xtal &= ~0x2;
+       if (high)
+               xtal |= high << 1;
+       return cx24113_writereg(state, 0x02, xtal);
+}
+
+static int cx24113_enable(struct cx24113_state *state, u8 enable)
+{
+       u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable;
+       if (state->rev == REV_CX24113)
+               r21 |= (1 << 1);
+       return cx24113_writereg(state, 0x21, r21);
+}
+
+static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz)
+{
+       u8 r;
+
+       if (bandwidth_khz <= 19000)
+               r = 0x03 << 6;
+       else if (bandwidth_khz <= 25000)
+               r = 0x02 << 6;
+       else
+               r = 0x01 << 6;
+
+       dprintk("bandwidth to be set: %d\n", bandwidth_khz);
+       bandwidth_khz *= 10;
+       bandwidth_khz -= 10000;
+       bandwidth_khz /= 1000;
+       bandwidth_khz += 5;
+       bandwidth_khz /= 10;
+
+       dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz);
+
+       r |= bandwidth_khz & 0x3f;
+
+       return cx24113_writereg(state, 0x1e, r);
+}
+
+static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on)
+{
+       u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7);
+       return cx24113_writereg(state, 0x10, r);
+}
+
+static int cx24113_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct cx24113_state *state = fe->tuner_priv;
+       u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1;
+       if (r)
+               *status |= TUNER_STATUS_LOCKED;
+       dprintk("PLL locked: %d\n", r);
+       return 0;
+}
+
+static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv)
+{
+       if (state->rev == 0x43 && state->vcodiv == VCODIV4)
+               refdiv = 2;
+       return state->refdiv = refdiv;
+}
+
+static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
+{
+       s32 N;
+       s64 F;
+       u64 dividend;
+       u8 R, r;
+       u8 vcodiv;
+       u8 factor;
+       s32 freq_hz = state->frequency * 1000;
+
+       if (state->config->xtal_khz < 20000)
+               factor = 1;
+       else
+               factor = 2;
+
+       if (state->rev == REV_CX24113) {
+               if (state->frequency >= 1100000)
+                       vcodiv = VCODIV2;
+               else
+                       vcodiv = VCODIV4;
+       } else {
+               if (state->frequency >= 1165000)
+                       vcodiv = VCODIV2;
+               else
+                       vcodiv = VCODIV4;
+       }
+       state->vcodiv = vcodiv;
+
+       dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv);
+       R = 0;
+       do {
+               R = cx24113_set_ref_div(state, R + 1);
+
+               /* calculate tuner PLL settings: */
+               N =  (freq_hz / 100 * vcodiv) * R;
+               N /= (state->config->xtal_khz) * factor * 2;
+               N += 5;     /* For round up. */
+               N /= 10;
+               N -= 32;
+       } while (N < 6 && R < 3);
+
+       if (N < 6) {
+               cx_err("strange frequency: N < 6\n");
+               return;
+       }
+       F = freq_hz;
+       F *= (u64) (R * vcodiv * 262144);
+       dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
+       /* do_div needs an u64 as first argument */
+       dividend = F;
+       do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
+       F = dividend;
+       dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
+       F -= (N + 32) * 262144;
+
+       dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
+
+       if (state->Fwindow_enabled) {
+               if (F > (262144 / 2 - 1638))
+                       F = 262144 / 2 - 1638;
+               if (F < (-262144 / 2 + 1638))
+                       F = -262144 / 2 + 1638;
+               if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) {
+                       F = 0;
+                       r = cx24113_readreg(state, 0x10);
+                       cx24113_writereg(state, 0x10, r | (1 << 6));
+               }
+       }
+       dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
+
+       *n = (u16) N;
+       *f = (s32) F;
+}
+
+
+static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r)
+{
+       u8 reg;
+       cx24113_writereg(state, 0x19, (n >> 1) & 0xff);
+
+       reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f);
+       cx24113_writereg(state, 0x1a, reg);
+
+       cx24113_writereg(state, 0x1b, (f >> 3) & 0xff);
+
+       reg = cx24113_readreg(state, 0x1c) & 0x1f;
+       cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5));
+
+       cx24113_set_Fref(state, r - 1);
+}
+
+static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency)
+{
+       u8 r = 1; /* or 2 */
+       u16 n = 6;
+       s32 f = 0;
+
+       r = cx24113_readreg(state, 0x14);
+       cx24113_writereg(state, 0x14, r & 0x3f);
+
+       r = cx24113_readreg(state, 0x10);
+       cx24113_writereg(state, 0x10, r & 0xbf);
+
+       state->frequency = frequency;
+
+       dprintk("tuning to frequency: %d\n", frequency);
+
+       cx24113_calc_pll_nf(state, &n, &f);
+       cx24113_set_nfr(state, n, f, state->refdiv);
+
+       r = cx24113_readreg(state, 0x18) & 0xbf;
+       if (state->vcodiv != VCODIV2)
+               r |= 1 << 6;
+       cx24113_writereg(state, 0x18, r);
+
+       /* The need for this sleep is not clear. But helps in some cases */
+       msleep(5);
+
+       r = cx24113_readreg(state, 0x1c) & 0xef;
+       cx24113_writereg(state, 0x1c, r | (1 << 4));
+       return 0;
+}
+
+static int cx24113_init(struct dvb_frontend *fe)
+{
+       struct cx24113_state *state = fe->tuner_priv;
+       int ret;
+
+       state->tuner_gain_thres = -50;
+       state->gain_level = 255; /* to force a gain-setting initialization */
+       state->icp_mode = 0;
+
+       if (state->config->xtal_khz < 11000) {
+               state->icp_auto_hi  = ICP_LEVEL4;
+               state->icp_auto_mhi  = ICP_LEVEL4;
+               state->icp_auto_mlow = ICP_LEVEL3;
+               state->icp_auto_low = ICP_LEVEL3;
+       } else {
+               state->icp_auto_hi  = ICP_LEVEL4;
+               state->icp_auto_mhi  = ICP_LEVEL4;
+               state->icp_auto_mlow = ICP_LEVEL3;
+               state->icp_auto_low = ICP_LEVEL2;
+       }
+
+       state->icp_dig = ICP_LEVEL3;
+       state->icp_man = ICP_LEVEL1;
+       state->acp_on  = 1;
+       state->vco_mode = 0;
+       state->vco_shift = 0;
+       state->vco_band = VCOBANDSEL_1;
+       state->bs_delay = 8;
+       state->bs_freqcnt = 0x0fff;
+       state->bs_rdiv = 0x0fff;
+       state->prescaler_mode = 0;
+       state->lna_gain = LNA_MAX_GAIN;
+       state->rfvga_bias_ctrl = 1;
+       state->Fwindow_enabled = 1;
+
+       cx24113_set_Fref(state, 0);
+       cx24113_enable(state, 0x3d);
+       cx24113_set_parameters(state);
+
+       cx24113_set_gain_settings(state, -30);
+
+       cx24113_set_bandwidth(state, 18025);
+       cx24113_set_clk_inversion(state, 1);
+
+       if (state->config->xtal_khz >= 40000)
+               ret = cx24113_writereg(state, 0x02,
+                       (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2));
+       else
+               ret = cx24113_writereg(state, 0x02,
+                       (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2));
+
+       return ret;
+}
+
+static int cx24113_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct cx24113_state *state = fe->tuner_priv;
+       /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */
+       u32 roll_off = 675;
+       u32 bw;
+
+       bw  = ((c->symbol_rate/100) * roll_off) / 1000;
+       bw += (10000000/100) + 5;
+       bw /= 10;
+       bw += 1000;
+       cx24113_set_bandwidth(state, bw);
+
+       cx24113_set_frequency(state, c->frequency);
+       msleep(5);
+       return cx24113_get_status(fe, &bw);
+}
+
+static s8 cx24113_agc_table[2][10] = {
+       {-54, -41, -35, -30, -25, -21, -16, -10,  -6,  -2},
+       {-39, -35, -30, -25, -19, -15, -11,  -5,   1,   9},
+};
+
+void cx24113_agc_callback(struct dvb_frontend *fe)
+{
+       struct cx24113_state *state = fe->tuner_priv;
+       s16 s, i;
+       if (!fe->ops.read_signal_strength)
+               return;
+
+       do {
+               /* this only works with the current CX24123 implementation */
+               fe->ops.read_signal_strength(fe, (u16 *) &s);
+               s >>= 8;
+               dprintk("signal strength: %d\n", s);
+               for (i = 0; i < sizeof(cx24113_agc_table[0]); i++)
+                       if (cx24113_agc_table[state->gain_level][i] > s)
+                               break;
+               s = -25 - i*5;
+       } while (cx24113_set_gain_settings(state, s));
+}
+EXPORT_SYMBOL(cx24113_agc_callback);
+
+static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct cx24113_state *state = fe->tuner_priv;
+       *frequency = state->frequency;
+       return 0;
+}
+
+static int cx24113_release(struct dvb_frontend *fe)
+{
+       struct cx24113_state *state = fe->tuner_priv;
+       dprintk("\n");
+       fe->tuner_priv = NULL;
+       kfree(state);
+       return 0;
+}
+
+static const struct dvb_tuner_ops cx24113_tuner_ops = {
+       .info = {
+               .name           = "Conexant CX24113",
+               .frequency_min  = 950000,
+               .frequency_max  = 2150000,
+               .frequency_step = 125,
+       },
+
+       .release       = cx24113_release,
+
+       .init          = cx24113_init,
+
+       .set_params    = cx24113_set_params,
+       .get_frequency = cx24113_get_frequency,
+       .get_status    = cx24113_get_status,
+};
+
+struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
+               const struct cx24113_config *config, struct i2c_adapter *i2c)
+{
+       /* allocate memory for the internal state */
+       struct cx24113_state *state =
+               kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
+       int rc;
+       if (state == NULL) {
+               cx_err("Unable to kzalloc\n");
+               goto error;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       cx_info("trying to detect myself\n");
+
+       /* making a dummy read, because of some expected troubles
+        * after power on */
+       cx24113_readreg(state, 0x00);
+
+       rc = cx24113_readreg(state, 0x00);
+       if (rc < 0) {
+               cx_info("CX24113 not found.\n");
+               goto error;
+       }
+       state->rev = rc;
+
+       switch (rc) {
+       case 0x43:
+               cx_info("detected CX24113 variant\n");
+               break;
+       case REV_CX24113:
+               cx_info("successfully detected\n");
+               break;
+       default:
+               cx_err("unsupported device id: %x\n", state->rev);
+               goto error;
+       }
+       state->ver = cx24113_readreg(state, 0x01);
+       cx_info("version: %x\n", state->ver);
+
+       /* create dvb_frontend */
+       memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops,
+                       sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = state;
+       return fe;
+
+error:
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(cx24113_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
+MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb-frontends/cx24113.h b/drivers/media/dvb-frontends/cx24113.h
new file mode 100644 (file)
index 0000000..01eb7b9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Driver for Conexant CX24113/CX24128 Tuner (Satellite)
+ *
+ *  Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef CX24113_H
+#define CX24113_H
+
+struct dvb_frontend;
+
+struct cx24113_config {
+       u8 i2c_addr; /* 0x14 or 0x54 */
+
+       u32 xtal_khz;
+};
+
+#if defined(CONFIG_DVB_TUNER_CX24113) || \
+       (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
+extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
+       const struct cx24113_config *config, struct i2c_adapter *i2c);
+
+extern void cx24113_agc_callback(struct dvb_frontend *fe);
+#else
+static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
+       const struct cx24113_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline void cx24113_agc_callback(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+#endif
+
+#endif /* CX24113_H */
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
new file mode 100644 (file)
index 0000000..b488791
--- /dev/null
@@ -0,0 +1,1508 @@
+/*
+    Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
+
+    Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
+    Copyright (C) 2006-2007 Georg Acher
+    Copyright (C) 2007-2008 Darron Broad
+       March 2007
+           Fixed some bugs.
+           Added diseqc support.
+           Added corrected signal strength support.
+       August 2007
+           Sync with legacy version.
+           Some clean ups.
+    Copyright (C) 2008 Igor Liplianin
+       September, 9th 2008
+           Fixed locking on high symbol rates (>30000).
+           Implement MPEG initialization parameter.
+       January, 17th 2009
+           Fill set_voltage with actually control voltage code.
+           Correct set tone to not affect voltage.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "cx24116.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_INFO "cx24116: " args); \
+       } while (0)
+
+#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
+#define CX24116_SEARCH_RANGE_KHZ 5000
+
+/* known registers */
+#define CX24116_REG_COMMAND (0x00)      /* command args 0x00..0x1e */
+#define CX24116_REG_EXECUTE (0x1f)      /* execute command */
+#define CX24116_REG_MAILBOX (0x96)      /* FW or multipurpose mailbox? */
+#define CX24116_REG_RESET   (0x20)      /* reset status > 0     */
+#define CX24116_REG_SIGNAL  (0x9e)      /* signal low           */
+#define CX24116_REG_SSTATUS (0x9d)      /* signal high / status */
+#define CX24116_REG_QUALITY8 (0xa3)
+#define CX24116_REG_QSTATUS (0xbc)
+#define CX24116_REG_QUALITY0 (0xd5)
+#define CX24116_REG_BER0    (0xc9)
+#define CX24116_REG_BER8    (0xc8)
+#define CX24116_REG_BER16   (0xc7)
+#define CX24116_REG_BER24   (0xc6)
+#define CX24116_REG_UCB0    (0xcb)
+#define CX24116_REG_UCB8    (0xca)
+#define CX24116_REG_CLKDIV  (0xf3)
+#define CX24116_REG_RATEDIV (0xf9)
+
+/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
+#define CX24116_REG_FECSTATUS (0x9c)
+
+/* FECSTATUS bits */
+/* mask to determine configured fec (not tuned) or actual fec (tuned) */
+#define CX24116_FEC_FECMASK   (0x1f)
+
+/* Select DVB-S demodulator, else DVB-S2 */
+#define CX24116_FEC_DVBS      (0x20)
+#define CX24116_FEC_UNKNOWN   (0x40)    /* Unknown/unused */
+
+/* Pilot mode requested when tuning else always reset when tuned */
+#define CX24116_FEC_PILOT     (0x80)
+
+/* arg buffer size */
+#define CX24116_ARGLEN (0x1e)
+
+/* rolloff */
+#define CX24116_ROLLOFF_020 (0x00)
+#define CX24116_ROLLOFF_025 (0x01)
+#define CX24116_ROLLOFF_035 (0x02)
+
+/* pilot bit */
+#define CX24116_PILOT_OFF (0x00)
+#define CX24116_PILOT_ON (0x40)
+
+/* signal status */
+#define CX24116_HAS_SIGNAL   (0x01)
+#define CX24116_HAS_CARRIER  (0x02)
+#define CX24116_HAS_VITERBI  (0x04)
+#define CX24116_HAS_SYNCLOCK (0x08)
+#define CX24116_HAS_UNKNOWN1 (0x10)
+#define CX24116_HAS_UNKNOWN2 (0x20)
+#define CX24116_STATUS_MASK  (0x0f)
+#define CX24116_SIGNAL_MASK  (0xc0)
+
+#define CX24116_DISEQC_TONEOFF   (0)    /* toneburst never sent */
+#define CX24116_DISEQC_TONECACHE (1)    /* toneburst cached     */
+#define CX24116_DISEQC_MESGCACHE (2)    /* message cached       */
+
+/* arg offset for DiSEqC */
+#define CX24116_DISEQC_BURST  (1)
+#define CX24116_DISEQC_ARG2_2 (2)   /* unknown value=2 */
+#define CX24116_DISEQC_ARG3_0 (3)   /* unknown value=0 */
+#define CX24116_DISEQC_ARG4_0 (4)   /* unknown value=0 */
+#define CX24116_DISEQC_MSGLEN (5)
+#define CX24116_DISEQC_MSGOFS (6)
+
+/* DiSEqC burst */
+#define CX24116_DISEQC_MINI_A (0)
+#define CX24116_DISEQC_MINI_B (1)
+
+/* DiSEqC tone burst */
+static int toneburst = 1;
+module_param(toneburst, int, 0644);
+MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
+       "2=MESSAGE CACHE (default:1)");
+
+/* SNR measurements */
+static int esno_snr;
+module_param(esno_snr, int, 0644);
+MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
+       "1=ESNO(db * 10) (default:0)");
+
+enum cmds {
+       CMD_SET_VCO     = 0x10,
+       CMD_TUNEREQUEST = 0x11,
+       CMD_MPEGCONFIG  = 0x13,
+       CMD_TUNERINIT   = 0x14,
+       CMD_BANDWIDTH   = 0x15,
+       CMD_GETAGC      = 0x19,
+       CMD_LNBCONFIG   = 0x20,
+       CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
+       CMD_LNBDCLEVEL  = 0x22,
+       CMD_SET_TONE    = 0x23,
+       CMD_UPDFWVERS   = 0x35,
+       CMD_TUNERSLEEP  = 0x36,
+       CMD_AGCCONTROL  = 0x3b, /* Unknown */
+};
+
+/* The Demod/Tuner can't easily provide these, we cache them */
+struct cx24116_tuning {
+       u32 frequency;
+       u32 symbol_rate;
+       fe_spectral_inversion_t inversion;
+       fe_code_rate_t fec;
+
+       fe_delivery_system_t delsys;
+       fe_modulation_t modulation;
+       fe_pilot_t pilot;
+       fe_rolloff_t rolloff;
+
+       /* Demod values */
+       u8 fec_val;
+       u8 fec_mask;
+       u8 inversion_val;
+       u8 pilot_val;
+       u8 rolloff_val;
+};
+
+/* Basic commands that are sent to the firmware */
+struct cx24116_cmd {
+       u8 len;
+       u8 args[CX24116_ARGLEN];
+};
+
+struct cx24116_state {
+       struct i2c_adapter *i2c;
+       const struct cx24116_config *config;
+
+       struct dvb_frontend frontend;
+
+       struct cx24116_tuning dcur;
+       struct cx24116_tuning dnxt;
+
+       u8 skip_fw_load;
+       u8 burst;
+       struct cx24116_cmd dsec_cmd;
+};
+
+static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+               .flags = 0, .buf = buf, .len = 2 };
+       int err;
+
+       if (debug > 1)
+               printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
+                       __func__, reg, data);
+
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
+                        " value == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+/* Bulk byte writes to a single I2C address, for 32k firmware load */
+static int cx24116_writeregN(struct cx24116_state *state, int reg,
+                            const u8 *data, u16 len)
+{
+       int ret = -EREMOTEIO;
+       struct i2c_msg msg;
+       u8 *buf;
+
+       buf = kmalloc(len + 1, GFP_KERNEL);
+       if (buf == NULL) {
+               printk("Unable to kmalloc\n");
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       *(buf) = reg;
+       memcpy(buf + 1, data, len);
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.buf = buf;
+       msg.len = len + 1;
+
+       if (debug > 1)
+               printk(KERN_INFO "cx24116: %s:  write regN 0x%02x, len = %d\n",
+                       __func__, reg, len);
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+       if (ret != 1) {
+               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
+                        __func__, ret, reg);
+               ret = -EREMOTEIO;
+       }
+
+error:
+       kfree(buf);
+
+       return ret;
+}
+
+static int cx24116_readreg(struct cx24116_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0,
+                       .buf = b0, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD,
+                       .buf = b1, .len = 1 }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
+                       __func__, reg, ret);
+               return ret;
+       }
+
+       if (debug > 1)
+               printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
+                       reg, b1[0]);
+
+       return b1[0];
+}
+
+static int cx24116_set_inversion(struct cx24116_state *state,
+       fe_spectral_inversion_t inversion)
+{
+       dprintk("%s(%d)\n", __func__, inversion);
+
+       switch (inversion) {
+       case INVERSION_OFF:
+               state->dnxt.inversion_val = 0x00;
+               break;
+       case INVERSION_ON:
+               state->dnxt.inversion_val = 0x04;
+               break;
+       case INVERSION_AUTO:
+               state->dnxt.inversion_val = 0x0C;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       state->dnxt.inversion = inversion;
+
+       return 0;
+}
+
+/*
+ * modfec (modulation and FEC)
+ * ===========================
+ *
+ * MOD          FEC             mask/val    standard
+ * ----         --------        ----------- --------
+ * QPSK         FEC_1_2         0x02 0x02+X DVB-S
+ * QPSK         FEC_2_3         0x04 0x02+X DVB-S
+ * QPSK         FEC_3_4         0x08 0x02+X DVB-S
+ * QPSK         FEC_4_5         0x10 0x02+X DVB-S (?)
+ * QPSK         FEC_5_6         0x20 0x02+X DVB-S
+ * QPSK         FEC_6_7         0x40 0x02+X DVB-S
+ * QPSK         FEC_7_8         0x80 0x02+X DVB-S
+ * QPSK         FEC_8_9         0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
+ * QPSK         AUTO            0xff 0x02+X DVB-S
+ *
+ * For DVB-S high byte probably represents FEC
+ * and low byte selects the modulator. The high
+ * byte is search range mask. Bit 5 may turn
+ * on DVB-S and remaining bits represent some
+ * kind of calibration (how/what i do not know).
+ *
+ * Eg.(2/3) szap "Zone Horror"
+ *
+ * mask/val = 0x04, 0x20
+ * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
+ *
+ * mask/val = 0x04, 0x30
+ * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
+ *
+ * After tuning FECSTATUS contains actual FEC
+ * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
+ *
+ * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
+ *
+ * NBC-QPSK     FEC_1_2         0x00, 0x04      DVB-S2
+ * NBC-QPSK     FEC_3_5         0x00, 0x05      DVB-S2
+ * NBC-QPSK     FEC_2_3         0x00, 0x06      DVB-S2
+ * NBC-QPSK     FEC_3_4         0x00, 0x07      DVB-S2
+ * NBC-QPSK     FEC_4_5         0x00, 0x08      DVB-S2
+ * NBC-QPSK     FEC_5_6         0x00, 0x09      DVB-S2
+ * NBC-QPSK     FEC_8_9         0x00, 0x0a      DVB-S2
+ * NBC-QPSK     FEC_9_10        0x00, 0x0b      DVB-S2
+ *
+ * NBC-8PSK     FEC_3_5         0x00, 0x0c      DVB-S2
+ * NBC-8PSK     FEC_2_3         0x00, 0x0d      DVB-S2
+ * NBC-8PSK     FEC_3_4         0x00, 0x0e      DVB-S2
+ * NBC-8PSK     FEC_5_6         0x00, 0x0f      DVB-S2
+ * NBC-8PSK     FEC_8_9         0x00, 0x10      DVB-S2
+ * NBC-8PSK     FEC_9_10        0x00, 0x11      DVB-S2
+ *
+ * For DVB-S2 low bytes selects both modulator
+ * and FEC. High byte is meaningless here. To
+ * set pilot, bit 6 (0x40) is set. When inspecting
+ * FECSTATUS bit 7 (0x80) represents the pilot
+ * selection whilst not tuned. When tuned, actual FEC
+ * in use is found in FECSTATUS as per above. Pilot
+ * value is reset.
+ */
+
+/* A table of modulation, fec and configuration bytes for the demod.
+ * Not all S2 mmodulation schemes are support and not all rates with
+ * a scheme are support. Especially, no auto detect when in S2 mode.
+ */
+static struct cx24116_modfec {
+       fe_delivery_system_t delivery_system;
+       fe_modulation_t modulation;
+       fe_code_rate_t fec;
+       u8 mask;        /* In DVBS mode this is used to autodetect */
+       u8 val;         /* Passed to the firmware to indicate mode selection */
+} CX24116_MODFEC_MODES[] = {
+ /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
+
+ /*mod   fec       mask  val */
+ { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
+ { SYS_DVBS, QPSK, FEC_1_2,  0x02, 0x2e }, /* 00000010 00101110 */
+ { SYS_DVBS, QPSK, FEC_2_3,  0x04, 0x2f }, /* 00000100 00101111 */
+ { SYS_DVBS, QPSK, FEC_3_4,  0x08, 0x30 }, /* 00001000 00110000 */
+ { SYS_DVBS, QPSK, FEC_4_5,  0xfe, 0x30 }, /* 000?0000 ?        */
+ { SYS_DVBS, QPSK, FEC_5_6,  0x20, 0x31 }, /* 00100000 00110001 */
+ { SYS_DVBS, QPSK, FEC_6_7,  0xfe, 0x30 }, /* 0?000000 ?        */
+ { SYS_DVBS, QPSK, FEC_7_8,  0x80, 0x32 }, /* 10000000 00110010 */
+ { SYS_DVBS, QPSK, FEC_8_9,  0xfe, 0x30 }, /* 0000000? ?        */
+ { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
+ /* NBC-QPSK */
+ { SYS_DVBS2, QPSK, FEC_1_2,  0x00, 0x04 },
+ { SYS_DVBS2, QPSK, FEC_3_5,  0x00, 0x05 },
+ { SYS_DVBS2, QPSK, FEC_2_3,  0x00, 0x06 },
+ { SYS_DVBS2, QPSK, FEC_3_4,  0x00, 0x07 },
+ { SYS_DVBS2, QPSK, FEC_4_5,  0x00, 0x08 },
+ { SYS_DVBS2, QPSK, FEC_5_6,  0x00, 0x09 },
+ { SYS_DVBS2, QPSK, FEC_8_9,  0x00, 0x0a },
+ { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
+ /* 8PSK */
+ { SYS_DVBS2, PSK_8, FEC_3_5,  0x00, 0x0c },
+ { SYS_DVBS2, PSK_8, FEC_2_3,  0x00, 0x0d },
+ { SYS_DVBS2, PSK_8, FEC_3_4,  0x00, 0x0e },
+ { SYS_DVBS2, PSK_8, FEC_5_6,  0x00, 0x0f },
+ { SYS_DVBS2, PSK_8, FEC_8_9,  0x00, 0x10 },
+ { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
+ /*
+  * `val' can be found in the FECSTATUS register when tuning.
+  * FECSTATUS will give the actual FEC in use if tuning was successful.
+  */
+};
+
+static int cx24116_lookup_fecmod(struct cx24116_state *state,
+       fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
+{
+       int i, ret = -EOPNOTSUPP;
+
+       dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
+
+       for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
+               if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
+                       (m == CX24116_MODFEC_MODES[i].modulation) &&
+                       (f == CX24116_MODFEC_MODES[i].fec)) {
+                               ret = i;
+                               break;
+                       }
+       }
+
+       return ret;
+}
+
+static int cx24116_set_fec(struct cx24116_state *state,
+       fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
+{
+       int ret = 0;
+
+       dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
+
+       ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
+
+       if (ret < 0)
+               return ret;
+
+       state->dnxt.fec = fec;
+       state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
+       state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
+       dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
+               state->dnxt.fec_mask, state->dnxt.fec_val);
+
+       return 0;
+}
+
+static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
+{
+       dprintk("%s(%d)\n", __func__, rate);
+
+       /*  check if symbol rate is within limits */
+       if ((rate > state->frontend.ops.info.symbol_rate_max) ||
+           (rate < state->frontend.ops.info.symbol_rate_min)) {
+               dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
+               return -EOPNOTSUPP;
+       }
+
+       state->dnxt.symbol_rate = rate;
+       dprintk("%s() symbol_rate = %d\n", __func__, rate);
+
+       return 0;
+}
+
+static int cx24116_load_firmware(struct dvb_frontend *fe,
+       const struct firmware *fw);
+
+static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       const struct firmware *fw;
+       int ret = 0;
+
+       dprintk("%s()\n", __func__);
+
+       if (cx24116_readreg(state, 0x20) > 0) {
+
+               if (state->skip_fw_load)
+                       return 0;
+
+               /* Load firmware */
+               /* request the firmware, this will block until loaded */
+               printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
+                       __func__, CX24116_DEFAULT_FIRMWARE);
+               ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
+                       state->i2c->dev.parent);
+               printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
+                       __func__);
+               if (ret) {
+                       printk(KERN_ERR "%s: No firmware uploaded "
+                               "(timeout or file not found?)\n", __func__);
+                       return ret;
+               }
+
+               /* Make sure we don't recurse back through here
+                * during loading */
+               state->skip_fw_load = 1;
+
+               ret = cx24116_load_firmware(fe, fw);
+               if (ret)
+                       printk(KERN_ERR "%s: Writing firmware to device failed\n",
+                               __func__);
+
+               release_firmware(fw);
+
+               printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
+                       ret == 0 ? "complete" : "failed");
+
+               /* Ensure firmware is always loaded if required */
+               state->skip_fw_load = 0;
+       }
+
+       return ret;
+}
+
+/* Take a basic firmware command structure, format it
+ * and forward it for processing
+ */
+static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       int i, ret;
+
+       dprintk("%s()\n", __func__);
+
+       /* Load the firmware if required */
+       ret = cx24116_firmware_ondemand(fe);
+       if (ret != 0) {
+               printk(KERN_ERR "%s(): Unable initialise the firmware\n",
+                       __func__);
+               return ret;
+       }
+
+       /* Write the command */
+       for (i = 0; i < cmd->len ; i++) {
+               dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
+               cx24116_writereg(state, i, cmd->args[i]);
+       }
+
+       /* Start execution and wait for cmd to terminate */
+       cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
+       while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
+               msleep(10);
+               if (i++ > 64) {
+                       /* Avoid looping forever if the firmware does
+                               not respond */
+                       printk(KERN_WARNING "%s() Firmware not responding\n",
+                               __func__);
+                       return -EREMOTEIO;
+               }
+       }
+       return 0;
+}
+
+static int cx24116_load_firmware(struct dvb_frontend *fe,
+       const struct firmware *fw)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct cx24116_cmd cmd;
+       int i, ret, len, max, remaining;
+       unsigned char vers[4];
+
+       dprintk("%s\n", __func__);
+       dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+                       fw->size,
+                       fw->data[0],
+                       fw->data[1],
+                       fw->data[fw->size-2],
+                       fw->data[fw->size-1]);
+
+       /* Toggle 88x SRST pin to reset demod */
+       if (state->config->reset_device)
+               state->config->reset_device(fe);
+
+       /* Begin the firmware load process */
+       /* Prepare the demod, load the firmware, cleanup after load */
+
+       /* Init PLL */
+       cx24116_writereg(state, 0xE5, 0x00);
+       cx24116_writereg(state, 0xF1, 0x08);
+       cx24116_writereg(state, 0xF2, 0x13);
+
+       /* Start PLL */
+       cx24116_writereg(state, 0xe0, 0x03);
+       cx24116_writereg(state, 0xe0, 0x00);
+
+       /* Unknown */
+       cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
+       cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
+
+       /* Unknown */
+       cx24116_writereg(state, 0xF0, 0x03);
+       cx24116_writereg(state, 0xF4, 0x81);
+       cx24116_writereg(state, 0xF5, 0x00);
+       cx24116_writereg(state, 0xF6, 0x00);
+
+       /* Split firmware to the max I2C write len and write.
+        * Writes whole firmware as one write when i2c_wr_max is set to 0. */
+       if (state->config->i2c_wr_max)
+               max = state->config->i2c_wr_max;
+       else
+               max = INT_MAX; /* enough for 32k firmware */
+
+       for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
+               len = remaining;
+               if (len > max - 1)
+                       len = max - 1;
+
+               cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
+                       len);
+       }
+
+       cx24116_writereg(state, 0xF4, 0x10);
+       cx24116_writereg(state, 0xF0, 0x00);
+       cx24116_writereg(state, 0xF8, 0x06);
+
+       /* Firmware CMD 10: VCO config */
+       cmd.args[0x00] = CMD_SET_VCO;
+       cmd.args[0x01] = 0x05;
+       cmd.args[0x02] = 0xdc;
+       cmd.args[0x03] = 0xda;
+       cmd.args[0x04] = 0xae;
+       cmd.args[0x05] = 0xaa;
+       cmd.args[0x06] = 0x04;
+       cmd.args[0x07] = 0x9d;
+       cmd.args[0x08] = 0xfc;
+       cmd.args[0x09] = 0x06;
+       cmd.len = 0x0a;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
+
+       /* Firmware CMD 14: Tuner config */
+       cmd.args[0x00] = CMD_TUNERINIT;
+       cmd.args[0x01] = 0x00;
+       cmd.args[0x02] = 0x00;
+       cmd.len = 0x03;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       cx24116_writereg(state, 0xe5, 0x00);
+
+       /* Firmware CMD 13: MPEG config */
+       cmd.args[0x00] = CMD_MPEGCONFIG;
+       cmd.args[0x01] = 0x01;
+       cmd.args[0x02] = 0x75;
+       cmd.args[0x03] = 0x00;
+       if (state->config->mpg_clk_pos_pol)
+               cmd.args[0x04] = state->config->mpg_clk_pos_pol;
+       else
+               cmd.args[0x04] = 0x02;
+       cmd.args[0x05] = 0x00;
+       cmd.len = 0x06;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       /* Firmware CMD 35: Get firmware version */
+       cmd.args[0x00] = CMD_UPDFWVERS;
+       cmd.len = 0x02;
+       for (i = 0; i < 4; i++) {
+               cmd.args[0x01] = i;
+               ret = cx24116_cmd_execute(fe, &cmd);
+               if (ret != 0)
+                       return ret;
+               vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
+       }
+       printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
+               vers[0], vers[1], vers[2], vers[3]);
+
+       return 0;
+}
+
+static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+
+       int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
+               CX24116_STATUS_MASK;
+
+       dprintk("%s: status = 0x%02x\n", __func__, lock);
+
+       *status = 0;
+
+       if (lock & CX24116_HAS_SIGNAL)
+               *status |= FE_HAS_SIGNAL;
+       if (lock & CX24116_HAS_CARRIER)
+               *status |= FE_HAS_CARRIER;
+       if (lock & CX24116_HAS_VITERBI)
+               *status |= FE_HAS_VITERBI;
+       if (lock & CX24116_HAS_SYNCLOCK)
+               *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       *ber =  (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
+               (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
+               (cx24116_readreg(state, CX24116_REG_BER8)  << 8)  |
+                cx24116_readreg(state, CX24116_REG_BER0);
+
+       return 0;
+}
+
+/* TODO Determine function and scale appropriately */
+static int cx24116_read_signal_strength(struct dvb_frontend *fe,
+       u16 *signal_strength)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct cx24116_cmd cmd;
+       int ret;
+       u16 sig_reading;
+
+       dprintk("%s()\n", __func__);
+
+       /* Firmware CMD 19: Get AGC */
+       cmd.args[0x00] = CMD_GETAGC;
+       cmd.len = 0x01;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       sig_reading =
+               (cx24116_readreg(state,
+                       CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
+               (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
+       *signal_strength = 0 - sig_reading;
+
+       dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
+               __func__, sig_reading, *signal_strength);
+
+       return 0;
+}
+
+/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
+static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       u8 snr_reading;
+       static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
+               0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
+               0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
+               0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
+               0x18000 };
+
+       dprintk("%s()\n", __func__);
+
+       snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
+
+       if (snr_reading >= 0xa0 /* 100% */)
+               *snr = 0xffff;
+       else
+               *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
+                       (snr_tab[(snr_reading & 0x0f)] >> 4);
+
+       dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+               snr_reading, *snr);
+
+       return 0;
+}
+
+/* The reelbox patches show the value in the registers represents
+ * ESNO, from 0->30db (values 0->300). We provide this value by
+ * default.
+ */
+static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
+               cx24116_readreg(state, CX24116_REG_QUALITY0);
+
+       dprintk("%s: raw 0x%04x\n", __func__, *snr);
+
+       return 0;
+}
+
+static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       if (esno_snr == 1)
+               return cx24116_read_snr_esno(fe, snr);
+       else
+               return cx24116_read_snr_pct(fe, snr);
+}
+
+static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
+               cx24116_readreg(state, CX24116_REG_UCB0);
+
+       return 0;
+}
+
+/* Overwrite the current tuning params, we are about to tune */
+static void cx24116_clone_params(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
+}
+
+/* Wait for LNB */
+static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       int i;
+
+       dprintk("%s() qstatus = 0x%02x\n", __func__,
+               cx24116_readreg(state, CX24116_REG_QSTATUS));
+
+       /* Wait for up to 300 ms */
+       for (i = 0; i < 30 ; i++) {
+               if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
+                       return 0;
+               msleep(10);
+       }
+
+       dprintk("%s(): LNB not ready\n", __func__);
+
+       return -ETIMEDOUT; /* -EBUSY ? */
+}
+
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+       fe_sec_voltage_t voltage)
+{
+       struct cx24116_cmd cmd;
+       int ret;
+
+       dprintk("%s: %s\n", __func__,
+               voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+               voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+       /* Wait for LNB ready */
+       ret = cx24116_wait_for_lnb(fe);
+       if (ret != 0)
+               return ret;
+
+       /* Wait for voltage/min repeat delay */
+       msleep(100);
+
+       cmd.args[0x00] = CMD_LNBDCLEVEL;
+       cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+       cmd.len = 0x02;
+
+       /* Min delay time before DiSEqC send */
+       msleep(15);
+
+       return cx24116_cmd_execute(fe, &cmd);
+}
+
+static int cx24116_set_tone(struct dvb_frontend *fe,
+       fe_sec_tone_mode_t tone)
+{
+       struct cx24116_cmd cmd;
+       int ret;
+
+       dprintk("%s(%d)\n", __func__, tone);
+       if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
+               printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
+               return -EINVAL;
+       }
+
+       /* Wait for LNB ready */
+       ret = cx24116_wait_for_lnb(fe);
+       if (ret != 0)
+               return ret;
+
+       /* Min delay time after DiSEqC send */
+       msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
+
+       /* Now we set the tone */
+       cmd.args[0x00] = CMD_SET_TONE;
+       cmd.args[0x01] = 0x00;
+       cmd.args[0x02] = 0x00;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               dprintk("%s: setting tone on\n", __func__);
+               cmd.args[0x03] = 0x01;
+               break;
+       case SEC_TONE_OFF:
+               dprintk("%s: setting tone off\n", __func__);
+               cmd.args[0x03] = 0x00;
+               break;
+       }
+       cmd.len = 0x04;
+
+       /* Min delay time before DiSEqC send */
+       msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
+
+       return cx24116_cmd_execute(fe, &cmd);
+}
+
+/* Initialise DiSEqC */
+static int cx24116_diseqc_init(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct cx24116_cmd cmd;
+       int ret;
+
+       /* Firmware CMD 20: LNB/DiSEqC config */
+       cmd.args[0x00] = CMD_LNBCONFIG;
+       cmd.args[0x01] = 0x00;
+       cmd.args[0x02] = 0x10;
+       cmd.args[0x03] = 0x00;
+       cmd.args[0x04] = 0x8f;
+       cmd.args[0x05] = 0x28;
+       cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
+       cmd.args[0x07] = 0x01;
+       cmd.len = 0x08;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       /* Prepare a DiSEqC command */
+       state->dsec_cmd.args[0x00] = CMD_LNBSEND;
+
+       /* DiSEqC burst */
+       state->dsec_cmd.args[CX24116_DISEQC_BURST]  = CX24116_DISEQC_MINI_A;
+
+       /* Unknown */
+       state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
+       state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
+       /* Continuation flag? */
+       state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
+
+       /* DiSEqC message length */
+       state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
+
+       /* Command length */
+       state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
+
+       return 0;
+}
+
+/* Send DiSEqC message with derived burst (hack) || previous burst */
+static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
+       struct dvb_diseqc_master_cmd *d)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       int i, ret;
+
+       /* Dump DiSEqC message */
+       if (debug) {
+               printk(KERN_INFO "cx24116: %s(", __func__);
+               for (i = 0 ; i < d->msg_len ;) {
+                       printk(KERN_INFO "0x%02x", d->msg[i]);
+                       if (++i < d->msg_len)
+                               printk(KERN_INFO ", ");
+               }
+               printk(") toneburst=%d\n", toneburst);
+       }
+
+       /* Validate length */
+       if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
+               return -EINVAL;
+
+       /* DiSEqC message */
+       for (i = 0; i < d->msg_len; i++)
+               state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
+
+       /* DiSEqC message length */
+       state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
+
+       /* Command length */
+       state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
+               state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
+
+       /* DiSEqC toneburst */
+       if (toneburst == CX24116_DISEQC_MESGCACHE)
+               /* Message is cached */
+               return 0;
+
+       else if (toneburst == CX24116_DISEQC_TONEOFF)
+               /* Message is sent without burst */
+               state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
+
+       else if (toneburst == CX24116_DISEQC_TONECACHE) {
+               /*
+                * Message is sent with derived else cached burst
+                *
+                * WRITE PORT GROUP COMMAND 38
+                *
+                * 0/A/A: E0 10 38 F0..F3
+                * 1/B/B: E0 10 38 F4..F7
+                * 2/C/A: E0 10 38 F8..FB
+                * 3/D/B: E0 10 38 FC..FF
+                *
+                * databyte[3]= 8421:8421
+                *              ABCD:WXYZ
+                *              CLR :SET
+                *
+                *              WX= PORT SELECT 0..3    (X=TONEBURST)
+                *              Y = VOLTAGE             (0=13V, 1=18V)
+                *              Z = BAND                (0=LOW, 1=HIGH(22K))
+                */
+               if (d->msg_len >= 4 && d->msg[2] == 0x38)
+                       state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+                               ((d->msg[3] & 4) >> 2);
+               if (debug)
+                       dprintk("%s burst=%d\n", __func__,
+                               state->dsec_cmd.args[CX24116_DISEQC_BURST]);
+       }
+
+       /* Wait for LNB ready */
+       ret = cx24116_wait_for_lnb(fe);
+       if (ret != 0)
+               return ret;
+
+       /* Wait for voltage/min repeat delay */
+       msleep(100);
+
+       /* Command */
+       ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
+       if (ret != 0)
+               return ret;
+       /*
+        * Wait for send
+        *
+        * Eutelsat spec:
+        * >15ms delay          + (XXX determine if FW does this, see set_tone)
+        *  13.5ms per byte     +
+        * >15ms delay          +
+        *  12.5ms burst        +
+        * >15ms delay            (XXX determine if FW does this, see set_tone)
+        */
+       msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
+               ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
+
+       return 0;
+}
+
+/* Send DiSEqC burst */
+static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
+       fe_sec_mini_cmd_t burst)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       int ret;
+
+       dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
+
+       /* DiSEqC burst */
+       if (burst == SEC_MINI_A)
+               state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+                       CX24116_DISEQC_MINI_A;
+       else if (burst == SEC_MINI_B)
+               state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+                       CX24116_DISEQC_MINI_B;
+       else
+               return -EINVAL;
+
+       /* DiSEqC toneburst */
+       if (toneburst != CX24116_DISEQC_MESGCACHE)
+               /* Burst is cached */
+               return 0;
+
+       /* Burst is to be sent with cached message */
+
+       /* Wait for LNB ready */
+       ret = cx24116_wait_for_lnb(fe);
+       if (ret != 0)
+               return ret;
+
+       /* Wait for voltage/min repeat delay */
+       msleep(100);
+
+       /* Command */
+       ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
+       if (ret != 0)
+               return ret;
+
+       /*
+        * Wait for send
+        *
+        * Eutelsat spec:
+        * >15ms delay          + (XXX determine if FW does this, see set_tone)
+        *  13.5ms per byte     +
+        * >15ms delay          +
+        *  12.5ms burst        +
+        * >15ms delay            (XXX determine if FW does this, see set_tone)
+        */
+       msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
+
+       return 0;
+}
+
+static void cx24116_release(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       dprintk("%s\n", __func__);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops cx24116_ops;
+
+struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
+       struct i2c_adapter *i2c)
+{
+       struct cx24116_state *state = NULL;
+       int ret;
+
+       dprintk("%s\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error1;
+
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is present */
+       ret = (cx24116_readreg(state, 0xFF) << 8) |
+               cx24116_readreg(state, 0xFE);
+       if (ret != 0x0501) {
+               printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
+               goto error2;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &cx24116_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error2: kfree(state);
+error1: return NULL;
+}
+EXPORT_SYMBOL(cx24116_attach);
+
+/*
+ * Initialise or wake up device
+ *
+ * Power config will reset and load initial firmware if required
+ */
+static int cx24116_initfe(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct cx24116_cmd cmd;
+       int ret;
+
+       dprintk("%s()\n", __func__);
+
+       /* Power on */
+       cx24116_writereg(state, 0xe0, 0);
+       cx24116_writereg(state, 0xe1, 0);
+       cx24116_writereg(state, 0xea, 0);
+
+       /* Firmware CMD 36: Power config */
+       cmd.args[0x00] = CMD_TUNERSLEEP;
+       cmd.args[0x01] = 0;
+       cmd.len = 0x02;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       ret = cx24116_diseqc_init(fe);
+       if (ret != 0)
+               return ret;
+
+       /* HVR-4000 needs this */
+       return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
+}
+
+/*
+ * Put device to sleep
+ */
+static int cx24116_sleep(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct cx24116_cmd cmd;
+       int ret;
+
+       dprintk("%s()\n", __func__);
+
+       /* Firmware CMD 36: Power config */
+       cmd.args[0x00] = CMD_TUNERSLEEP;
+       cmd.args[0x01] = 1;
+       cmd.len = 0x02;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       /* Power off (Shutdown clocks) */
+       cx24116_writereg(state, 0xea, 0xff);
+       cx24116_writereg(state, 0xe1, 1);
+       cx24116_writereg(state, 0xe0, 1);
+
+       return 0;
+}
+
+/* dvb-core told us to tune, the tv property cache will be complete,
+ * it's safe for is to pull values and use them for tuning purposes.
+ */
+static int cx24116_set_frontend(struct dvb_frontend *fe)
+{
+       struct cx24116_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct cx24116_cmd cmd;
+       fe_status_t tunerstat;
+       int i, status, ret, retune = 1;
+
+       dprintk("%s()\n", __func__);
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               dprintk("%s: DVB-S delivery system selected\n", __func__);
+
+               /* Only QPSK is supported for DVB-S */
+               if (c->modulation != QPSK) {
+                       dprintk("%s: unsupported modulation selected (%d)\n",
+                               __func__, c->modulation);
+                       return -EOPNOTSUPP;
+               }
+
+               /* Pilot doesn't exist in DVB-S, turn bit off */
+               state->dnxt.pilot_val = CX24116_PILOT_OFF;
+
+               /* DVB-S only supports 0.35 */
+               if (c->rolloff != ROLLOFF_35) {
+                       dprintk("%s: unsupported rolloff selected (%d)\n",
+                               __func__, c->rolloff);
+                       return -EOPNOTSUPP;
+               }
+               state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
+               break;
+
+       case SYS_DVBS2:
+               dprintk("%s: DVB-S2 delivery system selected\n", __func__);
+
+               /*
+                * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
+                * but not hardware auto detection
+                */
+               if (c->modulation != PSK_8 && c->modulation != QPSK) {
+                       dprintk("%s: unsupported modulation selected (%d)\n",
+                               __func__, c->modulation);
+                       return -EOPNOTSUPP;
+               }
+
+               switch (c->pilot) {
+               case PILOT_AUTO:        /* Not supported but emulated */
+                       state->dnxt.pilot_val = (c->modulation == QPSK)
+                               ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
+                       retune++;
+                       break;
+               case PILOT_OFF:
+                       state->dnxt.pilot_val = CX24116_PILOT_OFF;
+                       break;
+               case PILOT_ON:
+                       state->dnxt.pilot_val = CX24116_PILOT_ON;
+                       break;
+               default:
+                       dprintk("%s: unsupported pilot mode selected (%d)\n",
+                               __func__, c->pilot);
+                       return -EOPNOTSUPP;
+               }
+
+               switch (c->rolloff) {
+               case ROLLOFF_20:
+                       state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
+                       break;
+               case ROLLOFF_25:
+                       state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
+                       break;
+               case ROLLOFF_35:
+                       state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
+                       break;
+               case ROLLOFF_AUTO:      /* Rolloff must be explicit */
+               default:
+                       dprintk("%s: unsupported rolloff selected (%d)\n",
+                               __func__, c->rolloff);
+                       return -EOPNOTSUPP;
+               }
+               break;
+
+       default:
+               dprintk("%s: unsupported delivery system selected (%d)\n",
+                       __func__, c->delivery_system);
+               return -EOPNOTSUPP;
+       }
+       state->dnxt.delsys = c->delivery_system;
+       state->dnxt.modulation = c->modulation;
+       state->dnxt.frequency = c->frequency;
+       state->dnxt.pilot = c->pilot;
+       state->dnxt.rolloff = c->rolloff;
+
+       ret = cx24116_set_inversion(state, c->inversion);
+       if (ret !=  0)
+               return ret;
+
+       /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
+       ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
+       if (ret !=  0)
+               return ret;
+
+       ret = cx24116_set_symbolrate(state, c->symbol_rate);
+       if (ret !=  0)
+               return ret;
+
+       /* discard the 'current' tuning parameters and prepare to tune */
+       cx24116_clone_params(fe);
+
+       dprintk("%s:   delsys      = %d\n", __func__, state->dcur.delsys);
+       dprintk("%s:   modulation  = %d\n", __func__, state->dcur.modulation);
+       dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
+       dprintk("%s:   pilot       = %d (val = 0x%02x)\n", __func__,
+               state->dcur.pilot, state->dcur.pilot_val);
+       dprintk("%s:   retune      = %d\n", __func__, retune);
+       dprintk("%s:   rolloff     = %d (val = 0x%02x)\n", __func__,
+               state->dcur.rolloff, state->dcur.rolloff_val);
+       dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
+       dprintk("%s:   FEC         = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
+               state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
+       dprintk("%s:   Inversion   = %d (val = 0x%02x)\n", __func__,
+               state->dcur.inversion, state->dcur.inversion_val);
+
+       /* This is also done in advise/acquire on HVR4000 but not on LITE */
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+
+       /* Set/Reset B/W */
+       cmd.args[0x00] = CMD_BANDWIDTH;
+       cmd.args[0x01] = 0x01;
+       cmd.len = 0x02;
+       ret = cx24116_cmd_execute(fe, &cmd);
+       if (ret != 0)
+               return ret;
+
+       /* Prepare a tune request */
+       cmd.args[0x00] = CMD_TUNEREQUEST;
+
+       /* Frequency */
+       cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
+       cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
+       cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
+
+       /* Symbol Rate */
+       cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
+       cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
+
+       /* Automatic Inversion */
+       cmd.args[0x06] = state->dcur.inversion_val;
+
+       /* Modulation / FEC / Pilot */
+       cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
+
+       cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
+       cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
+       cmd.args[0x0a] = 0x00;
+       cmd.args[0x0b] = 0x00;
+       cmd.args[0x0c] = state->dcur.rolloff_val;
+       cmd.args[0x0d] = state->dcur.fec_mask;
+
+       if (state->dcur.symbol_rate > 30000000) {
+               cmd.args[0x0e] = 0x04;
+               cmd.args[0x0f] = 0x00;
+               cmd.args[0x10] = 0x01;
+               cmd.args[0x11] = 0x77;
+               cmd.args[0x12] = 0x36;
+               cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
+               cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
+       } else {
+               cmd.args[0x0e] = 0x06;
+               cmd.args[0x0f] = 0x00;
+               cmd.args[0x10] = 0x00;
+               cmd.args[0x11] = 0xFA;
+               cmd.args[0x12] = 0x24;
+               cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
+               cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
+       }
+
+       cmd.len = 0x13;
+
+       /* We need to support pilot and non-pilot tuning in the
+        * driver automatically. This is a workaround for because
+        * the demod does not support autodetect.
+        */
+       do {
+               /* Reset status register */
+               status = cx24116_readreg(state, CX24116_REG_SSTATUS)
+                       & CX24116_SIGNAL_MASK;
+               cx24116_writereg(state, CX24116_REG_SSTATUS, status);
+
+               /* Tune */
+               ret = cx24116_cmd_execute(fe, &cmd);
+               if (ret != 0)
+                       break;
+
+               /*
+                * Wait for up to 500 ms before retrying
+                *
+                * If we are able to tune then generally it occurs within 100ms.
+                * If it takes longer, try a different toneburst setting.
+                */
+               for (i = 0; i < 50 ; i++) {
+                       cx24116_read_status(fe, &tunerstat);
+                       status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
+                       if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
+                               dprintk("%s: Tuned\n", __func__);
+                               goto tuned;
+                       }
+                       msleep(10);
+               }
+
+               dprintk("%s: Not tuned\n", __func__);
+
+               /* Toggle pilot bit when in auto-pilot */
+               if (state->dcur.pilot == PILOT_AUTO)
+                       cmd.args[0x07] ^= CX24116_PILOT_ON;
+       } while (--retune);
+
+tuned:  /* Set/Reset B/W */
+       cmd.args[0x00] = CMD_BANDWIDTH;
+       cmd.args[0x01] = 0x00;
+       cmd.len = 0x02;
+       return cx24116_cmd_execute(fe, &cmd);
+}
+
+static int cx24116_tune(struct dvb_frontend *fe, bool re_tune,
+       unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
+{
+       /*
+        * It is safe to discard "params" here, as the DVB core will sync
+        * fe->dtv_property_cache with fepriv->parameters_in, where the
+        * DVBv3 params are stored. The only practical usage for it indicate
+        * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is
+        * true.
+        */
+
+       *delay = HZ / 5;
+       if (re_tune) {
+               int ret = cx24116_set_frontend(fe);
+               if (ret)
+                       return ret;
+       }
+       return cx24116_read_status(fe, status);
+}
+
+static int cx24116_get_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_HW;
+}
+
+static struct dvb_frontend_ops cx24116_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2 },
+       .info = {
+               .name = "Conexant CX24116/CX24118",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
+               .frequency_tolerance = 5000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_INVERSION_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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_2G_MODULATION |
+                       FE_CAN_QPSK | FE_CAN_RECOVER
+       },
+
+       .release = cx24116_release,
+
+       .init = cx24116_initfe,
+       .sleep = cx24116_sleep,
+       .read_status = cx24116_read_status,
+       .read_ber = cx24116_read_ber,
+       .read_signal_strength = cx24116_read_signal_strength,
+       .read_snr = cx24116_read_snr,
+       .read_ucblocks = cx24116_read_ucblocks,
+       .set_tone = cx24116_set_tone,
+       .set_voltage = cx24116_set_voltage,
+       .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
+       .diseqc_send_burst = cx24116_diseqc_send_burst,
+       .get_frontend_algo = cx24116_get_algo,
+       .tune = cx24116_tune,
+
+       .set_frontend = cx24116_set_frontend,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb-frontends/cx24116.h b/drivers/media/dvb-frontends/cx24116.h
new file mode 100644 (file)
index 0000000..7d90ab9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
+
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CX24116_H
+#define CX24116_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx24116_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* Need to set device param for start_dma */
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+
+       /* Need to reset device during firmware loading */
+       int (*reset_device)(struct dvb_frontend *fe);
+
+       /* Need to set MPEG parameters */
+       u8 mpg_clk_pos_pol:0x02;
+
+       /* max bytes I2C provider can write at once */
+       u16 i2c_wr_max;
+};
+
+#if defined(CONFIG_DVB_CX24116) || \
+       (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE))
+extern struct dvb_frontend *cx24116_attach(
+       const struct cx24116_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *cx24116_attach(
+       const struct cx24116_config *config,
+       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* CX24116_H */
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
new file mode 100644 (file)
index 0000000..7e28b4e
--- /dev/null
@@ -0,0 +1,1165 @@
+/*
+ *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
+ *
+ *   Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
+ *
+ *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
+ *
+ *   Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation; either version 2 of
+ *   the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "dvb_frontend.h"
+#include "cx24123.h"
+
+#define XTAL 10111000
+
+static int force_band;
+module_param(force_band, int, 0644);
+MODULE_PARM_DESC(force_band, "Force a specific band select "\
+       "(1-9, default:off).");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
+#define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
+
+#define dprintk(args...) \
+       do { \
+               if (debug) { \
+                       printk(KERN_DEBUG "CX24123: %s: ", __func__); \
+                       printk(args); \
+               } \
+       } while (0)
+
+struct cx24123_state {
+       struct i2c_adapter *i2c;
+       const struct cx24123_config *config;
+
+       struct dvb_frontend frontend;
+
+       /* Some PLL specifics for tuning */
+       u32 VCAarg;
+       u32 VGAarg;
+       u32 bandselectarg;
+       u32 pllarg;
+       u32 FILTune;
+
+       struct i2c_adapter tuner_i2c_adapter;
+
+       u8 demod_rev;
+
+       /* The Demod/Tuner can't easily provide these, we cache them */
+       u32 currentfreq;
+       u32 currentsymbolrate;
+};
+
+/* Various tuner defaults need to be established for a given symbol rate Sps */
+static struct cx24123_AGC_val {
+       u32 symbolrate_low;
+       u32 symbolrate_high;
+       u32 VCAprogdata;
+       u32 VGAprogdata;
+       u32 FILTune;
+} cx24123_AGC_vals[] =
+{
+       {
+               .symbolrate_low         = 1000000,
+               .symbolrate_high        = 4999999,
+               /* the specs recommend other values for VGA offsets,
+                  but tests show they are wrong */
+               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x07,
+               .FILTune                = 0x27f /* 0.41 V */
+       },
+       {
+               .symbolrate_low         =  5000000,
+               .symbolrate_high        = 14999999,
+               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x1f,
+               .FILTune                = 0x317 /* 0.90 V */
+       },
+       {
+               .symbolrate_low         = 15000000,
+               .symbolrate_high        = 45000000,
+               .VGAprogdata            = (1 << 19) | (0x100 << 9) | 0x180,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x3f,
+               .FILTune                = 0x145 /* 2.70 V */
+       },
+};
+
+/*
+ * Various tuner defaults need to be established for a given frequency kHz.
+ * fixme: The bounds on the bands do not match the doc in real life.
+ * fixme: Some of them have been moved, other might need adjustment.
+ */
+static struct cx24123_bandselect_val {
+       u32 freq_low;
+       u32 freq_high;
+       u32 VCOdivider;
+       u32 progdata;
+} cx24123_bandselect_vals[] =
+{
+       /* band 1 */
+       {
+               .freq_low       = 950000,
+               .freq_high      = 1074999,
+               .VCOdivider     = 4,
+               .progdata       = (0 << 19) | (0 << 9) | 0x40,
+       },
+
+       /* band 2 */
+       {
+               .freq_low       = 1075000,
+               .freq_high      = 1177999,
+               .VCOdivider     = 4,
+               .progdata       = (0 << 19) | (0 << 9) | 0x80,
+       },
+
+       /* band 3 */
+       {
+               .freq_low       = 1178000,
+               .freq_high      = 1295999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x01,
+       },
+
+       /* band 4 */
+       {
+               .freq_low       = 1296000,
+               .freq_high      = 1431999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x02,
+       },
+
+       /* band 5 */
+       {
+               .freq_low       = 1432000,
+               .freq_high      = 1575999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x04,
+       },
+
+       /* band 6 */
+       {
+               .freq_low       = 1576000,
+               .freq_high      = 1717999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x08,
+       },
+
+       /* band 7 */
+       {
+               .freq_low       = 1718000,
+               .freq_high      = 1855999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x10,
+       },
+
+       /* band 8 */
+       {
+               .freq_low       = 1856000,
+               .freq_high      = 2035999,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x20,
+       },
+
+       /* band 9 */
+       {
+               .freq_low       = 2036000,
+               .freq_high      = 2150000,
+               .VCOdivider     = 2,
+               .progdata       = (0 << 19) | (1 << 9) | 0x40,
+       },
+};
+
+static struct {
+       u8 reg;
+       u8 data;
+} cx24123_regdata[] =
+{
+       {0x00, 0x03}, /* Reset system */
+       {0x00, 0x00}, /* Clear reset */
+       {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
+       {0x04, 0x10}, /* MPEG */
+       {0x05, 0x04}, /* MPEG */
+       {0x06, 0x31}, /* MPEG (default) */
+       {0x0b, 0x00}, /* Freq search start point (default) */
+       {0x0c, 0x00}, /* Demodulator sample gain (default) */
+       {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
+       {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
+       {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
+       {0x10, 0x01}, /* Default search inversion, no repeat (default) */
+       {0x16, 0x00}, /* Enable reading of frequency */
+       {0x17, 0x01}, /* Enable EsNO Ready Counter */
+       {0x1c, 0x80}, /* Enable error counter */
+       {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
+       {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
+       {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
+       {0x29, 0x00}, /* DiSEqC LNB_DC off */
+       {0x2a, 0xb0}, /* DiSEqC Parameters (default) */
+       {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
+       {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
+       {0x2d, 0x00},
+       {0x2e, 0x00},
+       {0x2f, 0x00},
+       {0x30, 0x00},
+       {0x31, 0x00},
+       {0x32, 0x8c}, /* DiSEqC Parameters (default) */
+       {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
+       {0x34, 0x00},
+       {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
+       {0x36, 0x02}, /* DiSEqC Parameters (default) */
+       {0x37, 0x3a}, /* DiSEqC Parameters (default) */
+       {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
+       {0x44, 0x00}, /* Constellation (default) */
+       {0x45, 0x00}, /* Symbol count (default) */
+       {0x46, 0x0d}, /* Symbol rate estimator on (default) */
+       {0x56, 0xc1}, /* Error Counter = Viterbi BER */
+       {0x57, 0xff}, /* Error Counter Window (default) */
+       {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
+       {0x67, 0x83}, /* Non-DCII symbol clock */
+};
+
+static int cx24123_i2c_writereg(struct cx24123_state *state,
+       u8 i2c_addr, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+       };
+       int err;
+
+       /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
+
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("%s: writereg error(err == %i, reg == 0x%02x,"
+                        " data == 0x%02x)\n", __func__, err, reg, data);
+               return err;
+       }
+
+       return 0;
+}
+
+static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
+{
+       int ret;
+       u8 b = 0;
+       struct i2c_msg msg[] = {
+               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
+               return ret;
+       }
+
+       /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
+
+       return b;
+}
+
+#define cx24123_readreg(state, reg) \
+       cx24123_i2c_readreg(state, state->config->demod_address, reg)
+#define cx24123_writereg(state, reg, val) \
+       cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
+
+static int cx24123_set_inversion(struct cx24123_state *state,
+       fe_spectral_inversion_t inversion)
+{
+       u8 nom_reg = cx24123_readreg(state, 0x0e);
+       u8 auto_reg = cx24123_readreg(state, 0x10);
+
+       switch (inversion) {
+       case INVERSION_OFF:
+               dprintk("inversion off\n");
+               cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
+               cx24123_writereg(state, 0x10, auto_reg | 0x80);
+               break;
+       case INVERSION_ON:
+               dprintk("inversion on\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x80);
+               cx24123_writereg(state, 0x10, auto_reg | 0x80);
+               break;
+       case INVERSION_AUTO:
+               dprintk("inversion auto\n");
+               cx24123_writereg(state, 0x10, auto_reg & ~0x80);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cx24123_get_inversion(struct cx24123_state *state,
+       fe_spectral_inversion_t *inversion)
+{
+       u8 val;
+
+       val = cx24123_readreg(state, 0x1b) >> 7;
+
+       if (val == 0) {
+               dprintk("read inversion off\n");
+               *inversion = INVERSION_OFF;
+       } else {
+               dprintk("read inversion on\n");
+               *inversion = INVERSION_ON;
+       }
+
+       return 0;
+}
+
+static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
+{
+       u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
+
+       if ((fec < FEC_NONE) || (fec > FEC_AUTO))
+               fec = FEC_AUTO;
+
+       /* Set the soft decision threshold */
+       if (fec == FEC_1_2)
+               cx24123_writereg(state, 0x43,
+                       cx24123_readreg(state, 0x43) | 0x01);
+       else
+               cx24123_writereg(state, 0x43,
+                       cx24123_readreg(state, 0x43) & ~0x01);
+
+       switch (fec) {
+       case FEC_1_2:
+               dprintk("set FEC to 1/2\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x01);
+               cx24123_writereg(state, 0x0f, 0x02);
+               break;
+       case FEC_2_3:
+               dprintk("set FEC to 2/3\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x02);
+               cx24123_writereg(state, 0x0f, 0x04);
+               break;
+       case FEC_3_4:
+               dprintk("set FEC to 3/4\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x03);
+               cx24123_writereg(state, 0x0f, 0x08);
+               break;
+       case FEC_4_5:
+               dprintk("set FEC to 4/5\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x04);
+               cx24123_writereg(state, 0x0f, 0x10);
+               break;
+       case FEC_5_6:
+               dprintk("set FEC to 5/6\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x05);
+               cx24123_writereg(state, 0x0f, 0x20);
+               break;
+       case FEC_6_7:
+               dprintk("set FEC to 6/7\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x06);
+               cx24123_writereg(state, 0x0f, 0x40);
+               break;
+       case FEC_7_8:
+               dprintk("set FEC to 7/8\n");
+               cx24123_writereg(state, 0x0e, nom_reg | 0x07);
+               cx24123_writereg(state, 0x0f, 0x80);
+               break;
+       case FEC_AUTO:
+               dprintk("set FEC to auto\n");
+               cx24123_writereg(state, 0x0f, 0xfe);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec)
+{
+       int ret;
+
+       ret = cx24123_readreg(state, 0x1b);
+       if (ret < 0)
+               return ret;
+       ret = ret & 0x07;
+
+       switch (ret) {
+       case 1:
+               *fec = FEC_1_2;
+               break;
+       case 2:
+               *fec = FEC_2_3;
+               break;
+       case 3:
+               *fec = FEC_3_4;
+               break;
+       case 4:
+               *fec = FEC_4_5;
+               break;
+       case 5:
+               *fec = FEC_5_6;
+               break;
+       case 6:
+               *fec = FEC_6_7;
+               break;
+       case 7:
+               *fec = FEC_7_8;
+               break;
+       default:
+               /* this can happen when there's no lock */
+               *fec = FEC_NONE;
+       }
+
+       return 0;
+}
+
+/* Approximation of closest integer of log2(a/b). It actually gives the
+   lowest integer i such that 2^i >= round(a/b) */
+static u32 cx24123_int_log2(u32 a, u32 b)
+{
+       u32 exp, nearest = 0;
+       u32 div = a / b;
+       if (a % b >= b / 2)
+               ++div;
+       if (div < (1 << 31)) {
+               for (exp = 1; div > exp; nearest++)
+                       exp += exp;
+       }
+       return nearest;
+}
+
+static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
+{
+       u32 tmp, sample_rate, ratio, sample_gain;
+       u8 pll_mult;
+
+       /*  check if symbol rate is within limits */
+       if ((srate > state->frontend.ops.info.symbol_rate_max) ||
+           (srate < state->frontend.ops.info.symbol_rate_min))
+               return -EOPNOTSUPP;
+
+       /* choose the sampling rate high enough for the required operation,
+          while optimizing the power consumed by the demodulator */
+       if (srate < (XTAL*2)/2)
+               pll_mult = 2;
+       else if (srate < (XTAL*3)/2)
+               pll_mult = 3;
+       else if (srate < (XTAL*4)/2)
+               pll_mult = 4;
+       else if (srate < (XTAL*5)/2)
+               pll_mult = 5;
+       else if (srate < (XTAL*6)/2)
+               pll_mult = 6;
+       else if (srate < (XTAL*7)/2)
+               pll_mult = 7;
+       else if (srate < (XTAL*8)/2)
+               pll_mult = 8;
+       else
+               pll_mult = 9;
+
+
+       sample_rate = pll_mult * XTAL;
+
+       /*
+           SYSSymbolRate[21:0] = (srate << 23) / sample_rate
+
+           We have to use 32 bit unsigned arithmetic without precision loss.
+           The maximum srate is 45000000 or 0x02AEA540. This number has
+           only 6 clear bits on top, hence we can shift it left only 6 bits
+           at a time. Borrowed from cx24110.c
+       */
+
+       tmp = srate << 6;
+       ratio = tmp / sample_rate;
+
+       tmp = (tmp % sample_rate) << 6;
+       ratio = (ratio << 6) + (tmp / sample_rate);
+
+       tmp = (tmp % sample_rate) << 6;
+       ratio = (ratio << 6) + (tmp / sample_rate);
+
+       tmp = (tmp % sample_rate) << 5;
+       ratio = (ratio << 5) + (tmp / sample_rate);
+
+
+       cx24123_writereg(state, 0x01, pll_mult * 6);
+
+       cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
+       cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
+       cx24123_writereg(state, 0x0a, ratio & 0xff);
+
+       /* also set the demodulator sample gain */
+       sample_gain = cx24123_int_log2(sample_rate, srate);
+       tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
+       cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
+
+       dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
+               srate, ratio, sample_rate, sample_gain);
+
+       return 0;
+}
+
+/*
+ * Based on the required frequency and symbolrate, the tuner AGC has
+ * to be configured and the correct band selected.
+ * Calculate those values.
+ */
+static int cx24123_pll_calculate(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct cx24123_state *state = fe->demodulator_priv;
+       u32 ndiv = 0, adiv = 0, vco_div = 0;
+       int i = 0;
+       int pump = 2;
+       int band = 0;
+       int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
+       struct cx24123_bandselect_val *bsv = NULL;
+       struct cx24123_AGC_val *agcv = NULL;
+
+       /* Defaults for low freq, low rate */
+       state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
+       state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
+       state->bandselectarg = cx24123_bandselect_vals[0].progdata;
+       vco_div = cx24123_bandselect_vals[0].VCOdivider;
+
+       /* For the given symbol rate, determine the VCA, VGA and
+        * FILTUNE programming bits */
+       for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
+               agcv = &cx24123_AGC_vals[i];
+               if ((agcv->symbolrate_low <= p->symbol_rate) &&
+                   (agcv->symbolrate_high >= p->symbol_rate)) {
+                       state->VCAarg = agcv->VCAprogdata;
+                       state->VGAarg = agcv->VGAprogdata;
+                       state->FILTune = agcv->FILTune;
+               }
+       }
+
+       /* determine the band to use */
+       if (force_band < 1 || force_band > num_bands) {
+               for (i = 0; i < num_bands; i++) {
+                       bsv = &cx24123_bandselect_vals[i];
+                       if ((bsv->freq_low <= p->frequency) &&
+                               (bsv->freq_high >= p->frequency))
+                               band = i;
+               }
+       } else
+               band = force_band - 1;
+
+       state->bandselectarg = cx24123_bandselect_vals[band].progdata;
+       vco_div = cx24123_bandselect_vals[band].VCOdivider;
+
+       /* determine the charge pump current */
+       if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
+               cx24123_bandselect_vals[band].freq_high) / 2)
+               pump = 0x01;
+       else
+               pump = 0x02;
+
+       /* Determine the N/A dividers for the requested lband freq (in kHz). */
+       /* Note: the reference divider R=10, frequency is in KHz,
+        * XTAL is in Hz */
+       ndiv = (((p->frequency * vco_div * 10) /
+               (2 * XTAL / 1000)) / 32) & 0x1ff;
+       adiv = (((p->frequency * vco_div * 10) /
+               (2 * XTAL / 1000)) % 32) & 0x1f;
+
+       if (adiv == 0 && ndiv > 0)
+               ndiv--;
+
+       /* control bits 11, refdiv 11, charge pump polarity 1,
+        * charge pump current, ndiv, adiv */
+       state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
+               (pump << 14) | (ndiv << 5) | adiv;
+
+       return 0;
+}
+
+/*
+ * Tuner data is 21 bits long, must be left-aligned in data.
+ * Tuner cx24109 is written through a dedicated 3wire interface
+ * on the demod chip.
+ */
+static int cx24123_pll_writereg(struct dvb_frontend *fe, u32 data)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       unsigned long timeout;
+
+       dprintk("pll writereg called, data=0x%08x\n", data);
+
+       /* align the 21 bytes into to bit23 boundary */
+       data = data << 3;
+
+       /* Reset the demod pll word length to 0x15 bits */
+       cx24123_writereg(state, 0x21, 0x15);
+
+       /* write the msb 8 bits, wait for the send to be completed */
+       timeout = jiffies + msecs_to_jiffies(40);
+       cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
+       while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
+               if (time_after(jiffies, timeout)) {
+                       err("%s:  demodulator is not responding, "\
+                               "possibly hung, aborting.\n", __func__);
+                       return -EREMOTEIO;
+               }
+               msleep(10);
+       }
+
+       /* send another 8 bytes, wait for the send to be completed */
+       timeout = jiffies + msecs_to_jiffies(40);
+       cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
+       while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
+               if (time_after(jiffies, timeout)) {
+                       err("%s:  demodulator is not responding, "\
+                               "possibly hung, aborting.\n", __func__);
+                       return -EREMOTEIO;
+               }
+               msleep(10);
+       }
+
+       /* send the lower 5 bits of this byte, padded with 3 LBB,
+        * wait for the send to be completed */
+       timeout = jiffies + msecs_to_jiffies(40);
+       cx24123_writereg(state, 0x22, (data) & 0xff);
+       while ((cx24123_readreg(state, 0x20) & 0x80)) {
+               if (time_after(jiffies, timeout)) {
+                       err("%s:  demodulator is not responding," \
+                               "possibly hung, aborting.\n", __func__);
+                       return -EREMOTEIO;
+               }
+               msleep(10);
+       }
+
+       /* Trigger the demod to configure the tuner */
+       cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
+       cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
+
+       return 0;
+}
+
+static int cx24123_pll_tune(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct cx24123_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("frequency=%i\n", p->frequency);
+
+       if (cx24123_pll_calculate(fe) != 0) {
+               err("%s: cx24123_pll_calcutate failed\n", __func__);
+               return -EINVAL;
+       }
+
+       /* Write the new VCO/VGA */
+       cx24123_pll_writereg(fe, state->VCAarg);
+       cx24123_pll_writereg(fe, state->VGAarg);
+
+       /* Write the new bandselect and pll args */
+       cx24123_pll_writereg(fe, state->bandselectarg);
+       cx24123_pll_writereg(fe, state->pllarg);
+
+       /* set the FILTUNE voltage */
+       val = cx24123_readreg(state, 0x28) & ~0x3;
+       cx24123_writereg(state, 0x27, state->FILTune >> 2);
+       cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
+
+       dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
+                       state->bandselectarg, state->pllarg);
+
+       return 0;
+}
+
+
+/*
+ * 0x23:
+ *    [7:7] = BTI enabled
+ *    [6:6] = I2C repeater enabled
+ *    [5:5] = I2C repeater start
+ *    [0:0] = BTI start
+ */
+
+/* mode == 1 -> i2c-repeater, 0 -> bti */
+static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
+{
+       u8 r = cx24123_readreg(state, 0x23) & 0x1e;
+       if (mode)
+               r |= (1 << 6) | (start << 5);
+       else
+               r |= (1 << 7) | (start);
+       return cx24123_writereg(state, 0x23, r);
+}
+
+static int cx24123_initfe(struct dvb_frontend *fe)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       int i;
+
+       dprintk("init frontend\n");
+
+       /* Configure the demod to a good set of defaults */
+       for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
+               cx24123_writereg(state, cx24123_regdata[i].reg,
+                       cx24123_regdata[i].data);
+
+       /* Set the LNB polarity */
+       if (state->config->lnb_polarity)
+               cx24123_writereg(state, 0x32,
+                       cx24123_readreg(state, 0x32) | 0x02);
+
+       if (state->config->dont_use_pll)
+               cx24123_repeater_mode(state, 1, 0);
+
+       return 0;
+}
+
+static int cx24123_set_voltage(struct dvb_frontend *fe,
+       fe_sec_voltage_t voltage)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       u8 val;
+
+       val = cx24123_readreg(state, 0x29) & ~0x40;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               dprintk("setting voltage 13V\n");
+               return cx24123_writereg(state, 0x29, val & 0x7f);
+       case SEC_VOLTAGE_18:
+               dprintk("setting voltage 18V\n");
+               return cx24123_writereg(state, 0x29, val | 0x80);
+       case SEC_VOLTAGE_OFF:
+               /* already handled in cx88-dvb */
+               return 0;
+       default:
+               return -EINVAL;
+       };
+
+       return 0;
+}
+
+/* wait for diseqc queue to become ready (or timeout) */
+static void cx24123_wait_for_diseqc(struct cx24123_state *state)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(200);
+       while (!(cx24123_readreg(state, 0x29) & 0x40)) {
+               if (time_after(jiffies, timeout)) {
+                       err("%s: diseqc queue not ready, " \
+                               "command may be lost.\n", __func__);
+                       break;
+               }
+               msleep(10);
+       }
+}
+
+static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
+       struct dvb_diseqc_master_cmd *cmd)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       int i, val, tone;
+
+       dprintk("\n");
+
+       /* stop continuous tone if enabled */
+       tone = cx24123_readreg(state, 0x29);
+       if (tone & 0x10)
+               cx24123_writereg(state, 0x29, tone & ~0x50);
+
+       /* wait for diseqc queue ready */
+       cx24123_wait_for_diseqc(state);
+
+       /* select tone mode */
+       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
+
+       for (i = 0; i < cmd->msg_len; i++)
+               cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
+
+       val = cx24123_readreg(state, 0x29);
+       cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
+               ((cmd->msg_len-3) & 3));
+
+       /* wait for diseqc message to finish sending */
+       cx24123_wait_for_diseqc(state);
+
+       /* restart continuous tone if enabled */
+       if (tone & 0x10)
+               cx24123_writereg(state, 0x29, tone & ~0x40);
+
+       return 0;
+}
+
+static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
+       fe_sec_mini_cmd_t burst)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       int val, tone;
+
+       dprintk("\n");
+
+       /* stop continuous tone if enabled */
+       tone = cx24123_readreg(state, 0x29);
+       if (tone & 0x10)
+               cx24123_writereg(state, 0x29, tone & ~0x50);
+
+       /* wait for diseqc queue ready */
+       cx24123_wait_for_diseqc(state);
+
+       /* select tone mode */
+       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
+       msleep(30);
+       val = cx24123_readreg(state, 0x29);
+       if (burst == SEC_MINI_A)
+               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
+       else if (burst == SEC_MINI_B)
+               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
+       else
+               return -EINVAL;
+
+       cx24123_wait_for_diseqc(state);
+       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
+
+       /* restart continuous tone if enabled */
+       if (tone & 0x10)
+               cx24123_writereg(state, 0x29, tone & ~0x40);
+
+       return 0;
+}
+
+static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       int sync = cx24123_readreg(state, 0x14);
+
+       *status = 0;
+       if (state->config->dont_use_pll) {
+               u32 tun_status = 0;
+               if (fe->ops.tuner_ops.get_status)
+                       fe->ops.tuner_ops.get_status(fe, &tun_status);
+               if (tun_status & TUNER_STATUS_LOCKED)
+                       *status |= FE_HAS_SIGNAL;
+       } else {
+               int lock = cx24123_readreg(state, 0x20);
+               if (lock & 0x01)
+                       *status |= FE_HAS_SIGNAL;
+       }
+
+       if (sync & 0x02)
+               *status |= FE_HAS_CARRIER;      /* Phase locked */
+       if (sync & 0x04)
+               *status |= FE_HAS_VITERBI;
+
+       /* Reed-Solomon Status */
+       if (sync & 0x08)
+               *status |= FE_HAS_SYNC;
+       if (sync & 0x80)
+               *status |= FE_HAS_LOCK;         /*Full Sync */
+
+       return 0;
+}
+
+/*
+ * Configured to return the measurement of errors in blocks,
+ * because no UCBLOCKS value is available, so this value doubles up
+ * to satisfy both measurements.
+ */
+static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+
+       /* The true bit error rate is this value divided by
+          the window size (set as 256 * 255) */
+       *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
+               (cx24123_readreg(state, 0x1d) << 8 |
+                cx24123_readreg(state, 0x1e));
+
+       dprintk("BER = %d\n", *ber);
+
+       return 0;
+}
+
+static int cx24123_read_signal_strength(struct dvb_frontend *fe,
+       u16 *signal_strength)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+
+       /* larger = better */
+       *signal_strength = cx24123_readreg(state, 0x3b) << 8;
+
+       dprintk("Signal strength = %d\n", *signal_strength);
+
+       return 0;
+}
+
+static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+
+       /* Inverted raw Es/N0 count, totally bogus but better than the
+          BER threshold. */
+       *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
+                        (u16)cx24123_readreg(state, 0x19));
+
+       dprintk("read S/N index = %d\n", *snr);
+
+       return 0;
+}
+
+static int cx24123_set_frontend(struct dvb_frontend *fe)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       dprintk("\n");
+
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+
+       state->currentfreq = p->frequency;
+       state->currentsymbolrate = p->symbol_rate;
+
+       cx24123_set_inversion(state, p->inversion);
+       cx24123_set_fec(state, p->fec_inner);
+       cx24123_set_symbolrate(state, p->symbol_rate);
+
+       if (!state->config->dont_use_pll)
+               cx24123_pll_tune(fe);
+       else if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+       else
+               err("it seems I don't have a tuner...");
+
+       /* Enable automatic acquisition and reset cycle */
+       cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
+       cx24123_writereg(state, 0x00, 0x10);
+       cx24123_writereg(state, 0x00, 0);
+
+       if (state->config->agc_callback)
+               state->config->agc_callback(fe);
+
+       return 0;
+}
+
+static int cx24123_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct cx24123_state *state = fe->demodulator_priv;
+
+       dprintk("\n");
+
+       if (cx24123_get_inversion(state, &p->inversion) != 0) {
+               err("%s: Failed to get inversion status\n", __func__);
+               return -EREMOTEIO;
+       }
+       if (cx24123_get_fec(state, &p->fec_inner) != 0) {
+               err("%s: Failed to get fec status\n", __func__);
+               return -EREMOTEIO;
+       }
+       p->frequency = state->currentfreq;
+       p->symbol_rate = state->currentsymbolrate;
+
+       return 0;
+}
+
+static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       u8 val;
+
+       /* wait for diseqc queue ready */
+       cx24123_wait_for_diseqc(state);
+
+       val = cx24123_readreg(state, 0x29) & ~0x40;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               dprintk("setting tone on\n");
+               return cx24123_writereg(state, 0x29, val | 0x10);
+       case SEC_TONE_OFF:
+               dprintk("setting tone off\n");
+               return cx24123_writereg(state, 0x29, val & 0xef);
+       default:
+               err("CASE reached default with tone=%d\n", tone);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cx24123_tune(struct dvb_frontend *fe,
+                       bool re_tune,
+                       unsigned int mode_flags,
+                       unsigned int *delay,
+                       fe_status_t *status)
+{
+       int retval = 0;
+
+       if (re_tune)
+               retval = cx24123_set_frontend(fe);
+
+       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+               cx24123_read_status(fe, status);
+       *delay = HZ/10;
+
+       return retval;
+}
+
+static int cx24123_get_algo(struct dvb_frontend *fe)
+{
+       return 1; /* FE_ALGO_HW */
+}
+
+static void cx24123_release(struct dvb_frontend *fe)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       dprintk("\n");
+       i2c_del_adapter(&state->tuner_i2c_adapter);
+       kfree(state);
+}
+
+static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
+       struct i2c_msg msg[], int num)
+{
+       struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
+       /* this repeater closes after the first stop */
+       cx24123_repeater_mode(state, 1, 1);
+       return i2c_transfer(state->i2c, msg, num);
+}
+
+static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cx24123_tuner_i2c_algo = {
+       .master_xfer   = cx24123_tuner_i2c_tuner_xfer,
+       .functionality = cx24123_tuner_i2c_func,
+};
+
+struct i2c_adapter *
+       cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       return &state->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
+
+static struct dvb_frontend_ops cx24123_ops;
+
+struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       /* allocate memory for the internal state */
+       struct cx24123_state *state =
+               kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
+
+       dprintk("\n");
+       if (state == NULL) {
+               err("Unable to kzalloc\n");
+               goto error;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       state->demod_rev = cx24123_readreg(state, 0x00);
+       switch (state->demod_rev) {
+       case 0xe1:
+               info("detected CX24123C\n");
+               break;
+       case 0xd1:
+               info("detected CX24123\n");
+               break;
+       default:
+               err("wrong demod revision: %x\n", state->demod_rev);
+               goto error;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &cx24123_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* create tuner i2c adapter */
+       if (config->dont_use_pll)
+               cx24123_repeater_mode(state, 1, 0);
+
+       strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
+               sizeof(state->tuner_i2c_adapter.name));
+       state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
+       state->tuner_i2c_adapter.algo_data = NULL;
+       i2c_set_adapdata(&state->tuner_i2c_adapter, state);
+       if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
+               err("tuner i2c bus could not be initialized\n");
+               goto error;
+       }
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(cx24123_attach);
+
+static struct dvb_frontend_ops cx24123_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name = "Conexant CX24123/CX24109",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
+               .frequency_tolerance = 5000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_INVERSION_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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_RECOVER
+       },
+
+       .release = cx24123_release,
+
+       .init = cx24123_initfe,
+       .set_frontend = cx24123_set_frontend,
+       .get_frontend = cx24123_get_frontend,
+       .read_status = cx24123_read_status,
+       .read_ber = cx24123_read_ber,
+       .read_signal_strength = cx24123_read_signal_strength,
+       .read_snr = cx24123_read_snr,
+       .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
+       .diseqc_send_burst = cx24123_diseqc_send_burst,
+       .set_tone = cx24123_set_tone,
+       .set_voltage = cx24123_set_voltage,
+       .tune = cx24123_tune,
+       .get_frontend_algo = cx24123_get_algo,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
+       "CX24123/CX24109/CX24113 hardware");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb-frontends/cx24123.h b/drivers/media/dvb-frontends/cx24123.h
new file mode 100644 (file)
index 0000000..51ae866
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
+
+    Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CX24123_H
+#define CX24123_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx24123_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* Need to set device param for start_dma */
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+
+       /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
+       int lnb_polarity;
+
+       /* this device has another tuner */
+       u8 dont_use_pll;
+       void (*agc_callback) (struct dvb_frontend *);
+};
+
+#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
+       && defined(MODULE))
+extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
+                                          struct i2c_adapter *i2c);
+extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *cx24123_attach(
+       const struct cx24123_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static struct i2c_adapter *
+       cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* CX24123_H */
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h
new file mode 100644 (file)
index 0000000..5aa306e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#ifndef CXD2820R_H
+#define CXD2820R_H
+
+#include <linux/dvb/frontend.h>
+
+#define CXD2820R_GPIO_D (0 << 0) /* disable */
+#define CXD2820R_GPIO_E (1 << 0) /* enable */
+#define CXD2820R_GPIO_O (0 << 1) /* output */
+#define CXD2820R_GPIO_I (1 << 1) /* input */
+#define CXD2820R_GPIO_L (0 << 2) /* output low */
+#define CXD2820R_GPIO_H (1 << 2) /* output high */
+
+#define CXD2820R_TS_SERIAL        0x08
+#define CXD2820R_TS_SERIAL_MSB    0x28
+#define CXD2820R_TS_PARALLEL      0x30
+#define CXD2820R_TS_PARALLEL_MSB  0x70
+
+struct cxd2820r_config {
+       /* Demodulator I2C address.
+        * Driver determines DVB-C slave I2C address automatically from master
+        * address.
+        * Default: none, must set
+        * Values: 0x6c, 0x6d
+        */
+       u8 i2c_address;
+
+       /* TS output mode.
+        * Default: none, must set.
+        * Values:
+        */
+       u8 ts_mode;
+
+       /* IF AGC polarity.
+        * Default: 0
+        * Values: 0, 1
+        */
+       bool if_agc_polarity;
+
+       /* Spectrum inversion.
+        * Default: 0
+        * Values: 0, 1
+        */
+       bool spec_inv;
+
+       /* GPIOs for all used modes.
+        * Default: none, disabled
+        * Values: <see above>
+        */
+       u8 gpio_dvbt[3];
+       u8 gpio_dvbt2[3];
+       u8 gpio_dvbc[3];
+};
+
+
+#if defined(CONFIG_DVB_CXD2820R) || \
+       (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
+extern struct dvb_frontend *cxd2820r_attach(
+       const struct cxd2820r_config *config,
+       struct i2c_adapter *i2c
+);
+#else
+static inline struct dvb_frontend *cxd2820r_attach(
+       const struct cxd2820r_config *config,
+       struct i2c_adapter *i2c
+)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif
+
+#endif /* CXD2820R_H */
diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c
new file mode 100644 (file)
index 0000000..ed3b0ba
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       u8 buf[2];
+       u32 if_freq;
+       u16 if_ctl;
+       u64 num;
+       struct reg_val_mask tab[] = {
+               { 0x00080, 0x01, 0xff },
+               { 0x00081, 0x05, 0xff },
+               { 0x00085, 0x07, 0xff },
+               { 0x00088, 0x01, 0xff },
+
+               { 0x00082, 0x20, 0x60 },
+               { 0x1016a, 0x48, 0xff },
+               { 0x100a5, 0x00, 0x01 },
+               { 0x10020, 0x06, 0x07 },
+               { 0x10059, 0x50, 0xff },
+               { 0x10087, 0x0c, 0x3c },
+               { 0x1008b, 0x07, 0xff },
+               { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
+               { 0x10070, priv->cfg.ts_mode, 0xff },
+       };
+
+       dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
+
+       /* update GPIOs */
+       ret = cxd2820r_gpio(fe);
+       if (ret)
+               goto error;
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       if (priv->delivery_system !=  SYS_DVBC_ANNEX_A) {
+               for (i = 0; i < ARRAY_SIZE(tab); i++) {
+                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+                               tab[i].val, tab[i].mask);
+                       if (ret)
+                               goto error;
+               }
+       }
+
+       priv->delivery_system = SYS_DVBC_ANNEX_A;
+       priv->ber_running = 0; /* tune stops BER counter */
+
+       /* program IF frequency */
+       if (fe->ops.tuner_ops.get_if_frequency) {
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+               if (ret)
+                       goto error;
+       } else
+               if_freq = 0;
+
+       dbg("%s: if_freq=%d", __func__, if_freq);
+
+       num = if_freq / 1000; /* Hz => kHz */
+       num *= 0x4000;
+       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+       buf[0] = (if_ctl >> 8) & 0x3f;
+       buf[1] = (if_ctl >> 0) & 0xff;
+
+       ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_get_frontend_c(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u8 buf[2];
+
+       ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
+       if (ret)
+               goto error;
+
+       c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
+
+       ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 0) & 0x07) {
+       case 0:
+               c->modulation = QAM_16;
+               break;
+       case 1:
+               c->modulation = QAM_32;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       case 3:
+               c->modulation = QAM_128;
+               break;
+       case 4:
+               c->modulation = QAM_256;
+               break;
+       }
+
+       switch ((buf[0] >> 7) & 0x01) {
+       case 0:
+               c->inversion = INVERSION_OFF;
+               break;
+       case 1:
+               c->inversion = INVERSION_ON;
+               break;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[3], start_ber = 0;
+       *ber = 0;
+
+       if (priv->ber_running) {
+               ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
+               if (ret)
+                       goto error;
+
+               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
+                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
+                       start_ber = 1;
+               }
+       } else {
+               priv->ber_running = 1;
+               start_ber = 1;
+       }
+
+       if (start_ber) {
+               /* (re)start BER */
+               ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 tmp;
+
+       ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       tmp = (buf[0] & 0x03) << 8 | buf[1];
+       tmp = (~tmp & 0x03ff);
+
+       if (tmp == 512)
+               /* ~no signal */
+               tmp = 0;
+       else if (tmp > 350)
+               tmp = 350;
+
+       /* scale value to 0x0000-0xffff */
+       *strength = tmp * 0xffff / (350-0);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+       unsigned int A, B;
+       /* report SNR in dB * 10 */
+
+       ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
+       if (ret)
+               goto error;
+
+       if (((tmp >> 0) & 0x03) % 2) {
+               A = 875;
+               B = 650;
+       } else {
+               A = 950;
+               B = 760;
+       }
+
+       ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
+       if (ret)
+               goto error;
+
+       #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
+       if (tmp)
+               *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
+                       / 10;
+       else
+               *snr = 0;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       /* no way to read ? */
+       return 0;
+}
+
+int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       *status = 0;
+
+       ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       if (((buf[0] >> 0) & 0x01) == 1) {
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                       FE_HAS_VITERBI | FE_HAS_SYNC;
+
+               if (((buf[1] >> 3) & 0x01) == 1) {
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+               }
+       }
+
+       dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_init_c(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+
+       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_sleep_c(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret, i;
+       struct reg_val_mask tab[] = {
+               { 0x000ff, 0x1f, 0xff },
+               { 0x00085, 0x00, 0xff },
+               { 0x00088, 0x01, 0xff },
+               { 0x00081, 0x00, 0xff },
+               { 0x00080, 0x00, 0xff },
+       };
+
+       dbg("%s", __func__);
+
+       priv->delivery_system = SYS_UNDEFINED;
+
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+                       tab[i].mask);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 500;
+       s->step_size = 0; /* no zigzag */
+       s->max_drift = 0;
+
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
new file mode 100644 (file)
index 0000000..3bba37d
--- /dev/null
@@ -0,0 +1,646 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_debug;
+module_param_named(debug, cxd2820r_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+/* write multiple registers */
+static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
+       u8 *val, int len)
+{
+       int ret;
+       u8 buf[len+1];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = i2c,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple registers */
+static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
+       u8 *val, int len)
+{
+       int ret;
+       u8 buf[len];
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = i2c,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = i2c,
+                       .flags = I2C_M_RD,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               memcpy(val, buf, len);
+               ret = 0;
+       } else {
+               warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* write multiple registers */
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+       int len)
+{
+       int ret;
+       u8 i2c_addr;
+       u8 reg = (reginfo >> 0) & 0xff;
+       u8 bank = (reginfo >> 8) & 0xff;
+       u8 i2c = (reginfo >> 16) & 0x01;
+
+       /* select I2C */
+       if (i2c)
+               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
+       else
+               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
+
+       /* switch bank if needed */
+       if (bank != priv->bank[i2c]) {
+               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
+               if (ret)
+                       return ret;
+               priv->bank[i2c] = bank;
+       }
+       return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
+}
+
+/* read multiple registers */
+int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+       int len)
+{
+       int ret;
+       u8 i2c_addr;
+       u8 reg = (reginfo >> 0) & 0xff;
+       u8 bank = (reginfo >> 8) & 0xff;
+       u8 i2c = (reginfo >> 16) & 0x01;
+
+       /* select I2C */
+       if (i2c)
+               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
+       else
+               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
+
+       /* switch bank if needed */
+       if (bank != priv->bank[i2c]) {
+               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
+               if (ret)
+                       return ret;
+               priv->bank[i2c] = bank;
+       }
+       return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
+}
+
+/* write single register */
+int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
+{
+       return cxd2820r_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
+{
+       return cxd2820r_rd_regs(priv, reg, val, 1);
+}
+
+/* write single register with mask */
+int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
+       u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = cxd2820r_rd_reg(priv, reg, &tmp);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return cxd2820r_wr_reg(priv, reg, val);
+}
+
+int cxd2820r_gpio(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret, i;
+       u8 *gpio, tmp0, tmp1;
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               gpio = priv->cfg.gpio_dvbt;
+               break;
+       case SYS_DVBT2:
+               gpio = priv->cfg.gpio_dvbt2;
+               break;
+       case SYS_DVBC_ANNEX_AC:
+               gpio = priv->cfg.gpio_dvbc;
+               break;
+       default:
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* update GPIOs only when needed */
+       if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
+               return 0;
+
+       tmp0 = 0x00;
+       tmp1 = 0x00;
+       for (i = 0; i < sizeof(priv->gpio); i++) {
+               /* enable / disable */
+               if (gpio[i] & CXD2820R_GPIO_E)
+                       tmp0 |= (2 << 6) >> (2 * i);
+               else
+                       tmp0 |= (1 << 6) >> (2 * i);
+
+               /* input / output */
+               if (gpio[i] & CXD2820R_GPIO_I)
+                       tmp1 |= (1 << (3 + i));
+               else
+                       tmp1 |= (0 << (3 + i));
+
+               /* high / low */
+               if (gpio[i] & CXD2820R_GPIO_H)
+                       tmp1 |= (1 << (0 + i));
+               else
+                       tmp1 |= (0 << (0 + i));
+
+               dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
+       }
+
+       dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
+
+       /* write bits [7:2] */
+       ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
+       if (ret)
+               goto error;
+
+       /* write bits [5:0] */
+       ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
+       if (ret)
+               goto error;
+
+       memcpy(priv->gpio, gpio, sizeof(priv->gpio));
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
+u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
+{
+       return div_u64(dividend + (divisor / 2), divisor);
+}
+
+static int cxd2820r_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (c->delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_init_t(fe);
+               if (ret < 0)
+                       goto err;
+               ret = cxd2820r_set_frontend_t(fe);
+               if (ret < 0)
+                       goto err;
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_init_t(fe);
+               if (ret < 0)
+                       goto err;
+               ret = cxd2820r_set_frontend_t2(fe);
+               if (ret < 0)
+                       goto err;
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_init_c(fe);
+               if (ret < 0)
+                       goto err;
+               ret = cxd2820r_set_frontend_c(fe);
+               if (ret < 0)
+                       goto err;
+               break;
+       default:
+               dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system);
+               ret = -EINVAL;
+               break;
+       }
+err:
+       return ret;
+}
+static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_read_status_t(fe, status);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_read_status_t2(fe, status);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_read_status_c(fe, status);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_get_frontend(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+       if (priv->delivery_system == SYS_UNDEFINED)
+               return 0;
+
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_get_frontend_t(fe);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_get_frontend_t2(fe);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_get_frontend_c(fe);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_read_ber_t(fe, ber);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_read_ber_t2(fe, ber);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_read_ber_c(fe, ber);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_read_signal_strength_t(fe, strength);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_read_signal_strength_t2(fe, strength);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_read_signal_strength_c(fe, strength);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_read_snr_t(fe, snr);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_read_snr_t2(fe, snr);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_read_snr_c(fe, snr);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_init(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int cxd2820r_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_sleep_t(fe);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_sleep_t2(fe);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_sleep_c(fe);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
+                                     struct dvb_frontend_tune_settings *s)
+{
+       int ret;
+
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+       switch (fe->dtv_property_cache.delivery_system) {
+       case SYS_DVBT:
+               ret = cxd2820r_get_tune_settings_t(fe, s);
+               break;
+       case SYS_DVBT2:
+               ret = cxd2820r_get_tune_settings_t2(fe, s);
+               break;
+       case SYS_DVBC_ANNEX_A:
+               ret = cxd2820r_get_tune_settings_c(fe, s);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       fe_status_t status = 0;
+       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+       /* switch between DVB-T and DVB-T2 when tune fails */
+       if (priv->last_tune_failed) {
+               if (priv->delivery_system == SYS_DVBT) {
+                       ret = cxd2820r_sleep_t(fe);
+                       if (ret)
+                               goto error;
+
+                       c->delivery_system = SYS_DVBT2;
+               } else if (priv->delivery_system == SYS_DVBT2) {
+                       ret = cxd2820r_sleep_t2(fe);
+                       if (ret)
+                               goto error;
+
+                       c->delivery_system = SYS_DVBT;
+               }
+       }
+
+       /* set frontend */
+       ret = cxd2820r_set_frontend(fe);
+       if (ret)
+               goto error;
+
+
+       /* frontend lock wait loop count */
+       switch (priv->delivery_system) {
+       case SYS_DVBT:
+       case SYS_DVBC_ANNEX_A:
+               i = 20;
+               break;
+       case SYS_DVBT2:
+               i = 40;
+               break;
+       case SYS_UNDEFINED:
+       default:
+               i = 0;
+               break;
+       }
+
+       /* wait frontend lock */
+       for (; i > 0; i--) {
+               dbg("%s: LOOP=%d", __func__, i);
+               msleep(50);
+               ret = cxd2820r_read_status(fe, &status);
+               if (ret)
+                       goto error;
+
+               if (status & FE_HAS_LOCK)
+                       break;
+       }
+
+       /* check if we have a valid signal */
+       if (status & FE_HAS_LOCK) {
+               priv->last_tune_failed = 0;
+               return DVBFE_ALGO_SEARCH_SUCCESS;
+       } else {
+               priv->last_tune_failed = 1;
+               return DVBFE_ALGO_SEARCH_AGAIN;
+       }
+
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+static void cxd2820r_release(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       dbg("%s", __func__);
+
+       kfree(priv);
+       return;
+}
+
+static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       dbg("%s: %d", __func__, enable);
+
+       /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
+       return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
+}
+
+static const struct dvb_frontend_ops cxd2820r_ops = {
+       .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
+       /* default: DVB-T/T2 */
+       .info = {
+               .name = "Sony CXD2820R",
+
+               .caps = FE_CAN_FEC_1_2                  |
+                       FE_CAN_FEC_2_3                  |
+                       FE_CAN_FEC_3_4                  |
+                       FE_CAN_FEC_5_6                  |
+                       FE_CAN_FEC_7_8                  |
+                       FE_CAN_FEC_AUTO                 |
+                       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_TRANSMISSION_MODE_AUTO   |
+                       FE_CAN_GUARD_INTERVAL_AUTO      |
+                       FE_CAN_HIERARCHY_AUTO           |
+                       FE_CAN_MUTE_TS                  |
+                       FE_CAN_2G_MODULATION
+               },
+
+       .release                = cxd2820r_release,
+       .init                   = cxd2820r_init,
+       .sleep                  = cxd2820r_sleep,
+
+       .get_tune_settings      = cxd2820r_get_tune_settings,
+       .i2c_gate_ctrl          = cxd2820r_i2c_gate_ctrl,
+
+       .get_frontend           = cxd2820r_get_frontend,
+
+       .get_frontend_algo      = cxd2820r_get_frontend_algo,
+       .search                 = cxd2820r_search,
+
+       .read_status            = cxd2820r_read_status,
+       .read_snr               = cxd2820r_read_snr,
+       .read_ber               = cxd2820r_read_ber,
+       .read_ucblocks          = cxd2820r_read_ucblocks,
+       .read_signal_strength   = cxd2820r_read_signal_strength,
+};
+
+struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
+               struct i2c_adapter *i2c)
+{
+       struct cxd2820r_priv *priv = NULL;
+       int ret;
+       u8 tmp;
+
+       priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL);
+       if (!priv)
+               goto error;
+
+       priv->i2c = i2c;
+       memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config));
+
+       priv->bank[0] = priv->bank[1] = 0xff;
+       ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
+       dbg("%s: chip id=%02x", __func__, tmp);
+       if (ret || tmp != 0xe1)
+               goto error;
+
+       memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops));
+       priv->fe.demodulator_priv = priv;
+       return &priv->fe;
+error:
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(cxd2820r_attach);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h
new file mode 100644 (file)
index 0000000..9a9822c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#ifndef CXD2820R_PRIV_H
+#define CXD2820R_PRIV_H
+
+#include <linux/dvb/version.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "cxd2820r.h"
+
+#define LOG_PREFIX "cxd2820r"
+
+#undef dbg
+#define dbg(f, arg...) \
+       if (cxd2820r_debug) \
+               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct reg_val_mask {
+       u32 reg;
+       u8  val;
+       u8  mask;
+};
+
+struct cxd2820r_priv {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct cxd2820r_config cfg;
+
+       bool ber_running;
+
+       u8 bank[2];
+       u8 gpio[3];
+
+       fe_delivery_system_t delivery_system;
+       bool last_tune_failed; /* for switch between T and T2 tune */
+};
+
+/* cxd2820r_core.c */
+
+extern int cxd2820r_debug;
+
+int cxd2820r_gpio(struct dvb_frontend *fe);
+
+int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
+       u8 mask);
+
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+       int len);
+
+u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
+
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+       int len);
+
+int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+       int len);
+
+int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
+
+int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
+
+/* cxd2820r_c.c */
+
+int cxd2820r_get_frontend_c(struct dvb_frontend *fe);
+
+int cxd2820r_set_frontend_c(struct dvb_frontend *fe);
+
+int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_c(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_c(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s);
+
+/* cxd2820r_t.c */
+
+int cxd2820r_get_frontend_t(struct dvb_frontend *fe);
+
+int cxd2820r_set_frontend_t(struct dvb_frontend *fe);
+
+int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_t(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_t(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s);
+
+/* cxd2820r_t2.c */
+
+int cxd2820r_get_frontend_t2(struct dvb_frontend *fe);
+
+int cxd2820r_set_frontend_t2(struct dvb_frontend *fe);
+
+int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_t2(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_t2(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s);
+
+#endif /* CXD2820R_PRIV_H */
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c
new file mode 100644 (file)
index 0000000..e5dd22b
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i, bw_i;
+       u32 if_freq, if_ctl;
+       u64 num;
+       u8 buf[3], bw_param;
+       u8 bw_params1[][5] = {
+               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
+               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
+               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
+       };
+       u8 bw_params2[][2] = {
+               { 0x1f, 0xdc }, /* 6 MHz */
+               { 0x12, 0xf8 }, /* 7 MHz */
+               { 0x01, 0xe0 }, /* 8 MHz */
+       };
+       struct reg_val_mask tab[] = {
+               { 0x00080, 0x00, 0xff },
+               { 0x00081, 0x03, 0xff },
+               { 0x00085, 0x07, 0xff },
+               { 0x00088, 0x01, 0xff },
+
+               { 0x00070, priv->cfg.ts_mode, 0xff },
+               { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
+               { 0x000a5, 0x00, 0x01 },
+               { 0x00082, 0x20, 0x60 },
+               { 0x000c2, 0xc3, 0xff },
+               { 0x0016a, 0x50, 0xff },
+               { 0x00427, 0x41, 0xff },
+       };
+
+       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               bw_i = 0;
+               bw_param = 2;
+               break;
+       case 7000000:
+               bw_i = 1;
+               bw_param = 1;
+               break;
+       case 8000000:
+               bw_i = 2;
+               bw_param = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* update GPIOs */
+       ret = cxd2820r_gpio(fe);
+       if (ret)
+               goto error;
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       if (priv->delivery_system != SYS_DVBT) {
+               for (i = 0; i < ARRAY_SIZE(tab); i++) {
+                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+                               tab[i].val, tab[i].mask);
+                       if (ret)
+                               goto error;
+               }
+       }
+
+       priv->delivery_system = SYS_DVBT;
+       priv->ber_running = 0; /* tune stops BER counter */
+
+       /* program IF frequency */
+       if (fe->ops.tuner_ops.get_if_frequency) {
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+               if (ret)
+                       goto error;
+       } else
+               if_freq = 0;
+
+       dbg("%s: if_freq=%d", __func__, if_freq);
+
+       num = if_freq / 1000; /* Hz => kHz */
+       num *= 0x1000000;
+       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+       buf[0] = ((if_ctl >> 16) & 0xff);
+       buf[1] = ((if_ctl >>  8) & 0xff);
+       buf[2] = ((if_ctl >>  0) & 0xff);
+
+       ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_get_frontend_t(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u8 buf[2];
+
+       ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 6) & 0x03) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       }
+
+       switch ((buf[1] >> 1) & 0x03) {
+       case 0:
+               c->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               c->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+
+       switch ((buf[1] >> 3) & 0x03) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       switch ((buf[0] >> 3) & 0x07) {
+       case 0:
+               c->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               c->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               c->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               c->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+       switch ((buf[0] >> 0) & 0x07) {
+       case 0:
+               c->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_HP = FEC_7_8;
+               break;
+       }
+
+       switch ((buf[1] >> 5) & 0x07) {
+       case 0:
+               c->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 0) & 0x01) {
+       case 0:
+               c->inversion = INVERSION_OFF;
+               break;
+       case 1:
+               c->inversion = INVERSION_ON;
+               break;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[3], start_ber = 0;
+       *ber = 0;
+
+       if (priv->ber_running) {
+               ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
+               if (ret)
+                       goto error;
+
+               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
+                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
+                       start_ber = 1;
+               }
+       } else {
+               priv->ber_running = 1;
+               start_ber = 1;
+       }
+
+       if (start_ber) {
+               /* (re)start BER */
+               ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 tmp;
+
+       ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       tmp = (buf[0] & 0x0f) << 8 | buf[1];
+       tmp = ~tmp & 0x0fff;
+
+       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
+       *strength = tmp * 0xffff / 0x0fff;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 tmp;
+       /* report SNR in dB * 10 */
+
+       ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       tmp = (buf[0] & 0x1f) << 8 | buf[1];
+       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
+       if (tmp)
+               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
+                       / 100);
+       else
+               *snr = 0;
+
+       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       /* no way to read ? */
+       return 0;
+}
+
+int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[4];
+       *status = 0;
+
+       ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
+       if (ret)
+               goto error;
+
+       if ((buf[0] & 0x07) == 6) {
+               ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
+               if (ret)
+                       goto error;
+
+               if (((buf[1] >> 3) & 0x01) == 1) {
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+               } else {
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC;
+               }
+       } else {
+               ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
+               if (ret)
+                       goto error;
+
+               if ((buf[2] & 0x0f) >= 4) {
+                       ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
+                       if (ret)
+                               goto error;
+
+                       if (((buf[3] >> 4) & 0x01) == 1)
+                               *status |= FE_HAS_SIGNAL;
+               }
+       }
+
+       dbg("%s: lock=%*ph", __func__, 4, buf);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_init_t(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+
+       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_sleep_t(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret, i;
+       struct reg_val_mask tab[] = {
+               { 0x000ff, 0x1f, 0xff },
+               { 0x00085, 0x00, 0xff },
+               { 0x00088, 0x01, 0xff },
+               { 0x00081, 0x00, 0xff },
+               { 0x00080, 0x00, 0xff },
+       };
+
+       dbg("%s", __func__);
+
+       priv->delivery_system = SYS_UNDEFINED;
+
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+                       tab[i].mask);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 500;
+       s->step_size = fe->ops.info.frequency_stepsize * 2;
+       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c
new file mode 100644 (file)
index 0000000..3a5759e
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i, bw_i;
+       u32 if_freq, if_ctl;
+       u64 num;
+       u8 buf[3], bw_param;
+       u8 bw_params1[][5] = {
+               { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
+               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
+               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
+               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
+       };
+       struct reg_val_mask tab[] = {
+               { 0x00080, 0x02, 0xff },
+               { 0x00081, 0x20, 0xff },
+               { 0x00085, 0x07, 0xff },
+               { 0x00088, 0x01, 0xff },
+               { 0x02069, 0x01, 0xff },
+
+               { 0x0207f, 0x2a, 0xff },
+               { 0x02082, 0x0a, 0xff },
+               { 0x02083, 0x0a, 0xff },
+               { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
+               { 0x02070, priv->cfg.ts_mode, 0xff },
+               { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
+               { 0x02567, 0x07, 0x0f },
+               { 0x02569, 0x03, 0x03 },
+               { 0x02595, 0x1a, 0xff },
+               { 0x02596, 0x50, 0xff },
+               { 0x02a8c, 0x00, 0xff },
+               { 0x02a8d, 0x34, 0xff },
+               { 0x02a45, 0x06, 0x07 },
+               { 0x03f10, 0x0d, 0xff },
+               { 0x03f11, 0x02, 0xff },
+               { 0x03f12, 0x01, 0xff },
+               { 0x03f23, 0x2c, 0xff },
+               { 0x03f51, 0x13, 0xff },
+               { 0x03f52, 0x01, 0xff },
+               { 0x03f53, 0x00, 0xff },
+               { 0x027e6, 0x14, 0xff },
+               { 0x02786, 0x02, 0x07 },
+               { 0x02787, 0x40, 0xe0 },
+               { 0x027ef, 0x10, 0x18 },
+       };
+
+       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+
+       switch (c->bandwidth_hz) {
+       case 5000000:
+               bw_i = 0;
+               bw_param = 3;
+               break;
+       case 6000000:
+               bw_i = 1;
+               bw_param = 2;
+               break;
+       case 7000000:
+               bw_i = 2;
+               bw_param = 1;
+               break;
+       case 8000000:
+               bw_i = 3;
+               bw_param = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* update GPIOs */
+       ret = cxd2820r_gpio(fe);
+       if (ret)
+               goto error;
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       if (priv->delivery_system != SYS_DVBT2) {
+               for (i = 0; i < ARRAY_SIZE(tab); i++) {
+                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+                               tab[i].val, tab[i].mask);
+                       if (ret)
+                               goto error;
+               }
+       }
+
+       priv->delivery_system = SYS_DVBT2;
+
+       /* program IF frequency */
+       if (fe->ops.tuner_ops.get_if_frequency) {
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+               if (ret)
+                       goto error;
+       } else
+               if_freq = 0;
+
+       dbg("%s: if_freq=%d", __func__, if_freq);
+
+       num = if_freq / 1000; /* Hz => kHz */
+       num *= 0x1000000;
+       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+       buf[0] = ((if_ctl >> 16) & 0xff);
+       buf[1] = ((if_ctl >>  8) & 0xff);
+       buf[2] = ((if_ctl >>  0) & 0xff);
+
+       ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+       if (ret)
+               goto error;
+
+       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+
+}
+
+int cxd2820r_get_frontend_t2(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u8 buf[2];
+
+       ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 0) & 0x07) {
+       case 0:
+               c->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               c->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       case 2:
+               c->transmission_mode = TRANSMISSION_MODE_4K;
+               break;
+       case 3:
+               c->transmission_mode = TRANSMISSION_MODE_1K;
+               break;
+       case 4:
+               c->transmission_mode = TRANSMISSION_MODE_16K;
+               break;
+       case 5:
+               c->transmission_mode = TRANSMISSION_MODE_32K;
+               break;
+       }
+
+       switch ((buf[1] >> 4) & 0x07) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       case 4:
+               c->guard_interval = GUARD_INTERVAL_1_128;
+               break;
+       case 5:
+               c->guard_interval = GUARD_INTERVAL_19_128;
+               break;
+       case 6:
+               c->guard_interval = GUARD_INTERVAL_19_256;
+               break;
+       }
+
+       ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 0) & 0x07) {
+       case 0:
+               c->fec_inner = FEC_1_2;
+               break;
+       case 1:
+               c->fec_inner = FEC_3_5;
+               break;
+       case 2:
+               c->fec_inner = FEC_2_3;
+               break;
+       case 3:
+               c->fec_inner = FEC_3_4;
+               break;
+       case 4:
+               c->fec_inner = FEC_4_5;
+               break;
+       case 5:
+               c->fec_inner = FEC_5_6;
+               break;
+       }
+
+       switch ((buf[1] >> 0) & 0x07) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       case 3:
+               c->modulation = QAM_256;
+               break;
+       }
+
+       ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
+       if (ret)
+               goto error;
+
+       switch ((buf[0] >> 4) & 0x01) {
+       case 0:
+               c->inversion = INVERSION_OFF;
+               break;
+       case 1:
+               c->inversion = INVERSION_ON;
+               break;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[1];
+       *status = 0;
+
+       ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
+       if (ret)
+               goto error;
+
+       if ((buf[0] & 0x07) == 6) {
+               if (((buf[0] >> 5) & 0x01) == 1) {
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+               } else {
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC;
+               }
+       }
+
+       dbg("%s: lock=%02x", __func__, buf[0]);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[4];
+       unsigned int errbits;
+       *ber = 0;
+       /* FIXME: correct calculation */
+
+       ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       if ((buf[0] >> 4) & 0x01) {
+               errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
+                       buf[2] << 8 | buf[3];
+
+               if (errbits)
+                       *ber = errbits * 64 / 16588800;
+       }
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 tmp;
+
+       ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       tmp = (buf[0] & 0x0f) << 8 | buf[1];
+       tmp = ~tmp & 0x0fff;
+
+       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
+       *strength = tmp * 0xffff / 0x0fff;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 tmp;
+       /* report SNR in dB * 10 */
+
+       ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       tmp = (buf[0] & 0x0f) << 8 | buf[1];
+       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
+       if (tmp)
+               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
+                       / 100);
+       else
+               *snr = 0;
+
+       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       /* no way to read ? */
+       return 0;
+}
+
+int cxd2820r_sleep_t2(struct dvb_frontend *fe)
+{
+       struct cxd2820r_priv *priv = fe->demodulator_priv;
+       int ret, i;
+       struct reg_val_mask tab[] = {
+               { 0x000ff, 0x1f, 0xff },
+               { 0x00085, 0x00, 0xff },
+               { 0x00088, 0x01, 0xff },
+               { 0x02069, 0x00, 0xff },
+               { 0x00081, 0x00, 0xff },
+               { 0x00080, 0x00, 0xff },
+       };
+
+       dbg("%s", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+                       tab[i].mask);
+               if (ret)
+                       goto error;
+       }
+
+       priv->delivery_system = SYS_UNDEFINED;
+
+       return ret;
+error:
+       dbg("%s: failed:%d", __func__, ret);
+       return ret;
+}
+
+int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 1500;
+       s->step_size = fe->ops.info.frequency_stepsize * 2;
+       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c
new file mode 100644 (file)
index 0000000..3b024bf
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_frontend.h"
+
+#include "dib0070.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { \
+       if (debug) { \
+               printk(KERN_DEBUG "DiB0070: "); \
+               printk(args); \
+               printk("\n"); \
+       } \
+} while (0)
+
+#define DIB0070_P1D  0x00
+#define DIB0070_P1F  0x01
+#define DIB0070_P1G  0x03
+#define DIB0070S_P1A 0x02
+
+struct dib0070_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+       const struct dib0070_config *cfg;
+       u16 wbd_ff_offset;
+       u8 revision;
+
+    enum frontend_tune_state tune_state;
+    u32 current_rf;
+
+    /* for the captrim binary search */
+       s8 step;
+       u16 adc_diff;
+
+       s8 captrim;
+       s8 fcaptrim;
+       u16 lo4;
+
+       const struct dib0070_tuning *current_tune_table_index;
+       const struct dib0070_lna_match *lna_match;
+
+    u8  wbd_gain_current;
+       u16 wbd_offset_3_3[2];
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[3];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+};
+
+static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = reg;
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->cfg->i2c_address;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 1;
+       state->msg[1].addr = state->cfg->i2c_address;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = state->i2c_read_buffer;
+       state->msg[1].len = 2;
+
+       if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+               printk(KERN_WARNING "DiB0070 I2C read failed\n");
+               ret = 0;
+       } else
+               ret = (state->i2c_read_buffer[0] << 8)
+                       | state->i2c_read_buffer[1];
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+       state->i2c_write_buffer[0] = reg;
+       state->i2c_write_buffer[1] = val >> 8;
+       state->i2c_write_buffer[2] = val & 0xff;
+
+       memset(state->msg, 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->cfg->i2c_address;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 3;
+
+       if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0070 I2C write failed\n");
+               ret = -EREMOTEIO;
+       } else
+               ret = 0;
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+#define HARD_RESET(state) do { \
+    state->cfg->sleep(state->fe, 0); \
+    if (state->cfg->reset) { \
+       state->cfg->reset(state->fe,1); msleep(10); \
+       state->cfg->reset(state->fe,0); msleep(10); \
+    } \
+} while (0)
+
+static int dib0070_set_bandwidth(struct dvb_frontend *fe)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+    u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+
+    if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
+       tmp |= (0 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
+       tmp |= (1 << 14);
+    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
+       tmp |= (2 << 14);
+    else
+       tmp |= (3 << 14);
+
+    dib0070_write_reg(state, 0x02, tmp);
+
+    /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+       u16 value = dib0070_read_reg(state, 0x17);
+
+       dib0070_write_reg(state, 0x17, value & 0xfffc);
+       tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+       dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+
+       dib0070_write_reg(state, 0x17, value);
+    }
+       return 0;
+}
+
+static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
+{
+       int8_t step_sign;
+       u16 adc;
+       int ret = 0;
+
+       if (*tune_state == CT_TUNER_STEP_0) {
+
+               dib0070_write_reg(state, 0x0f, 0xed10);
+               dib0070_write_reg(state, 0x17,    0x0034);
+
+               dib0070_write_reg(state, 0x18, 0x0032);
+               state->step = state->captrim = state->fcaptrim = 64;
+               state->adc_diff = 3000;
+               ret = 20;
+
+       *tune_state = CT_TUNER_STEP_1;
+       } else if (*tune_state == CT_TUNER_STEP_1) {
+               state->step /= 2;
+               dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
+               ret = 15;
+
+               *tune_state = CT_TUNER_STEP_2;
+       } else if (*tune_state == CT_TUNER_STEP_2) {
+
+               adc = dib0070_read_reg(state, 0x19);
+
+               dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
+
+               if (adc >= 400) {
+                       adc -= 400;
+                       step_sign = -1;
+               } else {
+                       adc = 400 - adc;
+                       step_sign = 1;
+               }
+
+               if (adc < state->adc_diff) {
+                       dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
+                       state->adc_diff = adc;
+                       state->fcaptrim = state->captrim;
+
+
+
+               }
+               state->captrim += (step_sign * state->step);
+
+               if (state->step >= 1)
+                       *tune_state = CT_TUNER_STEP_1;
+               else
+                       *tune_state = CT_TUNER_STEP_3;
+
+       } else if (*tune_state == CT_TUNER_STEP_3) {
+               dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
+               dib0070_write_reg(state, 0x18, 0x07ff);
+               *tune_state = CT_TUNER_STEP_4;
+       }
+
+       return ret;
+}
+
+static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+       dprintk("CTRL_LO5: 0x%x", lo5);
+       return dib0070_write_reg(state, 0x15, lo5);
+}
+
+void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+
+       if (open) {
+               dib0070_write_reg(state, 0x1b, 0xff00);
+               dib0070_write_reg(state, 0x1a, 0x0000);
+       } else {
+               dib0070_write_reg(state, 0x1b, 0x4112);
+       if (state->cfg->vga_filter != 0) {
+               dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+               dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+       } else
+               dib0070_write_reg(state, 0x1a, 0x0009);
+       }
+}
+
+EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
+struct dib0070_tuning {
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 switch_trim;
+    u8 vco_band;
+    u8 hfdiv;
+    u8 vco_multi;
+    u8 presc;
+    u8 wbdmux;
+    u16 tuner_enable;
+};
+
+struct dib0070_lna_match {
+    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
+    u8 lna_band;
+};
+
+static const struct dib0070_tuning dib0070s_tuning_table[] = {
+    {     570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
+    {    1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
+    {    1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    {    2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
+    { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
+};
+
+static const struct dib0070_tuning dib0070_tuning_table[] = {
+    {     115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
+    {     179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
+    {     189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
+    {     250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
+    {     569999, 2, 1, 5,  6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
+    {     699999, 2, 0, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    {     863999, 2, 1, 1,  4, 2, 2, 0x4000 | 0x0800 },
+    { 0xffffffff, 0, 1, 0,  2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
+};
+
+static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 0 }, /* UHF */
+    {     590000, 1 },
+    {     666000, 3 },
+    {     864000, 5 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
+};
+
+static const struct dib0070_lna_match dib0070_lna[] = {
+    {     180000, 0 }, /* VHF */
+    {     188000, 1 },
+    {     196400, 2 },
+    {     250000, 3 },
+    {     550000, 2 }, /* UHF */
+    {     650000, 3 },
+    {     750000, 5 },
+    {     850000, 6 },
+    {     864000, 7 },
+    {    1500000, 0 }, /* LBAND or everything higher than UHF */
+    {    1600000, 1 },
+    {    2000000, 3 },
+    { 0xffffffff, 7 },
+};
+
+#define LPF    100
+static int dib0070_tune_digital(struct dvb_frontend *fe)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+
+    const struct dib0070_tuning *tune;
+    const struct dib0070_lna_match *lna_match;
+
+    enum frontend_tune_state *tune_state = &state->tune_state;
+    int ret = 10; /* 1ms is the default delay most of the time */
+
+    u8  band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
+    u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
+
+#ifdef CONFIG_SYS_ISDBT
+    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+               if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
+                    && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+                   || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+                       && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
+                   || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+                       && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
+                       freq += 850;
+#endif
+    if (state->current_rf != freq) {
+
+       switch (state->revision) {
+       case DIB0070S_P1A:
+           tune = dib0070s_tuning_table;
+           lna_match = dib0070_lna;
+           break;
+       default:
+           tune = dib0070_tuning_table;
+           if (state->cfg->flip_chip)
+               lna_match = dib0070_lna_flip_chip;
+           else
+               lna_match = dib0070_lna;
+           break;
+       }
+       while (freq > tune->max_freq) /* find the right one */
+           tune++;
+       while (freq > lna_match->max_freq) /* find the right one */
+           lna_match++;
+
+       state->current_tune_table_index = tune;
+       state->lna_match = lna_match;
+    }
+
+    if (*tune_state == CT_TUNER_START) {
+       dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
+       if (state->current_rf != freq) {
+               u8 REFDIV;
+               u32 FBDiv, Rest, FREF, VCOF_kHz;
+               u8 Den;
+
+               state->current_rf = freq;
+               state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
+
+
+               dib0070_write_reg(state, 0x17, 0x30);
+
+
+               VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
+
+               switch (band) {
+               case BAND_VHF:
+                       REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+                       break;
+               case BAND_FM:
+                       REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
+                       break;
+               default:
+                       REFDIV = (u8) (state->cfg->clock_khz  / 10000);
+                       break;
+               }
+               FREF = state->cfg->clock_khz / REFDIV;
+
+
+
+               switch (state->revision) {
+               case DIB0070S_P1A:
+                       FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+                       Rest  = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+                       break;
+
+               case DIB0070_P1G:
+               case DIB0070_P1F:
+               default:
+                       FBDiv = (freq / (FREF / 2));
+                       Rest  = 2 * freq - FBDiv * FREF;
+                       break;
+               }
+
+               if (Rest < LPF)
+                       Rest = 0;
+               else if (Rest < 2 * LPF)
+                       Rest = 2 * LPF;
+               else if (Rest > (FREF - LPF)) {
+                       Rest = 0;
+                       FBDiv += 1;
+               } else if (Rest > (FREF - 2 * LPF))
+                       Rest = FREF - 2 * LPF;
+               Rest = (Rest * 6528) / (FREF / 10);
+
+               Den = 1;
+               if (Rest > 0) {
+                       state->lo4 |= (1 << 14) | (1 << 12);
+                       Den = 255;
+               }
+
+
+               dib0070_write_reg(state, 0x11, (u16)FBDiv);
+               dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+               dib0070_write_reg(state, 0x13, (u16) Rest);
+
+               if (state->revision == DIB0070S_P1A) {
+
+                       if (band == BAND_SBAND) {
+                               dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+                               dib0070_write_reg(state, 0x1d, 0xFFFF);
+                       } else
+                               dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+               }
+
+               dib0070_write_reg(state, 0x20,
+                       0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
+
+               dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+               dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+               dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+               dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+               dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+               dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
+
+               *tune_state = CT_TUNER_STEP_0;
+       } else { /* we are already tuned to this frequency - the configuration is correct  */
+               ret = 50; /* wakeup time */
+               *tune_state = CT_TUNER_STEP_5;
+       }
+    } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+
+       ret = dib0070_captrim(state, tune_state);
+
+    } else if (*tune_state == CT_TUNER_STEP_4) {
+       const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+       if (tmp != NULL) {
+               while (freq/1000 > tmp->freq) /* find the right one */
+                       tmp++;
+               dib0070_write_reg(state, 0x0f,
+                       (0 << 15) | (1 << 14) | (3 << 12)
+                       | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
+                       | (state->current_tune_table_index->wbdmux << 0));
+               state->wbd_gain_current = tmp->wbd_gain_val;
+       } else {
+                       dib0070_write_reg(state, 0x0f,
+                                         (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
+                                                                                                               wbdmux << 0));
+           state->wbd_gain_current = 6;
+       }
+
+       dib0070_write_reg(state, 0x06, 0x3fff);
+               dib0070_write_reg(state, 0x07,
+                                 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
+       dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+       dib0070_write_reg(state, 0x0d, 0x0d80);
+
+
+       dib0070_write_reg(state, 0x18,   0x07ff);
+       dib0070_write_reg(state, 0x17, 0x0033);
+
+
+       *tune_state = CT_TUNER_STEP_5;
+    } else if (*tune_state == CT_TUNER_STEP_5) {
+       dib0070_set_bandwidth(fe);
+       *tune_state = CT_TUNER_STOP;
+    } else {
+       ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
+    }
+    return ret;
+}
+
+
+static int dib0070_tune(struct dvb_frontend *fe)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+    uint32_t ret;
+
+    state->tune_state = CT_TUNER_START;
+
+    do {
+       ret = dib0070_tune_digital(fe);
+       if (ret != FE_CALLBACK_TIME_NEVER)
+               msleep(ret/10);
+       else
+           break;
+    } while (state->tune_state != CT_TUNER_STOP);
+
+    return 0;
+}
+
+static int dib0070_wakeup(struct dvb_frontend *fe)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       if (state->cfg->sleep)
+               state->cfg->sleep(fe, 0);
+       return 0;
+}
+
+static int dib0070_sleep(struct dvb_frontend *fe)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       if (state->cfg->sleep)
+               state->cfg->sleep(fe, 1);
+       return 0;
+}
+
+u8 dib0070_get_rf_output(struct dvb_frontend *fe)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
+}
+EXPORT_SYMBOL(dib0070_get_rf_output);
+
+int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+       u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
+       if (no > 3)
+               no = 3;
+       if (no < 1)
+               no = 1;
+       return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
+}
+EXPORT_SYMBOL(dib0070_set_rf_output);
+
+static const u16 dib0070_p1f_defaults[] =
+
+{
+       7, 0x02,
+               0x0008,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0002,
+               0x0100,
+
+       3, 0x0d,
+               0x0d80,
+               0x0001,
+               0x0000,
+
+       4, 0x11,
+               0x0000,
+               0x0103,
+               0x0000,
+               0x0000,
+
+       3, 0x16,
+               0x0004 | 0x0040,
+               0x0030,
+               0x07ff,
+
+       6, 0x1b,
+               0x4112,
+               0xff00,
+               0xc07f,
+               0x0000,
+               0x0180,
+               0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+
+       0,
+};
+
+static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
+{
+    u16 tuner_en = dib0070_read_reg(state, 0x20);
+    u16 offset;
+
+    dib0070_write_reg(state, 0x18, 0x07ff);
+    dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+    dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
+    msleep(9);
+    offset = dib0070_read_reg(state, 0x19);
+    dib0070_write_reg(state, 0x20, tuner_en);
+    return offset;
+}
+
+static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
+{
+    u8 gain;
+    for (gain = 6; gain < 8; gain++) {
+       state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+       dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
+    }
+}
+
+u16 dib0070_wbd_offset(struct dvb_frontend *fe)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+    const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+    u32 freq = fe->dtv_property_cache.frequency/1000;
+
+    if (tmp != NULL) {
+       while (freq/1000 > tmp->freq) /* find the right one */
+           tmp++;
+       state->wbd_gain_current = tmp->wbd_gain_val;
+       } else
+       state->wbd_gain_current = 6;
+
+    return state->wbd_offset_3_3[state->wbd_gain_current - 6];
+}
+EXPORT_SYMBOL(dib0070_wbd_offset);
+
+#define pgm_read_word(w) (*w)
+static int dib0070_reset(struct dvb_frontend *fe)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+       u16 l, r, *n;
+
+       HARD_RESET(state);
+
+
+#ifndef FORCE_SBAND_TUNER
+       if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
+               state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
+       else
+#else
+#warning forcing SBAND
+#endif
+               state->revision = DIB0070S_P1A;
+
+       /* P1F or not */
+       dprintk("Revision: %x", state->revision);
+
+       if (state->revision == DIB0070_P1D) {
+               dprintk("Error: this driver is not to be used meant for P1D or earlier");
+               return -EINVAL;
+       }
+
+       n = (u16 *) dib0070_p1f_defaults;
+       l = pgm_read_word(n++);
+       while (l) {
+               r = pgm_read_word(n++);
+               do {
+                       dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
+                       r++;
+               } while (--l);
+               l = pgm_read_word(n++);
+       }
+
+       if (state->cfg->force_crystal_mode != 0)
+               r = state->cfg->force_crystal_mode;
+       else if (state->cfg->clock_khz >= 24000)
+               r = 1;
+       else
+               r = 2;
+
+
+       r |= state->cfg->osc_buffer_state << 3;
+
+       dib0070_write_reg(state, 0x10, r);
+       dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
+
+       if (state->cfg->invert_iq) {
+               r = dib0070_read_reg(state, 0x02) & 0xffdf;
+               dib0070_write_reg(state, 0x02, r | (1 << 5));
+       }
+
+    if (state->revision == DIB0070S_P1A)
+       dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+    else
+               dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
+
+       dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
+
+    dib0070_wbd_offset_calibration(state);
+
+    return 0;
+}
+
+static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+    struct dib0070_state *state = fe->tuner_priv;
+
+    *frequency = 1000 * state->current_rf;
+    return 0;
+}
+
+static int dib0070_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops dib0070_ops = {
+       .info = {
+               .name           = "DiBcom DiB0070",
+               .frequency_min  =  45000000,
+               .frequency_max  = 860000000,
+               .frequency_step =      1000,
+       },
+       .release       = dib0070_release,
+
+       .init          = dib0070_wakeup,
+       .sleep         = dib0070_sleep,
+       .set_params    = dib0070_tune,
+
+       .get_frequency = dib0070_get_frequency,
+//      .get_bandwidth = dib0070_get_bandwidth
+};
+
+struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
+{
+       struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->cfg = cfg;
+       state->i2c = i2c;
+       state->fe  = fe;
+       mutex_init(&state->i2c_buffer_lock);
+       fe->tuner_priv = state;
+
+       if (dib0070_reset(fe) != 0)
+               goto free_mem;
+
+       printk(KERN_INFO "DiB0070: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = state;
+       return fe;
+
+free_mem:
+       kfree(state);
+       fe->tuner_priv = NULL;
+       return NULL;
+}
+EXPORT_SYMBOL(dib0070_attach);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib0070.h b/drivers/media/dvb-frontends/dib0070.h
new file mode 100644 (file)
index 0000000..45c31fa
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#ifndef DIB0070_H
+#define DIB0070_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
+
+struct dib0070_wbd_gain_cfg {
+       u16 freq;
+       u16 wbd_gain_val;
+};
+
+struct dib0070_config {
+       u8 i2c_address;
+
+       /* tuner pins controlled externally */
+       int (*reset) (struct dvb_frontend *, int);
+       int (*sleep) (struct dvb_frontend *, int);
+
+       /*  offset in kHz */
+       int freq_offset_khz_uhf;
+       int freq_offset_khz_vhf;
+
+       u8 osc_buffer_state;    /* 0= normal, 1= tri-state */
+       u32 clock_khz;
+       u8 clock_pad_drive;     /* (Drive + 1) * 2mA */
+
+       u8 invert_iq;           /* invert Q - in case I or Q is inverted on the board */
+
+       u8 force_crystal_mode;  /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
+
+       u8 flip_chip;
+       u8 enable_third_order_filter;
+       u8 charge_pump;
+
+       const struct dib0070_wbd_gain_cfg *wbd_gain;
+
+       u8 vga_filter;
+};
+
+#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
+extern u16 dib0070_wbd_offset(struct dvb_frontend *);
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
+extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
+extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
+#else
+static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+
+static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
new file mode 100644 (file)
index 0000000..d9fe60b
--- /dev/null
@@ -0,0 +1,2686 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_frontend.h"
+
+#include "dib0090.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { \
+       if (debug) { \
+               printk(KERN_DEBUG "DiB0090: "); \
+               printk(args); \
+               printk("\n"); \
+       } \
+} while (0)
+
+#define CONFIG_SYS_DVBT
+#define CONFIG_SYS_ISDBT
+#define CONFIG_BAND_CBAND
+#define CONFIG_BAND_VHF
+#define CONFIG_BAND_UHF
+#define CONFIG_DIB0090_USE_PWM_AGC
+
+#define EN_LNA0      0x8000
+#define EN_LNA1      0x4000
+#define EN_LNA2      0x2000
+#define EN_LNA3      0x1000
+#define EN_MIX0      0x0800
+#define EN_MIX1      0x0400
+#define EN_MIX2      0x0200
+#define EN_MIX3      0x0100
+#define EN_IQADC     0x0040
+#define EN_PLL       0x0020
+#define EN_TX        0x0010
+#define EN_BB        0x0008
+#define EN_LO        0x0004
+#define EN_BIAS      0x0001
+
+#define EN_IQANA     0x0002
+#define EN_DIGCLK    0x0080    /* not in the 0x24 reg, only in 0x1b */
+#define EN_CRYSTAL   0x0002
+
+#define EN_UHF          0x22E9
+#define EN_VHF          0x44E9
+#define EN_LBD          0x11E9
+#define EN_SBD          0x44E9
+#define EN_CAB          0x88E9
+
+/* Calibration defines */
+#define      DC_CAL 0x1
+#define     WBD_CAL 0x2
+#define    TEMP_CAL 0x4
+#define CAPTRIM_CAL 0x8
+
+#define KROSUS_PLL_LOCKED   0x800
+#define KROSUS              0x2
+
+/* Use those defines to identify SOC version */
+#define SOC               0x02
+#define SOC_7090_P1G_11R1 0x82
+#define SOC_7090_P1G_21R1 0x8a
+#define SOC_8090_P1G_11R1 0x86
+#define SOC_8090_P1G_21R1 0x8e
+
+/* else use thos ones to check */
+#define P1A_B      0x0
+#define P1C       0x1
+#define P1D_E_F    0x3
+#define P1G       0x7
+#define P1G_21R2   0xf
+
+#define MP001 0x1              /* Single 9090/8096 */
+#define MP005 0x4              /* Single Sband */
+#define MP008 0x6              /* Dual diversity VHF-UHF-LBAND */
+#define MP009 0x7              /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
+
+#define pgm_read_word(w) (*w)
+
+struct dc_calibration;
+
+struct dib0090_tuning {
+       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
+       u8 switch_trim;
+       u8 lna_tune;
+       u16 lna_bias;
+       u16 v2i;
+       u16 mix;
+       u16 load;
+       u16 tuner_enable;
+};
+
+struct dib0090_pll {
+       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
+       u8 vco_band;
+       u8 hfdiv_code;
+       u8 hfdiv;
+       u8 topresc;
+};
+
+struct dib0090_identity {
+       u8 version;
+       u8 product;
+       u8 p1g;
+       u8 in_soc;
+};
+
+struct dib0090_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+       const struct dib0090_config *config;
+
+       u8 current_band;
+       enum frontend_tune_state tune_state;
+       u32 current_rf;
+
+       u16 wbd_offset;
+       s16 wbd_target;         /* in dB */
+
+       s16 rf_gain_limit;      /* take-over-point: where to split between bb and rf gain */
+       s16 current_gain;       /* keeps the currently programmed gain */
+       u8 agc_step;            /* new binary search */
+
+       u16 gain[2];            /* for channel monitoring */
+
+       const u16 *rf_ramp;
+       const u16 *bb_ramp;
+
+       /* for the software AGC ramps */
+       u16 bb_1_def;
+       u16 rf_lt_def;
+       u16 gain_reg[4];
+
+       /* for the captrim/dc-offset search */
+       s8 step;
+       s16 adc_diff;
+       s16 min_adc_diff;
+
+       s8 captrim;
+       s8 fcaptrim;
+
+       const struct dc_calibration *dc;
+       u16 bb6, bb7;
+
+       const struct dib0090_tuning *current_tune_table_index;
+       const struct dib0090_pll *current_pll_table_index;
+
+       u8 tuner_is_tuned;
+       u8 agc_freeze;
+
+       struct dib0090_identity identity;
+
+       u32 rf_request;
+       u8 current_standard;
+
+       u8 calibrate;
+       u32 rest;
+       u16 bias;
+       s16 temperature;
+
+       u8 wbd_calibration_gain;
+       const struct dib0090_wbd_slope *current_wbd_table;
+       u16 wbdmux;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[3];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+};
+
+struct dib0090_fw_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+       struct dib0090_identity identity;
+       const struct dib0090_config *config;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg;
+       u8 i2c_write_buffer[2];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+};
+
+static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = reg;
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->config->i2c_address;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 1;
+       state->msg[1].addr = state->config->i2c_address;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = state->i2c_read_buffer;
+       state->msg[1].len = 2;
+
+       if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+               printk(KERN_WARNING "DiB0090 I2C read failed\n");
+               ret = 0;
+       } else
+               ret = (state->i2c_read_buffer[0] << 8)
+                       | state->i2c_read_buffer[1];
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       state->i2c_write_buffer[0] = reg & 0xff;
+       state->i2c_write_buffer[1] = val >> 8;
+       state->i2c_write_buffer[2] = val & 0xff;
+
+       memset(state->msg, 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->config->i2c_address;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 3;
+
+       if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0090 I2C write failed\n");
+               ret = -EREMOTEIO;
+       } else
+               ret = 0;
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = reg;
+
+       memset(&state->msg, 0, sizeof(struct i2c_msg));
+       state->msg.addr = reg;
+       state->msg.flags = I2C_M_RD;
+       state->msg.buf = state->i2c_read_buffer;
+       state->msg.len = 2;
+       if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0090 I2C read failed\n");
+               ret = 0;
+       } else
+               ret = (state->i2c_read_buffer[0] << 8)
+                       | state->i2c_read_buffer[1];
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       state->i2c_write_buffer[0] = val >> 8;
+       state->i2c_write_buffer[1] = val & 0xff;
+
+       memset(&state->msg, 0, sizeof(struct i2c_msg));
+       state->msg.addr = reg;
+       state->msg.flags = 0;
+       state->msg.buf = state->i2c_write_buffer;
+       state->msg.len = 2;
+       if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0090 I2C write failed\n");
+               ret = -EREMOTEIO;
+       } else
+               ret = 0;
+
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+#define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
+#define ADC_TARGET -220
+#define GAIN_ALPHA 5
+#define WBD_ALPHA 6
+#define LPF    100
+static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
+{
+       do {
+               dib0090_write_reg(state, r++, *b++);
+       } while (--c);
+}
+
+static int dib0090_identify(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       u16 v;
+       struct dib0090_identity *identity = &state->identity;
+
+       v = dib0090_read_reg(state, 0x1a);
+
+       identity->p1g = 0;
+       identity->in_soc = 0;
+
+       dprintk("Tuner identification (Version = 0x%04x)", v);
+
+       /* without PLL lock info */
+       v &= ~KROSUS_PLL_LOCKED;
+
+       identity->version = v & 0xff;
+       identity->product = (v >> 8) & 0xf;
+
+       if (identity->product != KROSUS)
+               goto identification_error;
+
+       if ((identity->version & 0x3) == SOC) {
+               identity->in_soc = 1;
+               switch (identity->version) {
+               case SOC_8090_P1G_11R1:
+                       dprintk("SOC 8090 P1-G11R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_8090_P1G_21R1:
+                       dprintk("SOC 8090 P1-G21R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_7090_P1G_11R1:
+                       dprintk("SOC 7090 P1-G11R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_7090_P1G_21R1:
+                       dprintk("SOC 7090 P1-G21R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               default:
+                       goto identification_error;
+               }
+       } else {
+               switch ((identity->version >> 5) & 0x7) {
+               case MP001:
+                       dprintk("MP001 : 9090/8096");
+                       break;
+               case MP005:
+                       dprintk("MP005 : Single Sband");
+                       break;
+               case MP008:
+                       dprintk("MP008 : diversity VHF-UHF-LBAND");
+                       break;
+               case MP009:
+                       dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
+                       break;
+               default:
+                       goto identification_error;
+               }
+
+               switch (identity->version & 0x1f) {
+               case P1G_21R2:
+                       dprintk("P1G_21R2 detected");
+                       identity->p1g = 1;
+                       break;
+               case P1G:
+                       dprintk("P1G detected");
+                       identity->p1g = 1;
+                       break;
+               case P1D_E_F:
+                       dprintk("P1D/E/F detected");
+                       break;
+               case P1C:
+                       dprintk("P1C detected");
+                       break;
+               case P1A_B:
+                       dprintk("P1-A/B detected: driver is deactivated - not available");
+                       goto identification_error;
+                       break;
+               default:
+                       goto identification_error;
+               }
+       }
+
+       return 0;
+
+identification_error:
+       return -EIO;
+}
+
+static int dib0090_fw_identify(struct dvb_frontend *fe)
+{
+       struct dib0090_fw_state *state = fe->tuner_priv;
+       struct dib0090_identity *identity = &state->identity;
+
+       u16 v = dib0090_fw_read_reg(state, 0x1a);
+       identity->p1g = 0;
+       identity->in_soc = 0;
+
+       dprintk("FE: Tuner identification (Version = 0x%04x)", v);
+
+       /* without PLL lock info */
+       v &= ~KROSUS_PLL_LOCKED;
+
+       identity->version = v & 0xff;
+       identity->product = (v >> 8) & 0xf;
+
+       if (identity->product != KROSUS)
+               goto identification_error;
+
+       if ((identity->version & 0x3) == SOC) {
+               identity->in_soc = 1;
+               switch (identity->version) {
+               case SOC_8090_P1G_11R1:
+                       dprintk("SOC 8090 P1-G11R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_8090_P1G_21R1:
+                       dprintk("SOC 8090 P1-G21R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_7090_P1G_11R1:
+                       dprintk("SOC 7090 P1-G11R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               case SOC_7090_P1G_21R1:
+                       dprintk("SOC 7090 P1-G21R1 Has been detected");
+                       identity->p1g = 1;
+                       break;
+               default:
+                       goto identification_error;
+               }
+       } else {
+               switch ((identity->version >> 5) & 0x7) {
+               case MP001:
+                       dprintk("MP001 : 9090/8096");
+                       break;
+               case MP005:
+                       dprintk("MP005 : Single Sband");
+                       break;
+               case MP008:
+                       dprintk("MP008 : diversity VHF-UHF-LBAND");
+                       break;
+               case MP009:
+                       dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
+                       break;
+               default:
+                       goto identification_error;
+               }
+
+               switch (identity->version & 0x1f) {
+               case P1G_21R2:
+                       dprintk("P1G_21R2 detected");
+                       identity->p1g = 1;
+                       break;
+               case P1G:
+                       dprintk("P1G detected");
+                       identity->p1g = 1;
+                       break;
+               case P1D_E_F:
+                       dprintk("P1D/E/F detected");
+                       break;
+               case P1C:
+                       dprintk("P1C detected");
+                       break;
+               case P1A_B:
+                       dprintk("P1-A/B detected: driver is deactivated - not available");
+                       goto identification_error;
+                       break;
+               default:
+                       goto identification_error;
+               }
+       }
+
+       return 0;
+
+identification_error:
+       return -EIO;
+}
+
+static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       u16 PllCfg, i, v;
+
+       HARD_RESET(state);
+
+       dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
+       dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);        /* PLL, DIG_CLK and CRYSTAL remain */
+
+       if (!cfg->in_soc) {
+               /* adcClkOutRatio=8->7, release reset */
+               dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
+               if (cfg->clkoutdrive != 0)
+                       dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
+                                         | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
+               else
+                       dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
+                                         | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
+       }
+
+       /* Read Pll current config * */
+       PllCfg = dib0090_read_reg(state, 0x21);
+
+       /** Reconfigure PLL if current setting is different from default setting **/
+       if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
+                       && !cfg->io.pll_bypass) {
+
+               /* Set Bypass mode */
+               PllCfg |= (1 << 15);
+               dib0090_write_reg(state, 0x21, PllCfg);
+
+               /* Set Reset Pll */
+               PllCfg &= ~(1 << 13);
+               dib0090_write_reg(state, 0x21, PllCfg);
+
+       /*** Set new Pll configuration in bypass and reset state ***/
+               PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
+               dib0090_write_reg(state, 0x21, PllCfg);
+
+               /* Remove Reset Pll */
+               PllCfg |= (1 << 13);
+               dib0090_write_reg(state, 0x21, PllCfg);
+
+       /*** Wait for PLL lock ***/
+               i = 100;
+               do {
+                       v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
+                       if (v)
+                               break;
+               } while (--i);
+
+               if (i == 0) {
+                       dprintk("Pll: Unable to lock Pll");
+                       return;
+               }
+
+               /* Finally Remove Bypass mode */
+               PllCfg &= ~(1 << 15);
+               dib0090_write_reg(state, 0x21, PllCfg);
+       }
+
+       if (cfg->io.pll_bypass) {
+               PllCfg |= (cfg->io.pll_bypass << 15);
+               dib0090_write_reg(state, 0x21, PllCfg);
+       }
+}
+
+static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
+{
+       struct dib0090_fw_state *state = fe->tuner_priv;
+       u16 PllCfg;
+       u16 v;
+       int i;
+
+       dprintk("fw reset digital");
+       HARD_RESET(state);
+
+       dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
+       dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);     /* PLL, DIG_CLK and CRYSTAL remain */
+
+       dib0090_fw_write_reg(state, 0x20,
+                       ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
+
+       v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
+       if (cfg->clkoutdrive != 0)
+               v |= cfg->clkoutdrive << 5;
+       else
+               v |= 7 << 5;
+
+       v |= 2 << 10;
+       dib0090_fw_write_reg(state, 0x23, v);
+
+       /* Read Pll current config * */
+       PllCfg = dib0090_fw_read_reg(state, 0x21);
+
+       /** Reconfigure PLL if current setting is different from default setting **/
+       if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
+
+               /* Set Bypass mode */
+               PllCfg |= (1 << 15);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+
+               /* Set Reset Pll */
+               PllCfg &= ~(1 << 13);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+
+       /*** Set new Pll configuration in bypass and reset state ***/
+               PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+
+               /* Remove Reset Pll */
+               PllCfg |= (1 << 13);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+
+       /*** Wait for PLL lock ***/
+               i = 100;
+               do {
+                       v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
+                       if (v)
+                               break;
+               } while (--i);
+
+               if (i == 0) {
+                       dprintk("Pll: Unable to lock Pll");
+                       return -EIO;
+               }
+
+               /* Finally Remove Bypass mode */
+               PllCfg &= ~(1 << 15);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+       }
+
+       if (cfg->io.pll_bypass) {
+               PllCfg |= (cfg->io.pll_bypass << 15);
+               dib0090_fw_write_reg(state, 0x21, PllCfg);
+       }
+
+       return dib0090_fw_identify(fe);
+}
+
+static int dib0090_wakeup(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (state->config->sleep)
+               state->config->sleep(fe, 0);
+
+       /* enable dataTX in case we have been restarted in the wrong moment */
+       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
+       return 0;
+}
+
+static int dib0090_sleep(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (state->config->sleep)
+               state->config->sleep(fe, 1);
+       return 0;
+}
+
+void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (fast)
+               dib0090_write_reg(state, 0x04, 0);
+       else
+               dib0090_write_reg(state, 0x04, 1);
+}
+
+EXPORT_SYMBOL(dib0090_dcc_freq);
+
+static const u16 bb_ramp_pwm_normal_socs[] = {
+       550,                    /* max BB gain in 10th of dB */
+       (1 << 9) | 8,           /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
+       440,
+       (4 << 9) | 0,           /* BB_RAMP3 = 26dB */
+       (0 << 9) | 208,         /* BB_RAMP4 */
+       (4 << 9) | 208,         /* BB_RAMP5 = 29dB */
+       (0 << 9) | 440,         /* BB_RAMP6 */
+};
+
+static const u16 rf_ramp_pwm_cband_7090[] = {
+       280,                    /* max RF gain in 10th of dB */
+       18,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
+       504,                    /* ramp_max = maximum X used on the ramp */
+       (29 << 10) | 364,       /* RF_RAMP5, LNA 1 = 8dB */
+       (0 << 10) | 504,        /* RF_RAMP6, LNA 1 */
+       (60 << 10) | 228,       /* RF_RAMP7, LNA 2 = 7.7dB */
+       (0 << 10) | 364,        /* RF_RAMP8, LNA 2 */
+       (34 << 10) | 109,       /* GAIN_4_1, LNA 3 = 6.8dB */
+       (0 << 10) | 228,        /* GAIN_4_2, LNA 3 */
+       (37 << 10) | 0,         /* RF_RAMP3, LNA 4 = 6.2dB */
+       (0 << 10) | 109,        /* RF_RAMP4, LNA 4 */
+};
+
+static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
+       186,
+       40,
+       746,
+       (10 << 10) | 345,
+       (0  << 10) | 746,
+       (0 << 10) | 0,
+       (0  << 10) | 0,
+       (28 << 10) | 200,
+       (0  << 10) | 345,
+       (20 << 10) | 0,
+       (0  << 10) | 200,
+};
+
+static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
+       86,
+       40,
+       345,
+       (0 << 10) | 0,
+       (0 << 10) | 0,
+       (0 << 10) | 0,
+       (0 << 10) | 0,
+       (28 << 10) | 200,
+       (0  << 10) | 345,
+       (20 << 10) | 0,
+       (0  << 10) | 200,
+};
+
+static const u16 rf_ramp_pwm_cband_8090[] = {
+       345,                    /* max RF gain in 10th of dB */
+       29,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
+       1000,                   /* ramp_max = maximum X used on the ramp */
+       (35 << 10) | 772,       /* RF_RAMP3, LNA 1 = 8dB */
+       (0 << 10) | 1000,       /* RF_RAMP4, LNA 1 */
+       (58 << 10) | 496,       /* RF_RAMP5, LNA 2 = 9.5dB */
+       (0 << 10) | 772,        /* RF_RAMP6, LNA 2 */
+       (27 << 10) | 200,       /* RF_RAMP7, LNA 3 = 10.5dB */
+       (0 << 10) | 496,        /* RF_RAMP8, LNA 3 */
+       (40 << 10) | 0,         /* GAIN_4_1, LNA 4 = 7dB */
+       (0 << 10) | 200,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_uhf_7090[] = {
+       407,                    /* max RF gain in 10th of dB */
+       13,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
+       529,                    /* ramp_max = maximum X used on the ramp */
+       (23 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
+       (0 << 10) | 176,        /* RF_RAMP4, LNA 1 */
+       (63 << 10) | 400,       /* RF_RAMP5, LNA 2 = 8dB */
+       (0 << 10) | 529,        /* RF_RAMP6, LNA 2 */
+       (48 << 10) | 316,       /* RF_RAMP7, LNA 3 = 6.8dB */
+       (0 << 10) | 400,        /* RF_RAMP8, LNA 3 */
+       (29 << 10) | 176,       /* GAIN_4_1, LNA 4 = 11.5dB */
+       (0 << 10) | 316,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_uhf_8090[] = {
+       388,                    /* max RF gain in 10th of dB */
+       26,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
+       1008,                   /* ramp_max = maximum X used on the ramp */
+       (11 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
+       (0 << 10) | 369,        /* RF_RAMP4, LNA 1 */
+       (41 << 10) | 809,       /* RF_RAMP5, LNA 2 = 8dB */
+       (0 << 10) | 1008,       /* RF_RAMP6, LNA 2 */
+       (27 << 10) | 659,       /* RF_RAMP7, LNA 3 = 6dB */
+       (0 << 10) | 809,        /* RF_RAMP8, LNA 3 */
+       (14 << 10) | 369,       /* GAIN_4_1, LNA 4 = 11.5dB */
+       (0 << 10) | 659,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_cband[] = {
+       0,                      /* max RF gain in 10th of dB */
+       0,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       0,                      /* ramp_max = maximum X used on the ramp */
+       (0 << 10) | 0,          /* 0x2c, LNA 1 = 0dB */
+       (0 << 10) | 0,          /* 0x2d, LNA 1 */
+       (0 << 10) | 0,          /* 0x2e, LNA 2 = 0dB */
+       (0 << 10) | 0,          /* 0x2f, LNA 2 */
+       (0 << 10) | 0,          /* 0x30, LNA 3 = 0dB */
+       (0 << 10) | 0,          /* 0x31, LNA 3 */
+       (0 << 10) | 0,          /* GAIN_4_1, LNA 4 = 0dB */
+       (0 << 10) | 0,          /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_vhf[] = {
+       412,                    /* max RF gain in 10th of dB */
+       132, 307, 127,          /* LNA1,  13.2dB */
+       105, 412, 255,          /* LNA2,  10.5dB */
+       50, 50, 127,            /* LNA3,  5dB */
+       125, 175, 127,          /* LNA4,  12.5dB */
+       0, 0, 127,              /* CBAND, 0dB */
+};
+
+static const u16 rf_ramp_uhf[] = {
+       412,                    /* max RF gain in 10th of dB */
+       132, 307, 127,          /* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
+       105, 412, 255,          /* LNA2  : 10.5 dB */
+       50, 50, 127,            /* LNA3  :  5.0 dB */
+       125, 175, 127,          /* LNA4  : 12.5 dB */
+       0, 0, 127,              /* CBAND :  0.0 dB */
+};
+
+static const u16 rf_ramp_cband_broadmatching[] =       /* for p1G only */
+{
+       314,                    /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
+       84, 314, 127,           /* LNA1 */
+       80, 230, 255,           /* LNA2 */
+       80, 150, 127,           /* LNA3  It was measured 12dB, do not lock if 120 */
+       70, 70, 127,            /* LNA4 */
+       0, 0, 127,              /* CBAND */
+};
+
+static const u16 rf_ramp_cband[] = {
+       332,                    /* max RF gain in 10th of dB */
+       132, 252, 127,          /* LNA1,  dB */
+       80, 332, 255,           /* LNA2,  dB */
+       0, 0, 127,              /* LNA3,  dB */
+       0, 0, 127,              /* LNA4,  dB */
+       120, 120, 127,          /* LT1 CBAND */
+};
+
+static const u16 rf_ramp_pwm_vhf[] = {
+       404,                    /* max RF gain in 10th of dB */
+       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       1011,                   /* ramp_max = maximum X used on the ramp */
+       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
+       (0 << 10) | 756,        /* 0x2d, LNA 1 */
+       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
+       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
+       (16 << 10) | 290,       /* 0x30, LNA 3 = 5dB */
+       (0 << 10) | 417,        /* 0x31, LNA 3 */
+       (7 << 10) | 0,          /* GAIN_4_1, LNA 4 = 12.5dB */
+       (0 << 10) | 290,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 rf_ramp_pwm_uhf[] = {
+       404,                    /* max RF gain in 10th of dB */
+       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
+       1011,                   /* ramp_max = maximum X used on the ramp */
+       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
+       (0 << 10) | 756,        /* 0x2d, LNA 1 */
+       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
+       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
+       (16 << 10) | 0,         /* 0x30, LNA 3 = 5dB */
+       (0 << 10) | 127,        /* 0x31, LNA 3 */
+       (7 << 10) | 127,        /* GAIN_4_1, LNA 4 = 12.5dB */
+       (0 << 10) | 417,        /* GAIN_4_2, LNA 4 */
+};
+
+static const u16 bb_ramp_boost[] = {
+       550,                    /* max BB gain in 10th of dB */
+       260, 260, 26,           /* BB1, 26dB */
+       290, 550, 29,           /* BB2, 29dB */
+};
+
+static const u16 bb_ramp_pwm_normal[] = {
+       500,                    /* max RF gain in 10th of dB */
+       8,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
+       400,
+       (2 << 9) | 0,           /* 0x35 = 21dB */
+       (0 << 9) | 168,         /* 0x36 */
+       (2 << 9) | 168,         /* 0x37 = 29dB */
+       (0 << 9) | 400,         /* 0x38 */
+};
+
+struct slope {
+       s16 range;
+       s16 slope;
+};
+static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
+{
+       u8 i;
+       u16 rest;
+       u16 ret = 0;
+       for (i = 0; i < num; i++) {
+               if (val > slopes[i].range)
+                       rest = slopes[i].range;
+               else
+                       rest = val;
+               ret += (rest * slopes[i].slope) / slopes[i].range;
+               val -= rest;
+       }
+       return ret;
+}
+
+static const struct slope dib0090_wbd_slopes[3] = {
+       {66, 120},              /* -64,-52: offset -   65 */
+       {600, 170},             /* -52,-35: 65     -  665 */
+       {170, 250},             /* -45,-10: 665    - 835 */
+};
+
+static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
+{
+       wbd &= 0x3ff;
+       if (wbd < state->wbd_offset)
+               wbd = 0;
+       else
+               wbd -= state->wbd_offset;
+       /* -64dB is the floor */
+       return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
+}
+
+static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
+{
+       u16 offset = 250;
+
+       /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
+
+       if (state->current_band == BAND_VHF)
+               offset = 650;
+#ifndef FIRMWARE_FIREFLY
+       if (state->current_band == BAND_VHF)
+               offset = state->config->wbd_vhf_offset;
+       if (state->current_band == BAND_CBAND)
+               offset = state->config->wbd_cband_offset;
+#endif
+
+       state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
+       dprintk("wbd-target: %d dB", (u32) state->wbd_target);
+}
+
+static const int gain_reg_addr[4] = {
+       0x08, 0x0a, 0x0f, 0x01
+};
+
+static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
+{
+       u16 rf, bb, ref;
+       u16 i, v, gain_reg[4] = { 0 }, gain;
+       const u16 *g;
+
+       if (top_delta < -511)
+               top_delta = -511;
+       if (top_delta > 511)
+               top_delta = 511;
+
+       if (force) {
+               top_delta *= (1 << WBD_ALPHA);
+               gain_delta *= (1 << GAIN_ALPHA);
+       }
+
+       if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))       /* overflow */
+               state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
+       else
+               state->rf_gain_limit += top_delta;
+
+       if (state->rf_gain_limit < 0)   /*underflow */
+               state->rf_gain_limit = 0;
+
+       /* use gain as a temporary variable and correct current_gain */
+       gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
+       if (gain_delta >= ((s16) gain - state->current_gain))   /* overflow */
+               state->current_gain = gain;
+       else
+               state->current_gain += gain_delta;
+       /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
+       if (state->current_gain < 0)
+               state->current_gain = 0;
+
+       /* now split total gain to rf and bb gain */
+       gain = state->current_gain >> GAIN_ALPHA;
+
+       /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
+       if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
+               rf = state->rf_gain_limit >> WBD_ALPHA;
+               bb = gain - rf;
+               if (bb > state->bb_ramp[0])
+                       bb = state->bb_ramp[0];
+       } else {                /* high signal level -> all gains put on RF */
+               rf = gain;
+               bb = 0;
+       }
+
+       state->gain[0] = rf;
+       state->gain[1] = bb;
+
+       /* software ramp */
+       /* Start with RF gains */
+       g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
+       ref = rf;
+       for (i = 0; i < 7; i++) {       /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
+               if (g[0] == 0 || ref < (g[1] - g[0]))   /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
+                       v = 0;  /* force the gain to write for the current amp to be null */
+               else if (ref >= g[1])   /* Gain to set is higher than the high working point of this amp */
+                       v = g[2];       /* force this amp to be full gain */
+               else            /* compute the value to set to this amp because we are somewhere in his range */
+                       v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
+
+               if (i == 0)     /* LNA 1 reg mapping */
+                       gain_reg[0] = v;
+               else if (i == 1)        /* LNA 2 reg mapping */
+                       gain_reg[0] |= v << 7;
+               else if (i == 2)        /* LNA 3 reg mapping */
+                       gain_reg[1] = v;
+               else if (i == 3)        /* LNA 4 reg mapping */
+                       gain_reg[1] |= v << 7;
+               else if (i == 4)        /* CBAND LNA reg mapping */
+                       gain_reg[2] = v | state->rf_lt_def;
+               else if (i == 5)        /* BB gain 1 reg mapping */
+                       gain_reg[3] = v << 3;
+               else if (i == 6)        /* BB gain 2 reg mapping */
+                       gain_reg[3] |= v << 8;
+
+               g += 3;         /* go to next gain bloc */
+
+               /* When RF is finished, start with BB */
+               if (i == 4) {
+                       g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
+                       ref = bb;
+               }
+       }
+       gain_reg[3] |= state->bb_1_def;
+       gain_reg[3] |= ((bb % 10) * 100) / 125;
+
+#ifdef DEBUG_AGC
+       dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
+               gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
+#endif
+
+       /* Write the amplifier regs */
+       for (i = 0; i < 4; i++) {
+               v = gain_reg[i];
+               if (force || state->gain_reg[i] != v) {
+                       state->gain_reg[i] = v;
+                       dib0090_write_reg(state, gain_reg_addr[i], v);
+               }
+       }
+}
+
+static void dib0090_set_boost(struct dib0090_state *state, int onoff)
+{
+       state->bb_1_def &= 0xdfff;
+       state->bb_1_def |= onoff << 13;
+}
+
+static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
+{
+       state->rf_ramp = cfg;
+}
+
+static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
+{
+       state->rf_ramp = cfg;
+
+       dib0090_write_reg(state, 0x2a, 0xffff);
+
+       dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
+
+       dib0090_write_regs(state, 0x2c, cfg + 3, 6);
+       dib0090_write_regs(state, 0x3e, cfg + 9, 2);
+}
+
+static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
+{
+       state->bb_ramp = cfg;
+       dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
+}
+
+static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
+{
+       state->bb_ramp = cfg;
+
+       dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
+
+       dib0090_write_reg(state, 0x33, 0xffff);
+       dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
+       dib0090_write_regs(state, 0x35, cfg + 3, 4);
+}
+
+void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       /* reset the AGC */
+
+       if (state->config->use_pwm_agc) {
+#ifdef CONFIG_BAND_SBAND
+               if (state->current_band == BAND_SBAND) {
+                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
+                       dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
+               } else
+#endif
+#ifdef CONFIG_BAND_CBAND
+               if (state->current_band == BAND_CBAND) {
+                       if (state->identity.in_soc) {
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
+                               if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
+                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
+                               else if (state->identity.version == SOC_7090_P1G_11R1
+                                               || state->identity.version == SOC_7090_P1G_21R1) {
+                                       if (state->config->is_dib7090e) {
+                                               if (state->rf_ramp == NULL)
+                                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
+                                               else
+                                                       dib0090_set_rframp_pwm(state, state->rf_ramp);
+                                       } else
+                                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
+                               }
+                       } else {
+                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+                       }
+               } else
+#endif
+#ifdef CONFIG_BAND_VHF
+               if (state->current_band == BAND_VHF) {
+                       if (state->identity.in_soc) {
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
+                       } else {
+                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+                       }
+               } else
+#endif
+               {
+                       if (state->identity.in_soc) {
+                               if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
+                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
+                               else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
+                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
+                       } else {
+                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
+                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
+                       }
+               }
+
+               if (state->rf_ramp[0] != 0)
+                       dib0090_write_reg(state, 0x32, (3 << 11));
+               else
+                       dib0090_write_reg(state, 0x32, (0 << 11));
+
+               dib0090_write_reg(state, 0x04, 0x03);
+               dib0090_write_reg(state, 0x39, (1 << 10));
+       }
+}
+
+EXPORT_SYMBOL(dib0090_pwm_gain_reset);
+
+void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (DC_servo_cutoff < 4)
+               dib0090_write_reg(state, 0x04, DC_servo_cutoff);
+}
+EXPORT_SYMBOL(dib0090_set_dc_servo);
+
+static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
+{
+       u16 adc_val = dib0090_read_reg(state, 0x1d);
+       if (state->identity.in_soc)
+               adc_val >>= 2;
+       return adc_val;
+}
+
+int dib0090_gain_control(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       enum frontend_tune_state *tune_state = &state->tune_state;
+       int ret = 10;
+
+       u16 wbd_val = 0;
+       u8 apply_gain_immediatly = 1;
+       s16 wbd_error = 0, adc_error = 0;
+
+       if (*tune_state == CT_AGC_START) {
+               state->agc_freeze = 0;
+               dib0090_write_reg(state, 0x04, 0x0);
+
+#ifdef CONFIG_BAND_SBAND
+               if (state->current_band == BAND_SBAND) {
+                       dib0090_set_rframp(state, rf_ramp_sband);
+                       dib0090_set_bbramp(state, bb_ramp_boost);
+               } else
+#endif
+#ifdef CONFIG_BAND_VHF
+               if (state->current_band == BAND_VHF && !state->identity.p1g) {
+                       dib0090_set_rframp(state, rf_ramp_vhf);
+                       dib0090_set_bbramp(state, bb_ramp_boost);
+               } else
+#endif
+#ifdef CONFIG_BAND_CBAND
+               if (state->current_band == BAND_CBAND && !state->identity.p1g) {
+                       dib0090_set_rframp(state, rf_ramp_cband);
+                       dib0090_set_bbramp(state, bb_ramp_boost);
+               } else
+#endif
+               if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
+                       dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
+                       dib0090_set_bbramp(state, bb_ramp_boost);
+               } else {
+                       dib0090_set_rframp(state, rf_ramp_uhf);
+                       dib0090_set_bbramp(state, bb_ramp_boost);
+               }
+
+               dib0090_write_reg(state, 0x32, 0);
+               dib0090_write_reg(state, 0x39, 0);
+
+               dib0090_wbd_target(state, state->current_rf);
+
+               state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
+               state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
+
+               *tune_state = CT_AGC_STEP_0;
+       } else if (!state->agc_freeze) {
+               s16 wbd = 0, i, cnt;
+
+               int adc;
+               wbd_val = dib0090_get_slow_adc_val(state);
+
+               if (*tune_state == CT_AGC_STEP_0)
+                       cnt = 5;
+               else
+                       cnt = 1;
+
+               for (i = 0; i < cnt; i++) {
+                       wbd_val = dib0090_get_slow_adc_val(state);
+                       wbd += dib0090_wbd_to_db(state, wbd_val);
+               }
+               wbd /= cnt;
+               wbd_error = state->wbd_target - wbd;
+
+               if (*tune_state == CT_AGC_STEP_0) {
+                       if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
+#ifdef CONFIG_BAND_CBAND
+                               /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
+                               u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
+                               if (state->current_band == BAND_CBAND && ltg2) {
+                                       ltg2 >>= 1;
+                                       state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
+                               }
+#endif
+                       } else {
+                               state->agc_step = 0;
+                               *tune_state = CT_AGC_STEP_1;
+                       }
+               } else {
+                       /* calc the adc power */
+                       adc = state->config->get_adc_power(fe);
+                       adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
+
+                       adc_error = (s16) (((s32) ADC_TARGET) - adc);
+#ifdef CONFIG_STANDARD_DAB
+                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
+                               adc_error -= 10;
+#endif
+#ifdef CONFIG_STANDARD_DVBT
+                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
+                                       (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
+                               adc_error += 60;
+#endif
+#ifdef CONFIG_SYS_ISDBT
+                       if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
+                                                               0)
+                                                       &&
+                                                       ((state->fe->dtv_property_cache.layer[0].modulation ==
+                                                         QAM_64)
+                                                        || (state->fe->dtv_property_cache.
+                                                                layer[0].modulation == QAM_16)))
+                                               ||
+                                               ((state->fe->dtv_property_cache.layer[1].segment_count >
+                                                 0)
+                                                &&
+                                                ((state->fe->dtv_property_cache.layer[1].modulation ==
+                                                  QAM_64)
+                                                 || (state->fe->dtv_property_cache.
+                                                         layer[1].modulation == QAM_16)))
+                                               ||
+                                               ((state->fe->dtv_property_cache.layer[2].segment_count >
+                                                 0)
+                                                &&
+                                                ((state->fe->dtv_property_cache.layer[2].modulation ==
+                                                  QAM_64)
+                                                 || (state->fe->dtv_property_cache.
+                                                         layer[2].modulation == QAM_16)))
+                                               )
+                               )
+                               adc_error += 60;
+#endif
+
+                       if (*tune_state == CT_AGC_STEP_1) {     /* quickly go to the correct range of the ADC power */
+                               if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
+
+#ifdef CONFIG_STANDARD_DAB
+                                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
+                                               dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));      /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
+                                               dib0090_write_reg(state, 0x04, 0x0);
+                                       } else
+#endif
+                                       {
+                                               dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
+                                               dib0090_write_reg(state, 0x04, 0x01);   /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
+                                       }
+
+                                       *tune_state = CT_AGC_STOP;
+                               }
+                       } else {
+                               /* everything higher than or equal to CT_AGC_STOP means tracking */
+                               ret = 100;      /* 10ms interval */
+                               apply_gain_immediatly = 0;
+                       }
+               }
+#ifdef DEBUG_AGC
+               dprintk
+                       ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
+                        (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
+                        (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
+#endif
+       }
+
+       /* apply gain */
+       if (!state->agc_freeze)
+               dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
+       return ret;
+}
+
+EXPORT_SYMBOL(dib0090_gain_control);
+
+void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       if (rf)
+               *rf = state->gain[0];
+       if (bb)
+               *bb = state->gain[1];
+       if (rf_gain_limit)
+               *rf_gain_limit = state->rf_gain_limit;
+       if (rflt)
+               *rflt = (state->rf_lt_def >> 10) & 0x7;
+}
+
+EXPORT_SYMBOL(dib0090_get_current_gain);
+
+u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
+       s32 current_temp = state->temperature;
+       s32 wbd_thot, wbd_tcold;
+       const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
+
+       while (f_MHz > wbd->max_freq)
+               wbd++;
+
+       dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
+
+       if (current_temp < 0)
+               current_temp = 0;
+       if (current_temp > 128)
+               current_temp = 128;
+
+       state->wbdmux &= ~(7 << 13);
+       if (wbd->wbd_gain != 0)
+               state->wbdmux |= (wbd->wbd_gain << 13);
+       else
+               state->wbdmux |= (4 << 13);
+
+       dib0090_write_reg(state, 0x10, state->wbdmux);
+
+       wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
+       wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
+
+       wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
+
+       state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
+       dprintk("wbd-target: %d dB", (u32) state->wbd_target);
+       dprintk("wbd offset applied is %d", wbd_tcold);
+
+       return state->wbd_offset + wbd_tcold;
+}
+EXPORT_SYMBOL(dib0090_get_wbd_target);
+
+u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       return state->wbd_offset;
+}
+EXPORT_SYMBOL(dib0090_get_wbd_offset);
+
+int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
+                       | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
+
+       return 0;
+}
+EXPORT_SYMBOL(dib0090_set_switch);
+
+int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
+                       | ((onoff & 1) << 15));
+       return 0;
+}
+EXPORT_SYMBOL(dib0090_set_vga);
+
+int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       if ((!state->identity.p1g) || (!state->identity.in_soc)
+                       || ((state->identity.version != SOC_7090_P1G_21R1)
+                               && (state->identity.version != SOC_7090_P1G_11R1))) {
+               dprintk("%s() function can only be used for dib7090P", __func__);
+               return -ENODEV;
+       }
+
+       if (cfg_sensitivity)
+               state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
+       else
+               state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
+       dib0090_pwm_gain_reset(fe);
+
+       return 0;
+}
+EXPORT_SYMBOL(dib0090_update_rframp_7090);
+
+static const u16 dib0090_defaults[] = {
+
+       25, 0x01,
+       0x0000,
+       0x99a0,
+       0x6008,
+       0x0000,
+       0x8bcb,
+       0x0000,
+       0x0405,
+       0x0000,
+       0x0000,
+       0x0000,
+       0xb802,
+       0x0300,
+       0x2d12,
+       0xbac0,
+       0x7c00,
+       0xdbb9,
+       0x0954,
+       0x0743,
+       0x8000,
+       0x0001,
+       0x0040,
+       0x0100,
+       0x0000,
+       0xe910,
+       0x149e,
+
+       1, 0x1c,
+       0xff2d,
+
+       1, 0x39,
+       0x0000,
+
+       2, 0x1e,
+       0x07FF,
+       0x0007,
+
+       1, 0x24,
+       EN_UHF | EN_CRYSTAL,
+
+       2, 0x3c,
+       0x3ff,
+       0x111,
+       0
+};
+
+static const u16 dib0090_p1g_additionnal_defaults[] = {
+       1, 0x05,
+       0xabcd,
+
+       1, 0x11,
+       0x00b4,
+
+       1, 0x1c,
+       0xfffd,
+
+       1, 0x40,
+       0x108,
+       0
+};
+
+static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
+{
+       u16 l, r;
+
+       l = pgm_read_word(n++);
+       while (l) {
+               r = pgm_read_word(n++);
+               do {
+                       dib0090_write_reg(state, r, pgm_read_word(n++));
+                       r++;
+               } while (--l);
+               l = pgm_read_word(n++);
+       }
+}
+
+#define CAP_VALUE_MIN (u8)  9
+#define CAP_VALUE_MAX (u8) 40
+#define HR_MIN       (u8) 25
+#define HR_MAX       (u8) 40
+#define POLY_MIN      (u8)  0
+#define POLY_MAX      (u8)  8
+
+static void dib0090_set_EFUSE(struct dib0090_state *state)
+{
+       u8 c, h, n;
+       u16 e2, e4;
+       u16 cal;
+
+       e2 = dib0090_read_reg(state, 0x26);
+       e4 = dib0090_read_reg(state, 0x28);
+
+       if ((state->identity.version == P1D_E_F) ||
+                       (state->identity.version == P1G) || (e2 == 0xffff)) {
+
+               dib0090_write_reg(state, 0x22, 0x10);
+               cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
+
+               if ((cal < 670) || (cal == 1023))
+                       cal = 850;
+               n = 165 - ((cal * 10)>>6) ;
+               e2 = e4 = (3<<12) | (34<<6) | (n);
+       }
+
+       if (e2 != e4)
+               e2 &= e4; /* Remove the redundancy  */
+
+       if (e2 != 0xffff) {
+               c = e2 & 0x3f;
+               n = (e2 >> 12) & 0xf;
+               h = (e2 >> 6) & 0x3f;
+
+               if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
+                       c = 32;
+               if ((h >= HR_MAX) || (h <= HR_MIN))
+                       h = 34;
+               if ((n >= POLY_MAX) || (n <= POLY_MIN))
+                       n = 3;
+
+               dib0090_write_reg(state, 0x13, (h << 10)) ;
+               e2 = (n<<11) | ((h>>2)<<6) | (c);
+               dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
+       }
+}
+
+static int dib0090_reset(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       dib0090_reset_digital(fe, state->config);
+       if (dib0090_identify(fe) < 0)
+               return -EIO;
+
+#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
+       if (!(state->identity.version & 0x1))   /* it is P1B - reset is already done */
+               return 0;
+#endif
+
+       if (!state->identity.in_soc) {
+               if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
+                       dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
+               else
+                       dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
+       }
+
+       dib0090_set_default_config(state, dib0090_defaults);
+
+       if (state->identity.in_soc)
+               dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
+
+       if (state->identity.p1g)
+               dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
+
+       /* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
+       if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
+               dib0090_set_EFUSE(state);
+
+       /* Congigure in function of the crystal */
+       if (state->config->force_crystal_mode != 0)
+               dib0090_write_reg(state, 0x14,
+                               state->config->force_crystal_mode & 3);
+       else if (state->config->io.clock_khz >= 24000)
+               dib0090_write_reg(state, 0x14, 1);
+       else
+               dib0090_write_reg(state, 0x14, 2);
+       dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
+
+       state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
+
+       return 0;
+}
+
+#define steps(u) (((u) > 15) ? ((u)-16) : (u))
+#define INTERN_WAIT 10
+static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+       int ret = INTERN_WAIT * 10;
+
+       switch (*tune_state) {
+       case CT_TUNER_STEP_2:
+               /* Turns to positive */
+               dib0090_write_reg(state, 0x1f, 0x7);
+               *tune_state = CT_TUNER_STEP_3;
+               break;
+
+       case CT_TUNER_STEP_3:
+               state->adc_diff = dib0090_read_reg(state, 0x1d);
+
+               /* Turns to negative */
+               dib0090_write_reg(state, 0x1f, 0x4);
+               *tune_state = CT_TUNER_STEP_4;
+               break;
+
+       case CT_TUNER_STEP_4:
+               state->adc_diff -= dib0090_read_reg(state, 0x1d);
+               *tune_state = CT_TUNER_STEP_5;
+               ret = 0;
+               break;
+
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+struct dc_calibration {
+       u8 addr;
+       u8 offset;
+       u8 pga:1;
+       u16 bb1;
+       u8 i:1;
+};
+
+static const struct dc_calibration dc_table[] = {
+       /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
+       {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
+       {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
+       /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
+       {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
+       {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
+       {0},
+};
+
+static const struct dc_calibration dc_p1g_table[] = {
+       /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
+       /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
+       {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
+       {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
+       /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
+       {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
+       {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
+       {0},
+};
+
+static void dib0090_set_trim(struct dib0090_state *state)
+{
+       u16 *val;
+
+       if (state->dc->addr == 0x07)
+               val = &state->bb7;
+       else
+               val = &state->bb6;
+
+       *val &= ~(0x1f << state->dc->offset);
+       *val |= state->step << state->dc->offset;
+
+       dib0090_write_reg(state, state->dc->addr, *val);
+}
+
+static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+       int ret = 0;
+       u16 reg;
+
+       switch (*tune_state) {
+       case CT_TUNER_START:
+               dprintk("Start DC offset calibration");
+
+               /* force vcm2 = 0.8V */
+               state->bb6 = 0;
+               state->bb7 = 0x040d;
+
+               /* the LNA AND LO are off */
+               reg = dib0090_read_reg(state, 0x24) & 0x0ffb;   /* shutdown lna and lo */
+               dib0090_write_reg(state, 0x24, reg);
+
+               state->wbdmux = dib0090_read_reg(state, 0x10);
+               dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
+               dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
+
+               state->dc = dc_table;
+
+               if (state->identity.p1g)
+                       state->dc = dc_p1g_table;
+               *tune_state = CT_TUNER_STEP_0;
+
+               /* fall through */
+
+       case CT_TUNER_STEP_0:
+               dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
+               dib0090_write_reg(state, 0x01, state->dc->bb1);
+               dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
+
+               state->step = 0;
+               state->min_adc_diff = 1023;
+               *tune_state = CT_TUNER_STEP_1;
+               ret = 50;
+               break;
+
+       case CT_TUNER_STEP_1:
+               dib0090_set_trim(state);
+               *tune_state = CT_TUNER_STEP_2;
+               break;
+
+       case CT_TUNER_STEP_2:
+       case CT_TUNER_STEP_3:
+       case CT_TUNER_STEP_4:
+               ret = dib0090_get_offset(state, tune_state);
+               break;
+
+       case CT_TUNER_STEP_5:   /* found an offset */
+               dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
+               if (state->step == 0 && state->adc_diff < 0) {
+                       state->min_adc_diff = -1023;
+                       dprintk("Change of sign of the minimum adc diff");
+               }
+
+               dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
+
+               /* first turn for this frequency */
+               if (state->step == 0) {
+                       if (state->dc->pga && state->adc_diff < 0)
+                               state->step = 0x10;
+                       if (state->dc->pga == 0 && state->adc_diff > 0)
+                               state->step = 0x10;
+               }
+
+               /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
+               if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
+                       /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
+                       state->step++;
+                       state->min_adc_diff = state->adc_diff;
+                       *tune_state = CT_TUNER_STEP_1;
+               } else {
+                       /* the minimum was what we have seen in the step before */
+                       if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
+                               dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
+                               state->step--;
+                       }
+
+                       dib0090_set_trim(state);
+                       dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
+
+                       state->dc++;
+                       if (state->dc->addr == 0)       /* done */
+                               *tune_state = CT_TUNER_STEP_6;
+                       else
+                               *tune_state = CT_TUNER_STEP_0;
+
+               }
+               break;
+
+       case CT_TUNER_STEP_6:
+               dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
+               dib0090_write_reg(state, 0x1f, 0x7);
+               *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
+               state->calibrate &= ~DC_CAL;
+       default:
+               break;
+       }
+       return ret;
+}
+
+static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+       u8 wbd_gain;
+       const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
+
+       switch (*tune_state) {
+       case CT_TUNER_START:
+               while (state->current_rf / 1000 > wbd->max_freq)
+                       wbd++;
+               if (wbd->wbd_gain != 0)
+                       wbd_gain = wbd->wbd_gain;
+               else {
+                       wbd_gain = 4;
+#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
+                       if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
+                               wbd_gain = 2;
+#endif
+               }
+
+               if (wbd_gain == state->wbd_calibration_gain) {  /* the WBD calibration has already been done */
+                       *tune_state = CT_TUNER_START;
+                       state->calibrate &= ~WBD_CAL;
+                       return 0;
+               }
+
+               dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
+
+               dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
+               *tune_state = CT_TUNER_STEP_0;
+               state->wbd_calibration_gain = wbd_gain;
+               return 90;      /* wait for the WBDMUX to switch and for the ADC to sample */
+
+       case CT_TUNER_STEP_0:
+               state->wbd_offset = dib0090_get_slow_adc_val(state);
+               dprintk("WBD calibration offset = %d", state->wbd_offset);
+               *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
+               state->calibrate &= ~WBD_CAL;
+               break;
+
+       default:
+               break;
+       }
+       return 0;
+}
+
+static void dib0090_set_bandwidth(struct dib0090_state *state)
+{
+       u16 tmp;
+
+       if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
+               tmp = (3 << 14);
+       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
+               tmp = (2 << 14);
+       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
+               tmp = (1 << 14);
+       else
+               tmp = (0 << 14);
+
+       state->bb_1_def &= 0x3fff;
+       state->bb_1_def |= tmp;
+
+       dib0090_write_reg(state, 0x01, state->bb_1_def);        /* be sure that we have the right bb-filter */
+
+       dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
+       dib0090_write_reg(state, 0x04, 0x1);    /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
+       if (state->identity.in_soc) {
+               dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
+       } else {
+               dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));     /* 22 = cap_value */
+               dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
+       }
+}
+
+static const struct dib0090_pll dib0090_pll_table[] = {
+#ifdef CONFIG_BAND_CBAND
+       {56000, 0, 9, 48, 6},
+       {70000, 1, 9, 48, 6},
+       {87000, 0, 8, 32, 4},
+       {105000, 1, 8, 32, 4},
+       {115000, 0, 7, 24, 6},
+       {140000, 1, 7, 24, 6},
+       {170000, 0, 6, 16, 4},
+#endif
+#ifdef CONFIG_BAND_VHF
+       {200000, 1, 6, 16, 4},
+       {230000, 0, 5, 12, 6},
+       {280000, 1, 5, 12, 6},
+       {340000, 0, 4, 8, 4},
+       {380000, 1, 4, 8, 4},
+       {450000, 0, 3, 6, 6},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {580000, 1, 3, 6, 6},
+       {700000, 0, 2, 4, 4},
+       {860000, 1, 2, 4, 4},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1800000, 1, 0, 2, 4},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2900000, 0, 14, 1, 4},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
+
+#ifdef CONFIG_BAND_CBAND
+       {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+       {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+       {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table[] = {
+
+#ifdef CONFIG_BAND_CBAND
+       {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_VHF
+       {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+       {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+       {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
+#ifdef CONFIG_BAND_CBAND
+       {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_VHF
+       {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+       {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+       {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+static const struct dib0090_pll dib0090_p1g_pll_table[] = {
+#ifdef CONFIG_BAND_CBAND
+       {57000, 0, 11, 48, 6},
+       {70000, 1, 11, 48, 6},
+       {86000, 0, 10, 32, 4},
+       {105000, 1, 10, 32, 4},
+       {115000, 0, 9, 24, 6},
+       {140000, 1, 9, 24, 6},
+       {170000, 0, 8, 16, 4},
+#endif
+#ifdef CONFIG_BAND_VHF
+       {200000, 1, 8, 16, 4},
+       {230000, 0, 7, 12, 6},
+       {280000, 1, 7, 12, 6},
+       {340000, 0, 6, 8, 4},
+       {380000, 1, 6, 8, 4},
+       {455000, 0, 5, 6, 6},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {580000, 1, 5, 6, 6},
+       {680000, 0, 4, 4, 4},
+       {860000, 1, 4, 4, 4},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1800000, 1, 2, 2, 4},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2900000, 0, 1, 1, 6},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
+#ifdef CONFIG_BAND_CBAND
+       {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
+       {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
+       {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
+#endif
+#ifdef CONFIG_BAND_UHF
+       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
+#endif
+#ifdef CONFIG_BAND_LBAND
+       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
+#endif
+#ifdef CONFIG_BAND_SBAND
+       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
+       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
+#ifdef CONFIG_BAND_CBAND
+       {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
+       {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
+       {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
+       {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
+#endif
+};
+
+static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
+#ifdef CONFIG_BAND_CBAND
+       { 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+       { 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+       { 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
+       { 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
+       { 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
+       { 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
+#endif
+};
+
+int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+               u8 cfg_sensitivity)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       const struct dib0090_tuning *tune =
+               dib0090_tuning_table_cband_7090e_sensitivity;
+       const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
+               { 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+               { 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
+               { 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
+       };
+
+       if ((!state->identity.p1g) || (!state->identity.in_soc)
+                       || ((state->identity.version != SOC_7090_P1G_21R1)
+                               && (state->identity.version != SOC_7090_P1G_11R1))) {
+               dprintk("%s() function can only be used for dib7090", __func__);
+               return -ENODEV;
+       }
+
+       if (cfg_sensitivity)
+               tune = dib0090_tuning_table_cband_7090e_sensitivity;
+       else
+               tune = dib0090_tuning_table_cband_7090e_aci;
+
+       while (state->rf_request > tune->max_freq)
+               tune++;
+
+       dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
+                       | (tune->lna_bias & 0x7fff));
+       dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
+                       | ((tune->lna_tune << 6) & 0x07c0));
+       return 0;
+}
+EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
+
+static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+       int ret = 0;
+       u16 lo4 = 0xe900;
+
+       s16 adc_target;
+       u16 adc;
+       s8 step_sign;
+       u8 force_soft_search = 0;
+
+       if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
+               force_soft_search = 1;
+
+       if (*tune_state == CT_TUNER_START) {
+               dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
+               dib0090_write_reg(state, 0x10, 0x2B1);
+               dib0090_write_reg(state, 0x1e, 0x0032);
+
+               if (!state->tuner_is_tuned) {
+                       /* prepare a complete captrim */
+                       if (!state->identity.p1g || force_soft_search)
+                               state->step = state->captrim = state->fcaptrim = 64;
+
+                       state->current_rf = state->rf_request;
+               } else {        /* we are already tuned to this frequency - the configuration is correct  */
+                       if (!state->identity.p1g || force_soft_search) {
+                               /* do a minimal captrim even if the frequency has not changed */
+                               state->step = 4;
+                               state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
+                       }
+               }
+               state->adc_diff = 3000;
+               *tune_state = CT_TUNER_STEP_0;
+
+       } else if (*tune_state == CT_TUNER_STEP_0) {
+               if (state->identity.p1g && !force_soft_search) {
+                       u8 ratio = 31;
+
+                       dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
+                       dib0090_read_reg(state, 0x40);
+                       ret = 50;
+               } else {
+                       state->step /= 2;
+                       dib0090_write_reg(state, 0x18, lo4 | state->captrim);
+
+                       if (state->identity.in_soc)
+                               ret = 25;
+               }
+               *tune_state = CT_TUNER_STEP_1;
+
+       } else if (*tune_state == CT_TUNER_STEP_1) {
+               if (state->identity.p1g && !force_soft_search) {
+                       dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
+                       dib0090_read_reg(state, 0x40);
+
+                       state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
+                       dprintk("***Final Captrim= 0x%x", state->fcaptrim);
+                       *tune_state = CT_TUNER_STEP_3;
+
+               } else {
+                       /* MERGE for all krosus before P1G */
+                       adc = dib0090_get_slow_adc_val(state);
+                       dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
+
+                       if (state->rest == 0 || state->identity.in_soc) {       /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
+                               adc_target = 200;
+                       } else
+                               adc_target = 400;
+
+                       if (adc >= adc_target) {
+                               adc -= adc_target;
+                               step_sign = -1;
+                       } else {
+                               adc = adc_target - adc;
+                               step_sign = 1;
+                       }
+
+                       if (adc < state->adc_diff) {
+                               dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
+                               state->adc_diff = adc;
+                               state->fcaptrim = state->captrim;
+                       }
+
+                       state->captrim += step_sign * state->step;
+                       if (state->step >= 1)
+                               *tune_state = CT_TUNER_STEP_0;
+                       else
+                               *tune_state = CT_TUNER_STEP_2;
+
+                       ret = 25;
+               }
+       } else if (*tune_state == CT_TUNER_STEP_2) {    /* this step is only used by krosus < P1G */
+               /*write the final cptrim config */
+               dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
+
+               *tune_state = CT_TUNER_STEP_3;
+
+       } else if (*tune_state == CT_TUNER_STEP_3) {
+               state->calibrate &= ~CAPTRIM_CAL;
+               *tune_state = CT_TUNER_STEP_0;
+       }
+
+       return ret;
+}
+
+static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
+{
+       int ret = 15;
+       s16 val;
+
+       switch (*tune_state) {
+       case CT_TUNER_START:
+               state->wbdmux = dib0090_read_reg(state, 0x10);
+               dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
+
+               state->bias = dib0090_read_reg(state, 0x13);
+               dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
+
+               *tune_state = CT_TUNER_STEP_0;
+               /* wait for the WBDMUX to switch and for the ADC to sample */
+               break;
+
+       case CT_TUNER_STEP_0:
+               state->adc_diff = dib0090_get_slow_adc_val(state);
+               dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
+               *tune_state = CT_TUNER_STEP_1;
+               break;
+
+       case CT_TUNER_STEP_1:
+               val = dib0090_get_slow_adc_val(state);
+               state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
+
+               dprintk("temperature: %d C", state->temperature - 30);
+
+               *tune_state = CT_TUNER_STEP_2;
+               break;
+
+       case CT_TUNER_STEP_2:
+               dib0090_write_reg(state, 0x13, state->bias);
+               dib0090_write_reg(state, 0x10, state->wbdmux);  /* write back original WBDMUX */
+
+               *tune_state = CT_TUNER_START;
+               state->calibrate &= ~TEMP_CAL;
+               if (state->config->analog_output == 0)
+                       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
+
+               break;
+
+       default:
+               ret = 0;
+               break;
+       }
+       return ret;
+}
+
+#define WBD     0x781          /* 1 1 1 1 0000 0 0 1 */
+static int dib0090_tune(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       const struct dib0090_tuning *tune = state->current_tune_table_index;
+       const struct dib0090_pll *pll = state->current_pll_table_index;
+       enum frontend_tune_state *tune_state = &state->tune_state;
+
+       u16 lo5, lo6, Den, tmp;
+       u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
+       int ret = 10;           /* 1ms is the default delay most of the time */
+       u8 c, i;
+
+       /************************* VCO ***************************/
+       /* Default values for FG                                 */
+       /* from these are needed :                               */
+       /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
+
+       /* in any case we first need to do a calibration if needed */
+       if (*tune_state == CT_TUNER_START) {
+               /* deactivate DataTX before some calibrations */
+               if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
+                       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
+               else
+                       /* Activate DataTX in case a calibration has been done before */
+                       if (state->config->analog_output == 0)
+                               dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
+       }
+
+       if (state->calibrate & DC_CAL)
+               return dib0090_dc_offset_calibration(state, tune_state);
+       else if (state->calibrate & WBD_CAL) {
+               if (state->current_rf == 0)
+                       state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
+               return dib0090_wbd_calibration(state, tune_state);
+       } else if (state->calibrate & TEMP_CAL)
+               return dib0090_get_temperature(state, tune_state);
+       else if (state->calibrate & CAPTRIM_CAL)
+               return dib0090_captrim_search(state, tune_state);
+
+       if (*tune_state == CT_TUNER_START) {
+               /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
+               if (state->config->use_pwm_agc && state->identity.in_soc) {
+                       tmp = dib0090_read_reg(state, 0x39);
+                       if ((tmp >> 10) & 0x1)
+                               dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
+               }
+
+               state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
+               state->rf_request =
+                       state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
+                                       BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
+                                       freq_offset_khz_vhf);
+
+               /* in ISDB-T 1seg we shift tuning frequency */
+               if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
+                                       && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
+                       const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
+                       u8 found_offset = 0;
+                       u32 margin_khz = 100;
+
+                       if (LUT_offset != NULL) {
+                               while (LUT_offset->RF_freq != 0xffff) {
+                                       if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
+                                                               && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
+                                                       && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
+                                               state->rf_request += LUT_offset->offset_khz;
+                                               found_offset = 1;
+                                               break;
+                                       }
+                                       LUT_offset++;
+                               }
+                       }
+
+                       if (found_offset == 0)
+                               state->rf_request += 400;
+               }
+               if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
+                       state->tuner_is_tuned = 0;
+                       state->current_rf = 0;
+                       state->current_standard = 0;
+
+                       tune = dib0090_tuning_table;
+                       if (state->identity.p1g)
+                               tune = dib0090_p1g_tuning_table;
+
+                       tmp = (state->identity.version >> 5) & 0x7;
+
+                       if (state->identity.in_soc) {
+                               if (state->config->force_cband_input) { /* Use the CBAND input for all band */
+                                       if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
+                                                       || state->current_band & BAND_UHF) {
+                                               state->current_band = BAND_CBAND;
+                                               if (state->config->is_dib7090e)
+                                                       tune = dib0090_tuning_table_cband_7090e_sensitivity;
+                                               else
+                                                       tune = dib0090_tuning_table_cband_7090;
+                                       }
+                               } else {        /* Use the CBAND input for all band under UHF */
+                                       if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
+                                               state->current_band = BAND_CBAND;
+                                               if (state->config->is_dib7090e)
+                                                       tune = dib0090_tuning_table_cband_7090e_sensitivity;
+                                               else
+                                                       tune = dib0090_tuning_table_cband_7090;
+                                       }
+                               }
+                       } else
+                        if (tmp == 0x4 || tmp == 0x7) {
+                               /* CBAND tuner version for VHF */
+                               if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
+                                       state->current_band = BAND_CBAND;       /* Force CBAND */
+
+                                       tune = dib0090_tuning_table_fm_vhf_on_cband;
+                                       if (state->identity.p1g)
+                                               tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
+                               }
+                       }
+
+                       pll = dib0090_pll_table;
+                       if (state->identity.p1g)
+                               pll = dib0090_p1g_pll_table;
+
+                       /* Look for the interval */
+                       while (state->rf_request > tune->max_freq)
+                               tune++;
+                       while (state->rf_request > pll->max_freq)
+                               pll++;
+
+                       state->current_tune_table_index = tune;
+                       state->current_pll_table_index = pll;
+
+                       dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
+
+                       VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
+
+                       FREF = state->config->io.clock_khz;
+                       if (state->config->fref_clock_ratio != 0)
+                               FREF /= state->config->fref_clock_ratio;
+
+                       FBDiv = (VCOF_kHz / pll->topresc / FREF);
+                       Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
+
+                       if (Rest < LPF)
+                               Rest = 0;
+                       else if (Rest < 2 * LPF)
+                               Rest = 2 * LPF;
+                       else if (Rest > (FREF - LPF)) {
+                               Rest = 0;
+                               FBDiv += 1;
+                       } else if (Rest > (FREF - 2 * LPF))
+                               Rest = FREF - 2 * LPF;
+                       Rest = (Rest * 6528) / (FREF / 10);
+                       state->rest = Rest;
+
+                       /* external loop filter, otherwise:
+                        * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
+                        * lo6 = 0x0e34 */
+
+                       if (Rest == 0) {
+                               if (pll->vco_band)
+                                       lo5 = 0x049f;
+                               else
+                                       lo5 = 0x041f;
+                       } else {
+                               if (pll->vco_band)
+                                       lo5 = 0x049e;
+                               else if (state->config->analog_output)
+                                       lo5 = 0x041d;
+                               else
+                                       lo5 = 0x041c;
+                       }
+
+                       if (state->identity.p1g) {      /* Bias is done automatically in P1G */
+                               if (state->identity.in_soc) {
+                                       if (state->identity.version == SOC_8090_P1G_11R1)
+                                               lo5 = 0x46f;
+                                       else
+                                               lo5 = 0x42f;
+                               } else
+                                       lo5 = 0x42c;
+                       }
+
+                       lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);  /* bit 15 is the split to the slave, we do not do it here */
+
+                       if (!state->config->io.pll_int_loop_filt) {
+                               if (state->identity.in_soc)
+                                       lo6 = 0xff98;
+                               else if (state->identity.p1g || (Rest == 0))
+                                       lo6 = 0xfff8;
+                               else
+                                       lo6 = 0xff28;
+                       } else
+                               lo6 = (state->config->io.pll_int_loop_filt << 3);
+
+                       Den = 1;
+
+                       if (Rest > 0) {
+                               if (state->config->analog_output)
+                                       lo6 |= (1 << 2) | 2;
+                               else {
+                                       if (state->identity.in_soc)
+                                               lo6 |= (1 << 2) | 2;
+                                       else
+                                               lo6 |= (1 << 2) | 2;
+                               }
+                               Den = 255;
+                       }
+                       dib0090_write_reg(state, 0x15, (u16) FBDiv);
+                       if (state->config->fref_clock_ratio != 0)
+                               dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
+                       else
+                               dib0090_write_reg(state, 0x16, (Den << 8) | 1);
+                       dib0090_write_reg(state, 0x17, (u16) Rest);
+                       dib0090_write_reg(state, 0x19, lo5);
+                       dib0090_write_reg(state, 0x1c, lo6);
+
+                       lo6 = tune->tuner_enable;
+                       if (state->config->analog_output)
+                               lo6 = (lo6 & 0xff9f) | 0x2;
+
+                       dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
+
+               }
+
+               state->current_rf = state->rf_request;
+               state->current_standard = state->fe->dtv_property_cache.delivery_system;
+
+               ret = 20;
+               state->calibrate = CAPTRIM_CAL; /* captrim serach now */
+       }
+
+       else if (*tune_state == CT_TUNER_STEP_0) {      /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
+               const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
+
+               while (state->current_rf / 1000 > wbd->max_freq)
+                       wbd++;
+
+               dib0090_write_reg(state, 0x1e, 0x07ff);
+               dprintk("Final Captrim: %d", (u32) state->fcaptrim);
+               dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
+               dprintk("VCO = %d", (u32) pll->vco_band);
+               dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
+               dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
+               dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
+               dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
+                       (u32) dib0090_read_reg(state, 0x1c) & 0x3);
+
+#define WBD     0x781          /* 1 1 1 1 0000 0 0 1 */
+               c = 4;
+               i = 3;
+
+               if (wbd->wbd_gain != 0)
+                       c = wbd->wbd_gain;
+
+               state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
+               dib0090_write_reg(state, 0x10, state->wbdmux);
+
+               if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
+                       dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
+                       dib0090_write_reg(state, 0x09, tune->lna_bias);
+                       dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
+               } else
+                       dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
+
+               dib0090_write_reg(state, 0x0c, tune->v2i);
+               dib0090_write_reg(state, 0x0d, tune->mix);
+               dib0090_write_reg(state, 0x0e, tune->load);
+               *tune_state = CT_TUNER_STEP_1;
+
+       } else if (*tune_state == CT_TUNER_STEP_1) {
+               /* initialize the lt gain register */
+               state->rf_lt_def = 0x7c00;
+
+               dib0090_set_bandwidth(state);
+               state->tuner_is_tuned = 1;
+
+               state->calibrate |= WBD_CAL;
+               state->calibrate |= TEMP_CAL;
+               *tune_state = CT_TUNER_STOP;
+       } else
+               ret = FE_CALLBACK_TIME_NEVER;
+       return ret;
+}
+
+static int dib0090_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       return state->tune_state;
+}
+
+EXPORT_SYMBOL(dib0090_get_tune_state);
+
+int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       state->tune_state = tune_state;
+       return 0;
+}
+
+EXPORT_SYMBOL(dib0090_set_tune_state);
+
+static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+
+       *frequency = 1000 * state->current_rf;
+       return 0;
+}
+
+static int dib0090_set_params(struct dvb_frontend *fe)
+{
+       struct dib0090_state *state = fe->tuner_priv;
+       u32 ret;
+
+       state->tune_state = CT_TUNER_START;
+
+       do {
+               ret = dib0090_tune(fe);
+               if (ret != FE_CALLBACK_TIME_NEVER)
+                       msleep(ret / 10);
+               else
+                       break;
+       } while (state->tune_state != CT_TUNER_STOP);
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops dib0090_ops = {
+       .info = {
+                .name = "DiBcom DiB0090",
+                .frequency_min = 45000000,
+                .frequency_max = 860000000,
+                .frequency_step = 1000,
+                },
+       .release = dib0090_release,
+
+       .init = dib0090_wakeup,
+       .sleep = dib0090_sleep,
+       .set_params = dib0090_set_params,
+       .get_frequency = dib0090_get_frequency,
+};
+
+static const struct dvb_tuner_ops dib0090_fw_ops = {
+       .info = {
+                .name = "DiBcom DiB0090",
+                .frequency_min = 45000000,
+                .frequency_max = 860000000,
+                .frequency_step = 1000,
+                },
+       .release = dib0090_release,
+
+       .init = NULL,
+       .sleep = NULL,
+       .set_params = NULL,
+       .get_frequency = NULL,
+};
+
+static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
+       {470, 0, 250, 0, 100, 4},
+       {860, 51, 866, 21, 375, 4},
+       {1700, 0, 800, 0, 850, 4},
+       {2900, 0, 250, 0, 100, 6},
+       {0xFFFF, 0, 0, 0, 0, 0},
+};
+
+struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
+{
+       struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       st->config = config;
+       st->i2c = i2c;
+       st->fe = fe;
+       mutex_init(&st->i2c_buffer_lock);
+       fe->tuner_priv = st;
+
+       if (config->wbd == NULL)
+               st->current_wbd_table = dib0090_wbd_table_default;
+       else
+               st->current_wbd_table = config->wbd;
+
+       if (dib0090_reset(fe) != 0)
+               goto free_mem;
+
+       printk(KERN_INFO "DiB0090: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
+
+       return fe;
+ free_mem:
+       kfree(st);
+       fe->tuner_priv = NULL;
+       return NULL;
+}
+
+EXPORT_SYMBOL(dib0090_register);
+
+struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
+{
+       struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       st->config = config;
+       st->i2c = i2c;
+       st->fe = fe;
+       mutex_init(&st->i2c_buffer_lock);
+       fe->tuner_priv = st;
+
+       if (dib0090_fw_reset_digital(fe, st->config) != 0)
+               goto free_mem;
+
+       dprintk("DiB0090 FW: successfully identified");
+       memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
+
+       return fe;
+free_mem:
+       kfree(st);
+       fe->tuner_priv = NULL;
+       return NULL;
+}
+EXPORT_SYMBOL(dib0090_fw_register);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib0090.h b/drivers/media/dvb-frontends/dib0090.h
new file mode 100644 (file)
index 0000000..781dc49
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#ifndef DIB0090_H
+#define DIB0090_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
+
+struct dib0090_io_config {
+       u32 clock_khz;
+
+       u8 pll_bypass:1;
+       u8 pll_range:1;
+       u8 pll_prediv:6;
+       u8 pll_loopdiv:6;
+
+       u8 adc_clock_ratio;     /* valid is 8, 7 ,6 */
+       u16 pll_int_loop_filt;
+};
+
+struct dib0090_wbd_slope {
+       u16 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
+       u16 slope_cold;
+       u16 offset_cold;
+       u16 slope_hot;
+       u16 offset_hot;
+       u8 wbd_gain;
+};
+
+struct dib0090_low_if_offset_table {
+       int std;
+       u32 RF_freq;
+       s32 offset_khz;
+};
+
+struct dib0090_config {
+       struct dib0090_io_config io;
+       int (*reset) (struct dvb_frontend *, int);
+       int (*sleep) (struct dvb_frontend *, int);
+
+       /*  offset in kHz */
+       int freq_offset_khz_uhf;
+       int freq_offset_khz_vhf;
+
+       int (*get_adc_power) (struct dvb_frontend *);
+
+       u8 clkouttobamse:1;     /* activate or deactivate clock output */
+       u8 analog_output;
+
+       u8 i2c_address;
+       /* add drives and other things if necessary */
+       u16 wbd_vhf_offset;
+       u16 wbd_cband_offset;
+       u8 use_pwm_agc;
+       u8 clkoutdrive;
+
+       u8 ls_cfg_pad_drv;
+       u8 data_tx_drv;
+
+       u8 in_soc;
+       const struct dib0090_low_if_offset_table *low_if;
+       u8 fref_clock_ratio;
+       u16 force_cband_input;
+       struct dib0090_wbd_slope *wbd;
+       u8 is_dib7090e;
+       u8 force_crystal_mode;
+};
+
+#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
+extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
+extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
+extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
+extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner);
+extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe);
+extern int dib0090_gain_control(struct dvb_frontend *fe);
+extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
+extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
+extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
+extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff);
+extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3);
+extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff);
+extern int dib0090_update_rframp_7090(struct dvb_frontend *fe,
+               u8 cfg_sensitivity);
+extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+               u8 cfg_sensitivity);
+#else
+static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+
+static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+
+static inline int dib0090_gain_control(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return CT_DONE;
+}
+
+static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline int dib0090_set_switch(struct dvb_frontend *fe,
+               u8 sw1, u8 sw2, u8 sw3)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe,
+               u8 cfg_sensitivity)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+               u8 cfg_sensitivity)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib3000.h b/drivers/media/dvb-frontends/dib3000.h
new file mode 100644 (file)
index 0000000..404f63a
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * public header file of the frontend drivers for mobile DVB-T demodulators
+ * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DibCom, which has
+ *
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ *
+ * Acknowledgements
+ *
+ *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
+ *  sources, on which this driver (and the dvb-dibusb) are based.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+
+#ifndef DIB3000_H
+#define DIB3000_H
+
+#include <linux/dvb/frontend.h>
+
+struct dib3000_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+struct dib_fe_xfer_ops
+{
+       /* pid and transfer handling is done in the demodulator */
+       int (*pid_parse)(struct dvb_frontend *fe, int onoff);
+       int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
+       int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
+       int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
+};
+
+#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE))
+extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
+                                            struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
+#else
+static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
+                                            struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MB
+
+#endif // DIB3000_H
diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
new file mode 100644 (file)
index 0000000..af91e0c
--- /dev/null
@@ -0,0 +1,829 @@
+/*
+ * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
+ * DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DibCom, which has
+ *
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ *
+ * Acknowledgements
+ *
+ *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
+ *  sources, on which this driver (and the dvb-dibusb) are based.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "dib3000.h"
+#include "dib3000mb_priv.h"
+
+/* Version information */
+#define DRIVER_VERSION "0.1"
+#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
+#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
+
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_i2c(args...)  dprintk(0x02,args)
+#define deb_srch(args...) dprintk(0x04,args)
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_xfer(args...) dprintk(0x02,args)
+#define deb_setf(args...) dprintk(0x04,args)
+#define deb_getf(args...) dprintk(0x08,args)
+
+static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
+{
+       u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
+       u8 rb[2];
+       struct i2c_msg msg[] = {
+               { .addr = state->config.demod_address, .flags = 0,        .buf = wb, .len = 2 },
+               { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+       };
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2)
+               deb_i2c("i2c read error\n");
+
+       deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
+                       (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
+
+       return (rb[0] << 8) | rb[1];
+}
+
+static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
+{
+       u8 b[] = {
+               (reg >> 8) & 0xff, reg & 0xff,
+               (val >> 8) & 0xff, val & 0xff,
+       };
+       struct i2c_msg msg[] = {
+               { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
+       };
+       deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
+
+       return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static int dib3000_search_status(u16 irq,u16 lock)
+{
+       if (irq & 0x02) {
+               if (lock & 0x01) {
+                       deb_srch("auto search succeeded\n");
+                       return 1; // auto search succeeded
+               } else {
+                       deb_srch("auto search not successful\n");
+                       return 0; // auto search failed
+               }
+       } else if (irq & 0x01)  {
+               deb_srch("auto search failed\n");
+               return 0; // auto search failed
+       }
+       return -1; // try again
+}
+
+/* for auto search */
+static u16 dib3000_seq[2][2][2] =     /* fft,gua,   inv   */
+       { /* fft */
+               { /* gua */
+                       { 0, 1 },                   /*  0   0   { 0,1 } */
+                       { 3, 9 },                   /*  0   1   { 0,1 } */
+               },
+               {
+                       { 2, 5 },                   /*  1   0   { 0,1 } */
+                       { 6, 11 },                  /*  1   1   { 0,1 } */
+               }
+       };
+
+static int dib3000mb_get_frontend(struct dvb_frontend* fe);
+
+static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       fe_code_rate_t fe_cr = FEC_NONE;
+       int search_state, seq;
+
+       if (tuner && fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+
+               deb_setf("bandwidth: ");
+               switch (c->bandwidth_hz) {
+                       case 8000000:
+                               deb_setf("8 MHz\n");
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
+                               break;
+                       case 7000000:
+                               deb_setf("7 MHz\n");
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
+                               break;
+                       case 6000000:
+                               deb_setf("6 MHz\n");
+                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
+                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
+                               break;
+                       case 0:
+                               return -EOPNOTSUPP;
+                       default:
+                               err("unknown bandwidth value.");
+                               return -EINVAL;
+               }
+       }
+       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
+
+       deb_setf("transmission mode: ");
+       switch (c->transmission_mode) {
+               case TRANSMISSION_MODE_2K:
+                       deb_setf("2k\n");
+                       wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
+                       break;
+               case TRANSMISSION_MODE_8K:
+                       deb_setf("8k\n");
+                       wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
+                       break;
+               case TRANSMISSION_MODE_AUTO:
+                       deb_setf("auto\n");
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       deb_setf("guard: ");
+       switch (c->guard_interval) {
+               case GUARD_INTERVAL_1_32:
+                       deb_setf("1_32\n");
+                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
+                       break;
+               case GUARD_INTERVAL_1_16:
+                       deb_setf("1_16\n");
+                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
+                       break;
+               case GUARD_INTERVAL_1_8:
+                       deb_setf("1_8\n");
+                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
+                       break;
+               case GUARD_INTERVAL_1_4:
+                       deb_setf("1_4\n");
+                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
+                       break;
+               case GUARD_INTERVAL_AUTO:
+                       deb_setf("auto\n");
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       deb_setf("inversion: ");
+       switch (c->inversion) {
+               case INVERSION_OFF:
+                       deb_setf("off\n");
+                       wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
+                       break;
+               case INVERSION_AUTO:
+                       deb_setf("auto ");
+                       break;
+               case INVERSION_ON:
+                       deb_setf("on\n");
+                       wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       deb_setf("modulation: ");
+       switch (c->modulation) {
+               case QPSK:
+                       deb_setf("qpsk\n");
+                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
+                       break;
+               case QAM_16:
+                       deb_setf("qam16\n");
+                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
+                       break;
+               case QAM_64:
+                       deb_setf("qam64\n");
+                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
+                       break;
+               case QAM_AUTO:
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       deb_setf("hierarchy: ");
+       switch (c->hierarchy) {
+               case HIERARCHY_NONE:
+                       deb_setf("none ");
+                       /* fall through */
+               case HIERARCHY_1:
+                       deb_setf("alpha=1\n");
+                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
+                       break;
+               case HIERARCHY_2:
+                       deb_setf("alpha=2\n");
+                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
+                       break;
+               case HIERARCHY_4:
+                       deb_setf("alpha=4\n");
+                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
+                       break;
+               case HIERARCHY_AUTO:
+                       deb_setf("alpha=auto\n");
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       deb_setf("hierarchy: ");
+       if (c->hierarchy == HIERARCHY_NONE) {
+               deb_setf("none\n");
+               wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
+               wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
+               fe_cr = c->code_rate_HP;
+       } else if (c->hierarchy != HIERARCHY_AUTO) {
+               deb_setf("on\n");
+               wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
+               wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
+               fe_cr = c->code_rate_LP;
+       }
+       deb_setf("fec: ");
+       switch (fe_cr) {
+               case FEC_1_2:
+                       deb_setf("1_2\n");
+                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
+                       break;
+               case FEC_2_3:
+                       deb_setf("2_3\n");
+                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
+                       break;
+               case FEC_3_4:
+                       deb_setf("3_4\n");
+                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
+                       break;
+               case FEC_5_6:
+                       deb_setf("5_6\n");
+                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
+                       break;
+               case FEC_7_8:
+                       deb_setf("7_8\n");
+                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
+                       break;
+               case FEC_NONE:
+                       deb_setf("none ");
+                       break;
+               case FEC_AUTO:
+                       deb_setf("auto\n");
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       seq = dib3000_seq
+               [c->transmission_mode == TRANSMISSION_MODE_AUTO]
+               [c->guard_interval == GUARD_INTERVAL_AUTO]
+               [c->inversion == INVERSION_AUTO];
+
+       deb_setf("seq? %d\n", seq);
+
+       wr(DIB3000MB_REG_SEQ, seq);
+
+       wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
+
+       if (c->transmission_mode == TRANSMISSION_MODE_2K) {
+               if (c->guard_interval == GUARD_INTERVAL_1_8) {
+                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
+               } else {
+                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
+               }
+
+               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
+       } else {
+               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
+       }
+
+       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
+       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
+       wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
+
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
+
+       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
+
+       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
+       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
+
+       /* wait for AGC lock */
+       msleep(70);
+
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
+
+       /* something has to be auto searched */
+       if (c->modulation == QAM_AUTO ||
+               c->hierarchy == HIERARCHY_AUTO ||
+               fe_cr == FEC_AUTO ||
+               c->inversion == INVERSION_AUTO) {
+               int as_count=0;
+
+               deb_setf("autosearch enabled.\n");
+
+               wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
+
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
+
+               while ((search_state =
+                               dib3000_search_status(
+                                       rd(DIB3000MB_REG_AS_IRQ_PENDING),
+                                       rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
+                       msleep(1);
+
+               deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
+
+               if (search_state == 1) {
+                       if (dib3000mb_get_frontend(fe) == 0) {
+                               deb_setf("reading tuning data from frontend succeeded.\n");
+                               return dib3000mb_set_frontend(fe, 0);
+                       }
+               }
+
+       } else {
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
+               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
+       }
+
+       return 0;
+}
+
+static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+
+       deb_info("dib3000mb is getting up.\n");
+       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
+
+       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
+
+       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
+       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
+
+       wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
+
+       wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
+
+       wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
+       wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
+
+       wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
+
+       wr_foreach(dib3000mb_reg_impulse_noise,
+                       dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
+
+       wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
+
+       wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
+
+       wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
+
+       wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
+
+       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
+
+       wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
+       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
+       wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
+       wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
+
+       wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
+
+       wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
+       wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
+       wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
+       wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
+       wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
+       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
+       wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
+       wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
+       wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
+       wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
+       wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
+       wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
+       wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
+       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
+       wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
+
+       wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
+
+       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
+       wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
+       wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
+
+       wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
+
+       wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
+       wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
+       wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
+       wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
+       wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
+       wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
+
+       wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
+
+       return 0;
+}
+
+static int dib3000mb_get_frontend(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dib3000_state* state = fe->demodulator_priv;
+       fe_code_rate_t *cr;
+       u16 tps_val;
+       int inv_test1,inv_test2;
+       u32 dds_val, threshold = 0x800000;
+
+       if (!rd(DIB3000MB_REG_TPS_LOCK))
+               return 0;
+
+       dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
+       deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
+       if (dds_val < threshold)
+               inv_test1 = 0;
+       else if (dds_val == threshold)
+               inv_test1 = 1;
+       else
+               inv_test1 = 2;
+
+       dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
+       deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
+       if (dds_val < threshold)
+               inv_test2 = 0;
+       else if (dds_val == threshold)
+               inv_test2 = 1;
+       else
+               inv_test2 = 2;
+
+       c->inversion =
+               ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
+               ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
+               INVERSION_ON : INVERSION_OFF;
+
+       deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, c->inversion);
+
+       switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
+               case DIB3000_CONSTELLATION_QPSK:
+                       deb_getf("QPSK ");
+                       c->modulation = QPSK;
+                       break;
+               case DIB3000_CONSTELLATION_16QAM:
+                       deb_getf("QAM16 ");
+                       c->modulation = QAM_16;
+                       break;
+               case DIB3000_CONSTELLATION_64QAM:
+                       deb_getf("QAM64 ");
+                       c->modulation = QAM_64;
+                       break;
+               default:
+                       err("Unexpected constellation returned by TPS (%d)", tps_val);
+                       break;
+       }
+       deb_getf("TPS: %d\n", tps_val);
+
+       if (rd(DIB3000MB_REG_TPS_HRCH)) {
+               deb_getf("HRCH ON\n");
+               cr = &c->code_rate_LP;
+               c->code_rate_HP = FEC_NONE;
+               switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
+                       case DIB3000_ALPHA_0:
+                               deb_getf("HIERARCHY_NONE ");
+                               c->hierarchy = HIERARCHY_NONE;
+                               break;
+                       case DIB3000_ALPHA_1:
+                               deb_getf("HIERARCHY_1 ");
+                               c->hierarchy = HIERARCHY_1;
+                               break;
+                       case DIB3000_ALPHA_2:
+                               deb_getf("HIERARCHY_2 ");
+                               c->hierarchy = HIERARCHY_2;
+                               break;
+                       case DIB3000_ALPHA_4:
+                               deb_getf("HIERARCHY_4 ");
+                               c->hierarchy = HIERARCHY_4;
+                               break;
+                       default:
+                               err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
+                               break;
+               }
+               deb_getf("TPS: %d\n", tps_val);
+
+               tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
+       } else {
+               deb_getf("HRCH OFF\n");
+               cr = &c->code_rate_HP;
+               c->code_rate_LP = FEC_NONE;
+               c->hierarchy = HIERARCHY_NONE;
+
+               tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
+       }
+
+       switch (tps_val) {
+               case DIB3000_FEC_1_2:
+                       deb_getf("FEC_1_2 ");
+                       *cr = FEC_1_2;
+                       break;
+               case DIB3000_FEC_2_3:
+                       deb_getf("FEC_2_3 ");
+                       *cr = FEC_2_3;
+                       break;
+               case DIB3000_FEC_3_4:
+                       deb_getf("FEC_3_4 ");
+                       *cr = FEC_3_4;
+                       break;
+               case DIB3000_FEC_5_6:
+                       deb_getf("FEC_5_6 ");
+                       *cr = FEC_4_5;
+                       break;
+               case DIB3000_FEC_7_8:
+                       deb_getf("FEC_7_8 ");
+                       *cr = FEC_7_8;
+                       break;
+               default:
+                       err("Unexpected FEC returned by TPS (%d)", tps_val);
+                       break;
+       }
+       deb_getf("TPS: %d\n",tps_val);
+
+       switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
+               case DIB3000_GUARD_TIME_1_32:
+                       deb_getf("GUARD_INTERVAL_1_32 ");
+                       c->guard_interval = GUARD_INTERVAL_1_32;
+                       break;
+               case DIB3000_GUARD_TIME_1_16:
+                       deb_getf("GUARD_INTERVAL_1_16 ");
+                       c->guard_interval = GUARD_INTERVAL_1_16;
+                       break;
+               case DIB3000_GUARD_TIME_1_8:
+                       deb_getf("GUARD_INTERVAL_1_8 ");
+                       c->guard_interval = GUARD_INTERVAL_1_8;
+                       break;
+               case DIB3000_GUARD_TIME_1_4:
+                       deb_getf("GUARD_INTERVAL_1_4 ");
+                       c->guard_interval = GUARD_INTERVAL_1_4;
+                       break;
+               default:
+                       err("Unexpected Guard Time returned by TPS (%d)", tps_val);
+                       break;
+       }
+       deb_getf("TPS: %d\n", tps_val);
+
+       switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
+               case DIB3000_TRANSMISSION_MODE_2K:
+                       deb_getf("TRANSMISSION_MODE_2K ");
+                       c->transmission_mode = TRANSMISSION_MODE_2K;
+                       break;
+               case DIB3000_TRANSMISSION_MODE_8K:
+                       deb_getf("TRANSMISSION_MODE_8K ");
+                       c->transmission_mode = TRANSMISSION_MODE_8K;
+                       break;
+               default:
+                       err("unexpected transmission mode return by TPS (%d)", tps_val);
+                       break;
+       }
+       deb_getf("TPS: %d\n", tps_val);
+
+       return 0;
+}
+
+static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+
+       *stat = 0;
+
+       if (rd(DIB3000MB_REG_AGC_LOCK))
+               *stat |= FE_HAS_SIGNAL;
+       if (rd(DIB3000MB_REG_CARRIER_LOCK))
+               *stat |= FE_HAS_CARRIER;
+       if (rd(DIB3000MB_REG_VIT_LCK))
+               *stat |= FE_HAS_VITERBI;
+       if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
+               *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
+
+       deb_getf("actual status is %2x\n",*stat);
+
+       deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
+                       rd(DIB3000MB_REG_TPS_LOCK),
+                       rd(DIB3000MB_REG_TPS_QAM),
+                       rd(DIB3000MB_REG_TPS_HRCH),
+                       rd(DIB3000MB_REG_TPS_VIT_ALPHA),
+                       rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
+                       rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
+                       rd(DIB3000MB_REG_TPS_GUARD_TIME),
+                       rd(DIB3000MB_REG_TPS_FFT),
+                       rd(DIB3000MB_REG_TPS_CELL_ID));
+
+       //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       return 0;
+}
+
+static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+
+       *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
+       return 0;
+}
+
+/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
+static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+
+       *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
+       return 0;
+}
+
+static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+       short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
+       int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
+               rd(DIB3000MB_REG_NOISE_POWER_LSB);
+       *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
+       return 0;
+}
+
+static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+
+       *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
+       return 0;
+}
+
+static int dib3000mb_sleep(struct dvb_frontend* fe)
+{
+       struct dib3000_state* state = fe->demodulator_priv;
+       deb_info("dib3000mb is going to bed.\n");
+       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
+       return 0;
+}
+
+static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 800;
+       return 0;
+}
+
+static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
+{
+       return dib3000mb_fe_init(fe, 0);
+}
+
+static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend *fe)
+{
+       return dib3000mb_set_frontend(fe, 1);
+}
+
+static void dib3000mb_release(struct dvb_frontend* fe)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+/* pid filter and transfer stuff */
+static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+       pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
+       wr(index+DIB3000MB_REG_FIRST_PID,pid);
+       return 0;
+}
+
+static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+
+       deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
+       if (onoff) {
+               wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
+       } else {
+               wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
+       }
+       return 0;
+}
+
+static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+       deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
+       wr(DIB3000MB_REG_PID_PARSE,onoff);
+       return 0;
+}
+
+static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
+{
+       struct dib3000_state *state = fe->demodulator_priv;
+       if (onoff) {
+               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
+       } else {
+               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
+       }
+       return 0;
+}
+
+static struct dvb_frontend_ops dib3000mb_ops;
+
+struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
+                                     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
+{
+       struct dib3000_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config,config,sizeof(struct dib3000_config));
+
+       /* check for the correct demod */
+       if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
+               goto error;
+
+       if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* set the xfer operations */
+       xfer_ops->pid_parse = dib3000mb_pid_parse;
+       xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
+       xfer_ops->pid_ctrl = dib3000mb_pid_control;
+       xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops dib3000mb_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "DiBcom 3000M-B DVB-T",
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_INVERSION_AUTO |
+                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                               FE_CAN_TRANSMISSION_MODE_AUTO |
+                               FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_RECOVER |
+                               FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = dib3000mb_release,
+
+       .init = dib3000mb_fe_init_nonmobile,
+       .sleep = dib3000mb_sleep,
+
+       .set_frontend = dib3000mb_set_frontend_and_tuner,
+       .get_frontend = dib3000mb_get_frontend,
+       .get_tune_settings = dib3000mb_fe_get_tune_settings,
+
+       .read_status = dib3000mb_read_status,
+       .read_ber = dib3000mb_read_ber,
+       .read_signal_strength = dib3000mb_read_signal_strength,
+       .read_snr = dib3000mb_read_snr,
+       .read_ucblocks = dib3000mb_read_unc_blocks,
+};
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb-frontends/dib3000mb_priv.h b/drivers/media/dvb-frontends/dib3000mb_priv.h
new file mode 100644 (file)
index 0000000..9dc235a
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * dib3000mb_priv.h
+ *
+ * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ *
+ * for more information see dib3000mb.c .
+ */
+
+#ifndef __DIB3000MB_PRIV_H_INCLUDED__
+#define __DIB3000MB_PRIV_H_INCLUDED__
+
+/* info and err, taken from usb.h, if there is anything available like by default. */
+#define err(format, arg...)  printk(KERN_ERR     "dib3000: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO    "dib3000: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
+
+/* handy shortcuts */
+#define rd(reg) dib3000_read_reg(state,reg)
+
+#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
+       { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
+
+#define wr_foreach(a,v) { int i; \
+       if (sizeof(a) != sizeof(v)) \
+               err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
+       for (i=0; i < sizeof(a)/sizeof(u16); i++) \
+               wr(a[i],v[i]); \
+       }
+
+#define set_or(reg,val) wr(reg,rd(reg) | val)
+
+#define set_and(reg,val) wr(reg,rd(reg) & val)
+
+/* debug */
+
+#define dprintk(level,args...) \
+    do { if ((debug & level)) { printk(args); } } while (0)
+
+/* mask for enabling a specific pid for the pid_filter */
+#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
+
+/* common values for tuning */
+#define DIB3000_ALPHA_0                                        (     0)
+#define DIB3000_ALPHA_1                                        (     1)
+#define DIB3000_ALPHA_2                                        (     2)
+#define DIB3000_ALPHA_4                                        (     4)
+
+#define DIB3000_CONSTELLATION_QPSK             (     0)
+#define DIB3000_CONSTELLATION_16QAM            (     1)
+#define DIB3000_CONSTELLATION_64QAM            (     2)
+
+#define DIB3000_GUARD_TIME_1_32                        (     0)
+#define DIB3000_GUARD_TIME_1_16                        (     1)
+#define DIB3000_GUARD_TIME_1_8                 (     2)
+#define DIB3000_GUARD_TIME_1_4                 (     3)
+
+#define DIB3000_TRANSMISSION_MODE_2K   (     0)
+#define DIB3000_TRANSMISSION_MODE_8K   (     1)
+
+#define DIB3000_SELECT_LP                              (     0)
+#define DIB3000_SELECT_HP                              (     1)
+
+#define DIB3000_FEC_1_2                                        (     1)
+#define DIB3000_FEC_2_3                                        (     2)
+#define DIB3000_FEC_3_4                                        (     3)
+#define DIB3000_FEC_5_6                                        (     5)
+#define DIB3000_FEC_7_8                                        (     7)
+
+#define DIB3000_HRCH_OFF                               (     0)
+#define DIB3000_HRCH_ON                                        (     1)
+
+#define DIB3000_DDS_INVERSION_OFF              (     0)
+#define DIB3000_DDS_INVERSION_ON               (     1)
+
+#define DIB3000_TUNER_WRITE_ENABLE(a)  (0xffff & (a << 8))
+#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
+
+#define DIB3000_REG_MANUFACTOR_ID              (  1025)
+#define DIB3000_I2C_ID_DIBCOM                  (0x01b3)
+
+#define DIB3000_REG_DEVICE_ID                  (  1026)
+#define DIB3000MB_DEVICE_ID                            (0x3000)
+#define DIB3000MC_DEVICE_ID                            (0x3001)
+#define DIB3000P_DEVICE_ID                             (0x3002)
+
+/* frontend state */
+struct dib3000_state {
+       struct i2c_adapter* i2c;
+
+/* configuration settings */
+       struct dib3000_config config;
+
+       struct dvb_frontend frontend;
+       int timing_offset;
+       int timing_offset_comp_done;
+
+       u32 last_tuned_bw;
+       u32 last_tuned_freq;
+};
+
+/* register addresses and some of their default values */
+
+/* restart subsystems */
+#define DIB3000MB_REG_RESTART                  (     0)
+
+#define DIB3000MB_RESTART_OFF                  (     0)
+#define DIB3000MB_RESTART_AUTO_SEARCH          (1 << 1)
+#define DIB3000MB_RESTART_CTRL                         (1 << 2)
+#define DIB3000MB_RESTART_AGC                          (1 << 3)
+
+/* FFT size */
+#define DIB3000MB_REG_FFT                              (     1)
+
+/* Guard time */
+#define DIB3000MB_REG_GUARD_TIME               (     2)
+
+/* QAM */
+#define DIB3000MB_REG_QAM                              (     3)
+
+/* Alpha coefficient high priority Viterbi algorithm */
+#define DIB3000MB_REG_VIT_ALPHA                        (     4)
+
+/* spectrum inversion */
+#define DIB3000MB_REG_DDS_INV                  (     5)
+
+/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
+#define DIB3000MB_REG_DDS_FREQ_MSB             (     6)
+#define DIB3000MB_REG_DDS_FREQ_LSB             (     7)
+#define DIB3000MB_DDS_FREQ_MSB                         (   178)
+#define DIB3000MB_DDS_FREQ_LSB                         (  8990)
+
+/* timing frequency (carrier spacing) */
+static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
+static u16 dib3000mb_timing_freq[][2] = {
+       { 126 , 48873 }, /* 6 MHz */
+       { 147 , 57019 }, /* 7 MHz */
+       { 168 , 65164 }, /* 8 MHz */
+};
+
+/* impulse noise parameter */
+/* 36 ??? */
+
+static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
+
+enum dib3000mb_impulse_noise_type {
+       DIB3000MB_IMPNOISE_OFF,
+       DIB3000MB_IMPNOISE_MOBILE,
+       DIB3000MB_IMPNOISE_FIXED,
+       DIB3000MB_IMPNOISE_DEFAULT
+};
+
+static u16 dib3000mb_impulse_noise_values[][5] = {
+       { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
+       { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
+       { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
+       { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
+};
+
+/*
+ * Dual Automatic-Gain-Control
+ * - gains RF in tuner (AGC1)
+ * - gains IF after filtering (AGC2)
+ */
+
+/* also from 16 to 18 */
+static u16 dib3000mb_reg_agc_gain[] = {
+       19,20,21,22,23,24,25,26,27,28,29,30,31,32
+};
+
+static u16 dib3000mb_default_agc_gain[] =
+       { 0x0001, 52429,   623, 128, 166, 195, 61,   /* RF ??? */
+         0x0001, 53766, 38011,   0,  90,  33, 23 }; /* IF ??? */
+
+/* phase noise */
+/* 36 is set when setting the impulse noise */
+static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
+
+static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
+
+/* lock duration */
+static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
+static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
+
+/* AGC loop bandwidth */
+static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
+
+static u16 dib3000mb_agc_bandwidth_low[]  =
+       { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
+static u16 dib3000mb_agc_bandwidth_high[] =
+       { 2349,  5, 2349,  5, 2586, 2, 2586, 2 };
+
+/*
+ * lock0 definition (coff_lock)
+ */
+#define DIB3000MB_REG_LOCK0_MASK               (    51)
+#define DIB3000MB_LOCK0_DEFAULT                                (     4)
+
+/*
+ * lock1 definition (cpil_lock)
+ * for auto search
+ * which values hide behind the lock masks
+ */
+#define DIB3000MB_REG_LOCK1_MASK               (    52)
+#define DIB3000MB_LOCK1_SEARCH_4                       (0x0004)
+#define DIB3000MB_LOCK1_SEARCH_2048                    (0x0800)
+#define DIB3000MB_LOCK1_DEFAULT                                (0x0001)
+
+/*
+ * lock2 definition (fec_lock) */
+#define DIB3000MB_REG_LOCK2_MASK               (    53)
+#define DIB3000MB_LOCK2_DEFAULT                                (0x0080)
+
+/*
+ * SEQ ? what was that again ... :)
+ * changes when, inversion, guard time and fft is
+ * either automatically detected or not
+ */
+#define DIB3000MB_REG_SEQ                              (    54)
+
+/* bandwidth */
+static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
+static u16 dib3000mb_bandwidth_6mhz[] =
+       { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
+
+static u16 dib3000mb_bandwidth_7mhz[] =
+       { 0, 28, 64421,  96, 39973, 483,  3255, 0, 1000, 0, 1010, 1, 45264 };
+
+static u16 dib3000mb_bandwidth_8mhz[] =
+       { 0, 25, 23600,  84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
+
+#define DIB3000MB_REG_UNK_68                           (    68)
+#define DIB3000MB_UNK_68                                               (     0)
+
+#define DIB3000MB_REG_UNK_69                           (    69)
+#define DIB3000MB_UNK_69                                               (     0)
+
+#define DIB3000MB_REG_UNK_71                           (    71)
+#define DIB3000MB_UNK_71                                               (     0)
+
+#define DIB3000MB_REG_UNK_77                           (    77)
+#define DIB3000MB_UNK_77                                               (     6)
+
+#define DIB3000MB_REG_UNK_78                           (    78)
+#define DIB3000MB_UNK_78                                               (0x0080)
+
+/* isi */
+#define DIB3000MB_REG_ISI                              (    79)
+#define DIB3000MB_ISI_ACTIVATE                         (     0)
+#define DIB3000MB_ISI_INHIBIT                          (     1)
+
+/* sync impovement */
+#define DIB3000MB_REG_SYNC_IMPROVEMENT (    84)
+#define DIB3000MB_SYNC_IMPROVE_2K_1_8          (     3)
+#define DIB3000MB_SYNC_IMPROVE_DEFAULT         (     0)
+
+/* phase noise compensation inhibition */
+#define DIB3000MB_REG_PHASE_NOISE              (    87)
+#define DIB3000MB_PHASE_NOISE_DEFAULT  (     0)
+
+#define DIB3000MB_REG_UNK_92                           (    92)
+#define DIB3000MB_UNK_92                                               (0x0080)
+
+#define DIB3000MB_REG_UNK_96                           (    96)
+#define DIB3000MB_UNK_96                                               (0x0010)
+
+#define DIB3000MB_REG_UNK_97                           (    97)
+#define DIB3000MB_UNK_97                                               (0x0009)
+
+/* mobile mode ??? */
+#define DIB3000MB_REG_MOBILE_MODE              (   101)
+#define DIB3000MB_MOBILE_MODE_ON                       (     1)
+#define DIB3000MB_MOBILE_MODE_OFF                      (     0)
+
+#define DIB3000MB_REG_UNK_106                  (   106)
+#define DIB3000MB_UNK_106                                      (0x0080)
+
+#define DIB3000MB_REG_UNK_107                  (   107)
+#define DIB3000MB_UNK_107                                      (0x0080)
+
+#define DIB3000MB_REG_UNK_108                  (   108)
+#define DIB3000MB_UNK_108                                      (0x0080)
+
+/* fft */
+#define DIB3000MB_REG_UNK_121                  (   121)
+#define DIB3000MB_UNK_121_2K                           (     7)
+#define DIB3000MB_UNK_121_DEFAULT                      (     5)
+
+#define DIB3000MB_REG_UNK_122                  (   122)
+#define DIB3000MB_UNK_122                                      (  2867)
+
+/* QAM for mobile mode */
+#define DIB3000MB_REG_MOBILE_MODE_QAM  (   126)
+#define DIB3000MB_MOBILE_MODE_QAM_64           (     3)
+#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16      (     1)
+#define DIB3000MB_MOBILE_MODE_QAM_OFF          (     0)
+
+/*
+ * data diversity when having more than one chip on-board
+ * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
+ */
+#define DIB3000MB_REG_DATA_IN_DIVERSITY                (   127)
+#define DIB3000MB_DATA_DIVERSITY_IN_OFF                        (     0)
+#define DIB3000MB_DATA_DIVERSITY_IN_ON                 (     2)
+
+/* vit hrch */
+#define DIB3000MB_REG_VIT_HRCH                 (   128)
+
+/* vit code rate */
+#define DIB3000MB_REG_VIT_CODE_RATE            (   129)
+
+/* vit select hp */
+#define DIB3000MB_REG_VIT_HP                   (   130)
+
+/* time frame for Bit-Error-Rate calculation */
+#define DIB3000MB_REG_BERLEN                   (   135)
+#define DIB3000MB_BERLEN_LONG                          (     0)
+#define DIB3000MB_BERLEN_DEFAULT                       (     1)
+#define DIB3000MB_BERLEN_MEDIUM                                (     2)
+#define DIB3000MB_BERLEN_SHORT                         (     3)
+
+/* 142 - 152 FIFO parameters
+ * which is what ?
+ */
+
+#define DIB3000MB_REG_FIFO_142                 (   142)
+#define DIB3000MB_FIFO_142                                     (     0)
+
+/* MPEG2 TS output mode */
+#define DIB3000MB_REG_MPEG2_OUT_MODE   (   143)
+#define DIB3000MB_MPEG2_OUT_MODE_204           (     0)
+#define DIB3000MB_MPEG2_OUT_MODE_188           (     1)
+
+#define DIB3000MB_REG_PID_PARSE                        (   144)
+#define DIB3000MB_PID_PARSE_INHIBIT            (     0)
+#define DIB3000MB_PID_PARSE_ACTIVATE   (     1)
+
+#define DIB3000MB_REG_FIFO                             (   145)
+#define DIB3000MB_FIFO_INHIBIT                         (     1)
+#define DIB3000MB_FIFO_ACTIVATE                                (     0)
+
+#define DIB3000MB_REG_FIFO_146                 (   146)
+#define DIB3000MB_FIFO_146                                     (     3)
+
+#define DIB3000MB_REG_FIFO_147                 (   147)
+#define DIB3000MB_FIFO_147                                     (0x0100)
+
+/*
+ * pidfilter
+ * it is not a hardware pidfilter but a filter which drops all pids
+ * except the ones set. Necessary because of the limited USB1.1 bandwidth.
+ * regs 153-168
+ */
+
+#define DIB3000MB_REG_FIRST_PID                        (   153)
+#define DIB3000MB_NUM_PIDS                             (    16)
+
+/*
+ * output mode
+ * USB devices have to use 'slave'-mode
+ * see also DIB3000MB_REG_ELECT_OUT_MODE
+ */
+#define DIB3000MB_REG_OUTPUT_MODE              (   169)
+#define DIB3000MB_OUTPUT_MODE_GATED_CLK                (     0)
+#define DIB3000MB_OUTPUT_MODE_CONT_CLK         (     1)
+#define DIB3000MB_OUTPUT_MODE_SERIAL           (     2)
+#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY   (     5)
+#define DIB3000MB_OUTPUT_MODE_SLAVE                    (     6)
+
+/* irq event mask */
+#define DIB3000MB_REG_IRQ_EVENT_MASK           (   170)
+#define DIB3000MB_IRQ_EVENT_MASK                               (     0)
+
+/* filter coefficients */
+static u16 dib3000mb_reg_filter_coeffs[] = {
+       171, 172, 173, 174, 175, 176, 177, 178,
+       179, 180, 181, 182, 183, 184, 185, 186,
+       188, 189, 190, 191, 192, 194
+};
+
+static u16 dib3000mb_filter_coeffs[] = {
+        226,  160,   29,
+        979,  998,   19,
+         22, 1019, 1006,
+       1022,   12,    6,
+       1017, 1017,    3,
+          6,       1019,
+       1021,    2,    3,
+          1,          0,
+};
+
+/*
+ * mobile algorithm (when you are moving with your device)
+ * but not faster than 90 km/h
+ */
+#define DIB3000MB_REG_MOBILE_ALGO              (   195)
+#define DIB3000MB_MOBILE_ALGO_ON                       (     0)
+#define DIB3000MB_MOBILE_ALGO_OFF                      (     1)
+
+/* multiple demodulators algorithm */
+#define DIB3000MB_REG_MULTI_DEMOD_MSB  (   206)
+#define DIB3000MB_REG_MULTI_DEMOD_LSB  (   207)
+
+/* terminator, no more demods */
+#define DIB3000MB_MULTI_DEMOD_MSB                      ( 32767)
+#define DIB3000MB_MULTI_DEMOD_LSB                      (  4095)
+
+/* bring the device into a known  */
+#define DIB3000MB_REG_RESET_DEVICE             (  1024)
+#define DIB3000MB_RESET_DEVICE                         (0x812c)
+#define DIB3000MB_RESET_DEVICE_RST                     (     0)
+
+/* hardware clock configuration */
+#define DIB3000MB_REG_CLOCK                            (  1027)
+#define DIB3000MB_CLOCK_DEFAULT                                (0x9000)
+#define DIB3000MB_CLOCK_DIVERSITY                      (0x92b0)
+
+/* power down config */
+#define DIB3000MB_REG_POWER_CONTROL            (  1028)
+#define DIB3000MB_POWER_DOWN                           (     1)
+#define DIB3000MB_POWER_UP                                     (     0)
+
+/* electrical output mode */
+#define DIB3000MB_REG_ELECT_OUT_MODE   (  1029)
+#define DIB3000MB_ELECT_OUT_MODE_OFF           (     0)
+#define DIB3000MB_ELECT_OUT_MODE_ON                    (     1)
+
+/* set the tuner i2c address */
+#define DIB3000MB_REG_TUNER                            (  1089)
+
+/* monitoring registers (read only) */
+
+/* agc loop locked (size: 1) */
+#define DIB3000MB_REG_AGC_LOCK                 (   324)
+
+/* agc power (size: 16) */
+#define DIB3000MB_REG_AGC_POWER                        (   325)
+
+/* agc1 value (16) */
+#define DIB3000MB_REG_AGC1_VALUE               (   326)
+
+/* agc2 value (16) */
+#define DIB3000MB_REG_AGC2_VALUE               (   327)
+
+/* total RF power (16), can be used for signal strength */
+#define DIB3000MB_REG_RF_POWER                 (   328)
+
+/* dds_frequency with offset (24) */
+#define DIB3000MB_REG_DDS_VALUE_MSB            (   339)
+#define DIB3000MB_REG_DDS_VALUE_LSB            (   340)
+
+/* timing offset signed (24) */
+#define DIB3000MB_REG_TIMING_OFFSET_MSB        (   341)
+#define DIB3000MB_REG_TIMING_OFFSET_LSB        (   342)
+
+/* fft start position (13) */
+#define DIB3000MB_REG_FFT_WINDOW_POS   (   353)
+
+/* carriers locked (1) */
+#define DIB3000MB_REG_CARRIER_LOCK             (   355)
+
+/* noise power (24) */
+#define DIB3000MB_REG_NOISE_POWER_MSB  (   372)
+#define DIB3000MB_REG_NOISE_POWER_LSB  (   373)
+
+#define DIB3000MB_REG_MOBILE_NOISE_MSB (   374)
+#define DIB3000MB_REG_MOBILE_NOISE_LSB (   375)
+
+/*
+ * signal power (16), this and the above can be
+ * used to calculate the signal/noise - ratio
+ */
+#define DIB3000MB_REG_SIGNAL_POWER             (   380)
+
+/* mer (24) */
+#define DIB3000MB_REG_MER_MSB                  (   381)
+#define DIB3000MB_REG_MER_LSB                  (   382)
+
+/*
+ * Transmission Parameter Signalling (TPS)
+ * the following registers can be used to get TPS-information.
+ * The values are according to the DVB-T standard.
+ */
+
+/* TPS locked (1) */
+#define DIB3000MB_REG_TPS_LOCK                 (   394)
+
+/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
+#define DIB3000MB_REG_TPS_QAM                  (   398)
+
+/* hierarchy from TPS (1) */
+#define DIB3000MB_REG_TPS_HRCH                 (   399)
+
+/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
+#define DIB3000MB_REG_TPS_VIT_ALPHA            (   400)
+
+/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
+#define DIB3000MB_REG_TPS_CODE_RATE_HP (   401)
+
+/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
+#define DIB3000MB_REG_TPS_CODE_RATE_LP (   402)
+
+/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
+#define DIB3000MB_REG_TPS_GUARD_TIME   (   403)
+
+/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
+#define DIB3000MB_REG_TPS_FFT                  (   404)
+
+/* cell id from TPS (16) */
+#define DIB3000MB_REG_TPS_CELL_ID              (   406)
+
+/* TPS (68) */
+#define DIB3000MB_REG_TPS_1                            (   408)
+#define DIB3000MB_REG_TPS_2                            (   409)
+#define DIB3000MB_REG_TPS_3                            (   410)
+#define DIB3000MB_REG_TPS_4                            (   411)
+#define DIB3000MB_REG_TPS_5                            (   412)
+
+/* bit error rate (before RS correction) (21) */
+#define DIB3000MB_REG_BER_MSB                  (   414)
+#define DIB3000MB_REG_BER_LSB                  (   415)
+
+/* packet error rate (uncorrected TS packets) (16) */
+#define DIB3000MB_REG_PACKET_ERROR_RATE        (   417)
+
+/* uncorrected packet count (16) */
+#define DIB3000MB_REG_UNC                              (   420)
+
+/* viterbi locked (1) */
+#define DIB3000MB_REG_VIT_LCK                  (   421)
+
+/* viterbi inidcator (16) */
+#define DIB3000MB_REG_VIT_INDICATOR            (   422)
+
+/* transport stream sync lock (1) */
+#define DIB3000MB_REG_TS_SYNC_LOCK             (   423)
+
+/* transport stream RS lock (1) */
+#define DIB3000MB_REG_TS_RS_LOCK               (   424)
+
+/* lock mask 0 value (1) */
+#define DIB3000MB_REG_LOCK0_VALUE              (   425)
+
+/* lock mask 1 value (1) */
+#define DIB3000MB_REG_LOCK1_VALUE              (   426)
+
+/* lock mask 2 value (1) */
+#define DIB3000MB_REG_LOCK2_VALUE              (   427)
+
+/* interrupt pending for auto search */
+#define DIB3000MB_REG_AS_IRQ_PENDING   (   434)
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c
new file mode 100644 (file)
index 0000000..ffad181
--- /dev/null
@@ -0,0 +1,940 @@
+/*
+ * Driver for DiBcom DiB3000MC/P-demodulator.
+ *
+ * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This code is partially based on the previous dib3000mc.c .
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "dib3000mc.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+static int buggy_sfn_workaround;
+module_param(buggy_sfn_workaround, int, 0644);
+MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
+
+struct dib3000mc_state {
+       struct dvb_frontend demod;
+       struct dib3000mc_config *cfg;
+
+       u8 i2c_addr;
+       struct i2c_adapter *i2c_adap;
+
+       struct dibx000_i2c_master i2c_master;
+
+       u32 timf;
+
+       u32 current_bandwidth;
+
+       u16 dev_id;
+
+       u8 sfn_workaround_active :1;
+};
+
+static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
+{
+       u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
+       u8 rb[2];
+       struct i2c_msg msg[2] = {
+               { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
+               { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+       };
+
+       if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
+               dprintk("i2c read error on %d\n",reg);
+
+       return (rb[0] << 8) | rb[1];
+}
+
+static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
+{
+       u8 b[4] = {
+               (reg >> 8) & 0xff, reg & 0xff,
+               (val >> 8) & 0xff, val & 0xff,
+       };
+       struct i2c_msg msg = {
+               .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+       };
+       return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static int dib3000mc_identify(struct dib3000mc_state *state)
+{
+       u16 value;
+       if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
+               dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
+               return -EREMOTEIO;
+       }
+
+       value = dib3000mc_read_word(state, 1026);
+       if (value != 0x3001 && value != 0x3002) {
+               dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
+               return -EREMOTEIO;
+       }
+       state->dev_id = value;
+
+       dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);
+
+       return 0;
+}
+
+static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
+{
+       u32 timf;
+
+       if (state->timf == 0) {
+               timf = 1384402; // default value for 8MHz
+               if (update_offset)
+                       msleep(200); // first time we do an update
+       } else
+               timf = state->timf;
+
+       timf *= (bw / 1000);
+
+       if (update_offset) {
+               s16 tim_offs = dib3000mc_read_word(state, 416);
+
+               if (tim_offs &  0x2000)
+                       tim_offs -= 0x4000;
+
+               if (nfft == TRANSMISSION_MODE_2K)
+                       tim_offs *= 4;
+
+               timf += tim_offs;
+               state->timf = timf / (bw / 1000);
+       }
+
+       dprintk("timf: %d\n", timf);
+
+       dib3000mc_write_word(state, 23, (u16) (timf >> 16));
+       dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
+
+       return 0;
+}
+
+static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
+{
+       u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
+    if (state->cfg->pwm3_inversion) {
+               reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+               reg_52 |= (1 << 2);
+       } else {
+               reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
+               reg_52 |= (1 << 8);
+       }
+       dib3000mc_write_word(state, 51, reg_51);
+       dib3000mc_write_word(state, 52, reg_52);
+
+    if (state->cfg->use_pwm3)
+               dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
+       else
+               dib3000mc_write_word(state, 245, 0);
+
+    dib3000mc_write_word(state, 1040, 0x3);
+       return 0;
+}
+
+static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
+{
+       int    ret = 0;
+       u16 fifo_threshold = 1792;
+       u16 outreg = 0;
+       u16 outmode = 0;
+       u16 elecout = 1;
+       u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
+
+       dprintk("-I-  Setting output mode for demod %p to %d\n",
+                       &state->demod, mode);
+
+       switch (mode) {
+               case OUTMODE_HIGH_Z:  // disable
+                       elecout = 0;
+                       break;
+               case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
+                       outmode = 0;
+                       break;
+               case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
+                       outmode = 1;
+                       break;
+               case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
+                       outmode = 2;
+                       break;
+               case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
+                       elecout = 3;
+                       /*ADDR @ 206 :
+                       P_smo_error_discard  [1;6:6] = 0
+                       P_smo_rs_discard     [1;5:5] = 0
+                       P_smo_pid_parse      [1;4:4] = 0
+                       P_smo_fifo_flush     [1;3:3] = 0
+                       P_smo_mode           [2;2:1] = 11
+                       P_smo_ovf_prot       [1;0:0] = 0
+                       */
+                       smo_reg |= 3 << 1;
+                       fifo_threshold = 512;
+                       outmode = 5;
+                       break;
+               case OUTMODE_DIVERSITY:
+                       outmode = 4;
+                       elecout = 1;
+                       break;
+               default:
+                       dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
+                       outmode = 0;
+                       break;
+       }
+
+       if ((state->cfg->output_mpeg2_in_188_bytes))
+               smo_reg |= (1 << 5); // P_smo_rs_discard     [1;5:5] = 1
+
+       outreg = dib3000mc_read_word(state, 244) & 0x07FF;
+       outreg |= (outmode << 11);
+       ret |= dib3000mc_write_word(state,  244, outreg);
+       ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
+       ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
+       ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
+       return ret;
+}
+
+static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
+{
+       u16 bw_cfg[6] = { 0 };
+       u16 imp_bw_cfg[3] = { 0 };
+       u16 reg;
+
+/* settings here are for 27.7MHz */
+       switch (bw) {
+               case 8000:
+                       bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
+                       imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
+                       break;
+
+               case 7000:
+                       bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
+                       imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
+                       break;
+
+               case 6000:
+                       bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
+                       imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
+                       break;
+
+               case 5000:
+                       bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
+                       imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
+                       break;
+
+               default: return -EINVAL;
+       }
+
+       for (reg = 6; reg < 12; reg++)
+               dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
+       dib3000mc_write_word(state, 12, 0x0000);
+       dib3000mc_write_word(state, 13, 0x03e8);
+       dib3000mc_write_word(state, 14, 0x0000);
+       dib3000mc_write_word(state, 15, 0x03f2);
+       dib3000mc_write_word(state, 16, 0x0001);
+       dib3000mc_write_word(state, 17, 0xb0d0);
+       // P_sec_len
+       dib3000mc_write_word(state, 18, 0x0393);
+       dib3000mc_write_word(state, 19, 0x8700);
+
+       for (reg = 55; reg < 58; reg++)
+               dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
+
+       // Timing configuration
+       dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
+
+       return 0;
+}
+
+static u16 impulse_noise_val[29] =
+
+{
+       0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
+       0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
+       0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
+};
+
+static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
+{
+       u16 i;
+       for (i = 58; i < 87; i++)
+               dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
+
+       if (nfft == TRANSMISSION_MODE_8K) {
+               dib3000mc_write_word(state, 58, 0x3b);
+               dib3000mc_write_word(state, 84, 0x00);
+               dib3000mc_write_word(state, 85, 0x8200);
+       }
+
+       dib3000mc_write_word(state, 34, 0x1294);
+       dib3000mc_write_word(state, 35, 0x1ff8);
+       if (mode == 1)
+               dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
+}
+
+static int dib3000mc_init(struct dvb_frontend *demod)
+{
+       struct dib3000mc_state *state = demod->demodulator_priv;
+       struct dibx000_agc_config *agc = state->cfg->agc;
+
+       // Restart Configuration
+       dib3000mc_write_word(state, 1027, 0x8000);
+       dib3000mc_write_word(state, 1027, 0x0000);
+
+       // power up the demod + mobility configuration
+       dib3000mc_write_word(state, 140, 0x0000);
+       dib3000mc_write_word(state, 1031, 0);
+
+       if (state->cfg->mobile_mode) {
+               dib3000mc_write_word(state, 139,  0x0000);
+               dib3000mc_write_word(state, 141,  0x0000);
+               dib3000mc_write_word(state, 175,  0x0002);
+               dib3000mc_write_word(state, 1032, 0x0000);
+       } else {
+               dib3000mc_write_word(state, 139,  0x0001);
+               dib3000mc_write_word(state, 141,  0x0000);
+               dib3000mc_write_word(state, 175,  0x0000);
+               dib3000mc_write_word(state, 1032, 0x012C);
+       }
+       dib3000mc_write_word(state, 1033, 0x0000);
+
+       // P_clk_cfg
+       dib3000mc_write_word(state, 1037, 0x3130);
+
+       // other configurations
+
+       // P_ctrl_sfreq
+       dib3000mc_write_word(state, 33, (5 << 0));
+       dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
+
+       // Phase noise control
+       // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
+       dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
+
+       if (state->cfg->phase_noise_mode == 0)
+               dib3000mc_write_word(state, 111, 0x00);
+       else
+               dib3000mc_write_word(state, 111, 0x02);
+
+       // P_agc_global
+       dib3000mc_write_word(state, 50, 0x8000);
+
+       // agc setup misc
+       dib3000mc_setup_pwm_state(state);
+
+       // P_agc_counter_lock
+       dib3000mc_write_word(state, 53, 0x87);
+       // P_agc_counter_unlock
+       dib3000mc_write_word(state, 54, 0x87);
+
+       /* agc */
+       dib3000mc_write_word(state, 36, state->cfg->max_time);
+       dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
+       dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
+       dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
+
+       // set_agc_loop_Bw
+       dib3000mc_write_word(state, 40, 0x0179);
+       dib3000mc_write_word(state, 41, 0x03f0);
+
+       dib3000mc_write_word(state, 42, agc->agc1_max);
+       dib3000mc_write_word(state, 43, agc->agc1_min);
+       dib3000mc_write_word(state, 44, agc->agc2_max);
+       dib3000mc_write_word(state, 45, agc->agc2_min);
+       dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+       dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+       dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+       dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+// Begin: TimeOut registers
+       // P_pha3_thres
+       dib3000mc_write_word(state, 110, 3277);
+       // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
+       dib3000mc_write_word(state,  26, 0x6680);
+       // lock_mask0
+       dib3000mc_write_word(state, 1, 4);
+       // lock_mask1
+       dib3000mc_write_word(state, 2, 4);
+       // lock_mask2
+       dib3000mc_write_word(state, 3, 0x1000);
+       // P_search_maxtrial=1
+       dib3000mc_write_word(state, 5, 1);
+
+       dib3000mc_set_bandwidth(state, 8000);
+
+       // div_lock_mask
+       dib3000mc_write_word(state,  4, 0x814);
+
+       dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
+       dib3000mc_write_word(state, 22, 0x463d);
+
+       // Spurious rm cfg
+       // P_cspu_regul, P_cspu_win_cut
+       dib3000mc_write_word(state, 120, 0x200f);
+       // P_adp_selec_monit
+       dib3000mc_write_word(state, 134, 0);
+
+       // Fec cfg
+       dib3000mc_write_word(state, 195, 0x10);
+
+       // diversity register: P_dvsy_sync_wait..
+       dib3000mc_write_word(state, 180, 0x2FF0);
+
+       // Impulse noise configuration
+       dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
+
+       // output mode set-up
+       dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
+
+       /* close the i2c-gate */
+       dib3000mc_write_word(state, 769, (1 << 7) );
+
+       return 0;
+}
+
+static int dib3000mc_sleep(struct dvb_frontend *demod)
+{
+       struct dib3000mc_state *state = demod->demodulator_priv;
+
+       dib3000mc_write_word(state, 1031, 0xFFFF);
+       dib3000mc_write_word(state, 1032, 0xFFFF);
+       dib3000mc_write_word(state, 1033, 0xFFF0);
+
+    return 0;
+}
+
+static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
+{
+       u16 cfg[4] = { 0 },reg;
+       switch (qam) {
+               case QPSK:
+                       cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
+                       break;
+               case QAM_16:
+                       cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
+                       break;
+               case QAM_64:
+                       cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
+                       break;
+       }
+       for (reg = 129; reg < 133; reg++)
+               dib3000mc_write_word(state, reg, cfg[reg - 129]);
+}
+
+static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
+                                     struct dtv_frontend_properties *ch, u16 seq)
+{
+       u16 value;
+       u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
+
+       dib3000mc_set_bandwidth(state, bw);
+       dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
+
+//     if (boost)
+//             dib3000mc_write_word(state, 100, (11 << 6) + 6);
+//     else
+               dib3000mc_write_word(state, 100, (16 << 6) + 9);
+
+       dib3000mc_write_word(state, 1027, 0x0800);
+       dib3000mc_write_word(state, 1027, 0x0000);
+
+       //Default cfg isi offset adp
+       dib3000mc_write_word(state, 26,  0x6680);
+       dib3000mc_write_word(state, 29,  0x1273);
+       dib3000mc_write_word(state, 33,       5);
+       dib3000mc_set_adp_cfg(state, QAM_16);
+       dib3000mc_write_word(state, 133,  15564);
+
+       dib3000mc_write_word(state, 12 , 0x0);
+       dib3000mc_write_word(state, 13 , 0x3e8);
+       dib3000mc_write_word(state, 14 , 0x0);
+       dib3000mc_write_word(state, 15 , 0x3f2);
+
+       dib3000mc_write_word(state, 93,0);
+       dib3000mc_write_word(state, 94,0);
+       dib3000mc_write_word(state, 95,0);
+       dib3000mc_write_word(state, 96,0);
+       dib3000mc_write_word(state, 97,0);
+       dib3000mc_write_word(state, 98,0);
+
+       dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
+
+       value = 0;
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
+       }
+       switch (ch->guard_interval) {
+               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
+               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
+               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
+               default:
+               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
+       }
+       switch (ch->modulation) {
+               case QPSK:  value |= (0 << 3); break;
+               case QAM_16: value |= (1 << 3); break;
+               default:
+               case QAM_64: value |= (2 << 3); break;
+       }
+       switch (HIERARCHY_1) {
+               case HIERARCHY_2: value |= 2; break;
+               case HIERARCHY_4: value |= 4; break;
+               default:
+               case HIERARCHY_1: value |= 1; break;
+       }
+       dib3000mc_write_word(state, 0, value);
+       dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
+
+       value = 0;
+       if (ch->hierarchy == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
+               case FEC_2_3: value |= (2 << 1); break;
+               case FEC_3_4: value |= (3 << 1); break;
+               case FEC_5_6: value |= (5 << 1); break;
+               case FEC_7_8: value |= (7 << 1); break;
+               default:
+               case FEC_1_2: value |= (1 << 1); break;
+       }
+       dib3000mc_write_word(state, 181, value);
+
+       // diversity synchro delay add 50% SFN margin
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_8K: value = 256; break;
+               case TRANSMISSION_MODE_2K:
+               default: value = 64; break;
+       }
+       switch (ch->guard_interval) {
+               case GUARD_INTERVAL_1_16: value *= 2; break;
+               case GUARD_INTERVAL_1_8:  value *= 4; break;
+               case GUARD_INTERVAL_1_4:  value *= 8; break;
+               default:
+               case GUARD_INTERVAL_1_32: value *= 1; break;
+       }
+       value <<= 4;
+       value |= dib3000mc_read_word(state, 180) & 0x000f;
+       dib3000mc_write_word(state, 180, value);
+
+       // restart demod
+       value = dib3000mc_read_word(state, 0);
+       dib3000mc_write_word(state, 0, value | (1 << 9));
+       dib3000mc_write_word(state, 0, value);
+
+       msleep(30);
+
+       dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
+}
+
+static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
+       struct dib3000mc_state *state = demod->demodulator_priv;
+       u16 reg;
+//     u32 val;
+       struct dtv_frontend_properties schan;
+
+       schan = *chan;
+
+       /* TODO what is that ? */
+
+       /* a channel for autosearch */
+       schan.transmission_mode = TRANSMISSION_MODE_8K;
+       schan.guard_interval = GUARD_INTERVAL_1_32;
+       schan.modulation = QAM_64;
+       schan.code_rate_HP = FEC_2_3;
+       schan.code_rate_LP = FEC_2_3;
+       schan.hierarchy = 0;
+
+       dib3000mc_set_channel_cfg(state, &schan, 11);
+
+       reg = dib3000mc_read_word(state, 0);
+       dib3000mc_write_word(state, 0, reg | (1 << 8));
+       dib3000mc_read_word(state, 511);
+       dib3000mc_write_word(state, 0, reg);
+
+       return 0;
+}
+
+static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
+{
+       struct dib3000mc_state *state = demod->demodulator_priv;
+       u16 irq_pending = dib3000mc_read_word(state, 511);
+
+       if (irq_pending & 0x1) // failed
+               return 1;
+
+       if (irq_pending & 0x2) // succeeded
+               return 2;
+
+       return 0; // still pending
+}
+
+static int dib3000mc_tune(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib3000mc_state *state = demod->demodulator_priv;
+
+       // ** configure demod **
+       dib3000mc_set_channel_cfg(state, ch, 0);
+
+       // activates isi
+       if (state->sfn_workaround_active) {
+               dprintk("SFN workaround is active\n");
+               dib3000mc_write_word(state, 29, 0x1273);
+               dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
+       } else {
+               dib3000mc_write_word(state, 29, 0x1073);
+               dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
+       }
+
+       dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
+       if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
+               dib3000mc_write_word(state, 26, 38528);
+               dib3000mc_write_word(state, 33, 8);
+       } else {
+               dib3000mc_write_word(state, 26, 30336);
+               dib3000mc_write_word(state, 33, 6);
+       }
+
+       if (dib3000mc_read_word(state, 509) & 0x80)
+               dib3000mc_set_timing(state, ch->transmission_mode,
+                                    BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
+
+       return 0;
+}
+
+struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
+{
+       struct dib3000mc_state *st = demod->demodulator_priv;
+       return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
+}
+
+EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
+
+static int dib3000mc_get_frontend(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       u16 tps = dib3000mc_read_word(state,458);
+
+       fep->inversion = INVERSION_AUTO;
+
+       fep->bandwidth_hz = state->current_bandwidth;
+
+       switch ((tps >> 8) & 0x1) {
+               case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
+               case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
+       }
+
+       switch (tps & 0x3) {
+               case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
+               case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
+               case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
+               case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
+       }
+
+       switch ((tps >> 13) & 0x3) {
+               case 0: fep->modulation = QPSK; break;
+               case 1: fep->modulation = QAM_16; break;
+               case 2:
+               default: fep->modulation = QAM_64; break;
+       }
+
+       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
+       /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
+
+       fep->hierarchy = HIERARCHY_NONE;
+       switch ((tps >> 5) & 0x7) {
+               case 1: fep->code_rate_HP = FEC_1_2; break;
+               case 2: fep->code_rate_HP = FEC_2_3; break;
+               case 3: fep->code_rate_HP = FEC_3_4; break;
+               case 5: fep->code_rate_HP = FEC_5_6; break;
+               case 7:
+               default: fep->code_rate_HP = FEC_7_8; break;
+
+       }
+
+       switch ((tps >> 2) & 0x7) {
+               case 1: fep->code_rate_LP = FEC_1_2; break;
+               case 2: fep->code_rate_LP = FEC_2_3; break;
+               case 3: fep->code_rate_LP = FEC_3_4; break;
+               case 5: fep->code_rate_LP = FEC_5_6; break;
+               case 7:
+               default: fep->code_rate_LP = FEC_7_8; break;
+       }
+
+       return 0;
+}
+
+static int dib3000mc_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       int ret;
+
+       dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
+
+       state->current_bandwidth = fep->bandwidth_hz;
+       dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
+
+       /* maybe the parameter has been changed */
+       state->sfn_workaround_active = buggy_sfn_workaround;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               msleep(100);
+       }
+
+       if (fep->transmission_mode  == TRANSMISSION_MODE_AUTO ||
+           fep->guard_interval == GUARD_INTERVAL_AUTO ||
+           fep->modulation     == QAM_AUTO ||
+           fep->code_rate_HP   == FEC_AUTO) {
+               int i = 1000, found;
+
+               dib3000mc_autosearch_start(fe);
+               do {
+                       msleep(1);
+                       found = dib3000mc_autosearch_is_irq(fe);
+               } while (found == 0 && i--);
+
+               dprintk("autosearch returns: %d\n",found);
+               if (found == 0 || found == 1)
+                       return 0; // no channel found
+
+               dib3000mc_get_frontend(fe);
+       }
+
+       ret = dib3000mc_tune(fe);
+
+       /* make this a config parameter */
+       dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
+       return ret;
+}
+
+static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       u16 lock = dib3000mc_read_word(state, 509);
+
+       *stat = 0;
+
+       if (lock & 0x8000)
+               *stat |= FE_HAS_SIGNAL;
+       if (lock & 0x3000)
+               *stat |= FE_HAS_CARRIER;
+       if (lock & 0x0100)
+               *stat |= FE_HAS_VITERBI;
+       if (lock & 0x0010)
+               *stat |= FE_HAS_SYNC;
+       if (lock & 0x0008)
+               *stat |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
+       return 0;
+}
+
+static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       *unc = dib3000mc_read_word(state, 508);
+       return 0;
+}
+
+static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       u16 val = dib3000mc_read_word(state, 392);
+       *strength = 65535 - val;
+       return 0;
+}
+
+static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       *snr = 0x0000;
+       return 0;
+}
+
+static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void dib3000mc_release(struct dvb_frontend *fe)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       dibx000_exit_i2c_master(&state->i2c_master);
+       kfree(state);
+}
+
+int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
+       return 0;
+}
+EXPORT_SYMBOL(dib3000mc_pid_control);
+
+int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
+       tmp |= (onoff << 4);
+       return dib3000mc_write_word(state, 206, tmp);
+}
+EXPORT_SYMBOL(dib3000mc_pid_parse);
+
+void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
+{
+       struct dib3000mc_state *state = fe->demodulator_priv;
+       state->cfg = cfg;
+}
+EXPORT_SYMBOL(dib3000mc_set_config);
+
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
+{
+       struct dib3000mc_state *dmcst;
+       int k;
+       u8 new_addr;
+
+       static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
+
+       dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
+       if (dmcst == NULL)
+               return -ENOMEM;
+
+       dmcst->i2c_adap = i2c;
+
+       for (k = no_of_demods-1; k >= 0; k--) {
+               dmcst->cfg = &cfg[k];
+
+               /* designated i2c address */
+               new_addr          = DIB3000MC_I2C_ADDRESS[k];
+               dmcst->i2c_addr = new_addr;
+               if (dib3000mc_identify(dmcst) != 0) {
+                       dmcst->i2c_addr = default_addr;
+                       if (dib3000mc_identify(dmcst) != 0) {
+                               dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
+                               kfree(dmcst);
+                               return -ENODEV;
+                       }
+               }
+
+               dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
+
+               // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
+               dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
+               dmcst->i2c_addr = new_addr;
+       }
+
+       for (k = 0; k < no_of_demods; k++) {
+               dmcst->cfg = &cfg[k];
+               dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
+
+               dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
+
+               /* turn off data output */
+               dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
+       }
+
+       kfree(dmcst);
+       return 0;
+}
+EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
+
+static struct dvb_frontend_ops dib3000mc_ops;
+
+struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+{
+       struct dvb_frontend *demod;
+       struct dib3000mc_state *st;
+       st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       st->cfg = cfg;
+       st->i2c_adap = i2c_adap;
+       st->i2c_addr = i2c_addr;
+
+       demod                   = &st->demod;
+       demod->demodulator_priv = st;
+       memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
+
+       if (dib3000mc_identify(st) != 0)
+               goto error;
+
+       dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
+
+       dib3000mc_write_word(st, 1037, 0x3130);
+
+       return demod;
+
+error:
+       kfree(st);
+       return NULL;
+}
+EXPORT_SYMBOL(dib3000mc_attach);
+
+static struct dvb_frontend_ops dib3000mc_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "DiBcom 3000MC/P",
+               .frequency_min      = 44250000,
+               .frequency_max      = 867250000,
+               .frequency_stepsize = 62500,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release              = dib3000mc_release,
+
+       .init                 = dib3000mc_init,
+       .sleep                = dib3000mc_sleep,
+
+       .set_frontend         = dib3000mc_set_frontend,
+       .get_tune_settings    = dib3000mc_fe_get_tune_settings,
+       .get_frontend         = dib3000mc_get_frontend,
+
+       .read_status          = dib3000mc_read_status,
+       .read_ber             = dib3000mc_read_ber,
+       .read_signal_strength = dib3000mc_read_signal_strength,
+       .read_snr             = dib3000mc_read_snr,
+       .read_ucblocks        = dib3000mc_read_unc_blocks,
+};
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib3000mc.h b/drivers/media/dvb-frontends/dib3000mc.h
new file mode 100644 (file)
index 0000000..d75ffad
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Driver for DiBcom DiB3000MC/P-demodulator.
+ *
+ * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
+ *
+ * This code is partially based on the previous dib3000mc.c .
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#ifndef DIB3000MC_H
+#define DIB3000MC_H
+
+#include "dibx000_common.h"
+
+struct dib3000mc_config {
+       struct dibx000_agc_config *agc;
+
+       u8 phase_noise_mode;
+       u8 impulse_noise_mode;
+
+       u8  pwm3_inversion;
+       u8  use_pwm3;
+       u16 pwm3_value;
+
+       u16 max_time;
+       u16 ln_adc_level;
+
+       u8 agc_command1 :1;
+       u8 agc_command2 :1;
+
+       u8 mobile_mode;
+
+       u8 output_mpeg2_in_188_bytes;
+};
+
+#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
+#define DEFAULT_DIB3000P_I2C_ADDRESS  24
+
+#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
+                                     defined(MODULE))
+extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
+                                            u8 i2c_addr,
+                                            struct dib3000mc_config *cfg);
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+                                    int no_of_demods, u8 default_addr,
+                                    struct dib3000mc_config cfg[]);
+extern
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+                                                  int gating);
+#else
+static inline
+struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+                                     struct dib3000mc_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+                             int no_of_demods, u8 default_addr,
+                             struct dib3000mc_config cfg[])
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+                                                  int gating)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
+
+extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
+extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
+
+extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
new file mode 100644 (file)
index 0000000..148bf79
--- /dev/null
@@ -0,0 +1,1473 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB7000M and
+ *              first generation DiB7000P-demodulator-family.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_frontend.h"
+
+#include "dib7000m.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
+
+struct dib7000m_state {
+       struct dvb_frontend demod;
+    struct dib7000m_config cfg;
+
+       u8 i2c_addr;
+       struct i2c_adapter   *i2c_adap;
+
+       struct dibx000_i2c_master i2c_master;
+
+/* offset is 1 in case of the 7000MC */
+       u8 reg_offs;
+
+       u16 wbd_ref;
+
+       u8 current_band;
+       u32 current_bandwidth;
+       struct dibx000_agc_config *current_agc;
+       u32 timf;
+       u32 timf_default;
+       u32 internal_clk;
+
+       u8 div_force_off : 1;
+       u8 div_state : 1;
+       u16 div_sync_wait;
+
+       u16 revision;
+
+       u8 agc_state;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[4];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+};
+
+enum dib7000m_power_mode {
+       DIB7000M_POWER_ALL = 0,
+
+       DIB7000M_POWER_NO,
+       DIB7000M_POWER_INTERF_ANALOG_AGC,
+       DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
+       DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
+       DIB7000M_POWER_INTERFACE_ONLY,
+};
+
+static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
+       state->i2c_write_buffer[1] = reg & 0xff;
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 2;
+       state->msg[1].addr = state->i2c_addr >> 1;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = state->i2c_read_buffer;
+       state->msg[1].len = 2;
+
+       if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+               dprintk("i2c read error on %d",reg);
+
+       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+       mutex_unlock(&state->i2c_buffer_lock);
+
+       return ret;
+}
+
+static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       state->i2c_write_buffer[1] = reg & 0xff;
+       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+       state->i2c_write_buffer[3] = val & 0xff;
+
+       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 4;
+
+       ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
+                       -EREMOTEIO : 0);
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
+{
+       u16 l = 0, r, *n;
+       n = buf;
+       l = *n++;
+       while (l) {
+               r = *n++;
+
+               if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
+                       r++;
+
+               do {
+                       dib7000m_write_word(state, r, *n++);
+                       r++;
+               } while (--l);
+               l = *n++;
+       }
+}
+
+static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
+{
+       int    ret = 0;
+       u16 outreg, fifo_threshold, smo_mode,
+               sram = 0x0005; /* by default SRAM output is disabled */
+
+       outreg = 0;
+       fifo_threshold = 1792;
+       smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
+
+       dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
+
+       switch (mode) {
+               case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
+                       outreg = (1 << 10);  /* 0x0400 */
+                       break;
+               case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
+                       outreg = (1 << 10) | (1 << 6); /* 0x0440 */
+                       break;
+               case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
+                       outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
+                       break;
+               case OUTMODE_DIVERSITY:
+                       if (state->cfg.hostbus_diversity)
+                               outreg = (1 << 10) | (4 << 6); /* 0x0500 */
+                       else
+                               sram   |= 0x0c00;
+                       break;
+               case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
+                       smo_mode |= (3 << 1);
+                       fifo_threshold = 512;
+                       outreg = (1 << 10) | (5 << 6);
+                       break;
+               case OUTMODE_HIGH_Z:  // disable
+                       outreg = 0;
+                       break;
+               default:
+                       dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
+                       break;
+       }
+
+       if (state->cfg.output_mpeg2_in_188_bytes)
+               smo_mode |= (1 << 5) ;
+
+       ret |= dib7000m_write_word(state,  294 + state->reg_offs, smo_mode);
+       ret |= dib7000m_write_word(state,  295 + state->reg_offs, fifo_threshold); /* synchronous fread */
+       ret |= dib7000m_write_word(state, 1795, outreg);
+       ret |= dib7000m_write_word(state, 1805, sram);
+
+       if (state->revision == 0x4003) {
+               u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
+               if (mode == OUTMODE_DIVERSITY)
+                       clk_cfg1 |= (1 << 1); // P_O_CLK_en
+               dib7000m_write_word(state, 909, clk_cfg1);
+       }
+       return ret;
+}
+
+static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
+{
+       /* by default everything is going to be powered off */
+       u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
+       u8  offset = 0;
+
+       /* now, depending on the requested mode, we power on */
+       switch (mode) {
+               /* power up everything in the demod */
+               case DIB7000M_POWER_ALL:
+                       reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
+                       break;
+
+               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
+               case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
+                       reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
+                       break;
+
+               case DIB7000M_POWER_INTERF_ANALOG_AGC:
+                       reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
+                       reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
+                       reg_906 &= ~((1 << 0));
+                       break;
+
+               case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
+                       reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
+                       break;
+
+               case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
+                       reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
+                       break;
+               case DIB7000M_POWER_NO:
+                       break;
+       }
+
+       /* always power down unused parts */
+       if (!state->cfg.mobile_mode)
+               reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
+
+       /* P_sdio_select_clk = 0 on MC and after*/
+       if (state->revision != 0x4000)
+               reg_906 <<= 1;
+
+       if (state->revision == 0x4003)
+               offset = 1;
+
+       dib7000m_write_word(state, 903 + offset, reg_903);
+       dib7000m_write_word(state, 904 + offset, reg_904);
+       dib7000m_write_word(state, 905 + offset, reg_905);
+       dib7000m_write_word(state, 906 + offset, reg_906);
+}
+
+static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
+{
+       int ret = 0;
+       u16 reg_913 = dib7000m_read_word(state, 913),
+              reg_914 = dib7000m_read_word(state, 914);
+
+       switch (no) {
+               case DIBX000_SLOW_ADC_ON:
+                       reg_914 |= (1 << 1) | (1 << 0);
+                       ret |= dib7000m_write_word(state, 914, reg_914);
+                       reg_914 &= ~(1 << 1);
+                       break;
+
+               case DIBX000_SLOW_ADC_OFF:
+                       reg_914 |=  (1 << 1) | (1 << 0);
+                       break;
+
+               case DIBX000_ADC_ON:
+                       if (state->revision == 0x4000) { // workaround for PA/MA
+                               // power-up ADC
+                               dib7000m_write_word(state, 913, 0);
+                               dib7000m_write_word(state, 914, reg_914 & 0x3);
+                               // power-down bandgag
+                               dib7000m_write_word(state, 913, (1 << 15));
+                               dib7000m_write_word(state, 914, reg_914 & 0x3);
+                       }
+
+                       reg_913 &= 0x0fff;
+                       reg_914 &= 0x0003;
+                       break;
+
+               case DIBX000_ADC_OFF: // leave the VBG voltage on
+                       reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
+                       reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+                       break;
+
+               case DIBX000_VBG_ENABLE:
+                       reg_913 &= ~(1 << 15);
+                       break;
+
+               case DIBX000_VBG_DISABLE:
+                       reg_913 |= (1 << 15);
+                       break;
+
+               default:
+                       break;
+       }
+
+//     dprintk( "913: %x, 914: %x", reg_913, reg_914);
+       ret |= dib7000m_write_word(state, 913, reg_913);
+       ret |= dib7000m_write_word(state, 914, reg_914);
+
+       return ret;
+}
+
+static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
+{
+       u32 timf;
+
+       if (!bw)
+               bw = 8000;
+
+       // store the current bandwidth for later use
+       state->current_bandwidth = bw;
+
+       if (state->timf == 0) {
+               dprintk( "using default timf");
+               timf = state->timf_default;
+       } else {
+               dprintk( "using updated timf");
+               timf = state->timf;
+       }
+
+       timf = timf * (bw / 50) / 160;
+
+       dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
+       dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
+
+       return 0;
+}
+
+static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
+{
+       struct dib7000m_state *state = demod->demodulator_priv;
+
+       if (state->div_force_off) {
+               dprintk( "diversity combination deactivated - forced by COFDM parameters");
+               onoff = 0;
+       }
+       state->div_state = (u8)onoff;
+
+       if (onoff) {
+               dib7000m_write_word(state, 263 + state->reg_offs, 6);
+               dib7000m_write_word(state, 264 + state->reg_offs, 6);
+               dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+       } else {
+               dib7000m_write_word(state, 263 + state->reg_offs, 1);
+               dib7000m_write_word(state, 264 + state->reg_offs, 0);
+               dib7000m_write_word(state, 266 + state->reg_offs, 0);
+       }
+
+       return 0;
+}
+
+static int dib7000m_sad_calib(struct dib7000m_state *state)
+{
+
+/* internal */
+//     dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
+       dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
+       dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
+
+       /* do the calibration */
+       dib7000m_write_word(state, 929, (1 << 0));
+       dib7000m_write_word(state, 929, (0 << 0));
+
+       msleep(1);
+
+       return 0;
+}
+
+static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
+{
+       dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
+       dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
+       dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
+       dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
+
+       dib7000m_write_word(state, 928, bw->sad_cfg);
+}
+
+static void dib7000m_reset_pll(struct dib7000m_state *state)
+{
+       const struct dibx000_bandwidth_config *bw = state->cfg.bw;
+       u16 reg_907,reg_910;
+
+       /* default */
+       reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
+               (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
+               (bw->enable_refdiv << 1) | (0 << 0);
+       reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
+
+       // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
+       // this is only working only for 30 MHz crystals
+       if (!state->cfg.quartz_direct) {
+               reg_910 |= (1 << 5);  // forcing the predivider to 1
+
+               // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
+               if(state->cfg.input_clk_is_div_2)
+                       reg_907 |= (16 << 9);
+               else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
+                       reg_907 |= (8 << 9);
+       } else {
+               reg_907 |= (bw->pll_ratio & 0x3f) << 9;
+               reg_910 |= (bw->pll_prediv << 5);
+       }
+
+       dib7000m_write_word(state, 910, reg_910); // pll cfg
+       dib7000m_write_word(state, 907, reg_907); // clk cfg0
+       dib7000m_write_word(state, 908, 0x0006);  // clk_cfg1
+
+       dib7000m_reset_pll_common(state, bw);
+}
+
+static void dib7000mc_reset_pll(struct dib7000m_state *state)
+{
+       const struct dibx000_bandwidth_config *bw = state->cfg.bw;
+       u16 clk_cfg1;
+
+       // clk_cfg0
+       dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
+
+       // clk_cfg1
+       //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
+       clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
+                       (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
+                       (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
+       dib7000m_write_word(state, 908, clk_cfg1);
+       clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
+       dib7000m_write_word(state, 908, clk_cfg1);
+
+       // smpl_cfg
+       dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
+
+       dib7000m_reset_pll_common(state, bw);
+}
+
+static int dib7000m_reset_gpio(struct dib7000m_state *st)
+{
+       /* reset the GPIOs */
+       dib7000m_write_word(st, 773, st->cfg.gpio_dir);
+       dib7000m_write_word(st, 774, st->cfg.gpio_val);
+
+       /* TODO 782 is P_gpio_od */
+
+       dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
+
+       dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
+       return 0;
+}
+
+static u16 dib7000m_defaults_common[] =
+
+{
+       // auto search configuration
+       3, 2,
+               0x0004,
+               0x1000,
+               0x0814,
+
+       12, 6,
+               0x001b,
+               0x7740,
+               0x005b,
+               0x8d80,
+               0x01c9,
+               0xc380,
+               0x0000,
+               0x0080,
+               0x0000,
+               0x0090,
+               0x0001,
+               0xd4c0,
+
+       1, 26,
+               0x6680, // P_corm_thres Lock algorithms configuration
+
+       1, 170,
+               0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
+
+       8, 173,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+
+       1, 182,
+               8192, // P_fft_nb_to_cut
+
+       2, 195,
+               0x0ccd, // P_pha3_thres
+               0,      // P_cti_use_cpe, P_cti_use_prog
+
+       1, 205,
+               0x200f, // P_cspu_regul, P_cspu_win_cut
+
+       5, 214,
+               0x023d, // P_adp_regul_cnt
+               0x00a4, // P_adp_noise_cnt
+               0x00a4, // P_adp_regul_ext
+               0x7ff0, // P_adp_noise_ext
+               0x3ccc, // P_adp_fil
+
+       1, 226,
+               0, // P_2d_byp_ti_num
+
+       1, 255,
+               0x800, // P_equal_thres_wgn
+
+       1, 263,
+               0x0001,
+
+       1, 281,
+               0x0010, // P_fec_*
+
+       1, 294,
+               0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
+
+       0
+};
+
+static u16 dib7000m_defaults[] =
+
+{
+       /* set ADC level to -16 */
+       11, 76,
+               (1 << 13) - 825 - 117,
+               (1 << 13) - 837 - 117,
+               (1 << 13) - 811 - 117,
+               (1 << 13) - 766 - 117,
+               (1 << 13) - 737 - 117,
+               (1 << 13) - 693 - 117,
+               (1 << 13) - 648 - 117,
+               (1 << 13) - 619 - 117,
+               (1 << 13) - 575 - 117,
+               (1 << 13) - 531 - 117,
+               (1 << 13) - 501 - 117,
+
+       // Tuner IO bank: max drive (14mA)
+       1, 912,
+               0x2c8a,
+
+       1, 1817,
+               1,
+
+       0,
+};
+
+static int dib7000m_demod_reset(struct dib7000m_state *state)
+{
+       dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
+
+       /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
+       dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
+
+       /* restart all parts */
+       dib7000m_write_word(state,  898, 0xffff);
+       dib7000m_write_word(state,  899, 0xffff);
+       dib7000m_write_word(state,  900, 0xff0f);
+       dib7000m_write_word(state,  901, 0xfffc);
+
+       dib7000m_write_word(state,  898, 0);
+       dib7000m_write_word(state,  899, 0);
+       dib7000m_write_word(state,  900, 0);
+       dib7000m_write_word(state,  901, 0);
+
+       if (state->revision == 0x4000)
+               dib7000m_reset_pll(state);
+       else
+               dib7000mc_reset_pll(state);
+
+       if (dib7000m_reset_gpio(state) != 0)
+               dprintk( "GPIO reset was not successful.");
+
+       if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
+               dprintk( "OUTPUT_MODE could not be reset.");
+
+       /* unforce divstr regardless whether i2c enumeration was done or not */
+       dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
+
+       dib7000m_set_bandwidth(state, 8000);
+
+       dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+       dib7000m_sad_calib(state);
+       dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+
+       if (state->cfg.dvbt_mode)
+               dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
+
+       if (state->cfg.mobile_mode)
+               dib7000m_write_word(state, 261 + state->reg_offs, 2);
+       else
+               dib7000m_write_word(state, 224 + state->reg_offs, 1);
+
+       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
+       if(state->cfg.tuner_is_baseband)
+               dib7000m_write_word(state, 36, 0x0755);
+       else
+               dib7000m_write_word(state, 36, 0x1f55);
+
+       // P_divclksel=3 P_divbitsel=1
+       if (state->revision == 0x4000)
+               dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
+       else
+               dib7000m_write_word(state, 909, (3 << 4) | 1);
+
+       dib7000m_write_tab(state, dib7000m_defaults_common);
+       dib7000m_write_tab(state, dib7000m_defaults);
+
+       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
+
+       state->internal_clk = state->cfg.bw->internal;
+
+       return 0;
+}
+
+static void dib7000m_restart_agc(struct dib7000m_state *state)
+{
+       // P_restart_iqc & P_restart_agc
+       dib7000m_write_word(state, 898, 0x0c00);
+       dib7000m_write_word(state, 898, 0x0000);
+}
+
+static int dib7000m_agc_soft_split(struct dib7000m_state *state)
+{
+       u16 agc,split_offset;
+
+       if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
+               return 0;
+
+       // n_agc_global
+       agc = dib7000m_read_word(state, 390);
+
+       if (agc > state->current_agc->split.min_thres)
+               split_offset = state->current_agc->split.min;
+       else if (agc < state->current_agc->split.max_thres)
+               split_offset = state->current_agc->split.max;
+       else
+               split_offset = state->current_agc->split.max *
+                       (agc - state->current_agc->split.min_thres) /
+                       (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
+
+       dprintk( "AGC split_offset: %d",split_offset);
+
+       // P_agc_force_split and P_agc_split_offset
+       return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
+}
+
+static int dib7000m_update_lna(struct dib7000m_state *state)
+{
+       u16 dyn_gain;
+
+       if (state->cfg.update_lna) {
+               // read dyn_gain here (because it is demod-dependent and not fe)
+               dyn_gain = dib7000m_read_word(state, 390);
+
+               if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
+                       dib7000m_restart_agc(state);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
+{
+       struct dibx000_agc_config *agc = NULL;
+       int i;
+       if (state->current_band == band && state->current_agc != NULL)
+               return 0;
+       state->current_band = band;
+
+       for (i = 0; i < state->cfg.agc_config_count; i++)
+               if (state->cfg.agc[i].band_caps & band) {
+                       agc = &state->cfg.agc[i];
+                       break;
+               }
+
+       if (agc == NULL) {
+               dprintk( "no valid AGC configuration found for band 0x%02x",band);
+               return -EINVAL;
+       }
+
+       state->current_agc = agc;
+
+       /* AGC */
+       dib7000m_write_word(state, 72 ,  agc->setup);
+       dib7000m_write_word(state, 73 ,  agc->inv_gain);
+       dib7000m_write_word(state, 74 ,  agc->time_stabiliz);
+       dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
+
+       // Demod AGC loop configuration
+       dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
+       dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
+
+       dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+       /* AGC continued */
+       if (state->wbd_ref != 0)
+               dib7000m_write_word(state, 102, state->wbd_ref);
+       else // use default
+               dib7000m_write_word(state, 102, agc->wbd_ref);
+
+       dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
+       dib7000m_write_word(state, 104,  agc->agc1_max);
+       dib7000m_write_word(state, 105,  agc->agc1_min);
+       dib7000m_write_word(state, 106,  agc->agc2_max);
+       dib7000m_write_word(state, 107,  agc->agc2_min);
+       dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
+       dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+       dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+       dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+       if (state->revision > 0x4000) { // settings for the MC
+               dib7000m_write_word(state, 71,   agc->agc1_pt3);
+//             dprintk( "929: %x %d %d",
+//                     (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
+               dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
+       } else {
+               // wrong default values
+               u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
+               for (i = 0; i < 9; i++)
+                       dib7000m_write_word(state, 88 + i, b[i]);
+       }
+       return 0;
+}
+
+static void dib7000m_update_timf(struct dib7000m_state *state)
+{
+       u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
+       state->timf = timf * 160 / (state->current_bandwidth / 50);
+       dib7000m_write_word(state, 23, (u16) (timf >> 16));
+       dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
+       dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
+}
+
+static int dib7000m_agc_startup(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000m_state *state = demod->demodulator_priv;
+       u16 cfg_72 = dib7000m_read_word(state, 72);
+       int ret = -1;
+       u8 *agc_state = &state->agc_state;
+       u8 agc_split;
+
+       switch (state->agc_state) {
+               case 0:
+                       // set power-up level: interf+analog+AGC
+                       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
+                       dib7000m_set_adc_state(state, DIBX000_ADC_ON);
+
+                       if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
+                               return -1;
+
+                       ret = 7; /* ADC power up */
+                       (*agc_state)++;
+                       break;
+
+               case 1:
+                       /* AGC initialization */
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 1);
+
+                       dib7000m_write_word(state, 75, 32768);
+                       if (!state->current_agc->perform_agc_softsplit) {
+                               /* we are using the wbd - so slow AGC startup */
+                               dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
+                               (*agc_state)++;
+                               ret = 5;
+                       } else {
+                               /* default AGC startup */
+                               (*agc_state) = 4;
+                               /* wait AGC rough lock time */
+                               ret = 7;
+                       }
+
+                       dib7000m_restart_agc(state);
+                       break;
+
+               case 2: /* fast split search path after 5sec */
+                       dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
+                       dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
+                       (*agc_state)++;
+                       ret = 14;
+                       break;
+
+       case 3: /* split search ended */
+                       agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
+                       dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
+
+                       dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
+                       dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
+
+                       dib7000m_restart_agc(state);
+
+                       dprintk( "SPLIT %p: %hd", demod, agc_split);
+
+                       (*agc_state)++;
+                       ret = 5;
+                       break;
+
+               case 4: /* LNA startup */
+                       /* wait AGC accurate lock time */
+                       ret = 7;
+
+                       if (dib7000m_update_lna(state))
+                               // wait only AGC rough lock time
+                               ret = 5;
+                       else
+                               (*agc_state)++;
+                       break;
+
+               case 5:
+                       dib7000m_agc_soft_split(state);
+
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 0);
+
+                       (*agc_state)++;
+                       break;
+
+               default:
+                       break;
+       }
+       return ret;
+}
+
+static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
+                                u8 seq)
+{
+       u16 value, est[4];
+
+       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+
+       /* nfft, guard, qam, alpha */
+       value = 0;
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
+               case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
+       }
+       switch (ch->guard_interval) {
+               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
+               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
+               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
+               default:
+               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
+       }
+       switch (ch->modulation) {
+               case QPSK:  value |= (0 << 3); break;
+               case QAM_16: value |= (1 << 3); break;
+               default:
+               case QAM_64: value |= (2 << 3); break;
+       }
+       switch (HIERARCHY_1) {
+               case HIERARCHY_2: value |= 2; break;
+               case HIERARCHY_4: value |= 4; break;
+               default:
+               case HIERARCHY_1: value |= 1; break;
+       }
+       dib7000m_write_word(state, 0, value);
+       dib7000m_write_word(state, 5, (seq << 4));
+
+       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
+       value = 0;
+       if (1 != 0)
+               value |= (1 << 6);
+       if (ch->hierarchy == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
+               case FEC_2_3: value |= (2 << 1); break;
+               case FEC_3_4: value |= (3 << 1); break;
+               case FEC_5_6: value |= (5 << 1); break;
+               case FEC_7_8: value |= (7 << 1); break;
+               default:
+               case FEC_1_2: value |= (1 << 1); break;
+       }
+       dib7000m_write_word(state, 267 + state->reg_offs, value);
+
+       /* offset loop parameters */
+
+       /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
+       dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
+
+       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
+       dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
+
+       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
+       dib7000m_write_word(state, 32, (0 << 4) | 0x3);
+
+       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
+       dib7000m_write_word(state, 33, (0 << 4) | 0x5);
+
+       /* P_dvsy_sync_wait */
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_8K: value = 256; break;
+               case TRANSMISSION_MODE_4K: value = 128; break;
+               case TRANSMISSION_MODE_2K:
+               default: value = 64; break;
+       }
+       switch (ch->guard_interval) {
+               case GUARD_INTERVAL_1_16: value *= 2; break;
+               case GUARD_INTERVAL_1_8:  value *= 4; break;
+               case GUARD_INTERVAL_1_4:  value *= 8; break;
+               default:
+               case GUARD_INTERVAL_1_32: value *= 1; break;
+       }
+       state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
+
+       /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
+       /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
+       if (1 == 1 || state->revision > 0x4000)
+               state->div_force_off = 0;
+       else
+               state->div_force_off = 1;
+       dib7000m_set_diversity_in(&state->demod, state->div_state);
+
+       /* channel estimation fine configuration */
+       switch (ch->modulation) {
+               case QAM_64:
+                       est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
+                       est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
+                       est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
+                       est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
+                       break;
+               case QAM_16:
+                       est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
+                       est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
+                       est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
+                       est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
+                       break;
+               default:
+                       est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
+                       est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
+                       est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
+                       est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
+                       break;
+       }
+       for (value = 0; value < 4; value++)
+               dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
+
+       // set power-up level: autosearch
+       dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
+}
+
+static int dib7000m_autosearch_start(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000m_state *state = demod->demodulator_priv;
+       struct dtv_frontend_properties schan;
+       int ret = 0;
+       u32 value, factor;
+
+       schan = *ch;
+
+       schan.modulation = QAM_64;
+       schan.guard_interval        = GUARD_INTERVAL_1_32;
+       schan.transmission_mode         = TRANSMISSION_MODE_8K;
+       schan.code_rate_HP = FEC_2_3;
+       schan.code_rate_LP = FEC_3_4;
+       schan.hierarchy    = 0;
+
+       dib7000m_set_channel(state, &schan, 7);
+
+       factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
+       if (factor >= 5000)
+               factor = 1;
+       else
+               factor = 6;
+
+       // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
+       value = 30 * state->internal_clk * factor;
+       ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
+       ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
+       value = 100 * state->internal_clk * factor;
+       ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
+       ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
+       value = 500 * state->internal_clk * factor;
+       ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
+       ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
+
+       // start search
+       value = dib7000m_read_word(state, 0);
+       ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
+
+       /* clear n_irq_pending */
+       if (state->revision == 0x4000)
+               dib7000m_write_word(state, 1793, 0);
+       else
+               dib7000m_read_word(state, 537);
+
+       ret |= dib7000m_write_word(state, 0, (u16) value);
+
+       return ret;
+}
+
+static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
+{
+       u16 irq_pending = dib7000m_read_word(state, reg);
+
+       if (irq_pending & 0x1) { // failed
+               dprintk( "autosearch failed");
+               return 1;
+       }
+
+       if (irq_pending & 0x2) { // succeeded
+               dprintk( "autosearch succeeded");
+               return 2;
+       }
+       return 0; // still pending
+}
+
+static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
+{
+       struct dib7000m_state *state = demod->demodulator_priv;
+       if (state->revision == 0x4000)
+               return dib7000m_autosearch_irq(state, 1793);
+       else
+               return dib7000m_autosearch_irq(state, 537);
+}
+
+static int dib7000m_tune(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000m_state *state = demod->demodulator_priv;
+       int ret = 0;
+       u16 value;
+
+       // we are already tuned - just resuming from suspend
+       if (ch != NULL)
+               dib7000m_set_channel(state, ch, 0);
+       else
+               return -EINVAL;
+
+       // restart demod
+       ret |= dib7000m_write_word(state, 898, 0x4000);
+       ret |= dib7000m_write_word(state, 898, 0x0000);
+       msleep(45);
+
+       dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
+       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
+       ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
+
+       // never achieved a lock before - wait for timfreq to update
+       if (state->timf == 0)
+               msleep(200);
+
+       //dump_reg(state);
+       /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
+       value = (6 << 8) | 0x80;
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
+               case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
+       }
+       ret |= dib7000m_write_word(state, 26, value);
+
+       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
+       value = (0 << 4);
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= 0x6; break;
+               case TRANSMISSION_MODE_4K: value |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= 0x8; break;
+       }
+       ret |= dib7000m_write_word(state, 32, value);
+
+       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
+       value = (0 << 4);
+       switch (ch->transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= 0x6; break;
+               case TRANSMISSION_MODE_4K: value |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= 0x8; break;
+       }
+       ret |= dib7000m_write_word(state, 33,  value);
+
+       // we achieved a lock - it's time to update the timf freq
+       if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
+               dib7000m_update_timf(state);
+
+       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+       return ret;
+}
+
+static int dib7000m_wakeup(struct dvb_frontend *demod)
+{
+       struct dib7000m_state *state = demod->demodulator_priv;
+
+       dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
+
+       if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
+               dprintk( "could not start Slow ADC");
+
+       return 0;
+}
+
+static int dib7000m_sleep(struct dvb_frontend *demod)
+{
+       struct dib7000m_state *st = demod->demodulator_priv;
+       dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
+       dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
+       return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
+               dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
+}
+
+static int dib7000m_identify(struct dib7000m_state *state)
+{
+       u16 value;
+
+       if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
+               dprintk( "wrong Vendor ID (0x%x)",value);
+               return -EREMOTEIO;
+       }
+
+       state->revision = dib7000m_read_word(state, 897);
+       if (state->revision != 0x4000 &&
+               state->revision != 0x4001 &&
+               state->revision != 0x4002 &&
+               state->revision != 0x4003) {
+               dprintk( "wrong Device ID (0x%x)",value);
+               return -EREMOTEIO;
+       }
+
+       /* protect this driver to be used with 7000PC */
+       if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
+               dprintk( "this driver does not work with DiB7000PC");
+               return -EREMOTEIO;
+       }
+
+       switch (state->revision) {
+               case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
+               case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
+               case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
+               case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
+       }
+
+       return 0;
+}
+
+
+static int dib7000m_get_frontend(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib7000m_state *state = fe->demodulator_priv;
+       u16 tps = dib7000m_read_word(state,480);
+
+       fep->inversion = INVERSION_AUTO;
+
+       fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
+
+       switch ((tps >> 8) & 0x3) {
+               case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
+               case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
+               /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
+       }
+
+       switch (tps & 0x3) {
+               case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
+               case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
+               case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
+               case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
+       }
+
+       switch ((tps >> 14) & 0x3) {
+               case 0: fep->modulation = QPSK; break;
+               case 1: fep->modulation = QAM_16; break;
+               case 2:
+               default: fep->modulation = QAM_64; break;
+       }
+
+       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
+       /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
+
+       fep->hierarchy = HIERARCHY_NONE;
+       switch ((tps >> 5) & 0x7) {
+               case 1: fep->code_rate_HP = FEC_1_2; break;
+               case 2: fep->code_rate_HP = FEC_2_3; break;
+               case 3: fep->code_rate_HP = FEC_3_4; break;
+               case 5: fep->code_rate_HP = FEC_5_6; break;
+               case 7:
+               default: fep->code_rate_HP = FEC_7_8; break;
+
+       }
+
+       switch ((tps >> 2) & 0x7) {
+               case 1: fep->code_rate_LP = FEC_1_2; break;
+               case 2: fep->code_rate_LP = FEC_2_3; break;
+               case 3: fep->code_rate_LP = FEC_3_4; break;
+               case 5: fep->code_rate_LP = FEC_5_6; break;
+               case 7:
+               default: fep->code_rate_LP = FEC_7_8; break;
+       }
+
+       /* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
+
+       return 0;
+}
+
+static int dib7000m_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib7000m_state *state = fe->demodulator_priv;
+       int time, ret;
+
+       dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
+
+       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
+
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       /* start up the AGC */
+       state->agc_state = 0;
+       do {
+               time = dib7000m_agc_startup(fe);
+               if (time != -1)
+                       msleep(time);
+       } while (time != -1);
+
+       if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
+               fep->guard_interval    == GUARD_INTERVAL_AUTO ||
+               fep->modulation        == QAM_AUTO ||
+               fep->code_rate_HP      == FEC_AUTO) {
+               int i = 800, found;
+
+               dib7000m_autosearch_start(fe);
+               do {
+                       msleep(1);
+                       found = dib7000m_autosearch_is_irq(fe);
+               } while (found == 0 && i--);
+
+               dprintk("autosearch returns: %d",found);
+               if (found == 0 || found == 1)
+                       return 0; // no channel found
+
+               dib7000m_get_frontend(fe);
+       }
+
+       ret = dib7000m_tune(fe);
+
+       /* make this a config parameter */
+       dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
+       return ret;
+}
+
+static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       u16 lock = dib7000m_read_word(state, 535);
+
+       *stat = 0;
+
+       if (lock & 0x8000)
+               *stat |= FE_HAS_SIGNAL;
+       if (lock & 0x3000)
+               *stat |= FE_HAS_CARRIER;
+       if (lock & 0x0100)
+               *stat |= FE_HAS_VITERBI;
+       if (lock & 0x0010)
+               *stat |= FE_HAS_SYNC;
+       if (lock & 0x0008)
+               *stat |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
+       return 0;
+}
+
+static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       *unc = dib7000m_read_word(state, 534);
+       return 0;
+}
+
+static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       u16 val = dib7000m_read_word(state, 390);
+       *strength = 65535 - val;
+       return 0;
+}
+
+static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+       *snr = 0x0000;
+       return 0;
+}
+
+static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void dib7000m_release(struct dvb_frontend *demod)
+{
+       struct dib7000m_state *st = demod->demodulator_priv;
+       dibx000_exit_i2c_master(&st->i2c_master);
+       kfree(st);
+}
+
+struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
+{
+       struct dib7000m_state *st = demod->demodulator_priv;
+       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+EXPORT_SYMBOL(dib7000m_get_i2c_master);
+
+int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
+       val |= (onoff & 0x1) << 4;
+       dprintk("PID filter enabled %d", onoff);
+       return dib7000m_write_word(state, 294 + state->reg_offs, val);
+}
+EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
+
+int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       struct dib7000m_state *state = fe->demodulator_priv;
+       dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
+       return dib7000m_write_word(state, 300 + state->reg_offs + id,
+                       onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib7000m_pid_filter);
+
+#if 0
+/* used with some prototype boards */
+int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
+               u8 default_addr, struct dib7000m_config cfg[])
+{
+       struct dib7000m_state st = { .i2c_adap = i2c };
+       int k = 0;
+       u8 new_addr = 0;
+
+       for (k = no_of_demods-1; k >= 0; k--) {
+               st.cfg = cfg[k];
+
+               /* designated i2c address */
+               new_addr          = (0x40 + k) << 1;
+               st.i2c_addr = new_addr;
+               if (dib7000m_identify(&st) != 0) {
+                       st.i2c_addr = default_addr;
+                       if (dib7000m_identify(&st) != 0) {
+                               dprintk("DiB7000M #%d: not identified", k);
+                               return -EIO;
+                       }
+               }
+
+               /* start diversity to pull_down div_str - just for i2c-enumeration */
+               dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
+
+               dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
+
+               /* set new i2c address and force divstart */
+               dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
+
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+       }
+
+       for (k = 0; k < no_of_demods; k++) {
+               st.cfg = cfg[k];
+               st.i2c_addr = (0x40 + k) << 1;
+
+               // unforce divstr
+               dib7000m_write_word(&st,1794, st.i2c_addr << 2);
+
+               /* deactivate div - it was just for i2c-enumeration */
+               dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(dib7000m_i2c_enumeration);
+#endif
+
+static struct dvb_frontend_ops dib7000m_ops;
+struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
+{
+       struct dvb_frontend *demod;
+       struct dib7000m_state *st;
+       st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
+       st->i2c_adap = i2c_adap;
+       st->i2c_addr = i2c_addr;
+
+       demod                   = &st->demod;
+       demod->demodulator_priv = st;
+       memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
+       mutex_init(&st->i2c_buffer_lock);
+
+       st->timf_default = cfg->bw->timf;
+
+       if (dib7000m_identify(st) != 0)
+               goto error;
+
+       if (st->revision == 0x4000)
+               dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
+       else
+               dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
+
+       dib7000m_demod_reset(st);
+
+       return demod;
+
+error:
+       kfree(st);
+       return NULL;
+}
+EXPORT_SYMBOL(dib7000m_attach);
+
+static struct dvb_frontend_ops dib7000m_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "DiBcom 7000MA/MB/PA/PB/MC",
+               .frequency_min      = 44250000,
+               .frequency_max      = 867250000,
+               .frequency_stepsize = 62500,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release              = dib7000m_release,
+
+       .init                 = dib7000m_wakeup,
+       .sleep                = dib7000m_sleep,
+
+       .set_frontend         = dib7000m_set_frontend,
+       .get_tune_settings    = dib7000m_fe_get_tune_settings,
+       .get_frontend         = dib7000m_get_frontend,
+
+       .read_status          = dib7000m_read_status,
+       .read_ber             = dib7000m_read_ber,
+       .read_signal_strength = dib7000m_read_signal_strength,
+       .read_snr             = dib7000m_read_snr,
+       .read_ucblocks        = dib7000m_read_unc_blocks,
+};
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib7000m.h b/drivers/media/dvb-frontends/dib7000m.h
new file mode 100644 (file)
index 0000000..81fcf22
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef DIB7000M_H
+#define DIB7000M_H
+
+#include "dibx000_common.h"
+
+struct dib7000m_config {
+       u8 dvbt_mode;
+       u8 output_mpeg2_in_188_bytes;
+       u8 hostbus_diversity;
+       u8 tuner_is_baseband;
+       u8 mobile_mode;
+       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
+
+       u8 agc_config_count;
+       struct dibx000_agc_config *agc;
+
+       struct dibx000_bandwidth_config *bw;
+
+#define DIB7000M_GPIO_DEFAULT_DIRECTIONS 0xffff
+       u16 gpio_dir;
+#define DIB7000M_GPIO_DEFAULT_VALUES     0x0000
+       u16 gpio_val;
+#define DIB7000M_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
+#define DIB7000M_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
+#define DIB7000M_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
+#define DIB7000M_GPIO_PWM_POS3(v)         (v & 0xf)
+#define DIB7000M_GPIO_DEFAULT_PWM_POS    0xffff
+       u16 gpio_pwm_pos;
+
+       u16 pwm_freq_div;
+
+       u8 quartz_direct;
+
+       u8 input_clk_is_div_2;
+
+       int (*agc_control) (struct dvb_frontend *, u8 before);
+};
+
+#define DEFAULT_DIB7000M_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
+                                    defined(MODULE))
+extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+                                           u8 i2c_addr,
+                                           struct dib7000m_config *cfg);
+extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
+                                                  enum dibx000_i2c_interface,
+                                                  int);
+extern int dib7000m_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
+#else
+static inline
+struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+                                    u8 i2c_addr, struct dib7000m_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline
+struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
+                                           enum dibx000_i2c_interface intf,
+                                           int gating)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id,
+                                               u16 pid, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe,
+                                               uint8_t onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+#endif
+
+/* TODO
+extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
+extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod);
+extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff);
+extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod);
+*/
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
new file mode 100644 (file)
index 0000000..3e1eefa
--- /dev/null
@@ -0,0 +1,2457 @@
+/*
+ * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_math.h"
+#include "dvb_frontend.h"
+
+#include "dib7000p.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+static int buggy_sfn_workaround;
+module_param(buggy_sfn_workaround, int, 0644);
+MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
+
+struct i2c_device {
+       struct i2c_adapter *i2c_adap;
+       u8 i2c_addr;
+};
+
+struct dib7000p_state {
+       struct dvb_frontend demod;
+       struct dib7000p_config cfg;
+
+       u8 i2c_addr;
+       struct i2c_adapter *i2c_adap;
+
+       struct dibx000_i2c_master i2c_master;
+
+       u16 wbd_ref;
+
+       u8 current_band;
+       u32 current_bandwidth;
+       struct dibx000_agc_config *current_agc;
+       u32 timf;
+
+       u8 div_force_off:1;
+       u8 div_state:1;
+       u16 div_sync_wait;
+
+       u8 agc_state;
+
+       u16 gpio_dir;
+       u16 gpio_val;
+
+       u8 sfn_workaround_active:1;
+
+#define SOC7090 0x7090
+       u16 version;
+
+       u16 tuner_enable;
+       struct i2c_adapter dib7090_tuner_adap;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[4];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+
+       u8 input_mode_mpeg;
+};
+
+enum dib7000p_power_mode {
+       DIB7000P_POWER_ALL = 0,
+       DIB7000P_POWER_ANALOG_ADC,
+       DIB7000P_POWER_INTERFACE_ONLY,
+};
+
+/* dib7090 specific fonctions */
+static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
+static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
+static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
+static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
+
+static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = reg >> 8;
+       state->i2c_write_buffer[1] = reg & 0xff;
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 2;
+       state->msg[1].addr = state->i2c_addr >> 1;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = state->i2c_read_buffer;
+       state->msg[1].len = 2;
+
+       if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+               dprintk("i2c read error on %d", reg);
+
+       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       state->i2c_write_buffer[1] = reg & 0xff;
+       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+       state->i2c_write_buffer[3] = val & 0xff;
+
+       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 4;
+
+       ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
+                       -EREMOTEIO : 0);
+       mutex_unlock(&state->i2c_buffer_lock);
+       return ret;
+}
+
+static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
+{
+       u16 l = 0, r, *n;
+       n = buf;
+       l = *n++;
+       while (l) {
+               r = *n++;
+
+               do {
+                       dib7000p_write_word(state, r, *n++);
+                       r++;
+               } while (--l);
+               l = *n++;
+       }
+}
+
+static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
+{
+       int ret = 0;
+       u16 outreg, fifo_threshold, smo_mode;
+
+       outreg = 0;
+       fifo_threshold = 1792;
+       smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
+
+       dprintk("setting output mode for demod %p to %d", &state->demod, mode);
+
+       switch (mode) {
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+               outreg = (1 << 10);     /* 0x0400 */
+               break;
+       case OUTMODE_MPEG2_PAR_CONT_CLK:
+               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
+               break;
+       case OUTMODE_MPEG2_SERIAL:
+               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0480 */
+               break;
+       case OUTMODE_DIVERSITY:
+               if (state->cfg.hostbus_diversity)
+                       outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
+               else
+                       outreg = (1 << 11);
+               break;
+       case OUTMODE_MPEG2_FIFO:
+               smo_mode |= (3 << 1);
+               fifo_threshold = 512;
+               outreg = (1 << 10) | (5 << 6);
+               break;
+       case OUTMODE_ANALOG_ADC:
+               outreg = (1 << 10) | (3 << 6);
+               break;
+       case OUTMODE_HIGH_Z:
+               outreg = 0;
+               break;
+       default:
+               dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
+               break;
+       }
+
+       if (state->cfg.output_mpeg2_in_188_bytes)
+               smo_mode |= (1 << 5);
+
+       ret |= dib7000p_write_word(state, 235, smo_mode);
+       ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
+       if (state->version != SOC7090)
+               ret |= dib7000p_write_word(state, 1286, outreg);        /* P_Div_active */
+
+       return ret;
+}
+
+static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+
+       if (state->div_force_off) {
+               dprintk("diversity combination deactivated - forced by COFDM parameters");
+               onoff = 0;
+               dib7000p_write_word(state, 207, 0);
+       } else
+               dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+
+       state->div_state = (u8) onoff;
+
+       if (onoff) {
+               dib7000p_write_word(state, 204, 6);
+               dib7000p_write_word(state, 205, 16);
+               /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
+       } else {
+               dib7000p_write_word(state, 204, 1);
+               dib7000p_write_word(state, 205, 0);
+       }
+
+       return 0;
+}
+
+static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
+{
+       /* by default everything is powered off */
+       u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
+
+       /* now, depending on the requested mode, we power on */
+       switch (mode) {
+               /* power up everything in the demod */
+       case DIB7000P_POWER_ALL:
+               reg_774 = 0x0000;
+               reg_775 = 0x0000;
+               reg_776 = 0x0;
+               reg_899 = 0x0;
+               if (state->version == SOC7090)
+                       reg_1280 &= 0x001f;
+               else
+                       reg_1280 &= 0x01ff;
+               break;
+
+       case DIB7000P_POWER_ANALOG_ADC:
+               /* dem, cfg, iqc, sad, agc */
+               reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
+               /* nud */
+               reg_776 &= ~((1 << 0));
+               /* Dout */
+               if (state->version != SOC7090)
+                       reg_1280 &= ~((1 << 11));
+               reg_1280 &= ~(1 << 6);
+               /* fall through wanted to enable the interfaces */
+
+               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
+       case DIB7000P_POWER_INTERFACE_ONLY:     /* TODO power up either SDIO or I2C */
+               if (state->version == SOC7090)
+                       reg_1280 &= ~((1 << 7) | (1 << 5));
+               else
+                       reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
+               break;
+
+/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
+       }
+
+       dib7000p_write_word(state, 774, reg_774);
+       dib7000p_write_word(state, 775, reg_775);
+       dib7000p_write_word(state, 776, reg_776);
+       dib7000p_write_word(state, 1280, reg_1280);
+       if (state->version != SOC7090)
+               dib7000p_write_word(state, 899, reg_899);
+
+       return 0;
+}
+
+static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
+{
+       u16 reg_908 = 0, reg_909 = 0;
+       u16 reg;
+
+       if (state->version != SOC7090) {
+               reg_908 = dib7000p_read_word(state, 908);
+               reg_909 = dib7000p_read_word(state, 909);
+       }
+
+       switch (no) {
+       case DIBX000_SLOW_ADC_ON:
+               if (state->version == SOC7090) {
+                       reg = dib7000p_read_word(state, 1925);
+
+                       dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2));    /* en_slowAdc = 1 & reset_sladc = 1 */
+
+                       reg = dib7000p_read_word(state, 1925);  /* read acces to make it works... strange ... */
+                       msleep(200);
+                       dib7000p_write_word(state, 1925, reg & ~(1 << 4));      /* en_slowAdc = 1 & reset_sladc = 0 */
+
+                       reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
+                       dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524);      /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
+               } else {
+                       reg_909 |= (1 << 1) | (1 << 0);
+                       dib7000p_write_word(state, 909, reg_909);
+                       reg_909 &= ~(1 << 1);
+               }
+               break;
+
+       case DIBX000_SLOW_ADC_OFF:
+               if (state->version == SOC7090) {
+                       reg = dib7000p_read_word(state, 1925);
+                       dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
+               } else
+                       reg_909 |= (1 << 1) | (1 << 0);
+               break;
+
+       case DIBX000_ADC_ON:
+               reg_908 &= 0x0fff;
+               reg_909 &= 0x0003;
+               break;
+
+       case DIBX000_ADC_OFF:
+               reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
+               reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+               break;
+
+       case DIBX000_VBG_ENABLE:
+               reg_908 &= ~(1 << 15);
+               break;
+
+       case DIBX000_VBG_DISABLE:
+               reg_908 |= (1 << 15);
+               break;
+
+       default:
+               break;
+       }
+
+//     dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
+
+       reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
+       reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
+
+       if (state->version != SOC7090) {
+               dib7000p_write_word(state, 908, reg_908);
+               dib7000p_write_word(state, 909, reg_909);
+       }
+}
+
+static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
+{
+       u32 timf;
+
+       // store the current bandwidth for later use
+       state->current_bandwidth = bw;
+
+       if (state->timf == 0) {
+               dprintk("using default timf");
+               timf = state->cfg.bw->timf;
+       } else {
+               dprintk("using updated timf");
+               timf = state->timf;
+       }
+
+       timf = timf * (bw / 50) / 160;
+
+       dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
+       dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
+
+       return 0;
+}
+
+static int dib7000p_sad_calib(struct dib7000p_state *state)
+{
+/* internal */
+       dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
+
+       if (state->version == SOC7090)
+               dib7000p_write_word(state, 74, 2048);
+       else
+               dib7000p_write_word(state, 74, 776);
+
+       /* do the calibration */
+       dib7000p_write_word(state, 73, (1 << 0));
+       dib7000p_write_word(state, 73, (0 << 0));
+
+       msleep(1);
+
+       return 0;
+}
+
+int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       if (value > 4095)
+               value = 4095;
+       state->wbd_ref = value;
+       return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
+}
+EXPORT_SYMBOL(dib7000p_set_wbd_ref);
+
+int dib7000p_get_agc_values(struct dvb_frontend *fe,
+               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+
+       if (agc_global != NULL)
+               *agc_global = dib7000p_read_word(state, 394);
+       if (agc1 != NULL)
+               *agc1 = dib7000p_read_word(state, 392);
+       if (agc2 != NULL)
+               *agc2 = dib7000p_read_word(state, 393);
+       if (wbd != NULL)
+               *wbd = dib7000p_read_word(state, 397);
+
+       return 0;
+}
+EXPORT_SYMBOL(dib7000p_get_agc_values);
+
+static void dib7000p_reset_pll(struct dib7000p_state *state)
+{
+       struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
+       u16 clk_cfg0;
+
+       if (state->version == SOC7090) {
+               dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
+
+               while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
+                       ;
+
+               dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
+       } else {
+               /* force PLL bypass */
+               clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
+                       (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
+
+               dib7000p_write_word(state, 900, clk_cfg0);
+
+               /* P_pll_cfg */
+               dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
+               clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
+               dib7000p_write_word(state, 900, clk_cfg0);
+       }
+
+       dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
+       dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
+       dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
+       dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
+
+       dib7000p_write_word(state, 72, bw->sad_cfg);
+}
+
+static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
+{
+       u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
+       internal |= (u32) dib7000p_read_word(state, 19);
+       internal /= 1000;
+
+       return internal;
+}
+
+int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
+       u8 loopdiv, prediv;
+       u32 internal, xtal;
+
+       /* get back old values */
+       prediv = reg_1856 & 0x3f;
+       loopdiv = (reg_1856 >> 6) & 0x3f;
+
+       if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
+               dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
+               reg_1856 &= 0xf000;
+               reg_1857 = dib7000p_read_word(state, 1857);
+               dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
+
+               dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
+
+               /* write new system clk into P_sec_len */
+               internal = dib7000p_get_internal_freq(state);
+               xtal = (internal / loopdiv) * prediv;
+               internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio;      /* new internal */
+               dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
+               dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
+
+               dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
+
+               while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
+                       dprintk("Waiting for PLL to lock");
+
+               return 0;
+       }
+       return -EIO;
+}
+EXPORT_SYMBOL(dib7000p_update_pll);
+
+static int dib7000p_reset_gpio(struct dib7000p_state *st)
+{
+       /* reset the GPIOs */
+       dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
+
+       dib7000p_write_word(st, 1029, st->gpio_dir);
+       dib7000p_write_word(st, 1030, st->gpio_val);
+
+       /* TODO 1031 is P_gpio_od */
+
+       dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
+
+       dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
+       return 0;
+}
+
+static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
+{
+       st->gpio_dir = dib7000p_read_word(st, 1029);
+       st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
+       st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
+       dib7000p_write_word(st, 1029, st->gpio_dir);
+
+       st->gpio_val = dib7000p_read_word(st, 1030);
+       st->gpio_val &= ~(1 << num);    /* reset the direction bit */
+       st->gpio_val |= (val & 0x01) << num;    /* set the new value */
+       dib7000p_write_word(st, 1030, st->gpio_val);
+
+       return 0;
+}
+
+int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       return dib7000p_cfg_gpio(state, num, dir, val);
+}
+EXPORT_SYMBOL(dib7000p_set_gpio);
+
+static u16 dib7000p_defaults[] = {
+       // auto search configuration
+       3, 2,
+       0x0004,
+       (1<<3)|(1<<11)|(1<<12)|(1<<13),
+       0x0814,                 /* Equal Lock */
+
+       12, 6,
+       0x001b,
+       0x7740,
+       0x005b,
+       0x8d80,
+       0x01c9,
+       0xc380,
+       0x0000,
+       0x0080,
+       0x0000,
+       0x0090,
+       0x0001,
+       0xd4c0,
+
+       1, 26,
+       0x6680,
+
+       /* set ADC level to -16 */
+       11, 79,
+       (1 << 13) - 825 - 117,
+       (1 << 13) - 837 - 117,
+       (1 << 13) - 811 - 117,
+       (1 << 13) - 766 - 117,
+       (1 << 13) - 737 - 117,
+       (1 << 13) - 693 - 117,
+       (1 << 13) - 648 - 117,
+       (1 << 13) - 619 - 117,
+       (1 << 13) - 575 - 117,
+       (1 << 13) - 531 - 117,
+       (1 << 13) - 501 - 117,
+
+       1, 142,
+       0x0410,
+
+       /* disable power smoothing */
+       8, 145,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+
+       1, 154,
+       1 << 13,
+
+       1, 168,
+       0x0ccd,
+
+       1, 183,
+       0x200f,
+
+       1, 212,
+               0x169,
+
+       5, 187,
+       0x023d,
+       0x00a4,
+       0x00a4,
+       0x7ff0,
+       0x3ccc,
+
+       1, 198,
+       0x800,
+
+       1, 222,
+       0x0010,
+
+       1, 235,
+       0x0062,
+
+       0,
+};
+
+static int dib7000p_demod_reset(struct dib7000p_state *state)
+{
+       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
+
+       if (state->version == SOC7090)
+               dibx000_reset_i2c_master(&state->i2c_master);
+
+       dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
+
+       /* restart all parts */
+       dib7000p_write_word(state, 770, 0xffff);
+       dib7000p_write_word(state, 771, 0xffff);
+       dib7000p_write_word(state, 772, 0x001f);
+       dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
+
+       dib7000p_write_word(state, 770, 0);
+       dib7000p_write_word(state, 771, 0);
+       dib7000p_write_word(state, 772, 0);
+       dib7000p_write_word(state, 1280, 0);
+
+       if (state->version != SOC7090) {
+               dib7000p_write_word(state,  898, 0x0003);
+               dib7000p_write_word(state,  898, 0);
+       }
+
+       /* default */
+       dib7000p_reset_pll(state);
+
+       if (dib7000p_reset_gpio(state) != 0)
+               dprintk("GPIO reset was not successful.");
+
+       if (state->version == SOC7090) {
+               dib7000p_write_word(state, 899, 0);
+
+               /* impulse noise */
+               dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
+               dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
+               dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
+               dib7000p_write_word(state, 273, (0<<6) | 30);
+       }
+       if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
+               dprintk("OUTPUT_MODE could not be reset.");
+
+       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+       dib7000p_sad_calib(state);
+       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+
+       /* unforce divstr regardless whether i2c enumeration was done or not */
+       dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
+
+       dib7000p_set_bandwidth(state, 8000);
+
+       if (state->version == SOC7090) {
+               dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
+       } else {
+               if (state->cfg.tuner_is_baseband)
+                       dib7000p_write_word(state, 36, 0x0755);
+               else
+                       dib7000p_write_word(state, 36, 0x1f55);
+       }
+
+       dib7000p_write_tab(state, dib7000p_defaults);
+       if (state->version != SOC7090) {
+               dib7000p_write_word(state, 901, 0x0006);
+               dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
+               dib7000p_write_word(state, 905, 0x2c8e);
+       }
+
+       dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
+
+       return 0;
+}
+
+static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
+{
+       u16 tmp = 0;
+       tmp = dib7000p_read_word(state, 903);
+       dib7000p_write_word(state, 903, (tmp | 0x1));
+       tmp = dib7000p_read_word(state, 900);
+       dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
+}
+
+static void dib7000p_restart_agc(struct dib7000p_state *state)
+{
+       // P_restart_iqc & P_restart_agc
+       dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
+       dib7000p_write_word(state, 770, 0x0000);
+}
+
+static int dib7000p_update_lna(struct dib7000p_state *state)
+{
+       u16 dyn_gain;
+
+       if (state->cfg.update_lna) {
+               dyn_gain = dib7000p_read_word(state, 394);
+               if (state->cfg.update_lna(&state->demod, dyn_gain)) {
+                       dib7000p_restart_agc(state);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
+{
+       struct dibx000_agc_config *agc = NULL;
+       int i;
+       if (state->current_band == band && state->current_agc != NULL)
+               return 0;
+       state->current_band = band;
+
+       for (i = 0; i < state->cfg.agc_config_count; i++)
+               if (state->cfg.agc[i].band_caps & band) {
+                       agc = &state->cfg.agc[i];
+                       break;
+               }
+
+       if (agc == NULL) {
+               dprintk("no valid AGC configuration found for band 0x%02x", band);
+               return -EINVAL;
+       }
+
+       state->current_agc = agc;
+
+       /* AGC */
+       dib7000p_write_word(state, 75, agc->setup);
+       dib7000p_write_word(state, 76, agc->inv_gain);
+       dib7000p_write_word(state, 77, agc->time_stabiliz);
+       dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
+
+       // Demod AGC loop configuration
+       dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
+       dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
+
+       /* AGC continued */
+       dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+       if (state->wbd_ref != 0)
+               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
+       else
+               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
+
+       dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
+
+       dib7000p_write_word(state, 107, agc->agc1_max);
+       dib7000p_write_word(state, 108, agc->agc1_min);
+       dib7000p_write_word(state, 109, agc->agc2_max);
+       dib7000p_write_word(state, 110, agc->agc2_min);
+       dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+       dib7000p_write_word(state, 112, agc->agc1_pt3);
+       dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+       dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+       dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+       return 0;
+}
+
+static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
+{
+       u32 internal = dib7000p_get_internal_freq(state);
+       s32 unit_khz_dds_val = 67108864 / (internal);   /* 2**26 / Fsampling is the unit 1KHz offset */
+       u32 abs_offset_khz = ABS(offset_khz);
+       u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
+       u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
+
+       dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
+
+       if (offset_khz < 0)
+               unit_khz_dds_val *= -1;
+
+       /* IF tuner */
+       if (invert)
+               dds -= (abs_offset_khz * unit_khz_dds_val);     /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
+       else
+               dds += (abs_offset_khz * unit_khz_dds_val);
+
+       if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
+               dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
+               dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
+       }
+}
+
+static int dib7000p_agc_startup(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000p_state *state = demod->demodulator_priv;
+       int ret = -1;
+       u8 *agc_state = &state->agc_state;
+       u8 agc_split;
+       u16 reg;
+       u32 upd_demod_gain_period = 0x1000;
+
+       switch (state->agc_state) {
+       case 0:
+               dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
+               if (state->version == SOC7090) {
+                       reg = dib7000p_read_word(state, 0x79b) & 0xff00;
+                       dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF);      /* lsb */
+                       dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
+
+                       /* enable adc i & q */
+                       reg = dib7000p_read_word(state, 0x780);
+                       dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
+               } else {
+                       dib7000p_set_adc_state(state, DIBX000_ADC_ON);
+                       dib7000p_pll_clk_cfg(state);
+               }
+
+               if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
+                       return -1;
+
+               dib7000p_set_dds(state, 0);
+               ret = 7;
+               (*agc_state)++;
+               break;
+
+       case 1:
+               if (state->cfg.agc_control)
+                       state->cfg.agc_control(&state->demod, 1);
+
+               dib7000p_write_word(state, 78, 32768);
+               if (!state->current_agc->perform_agc_softsplit) {
+                       /* we are using the wbd - so slow AGC startup */
+                       /* force 0 split on WBD and restart AGC */
+                       dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
+                       (*agc_state)++;
+                       ret = 5;
+               } else {
+                       /* default AGC startup */
+                       (*agc_state) = 4;
+                       /* wait AGC rough lock time */
+                       ret = 7;
+               }
+
+               dib7000p_restart_agc(state);
+               break;
+
+       case 2:         /* fast split search path after 5sec */
+               dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4));   /* freeze AGC loop */
+               dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8));     /* fast split search 0.25kHz */
+               (*agc_state)++;
+               ret = 14;
+               break;
+
+       case 3:         /* split search ended */
+               agc_split = (u8) dib7000p_read_word(state, 396);        /* store the split value for the next time */
+               dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
+
+               dib7000p_write_word(state, 75, state->current_agc->setup);      /* std AGC loop */
+               dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split);        /* standard split search */
+
+               dib7000p_restart_agc(state);
+
+               dprintk("SPLIT %p: %hd", demod, agc_split);
+
+               (*agc_state)++;
+               ret = 5;
+               break;
+
+       case 4:         /* LNA startup */
+               ret = 7;
+
+               if (dib7000p_update_lna(state))
+                       ret = 5;
+               else
+                       (*agc_state)++;
+               break;
+
+       case 5:
+               if (state->cfg.agc_control)
+                       state->cfg.agc_control(&state->demod, 0);
+               (*agc_state)++;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+static void dib7000p_update_timf(struct dib7000p_state *state)
+{
+       u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
+       state->timf = timf * 160 / (state->current_bandwidth / 50);
+       dib7000p_write_word(state, 23, (u16) (timf >> 16));
+       dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
+       dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
+
+}
+
+u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       switch (op) {
+       case DEMOD_TIMF_SET:
+               state->timf = timf;
+               break;
+       case DEMOD_TIMF_UPDATE:
+               dib7000p_update_timf(state);
+               break;
+       case DEMOD_TIMF_GET:
+               break;
+       }
+       dib7000p_set_bandwidth(state, state->current_bandwidth);
+       return state->timf;
+}
+EXPORT_SYMBOL(dib7000p_ctrl_timf);
+
+static void dib7000p_set_channel(struct dib7000p_state *state,
+                                struct dtv_frontend_properties *ch, u8 seq)
+{
+       u16 value, est[4];
+
+       dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+
+       /* nfft, guard, qam, alpha */
+       value = 0;
+       switch (ch->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               value |= (0 << 7);
+               break;
+       case TRANSMISSION_MODE_4K:
+               value |= (2 << 7);
+               break;
+       default:
+       case TRANSMISSION_MODE_8K:
+               value |= (1 << 7);
+               break;
+       }
+       switch (ch->guard_interval) {
+       case GUARD_INTERVAL_1_32:
+               value |= (0 << 5);
+               break;
+       case GUARD_INTERVAL_1_16:
+               value |= (1 << 5);
+               break;
+       case GUARD_INTERVAL_1_4:
+               value |= (3 << 5);
+               break;
+       default:
+       case GUARD_INTERVAL_1_8:
+               value |= (2 << 5);
+               break;
+       }
+       switch (ch->modulation) {
+       case QPSK:
+               value |= (0 << 3);
+               break;
+       case QAM_16:
+               value |= (1 << 3);
+               break;
+       default:
+       case QAM_64:
+               value |= (2 << 3);
+               break;
+       }
+       switch (HIERARCHY_1) {
+       case HIERARCHY_2:
+               value |= 2;
+               break;
+       case HIERARCHY_4:
+               value |= 4;
+               break;
+       default:
+       case HIERARCHY_1:
+               value |= 1;
+               break;
+       }
+       dib7000p_write_word(state, 0, value);
+       dib7000p_write_word(state, 5, (seq << 4) | 1);  /* do not force tps, search list 0 */
+
+       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
+       value = 0;
+       if (1 != 0)
+               value |= (1 << 6);
+       if (ch->hierarchy == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
+       case FEC_2_3:
+               value |= (2 << 1);
+               break;
+       case FEC_3_4:
+               value |= (3 << 1);
+               break;
+       case FEC_5_6:
+               value |= (5 << 1);
+               break;
+       case FEC_7_8:
+               value |= (7 << 1);
+               break;
+       default:
+       case FEC_1_2:
+               value |= (1 << 1);
+               break;
+       }
+       dib7000p_write_word(state, 208, value);
+
+       /* offset loop parameters */
+       dib7000p_write_word(state, 26, 0x6680);
+       dib7000p_write_word(state, 32, 0x0003);
+       dib7000p_write_word(state, 29, 0x1273);
+       dib7000p_write_word(state, 33, 0x0005);
+
+       /* P_dvsy_sync_wait */
+       switch (ch->transmission_mode) {
+       case TRANSMISSION_MODE_8K:
+               value = 256;
+               break;
+       case TRANSMISSION_MODE_4K:
+               value = 128;
+               break;
+       case TRANSMISSION_MODE_2K:
+       default:
+               value = 64;
+               break;
+       }
+       switch (ch->guard_interval) {
+       case GUARD_INTERVAL_1_16:
+               value *= 2;
+               break;
+       case GUARD_INTERVAL_1_8:
+               value *= 4;
+               break;
+       case GUARD_INTERVAL_1_4:
+               value *= 8;
+               break;
+       default:
+       case GUARD_INTERVAL_1_32:
+               value *= 1;
+               break;
+       }
+       if (state->cfg.diversity_delay == 0)
+               state->div_sync_wait = (value * 3) / 2 + 48;
+       else
+               state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
+
+       /* deactive the possibility of diversity reception if extended interleaver */
+       state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K;
+       dib7000p_set_diversity_in(&state->demod, state->div_state);
+
+       /* channel estimation fine configuration */
+       switch (ch->modulation) {
+       case QAM_64:
+               est[0] = 0x0148;        /* P_adp_regul_cnt 0.04 */
+               est[1] = 0xfff0;        /* P_adp_noise_cnt -0.002 */
+               est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
+               est[3] = 0xfff8;        /* P_adp_noise_ext -0.001 */
+               break;
+       case QAM_16:
+               est[0] = 0x023d;        /* P_adp_regul_cnt 0.07 */
+               est[1] = 0xffdf;        /* P_adp_noise_cnt -0.004 */
+               est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
+               est[3] = 0xfff0;        /* P_adp_noise_ext -0.002 */
+               break;
+       default:
+               est[0] = 0x099a;        /* P_adp_regul_cnt 0.3 */
+               est[1] = 0xffae;        /* P_adp_noise_cnt -0.01 */
+               est[2] = 0x0333;        /* P_adp_regul_ext 0.1 */
+               est[3] = 0xfff8;        /* P_adp_noise_ext -0.002 */
+               break;
+       }
+       for (value = 0; value < 4; value++)
+               dib7000p_write_word(state, 187 + value, est[value]);
+}
+
+static int dib7000p_autosearch_start(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000p_state *state = demod->demodulator_priv;
+       struct dtv_frontend_properties schan;
+       u32 value, factor;
+       u32 internal = dib7000p_get_internal_freq(state);
+
+       schan = *ch;
+       schan.modulation = QAM_64;
+       schan.guard_interval = GUARD_INTERVAL_1_32;
+       schan.transmission_mode = TRANSMISSION_MODE_8K;
+       schan.code_rate_HP = FEC_2_3;
+       schan.code_rate_LP = FEC_3_4;
+       schan.hierarchy = 0;
+
+       dib7000p_set_channel(state, &schan, 7);
+
+       factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
+       if (factor >= 5000) {
+               if (state->version == SOC7090)
+                       factor = 2;
+               else
+                       factor = 1;
+       } else
+               factor = 6;
+
+       value = 30 * internal * factor;
+       dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
+       dib7000p_write_word(state, 7, (u16) (value & 0xffff));
+       value = 100 * internal * factor;
+       dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
+       dib7000p_write_word(state, 9, (u16) (value & 0xffff));
+       value = 500 * internal * factor;
+       dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
+       dib7000p_write_word(state, 11, (u16) (value & 0xffff));
+
+       value = dib7000p_read_word(state, 0);
+       dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
+       dib7000p_read_word(state, 1284);
+       dib7000p_write_word(state, 0, (u16) value);
+
+       return 0;
+}
+
+static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       u16 irq_pending = dib7000p_read_word(state, 1284);
+
+       if (irq_pending & 0x1)
+               return 1;
+
+       if (irq_pending & 0x2)
+               return 2;
+
+       return 0;
+}
+
+static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
+{
+       static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
+       static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
+               24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
+               53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
+               82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
+               107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
+               128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
+               147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
+               166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
+               183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
+               199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
+               213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
+               225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
+               235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
+               244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
+               250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
+               254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+               255, 255, 255, 255, 255, 255
+       };
+
+       u32 xtal = state->cfg.bw->xtal_hz / 1000;
+       int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
+       int k;
+       int coef_re[8], coef_im[8];
+       int bw_khz = bw;
+       u32 pha;
+
+       dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
+
+       if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
+               return;
+
+       bw_khz /= 100;
+
+       dib7000p_write_word(state, 142, 0x0610);
+
+       for (k = 0; k < 8; k++) {
+               pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
+
+               if (pha == 0) {
+                       coef_re[k] = 256;
+                       coef_im[k] = 0;
+               } else if (pha < 256) {
+                       coef_re[k] = sine[256 - (pha & 0xff)];
+                       coef_im[k] = sine[pha & 0xff];
+               } else if (pha == 256) {
+                       coef_re[k] = 0;
+                       coef_im[k] = 256;
+               } else if (pha < 512) {
+                       coef_re[k] = -sine[pha & 0xff];
+                       coef_im[k] = sine[256 - (pha & 0xff)];
+               } else if (pha == 512) {
+                       coef_re[k] = -256;
+                       coef_im[k] = 0;
+               } else if (pha < 768) {
+                       coef_re[k] = -sine[256 - (pha & 0xff)];
+                       coef_im[k] = -sine[pha & 0xff];
+               } else if (pha == 768) {
+                       coef_re[k] = 0;
+                       coef_im[k] = -256;
+               } else {
+                       coef_re[k] = sine[pha & 0xff];
+                       coef_im[k] = -sine[256 - (pha & 0xff)];
+               }
+
+               coef_re[k] *= notch[k];
+               coef_re[k] += (1 << 14);
+               if (coef_re[k] >= (1 << 24))
+                       coef_re[k] = (1 << 24) - 1;
+               coef_re[k] /= (1 << 15);
+
+               coef_im[k] *= notch[k];
+               coef_im[k] += (1 << 14);
+               if (coef_im[k] >= (1 << 24))
+                       coef_im[k] = (1 << 24) - 1;
+               coef_im[k] /= (1 << 15);
+
+               dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
+
+               dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
+               dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
+               dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
+       }
+       dib7000p_write_word(state, 143, 0);
+}
+
+static int dib7000p_tune(struct dvb_frontend *demod)
+{
+       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
+       struct dib7000p_state *state = demod->demodulator_priv;
+       u16 tmp = 0;
+
+       if (ch != NULL)
+               dib7000p_set_channel(state, ch, 0);
+       else
+               return -EINVAL;
+
+       // restart demod
+       dib7000p_write_word(state, 770, 0x4000);
+       dib7000p_write_word(state, 770, 0x0000);
+       msleep(45);
+
+       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
+       tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
+       if (state->sfn_workaround_active) {
+               dprintk("SFN workaround is active");
+               tmp |= (1 << 9);
+               dib7000p_write_word(state, 166, 0x4000);
+       } else {
+               dib7000p_write_word(state, 166, 0x0000);
+       }
+       dib7000p_write_word(state, 29, tmp);
+
+       // never achieved a lock with that bandwidth so far - wait for osc-freq to update
+       if (state->timf == 0)
+               msleep(200);
+
+       /* offset loop parameters */
+
+       /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
+       tmp = (6 << 8) | 0x80;
+       switch (ch->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               tmp |= (2 << 12);
+               break;
+       case TRANSMISSION_MODE_4K:
+               tmp |= (3 << 12);
+               break;
+       default:
+       case TRANSMISSION_MODE_8K:
+               tmp |= (4 << 12);
+               break;
+       }
+       dib7000p_write_word(state, 26, tmp);    /* timf_a(6xxx) */
+
+       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
+       tmp = (0 << 4);
+       switch (ch->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               tmp |= 0x6;
+               break;
+       case TRANSMISSION_MODE_4K:
+               tmp |= 0x7;
+               break;
+       default:
+       case TRANSMISSION_MODE_8K:
+               tmp |= 0x8;
+               break;
+       }
+       dib7000p_write_word(state, 32, tmp);
+
+       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
+       tmp = (0 << 4);
+       switch (ch->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               tmp |= 0x6;
+               break;
+       case TRANSMISSION_MODE_4K:
+               tmp |= 0x7;
+               break;
+       default:
+       case TRANSMISSION_MODE_8K:
+               tmp |= 0x8;
+               break;
+       }
+       dib7000p_write_word(state, 33, tmp);
+
+       tmp = dib7000p_read_word(state, 509);
+       if (!((tmp >> 6) & 0x1)) {
+               /* restart the fec */
+               tmp = dib7000p_read_word(state, 771);
+               dib7000p_write_word(state, 771, tmp | (1 << 1));
+               dib7000p_write_word(state, 771, tmp);
+               msleep(40);
+               tmp = dib7000p_read_word(state, 509);
+       }
+       // we achieved a lock - it's time to update the osc freq
+       if ((tmp >> 6) & 0x1) {
+               dib7000p_update_timf(state);
+               /* P_timf_alpha += 2 */
+               tmp = dib7000p_read_word(state, 26);
+               dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
+       }
+
+       if (state->cfg.spur_protect)
+               dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+
+       dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+       return 0;
+}
+
+static int dib7000p_wakeup(struct dvb_frontend *demod)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
+       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+       if (state->version == SOC7090)
+               dib7000p_sad_calib(state);
+       return 0;
+}
+
+static int dib7000p_sleep(struct dvb_frontend *demod)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       if (state->version == SOC7090)
+               return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
+       return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
+}
+
+static int dib7000p_identify(struct dib7000p_state *st)
+{
+       u16 value;
+       dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
+
+       if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
+               dprintk("wrong Vendor ID (read=0x%x)", value);
+               return -EREMOTEIO;
+       }
+
+       if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
+               dprintk("wrong Device ID (%x)", value);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int dib7000p_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 tps = dib7000p_read_word(state, 463);
+
+       fep->inversion = INVERSION_AUTO;
+
+       fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
+
+       switch ((tps >> 8) & 0x3) {
+       case 0:
+               fep->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               fep->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
+       }
+
+       switch (tps & 0x3) {
+       case 0:
+               fep->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               fep->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               fep->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               fep->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       switch ((tps >> 14) & 0x3) {
+       case 0:
+               fep->modulation = QPSK;
+               break;
+       case 1:
+               fep->modulation = QAM_16;
+               break;
+       case 2:
+       default:
+               fep->modulation = QAM_64;
+               break;
+       }
+
+       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
+       /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
+
+       fep->hierarchy = HIERARCHY_NONE;
+       switch ((tps >> 5) & 0x7) {
+       case 1:
+               fep->code_rate_HP = FEC_1_2;
+               break;
+       case 2:
+               fep->code_rate_HP = FEC_2_3;
+               break;
+       case 3:
+               fep->code_rate_HP = FEC_3_4;
+               break;
+       case 5:
+               fep->code_rate_HP = FEC_5_6;
+               break;
+       case 7:
+       default:
+               fep->code_rate_HP = FEC_7_8;
+               break;
+
+       }
+
+       switch ((tps >> 2) & 0x7) {
+       case 1:
+               fep->code_rate_LP = FEC_1_2;
+               break;
+       case 2:
+               fep->code_rate_LP = FEC_2_3;
+               break;
+       case 3:
+               fep->code_rate_LP = FEC_3_4;
+               break;
+       case 5:
+               fep->code_rate_LP = FEC_5_6;
+               break;
+       case 7:
+       default:
+               fep->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       /* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
+
+       return 0;
+}
+
+static int dib7000p_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct dib7000p_state *state = fe->demodulator_priv;
+       int time, ret;
+
+       if (state->version == SOC7090)
+               dib7090_set_diversity_in(fe, 0);
+       else
+               dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
+
+       /* maybe the parameter has been changed */
+       state->sfn_workaround_active = buggy_sfn_workaround;
+
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       /* start up the AGC */
+       state->agc_state = 0;
+       do {
+               time = dib7000p_agc_startup(fe);
+               if (time != -1)
+                       msleep(time);
+       } while (time != -1);
+
+       if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
+               fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) {
+               int i = 800, found;
+
+               dib7000p_autosearch_start(fe);
+               do {
+                       msleep(1);
+                       found = dib7000p_autosearch_is_irq(fe);
+               } while (found == 0 && i--);
+
+               dprintk("autosearch returns: %d", found);
+               if (found == 0 || found == 1)
+                       return 0;
+
+               dib7000p_get_frontend(fe);
+       }
+
+       ret = dib7000p_tune(fe);
+
+       /* make this a config parameter */
+       if (state->version == SOC7090) {
+               dib7090_set_output_mode(fe, state->cfg.output_mode);
+               if (state->cfg.enMpegOutput == 0) {
+                       dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
+                       dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+               }
+       } else
+               dib7000p_set_output_mode(state, state->cfg.output_mode);
+
+       return ret;
+}
+
+static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 lock = dib7000p_read_word(state, 509);
+
+       *stat = 0;
+
+       if (lock & 0x8000)
+               *stat |= FE_HAS_SIGNAL;
+       if (lock & 0x3000)
+               *stat |= FE_HAS_CARRIER;
+       if (lock & 0x0100)
+               *stat |= FE_HAS_VITERBI;
+       if (lock & 0x0010)
+               *stat |= FE_HAS_SYNC;
+       if ((lock & 0x0038) == 0x38)
+               *stat |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
+       return 0;
+}
+
+static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       *unc = dib7000p_read_word(state, 506);
+       return 0;
+}
+
+static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 val = dib7000p_read_word(state, 394);
+       *strength = 65535 - val;
+       return 0;
+}
+
+static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 val;
+       s32 signal_mant, signal_exp, noise_mant, noise_exp;
+       u32 result = 0;
+
+       val = dib7000p_read_word(state, 479);
+       noise_mant = (val >> 4) & 0xff;
+       noise_exp = ((val & 0xf) << 2);
+       val = dib7000p_read_word(state, 480);
+       noise_exp += ((val >> 14) & 0x3);
+       if ((noise_exp & 0x20) != 0)
+               noise_exp -= 0x40;
+
+       signal_mant = (val >> 6) & 0xFF;
+       signal_exp = (val & 0x3F);
+       if ((signal_exp & 0x20) != 0)
+               signal_exp -= 0x40;
+
+       if (signal_mant != 0)
+               result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
+       else
+               result = intlog10(2) * 10 * signal_exp - 100;
+
+       if (noise_mant != 0)
+               result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
+       else
+               result -= intlog10(2) * 10 * noise_exp - 100;
+
+       *snr = result / ((1 << 24) / 10);
+       return 0;
+}
+
+static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void dib7000p_release(struct dvb_frontend *demod)
+{
+       struct dib7000p_state *st = demod->demodulator_priv;
+       dibx000_exit_i2c_master(&st->i2c_master);
+       i2c_del_adapter(&st->dib7090_tuner_adap);
+       kfree(st);
+}
+
+int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+       u8 *tx, *rx;
+       struct i2c_msg msg[2] = {
+               {.addr = 18 >> 1, .flags = 0, .len = 2},
+               {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
+       };
+       int ret = 0;
+
+       tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
+       if (!tx)
+               return -ENOMEM;
+       rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
+       if (!rx) {
+               ret = -ENOMEM;
+               goto rx_memory_error;
+       }
+
+       msg[0].buf = tx;
+       msg[1].buf = rx;
+
+       tx[0] = 0x03;
+       tx[1] = 0x00;
+
+       if (i2c_transfer(i2c_adap, msg, 2) == 2)
+               if (rx[0] == 0x01 && rx[1] == 0xb3) {
+                       dprintk("-D-  DiB7000PC detected");
+                       return 1;
+               }
+
+       msg[0].addr = msg[1].addr = 0x40;
+
+       if (i2c_transfer(i2c_adap, msg, 2) == 2)
+               if (rx[0] == 0x01 && rx[1] == 0xb3) {
+                       dprintk("-D-  DiB7000PC detected");
+                       return 1;
+               }
+
+       dprintk("-D-  DiB7000PC not detected");
+
+       kfree(rx);
+rx_memory_error:
+       kfree(tx);
+       return ret;
+}
+EXPORT_SYMBOL(dib7000pc_detection);
+
+struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
+{
+       struct dib7000p_state *st = demod->demodulator_priv;
+       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+EXPORT_SYMBOL(dib7000p_get_i2c_master);
+
+int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 val = dib7000p_read_word(state, 235) & 0xffef;
+       val |= (onoff & 0x1) << 4;
+       dprintk("PID filter enabled %d", onoff);
+       return dib7000p_write_word(state, 235, val);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
+
+int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
+       return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter);
+
+int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
+{
+       struct dib7000p_state *dpst;
+       int k = 0;
+       u8 new_addr = 0;
+
+       dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
+       if (!dpst)
+               return -ENOMEM;
+
+       dpst->i2c_adap = i2c;
+       mutex_init(&dpst->i2c_buffer_lock);
+
+       for (k = no_of_demods - 1; k >= 0; k--) {
+               dpst->cfg = cfg[k];
+
+               /* designated i2c address */
+               if (cfg[k].default_i2c_addr != 0)
+                       new_addr = cfg[k].default_i2c_addr + (k << 1);
+               else
+                       new_addr = (0x40 + k) << 1;
+               dpst->i2c_addr = new_addr;
+               dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
+               if (dib7000p_identify(dpst) != 0) {
+                       dpst->i2c_addr = default_addr;
+                       dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
+                       if (dib7000p_identify(dpst) != 0) {
+                               dprintk("DiB7000P #%d: not identified\n", k);
+                               kfree(dpst);
+                               return -EIO;
+                       }
+               }
+
+               /* start diversity to pull_down div_str - just for i2c-enumeration */
+               dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
+
+               /* set new i2c address and force divstart */
+               dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
+
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+       }
+
+       for (k = 0; k < no_of_demods; k++) {
+               dpst->cfg = cfg[k];
+               if (cfg[k].default_i2c_addr != 0)
+                       dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
+               else
+                       dpst->i2c_addr = (0x40 + k) << 1;
+
+               // unforce divstr
+               dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
+
+               /* deactivate div - it was just for i2c-enumeration */
+               dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
+       }
+
+       kfree(dpst);
+       return 0;
+}
+EXPORT_SYMBOL(dib7000p_i2c_enumeration);
+
+static const s32 lut_1000ln_mant[] = {
+       6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
+};
+
+static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u32 tmp_val = 0, exp = 0, mant = 0;
+       s32 pow_i;
+       u16 buf[2];
+       u8 ix = 0;
+
+       buf[0] = dib7000p_read_word(state, 0x184);
+       buf[1] = dib7000p_read_word(state, 0x185);
+       pow_i = (buf[0] << 16) | buf[1];
+       dprintk("raw pow_i = %d", pow_i);
+
+       tmp_val = pow_i;
+       while (tmp_val >>= 1)
+               exp++;
+
+       mant = (pow_i * 1000 / (1 << exp));
+       dprintk(" mant = %d exp = %d", mant / 1000, exp);
+
+       ix = (u8) ((mant - 1000) / 100);        /* index of the LUT */
+       dprintk(" ix = %d", ix);
+
+       pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
+       pow_i = (pow_i << 8) / 1000;
+       dprintk(" pow_i = %d", pow_i);
+
+       return pow_i;
+}
+
+static int map_addr_to_serpar_number(struct i2c_msg *msg)
+{
+       if ((msg->buf[0] <= 15))
+               msg->buf[0] -= 1;
+       else if (msg->buf[0] == 17)
+               msg->buf[0] = 15;
+       else if (msg->buf[0] == 16)
+               msg->buf[0] = 17;
+       else if (msg->buf[0] == 19)
+               msg->buf[0] = 16;
+       else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
+               msg->buf[0] -= 3;
+       else if (msg->buf[0] == 28)
+               msg->buf[0] = 23;
+       else
+               return -EINVAL;
+       return 0;
+}
+
+static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
+       u8 n_overflow = 1;
+       u16 i = 1000;
+       u16 serpar_num = msg[0].buf[0];
+
+       while (n_overflow == 1 && i) {
+               n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
+               i--;
+               if (i == 0)
+                       dprintk("Tuner ITF: write busy (overflow)");
+       }
+       dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
+       dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
+
+       return num;
+}
+
+static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
+       u8 n_overflow = 1, n_empty = 1;
+       u16 i = 1000;
+       u16 serpar_num = msg[0].buf[0];
+       u16 read_word;
+
+       while (n_overflow == 1 && i) {
+               n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
+               i--;
+               if (i == 0)
+                       dprintk("TunerITF: read busy (overflow)");
+       }
+       dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
+
+       i = 1000;
+       while (n_empty == 1 && i) {
+               n_empty = dib7000p_read_word(state, 1984) & 0x1;
+               i--;
+               if (i == 0)
+                       dprintk("TunerITF: read busy (empty)");
+       }
+       read_word = dib7000p_read_word(state, 1987);
+       msg[1].buf[0] = (read_word >> 8) & 0xff;
+       msg[1].buf[1] = (read_word) & 0xff;
+
+       return num;
+}
+
+static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       if (map_addr_to_serpar_number(&msg[0]) == 0) {  /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
+               if (num == 1) { /* write */
+                       return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
+               } else {        /* read */
+                       return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
+               }
+       }
+       return num;
+}
+
+static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num, u16 apb_address)
+{
+       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
+       u16 word;
+
+       if (num == 1) {         /* write */
+               dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
+       } else {
+               word = dib7000p_read_word(state, apb_address);
+               msg[1].buf[0] = (word >> 8) & 0xff;
+               msg[1].buf[1] = (word) & 0xff;
+       }
+
+       return num;
+}
+
+static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
+
+       u16 apb_address = 0, word;
+       int i = 0;
+       switch (msg[0].buf[0]) {
+       case 0x12:
+               apb_address = 1920;
+               break;
+       case 0x14:
+               apb_address = 1921;
+               break;
+       case 0x24:
+               apb_address = 1922;
+               break;
+       case 0x1a:
+               apb_address = 1923;
+               break;
+       case 0x22:
+               apb_address = 1924;
+               break;
+       case 0x33:
+               apb_address = 1926;
+               break;
+       case 0x34:
+               apb_address = 1927;
+               break;
+       case 0x35:
+               apb_address = 1928;
+               break;
+       case 0x36:
+               apb_address = 1929;
+               break;
+       case 0x37:
+               apb_address = 1930;
+               break;
+       case 0x38:
+               apb_address = 1931;
+               break;
+       case 0x39:
+               apb_address = 1932;
+               break;
+       case 0x2a:
+               apb_address = 1935;
+               break;
+       case 0x2b:
+               apb_address = 1936;
+               break;
+       case 0x2c:
+               apb_address = 1937;
+               break;
+       case 0x2d:
+               apb_address = 1938;
+               break;
+       case 0x2e:
+               apb_address = 1939;
+               break;
+       case 0x2f:
+               apb_address = 1940;
+               break;
+       case 0x30:
+               apb_address = 1941;
+               break;
+       case 0x31:
+               apb_address = 1942;
+               break;
+       case 0x32:
+               apb_address = 1943;
+               break;
+       case 0x3e:
+               apb_address = 1944;
+               break;
+       case 0x3f:
+               apb_address = 1945;
+               break;
+       case 0x40:
+               apb_address = 1948;
+               break;
+       case 0x25:
+               apb_address = 914;
+               break;
+       case 0x26:
+               apb_address = 915;
+               break;
+       case 0x27:
+               apb_address = 917;
+               break;
+       case 0x28:
+               apb_address = 916;
+               break;
+       case 0x1d:
+               i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
+               word = dib7000p_read_word(state, 384 + i);
+               msg[1].buf[0] = (word >> 8) & 0xff;
+               msg[1].buf[1] = (word) & 0xff;
+               return num;
+       case 0x1f:
+               if (num == 1) { /* write */
+                       word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
+                       word &= 0x3;
+                       word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
+                       dib7000p_write_word(state, 72, word);   /* Set the proper input */
+                       return num;
+               }
+       }
+
+       if (apb_address != 0)   /* R/W acces via APB */
+               return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
+       else                    /* R/W access via SERPAR  */
+               return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
+
+       return 0;
+}
+
+static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dib7090_tuner_xfer_algo = {
+       .master_xfer = dib7090_tuner_xfer,
+       .functionality = dib7000p_i2c_func,
+};
+
+struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
+{
+       struct dib7000p_state *st = fe->demodulator_priv;
+       return &st->dib7090_tuner_adap;
+}
+EXPORT_SYMBOL(dib7090_get_i2c_tuner);
+
+static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
+{
+       u16 reg;
+
+       /* drive host bus 2, 3, 4 */
+       reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive << 12) | (drive << 6) | drive;
+       dib7000p_write_word(state, 1798, reg);
+
+       /* drive host bus 5,6 */
+       reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
+       reg |= (drive << 8) | (drive << 2);
+       dib7000p_write_word(state, 1799, reg);
+
+       /* drive host bus 7, 8, 9 */
+       reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive << 12) | (drive << 6) | drive;
+       dib7000p_write_word(state, 1800, reg);
+
+       /* drive host bus 10, 11 */
+       reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
+       reg |= (drive << 8) | (drive << 2);
+       dib7000p_write_word(state, 1801, reg);
+
+       /* drive host bus 12, 13, 14 */
+       reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive << 12) | (drive << 6) | drive;
+       dib7000p_write_word(state, 1802, reg);
+
+       return 0;
+}
+
+static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
+{
+       u32 quantif = 3;
+       u32 nom = (insertExtSynchro * P_Kin + syncSize);
+       u32 denom = P_Kout;
+       u32 syncFreq = ((nom << quantif) / denom);
+
+       if ((syncFreq & ((1 << quantif) - 1)) != 0)
+               syncFreq = (syncFreq >> quantif) + 1;
+       else
+               syncFreq = (syncFreq >> quantif);
+
+       if (syncFreq != 0)
+               syncFreq = syncFreq - 1;
+
+       return syncFreq;
+}
+
+static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
+{
+       dprintk("Configure DibStream Tx");
+
+       dib7000p_write_word(state, 1615, 1);
+       dib7000p_write_word(state, 1603, P_Kin);
+       dib7000p_write_word(state, 1605, P_Kout);
+       dib7000p_write_word(state, 1606, insertExtSynchro);
+       dib7000p_write_word(state, 1608, synchroMode);
+       dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
+       dib7000p_write_word(state, 1610, syncWord & 0xffff);
+       dib7000p_write_word(state, 1612, syncSize);
+       dib7000p_write_word(state, 1615, 0);
+
+       return 0;
+}
+
+static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
+               u32 dataOutRate)
+{
+       u32 syncFreq;
+
+       dprintk("Configure DibStream Rx");
+       if ((P_Kin != 0) && (P_Kout != 0)) {
+               syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
+               dib7000p_write_word(state, 1542, syncFreq);
+       }
+       dib7000p_write_word(state, 1554, 1);
+       dib7000p_write_word(state, 1536, P_Kin);
+       dib7000p_write_word(state, 1537, P_Kout);
+       dib7000p_write_word(state, 1539, synchroMode);
+       dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
+       dib7000p_write_word(state, 1541, syncWord & 0xffff);
+       dib7000p_write_word(state, 1543, syncSize);
+       dib7000p_write_word(state, 1544, dataOutRate);
+       dib7000p_write_word(state, 1554, 0);
+
+       return 0;
+}
+
+static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
+{
+       u16 reg_1287 = dib7000p_read_word(state, 1287);
+
+       switch (onoff) {
+       case 1:
+                       reg_1287 &= ~(1<<7);
+                       break;
+       case 0:
+                       reg_1287 |= (1<<7);
+                       break;
+       }
+
+       dib7000p_write_word(state, 1287, reg_1287);
+}
+
+static void dib7090_configMpegMux(struct dib7000p_state *state,
+               u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
+{
+       dprintk("Enable Mpeg mux");
+
+       dib7090_enMpegMux(state, 0);
+
+       /* If the input mode is MPEG do not divide the serial clock */
+       if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
+               enSerialClkDiv2 = 0;
+
+       dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
+                       | ((enSerialMode & 0x1) << 1)
+                       | (enSerialClkDiv2 & 0x1));
+
+       dib7090_enMpegMux(state, 1);
+}
+
+static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
+{
+       u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
+
+       switch (mode) {
+       case MPEG_ON_DIBTX:
+                       dprintk("SET MPEG ON DIBSTREAM TX");
+                       dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
+                       reg_1288 |= (1<<9);
+                       break;
+       case DIV_ON_DIBTX:
+                       dprintk("SET DIV_OUT ON DIBSTREAM TX");
+                       dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
+                       reg_1288 |= (1<<8);
+                       break;
+       case ADC_ON_DIBTX:
+                       dprintk("SET ADC_OUT ON DIBSTREAM TX");
+                       dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
+                       reg_1288 |= (1<<7);
+                       break;
+       default:
+                       break;
+       }
+       dib7000p_write_word(state, 1288, reg_1288);
+}
+
+static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
+{
+       u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
+
+       switch (mode) {
+       case DEMOUT_ON_HOSTBUS:
+                       dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
+                       dib7090_enMpegMux(state, 0);
+                       reg_1288 |= (1<<6);
+                       break;
+       case DIBTX_ON_HOSTBUS:
+                       dprintk("SET DIBSTREAM TX ON HOST BUS");
+                       dib7090_enMpegMux(state, 0);
+                       reg_1288 |= (1<<5);
+                       break;
+       case MPEG_ON_HOSTBUS:
+                       dprintk("SET MPEG MUX ON HOST BUS");
+                       reg_1288 |= (1<<4);
+                       break;
+       default:
+                       break;
+       }
+       dib7000p_write_word(state, 1288, reg_1288);
+}
+
+int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 reg_1287;
+
+       switch (onoff) {
+       case 0: /* only use the internal way - not the diversity input */
+                       dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__);
+                       dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
+
+                       /* Do not divide the serial clock of MPEG MUX */
+                       /* in SERIAL MODE in case input mode MPEG is used */
+                       reg_1287 = dib7000p_read_word(state, 1287);
+                       /* enSerialClkDiv2 == 1 ? */
+                       if ((reg_1287 & 0x1) == 1) {
+                               /* force enSerialClkDiv2 = 0 */
+                               reg_1287 &= ~0x1;
+                               dib7000p_write_word(state, 1287, reg_1287);
+                       }
+                       state->input_mode_mpeg = 1;
+                       break;
+       case 1: /* both ways */
+       case 2: /* only the diversity input */
+                       dprintk("%s ON : Enable diversity INPUT", __func__);
+                       dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
+                       state->input_mode_mpeg = 0;
+                       break;
+       }
+
+       dib7000p_set_diversity_in(&state->demod, onoff);
+       return 0;
+}
+
+static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+
+       u16 outreg, smo_mode, fifo_threshold;
+       u8 prefer_mpeg_mux_use = 1;
+       int ret = 0;
+
+       dib7090_host_bus_drive(state, 1);
+
+       fifo_threshold = 1792;
+       smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
+       outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
+
+       switch (mode) {
+       case OUTMODE_HIGH_Z:
+               outreg = 0;
+               break;
+
+       case OUTMODE_MPEG2_SERIAL:
+               if (prefer_mpeg_mux_use) {
+                       dprintk("setting output mode TS_SERIAL using Mpeg Mux");
+                       dib7090_configMpegMux(state, 3, 1, 1);
+                       dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
+               } else {/* Use Smooth block */
+                       dprintk("setting output mode TS_SERIAL using Smooth bloc");
+                       dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+                       outreg |= (2<<6) | (0 << 1);
+               }
+               break;
+
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+               if (prefer_mpeg_mux_use) {
+                       dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
+                       dib7090_configMpegMux(state, 2, 0, 0);
+                       dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
+               } else { /* Use Smooth block */
+                       dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
+                       dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+                       outreg |= (0<<6);
+               }
+               break;
+
+       case OUTMODE_MPEG2_PAR_CONT_CLK:        /* Using Smooth block only */
+               dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
+               dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+               outreg |= (1<<6);
+               break;
+
+       case OUTMODE_MPEG2_FIFO:        /* Using Smooth block because not supported by new Mpeg Mux bloc */
+               dprintk("setting output mode TS_FIFO using Smooth block");
+               dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+               outreg |= (5<<6);
+               smo_mode |= (3 << 1);
+               fifo_threshold = 512;
+               break;
+
+       case OUTMODE_DIVERSITY:
+               dprintk("setting output mode MODE_DIVERSITY");
+               dib7090_setDibTxMux(state, DIV_ON_DIBTX);
+               dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+               break;
+
+       case OUTMODE_ANALOG_ADC:
+               dprintk("setting output mode MODE_ANALOG_ADC");
+               dib7090_setDibTxMux(state, ADC_ON_DIBTX);
+               dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+               break;
+       }
+       if (mode != OUTMODE_HIGH_Z)
+               outreg |= (1 << 10);
+
+       if (state->cfg.output_mpeg2_in_188_bytes)
+               smo_mode |= (1 << 5);
+
+       ret |= dib7000p_write_word(state, 235, smo_mode);
+       ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
+       ret |= dib7000p_write_word(state, 1286, outreg);
+
+       return ret;
+}
+
+int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 en_cur_state;
+
+       dprintk("sleep dib7090: %d", onoff);
+
+       en_cur_state = dib7000p_read_word(state, 1922);
+
+       if (en_cur_state > 0xff)
+               state->tuner_enable = en_cur_state;
+
+       if (onoff)
+               en_cur_state &= 0x00ff;
+       else {
+               if (state->tuner_enable != 0)
+                       en_cur_state = state->tuner_enable;
+       }
+
+       dib7000p_write_word(state, 1922, en_cur_state);
+
+       return 0;
+}
+EXPORT_SYMBOL(dib7090_tuner_sleep);
+
+int dib7090_get_adc_power(struct dvb_frontend *fe)
+{
+       return dib7000p_get_adc_power(fe);
+}
+EXPORT_SYMBOL(dib7090_get_adc_power);
+
+int dib7090_slave_reset(struct dvb_frontend *fe)
+{
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 reg;
+
+       reg = dib7000p_read_word(state, 1794);
+       dib7000p_write_word(state, 1794, reg | (4 << 12));
+
+       dib7000p_write_word(state, 1032, 0xffff);
+       return 0;
+}
+EXPORT_SYMBOL(dib7090_slave_reset);
+
+static struct dvb_frontend_ops dib7000p_ops;
+struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
+{
+       struct dvb_frontend *demod;
+       struct dib7000p_state *st;
+       st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+
+       memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
+       st->i2c_adap = i2c_adap;
+       st->i2c_addr = i2c_addr;
+       st->gpio_val = cfg->gpio_val;
+       st->gpio_dir = cfg->gpio_dir;
+
+       /* Ensure the output mode remains at the previous default if it's
+        * not specifically set by the caller.
+        */
+       if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
+               st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
+       demod = &st->demod;
+       demod->demodulator_priv = st;
+       memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
+       mutex_init(&st->i2c_buffer_lock);
+
+       dib7000p_write_word(st, 1287, 0x0003);  /* sram lead in, rdy */
+
+       if (dib7000p_identify(st) != 0)
+               goto error;
+
+       st->version = dib7000p_read_word(st, 897);
+
+       /* FIXME: make sure the dev.parent field is initialized, or else
+          request_firmware() will hit an OOPS (this should be moved somewhere
+          more common) */
+       st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
+
+       dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
+
+       /* init 7090 tuner adapter */
+       strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
+       st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
+       st->dib7090_tuner_adap.algo_data = NULL;
+       st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
+       i2c_set_adapdata(&st->dib7090_tuner_adap, st);
+       i2c_add_adapter(&st->dib7090_tuner_adap);
+
+       dib7000p_demod_reset(st);
+
+       if (st->version == SOC7090) {
+               dib7090_set_output_mode(demod, st->cfg.output_mode);
+               dib7090_set_diversity_in(demod, 0);
+       }
+
+       return demod;
+
+error:
+       kfree(st);
+       return NULL;
+}
+EXPORT_SYMBOL(dib7000p_attach);
+
+static struct dvb_frontend_ops dib7000p_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+                .name = "DiBcom 7000PC",
+                .frequency_min = 44250000,
+                .frequency_max = 867250000,
+                .frequency_stepsize = 62500,
+                .caps = FE_CAN_INVERSION_AUTO |
+                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+                },
+
+       .release = dib7000p_release,
+
+       .init = dib7000p_wakeup,
+       .sleep = dib7000p_sleep,
+
+       .set_frontend = dib7000p_set_frontend,
+       .get_tune_settings = dib7000p_fe_get_tune_settings,
+       .get_frontend = dib7000p_get_frontend,
+
+       .read_status = dib7000p_read_status,
+       .read_ber = dib7000p_read_ber,
+       .read_signal_strength = dib7000p_read_signal_strength,
+       .read_snr = dib7000p_read_snr,
+       .read_ucblocks = dib7000p_read_unc_blocks,
+};
+
+MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib7000p.h b/drivers/media/dvb-frontends/dib7000p.h
new file mode 100644 (file)
index 0000000..b61b03a
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef DIB7000P_H
+#define DIB7000P_H
+
+#include "dibx000_common.h"
+
+struct dib7000p_config {
+       u8 output_mpeg2_in_188_bytes;
+       u8 hostbus_diversity;
+       u8 tuner_is_baseband;
+       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
+
+       u8 agc_config_count;
+       struct dibx000_agc_config *agc;
+       struct dibx000_bandwidth_config *bw;
+
+#define DIB7000P_GPIO_DEFAULT_DIRECTIONS 0xffff
+       u16 gpio_dir;
+#define DIB7000P_GPIO_DEFAULT_VALUES     0x0000
+       u16 gpio_val;
+#define DIB7000P_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
+#define DIB7000P_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
+#define DIB7000P_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
+#define DIB7000P_GPIO_PWM_POS3(v)         (v & 0xf)
+#define DIB7000P_GPIO_DEFAULT_PWM_POS    0xffff
+       u16 gpio_pwm_pos;
+
+       u16 pwm_freq_div;
+
+       u8 quartz_direct;
+
+       u8 spur_protect;
+
+       int (*agc_control) (struct dvb_frontend *, u8 before);
+
+       u8 output_mode;
+       u8 disable_sample_and_hold:1;
+
+       u8 enable_current_mirror:1;
+       u16 diversity_delay;
+
+       u8 default_i2c_addr;
+       u8 enMpegOutput:1;
+};
+
+#define DEFAULT_DIB7000P_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
+                                       defined(MODULE))
+extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
+extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
+extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
+extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
+extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
+extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
+extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
+extern int dib7090_get_adc_power(struct dvb_frontend *fe);
+extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
+extern int dib7090_slave_reset(struct dvb_frontend *fe);
+extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
+               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
+#else
+static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+
+static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib7090_slave_reset(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
+               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
new file mode 100644 (file)
index 0000000..1f3bcb5
--- /dev/null
@@ -0,0 +1,3560 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
+ *
+ * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License as
+ *  published by the Free Software Foundation, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_math.h"
+
+#include "dvb_frontend.h"
+
+#include "dib8000.h"
+
+#define LAYER_ALL -1
+#define LAYER_A   1
+#define LAYER_B   2
+#define LAYER_C   3
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+#define MAX_NUMBER_OF_FRONTENDS 6
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
+
+#define FE_STATUS_TUNE_FAILED 0
+
+struct i2c_device {
+       struct i2c_adapter *adap;
+       u8 addr;
+       u8 *i2c_write_buffer;
+       u8 *i2c_read_buffer;
+       struct mutex *i2c_buffer_lock;
+};
+
+struct dib8000_state {
+       struct dib8000_config cfg;
+
+       struct i2c_device i2c;
+
+       struct dibx000_i2c_master i2c_master;
+
+       u16 wbd_ref;
+
+       u8 current_band;
+       u32 current_bandwidth;
+       struct dibx000_agc_config *current_agc;
+       u32 timf;
+       u32 timf_default;
+
+       u8 div_force_off:1;
+       u8 div_state:1;
+       u16 div_sync_wait;
+
+       u8 agc_state;
+       u8 differential_constellation;
+       u8 diversity_onoff;
+
+       s16 ber_monitored_layer;
+       u16 gpio_dir;
+       u16 gpio_val;
+
+       u16 revision;
+       u8 isdbt_cfg_loaded;
+       enum frontend_tune_state tune_state;
+       u32 status;
+
+       struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[4];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+       u8 input_mode_mpeg;
+
+       u16 tuner_enable;
+       struct i2c_adapter dib8096p_tuner_adap;
+};
+
+enum dib8000_power_mode {
+       DIB8000_POWER_ALL = 0,
+       DIB8000_POWER_INTERFACE_ONLY,
+};
+
+static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
+{
+       u16 ret;
+       struct i2c_msg msg[2] = {
+               {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
+               {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
+       };
+
+       if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       msg[0].buf    = i2c->i2c_write_buffer;
+       msg[0].buf[0] = reg >> 8;
+       msg[0].buf[1] = reg & 0xff;
+       msg[1].buf    = i2c->i2c_read_buffer;
+
+       if (i2c_transfer(i2c->adap, msg, 2) != 2)
+               dprintk("i2c read error on %d", reg);
+
+       ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
+       mutex_unlock(i2c->i2c_buffer_lock);
+       return ret;
+}
+
+static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       state->i2c_write_buffer[0] = reg >> 8;
+       state->i2c_write_buffer[1] = reg & 0xff;
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c.addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 2;
+       state->msg[1].addr = state->i2c.addr >> 1;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = state->i2c_read_buffer;
+       state->msg[1].len = 2;
+
+       if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
+               dprintk("i2c read error on %d", reg);
+
+       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+       mutex_unlock(&state->i2c_buffer_lock);
+
+       return ret;
+}
+
+static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
+{
+       u16 rw[2];
+
+       rw[0] = dib8000_read_word(state, reg + 0);
+       rw[1] = dib8000_read_word(state, reg + 1);
+
+       return ((rw[0] << 16) | (rw[1]));
+}
+
+static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
+{
+       struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
+       int ret = 0;
+
+       if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       msg.buf    = i2c->i2c_write_buffer;
+       msg.buf[0] = (reg >> 8) & 0xff;
+       msg.buf[1] = reg & 0xff;
+       msg.buf[2] = (val >> 8) & 0xff;
+       msg.buf[3] = val & 0xff;
+
+       ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+       mutex_unlock(i2c->i2c_buffer_lock);
+
+       return ret;
+}
+
+static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       state->i2c_write_buffer[1] = reg & 0xff;
+       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+       state->i2c_write_buffer[3] = val & 0xff;
+
+       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c.addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 4;
+
+       ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
+                       -EREMOTEIO : 0);
+       mutex_unlock(&state->i2c_buffer_lock);
+
+       return ret;
+}
+
+static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
+       (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
+               (920 << 5) | 0x09
+};
+
+static const s16 coeff_2k_sb_1seg[8] = {
+       (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
+};
+
+static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
+       (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
+               (-931 << 5) | 0x0f
+};
+
+static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
+       (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
+               (982 << 5) | 0x0c
+};
+
+static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
+       (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
+               (-720 << 5) | 0x0d
+};
+
+static const s16 coeff_2k_sb_3seg[8] = {
+       (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
+               (-610 << 5) | 0x0a
+};
+
+static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
+       (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
+               (-922 << 5) | 0x0d
+};
+
+static const s16 coeff_4k_sb_1seg[8] = {
+       (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
+               (-655 << 5) | 0x0a
+};
+
+static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
+       (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
+               (-958 << 5) | 0x13
+};
+
+static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
+       (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
+               (-568 << 5) | 0x0f
+};
+
+static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
+       (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
+               (-848 << 5) | 0x13
+};
+
+static const s16 coeff_4k_sb_3seg[8] = {
+       (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
+               (-869 << 5) | 0x13
+};
+
+static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
+       (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
+               (-598 << 5) | 0x10
+};
+
+static const s16 coeff_8k_sb_1seg[8] = {
+       (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
+               (585 << 5) | 0x0f
+};
+
+static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
+       (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
+               (0 << 5) | 0x14
+};
+
+static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
+       (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
+               (-877 << 5) | 0x15
+};
+
+static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
+       (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
+               (-921 << 5) | 0x14
+};
+
+static const s16 coeff_8k_sb_3seg[8] = {
+       (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
+               (690 << 5) | 0x14
+};
+
+static const s16 ana_fe_coeff_3seg[24] = {
+       81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
+};
+
+static const s16 ana_fe_coeff_1seg[24] = {
+       249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
+};
+
+static const s16 ana_fe_coeff_13seg[24] = {
+       396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
+};
+
+static u16 fft_to_mode(struct dib8000_state *state)
+{
+       u16 mode;
+       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               mode = 1;
+               break;
+       case TRANSMISSION_MODE_4K:
+               mode = 2;
+               break;
+       default:
+       case TRANSMISSION_MODE_AUTO:
+       case TRANSMISSION_MODE_8K:
+               mode = 3;
+               break;
+       }
+       return mode;
+}
+
+static void dib8000_set_acquisition_mode(struct dib8000_state *state)
+{
+       u16 nud = dib8000_read_word(state, 298);
+       nud |= (1 << 3) | (1 << 0);
+       dprintk("acquisition mode activated");
+       dib8000_write_word(state, 298, nud);
+}
+static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;    /* by default SDRAM deintlv is enabled */
+
+       outreg = 0;
+       fifo_threshold = 1792;
+       smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
+
+       dprintk("-I-    Setting output mode for demod %p to %d",
+                       &state->fe[0], mode);
+
+       switch (mode) {
+       case OUTMODE_MPEG2_PAR_GATED_CLK:       // STBs with parallel gated clock
+               outreg = (1 << 10);     /* 0x0400 */
+               break;
+       case OUTMODE_MPEG2_PAR_CONT_CLK:        // STBs with parallel continues clock
+               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
+               break;
+       case OUTMODE_MPEG2_SERIAL:      // STBs with serial input
+               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
+               break;
+       case OUTMODE_DIVERSITY:
+               if (state->cfg.hostbus_diversity) {
+                       outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
+                       sram &= 0xfdff;
+               } else
+                       sram |= 0x0c00;
+               break;
+       case OUTMODE_MPEG2_FIFO:        // e.g. USB feeding
+               smo_mode |= (3 << 1);
+               fifo_threshold = 512;
+               outreg = (1 << 10) | (5 << 6);
+               break;
+       case OUTMODE_HIGH_Z:    // disable
+               outreg = 0;
+               break;
+
+       case OUTMODE_ANALOG_ADC:
+               outreg = (1 << 10) | (3 << 6);
+               dib8000_set_acquisition_mode(state);
+               break;
+
+       default:
+               dprintk("Unhandled output_mode passed to be set for demod %p",
+                               &state->fe[0]);
+               return -EINVAL;
+       }
+
+       if (state->cfg.output_mpeg2_in_188_bytes)
+               smo_mode |= (1 << 5);
+
+       dib8000_write_word(state, 299, smo_mode);
+       dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
+       dib8000_write_word(state, 1286, outreg);
+       dib8000_write_word(state, 1291, sram);
+
+       return 0;
+}
+
+static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
+
+       if (!state->differential_constellation) {
+               dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
+               dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);       // sync_enable = 1; comb_mode = 2
+       } else {
+               dib8000_write_word(state, 272, 0);      //dvsy_off_lmod4 = 0
+               dib8000_write_word(state, 273, sync_wait);      // sync_enable = 0; comb_mode = 0
+       }
+       state->diversity_onoff = onoff;
+
+       switch (onoff) {
+       case 0:         /* only use the internal way - not the diversity input */
+               dib8000_write_word(state, 270, 1);
+               dib8000_write_word(state, 271, 0);
+               break;
+       case 1:         /* both ways */
+               dib8000_write_word(state, 270, 6);
+               dib8000_write_word(state, 271, 6);
+               break;
+       case 2:         /* only the diversity input */
+               dib8000_write_word(state, 270, 0);
+               dib8000_write_word(state, 271, 1);
+               break;
+       }
+       return 0;
+}
+
+static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
+{
+       /* by default everything is going to be powered off */
+       u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
+               reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
+               reg_1280;
+
+       if (state->revision != 0x8090)
+               reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
+       else
+               reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
+
+       /* now, depending on the requested mode, we power on */
+       switch (mode) {
+               /* power up everything in the demod */
+       case DIB8000_POWER_ALL:
+               reg_774 = 0x0000;
+               reg_775 = 0x0000;
+               reg_776 = 0x0000;
+               reg_900 &= 0xfffc;
+               if (state->revision != 0x8090)
+                       reg_1280 &= 0x00ff;
+               else
+                       reg_1280 &= 0x707f;
+               break;
+       case DIB8000_POWER_INTERFACE_ONLY:
+               if (state->revision != 0x8090)
+                       reg_1280 &= 0x00ff;
+               else
+                       reg_1280 &= 0xfa7b;
+               break;
+       }
+
+       dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
+       dib8000_write_word(state, 774, reg_774);
+       dib8000_write_word(state, 775, reg_775);
+       dib8000_write_word(state, 776, reg_776);
+       dib8000_write_word(state, 900, reg_900);
+       dib8000_write_word(state, 1280, reg_1280);
+}
+
+static int dib8000_init_sdram(struct dib8000_state *state)
+{
+       u16 reg = 0;
+       dprintk("Init sdram");
+
+       reg = dib8000_read_word(state, 274)&0xfff0;
+       /* P_dintlv_delay_ram = 7 because of MobileSdram */
+       dib8000_write_word(state, 274, reg | 0x7);
+
+       dib8000_write_word(state, 1803, (7<<2));
+
+       reg = dib8000_read_word(state, 1280);
+       /* force restart P_restart_sdram */
+       dib8000_write_word(state, 1280,  reg | (1<<2));
+
+       /* release restart P_restart_sdram */
+       dib8000_write_word(state, 1280,  reg);
+
+       return 0;
+}
+
+static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
+{
+       int ret = 0;
+       u16 reg, reg_907 = dib8000_read_word(state, 907);
+       u16 reg_908 = dib8000_read_word(state, 908);
+
+       switch (no) {
+       case DIBX000_SLOW_ADC_ON:
+               if (state->revision != 0x8090) {
+                       reg_908 |= (1 << 1) | (1 << 0);
+                       ret |= dib8000_write_word(state, 908, reg_908);
+                       reg_908 &= ~(1 << 1);
+               } else {
+                       reg = dib8000_read_word(state, 1925);
+                       /* en_slowAdc = 1 & reset_sladc = 1 */
+                       dib8000_write_word(state, 1925, reg |
+                                       (1<<4) | (1<<2));
+
+                       /* read acces to make it works... strange ... */
+                       reg = dib8000_read_word(state, 1925);
+                       msleep(20);
+                       /* en_slowAdc = 1 & reset_sladc = 0 */
+                       dib8000_write_word(state, 1925, reg & ~(1<<4));
+
+                       reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
+                                       | (0x3 << 12));
+                       /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
+                          (Vin2 = Vcm) */
+                       dib8000_write_word(state, 921, reg | (1 << 14)
+                                       | (3 << 12));
+               }
+               break;
+
+       case DIBX000_SLOW_ADC_OFF:
+               if (state->revision == 0x8090) {
+                       reg = dib8000_read_word(state, 1925);
+                       /* reset_sladc = 1 en_slowAdc = 0 */
+                       dib8000_write_word(state, 1925,
+                                       (reg & ~(1<<2)) | (1<<4));
+               }
+               reg_908 |= (1 << 1) | (1 << 0);
+               break;
+
+       case DIBX000_ADC_ON:
+               reg_907 &= 0x0fff;
+               reg_908 &= 0x0003;
+               break;
+
+       case DIBX000_ADC_OFF:   // leave the VBG voltage on
+               reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
+               reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+               break;
+
+       case DIBX000_VBG_ENABLE:
+               reg_907 &= ~(1 << 15);
+               break;
+
+       case DIBX000_VBG_DISABLE:
+               reg_907 |= (1 << 15);
+               break;
+
+       default:
+               break;
+       }
+
+       ret |= dib8000_write_word(state, 907, reg_907);
+       ret |= dib8000_write_word(state, 908, reg_908);
+
+       return ret;
+}
+
+static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u32 timf;
+
+       if (bw == 0)
+               bw = 6000;
+
+       if (state->timf == 0) {
+               dprintk("using default timf");
+               timf = state->timf_default;
+       } else {
+               dprintk("using updated timf");
+               timf = state->timf;
+       }
+
+       dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
+       dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
+
+       return 0;
+}
+
+static int dib8000_sad_calib(struct dib8000_state *state)
+{
+       if (state->revision == 0x8090) {
+               dprintk("%s: the sad calibration is not needed for the dib8096P",
+                               __func__);
+               return 0;
+       }
+       /* internal */
+       dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
+       dib8000_write_word(state, 924, 776);    // 0.625*3.3 / 4096
+
+       /* do the calibration */
+       dib8000_write_word(state, 923, (1 << 0));
+       dib8000_write_word(state, 923, (0 << 0));
+
+       msleep(1);
+       return 0;
+}
+
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       if (value > 4095)
+               value = 4095;
+       state->wbd_ref = value;
+       return dib8000_write_word(state, 106, value);
+}
+
+EXPORT_SYMBOL(dib8000_set_wbd_ref);
+static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
+{
+       dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
+       if (state->revision != 0x8090) {
+               dib8000_write_word(state, 23,
+                               (u16) (((bw->internal * 1000) >> 16) & 0xffff));
+               dib8000_write_word(state, 24,
+                               (u16) ((bw->internal * 1000) & 0xffff));
+       } else {
+               dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
+               dib8000_write_word(state, 24,
+                               (u16) ((bw->internal  / 2 * 1000) & 0xffff));
+       }
+       dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
+       dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
+       dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
+
+       if (state->revision != 0x8090)
+               dib8000_write_word(state, 922, bw->sad_cfg);
+}
+
+static void dib8000_reset_pll(struct dib8000_state *state)
+{
+       const struct dibx000_bandwidth_config *pll = state->cfg.pll;
+       u16 clk_cfg1, reg;
+
+       if (state->revision != 0x8090) {
+               dib8000_write_word(state, 901,
+                               (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
+
+               clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
+                       (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
+                       (1 << 3) | (pll->pll_range << 1) |
+                       (pll->pll_reset << 0);
+
+               dib8000_write_word(state, 902, clk_cfg1);
+               clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
+               dib8000_write_word(state, 902, clk_cfg1);
+
+               dprintk("clk_cfg1: 0x%04x", clk_cfg1);
+
+               /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
+               if (state->cfg.pll->ADClkSrc == 0)
+                       dib8000_write_word(state, 904,
+                                       (0 << 15) | (0 << 12) | (0 << 10) |
+                                       (pll->modulo << 8) |
+                                       (pll->ADClkSrc << 7) | (0 << 1));
+               else if (state->cfg.refclksel != 0)
+                       dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
+                                       ((state->cfg.refclksel & 0x3) << 10) |
+                                       (pll->modulo << 8) |
+                                       (pll->ADClkSrc << 7) | (0 << 1));
+               else
+                       dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
+                                       (3 << 10) | (pll->modulo << 8) |
+                                       (pll->ADClkSrc << 7) | (0 << 1));
+       } else {
+               dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
+                               (pll->pll_range<<12) | (pll->pll_ratio<<6) |
+                               (pll->pll_prediv));
+
+               reg = dib8000_read_word(state, 1857);
+               dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
+
+               reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
+               dib8000_write_word(state, 1858, reg | 1);
+
+               dib8000_write_word(state, 904, (pll->modulo << 8));
+       }
+
+       dib8000_reset_pll_common(state, pll);
+}
+
+int dib8000_update_pll(struct dvb_frontend *fe,
+               struct dibx000_bandwidth_config *pll)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
+       u8 loopdiv, prediv;
+       u32 internal, xtal;
+
+       /* get back old values */
+       prediv = reg_1856 & 0x3f;
+       loopdiv = (reg_1856 >> 6) & 0x3f;
+
+       if ((pll != NULL) && (pll->pll_prediv != prediv ||
+                               pll->pll_ratio != loopdiv)) {
+               dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
+               reg_1856 &= 0xf000;
+               reg_1857 = dib8000_read_word(state, 1857);
+               /* disable PLL */
+               dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
+
+               dib8000_write_word(state, 1856, reg_1856 |
+                               ((pll->pll_ratio & 0x3f) << 6) |
+                               (pll->pll_prediv & 0x3f));
+
+               /* write new system clk into P_sec_len */
+               internal = dib8000_read32(state, 23) / 1000;
+               dprintk("Old Internal = %d", internal);
+               xtal = 2 * (internal / loopdiv) * prediv;
+               internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
+               dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
+               dprintk("New Internal = %d", internal);
+
+               dib8000_write_word(state, 23,
+                               (u16) (((internal / 2) >> 16) & 0xffff));
+               dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
+               /* enable PLL */
+               dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
+
+               while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
+                       dprintk("Waiting for PLL to lock");
+
+               /* verify */
+               reg_1856 = dib8000_read_word(state, 1856);
+               dprintk("PLL Updated with prediv = %d and loopdiv = %d",
+                               reg_1856&0x3f, (reg_1856>>6)&0x3f);
+
+               return 0;
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(dib8000_update_pll);
+
+
+static int dib8000_reset_gpio(struct dib8000_state *st)
+{
+       /* reset the GPIOs */
+       dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+       dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+       /* TODO 782 is P_gpio_od */
+
+       dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
+
+       dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
+       return 0;
+}
+
+static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
+{
+       st->cfg.gpio_dir = dib8000_read_word(st, 1029);
+       st->cfg.gpio_dir &= ~(1 << num);        /* reset the direction bit */
+       st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
+       dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+
+       st->cfg.gpio_val = dib8000_read_word(st, 1030);
+       st->cfg.gpio_val &= ~(1 << num);        /* reset the direction bit */
+       st->cfg.gpio_val |= (val & 0x01) << num;        /* set the new value */
+       dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+       dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
+
+       return 0;
+}
+
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       return dib8000_cfg_gpio(state, num, dir, val);
+}
+
+EXPORT_SYMBOL(dib8000_set_gpio);
+static const u16 dib8000_defaults[] = {
+       /* auto search configuration - lock0 by default waiting
+        * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
+       3, 7,
+       0x0004,
+       0x0400,
+       0x0814,
+
+       12, 11,
+       0x001b,
+       0x7740,
+       0x005b,
+       0x8d80,
+       0x01c9,
+       0xc380,
+       0x0000,
+       0x0080,
+       0x0000,
+       0x0090,
+       0x0001,
+       0xd4c0,
+
+       /*1, 32,
+               0x6680 // P_corm_thres Lock algorithms configuration */
+
+       11, 80,                 /* set ADC level to -16 */
+       (1 << 13) - 825 - 117,
+       (1 << 13) - 837 - 117,
+       (1 << 13) - 811 - 117,
+       (1 << 13) - 766 - 117,
+       (1 << 13) - 737 - 117,
+       (1 << 13) - 693 - 117,
+       (1 << 13) - 648 - 117,
+       (1 << 13) - 619 - 117,
+       (1 << 13) - 575 - 117,
+       (1 << 13) - 531 - 117,
+       (1 << 13) - 501 - 117,
+
+       4, 108,
+       0,
+       0,
+       0,
+       0,
+
+       1, 175,
+       0x0410,
+       1, 179,
+       8192,                   // P_fft_nb_to_cut
+
+       6, 181,
+       0x2800,                 // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
+       0x2800,
+       0x2800,
+       0x2800,                 // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
+       0x2800,
+       0x2800,
+
+       2, 193,
+       0x0666,                 // P_pha3_thres
+       0x0000,                 // P_cti_use_cpe, P_cti_use_prog
+
+       2, 205,
+       0x200f,                 // P_cspu_regul, P_cspu_win_cut
+       0x000f,                 // P_des_shift_work
+
+       5, 215,
+       0x023d,                 // P_adp_regul_cnt
+       0x00a4,                 // P_adp_noise_cnt
+       0x00a4,                 // P_adp_regul_ext
+       0x7ff0,                 // P_adp_noise_ext
+       0x3ccc,                 // P_adp_fil
+
+       1, 230,
+       0x0000,                 // P_2d_byp_ti_num
+
+       1, 263,
+       0x800,                  //P_equal_thres_wgn
+
+       1, 268,
+       (2 << 9) | 39,          // P_equal_ctrl_synchro, P_equal_speedmode
+
+       1, 270,
+       0x0001,                 // P_div_lock0_wait
+       1, 285,
+       0x0020,                 //p_fec_
+       1, 299,
+       0x0062,                 /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
+
+       1, 338,
+       (1 << 12) |             // P_ctrl_corm_thres4pre_freq_inh=1
+               (1 << 10) |
+               (0 << 9) |              /* P_ctrl_pre_freq_inh=0 */
+               (3 << 5) |              /* P_ctrl_pre_freq_step=3 */
+               (1 << 0),               /* P_pre_freq_win_len=1 */
+
+       0,
+};
+
+static u16 dib8000_identify(struct i2c_device *client)
+{
+       u16 value;
+
+       //because of glitches sometimes
+       value = dib8000_i2c_read16(client, 896);
+
+       if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
+               dprintk("wrong Vendor ID (read=0x%x)", value);
+               return 0;
+       }
+
+       value = dib8000_i2c_read16(client, 897);
+       if (value != 0x8000 && value != 0x8001 &&
+                       value != 0x8002 && value != 0x8090) {
+               dprintk("wrong Device ID (%x)", value);
+               return 0;
+       }
+
+       switch (value) {
+       case 0x8000:
+               dprintk("found DiB8000A");
+               break;
+       case 0x8001:
+               dprintk("found DiB8000B");
+               break;
+       case 0x8002:
+               dprintk("found DiB8000C");
+               break;
+       case 0x8090:
+               dprintk("found DiB8096P");
+               break;
+       }
+       return value;
+}
+
+static int dib8000_reset(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       if ((state->revision = dib8000_identify(&state->i2c)) == 0)
+               return -EINVAL;
+
+       /* sram lead in, rdy */
+       if (state->revision != 0x8090)
+               dib8000_write_word(state, 1287, 0x0003);
+
+       if (state->revision == 0x8000)
+               dprintk("error : dib8000 MA not supported");
+
+       dibx000_reset_i2c_master(&state->i2c_master);
+
+       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
+
+       /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
+       dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
+
+       /* restart all parts */
+       dib8000_write_word(state, 770, 0xffff);
+       dib8000_write_word(state, 771, 0xffff);
+       dib8000_write_word(state, 772, 0xfffc);
+       if (state->revision == 0x8090)
+               dib8000_write_word(state, 1280, 0x0045);
+       else
+               dib8000_write_word(state, 1280, 0x004d);
+       dib8000_write_word(state, 1281, 0x000c);
+
+       dib8000_write_word(state, 770, 0x0000);
+       dib8000_write_word(state, 771, 0x0000);
+       dib8000_write_word(state, 772, 0x0000);
+       dib8000_write_word(state, 898, 0x0004); // sad
+       dib8000_write_word(state, 1280, 0x0000);
+       dib8000_write_word(state, 1281, 0x0000);
+
+       /* drives */
+       if (state->revision != 0x8090) {
+               if (state->cfg.drives)
+                       dib8000_write_word(state, 906, state->cfg.drives);
+               else {
+                       dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
+                       /* min drive SDRAM - not optimal - adjust */
+                       dib8000_write_word(state, 906, 0x2d98);
+               }
+       }
+
+       dib8000_reset_pll(state);
+       if (state->revision != 0x8090)
+               dib8000_write_word(state, 898, 0x0004);
+
+       if (dib8000_reset_gpio(state) != 0)
+               dprintk("GPIO reset was not successful.");
+
+       if ((state->revision != 0x8090) &&
+                       (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
+               dprintk("OUTPUT_MODE could not be resetted.");
+
+       state->current_agc = NULL;
+
+       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
+       /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
+       if (state->cfg.pll->ifreq == 0)
+               dib8000_write_word(state, 40, 0x0755);  /* P_iqc_corr_inh = 0 enable IQcorr block */
+       else
+               dib8000_write_word(state, 40, 0x1f55);  /* P_iqc_corr_inh = 1 disable IQcorr block */
+
+       {
+               u16 l = 0, r;
+               const u16 *n;
+               n = dib8000_defaults;
+               l = *n++;
+               while (l) {
+                       r = *n++;
+                       do {
+                               dib8000_write_word(state, r, *n++);
+                               r++;
+                       } while (--l);
+                       l = *n++;
+               }
+       }
+       if (state->revision != 0x8090)
+               dib8000_write_word(state, 903, (0 << 4) | 2);
+       state->isdbt_cfg_loaded = 0;
+
+       //div_cfg override for special configs
+       if (state->cfg.div_cfg != 0)
+               dib8000_write_word(state, 903, state->cfg.div_cfg);
+
+       /* unforce divstr regardless whether i2c enumeration was done or not */
+       dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
+
+       dib8000_set_bandwidth(fe, 6000);
+
+       dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+       if (state->revision != 0x8090) {
+               dib8000_sad_calib(state);
+               dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+       }
+
+       dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
+
+       return 0;
+}
+
+static void dib8000_restart_agc(struct dib8000_state *state)
+{
+       // P_restart_iqc & P_restart_agc
+       dib8000_write_word(state, 770, 0x0a00);
+       dib8000_write_word(state, 770, 0x0000);
+}
+
+static int dib8000_update_lna(struct dib8000_state *state)
+{
+       u16 dyn_gain;
+
+       if (state->cfg.update_lna) {
+               // read dyn_gain here (because it is demod-dependent and not tuner)
+               dyn_gain = dib8000_read_word(state, 390);
+
+               if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
+                       dib8000_restart_agc(state);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
+{
+       struct dibx000_agc_config *agc = NULL;
+       int i;
+       u16 reg;
+
+       if (state->current_band == band && state->current_agc != NULL)
+               return 0;
+       state->current_band = band;
+
+       for (i = 0; i < state->cfg.agc_config_count; i++)
+               if (state->cfg.agc[i].band_caps & band) {
+                       agc = &state->cfg.agc[i];
+                       break;
+               }
+
+       if (agc == NULL) {
+               dprintk("no valid AGC configuration found for band 0x%02x", band);
+               return -EINVAL;
+       }
+
+       state->current_agc = agc;
+
+       /* AGC */
+       dib8000_write_word(state, 76, agc->setup);
+       dib8000_write_word(state, 77, agc->inv_gain);
+       dib8000_write_word(state, 78, agc->time_stabiliz);
+       dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
+
+       // Demod AGC loop configuration
+       dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
+       dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
+
+       dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+       /* AGC continued */
+       if (state->wbd_ref != 0)
+               dib8000_write_word(state, 106, state->wbd_ref);
+       else                    // use default
+               dib8000_write_word(state, 106, agc->wbd_ref);
+
+       if (state->revision == 0x8090) {
+               reg = dib8000_read_word(state, 922) & (0x3 << 2);
+               dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
+       }
+
+       dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
+       dib8000_write_word(state, 108, agc->agc1_max);
+       dib8000_write_word(state, 109, agc->agc1_min);
+       dib8000_write_word(state, 110, agc->agc2_max);
+       dib8000_write_word(state, 111, agc->agc2_min);
+       dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+       dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+       dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+       dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+       dib8000_write_word(state, 75, agc->agc1_pt3);
+       if (state->revision != 0x8090)
+               dib8000_write_word(state, 923,
+                               (dib8000_read_word(state, 923) & 0xffe3) |
+                               (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
+
+       return 0;
+}
+
+void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       dib8000_set_adc_state(state, DIBX000_ADC_ON);
+       dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
+}
+EXPORT_SYMBOL(dib8000_pwm_agc_reset);
+
+static int dib8000_agc_soft_split(struct dib8000_state *state)
+{
+       u16 agc, split_offset;
+
+       if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
+               return FE_CALLBACK_TIME_NEVER;
+
+       // n_agc_global
+       agc = dib8000_read_word(state, 390);
+
+       if (agc > state->current_agc->split.min_thres)
+               split_offset = state->current_agc->split.min;
+       else if (agc < state->current_agc->split.max_thres)
+               split_offset = state->current_agc->split.max;
+       else
+               split_offset = state->current_agc->split.max *
+                       (agc - state->current_agc->split.min_thres) /
+                       (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
+
+       dprintk("AGC split_offset: %d", split_offset);
+
+       // P_agc_force_split and P_agc_split_offset
+       dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
+       return 5000;
+}
+
+static int dib8000_agc_startup(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       enum frontend_tune_state *tune_state = &state->tune_state;
+       int ret = 0;
+       u16 reg, upd_demod_gain_period = 0x8000;
+
+       switch (*tune_state) {
+       case CT_AGC_START:
+               // set power-up level: interf+analog+AGC
+
+               if (state->revision != 0x8090)
+                       dib8000_set_adc_state(state, DIBX000_ADC_ON);
+               else {
+                       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
+
+                       reg = dib8000_read_word(state, 1947)&0xff00;
+                       dib8000_write_word(state, 1946,
+                                       upd_demod_gain_period & 0xFFFF);
+                       /* bit 14 = enDemodGain */
+                       dib8000_write_word(state, 1947, reg | (1<<14) |
+                                       ((upd_demod_gain_period >> 16) & 0xFF));
+
+                       /* enable adc i & q */
+                       reg = dib8000_read_word(state, 1920);
+                       dib8000_write_word(state, 1920, (reg | 0x3) &
+                                       (~(1 << 7)));
+               }
+
+               if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
+                       *tune_state = CT_AGC_STOP;
+                       state->status = FE_STATUS_TUNE_FAILED;
+                       break;
+               }
+
+               ret = 70;
+               *tune_state = CT_AGC_STEP_0;
+               break;
+
+       case CT_AGC_STEP_0:
+               //AGC initialization
+               if (state->cfg.agc_control)
+                       state->cfg.agc_control(fe, 1);
+
+               dib8000_restart_agc(state);
+
+               // wait AGC rough lock time
+               ret = 50;
+               *tune_state = CT_AGC_STEP_1;
+               break;
+
+       case CT_AGC_STEP_1:
+               // wait AGC accurate lock time
+               ret = 70;
+
+               if (dib8000_update_lna(state))
+                       // wait only AGC rough lock time
+                       ret = 50;
+               else
+                       *tune_state = CT_AGC_STEP_2;
+               break;
+
+       case CT_AGC_STEP_2:
+               dib8000_agc_soft_split(state);
+
+               if (state->cfg.agc_control)
+                       state->cfg.agc_control(fe, 0);
+
+               *tune_state = CT_AGC_STOP;
+               break;
+       default:
+               ret = dib8000_agc_soft_split(state);
+               break;
+       }
+       return ret;
+
+}
+
+static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
+{
+       u16 reg;
+
+       drive &= 0x7;
+
+       /* drive host bus 2, 3, 4 */
+       reg = dib8000_read_word(state, 1798) &
+               ~(0x7 | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive<<12) | (drive<<6) | drive;
+       dib8000_write_word(state, 1798, reg);
+
+       /* drive host bus 5,6 */
+       reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
+       reg |= (drive<<8) | (drive<<2);
+       dib8000_write_word(state, 1799, reg);
+
+       /* drive host bus 7, 8, 9 */
+       reg = dib8000_read_word(state, 1800) &
+               ~(0x7 | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive<<12) | (drive<<6) | drive;
+       dib8000_write_word(state, 1800, reg);
+
+       /* drive host bus 10, 11 */
+       reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
+       reg |= (drive<<8) | (drive<<2);
+       dib8000_write_word(state, 1801, reg);
+
+       /* drive host bus 12, 13, 14 */
+       reg = dib8000_read_word(state, 1802) &
+               ~(0x7 | (0x7 << 6) | (0x7 << 12));
+       reg |= (drive<<12) | (drive<<6) | drive;
+       dib8000_write_word(state, 1802, reg);
+}
+
+static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
+               u32 insertExtSynchro, u32 syncSize)
+{
+       u32 quantif = 3;
+       u32 nom = (insertExtSynchro * P_Kin+syncSize);
+       u32 denom = P_Kout;
+       u32 syncFreq = ((nom << quantif) / denom);
+
+       if ((syncFreq & ((1 << quantif) - 1)) != 0)
+               syncFreq = (syncFreq >> quantif) + 1;
+       else
+               syncFreq = (syncFreq >> quantif);
+
+       if (syncFreq != 0)
+               syncFreq = syncFreq - 1;
+
+       return syncFreq;
+}
+
+static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
+               u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
+               u32 syncWord, u32 syncSize)
+{
+       dprintk("Configure DibStream Tx");
+
+       dib8000_write_word(state, 1615, 1);
+       dib8000_write_word(state, 1603, P_Kin);
+       dib8000_write_word(state, 1605, P_Kout);
+       dib8000_write_word(state, 1606, insertExtSynchro);
+       dib8000_write_word(state, 1608, synchroMode);
+       dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
+       dib8000_write_word(state, 1610, syncWord & 0xffff);
+       dib8000_write_word(state, 1612, syncSize);
+       dib8000_write_word(state, 1615, 0);
+}
+
+static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
+               u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
+               u32 syncWord, u32 syncSize, u32 dataOutRate)
+{
+       u32 syncFreq;
+
+       dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
+
+       if ((P_Kin != 0) && (P_Kout != 0)) {
+               syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
+                               insertExtSynchro, syncSize);
+               dib8000_write_word(state, 1542, syncFreq);
+       }
+
+       dib8000_write_word(state, 1554, 1);
+       dib8000_write_word(state, 1536, P_Kin);
+       dib8000_write_word(state, 1537, P_Kout);
+       dib8000_write_word(state, 1539, synchroMode);
+       dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
+       dib8000_write_word(state, 1541, syncWord & 0xffff);
+       dib8000_write_word(state, 1543, syncSize);
+       dib8000_write_word(state, 1544, dataOutRate);
+       dib8000_write_word(state, 1554, 0);
+}
+
+static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
+{
+       u16 reg_1287;
+
+       reg_1287 = dib8000_read_word(state, 1287);
+
+       switch (onoff) {
+       case 1:
+                       reg_1287 &= ~(1 << 8);
+                       break;
+       case 0:
+                       reg_1287 |= (1 << 8);
+                       break;
+       }
+
+       dib8000_write_word(state, 1287, reg_1287);
+}
+
+static void dib8096p_configMpegMux(struct dib8000_state *state,
+               u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
+{
+       u16 reg_1287;
+
+       dprintk("Enable Mpeg mux");
+
+       dib8096p_enMpegMux(state, 0);
+
+       /* If the input mode is MPEG do not divide the serial clock */
+       if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
+               enSerialClkDiv2 = 0;
+
+       reg_1287 = ((pulseWidth & 0x1f) << 3) |
+               ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
+       dib8000_write_word(state, 1287, reg_1287);
+
+       dib8096p_enMpegMux(state, 1);
+}
+
+static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
+{
+       u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
+
+       switch (mode) {
+       case MPEG_ON_DIBTX:
+                       dprintk("SET MPEG ON DIBSTREAM TX");
+                       dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
+                       reg_1288 |= (1 << 9); break;
+       case DIV_ON_DIBTX:
+                       dprintk("SET DIV_OUT ON DIBSTREAM TX");
+                       dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
+                       reg_1288 |= (1 << 8); break;
+       case ADC_ON_DIBTX:
+                       dprintk("SET ADC_OUT ON DIBSTREAM TX");
+                       dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
+                       reg_1288 |= (1 << 7); break;
+       default:
+                       break;
+       }
+       dib8000_write_word(state, 1288, reg_1288);
+}
+
+static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
+{
+       u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
+
+       switch (mode) {
+       case DEMOUT_ON_HOSTBUS:
+                       dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
+                       dib8096p_enMpegMux(state, 0);
+                       reg_1288 |= (1 << 6);
+                       break;
+       case DIBTX_ON_HOSTBUS:
+                       dprintk("SET DIBSTREAM TX ON HOST BUS");
+                       dib8096p_enMpegMux(state, 0);
+                       reg_1288 |= (1 << 5);
+                       break;
+       case MPEG_ON_HOSTBUS:
+                       dprintk("SET MPEG MUX ON HOST BUS");
+                       reg_1288 |= (1 << 4);
+                       break;
+       default:
+                       break;
+       }
+       dib8000_write_word(state, 1288, reg_1288);
+}
+
+static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 reg_1287;
+
+       switch (onoff) {
+       case 0: /* only use the internal way - not the diversity input */
+                       dprintk("%s mode OFF : by default Enable Mpeg INPUT",
+                                       __func__);
+                       /* outputRate = 8 */
+                       dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
+
+                       /* Do not divide the serial clock of MPEG MUX in
+                          SERIAL MODE in case input mode MPEG is used */
+                       reg_1287 = dib8000_read_word(state, 1287);
+                       /* enSerialClkDiv2 == 1 ? */
+                       if ((reg_1287 & 0x1) == 1) {
+                               /* force enSerialClkDiv2 = 0 */
+                               reg_1287 &= ~0x1;
+                               dib8000_write_word(state, 1287, reg_1287);
+                       }
+                       state->input_mode_mpeg = 1;
+                       break;
+       case 1: /* both ways */
+       case 2: /* only the diversity input */
+                       dprintk("%s ON : Enable diversity INPUT", __func__);
+                       dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
+                       state->input_mode_mpeg = 0;
+                       break;
+       }
+
+       dib8000_set_diversity_in(state->fe[0], onoff);
+       return 0;
+}
+
+static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 outreg, smo_mode, fifo_threshold;
+       u8 prefer_mpeg_mux_use = 1;
+       int ret = 0;
+
+       dib8096p_host_bus_drive(state, 1);
+
+       fifo_threshold = 1792;
+       smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
+       outreg   = dib8000_read_word(state, 1286) &
+               ~((1 << 10) | (0x7 << 6) | (1 << 1));
+
+       switch (mode) {
+       case OUTMODE_HIGH_Z:
+                       outreg = 0;
+                       break;
+
+       case OUTMODE_MPEG2_SERIAL:
+                       if (prefer_mpeg_mux_use) {
+                               dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
+                               dib8096p_configMpegMux(state, 3, 1, 1);
+                               dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
+                       } else {/* Use Smooth block */
+                               dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
+                               dib8096p_setHostBusMux(state,
+                                               DEMOUT_ON_HOSTBUS);
+                               outreg |= (2 << 6) | (0 << 1);
+                       }
+                       break;
+
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+                       if (prefer_mpeg_mux_use) {
+                               dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
+                               dib8096p_configMpegMux(state, 2, 0, 0);
+                               dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
+                       } else { /* Use Smooth block */
+                               dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
+                               dib8096p_setHostBusMux(state,
+                                               DEMOUT_ON_HOSTBUS);
+                               outreg |= (0 << 6);
+                       }
+                       break;
+
+       case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
+                       dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
+                       dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+                       outreg |= (1 << 6);
+                       break;
+
+       case OUTMODE_MPEG2_FIFO:
+                       /* Using Smooth block because not supported
+                          by new Mpeg Mux bloc */
+                       dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
+                       dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+                       outreg |= (5 << 6);
+                       smo_mode |= (3 << 1);
+                       fifo_threshold = 512;
+                       break;
+
+       case OUTMODE_DIVERSITY:
+                       dprintk("dib8096P setting output mode MODE_DIVERSITY");
+                       dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
+                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+                       break;
+
+       case OUTMODE_ANALOG_ADC:
+                       dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
+                       dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
+                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+                       break;
+       }
+
+       if (mode != OUTMODE_HIGH_Z)
+               outreg |= (1<<10);
+
+       dprintk("output_mpeg2_in_188_bytes = %d",
+                       state->cfg.output_mpeg2_in_188_bytes);
+       if (state->cfg.output_mpeg2_in_188_bytes)
+               smo_mode |= (1 << 5);
+
+       ret |= dib8000_write_word(state, 299, smo_mode);
+       /* synchronous fread */
+       ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
+       ret |= dib8000_write_word(state, 1286, outreg);
+
+       return ret;
+}
+
+static int map_addr_to_serpar_number(struct i2c_msg *msg)
+{
+       if (msg->buf[0] <= 15)
+               msg->buf[0] -= 1;
+       else if (msg->buf[0] == 17)
+               msg->buf[0] = 15;
+       else if (msg->buf[0] == 16)
+               msg->buf[0] = 17;
+       else if (msg->buf[0] == 19)
+               msg->buf[0] = 16;
+       else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
+               msg->buf[0] -= 3;
+       else if (msg->buf[0] == 28)
+               msg->buf[0] = 23;
+       else if (msg->buf[0] == 99)
+               msg->buf[0] = 99;
+       else
+               return -EINVAL;
+       return 0;
+}
+
+static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+       u8 n_overflow = 1;
+       u16 i = 1000;
+       u16 serpar_num = msg[0].buf[0];
+
+       while (n_overflow == 1 && i) {
+               n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
+               i--;
+               if (i == 0)
+                       dprintk("Tuner ITF: write busy (overflow)");
+       }
+       dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
+       dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
+
+       return num;
+}
+
+static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+       u8 n_overflow = 1, n_empty = 1;
+       u16 i = 1000;
+       u16 serpar_num = msg[0].buf[0];
+       u16 read_word;
+
+       while (n_overflow == 1 && i) {
+               n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
+               i--;
+               if (i == 0)
+                       dprintk("TunerITF: read busy (overflow)");
+       }
+       dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
+
+       i = 1000;
+       while (n_empty == 1 && i) {
+               n_empty = dib8000_read_word(state, 1984)&0x1;
+               i--;
+               if (i == 0)
+                       dprintk("TunerITF: read busy (empty)");
+       }
+
+       read_word = dib8000_read_word(state, 1987);
+       msg[1].buf[0] = (read_word >> 8) & 0xff;
+       msg[1].buf[1] = (read_word) & 0xff;
+
+       return num;
+}
+
+static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num)
+{
+       if (map_addr_to_serpar_number(&msg[0]) == 0) {
+               if (num == 1) /* write */
+                       return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
+               else /* read */
+                       return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
+       }
+       return num;
+}
+
+static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num, u16 apb_address)
+{
+       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+       u16 word;
+
+       if (num == 1) {         /* write */
+               dib8000_write_word(state, apb_address,
+                               ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
+       } else {
+               word = dib8000_read_word(state, apb_address);
+               msg[1].buf[0] = (word >> 8) & 0xff;
+               msg[1].buf[1] = (word) & 0xff;
+       }
+       return num;
+}
+
+static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
+               struct i2c_msg msg[], int num)
+{
+       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+       u16 apb_address = 0, word;
+       int i = 0;
+
+       switch (msg[0].buf[0]) {
+       case 0x12:
+                       apb_address = 1920;
+                       break;
+       case 0x14:
+                       apb_address = 1921;
+                       break;
+       case 0x24:
+                       apb_address = 1922;
+                       break;
+       case 0x1a:
+                       apb_address = 1923;
+                       break;
+       case 0x22:
+                       apb_address = 1924;
+                       break;
+       case 0x33:
+                       apb_address = 1926;
+                       break;
+       case 0x34:
+                       apb_address = 1927;
+                       break;
+       case 0x35:
+                       apb_address = 1928;
+                       break;
+       case 0x36:
+                       apb_address = 1929;
+                       break;
+       case 0x37:
+                       apb_address = 1930;
+                       break;
+       case 0x38:
+                       apb_address = 1931;
+                       break;
+       case 0x39:
+                       apb_address = 1932;
+                       break;
+       case 0x2a:
+                       apb_address = 1935;
+                       break;
+       case 0x2b:
+                       apb_address = 1936;
+                       break;
+       case 0x2c:
+                       apb_address = 1937;
+                       break;
+       case 0x2d:
+                       apb_address = 1938;
+                       break;
+       case 0x2e:
+                       apb_address = 1939;
+                       break;
+       case 0x2f:
+                       apb_address = 1940;
+                       break;
+       case 0x30:
+                       apb_address = 1941;
+                       break;
+       case 0x31:
+                       apb_address = 1942;
+                       break;
+       case 0x32:
+                       apb_address = 1943;
+                       break;
+       case 0x3e:
+                       apb_address = 1944;
+                       break;
+       case 0x3f:
+                       apb_address = 1945;
+                       break;
+       case 0x40:
+                       apb_address = 1948;
+                       break;
+       case 0x25:
+                       apb_address = 936;
+                       break;
+       case 0x26:
+                       apb_address = 937;
+                       break;
+       case 0x27:
+                       apb_address = 938;
+                       break;
+       case 0x28:
+                       apb_address = 939;
+                       break;
+       case 0x1d:
+                       /* get sad sel request */
+                       i = ((dib8000_read_word(state, 921) >> 12)&0x3);
+                       word = dib8000_read_word(state, 924+i);
+                       msg[1].buf[0] = (word >> 8) & 0xff;
+                       msg[1].buf[1] = (word) & 0xff;
+                       return num;
+       case 0x1f:
+                       if (num == 1) { /* write */
+                               word = (u16) ((msg[0].buf[1] << 8) |
+                                               msg[0].buf[2]);
+                               /* in the VGAMODE Sel are located on bit 0/1 */
+                               word &= 0x3;
+                               word = (dib8000_read_word(state, 921) &
+                                               ~(3<<12)) | (word<<12);
+                               /* Set the proper input */
+                               dib8000_write_word(state, 921, word);
+                               return num;
+                       }
+       }
+
+       if (apb_address != 0) /* R/W acces via APB */
+               return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
+       else  /* R/W access via SERPAR  */
+               return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
+
+       return 0;
+}
+
+static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
+       .master_xfer = dib8096p_tuner_xfer,
+       .functionality = dib8096p_i2c_func,
+};
+
+struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
+{
+       struct dib8000_state *st = fe->demodulator_priv;
+       return &st->dib8096p_tuner_adap;
+}
+EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
+
+int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 en_cur_state;
+
+       dprintk("sleep dib8096p: %d", onoff);
+
+       en_cur_state = dib8000_read_word(state, 1922);
+
+       /* LNAs and MIX are ON and therefore it is a valid configuration */
+       if (en_cur_state > 0xff)
+               state->tuner_enable = en_cur_state ;
+
+       if (onoff)
+               en_cur_state &= 0x00ff;
+       else {
+               if (state->tuner_enable != 0)
+                       en_cur_state = state->tuner_enable;
+       }
+
+       dib8000_write_word(state, 1922, en_cur_state);
+
+       return 0;
+}
+EXPORT_SYMBOL(dib8096p_tuner_sleep);
+
+static const s32 lut_1000ln_mant[] =
+{
+       908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
+};
+
+s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
+       s32 val;
+
+       val = dib8000_read32(state, 384);
+       if (mode) {
+               tmp_val = val;
+               while (tmp_val >>= 1)
+                       exp++;
+               mant = (val * 1000 / (1<<exp));
+               ix = (u8)((mant-1000)/100); /* index of the LUT */
+               val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
+               val = (val*256)/1000;
+       }
+       return val;
+}
+EXPORT_SYMBOL(dib8000_get_adc_power);
+
+int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       int val = 0;
+
+       switch (IQ) {
+       case 1:
+                       val = dib8000_read_word(state, 403);
+                       break;
+       case 0:
+                       val = dib8000_read_word(state, 404);
+                       break;
+       }
+       if (val  & 0x200)
+               val -= 1024;
+
+       return val;
+}
+EXPORT_SYMBOL(dib8090p_get_dc_power);
+
+static void dib8000_update_timf(struct dib8000_state *state)
+{
+       u32 timf = state->timf = dib8000_read32(state, 435);
+
+       dib8000_write_word(state, 29, (u16) (timf >> 16));
+       dib8000_write_word(state, 30, (u16) (timf & 0xffff));
+       dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
+}
+
+u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       switch (op) {
+       case DEMOD_TIMF_SET:
+                       state->timf = timf;
+                       break;
+       case DEMOD_TIMF_UPDATE:
+                       dib8000_update_timf(state);
+                       break;
+       case DEMOD_TIMF_GET:
+                       break;
+       }
+       dib8000_set_bandwidth(state->fe[0], 6000);
+
+       return state->timf;
+}
+EXPORT_SYMBOL(dib8000_ctrl_timf);
+
+static const u16 adc_target_16dB[11] = {
+       (1 << 13) - 825 - 117,
+       (1 << 13) - 837 - 117,
+       (1 << 13) - 811 - 117,
+       (1 << 13) - 766 - 117,
+       (1 << 13) - 737 - 117,
+       (1 << 13) - 693 - 117,
+       (1 << 13) - 648 - 117,
+       (1 << 13) - 619 - 117,
+       (1 << 13) - 575 - 117,
+       (1 << 13) - 531 - 117,
+       (1 << 13) - 501 - 117
+};
+static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
+
+static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
+{
+       u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
+       u8 guard, crate, constellation, timeI;
+       u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;        // All 13 segments enabled
+       const s16 *ncoeff = NULL, *ana_fe;
+       u16 tmcc_pow = 0;
+       u16 coff_pow = 0x2800;
+       u16 init_prbs = 0xfff;
+       u16 ana_gain = 0;
+
+       if (state->revision == 0x8090)
+               dib8000_init_sdram(state);
+
+       if (state->ber_monitored_layer != LAYER_ALL)
+               dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
+       else
+               dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
+
+       i = dib8000_read_word(state, 26) & 1;   // P_dds_invspec
+       dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
+               //compute new dds_freq for the seg and adjust prbs
+               int seg_offset =
+                       state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
+                       (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
+                       (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
+               int clk = state->cfg.pll->internal;
+               u32 segtodds = ((u32) (430 << 23) / clk) << 3;  // segtodds = SegBW / Fclk * pow(2,26)
+               int dds_offset = seg_offset * segtodds;
+               int new_dds, sub_channel;
+               if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+                       dds_offset -= (int)(segtodds / 2);
+
+               if (state->cfg.pll->ifreq == 0) {
+                       if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
+                               dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
+                               new_dds = dds_offset;
+                       } else
+                               new_dds = dds_offset;
+
+                       // We shift tuning frequency if the wanted segment is :
+                       //  - the segment of center frequency with an odd total number of segments
+                       //  - the segment to the left of center frequency with an even total number of segments
+                       //  - the segment to the right of center frequency with an even total number of segments
+                       if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
+                               && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
+                                       && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
+                                         && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
+                                 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+                                        || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+                                                && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
+                                        || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+                                                && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
+                                                        ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+                                       )) {
+                               new_dds -= ((u32) (850 << 22) / clk) << 4;      // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
+                       }
+               } else {
+                       if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
+                               new_dds = state->cfg.pll->ifreq - dds_offset;
+                       else
+                               new_dds = state->cfg.pll->ifreq + dds_offset;
+               }
+               dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
+               dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
+               if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
+                       sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
+               else
+                       sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
+               sub_channel -= 6;
+
+               if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
+                               || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
+                       dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);    //adp_pass =1
+                       dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));    //pha3_force_pha_shift = 1
+               } else {
+                       dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
+                       dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
+               }
+
+               switch (state->fe[0]->dtv_property_cache.transmission_mode) {
+               case TRANSMISSION_MODE_2K:
+                       switch (sub_channel) {
+                       case -6:
+                               init_prbs = 0x0;
+                               break;  // 41, 0, 1
+                       case -5:
+                               init_prbs = 0x423;
+                               break;  // 02~04
+                       case -4:
+                               init_prbs = 0x9;
+                               break;  // 05~07
+                       case -3:
+                               init_prbs = 0x5C7;
+                               break;  // 08~10
+                       case -2:
+                               init_prbs = 0x7A6;
+                               break;  // 11~13
+                       case -1:
+                               init_prbs = 0x3D8;
+                               break;  // 14~16
+                       case 0:
+                               init_prbs = 0x527;
+                               break;  // 17~19
+                       case 1:
+                               init_prbs = 0x7FF;
+                               break;  // 20~22
+                       case 2:
+                               init_prbs = 0x79B;
+                               break;  // 23~25
+                       case 3:
+                               init_prbs = 0x3D6;
+                               break;  // 26~28
+                       case 4:
+                               init_prbs = 0x3A2;
+                               break;  // 29~31
+                       case 5:
+                               init_prbs = 0x53B;
+                               break;  // 32~34
+                       case 6:
+                               init_prbs = 0x2F4;
+                               break;  // 35~37
+                       default:
+                       case 7:
+                               init_prbs = 0x213;
+                               break;  // 38~40
+                       }
+                       break;
+
+               case TRANSMISSION_MODE_4K:
+                       switch (sub_channel) {
+                       case -6:
+                               init_prbs = 0x0;
+                               break;  // 41, 0, 1
+                       case -5:
+                               init_prbs = 0x208;
+                               break;  // 02~04
+                       case -4:
+                               init_prbs = 0xC3;
+                               break;  // 05~07
+                       case -3:
+                               init_prbs = 0x7B9;
+                               break;  // 08~10
+                       case -2:
+                               init_prbs = 0x423;
+                               break;  // 11~13
+                       case -1:
+                               init_prbs = 0x5C7;
+                               break;  // 14~16
+                       case 0:
+                               init_prbs = 0x3D8;
+                               break;  // 17~19
+                       case 1:
+                               init_prbs = 0x7FF;
+                               break;  // 20~22
+                       case 2:
+                               init_prbs = 0x3D6;
+                               break;  // 23~25
+                       case 3:
+                               init_prbs = 0x53B;
+                               break;  // 26~28
+                       case 4:
+                               init_prbs = 0x213;
+                               break;  // 29~31
+                       case 5:
+                               init_prbs = 0x29;
+                               break;  // 32~34
+                       case 6:
+                               init_prbs = 0xD0;
+                               break;  // 35~37
+                       default:
+                       case 7:
+                               init_prbs = 0x48E;
+                               break;  // 38~40
+                       }
+                       break;
+
+               default:
+               case TRANSMISSION_MODE_8K:
+                       switch (sub_channel) {
+                       case -6:
+                               init_prbs = 0x0;
+                               break;  // 41, 0, 1
+                       case -5:
+                               init_prbs = 0x740;
+                               break;  // 02~04
+                       case -4:
+                               init_prbs = 0x069;
+                               break;  // 05~07
+                       case -3:
+                               init_prbs = 0x7DD;
+                               break;  // 08~10
+                       case -2:
+                               init_prbs = 0x208;
+                               break;  // 11~13
+                       case -1:
+                               init_prbs = 0x7B9;
+                               break;  // 14~16
+                       case 0:
+                               init_prbs = 0x5C7;
+                               break;  // 17~19
+                       case 1:
+                               init_prbs = 0x7FF;
+                               break;  // 20~22
+                       case 2:
+                               init_prbs = 0x53B;
+                               break;  // 23~25
+                       case 3:
+                               init_prbs = 0x29;
+                               break;  // 26~28
+                       case 4:
+                               init_prbs = 0x48E;
+                               break;  // 29~31
+                       case 5:
+                               init_prbs = 0x4C4;
+                               break;  // 32~34
+                       case 6:
+                               init_prbs = 0x367;
+                               break;  // 33~37
+                       default:
+                       case 7:
+                               init_prbs = 0x684;
+                               break;  // 38~40
+                       }
+                       break;
+               }
+       } else {
+               dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
+               dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
+               dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
+       }
+       /*P_mode == ?? */
+       dib8000_write_word(state, 10, (seq << 4));
+       //  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
+
+       switch (state->fe[0]->dtv_property_cache.guard_interval) {
+       case GUARD_INTERVAL_1_32:
+               guard = 0;
+               break;
+       case GUARD_INTERVAL_1_16:
+               guard = 1;
+               break;
+       case GUARD_INTERVAL_1_8:
+               guard = 2;
+               break;
+       case GUARD_INTERVAL_1_4:
+       default:
+               guard = 3;
+               break;
+       }
+
+       dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
+
+       max_constellation = DQPSK;
+       for (i = 0; i < 3; i++) {
+               switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
+               case DQPSK:
+                       constellation = 0;
+                       break;
+               case QPSK:
+                       constellation = 1;
+                       break;
+               case QAM_16:
+                       constellation = 2;
+                       break;
+               case QAM_64:
+               default:
+                       constellation = 3;
+                       break;
+               }
+
+               switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
+               case FEC_1_2:
+                       crate = 1;
+                       break;
+               case FEC_2_3:
+                       crate = 2;
+                       break;
+               case FEC_3_4:
+                       crate = 3;
+                       break;
+               case FEC_5_6:
+                       crate = 5;
+                       break;
+               case FEC_7_8:
+               default:
+                       crate = 7;
+                       break;
+               }
+
+               if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
+                               ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
+                                (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
+                       )
+                       timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
+               else
+                       timeI = 0;
+               dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
+                                       (crate << 3) | timeI);
+               if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
+                       switch (max_constellation) {
+                       case DQPSK:
+                       case QPSK:
+                               if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
+                                       state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
+                                       max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
+                               break;
+                       case QAM_16:
+                               if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
+                                       max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
+                               break;
+                       }
+               }
+       }
+
+       mode = fft_to_mode(state);
+
+       //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
+
+       dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
+                               ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
+                                                                                                isdbt_sb_mode & 1) << 4));
+
+       dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
+
+       /* signal optimization parameter */
+
+       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
+               seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
+               for (i = 1; i < 3; i++)
+                       nbseg_diff +=
+                               (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
+               for (i = 0; i < nbseg_diff; i++)
+                       seg_diff_mask |= 1 << permu_seg[i + 1];
+       } else {
+               for (i = 0; i < 3; i++)
+                       nbseg_diff +=
+                               (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
+               for (i = 0; i < nbseg_diff; i++)
+                       seg_diff_mask |= 1 << permu_seg[i];
+       }
+       dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
+
+       state->differential_constellation = (seg_diff_mask != 0);
+       if (state->revision != 0x8090)
+               dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
+       else
+               dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
+                       seg_mask13 = 0x00E0;
+               else            // 1-segment
+                       seg_mask13 = 0x0040;
+       } else
+               seg_mask13 = 0x1fff;
+
+       // WRITE: Mode & Diff mask
+       dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
+
+       if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
+               dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
+       else
+               dib8000_write_word(state, 268, (2 << 9) | 39);  //init value
+
+       // ---- SMALL ----
+       // P_small_seg_diff
+       dib8000_write_word(state, 352, seg_diff_mask);  // ADDR 352
+
+       dib8000_write_word(state, 353, seg_mask13);     // ADDR 353
+
+/*     // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
+
+       // ---- SMALL ----
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               switch (state->fe[0]->dtv_property_cache.transmission_mode) {
+               case TRANSMISSION_MODE_2K:
+                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
+                                       ncoeff = coeff_2k_sb_1seg_dqpsk;
+                               else    // QPSK or QAM
+                                       ncoeff = coeff_2k_sb_1seg;
+                       } else {        // 3-segments
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
+                                               ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
+                                       else    // QPSK or QAM on external segments
+                                               ncoeff = coeff_2k_sb_3seg_0dqpsk;
+                               } else {        // QPSK or QAM on central segment
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
+                                               ncoeff = coeff_2k_sb_3seg_1dqpsk;
+                                       else    // QPSK or QAM on external segments
+                                               ncoeff = coeff_2k_sb_3seg;
+                               }
+                       }
+                       break;
+
+               case TRANSMISSION_MODE_4K:
+                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
+                                       ncoeff = coeff_4k_sb_1seg_dqpsk;
+                               else    // QPSK or QAM
+                                       ncoeff = coeff_4k_sb_1seg;
+                       } else {        // 3-segments
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
+                                               ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
+                                       } else {        // QPSK or QAM on external segments
+                                               ncoeff = coeff_4k_sb_3seg_0dqpsk;
+                                       }
+                               } else {        // QPSK or QAM on central segment
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
+                                               ncoeff = coeff_4k_sb_3seg_1dqpsk;
+                                       } else  // QPSK or QAM on external segments
+                                               ncoeff = coeff_4k_sb_3seg;
+                               }
+                       }
+                       break;
+
+               case TRANSMISSION_MODE_AUTO:
+               case TRANSMISSION_MODE_8K:
+               default:
+                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
+                                       ncoeff = coeff_8k_sb_1seg_dqpsk;
+                               else    // QPSK or QAM
+                                       ncoeff = coeff_8k_sb_1seg;
+                       } else {        // 3-segments
+                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
+                                               ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
+                                       } else {        // QPSK or QAM on external segments
+                                               ncoeff = coeff_8k_sb_3seg_0dqpsk;
+                                       }
+                               } else {        // QPSK or QAM on central segment
+                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
+                                               ncoeff = coeff_8k_sb_3seg_1dqpsk;
+                                       } else  // QPSK or QAM on external segments
+                                               ncoeff = coeff_8k_sb_3seg;
+                               }
+                       }
+                       break;
+               }
+               for (i = 0; i < 8; i++)
+                       dib8000_write_word(state, 343 + i, ncoeff[i]);
+       }
+
+       // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
+       dib8000_write_word(state, 351,
+                               (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
+
+       // ---- COFF ----
+       // Carloff, the most robust
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+
+               // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
+               // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
+               dib8000_write_word(state, 187,
+                                       (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
+                                       | 0x3);
+
+/*             // P_small_coef_ext_enable = 1 */
+/*             dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
+
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
+
+                       // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
+                       if (mode == 3)
+                               dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
+                       else
+                               dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
+                       // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
+                       // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
+                       dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
+                       // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+                       dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+                       // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+                       dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+                       // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+                       dib8000_write_word(state, 181, 300);
+                       dib8000_write_word(state, 182, 150);
+                       dib8000_write_word(state, 183, 80);
+                       dib8000_write_word(state, 184, 300);
+                       dib8000_write_word(state, 185, 150);
+                       dib8000_write_word(state, 186, 80);
+               } else {        // Sound Broadcasting mode 3 seg
+                       // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
+                       /*      if (mode == 3) */
+                       /*              dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
+                       /*      else */
+                       /*              dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
+                       dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
+
+                       // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
+                       // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
+                       dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
+                       // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+                       dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+                       //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+                       dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+                       // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+                       dib8000_write_word(state, 181, 350);
+                       dib8000_write_word(state, 182, 300);
+                       dib8000_write_word(state, 183, 250);
+                       dib8000_write_word(state, 184, 350);
+                       dib8000_write_word(state, 185, 300);
+                       dib8000_write_word(state, 186, 250);
+               }
+
+       } else if (state->isdbt_cfg_loaded == 0) {      // if not Sound Broadcasting mode : put default values for 13 segments
+               dib8000_write_word(state, 180, (16 << 6) | 9);
+               dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
+               coff_pow = 0x2800;
+               for (i = 0; i < 6; i++)
+                       dib8000_write_word(state, 181 + i, coff_pow);
+
+               // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
+               // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
+               dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
+
+               // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
+               dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
+               // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
+               dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+       }
+       // ---- FFT ----
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
+               dib8000_write_word(state, 178, 64);     // P_fft_powrange=64
+       else
+               dib8000_write_word(state, 178, 32);     // P_fft_powrange=32
+
+       /* make the cpil_coff_lock more robust but slower p_coff_winlen
+        * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
+        */
+       /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
+               dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
+
+       dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);    /* P_lmod4_seg_inh       */
+       dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);    /* P_pha3_seg_inh        */
+       dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);    /* P_tac_seg_inh         */
+       if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
+               dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);     /* P_equal_noise_seg_inh */
+       else
+               dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);    /* P_equal_noise_seg_inh */
+       dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);   /* P_tmcc_seg_inh        */
+       //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
+       if (!autosearching)
+               dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
+       else
+               dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
+       dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
+
+       dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));  /* P_des_seg_enabled     */
+
+       /* offset loop parameters */
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
+                       /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+                       dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
+
+               else            // Sound Broadcasting mode 3 seg
+                       /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+                       dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
+       } else
+               // TODO in 13 seg, timf_alpha can always be the same or not ?
+               /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
+               dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
+                       /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (11-P_mode)  */
+                       dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
+
+               else            // Sound Broadcasting mode 3 seg
+                       /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
+                       dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
+       } else
+               /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
+               dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
+
+       /* P_dvsy_sync_wait - reuse mode */
+       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
+       case TRANSMISSION_MODE_8K:
+               mode = 256;
+               break;
+       case TRANSMISSION_MODE_4K:
+               mode = 128;
+               break;
+       default:
+       case TRANSMISSION_MODE_2K:
+               mode = 64;
+               break;
+       }
+       if (state->cfg.diversity_delay == 0)
+               mode = (mode * (1 << (guard)) * 3) / 2 + 48;    // add 50% SFN margin + compensate for one DVSY-fifo
+       else
+               mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay;    // add 50% SFN margin + compensate for DVSY-fifo
+       mode <<= 4;
+       dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
+
+       /* channel estimation fine configuration */
+       switch (max_constellation) {
+       case QAM_64:
+               ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
+               coeff[0] = 0x0148;      /* P_adp_regul_cnt 0.04 */
+               coeff[1] = 0xfff0;      /* P_adp_noise_cnt -0.002 */
+               coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
+               coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.001 */
+               //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
+               break;
+       case QAM_16:
+               ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
+               coeff[0] = 0x023d;      /* P_adp_regul_cnt 0.07 */
+               coeff[1] = 0xffdf;      /* P_adp_noise_cnt -0.004 */
+               coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
+               coeff[3] = 0xfff0;      /* P_adp_noise_ext -0.002 */
+               //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
+               break;
+       default:
+               ana_gain = 0;   // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
+               coeff[0] = 0x099a;      /* P_adp_regul_cnt 0.3 */
+               coeff[1] = 0xffae;      /* P_adp_noise_cnt -0.01 */
+               coeff[2] = 0x0333;      /* P_adp_regul_ext 0.1 */
+               coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.002 */
+               break;
+       }
+       for (mode = 0; mode < 4; mode++)
+               dib8000_write_word(state, 215 + mode, coeff[mode]);
+
+       // update ana_gain depending on max constellation
+       dib8000_write_word(state, 116, ana_gain);
+       // update ADC target depending on ana_gain
+       if (ana_gain) {         // set -16dB ADC target for ana_gain=-1
+               for (i = 0; i < 10; i++)
+                       dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
+       } else {                // set -22dB ADC target for ana_gain=0
+               for (i = 0; i < 10; i++)
+                       dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
+       }
+
+       // ---- ANA_FE ----
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
+                       ana_fe = ana_fe_coeff_3seg;
+               else            // 1-segment
+                       ana_fe = ana_fe_coeff_1seg;
+       } else
+               ana_fe = ana_fe_coeff_13seg;
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
+               for (mode = 0; mode < 24; mode++)
+                       dib8000_write_word(state, 117 + mode, ana_fe[mode]);
+
+       // ---- CHAN_BLK ----
+       for (i = 0; i < 13; i++) {
+               if ((((~seg_diff_mask) >> i) & 1) == 1) {
+                       P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
+                       P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
+               }
+       }
+       dib8000_write_word(state, 222, P_cfr_left_edge);        // P_cfr_left_edge
+       dib8000_write_word(state, 223, P_cfr_right_edge);       // P_cfr_right_edge
+       // "P_cspu_left_edge"  not used => do not care
+       // "P_cspu_right_edge" not used => do not care
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               dib8000_write_word(state, 228, 1);      // P_2d_mode_byp=1
+               dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
+                       && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
+                       //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
+                       dib8000_write_word(state, 265, 15);     // P_equal_noise_sel = 15
+               }
+       } else if (state->isdbt_cfg_loaded == 0) {
+               dib8000_write_word(state, 228, 0);      // default value
+               dib8000_write_word(state, 265, 31);     // default value
+               dib8000_write_word(state, 205, 0x200f); // init value
+       }
+       // ---- TMCC ----
+       for (i = 0; i < 3; i++)
+               tmcc_pow +=
+                       (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
+       // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
+       // Threshold is set at 1/4 of max power.
+       tmcc_pow *= (1 << (9 - 2));
+
+       dib8000_write_word(state, 290, tmcc_pow);       // P_tmcc_dec_thres_2k
+       dib8000_write_word(state, 291, tmcc_pow);       // P_tmcc_dec_thres_4k
+       dib8000_write_word(state, 292, tmcc_pow);       // P_tmcc_dec_thres_8k
+       //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
+       // ---- PHA3 ----
+
+       if (state->isdbt_cfg_loaded == 0)
+               dib8000_write_word(state, 250, 3285);   /*p_2d_hspeed_thr0 */
+
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
+               state->isdbt_cfg_loaded = 0;
+       else
+               state->isdbt_cfg_loaded = 1;
+
+}
+
+static int dib8000_autosearch_start(struct dvb_frontend *fe)
+{
+       u8 factor;
+       u32 value;
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       int slist = 0;
+
+       state->fe[0]->dtv_property_cache.inversion = 0;
+       if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
+               state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
+       state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
+       state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
+       state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
+
+       //choose the right list, in sb, always do everything
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
+               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+               slist = 7;
+               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
+       } else {
+               if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
+                       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+                               slist = 7;
+                               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1 to have autosearch start ok with mode2
+                       } else
+                               slist = 3;
+               } else {
+                       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+                               slist = 2;
+                               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1
+                       } else
+                               slist = 0;
+               }
+
+               if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
+                       state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+               if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
+                       state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+
+               dprintk("using list for autosearch : %d", slist);
+               dib8000_set_channel(state, (unsigned char)slist, 1);
+               //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  // P_mode = 1
+
+               factor = 1;
+
+               //set lock_mask values
+               dib8000_write_word(state, 6, 0x4);
+               dib8000_write_word(state, 7, 0x8);
+               dib8000_write_word(state, 8, 0x1000);
+
+               //set lock_mask wait time values
+               value = 50 * state->cfg.pll->internal * factor;
+               dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff));  // lock0 wait time
+               dib8000_write_word(state, 12, (u16) (value & 0xffff));  // lock0 wait time
+               value = 100 * state->cfg.pll->internal * factor;
+               dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff));  // lock1 wait time
+               dib8000_write_word(state, 14, (u16) (value & 0xffff));  // lock1 wait time
+               value = 1000 * state->cfg.pll->internal * factor;
+               dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff));  // lock2 wait time
+               dib8000_write_word(state, 16, (u16) (value & 0xffff));  // lock2 wait time
+
+               value = dib8000_read_word(state, 0);
+               dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
+               dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
+               dib8000_write_word(state, 0, (u16) value);
+
+       }
+
+       return 0;
+}
+
+static int dib8000_autosearch_irq(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 irq_pending = dib8000_read_word(state, 1284);
+
+       if (irq_pending & 0x1) {        // failed
+               dprintk("dib8000_autosearch_irq failed");
+               return 1;
+       }
+
+       if (irq_pending & 0x2) {        // succeeded
+               dprintk("dib8000_autosearch_irq succeeded");
+               return 2;
+       }
+
+       return 0;               // still pending
+}
+
+static int dib8000_tune(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       int ret = 0;
+       u16 lock, value, mode;
+
+       // we are already tuned - just resuming from suspend
+       if (state == NULL)
+               return -EINVAL;
+
+       mode = fft_to_mode(state);
+
+       dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
+       dib8000_set_channel(state, 0, 0);
+
+       // restart demod
+       ret |= dib8000_write_word(state, 770, 0x4000);
+       ret |= dib8000_write_word(state, 770, 0x0000);
+       msleep(45);
+
+       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
+       /*  ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) );  workaround inh_isi stays at 1 */
+
+       // never achieved a lock before - wait for timfreq to update
+       if (state->timf == 0) {
+               if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
+                               msleep(300);
+                       else    // Sound Broadcasting mode 3 seg
+                               msleep(500);
+               } else          // 13 seg
+                       msleep(200);
+       }
+       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
+               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
+
+                       /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40  alpha to check on board */
+                       dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
+                       //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
+
+                       /*  P_ctrl_sfreq_step= (12-P_mode)   P_ctrl_sfreq_inh =0     P_ctrl_pha_off_max  */
+                       ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
+
+               } else {        // Sound Broadcasting mode 3 seg
+
+                       /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60  alpha to check on board */
+                       dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
+
+                       ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
+               }
+
+       } else {                // 13 seg
+               /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80  alpha to check on board */
+               dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
+
+               ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
+
+       }
+
+       // we achieved a coff_cpil_lock - it's time to update the timf
+       if (state->revision != 0x8090)
+               lock = dib8000_read_word(state, 568);
+       else
+               lock = dib8000_read_word(state, 570);
+       if ((lock >> 11) & 0x1)
+               dib8000_update_timf(state);
+
+       //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
+       dib8000_write_word(state, 6, 0x200);
+
+       if (state->revision == 0x8002) {
+               value = dib8000_read_word(state, 903);
+               dib8000_write_word(state, 903, value & ~(1 << 3));
+               msleep(1);
+               dib8000_write_word(state, 903, value | (1 << 3));
+       }
+
+       return ret;
+}
+
+static int dib8000_wakeup(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       int ret;
+
+       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
+       dib8000_set_adc_state(state, DIBX000_ADC_ON);
+       if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
+               dprintk("could not start Slow ADC");
+
+       if (state->revision != 0x8090)
+               dib8000_sad_calib(state);
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int dib8000_sleep(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       int ret;
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (state->revision != 0x8090)
+               dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
+       dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
+       return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
+}
+
+enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       return state->tune_state;
+}
+EXPORT_SYMBOL(dib8000_get_tune_state);
+
+int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       state->tune_state = tune_state;
+       return 0;
+}
+EXPORT_SYMBOL(dib8000_set_tune_state);
+
+static int dib8000_get_frontend(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 i, val = 0;
+       fe_status_t stat;
+       u8 index_frontend, sub_index_frontend;
+
+       fe->dtv_property_cache.bandwidth_hz = 6000000;
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
+               if (stat&FE_HAS_SYNC) {
+                       dprintk("TMCC lock on the slave%i", index_frontend);
+                       /* synchronize the cache with the other frontends */
+                       state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
+                       for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
+                               if (sub_index_frontend != index_frontend) {
+                                       state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
+                                       for (i = 0; i < 3; i++) {
+                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
+                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
+                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
+                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
+                                       }
+                               }
+                       }
+                       return 0;
+               }
+       }
+
+       fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
+
+       if (state->revision == 0x8090)
+               val = dib8000_read_word(state, 572);
+       else
+               val = dib8000_read_word(state, 570);
+       fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
+       switch ((val & 0x30) >> 4) {
+       case 1:
+               fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 3:
+       default:
+               fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+
+       switch (val & 0x3) {
+       case 0:
+               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
+               dprintk("dib8000_get_frontend GI = 1/32 ");
+               break;
+       case 1:
+               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
+               dprintk("dib8000_get_frontend GI = 1/16 ");
+               break;
+       case 2:
+               dprintk("dib8000_get_frontend GI = 1/8 ");
+               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               dprintk("dib8000_get_frontend GI = 1/4 ");
+               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       val = dib8000_read_word(state, 505);
+       fe->dtv_property_cache.isdbt_partial_reception = val & 1;
+       dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
+
+       for (i = 0; i < 3; i++) {
+               val = dib8000_read_word(state, 493 + i);
+               fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
+               dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
+
+               val = dib8000_read_word(state, 499 + i);
+               fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
+               dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
+
+               val = dib8000_read_word(state, 481 + i);
+               switch (val & 0x7) {
+               case 1:
+                       fe->dtv_property_cache.layer[i].fec = FEC_1_2;
+                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
+                       break;
+               case 2:
+                       fe->dtv_property_cache.layer[i].fec = FEC_2_3;
+                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
+                       break;
+               case 3:
+                       fe->dtv_property_cache.layer[i].fec = FEC_3_4;
+                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
+                       break;
+               case 5:
+                       fe->dtv_property_cache.layer[i].fec = FEC_5_6;
+                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
+                       break;
+               default:
+                       fe->dtv_property_cache.layer[i].fec = FEC_7_8;
+                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
+                       break;
+               }
+
+               val = dib8000_read_word(state, 487 + i);
+               switch (val & 0x3) {
+               case 0:
+                       dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
+                       fe->dtv_property_cache.layer[i].modulation = DQPSK;
+                       break;
+               case 1:
+                       fe->dtv_property_cache.layer[i].modulation = QPSK;
+                       dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
+                       break;
+               case 2:
+                       fe->dtv_property_cache.layer[i].modulation = QAM_16;
+                       dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
+                       break;
+               case 3:
+               default:
+                       dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
+                       fe->dtv_property_cache.layer[i].modulation = QAM_64;
+                       break;
+               }
+       }
+
+       /* synchronize the cache with the other frontends */
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
+               state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
+               state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
+               state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
+               state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
+               for (i = 0; i < 3; i++) {
+                       state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
+                       state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
+                       state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
+                       state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
+               }
+       }
+       return 0;
+}
+
+static int dib8000_set_frontend(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 nbr_pending, exit_condition, index_frontend;
+       s8 index_frontend_success = -1;
+       int time, ret;
+       int  time_slave = FE_CALLBACK_TIME_NEVER;
+
+       if (state->fe[0]->dtv_property_cache.frequency == 0) {
+               dprintk("dib8000: must at least specify frequency ");
+               return 0;
+       }
+
+       if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
+               dprintk("dib8000: no bandwidth specified, set to default ");
+               state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
+       }
+
+       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               /* synchronization of the cache */
+               state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
+               memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
+
+               if (state->revision != 0x8090)
+                       dib8000_set_output_mode(state->fe[index_frontend],
+                                       OUTMODE_HIGH_Z);
+               else
+                       dib8096p_set_output_mode(state->fe[index_frontend],
+                                       OUTMODE_HIGH_Z);
+               if (state->fe[index_frontend]->ops.tuner_ops.set_params)
+                       state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
+
+               dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
+       }
+
+       /* start up the AGC */
+       do {
+               time = dib8000_agc_startup(state->fe[0]);
+               for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       time_slave = dib8000_agc_startup(state->fe[index_frontend]);
+                       if (time == FE_CALLBACK_TIME_NEVER)
+                               time = time_slave;
+                       else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
+                               time = time_slave;
+               }
+               if (time != FE_CALLBACK_TIME_NEVER)
+                       msleep(time / 10);
+               else
+                       break;
+               exit_condition = 1;
+               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
+                               exit_condition = 0;
+                               break;
+                       }
+               }
+       } while (exit_condition == 0);
+
+       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
+
+       if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
+                       (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
+                       (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
+                       (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
+                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
+                        (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
+                        (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
+                        ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
+                         (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
+                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
+                        (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
+                        (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
+                        ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
+                         (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
+                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
+                        (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
+                        (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
+                        ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
+                         (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
+                       (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
+                         ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
+                        ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
+                         ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
+                        ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
+               int i = 100;
+               u8 found = 0;
+               u8 tune_failed = 0;
+
+               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
+                       dib8000_autosearch_start(state->fe[index_frontend]);
+               }
+
+               do {
+                       msleep(20);
+                       nbr_pending = 0;
+                       exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
+                       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                               if (((tune_failed >> index_frontend) & 0x1) == 0) {
+                                       found = dib8000_autosearch_irq(state->fe[index_frontend]);
+                                       switch (found) {
+                                       case 0: /* tune pending */
+                                                nbr_pending++;
+                                                break;
+                                       case 2:
+                                                dprintk("autosearch succeed on the frontend%i", index_frontend);
+                                                exit_condition = 2;
+                                                index_frontend_success = index_frontend;
+                                                break;
+                                       default:
+                                                dprintk("unhandled autosearch result");
+                                       case 1:
+                                                tune_failed |= (1 << index_frontend);
+                                                dprintk("autosearch failed for the frontend%i", index_frontend);
+                                                break;
+                                       }
+                               }
+                       }
+
+                       /* if all tune are done and no success, exit: tune failed */
+                       if ((nbr_pending == 0) && (exit_condition == 0))
+                               exit_condition = 1;
+               } while ((exit_condition == 0) && i--);
+
+               if (exit_condition == 1) { /* tune failed */
+                       dprintk("tune failed");
+                       return 0;
+               }
+
+               dprintk("tune success on frontend%i", index_frontend_success);
+
+               dib8000_get_frontend(fe);
+       }
+
+       for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               ret = dib8000_tune(state->fe[index_frontend]);
+
+       /* set output mode and diversity input */
+       if (state->revision != 0x8090) {
+               dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
+               for (index_frontend = 1;
+                               (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
+                               (state->fe[index_frontend] != NULL);
+                               index_frontend++) {
+                       dib8000_set_output_mode(state->fe[index_frontend],
+                                       OUTMODE_DIVERSITY);
+                       dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
+               }
+
+               /* turn off the diversity of the last chip */
+               dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
+       } else {
+               dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
+               if (state->cfg.enMpegOutput == 0) {
+                       dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
+                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+               }
+               for (index_frontend = 1;
+                               (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
+                               (state->fe[index_frontend] != NULL);
+                               index_frontend++) {
+                       dib8096p_set_output_mode(state->fe[index_frontend],
+                                       OUTMODE_DIVERSITY);
+                       dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
+               }
+
+               /* turn off the diversity of the last chip */
+               dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
+       }
+
+       return ret;
+}
+
+static u16 dib8000_read_lock(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       if (state->revision == 0x8090)
+               return dib8000_read_word(state, 570);
+       return dib8000_read_word(state, 568);
+}
+
+static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u16 lock_slave = 0, lock;
+       u8 index_frontend;
+
+       if (state->revision == 0x8090)
+               lock = dib8000_read_word(state, 570);
+       else
+               lock = dib8000_read_word(state, 568);
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
+
+       *stat = 0;
+
+       if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
+               *stat |= FE_HAS_SIGNAL;
+
+       if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
+               *stat |= FE_HAS_CARRIER;
+
+       if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
+               *stat |= FE_HAS_SYNC;
+
+       if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
+               *stat |= FE_HAS_LOCK;
+
+       if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
+               lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
+               if (lock & 0x01)
+                       *stat |= FE_HAS_VITERBI;
+
+               lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
+               if (lock & 0x01)
+                       *stat |= FE_HAS_VITERBI;
+
+               lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
+               if (lock & 0x01)
+                       *stat |= FE_HAS_VITERBI;
+       }
+
+       return 0;
+}
+
+static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       /* 13 segments */
+       if (state->revision == 0x8090)
+               *ber = (dib8000_read_word(state, 562) << 16) |
+                       dib8000_read_word(state, 563);
+       else
+               *ber = (dib8000_read_word(state, 560) << 16) |
+                       dib8000_read_word(state, 561);
+       return 0;
+}
+
+static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       /* packet error on 13 seg */
+       if (state->revision == 0x8090)
+               *unc = dib8000_read_word(state, 567);
+       else
+               *unc = dib8000_read_word(state, 565);
+       return 0;
+}
+
+static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       u16 val;
+
+       *strength = 0;
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
+               if (val > 65535 - *strength)
+                       *strength = 65535;
+               else
+                       *strength += val;
+       }
+
+       val = 65535 - dib8000_read_word(state, 390);
+       if (val > 65535 - *strength)
+               *strength = 65535;
+       else
+               *strength += val;
+       return 0;
+}
+
+static u32 dib8000_get_snr(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u32 n, s, exp;
+       u16 val;
+
+       if (state->revision != 0x8090)
+               val = dib8000_read_word(state, 542);
+       else
+               val = dib8000_read_word(state, 544);
+       n = (val >> 6) & 0xff;
+       exp = (val & 0x3f);
+       if ((exp & 0x20) != 0)
+               exp -= 0x40;
+       n <<= exp+16;
+
+       if (state->revision != 0x8090)
+               val = dib8000_read_word(state, 543);
+       else
+               val = dib8000_read_word(state, 545);
+       s = (val >> 6) & 0xff;
+       exp = (val & 0x3f);
+       if ((exp & 0x20) != 0)
+               exp -= 0x40;
+       s <<= exp+16;
+
+       if (n > 0) {
+               u32 t = (s/n) << 16;
+               return t + ((s << 16) - n*t) / n;
+       }
+       return 0xffffffff;
+}
+
+static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       u32 snr_master;
+
+       snr_master = dib8000_get_snr(fe);
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               snr_master += dib8000_get_snr(state->fe[index_frontend]);
+
+       if ((snr_master >> 16) != 0) {
+               snr_master = 10*intlog10(snr_master>>16);
+               *snr = snr_master / ((1 << 24) / 10);
+       }
+       else
+               *snr = 0;
+
+       return 0;
+}
+
+int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend = 1;
+
+       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
+               index_frontend++;
+       if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
+               dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
+               state->fe[index_frontend] = fe_slave;
+               return 0;
+       }
+
+       dprintk("too many slave frontend");
+       return -ENOMEM;
+}
+EXPORT_SYMBOL(dib8000_set_slave_frontend);
+
+int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+       u8 index_frontend = 1;
+
+       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
+               index_frontend++;
+       if (index_frontend != 1) {
+               dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
+               state->fe[index_frontend] = NULL;
+               return 0;
+       }
+
+       dprintk("no frontend to be removed");
+       return -ENODEV;
+}
+EXPORT_SYMBOL(dib8000_remove_slave_frontend);
+
+struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+{
+       struct dib8000_state *state = fe->demodulator_priv;
+
+       if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
+               return NULL;
+       return state->fe[slave_index];
+}
+EXPORT_SYMBOL(dib8000_get_slave_frontend);
+
+
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+               u8 default_addr, u8 first_addr, u8 is_dib8096p)
+{
+       int k = 0, ret = 0;
+       u8 new_addr = 0;
+       struct i2c_device client = {.adap = host };
+
+       client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+       if (!client.i2c_write_buffer) {
+               dprintk("%s: not enough memory", __func__);
+               return -ENOMEM;
+       }
+       client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+       if (!client.i2c_read_buffer) {
+               dprintk("%s: not enough memory", __func__);
+               ret = -ENOMEM;
+               goto error_memory_read;
+       }
+       client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
+       if (!client.i2c_buffer_lock) {
+               dprintk("%s: not enough memory", __func__);
+               ret = -ENOMEM;
+               goto error_memory_lock;
+       }
+       mutex_init(client.i2c_buffer_lock);
+
+       for (k = no_of_demods - 1; k >= 0; k--) {
+               /* designated i2c address */
+               new_addr = first_addr + (k << 1);
+
+               client.addr = new_addr;
+               if (!is_dib8096p)
+                       dib8000_i2c_write16(&client, 1287, 0x0003);     /* sram lead in, rdy */
+               if (dib8000_identify(&client) == 0) {
+                       /* sram lead in, rdy */
+                       if (!is_dib8096p)
+                               dib8000_i2c_write16(&client, 1287, 0x0003);
+                       client.addr = default_addr;
+                       if (dib8000_identify(&client) == 0) {
+                               dprintk("#%d: not identified", k);
+                               ret  = -EINVAL;
+                               goto error;
+                       }
+               }
+
+               /* start diversity to pull_down div_str - just for i2c-enumeration */
+               dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
+
+               /* set new i2c address and force divstart */
+               dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
+               client.addr = new_addr;
+               dib8000_identify(&client);
+
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+       }
+
+       for (k = 0; k < no_of_demods; k++) {
+               new_addr = first_addr | (k << 1);
+               client.addr = new_addr;
+
+               // unforce divstr
+               dib8000_i2c_write16(&client, 1285, new_addr << 2);
+
+               /* deactivate div - it was just for i2c-enumeration */
+               dib8000_i2c_write16(&client, 1286, 0);
+       }
+
+error:
+       kfree(client.i2c_buffer_lock);
+error_memory_lock:
+       kfree(client.i2c_read_buffer);
+error_memory_read:
+       kfree(client.i2c_write_buffer);
+
+       return ret;
+}
+
+EXPORT_SYMBOL(dib8000_i2c_enumeration);
+static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       tune->step_size = 0;
+       tune->max_drift = 0;
+       return 0;
+}
+
+static void dib8000_release(struct dvb_frontend *fe)
+{
+       struct dib8000_state *st = fe->demodulator_priv;
+       u8 index_frontend;
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
+               dvb_frontend_detach(st->fe[index_frontend]);
+
+       dibx000_exit_i2c_master(&st->i2c_master);
+       i2c_del_adapter(&st->dib8096p_tuner_adap);
+       kfree(st->fe[0]);
+       kfree(st);
+}
+
+struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+{
+       struct dib8000_state *st = fe->demodulator_priv;
+       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+
+EXPORT_SYMBOL(dib8000_get_i2c_master);
+
+int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       struct dib8000_state *st = fe->demodulator_priv;
+       u16 val = dib8000_read_word(st, 299) & 0xffef;
+       val |= (onoff & 0x1) << 4;
+
+       dprintk("pid filter enabled %d", onoff);
+       return dib8000_write_word(st, 299, val);
+}
+EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
+
+int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       struct dib8000_state *st = fe->demodulator_priv;
+       dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
+       return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib8000_pid_filter);
+
+static const struct dvb_frontend_ops dib8000_ops = {
+       .delsys = { SYS_ISDBT },
+       .info = {
+                .name = "DiBcom 8000 ISDB-T",
+                .frequency_min = 44250000,
+                .frequency_max = 867250000,
+                .frequency_stepsize = 62500,
+                .caps = FE_CAN_INVERSION_AUTO |
+                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+                },
+
+       .release = dib8000_release,
+
+       .init = dib8000_wakeup,
+       .sleep = dib8000_sleep,
+
+       .set_frontend = dib8000_set_frontend,
+       .get_tune_settings = dib8000_fe_get_tune_settings,
+       .get_frontend = dib8000_get_frontend,
+
+       .read_status = dib8000_read_status,
+       .read_ber = dib8000_read_ber,
+       .read_signal_strength = dib8000_read_signal_strength,
+       .read_snr = dib8000_read_snr,
+       .read_ucblocks = dib8000_read_unc_blocks,
+};
+
+struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+       struct dvb_frontend *fe;
+       struct dib8000_state *state;
+
+       dprintk("dib8000_attach");
+
+       state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+       fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
+       if (fe == NULL)
+               goto error;
+
+       memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
+       state->i2c.adap = i2c_adap;
+       state->i2c.addr = i2c_addr;
+       state->i2c.i2c_write_buffer = state->i2c_write_buffer;
+       state->i2c.i2c_read_buffer = state->i2c_read_buffer;
+       mutex_init(&state->i2c_buffer_lock);
+       state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
+       state->gpio_val = cfg->gpio_val;
+       state->gpio_dir = cfg->gpio_dir;
+
+       /* Ensure the output mode remains at the previous default if it's
+        * not specifically set by the caller.
+        */
+       if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
+               state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
+       state->fe[0] = fe;
+       fe->demodulator_priv = state;
+       memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
+
+       state->timf_default = cfg->pll->timf;
+
+       if (dib8000_identify(&state->i2c) == 0)
+               goto error;
+
+       dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
+
+       /* init 8096p tuner adapter */
+       strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
+                       sizeof(state->dib8096p_tuner_adap.name));
+       state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
+       state->dib8096p_tuner_adap.algo_data = NULL;
+       state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
+       i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
+       i2c_add_adapter(&state->dib8096p_tuner_adap);
+
+       dib8000_reset(fe);
+
+       dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));     /* ber_rs_len = 3 */
+
+       return fe;
+
+ error:
+       kfree(state);
+       return NULL;
+}
+
+EXPORT_SYMBOL(dib8000_attach);
+
+MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h
new file mode 100644 (file)
index 0000000..39591bb
--- /dev/null
@@ -0,0 +1,174 @@
+#ifndef DIB8000_H
+#define DIB8000_H
+
+#include "dibx000_common.h"
+
+struct dib8000_config {
+       u8 output_mpeg2_in_188_bytes;
+       u8 hostbus_diversity;
+       u8 tuner_is_baseband;
+       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
+
+       u8 agc_config_count;
+       struct dibx000_agc_config *agc;
+       struct dibx000_bandwidth_config *pll;
+
+#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
+       u16 gpio_dir;
+#define DIB8000_GPIO_DEFAULT_VALUES     0x0000
+       u16 gpio_val;
+#define DIB8000_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
+#define DIB8000_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
+#define DIB8000_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
+#define DIB8000_GPIO_PWM_POS3(v)         (v & 0xf)
+#define DIB8000_GPIO_DEFAULT_PWM_POS    0xffff
+       u16 gpio_pwm_pos;
+       u16 pwm_freq_div;
+
+       void (*agc_control) (struct dvb_frontend *, u8 before);
+
+       u16 drives;
+       u16 diversity_delay;
+       u8 div_cfg;
+       u8 output_mode;
+       u8 refclksel;
+       u8 enMpegOutput:1;
+};
+
+#define DEFAULT_DIB8000_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
+extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+
+extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+               u8 default_addr, u8 first_addr, u8 is_dib8096p);
+
+extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
+extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
+extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
+extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
+extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
+extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
+extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
+extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
+extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
+extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
+               uint8_t op, uint32_t timf);
+extern int dib8000_update_pll(struct dvb_frontend *fe,
+               struct dibx000_bandwidth_config *pll);
+extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
+extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
+extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
+#else
+static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
+               int no_of_demods, u8 default_addr, u8 first_addr,
+               u8 is_dib8096p)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return CT_SHUTDOWN;
+}
+static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
+               uint8_t op, uint32_t timf)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return 0;
+}
+static inline int dib8000_update_pll(struct dvb_frontend *fe,
+               struct dibx000_bandwidth_config *pll)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
new file mode 100644 (file)
index 0000000..6201c59
--- /dev/null
@@ -0,0 +1,2590 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
+ *
+ * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#include "dvb_math.h"
+#include "dvb_frontend.h"
+
+#include "dib9000.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0)
+#define MAX_NUMBER_OF_FRONTENDS 6
+
+struct i2c_device {
+       struct i2c_adapter *i2c_adap;
+       u8 i2c_addr;
+       u8 *i2c_read_buffer;
+       u8 *i2c_write_buffer;
+};
+
+struct dib9000_pid_ctrl {
+#define DIB9000_PID_FILTER_CTRL 0
+#define DIB9000_PID_FILTER      1
+       u8 cmd;
+       u8 id;
+       u16 pid;
+       u8 onoff;
+};
+
+struct dib9000_state {
+       struct i2c_device i2c;
+
+       struct dibx000_i2c_master i2c_master;
+       struct i2c_adapter tuner_adap;
+       struct i2c_adapter component_bus;
+
+       u16 revision;
+       u8 reg_offs;
+
+       enum frontend_tune_state tune_state;
+       u32 status;
+       struct dvb_frontend_parametersContext channel_status;
+
+       u8 fe_id;
+
+#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
+       u16 gpio_dir;
+#define DIB9000_GPIO_DEFAULT_VALUES     0x0000
+       u16 gpio_val;
+#define DIB9000_GPIO_DEFAULT_PWM_POS    0xffff
+       u16 gpio_pwm_pos;
+
+       union {                 /* common for all chips */
+               struct {
+                       u8 mobile_mode:1;
+               } host;
+
+               struct {
+                       struct dib9000_fe_memory_map {
+                               u16 addr;
+                               u16 size;
+                       } fe_mm[18];
+                       u8 memcmd;
+
+                       struct mutex mbx_if_lock;       /* to protect read/write operations */
+                       struct mutex mbx_lock;  /* to protect the whole mailbox handling */
+
+                       struct mutex mem_lock;  /* to protect the memory accesses */
+                       struct mutex mem_mbx_lock;      /* to protect the memory-based mailbox */
+
+#define MBX_MAX_WORDS (256 - 200 - 2)
+#define DIB9000_MSG_CACHE_SIZE 2
+                       u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
+                       u8 fw_is_running;
+               } risc;
+       } platform;
+
+       union {                 /* common for all platforms */
+               struct {
+                       struct dib9000_config cfg;
+               } d9;
+       } chip;
+
+       struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
+       u16 component_bus_speed;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[2];
+       u8 i2c_write_buffer[255];
+       u8 i2c_read_buffer[255];
+       struct mutex demod_lock;
+       u8 get_frontend_internal;
+       struct dib9000_pid_ctrl pid_ctrl[10];
+       s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
+};
+
+static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0
+};
+
+enum dib9000_power_mode {
+       DIB9000_POWER_ALL = 0,
+
+       DIB9000_POWER_NO,
+       DIB9000_POWER_INTERF_ANALOG_AGC,
+       DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
+       DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
+       DIB9000_POWER_INTERFACE_ONLY,
+};
+
+enum dib9000_out_messages {
+       OUT_MSG_HBM_ACK,
+       OUT_MSG_HOST_BUF_FAIL,
+       OUT_MSG_REQ_VERSION,
+       OUT_MSG_BRIDGE_I2C_W,
+       OUT_MSG_BRIDGE_I2C_R,
+       OUT_MSG_BRIDGE_APB_W,
+       OUT_MSG_BRIDGE_APB_R,
+       OUT_MSG_SCAN_CHANNEL,
+       OUT_MSG_MONIT_DEMOD,
+       OUT_MSG_CONF_GPIO,
+       OUT_MSG_DEBUG_HELP,
+       OUT_MSG_SUBBAND_SEL,
+       OUT_MSG_ENABLE_TIME_SLICE,
+       OUT_MSG_FE_FW_DL,
+       OUT_MSG_FE_CHANNEL_SEARCH,
+       OUT_MSG_FE_CHANNEL_TUNE,
+       OUT_MSG_FE_SLEEP,
+       OUT_MSG_FE_SYNC,
+       OUT_MSG_CTL_MONIT,
+
+       OUT_MSG_CONF_SVC,
+       OUT_MSG_SET_HBM,
+       OUT_MSG_INIT_DEMOD,
+       OUT_MSG_ENABLE_DIVERSITY,
+       OUT_MSG_SET_OUTPUT_MODE,
+       OUT_MSG_SET_PRIORITARY_CHANNEL,
+       OUT_MSG_ACK_FRG,
+       OUT_MSG_INIT_PMU,
+};
+
+enum dib9000_in_messages {
+       IN_MSG_DATA,
+       IN_MSG_FRAME_INFO,
+       IN_MSG_CTL_MONIT,
+       IN_MSG_ACK_FREE_ITEM,
+       IN_MSG_DEBUG_BUF,
+       IN_MSG_MPE_MONITOR,
+       IN_MSG_RAWTS_MONITOR,
+       IN_MSG_END_BRIDGE_I2C_RW,
+       IN_MSG_END_BRIDGE_APB_RW,
+       IN_MSG_VERSION,
+       IN_MSG_END_OF_SCAN,
+       IN_MSG_MONIT_DEMOD,
+       IN_MSG_ERROR,
+       IN_MSG_FE_FW_DL_DONE,
+       IN_MSG_EVENT,
+       IN_MSG_ACK_CHANGE_SVC,
+       IN_MSG_HBM_PROF,
+};
+
+/* memory_access requests */
+#define FE_MM_W_CHANNEL                   0
+#define FE_MM_W_FE_INFO                   1
+#define FE_MM_RW_SYNC                     2
+
+#define FE_SYNC_CHANNEL          1
+#define FE_SYNC_W_GENERIC_MONIT         2
+#define FE_SYNC_COMPONENT_ACCESS 3
+
+#define FE_MM_R_CHANNEL_SEARCH_STATE      3
+#define FE_MM_R_CHANNEL_UNION_CONTEXT     4
+#define FE_MM_R_FE_INFO                   5
+#define FE_MM_R_FE_MONITOR                6
+
+#define FE_MM_W_CHANNEL_HEAD              7
+#define FE_MM_W_CHANNEL_UNION             8
+#define FE_MM_W_CHANNEL_CONTEXT           9
+#define FE_MM_R_CHANNEL_UNION            10
+#define FE_MM_R_CHANNEL_CONTEXT          11
+#define FE_MM_R_CHANNEL_TUNE_STATE       12
+
+#define FE_MM_R_GENERIC_MONITORING_SIZE         13
+#define FE_MM_W_GENERIC_MONITORING          14
+#define FE_MM_R_GENERIC_MONITORING          15
+
+#define FE_MM_W_COMPONENT_ACCESS         16
+#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
+static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
+static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
+
+static u16 to_fw_output_mode(u16 mode)
+{
+       switch (mode) {
+       case OUTMODE_HIGH_Z:
+               return 0;
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+               return 4;
+       case OUTMODE_MPEG2_PAR_CONT_CLK:
+               return 8;
+       case OUTMODE_MPEG2_SERIAL:
+               return 16;
+       case OUTMODE_DIVERSITY:
+               return 128;
+       case OUTMODE_MPEG2_FIFO:
+               return 2;
+       case OUTMODE_ANALOG_ADC:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 len, u16 attribute)
+{
+       u32 chunk_size = 126;
+       u32 l;
+       int ret;
+
+       if (state->platform.risc.fw_is_running && (reg < 1024))
+               return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
+
+       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c.i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = 2;
+       state->msg[1].addr = state->i2c.i2c_addr >> 1;
+       state->msg[1].flags = I2C_M_RD;
+       state->msg[1].buf = b;
+       state->msg[1].len = len;
+
+       state->i2c_write_buffer[0] = reg >> 8;
+       state->i2c_write_buffer[1] = reg & 0xff;
+
+       if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
+               state->i2c_write_buffer[0] |= (1 << 5);
+       if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+               state->i2c_write_buffer[0] |= (1 << 4);
+
+       do {
+               l = len < chunk_size ? len : chunk_size;
+               state->msg[1].len = l;
+               state->msg[1].buf = b;
+               ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
+               if (ret != 0) {
+                       dprintk("i2c read error on %d", reg);
+                       return -EREMOTEIO;
+               }
+
+               b += l;
+               len -= l;
+
+               if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
+                       reg += l / 2;
+       } while ((ret == 0) && len);
+
+       return 0;
+}
+
+static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
+{
+       struct i2c_msg msg[2] = {
+               {.addr = i2c->i2c_addr >> 1, .flags = 0,
+                       .buf = i2c->i2c_write_buffer, .len = 2},
+               {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
+                       .buf = i2c->i2c_read_buffer, .len = 2},
+       };
+
+       i2c->i2c_write_buffer[0] = reg >> 8;
+       i2c->i2c_write_buffer[1] = reg & 0xff;
+
+       if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
+               dprintk("read register %x error", reg);
+               return 0;
+       }
+
+       return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
+}
+
+static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
+{
+       if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
+               return 0;
+       return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+}
+
+static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
+{
+       if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
+                               attribute) != 0)
+               return 0;
+       return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+}
+
+#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+
+static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
+{
+       u32 chunk_size = 126;
+       u32 l;
+       int ret;
+
+       if (state->platform.risc.fw_is_running && (reg < 1024)) {
+               if (dib9000_risc_apb_access_write
+                   (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
+                       return -EINVAL;
+               return 0;
+       }
+
+       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+       state->msg[0].addr = state->i2c.i2c_addr >> 1;
+       state->msg[0].flags = 0;
+       state->msg[0].buf = state->i2c_write_buffer;
+       state->msg[0].len = len + 2;
+
+       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       state->i2c_write_buffer[1] = (reg) & 0xff;
+
+       if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
+               state->i2c_write_buffer[0] |= (1 << 5);
+       if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+               state->i2c_write_buffer[0] |= (1 << 4);
+
+       do {
+               l = len < chunk_size ? len : chunk_size;
+               state->msg[0].len = l + 2;
+               memcpy(&state->i2c_write_buffer[2], buf, l);
+
+               ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+
+               buf += l;
+               len -= l;
+
+               if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
+                       reg += l / 2;
+       } while ((ret == 0) && len);
+
+       return ret;
+}
+
+static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
+{
+       struct i2c_msg msg = {
+               .addr = i2c->i2c_addr >> 1, .flags = 0,
+               .buf = i2c->i2c_write_buffer, .len = 4
+       };
+
+       i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       i2c->i2c_write_buffer[1] = reg & 0xff;
+       i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
+       i2c->i2c_write_buffer[3] = val & 0xff;
+
+       return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
+{
+       u8 b[2] = { val >> 8, val & 0xff };
+       return dib9000_write16_attr(state, reg, b, 2, 0);
+}
+
+static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
+{
+       u8 b[2] = { val >> 8, val & 0xff };
+       return dib9000_write16_attr(state, reg, b, 2, attribute);
+}
+
+#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
+#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
+
+#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
+#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
+
+#define MAC_IRQ      (1 << 1)
+#define IRQ_POL_MSK  (1 << 4)
+
+#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
+
+static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
+{
+       u8 b[14] = { 0 };
+
+/*      dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
+/*      b[0] = 0 << 7; */
+       b[1] = 1;
+
+/*      b[2] = 0; */
+/*      b[3] = 0; */
+       b[4] = (u8) (addr >> 8);
+       b[5] = (u8) (addr & 0xff);
+
+/*      b[10] = 0; */
+/*      b[11] = 0; */
+       b[12] = (u8) (addr >> 8);
+       b[13] = (u8) (addr & 0xff);
+
+       addr += len;
+/*      b[6] = 0; */
+/*      b[7] = 0; */
+       b[8] = (u8) (addr >> 8);
+       b[9] = (u8) (addr & 0xff);
+
+       dib9000_write(state, 1056, b, 14);
+       if (reading)
+               dib9000_write_word(state, 1056, (1 << 15) | 1);
+       state->platform.risc.memcmd = -1;       /* if it was called directly reset it - to force a future setup-call to set it */
+}
+
+static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
+{
+       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
+       /* decide whether we need to "refresh" the memory controller */
+       if (state->platform.risc.memcmd == cmd &&       /* same command */
+           !(cmd & 0x80 && m->size < 67))      /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
+               return;
+       dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
+       state->platform.risc.memcmd = cmd;
+}
+
+static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
+{
+       if (!state->platform.risc.fw_is_running)
+               return -EIO;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       dib9000_risc_mem_setup(state, cmd | 0x80);
+       dib9000_risc_mem_read_chunks(state, b, len);
+       mutex_unlock(&state->platform.risc.mem_lock);
+       return 0;
+}
+
+static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
+{
+       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
+       if (!state->platform.risc.fw_is_running)
+               return -EIO;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       dib9000_risc_mem_setup(state, cmd);
+       dib9000_risc_mem_write_chunks(state, b, m->size);
+       mutex_unlock(&state->platform.risc.mem_lock);
+       return 0;
+}
+
+static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
+{
+       u16 offs;
+
+       if (risc_id == 1)
+               offs = 16;
+       else
+               offs = 0;
+
+       /* config crtl reg */
+       dib9000_write_word(state, 1024 + offs, 0x000f);
+       dib9000_write_word(state, 1025 + offs, 0);
+       dib9000_write_word(state, 1031 + offs, key);
+
+       dprintk("going to download %dB of microcode", len);
+       if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
+               dprintk("error while downloading microcode for RISC %c", 'A' + risc_id);
+               return -EIO;
+       }
+
+       dprintk("Microcode for RISC %c loaded", 'A' + risc_id);
+
+       return 0;
+}
+
+static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
+{
+       u16 mbox_offs;
+       u16 reset_reg;
+       u16 tries = 1000;
+
+       if (risc_id == 1)
+               mbox_offs = 16;
+       else
+               mbox_offs = 0;
+
+       /* Reset mailbox  */
+       dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
+
+       /* Read reset status */
+       do {
+               reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
+               msleep(100);
+       } while ((reset_reg & 0x8000) && --tries);
+
+       if (reset_reg & 0x8000) {
+               dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id);
+               return -EIO;
+       }
+       dprintk("MBX: initialized");
+       return 0;
+}
+
+#define MAX_MAILBOX_TRY 100
+static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
+{
+       u8 *d, b[2];
+       u16 tmp;
+       u16 size;
+       u32 i;
+       int ret = 0;
+
+       if (!state->platform.risc.fw_is_running)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       tmp = MAX_MAILBOX_TRY;
+       do {
+               size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
+               if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
+                       dprintk("MBX: RISC mbx full, retrying");
+                       msleep(100);
+               } else
+                       break;
+       } while (1);
+
+       /*dprintk( "MBX: size: %d", size); */
+
+       if (tmp == 0) {
+               ret = -EINVAL;
+               goto out;
+       }
+#ifdef DUMP_MSG
+       dprintk("--> %02x %d ", id, len + 1);
+       for (i = 0; i < len; i++)
+               dprintk("%04x ", data[i]);
+       dprintk("\n");
+#endif
+
+       /* byte-order conversion - works on big (where it is not necessary) or little endian */
+       d = (u8 *) data;
+       for (i = 0; i < len; i++) {
+               tmp = data[i];
+               *d++ = tmp >> 8;
+               *d++ = tmp & 0xff;
+       }
+
+       /* write msg */
+       b[0] = id;
+       b[1] = len + 1;
+       if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
+               ret = -EIO;
+               goto out;
+       }
+
+       /* update register nb_mes_in_RX */
+       ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
+
+out:
+       mutex_unlock(&state->platform.risc.mbx_if_lock);
+
+       return ret;
+}
+
+static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
+{
+#ifdef DUMP_MSG
+       u16 *d = data;
+#endif
+
+       u16 tmp, i;
+       u8 size;
+       u8 mc_base;
+
+       if (!state->platform.risc.fw_is_running)
+               return 0;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
+               dprintk("could not get the lock");
+               return 0;
+       }
+       if (risc_id == 1)
+               mc_base = 16;
+       else
+               mc_base = 0;
+
+       /* Length and type in the first word */
+       *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
+
+       size = *data & 0xff;
+       if (size <= MBX_MAX_WORDS) {
+               data++;
+               size--;         /* Initial word already read */
+
+               dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
+
+               /* to word conversion */
+               for (i = 0; i < size; i++) {
+                       tmp = *data;
+                       *data = (tmp >> 8) | (tmp << 8);
+                       data++;
+               }
+
+#ifdef DUMP_MSG
+               dprintk("<-- ");
+               for (i = 0; i < size + 1; i++)
+                       dprintk("%04x ", d[i]);
+               dprintk("\n");
+#endif
+       } else {
+               dprintk("MBX: message is too big for message cache (%d), flushing message", size);
+               size--;         /* Initial word already read */
+               while (size--)
+                       dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
+       }
+       /* Update register nb_mes_in_TX */
+       dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
+
+       mutex_unlock(&state->platform.risc.mbx_if_lock);
+
+       return size + 1;
+}
+
+static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
+{
+       u32 ts = data[1] << 16 | data[0];
+       char *b = (char *)&data[2];
+
+       b[2 * (size - 2) - 1] = '\0';   /* Bullet proof the buffer */
+       if (*b == '~') {
+               b++;
+               dprintk(b);
+       } else
+               dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>");
+       return 1;
+}
+
+static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
+{
+       int i;
+       u8 size;
+       u16 *block;
+       /* find a free slot */
+       for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
+               block = state->platform.risc.message_cache[i];
+               if (*block == 0) {
+                       size = dib9000_mbx_read(state, block, 1, attr);
+
+/*                      dprintk( "MBX: fetched %04x message to cache", *block); */
+
+                       switch (*block >> 8) {
+                       case IN_MSG_DEBUG_BUF:
+                               dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
+                               *block = 0;     /* free the block */
+                               break;
+#if 0
+                       case IN_MSG_DATA:       /* FE-TRACE */
+                               dib9000_risc_data_process(state, block + 1, size);
+                               *block = 0;
+                               break;
+#endif
+                       default:
+                               break;
+                       }
+
+                       return 1;
+               }
+       }
+       dprintk("MBX: no free cache-slot found for new message...");
+       return -1;
+}
+
+static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
+{
+       if (risc_id == 0)
+               return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f;   /* 5 bit field */
+       else
+               return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f;    /* 7 bit field */
+}
+
+static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
+{
+       int ret = 0;
+
+       if (!state->platform.risc.fw_is_running)
+               return -1;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               return -1;
+       }
+
+       if (dib9000_mbx_count(state, 1, attr))  /* 1=RiscB */
+               ret = dib9000_mbx_fetch_to_cache(state, attr);
+
+       dib9000_read_word_attr(state, 1229, attr);      /* Clear the IRQ */
+/*      if (tmp) */
+/*              dprintk( "cleared IRQ: %x", tmp); */
+       mutex_unlock(&state->platform.risc.mbx_lock);
+
+       return ret;
+}
+
+static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
+{
+       u8 i;
+       u16 *block;
+       u16 timeout = 30;
+
+       *msg = 0;
+       do {
+               /* dib9000_mbx_get_from_cache(); */
+               for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
+                       block = state->platform.risc.message_cache[i];
+                       if ((*block >> 8) == id) {
+                               *size = (*block & 0xff) - 1;
+                               memcpy(msg, block + 1, (*size) * 2);
+                               *block = 0;     /* free the block */
+                               i = 0;  /* signal that we found a message */
+                               break;
+                       }
+               }
+
+               if (i == 0)
+                       break;
+
+               if (dib9000_mbx_process(state, attr) == -1)     /* try to fetch one message - if any */
+                       return -1;
+
+       } while (--timeout);
+
+       if (timeout == 0) {
+               dprintk("waiting for message %d timed out", id);
+               return -1;
+       }
+
+       return i == 0;
+}
+
+static int dib9000_risc_check_version(struct dib9000_state *state)
+{
+       u8 r[4];
+       u8 size;
+       u16 fw_version = 0;
+
+       if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
+               return -EIO;
+
+       if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
+               return -EIO;
+
+       fw_version = (r[0] << 8) | r[1];
+       dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
+
+       if ((fw_version >> 10) != 7)
+               return -EINVAL;
+
+       switch (fw_version & 0x3ff) {
+       case 11:
+       case 12:
+       case 14:
+       case 15:
+       case 16:
+       case 17:
+               break;
+       default:
+               dprintk("RISC: invalid firmware version");
+               return -EINVAL;
+       }
+
+       dprintk("RISC: valid firmware version");
+       return 0;
+}
+
+static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
+{
+       /* Reconfig pool mac ram */
+       dib9000_write_word(state, 1225, 0x02);  /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
+       dib9000_write_word(state, 1226, 0x05);
+
+       /* Toggles IP crypto to Host APB interface. */
+       dib9000_write_word(state, 1542, 1);
+
+       /* Set jump and no jump in the dma box */
+       dib9000_write_word(state, 1074, 0);
+       dib9000_write_word(state, 1075, 0);
+
+       /* Set MAC as APB Master. */
+       dib9000_write_word(state, 1237, 0);
+
+       /* Reset the RISCs */
+       if (codeA != NULL)
+               dib9000_write_word(state, 1024, 2);
+       else
+               dib9000_write_word(state, 1024, 15);
+       if (codeB != NULL)
+               dib9000_write_word(state, 1040, 2);
+
+       if (codeA != NULL)
+               dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
+       if (codeB != NULL)
+               dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
+
+       /* Run the RISCs */
+       if (codeA != NULL)
+               dib9000_write_word(state, 1024, 0);
+       if (codeB != NULL)
+               dib9000_write_word(state, 1040, 0);
+
+       if (codeA != NULL)
+               if (dib9000_mbx_host_init(state, 0) != 0)
+                       return -EIO;
+       if (codeB != NULL)
+               if (dib9000_mbx_host_init(state, 1) != 0)
+                       return -EIO;
+
+       msleep(100);
+       state->platform.risc.fw_is_running = 1;
+
+       if (dib9000_risc_check_version(state) != 0)
+               return -EINVAL;
+
+       state->platform.risc.memcmd = 0xff;
+       return 0;
+}
+
+static u16 dib9000_identify(struct i2c_device *client)
+{
+       u16 value;
+
+       value = dib9000_i2c_read16(client, 896);
+       if (value != 0x01b3) {
+               dprintk("wrong Vendor ID (0x%x)", value);
+               return 0;
+       }
+
+       value = dib9000_i2c_read16(client, 897);
+       if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
+               dprintk("wrong Device ID (0x%x)", value);
+               return 0;
+       }
+
+       /* protect this driver to be used with 7000PC */
+       if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
+               dprintk("this driver does not work with DiB7000PC");
+               return 0;
+       }
+
+       switch (value) {
+       case 0x4000:
+               dprintk("found DiB7000MA/PA/MB/PB");
+               break;
+       case 0x4001:
+               dprintk("found DiB7000HC");
+               break;
+       case 0x4002:
+               dprintk("found DiB7000MC");
+               break;
+       case 0x4003:
+               dprintk("found DiB9000A");
+               break;
+       case 0x4004:
+               dprintk("found DiB9000H");
+               break;
+       case 0x4005:
+               dprintk("found DiB9000M");
+               break;
+       }
+
+       return value;
+}
+
+static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
+{
+       /* by default everything is going to be powered off */
+       u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
+       u8 offset;
+
+       if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
+               offset = 1;
+       else
+               offset = 0;
+
+       reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
+
+       /* now, depending on the requested mode, we power on */
+       switch (mode) {
+               /* power up everything in the demod */
+       case DIB9000_POWER_ALL:
+               reg_903 = 0x0000;
+               reg_904 = 0x0000;
+               reg_905 = 0x0000;
+               reg_906 = 0x0000;
+               break;
+
+               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
+       case DIB9000_POWER_INTERFACE_ONLY:      /* TODO power up either SDIO or I2C or SRAM */
+               reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
+               break;
+
+       case DIB9000_POWER_INTERF_ANALOG_AGC:
+               reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
+               reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
+               reg_906 &= ~((1 << 0));
+               break;
+
+       case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
+               reg_903 = 0x0000;
+               reg_904 = 0x801f;
+               reg_905 = 0x0000;
+               reg_906 &= ~((1 << 0));
+               break;
+
+       case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
+               reg_903 = 0x0000;
+               reg_904 = 0x8000;
+               reg_905 = 0x010b;
+               reg_906 &= ~((1 << 0));
+               break;
+       default:
+       case DIB9000_POWER_NO:
+               break;
+       }
+
+       /* always power down unused parts */
+       if (!state->platform.host.mobile_mode)
+               reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
+
+       /* P_sdio_select_clk = 0 on MC and after */
+       if (state->revision != 0x4000)
+               reg_906 <<= 1;
+
+       dib9000_write_word(state, 903 + offset, reg_903);
+       dib9000_write_word(state, 904 + offset, reg_904);
+       dib9000_write_word(state, 905 + offset, reg_905);
+       dib9000_write_word(state, 906 + offset, reg_906);
+}
+
+static int dib9000_fw_reset(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+
+       dib9000_write_word(state, 1817, 0x0003);
+
+       dib9000_write_word(state, 1227, 1);
+       dib9000_write_word(state, 1227, 0);
+
+       switch ((state->revision = dib9000_identify(&state->i2c))) {
+       case 0x4003:
+       case 0x4004:
+       case 0x4005:
+               state->reg_offs = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* reset the i2c-master to use the host interface */
+       dibx000_reset_i2c_master(&state->i2c_master);
+
+       dib9000_set_power_mode(state, DIB9000_POWER_ALL);
+
+       /* unforce divstr regardless whether i2c enumeration was done or not */
+       dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
+       dib9000_write_word(state, 1796, 0);
+       dib9000_write_word(state, 1805, 0x805);
+
+       /* restart all parts */
+       dib9000_write_word(state, 898, 0xffff);
+       dib9000_write_word(state, 899, 0xffff);
+       dib9000_write_word(state, 900, 0x0001);
+       dib9000_write_word(state, 901, 0xff19);
+       dib9000_write_word(state, 902, 0x003c);
+
+       dib9000_write_word(state, 898, 0);
+       dib9000_write_word(state, 899, 0);
+       dib9000_write_word(state, 900, 0);
+       dib9000_write_word(state, 901, 0);
+       dib9000_write_word(state, 902, 0);
+
+       dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
+
+       dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
+
+       return 0;
+}
+
+static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
+{
+       u16 mb[10];
+       u8 i, s;
+
+       if (address >= 1024 || !state->platform.risc.fw_is_running)
+               return -EINVAL;
+
+       /* dprintk( "APB access thru rd fw %d %x", address, attribute); */
+
+       mb[0] = (u16) address;
+       mb[1] = len / 2;
+       dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
+       switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
+       case 1:
+               s--;
+               for (i = 0; i < s; i++) {
+                       b[i * 2] = (mb[i + 1] >> 8) & 0xff;
+                       b[i * 2 + 1] = (mb[i + 1]) & 0xff;
+               }
+               return 0;
+       default:
+               return -EIO;
+       }
+       return -EIO;
+}
+
+static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
+{
+       u16 mb[10];
+       u8 s, i;
+
+       if (address >= 1024 || !state->platform.risc.fw_is_running)
+               return -EINVAL;
+
+       /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
+
+       mb[0] = (unsigned short)address;
+       for (i = 0; i < len && i < 20; i += 2)
+               mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
+
+       dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
+       return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
+}
+
+static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
+{
+       u8 index_loop = 10;
+
+       if (!state->platform.risc.fw_is_running)
+               return 0;
+       dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
+       do {
+               dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
+       } while (state->i2c_read_buffer[0] && index_loop--);
+
+       if (index_loop > 0)
+               return 0;
+       return -EIO;
+}
+
+static int dib9000_fw_init(struct dib9000_state *state)
+{
+       struct dibGPIOFunction *f;
+       u16 b[40] = { 0 };
+       u8 i;
+       u8 size;
+
+       if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
+               return -EIO;
+
+       /* initialize the firmware */
+       for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
+               f = &state->chip.d9.cfg.gpio_function[i];
+               if (f->mask) {
+                       switch (f->function) {
+                       case BOARD_GPIO_FUNCTION_COMPONENT_ON:
+                               b[0] = (u16) f->mask;
+                               b[1] = (u16) f->direction;
+                               b[2] = (u16) f->value;
+                               break;
+                       case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
+                               b[3] = (u16) f->mask;
+                               b[4] = (u16) f->direction;
+                               b[5] = (u16) f->value;
+                               break;
+                       }
+               }
+       }
+       if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
+               return -EIO;
+
+       /* subband */
+       b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
+       for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
+               b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
+               b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
+               b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
+               b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
+       }
+       b[1 + i * 4] = 0;       /* fe_id */
+       if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
+               return -EIO;
+
+       /* 0 - id, 1 - no_of_frontends */
+       b[0] = (0 << 8) | 1;
+       /* 0 = i2c-address demod, 0 = tuner */
+       b[1] = (0 << 8) | (0);
+       b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
+       b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
+       b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
+       b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
+       b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
+       b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
+       b[29] = state->chip.d9.cfg.if_drives;
+       if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
+               return -EIO;
+
+       if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
+               return -EIO;
+
+       if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
+               return -EIO;
+
+       if (size > ARRAY_SIZE(b)) {
+               dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
+                       (int)ARRAY_SIZE(b));
+               return -EINVAL;
+       }
+
+       for (i = 0; i < size; i += 2) {
+               state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
+               state->platform.risc.fe_mm[i / 2].size = b[i + 1];
+       }
+
+       return 0;
+}
+
+static void dib9000_fw_set_channel_head(struct dib9000_state *state)
+{
+       u8 b[9];
+       u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
+       if (state->fe_id % 2)
+               freq += 101;
+
+       b[0] = (u8) ((freq >> 0) & 0xff);
+       b[1] = (u8) ((freq >> 8) & 0xff);
+       b[2] = (u8) ((freq >> 16) & 0xff);
+       b[3] = (u8) ((freq >> 24) & 0xff);
+       b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
+       b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
+       b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
+       b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
+       b[8] = 0x80;            /* do not wait for CELL ID when doing autosearch */
+       if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
+               b[8] |= 1;
+       dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
+}
+
+static int dib9000_fw_get_channel(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       struct dibDVBTChannel {
+               s8 spectrum_inversion;
+
+               s8 nfft;
+               s8 guard;
+               s8 constellation;
+
+               s8 hrch;
+               s8 alpha;
+               s8 code_rate_hp;
+               s8 code_rate_lp;
+               s8 select_hp;
+
+               s8 intlv_native;
+       };
+       struct dibDVBTChannel *ch;
+       int ret = 0;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+               ret = -EIO;
+               goto error;
+       }
+
+       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
+                       state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
+       ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
+
+
+       switch (ch->spectrum_inversion & 0x7) {
+       case 1:
+               state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
+               break;
+       case 0:
+               state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
+               break;
+       }
+       switch (ch->nfft) {
+       case 0:
+               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 2:
+               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
+               break;
+       case 1:
+               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+               break;
+       }
+       switch (ch->guard) {
+       case 0:
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+               break;
+       }
+       switch (ch->constellation) {
+       case 2:
+               state->fe[0]->dtv_property_cache.modulation = QAM_64;
+               break;
+       case 1:
+               state->fe[0]->dtv_property_cache.modulation = QAM_16;
+               break;
+       case 0:
+               state->fe[0]->dtv_property_cache.modulation = QPSK;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
+               break;
+       }
+       switch (ch->hrch) {
+       case 0:
+               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
+               break;
+       }
+       switch (ch->code_rate_hp) {
+       case 1:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
+               break;
+       case 2:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
+               break;
+       case 3:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
+               break;
+       case 5:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
+               break;
+       case 7:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
+               break;
+       }
+       switch (ch->code_rate_lp) {
+       case 1:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
+               break;
+       case 2:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
+               break;
+       case 3:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
+               break;
+       case 5:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
+               break;
+       case 7:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
+               break;
+       default:
+       case -1:
+               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
+               break;
+       }
+
+error:
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+       return ret;
+}
+
+static int dib9000_fw_set_channel_union(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       struct dibDVBTChannel {
+               s8 spectrum_inversion;
+
+               s8 nfft;
+               s8 guard;
+               s8 constellation;
+
+               s8 hrch;
+               s8 alpha;
+               s8 code_rate_hp;
+               s8 code_rate_lp;
+               s8 select_hp;
+
+               s8 intlv_native;
+       };
+       struct dibDVBTChannel ch;
+
+       switch (state->fe[0]->dtv_property_cache.inversion) {
+       case INVERSION_ON:
+               ch.spectrum_inversion = 1;
+               break;
+       case INVERSION_OFF:
+               ch.spectrum_inversion = 0;
+               break;
+       default:
+       case INVERSION_AUTO:
+               ch.spectrum_inversion = -1;
+               break;
+       }
+       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               ch.nfft = 0;
+               break;
+       case TRANSMISSION_MODE_4K:
+               ch.nfft = 2;
+               break;
+       case TRANSMISSION_MODE_8K:
+               ch.nfft = 1;
+               break;
+       default:
+       case TRANSMISSION_MODE_AUTO:
+               ch.nfft = 1;
+               break;
+       }
+       switch (state->fe[0]->dtv_property_cache.guard_interval) {
+       case GUARD_INTERVAL_1_32:
+               ch.guard = 0;
+               break;
+       case GUARD_INTERVAL_1_16:
+               ch.guard = 1;
+               break;
+       case GUARD_INTERVAL_1_8:
+               ch.guard = 2;
+               break;
+       case GUARD_INTERVAL_1_4:
+               ch.guard = 3;
+               break;
+       default:
+       case GUARD_INTERVAL_AUTO:
+               ch.guard = -1;
+               break;
+       }
+       switch (state->fe[0]->dtv_property_cache.modulation) {
+       case QAM_64:
+               ch.constellation = 2;
+               break;
+       case QAM_16:
+               ch.constellation = 1;
+               break;
+       case QPSK:
+               ch.constellation = 0;
+               break;
+       default:
+       case QAM_AUTO:
+               ch.constellation = -1;
+               break;
+       }
+       switch (state->fe[0]->dtv_property_cache.hierarchy) {
+       case HIERARCHY_NONE:
+               ch.hrch = 0;
+               break;
+       case HIERARCHY_1:
+       case HIERARCHY_2:
+       case HIERARCHY_4:
+               ch.hrch = 1;
+               break;
+       default:
+       case HIERARCHY_AUTO:
+               ch.hrch = -1;
+               break;
+       }
+       ch.alpha = 1;
+       switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
+       case FEC_1_2:
+               ch.code_rate_hp = 1;
+               break;
+       case FEC_2_3:
+               ch.code_rate_hp = 2;
+               break;
+       case FEC_3_4:
+               ch.code_rate_hp = 3;
+               break;
+       case FEC_5_6:
+               ch.code_rate_hp = 5;
+               break;
+       case FEC_7_8:
+               ch.code_rate_hp = 7;
+               break;
+       default:
+       case FEC_AUTO:
+               ch.code_rate_hp = -1;
+               break;
+       }
+       switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
+       case FEC_1_2:
+               ch.code_rate_lp = 1;
+               break;
+       case FEC_2_3:
+               ch.code_rate_lp = 2;
+               break;
+       case FEC_3_4:
+               ch.code_rate_lp = 3;
+               break;
+       case FEC_5_6:
+               ch.code_rate_lp = 5;
+               break;
+       case FEC_7_8:
+               ch.code_rate_lp = 7;
+               break;
+       default:
+       case FEC_AUTO:
+               ch.code_rate_lp = -1;
+               break;
+       }
+       ch.select_hp = 1;
+       ch.intlv_native = 1;
+
+       dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
+
+       return 0;
+}
+
+static int dib9000_fw_tune(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
+       s8 i;
+
+       switch (state->tune_state) {
+       case CT_DEMOD_START:
+               dib9000_fw_set_channel_head(state);
+
+               /* write the channel context - a channel is initialized to 0, so it is OK */
+               dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
+               dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
+
+               if (search)
+                       dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
+               else {
+                       dib9000_fw_set_channel_union(fe);
+                       dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
+               }
+               state->tune_state = CT_DEMOD_STEP_1;
+               break;
+       case CT_DEMOD_STEP_1:
+               if (search)
+                       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
+               else
+                       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
+               i = (s8)state->i2c_read_buffer[0];
+               switch (i) {    /* something happened */
+               case 0:
+                       break;
+               case -2:        /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
+                       if (search)
+                               state->status = FE_STATUS_DEMOD_SUCCESS;
+                       else {
+                               state->tune_state = CT_DEMOD_STOP;
+                               state->status = FE_STATUS_LOCKED;
+                       }
+                       break;
+               default:
+                       state->status = FE_STATUS_TUNE_FAILED;
+                       state->tune_state = CT_DEMOD_STOP;
+                       break;
+               }
+               break;
+       default:
+               ret = FE_CALLBACK_TIME_NEVER;
+               break;
+       }
+
+       return ret;
+}
+
+static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 mode = (u16) onoff;
+       return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
+}
+
+static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 outreg, smo_mode;
+
+       dprintk("setting output mode for demod %p to %d", fe, mode);
+
+       switch (mode) {
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+               outreg = (1 << 10);     /* 0x0400 */
+               break;
+       case OUTMODE_MPEG2_PAR_CONT_CLK:
+               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
+               break;
+       case OUTMODE_MPEG2_SERIAL:
+               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
+               break;
+       case OUTMODE_DIVERSITY:
+               outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
+               break;
+       case OUTMODE_MPEG2_FIFO:
+               outreg = (1 << 10) | (5 << 6);
+               break;
+       case OUTMODE_HIGH_Z:
+               outreg = 0;
+               break;
+       default:
+               dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]);
+               return -EINVAL;
+       }
+
+       dib9000_write_word(state, 1795, outreg);
+
+       switch (mode) {
+       case OUTMODE_MPEG2_PAR_GATED_CLK:
+       case OUTMODE_MPEG2_PAR_CONT_CLK:
+       case OUTMODE_MPEG2_SERIAL:
+       case OUTMODE_MPEG2_FIFO:
+               smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
+               if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
+                       smo_mode |= (1 << 5);
+               dib9000_write_word(state, 295, smo_mode);
+               break;
+       }
+
+       outreg = to_fw_output_mode(mode);
+       return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
+}
+
+static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
+       u16 i, len, t, index_msg;
+
+       for (index_msg = 0; index_msg < num; index_msg++) {
+               if (msg[index_msg].flags & I2C_M_RD) {  /* read */
+                       len = msg[index_msg].len;
+                       if (len > 16)
+                               len = 16;
+
+                       if (dib9000_read_word(state, 790) != 0)
+                               dprintk("TunerITF: read busy");
+
+                       dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
+                       dib9000_write_word(state, 787, (len / 2) - 1);
+                       dib9000_write_word(state, 786, 1);      /* start read */
+
+                       i = 1000;
+                       while (dib9000_read_word(state, 790) != (len / 2) && i)
+                               i--;
+
+                       if (i == 0)
+                               dprintk("TunerITF: read failed");
+
+                       for (i = 0; i < len; i += 2) {
+                               t = dib9000_read_word(state, 785);
+                               msg[index_msg].buf[i] = (t >> 8) & 0xff;
+                               msg[index_msg].buf[i + 1] = (t) & 0xff;
+                       }
+                       if (dib9000_read_word(state, 790) != 0)
+                               dprintk("TunerITF: read more data than expected");
+               } else {
+                       i = 1000;
+                       while (dib9000_read_word(state, 789) && i)
+                               i--;
+                       if (i == 0)
+                               dprintk("TunerITF: write busy");
+
+                       len = msg[index_msg].len;
+                       if (len > 16)
+                               len = 16;
+
+                       for (i = 0; i < len; i += 2)
+                               dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
+                       dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
+                       dib9000_write_word(state, 787, (len / 2) - 1);
+                       dib9000_write_word(state, 786, 0);      /* start write */
+
+                       i = 1000;
+                       while (dib9000_read_word(state, 791) > 0 && i)
+                               i--;
+                       if (i == 0)
+                               dprintk("TunerITF: write failed");
+               }
+       }
+       return num;
+}
+
+int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+
+       state->component_bus_speed = speed;
+       return 0;
+}
+EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
+
+static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
+       u8 type = 0;            /* I2C */
+       u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
+       u16 scl = state->component_bus_speed;   /* SCL frequency */
+       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
+       u8 p[13] = { 0 };
+
+       p[0] = type;
+       p[1] = port;
+       p[2] = msg[0].addr << 1;
+
+       p[3] = (u8) scl & 0xff; /* scl */
+       p[4] = (u8) (scl >> 8);
+
+       p[7] = 0;
+       p[8] = 0;
+
+       p[9] = (u8) (msg[0].len);
+       p[10] = (u8) (msg[0].len >> 8);
+       if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
+               p[11] = (u8) (msg[1].len);
+               p[12] = (u8) (msg[1].len >> 8);
+       } else {
+               p[11] = 0;
+               p[12] = 0;
+       }
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               return 0;
+       }
+
+       dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
+
+       {                       /* write-part */
+               dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
+               dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
+       }
+
+       /* do the transaction */
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
+               mutex_unlock(&state->platform.risc.mem_mbx_lock);
+               return 0;
+       }
+
+       /* read back any possible result */
+       if ((num > 1) && (msg[1].flags & I2C_M_RD))
+               dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
+
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+
+       return num;
+}
+
+static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dib9000_tuner_algo = {
+       .master_xfer = dib9000_tuner_xfer,
+       .functionality = dib9000_i2c_func,
+};
+
+static struct i2c_algorithm dib9000_component_bus_algo = {
+       .master_xfer = dib9000_fw_component_bus_xfer,
+       .functionality = dib9000_i2c_func,
+};
+
+struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
+{
+       struct dib9000_state *st = fe->demodulator_priv;
+       return &st->tuner_adap;
+}
+EXPORT_SYMBOL(dib9000_get_tuner_interface);
+
+struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
+{
+       struct dib9000_state *st = fe->demodulator_priv;
+       return &st->component_bus;
+}
+EXPORT_SYMBOL(dib9000_get_component_bus_interface);
+
+struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+{
+       struct dib9000_state *st = fe->demodulator_priv;
+       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+EXPORT_SYMBOL(dib9000_get_i2c_master);
+
+int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
+{
+       struct dib9000_state *st = fe->demodulator_priv;
+
+       st->i2c.i2c_adap = i2c;
+       return 0;
+}
+EXPORT_SYMBOL(dib9000_set_i2c_adapter);
+
+static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
+{
+       st->gpio_dir = dib9000_read_word(st, 773);
+       st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
+       st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
+       dib9000_write_word(st, 773, st->gpio_dir);
+
+       st->gpio_val = dib9000_read_word(st, 774);
+       st->gpio_val &= ~(1 << num);    /* reset the direction bit */
+       st->gpio_val |= (val & 0x01) << num;    /* set the new value */
+       dib9000_write_word(st, 774, st->gpio_val);
+
+       dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val);
+
+       return 0;
+}
+
+int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       return dib9000_cfg_gpio(state, num, dir, val);
+}
+EXPORT_SYMBOL(dib9000_set_gpio);
+
+int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 val;
+       int ret;
+
+       if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
+               /* postpone the pid filtering cmd */
+               dprintk("pid filter cmd postpone");
+               state->pid_ctrl_index++;
+               state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
+               state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
+               return 0;
+       }
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+
+       val = dib9000_read_word(state, 294 + 1) & 0xffef;
+       val |= (onoff & 0x1) << 4;
+
+       dprintk("PID filter enabled %d", onoff);
+       ret = dib9000_write_word(state, 294 + 1, val);
+       mutex_unlock(&state->demod_lock);
+       return ret;
+
+}
+EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
+
+int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       int ret;
+
+       if (state->pid_ctrl_index != -2) {
+               /* postpone the pid filtering cmd */
+               dprintk("pid filter postpone");
+               if (state->pid_ctrl_index < 9) {
+                       state->pid_ctrl_index++;
+                       state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
+                       state->pid_ctrl[state->pid_ctrl_index].id = id;
+                       state->pid_ctrl[state->pid_ctrl_index].pid = pid;
+                       state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
+               } else
+                       dprintk("can not add any more pid ctrl cmd");
+               return 0;
+       }
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
+       ret = dib9000_write_word(state, 300 + 1 + id,
+                       onoff ? (1 << 13) | pid : 0);
+       mutex_unlock(&state->demod_lock);
+       return ret;
+}
+EXPORT_SYMBOL(dib9000_fw_pid_filter);
+
+int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       return dib9000_fw_init(state);
+}
+EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
+
+static void dib9000_release(struct dvb_frontend *demod)
+{
+       struct dib9000_state *st = demod->demodulator_priv;
+       u8 index_frontend;
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
+               dvb_frontend_detach(st->fe[index_frontend]);
+
+       dibx000_exit_i2c_master(&st->i2c_master);
+
+       i2c_del_adapter(&st->tuner_adap);
+       i2c_del_adapter(&st->component_bus);
+       kfree(st->fe[0]);
+       kfree(st);
+}
+
+static int dib9000_wakeup(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int dib9000_sleep(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       int ret = 0;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
+               if (ret < 0)
+                       goto error;
+       }
+       ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
+
+error:
+       mutex_unlock(&state->demod_lock);
+       return ret;
+}
+
+static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static int dib9000_get_frontend(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend, sub_index_frontend;
+       fe_status_t stat;
+       int ret = 0;
+
+       if (state->get_frontend_internal == 0) {
+               if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+                       dprintk("could not get the lock");
+                       return -EINTR;
+               }
+       }
+
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
+               if (stat & FE_HAS_SYNC) {
+                       dprintk("TPS lock on the slave%i", index_frontend);
+
+                       /* synchronize the cache with the other frontends */
+                       state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
+                       for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
+                            sub_index_frontend++) {
+                               if (sub_index_frontend != index_frontend) {
+                                       state->fe[sub_index_frontend]->dtv_property_cache.modulation =
+                                           state->fe[index_frontend]->dtv_property_cache.modulation;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.inversion =
+                                           state->fe[index_frontend]->dtv_property_cache.inversion;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
+                                           state->fe[index_frontend]->dtv_property_cache.transmission_mode;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
+                                           state->fe[index_frontend]->dtv_property_cache.guard_interval;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
+                                           state->fe[index_frontend]->dtv_property_cache.hierarchy;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
+                                           state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
+                                           state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
+                                       state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
+                                           state->fe[index_frontend]->dtv_property_cache.rolloff;
+                               }
+                       }
+                       ret = 0;
+                       goto return_value;
+               }
+       }
+
+       /* get the channel from master chip */
+       ret = dib9000_fw_get_channel(fe);
+       if (ret != 0)
+               goto return_value;
+
+       /* synchronize the cache with the other frontends */
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
+               state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
+               state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
+               state->fe[index_frontend]->dtv_property_cache.modulation = fe->dtv_property_cache.modulation;
+               state->fe[index_frontend]->dtv_property_cache.hierarchy = fe->dtv_property_cache.hierarchy;
+               state->fe[index_frontend]->dtv_property_cache.code_rate_HP = fe->dtv_property_cache.code_rate_HP;
+               state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
+               state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
+       }
+       ret = 0;
+
+return_value:
+       if (state->get_frontend_internal == 0)
+               mutex_unlock(&state->demod_lock);
+       return ret;
+}
+
+static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       state->tune_state = tune_state;
+       if (tune_state == CT_DEMOD_START)
+               state->status = FE_STATUS_TUNE_PENDING;
+
+       return 0;
+}
+
+static u32 dib9000_get_status(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       return state->status;
+}
+
+static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+
+       memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
+       return 0;
+}
+
+static int dib9000_set_frontend(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       int sleep_time, sleep_time_slave;
+       u32 frontend_status;
+       u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
+       struct dvb_frontend_parametersContext channel_status;
+
+       /* check that the correct parameters are set */
+       if (state->fe[0]->dtv_property_cache.frequency == 0) {
+               dprintk("dib9000: must specify frequency ");
+               return 0;
+       }
+
+       if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
+               dprintk("dib9000: must specify bandwidth ");
+               return 0;
+       }
+
+       state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return 0;
+       }
+
+       fe->dtv_property_cache.delivery_system = SYS_DVBT;
+
+       /* set the master status */
+       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO ||
+           state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO ||
+           state->fe[0]->dtv_property_cache.modulation == QAM_AUTO ||
+           state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) {
+               /* no channel specified, autosearch the channel */
+               state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
+       } else
+               state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
+
+       /* set mode and status for the different frontends */
+       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
+
+               /* synchronization of the cache */
+               memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
+
+               state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
+               dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
+
+               dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
+               dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
+       }
+
+       /* actual tune */
+       exit_condition = 0;     /* 0: tune pending; 1: tune failed; 2:tune success */
+       index_frontend_success = 0;
+       do {
+               sleep_time = dib9000_fw_tune(state->fe[0]);
+               for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
+                       if (sleep_time == FE_CALLBACK_TIME_NEVER)
+                               sleep_time = sleep_time_slave;
+                       else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
+                               sleep_time = sleep_time_slave;
+               }
+               if (sleep_time != FE_CALLBACK_TIME_NEVER)
+                       msleep(sleep_time / 10);
+               else
+                       break;
+
+               nbr_pending = 0;
+               exit_condition = 0;
+               index_frontend_success = 0;
+               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       frontend_status = -dib9000_get_status(state->fe[index_frontend]);
+                       if (frontend_status > -FE_STATUS_TUNE_PENDING) {
+                               exit_condition = 2;     /* tune success */
+                               index_frontend_success = index_frontend;
+                               break;
+                       }
+                       if (frontend_status == -FE_STATUS_TUNE_PENDING)
+                               nbr_pending++;  /* some frontends are still tuning */
+               }
+               if ((exit_condition != 2) && (nbr_pending == 0))
+                       exit_condition = 1;     /* if all tune are done and no success, exit: tune failed */
+
+       } while (exit_condition == 0);
+
+       /* check the tune result */
+       if (exit_condition == 1) {      /* tune failed */
+               dprintk("tune failed");
+               mutex_unlock(&state->demod_lock);
+               /* tune failed; put all the pid filtering cmd to junk */
+               state->pid_ctrl_index = -1;
+               return 0;
+       }
+
+       dprintk("tune success on frontend%i", index_frontend_success);
+
+       /* synchronize all the channel cache */
+       state->get_frontend_internal = 1;
+       dib9000_get_frontend(state->fe[0]);
+       state->get_frontend_internal = 0;
+
+       /* retune the other frontends with the found channel */
+       channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
+       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               /* only retune the frontends which was not tuned success */
+               if (index_frontend != index_frontend_success) {
+                       dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
+                       dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
+               }
+       }
+       do {
+               sleep_time = FE_CALLBACK_TIME_NEVER;
+               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       if (index_frontend != index_frontend_success) {
+                               sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
+                               if (sleep_time == FE_CALLBACK_TIME_NEVER)
+                                       sleep_time = sleep_time_slave;
+                               else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
+                                       sleep_time = sleep_time_slave;
+                       }
+               }
+               if (sleep_time != FE_CALLBACK_TIME_NEVER)
+                       msleep(sleep_time / 10);
+               else
+                       break;
+
+               nbr_pending = 0;
+               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+                       if (index_frontend != index_frontend_success) {
+                               frontend_status = -dib9000_get_status(state->fe[index_frontend]);
+                               if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
+                                       nbr_pending++;  /* some frontends are still tuning */
+                       }
+               }
+       } while (nbr_pending != 0);
+
+       /* set the output mode */
+       dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
+
+       /* turn off the diversity for the last frontend */
+       dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
+
+       mutex_unlock(&state->demod_lock);
+       if (state->pid_ctrl_index >= 0) {
+               u8 index_pid_filter_cmd;
+               u8 pid_ctrl_index = state->pid_ctrl_index;
+
+               state->pid_ctrl_index = -2;
+               for (index_pid_filter_cmd = 0;
+                               index_pid_filter_cmd <= pid_ctrl_index;
+                               index_pid_filter_cmd++) {
+                       if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
+                               dib9000_fw_pid_filter_ctrl(state->fe[0],
+                                               state->pid_ctrl[index_pid_filter_cmd].onoff);
+                       else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
+                               dib9000_fw_pid_filter(state->fe[0],
+                                               state->pid_ctrl[index_pid_filter_cmd].id,
+                                               state->pid_ctrl[index_pid_filter_cmd].pid,
+                                               state->pid_ctrl[index_pid_filter_cmd].onoff);
+               }
+       }
+       /* do not postpone any more the pid filtering */
+       state->pid_ctrl_index = -2;
+
+       return 0;
+}
+
+static u16 dib9000_read_lock(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+
+       return dib9000_read_word(state, 535);
+}
+
+static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       u16 lock = 0, lock_slave = 0;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
+
+       lock = dib9000_read_word(state, 535);
+
+       *stat = 0;
+
+       if ((lock & 0x8000) || (lock_slave & 0x8000))
+               *stat |= FE_HAS_SIGNAL;
+       if ((lock & 0x3000) || (lock_slave & 0x3000))
+               *stat |= FE_HAS_CARRIER;
+       if ((lock & 0x0100) || (lock_slave & 0x0100))
+               *stat |= FE_HAS_VITERBI;
+       if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
+               *stat |= FE_HAS_SYNC;
+       if ((lock & 0x0008) || (lock_slave & 0x0008))
+               *stat |= FE_HAS_LOCK;
+
+       mutex_unlock(&state->demod_lock);
+
+       return 0;
+}
+
+static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 *c;
+       int ret = 0;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               ret = -EINTR;
+               goto error;
+       }
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+               mutex_unlock(&state->platform.risc.mem_mbx_lock);
+               ret = -EIO;
+               goto error;
+       }
+       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
+                       state->i2c_read_buffer, 16 * 2);
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+
+       c = (u16 *)state->i2c_read_buffer;
+
+       *ber = c[10] << 16 | c[11];
+
+error:
+       mutex_unlock(&state->demod_lock);
+       return ret;
+}
+
+static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       u16 *c = (u16 *)state->i2c_read_buffer;
+       u16 val;
+       int ret = 0;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       *strength = 0;
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
+               state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
+               if (val > 65535 - *strength)
+                       *strength = 65535;
+               else
+                       *strength += val;
+       }
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               ret = -EINTR;
+               goto error;
+       }
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+               mutex_unlock(&state->platform.risc.mem_mbx_lock);
+               ret = -EIO;
+               goto error;
+       }
+       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+
+       val = 65535 - c[4];
+       if (val > 65535 - *strength)
+               *strength = 65535;
+       else
+               *strength += val;
+
+error:
+       mutex_unlock(&state->demod_lock);
+       return ret;
+}
+
+static u32 dib9000_get_snr(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 *c = (u16 *)state->i2c_read_buffer;
+       u32 n, s, exp;
+       u16 val;
+
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               return 0;
+       }
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+               mutex_unlock(&state->platform.risc.mem_mbx_lock);
+               return 0;
+       }
+       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+
+       val = c[7];
+       n = (val >> 4) & 0xff;
+       exp = ((val & 0xf) << 2);
+       val = c[8];
+       exp += ((val >> 14) & 0x3);
+       if ((exp & 0x20) != 0)
+               exp -= 0x40;
+       n <<= exp + 16;
+
+       s = (val >> 6) & 0xFF;
+       exp = (val & 0x3F);
+       if ((exp & 0x20) != 0)
+               exp -= 0x40;
+       s <<= exp + 16;
+
+       if (n > 0) {
+               u32 t = (s / n) << 16;
+               return t + ((s << 16) - n * t) / n;
+       }
+       return 0xffffffff;
+}
+
+static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend;
+       u32 snr_master;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       snr_master = dib9000_get_snr(fe);
+       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
+               snr_master += dib9000_get_snr(state->fe[index_frontend]);
+
+       if ((snr_master >> 16) != 0) {
+               snr_master = 10 * intlog10(snr_master >> 16);
+               *snr = snr_master / ((1 << 24) / 10);
+       } else
+               *snr = 0;
+
+       mutex_unlock(&state->demod_lock);
+
+       return 0;
+}
+
+static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u16 *c = (u16 *)state->i2c_read_buffer;
+       int ret = 0;
+
+       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
+               dprintk("could not get the lock");
+               return -EINTR;
+       }
+       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
+               dprintk("could not get the lock");
+               ret = -EINTR;
+               goto error;
+       }
+       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
+               mutex_unlock(&state->platform.risc.mem_mbx_lock);
+               ret = -EIO;
+               goto error;
+       }
+       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+       mutex_unlock(&state->platform.risc.mem_mbx_lock);
+
+       *unc = c[12];
+
+error:
+       mutex_unlock(&state->demod_lock);
+       return ret;
+}
+
+int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+       int k = 0, ret = 0;
+       u8 new_addr = 0;
+       struct i2c_device client = {.i2c_adap = i2c };
+
+       client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+       if (!client.i2c_write_buffer) {
+               dprintk("%s: not enough memory", __func__);
+               return -ENOMEM;
+       }
+       client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+       if (!client.i2c_read_buffer) {
+               dprintk("%s: not enough memory", __func__);
+               ret = -ENOMEM;
+               goto error_memory;
+       }
+
+       client.i2c_addr = default_addr + 16;
+       dib9000_i2c_write16(&client, 1796, 0x0);
+
+       for (k = no_of_demods - 1; k >= 0; k--) {
+               /* designated i2c address */
+               new_addr = first_addr + (k << 1);
+               client.i2c_addr = default_addr;
+
+               dib9000_i2c_write16(&client, 1817, 3);
+               dib9000_i2c_write16(&client, 1796, 0);
+               dib9000_i2c_write16(&client, 1227, 1);
+               dib9000_i2c_write16(&client, 1227, 0);
+
+               client.i2c_addr = new_addr;
+               dib9000_i2c_write16(&client, 1817, 3);
+               dib9000_i2c_write16(&client, 1796, 0);
+               dib9000_i2c_write16(&client, 1227, 1);
+               dib9000_i2c_write16(&client, 1227, 0);
+
+               if (dib9000_identify(&client) == 0) {
+                       client.i2c_addr = default_addr;
+                       if (dib9000_identify(&client) == 0) {
+                               dprintk("DiB9000 #%d: not identified", k);
+                               ret = -EIO;
+                               goto error;
+                       }
+               }
+
+               dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
+               dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
+
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+       }
+
+       for (k = 0; k < no_of_demods; k++) {
+               new_addr = first_addr | (k << 1);
+               client.i2c_addr = new_addr;
+
+               dib9000_i2c_write16(&client, 1794, (new_addr << 2));
+               dib9000_i2c_write16(&client, 1795, 0);
+       }
+
+error:
+       kfree(client.i2c_read_buffer);
+error_memory:
+       kfree(client.i2c_write_buffer);
+
+       return ret;
+}
+EXPORT_SYMBOL(dib9000_i2c_enumeration);
+
+int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend = 1;
+
+       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
+               index_frontend++;
+       if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
+               dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
+               state->fe[index_frontend] = fe_slave;
+               return 0;
+       }
+
+       dprintk("too many slave frontend");
+       return -ENOMEM;
+}
+EXPORT_SYMBOL(dib9000_set_slave_frontend);
+
+int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+       u8 index_frontend = 1;
+
+       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
+               index_frontend++;
+       if (index_frontend != 1) {
+               dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1);
+               state->fe[index_frontend] = NULL;
+               return 0;
+       }
+
+       dprintk("no frontend to be removed");
+       return -ENODEV;
+}
+EXPORT_SYMBOL(dib9000_remove_slave_frontend);
+
+struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+{
+       struct dib9000_state *state = fe->demodulator_priv;
+
+       if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
+               return NULL;
+       return state->fe[slave_index];
+}
+EXPORT_SYMBOL(dib9000_get_slave_frontend);
+
+static struct dvb_frontend_ops dib9000_ops;
+struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
+{
+       struct dvb_frontend *fe;
+       struct dib9000_state *st;
+       st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
+       if (st == NULL)
+               return NULL;
+       fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
+       if (fe == NULL) {
+               kfree(st);
+               return NULL;
+       }
+
+       memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
+       st->i2c.i2c_adap = i2c_adap;
+       st->i2c.i2c_addr = i2c_addr;
+       st->i2c.i2c_write_buffer = st->i2c_write_buffer;
+       st->i2c.i2c_read_buffer = st->i2c_read_buffer;
+
+       st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
+       st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
+       st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
+
+       mutex_init(&st->platform.risc.mbx_if_lock);
+       mutex_init(&st->platform.risc.mbx_lock);
+       mutex_init(&st->platform.risc.mem_lock);
+       mutex_init(&st->platform.risc.mem_mbx_lock);
+       mutex_init(&st->demod_lock);
+       st->get_frontend_internal = 0;
+
+       st->pid_ctrl_index = -2;
+
+       st->fe[0] = fe;
+       fe->demodulator_priv = st;
+       memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
+
+       /* Ensure the output mode remains at the previous default if it's
+        * not specifically set by the caller.
+        */
+       if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
+               st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
+       if (dib9000_identify(&st->i2c) == 0)
+               goto error;
+
+       dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
+
+       st->tuner_adap.dev.parent = i2c_adap->dev.parent;
+       strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name));
+       st->tuner_adap.algo = &dib9000_tuner_algo;
+       st->tuner_adap.algo_data = NULL;
+       i2c_set_adapdata(&st->tuner_adap, st);
+       if (i2c_add_adapter(&st->tuner_adap) < 0)
+               goto error;
+
+       st->component_bus.dev.parent = i2c_adap->dev.parent;
+       strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name));
+       st->component_bus.algo = &dib9000_component_bus_algo;
+       st->component_bus.algo_data = NULL;
+       st->component_bus_speed = 340;
+       i2c_set_adapdata(&st->component_bus, st);
+       if (i2c_add_adapter(&st->component_bus) < 0)
+               goto component_bus_add_error;
+
+       dib9000_fw_reset(fe);
+
+       return fe;
+
+component_bus_add_error:
+       i2c_del_adapter(&st->tuner_adap);
+error:
+       kfree(st);
+       return NULL;
+}
+EXPORT_SYMBOL(dib9000_attach);
+
+static struct dvb_frontend_ops dib9000_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+                .name = "DiBcom 9000",
+                .frequency_min = 44250000,
+                .frequency_max = 867250000,
+                .frequency_stepsize = 62500,
+                .caps = FE_CAN_INVERSION_AUTO |
+                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+                },
+
+       .release = dib9000_release,
+
+       .init = dib9000_wakeup,
+       .sleep = dib9000_sleep,
+
+       .set_frontend = dib9000_set_frontend,
+       .get_tune_settings = dib9000_fe_get_tune_settings,
+       .get_frontend = dib9000_get_frontend,
+
+       .read_status = dib9000_read_status,
+       .read_ber = dib9000_read_ber,
+       .read_signal_strength = dib9000_read_signal_strength,
+       .read_snr = dib9000_read_snr,
+       .read_ucblocks = dib9000_read_unc_blocks,
+};
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dib9000.h b/drivers/media/dvb-frontends/dib9000.h
new file mode 100644 (file)
index 0000000..b5781a4
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef DIB9000_H
+#define DIB9000_H
+
+#include "dibx000_common.h"
+
+struct dib9000_config {
+       u8 dvbt_mode;
+       u8 output_mpeg2_in_188_bytes;
+       u8 hostbus_diversity;
+       struct dibx000_bandwidth_config *bw;
+
+       u16 if_drives;
+
+       u32 timing_frequency;
+       u32 xtal_clock_khz;
+       u32 vcxo_timer;
+       u32 demod_clock_khz;
+
+       const u8 *microcode_B_fe_buffer;
+       u32 microcode_B_fe_size;
+
+       struct dibGPIOFunction gpio_function[2];
+       struct dibSubbandSelection subband;
+
+       u8 output_mode;
+};
+
+#define DEFAULT_DIB9000_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB9000) || (defined(CONFIG_DVB_DIB9000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
+extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
+extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
+extern struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
+extern int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
+extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
+extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
+extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe);
+extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
+extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe);
+extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
+extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe);
+extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c);
+extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed);
+#else
+static inline struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib9000_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+
+static inline int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c
new file mode 100644 (file)
index 0000000..43be723
--- /dev/null
@@ -0,0 +1,515 @@
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
+
+static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
+{
+       int ret;
+
+       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+       mst->i2c_write_buffer[1] = reg & 0xff;
+       mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
+       mst->i2c_write_buffer[3] = val & 0xff;
+
+       memset(mst->msg, 0, sizeof(struct i2c_msg));
+       mst->msg[0].addr = mst->i2c_addr;
+       mst->msg[0].flags = 0;
+       mst->msg[0].buf = mst->i2c_write_buffer;
+       mst->msg[0].len = 4;
+
+       ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
+       mutex_unlock(&mst->i2c_buffer_lock);
+
+       return ret;
+}
+
+static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
+{
+       u16 ret;
+
+       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return 0;
+       }
+
+       mst->i2c_write_buffer[0] = reg >> 8;
+       mst->i2c_write_buffer[1] = reg & 0xff;
+
+       memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
+       mst->msg[0].addr = mst->i2c_addr;
+       mst->msg[0].flags = 0;
+       mst->msg[0].buf = mst->i2c_write_buffer;
+       mst->msg[0].len = 2;
+       mst->msg[1].addr = mst->i2c_addr;
+       mst->msg[1].flags = I2C_M_RD;
+       mst->msg[1].buf = mst->i2c_read_buffer;
+       mst->msg[1].len = 2;
+
+       if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
+               dprintk("i2c read error on %d", reg);
+
+       ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
+       mutex_unlock(&mst->i2c_buffer_lock);
+
+       return ret;
+}
+
+static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
+{
+       int i = 100;
+       u16 status;
+
+       while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
+               ;
+
+       /* i2c timed out */
+       if (i == 0)
+               return -EREMOTEIO;
+
+       /* no acknowledge */
+       if ((status & 0x0080) == 0)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
+{
+       u16 data;
+       u16 da;
+       u16 i;
+       u16 txlen = msg->len, len;
+       const u8 *b = msg->buf;
+
+       while (txlen) {
+               dibx000_read_word(mst, mst->base_reg + 2);
+
+               len = txlen > 8 ? 8 : txlen;
+               for (i = 0; i < len; i += 2) {
+                       data = *b++ << 8;
+                       if (i+1 < len)
+                               data |= *b++;
+                       dibx000_write_word(mst, mst->base_reg, data);
+               }
+               da = (((u8) (msg->addr))  << 9) |
+                       (1           << 8) |
+                       (1           << 7) |
+                       (0           << 6) |
+                       (0           << 5) |
+                       ((len & 0x7) << 2) |
+                       (0           << 1) |
+                       (0           << 0);
+
+               if (txlen == msg->len)
+                       da |= 1 << 5; /* start */
+
+               if (txlen-len == 0 && stop)
+                       da |= 1 << 6; /* stop */
+
+               dibx000_write_word(mst, mst->base_reg+1, da);
+
+               if (dibx000_is_i2c_done(mst) != 0)
+                       return -EREMOTEIO;
+               txlen -= len;
+       }
+
+       return 0;
+}
+
+static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
+{
+       u16 da;
+       u8 *b = msg->buf;
+       u16 rxlen = msg->len, len;
+
+       while (rxlen) {
+               len = rxlen > 8 ? 8 : rxlen;
+               da = (((u8) (msg->addr)) << 9) |
+                       (1           << 8) |
+                       (1           << 7) |
+                       (0           << 6) |
+                       (0           << 5) |
+                       ((len & 0x7) << 2) |
+                       (1           << 1) |
+                       (0           << 0);
+
+               if (rxlen == msg->len)
+                       da |= 1 << 5; /* start */
+
+               if (rxlen-len == 0)
+                       da |= 1 << 6; /* stop */
+               dibx000_write_word(mst, mst->base_reg+1, da);
+
+               if (dibx000_is_i2c_done(mst) != 0)
+                       return -EREMOTEIO;
+
+               rxlen -= len;
+
+               while (len) {
+                       da = dibx000_read_word(mst, mst->base_reg);
+                       *b++ = (da >> 8) & 0xff;
+                       len--;
+                       if (len >= 1) {
+                               *b++ =  da   & 0xff;
+                               len--;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
+{
+       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+
+       if (mst->device_rev < DIB7000MC && speed < 235)
+               speed = 235;
+       return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
+
+}
+EXPORT_SYMBOL(dibx000_i2c_set_speed);
+
+static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
+                                       enum dibx000_i2c_interface intf)
+{
+       if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
+               dprintk("selecting interface: %d", intf);
+               mst->selected_interface = intf;
+               return dibx000_write_word(mst, mst->base_reg + 4, intf);
+       }
+       return 0;
+}
+
+static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+       int msg_index;
+       int ret = 0;
+
+       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
+       for (msg_index = 0; msg_index < num; msg_index++) {
+               if (msg[msg_index].flags & I2C_M_RD) {
+                       ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
+                       if (ret != 0)
+                               return 0;
+               } else {
+                       ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
+                       if (ret != 0)
+                               return 0;
+               }
+       }
+
+       return num;
+}
+
+static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+       int msg_index;
+       int ret = 0;
+
+       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
+       for (msg_index = 0; msg_index < num; msg_index++) {
+               if (msg[msg_index].flags & I2C_M_RD) {
+                       ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
+                       if (ret != 0)
+                               return 0;
+               } else {
+                       ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
+                       if (ret != 0)
+                               return 0;
+               }
+       }
+
+       return num;
+}
+
+static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
+       .master_xfer = dibx000_i2c_master_xfer_gpio12,
+       .functionality = dibx000_i2c_func,
+};
+
+static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
+       .master_xfer = dibx000_i2c_master_xfer_gpio34,
+       .functionality = dibx000_i2c_func,
+};
+
+static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
+                                u8 addr, int onoff)
+{
+       u16 val;
+
+
+       if (onoff)
+               val = addr << 8;        // bit 7 = use master or not, if 0, the gate is open
+       else
+               val = 1 << 7;
+
+       if (mst->device_rev > DIB7000)
+               val <<= 1;
+
+       tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
+       tx[1] = ((mst->base_reg + 1) & 0xff);
+       tx[2] = val >> 8;
+       tx[3] = val & 0xff;
+
+       return 0;
+}
+
+static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
+                                       struct i2c_msg msg[], int num)
+{
+       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+       int ret;
+
+       if (num > 32) {
+               dprintk("%s: too much I2C message to be transmitted (%i).\
+                               Maximum is 32", __func__, num);
+               return -ENOMEM;
+       }
+
+       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
+
+       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+
+       memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+
+       /* open the gate */
+       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
+       mst->msg[0].addr = mst->i2c_addr;
+       mst->msg[0].buf = &mst->i2c_write_buffer[0];
+       mst->msg[0].len = 4;
+
+       memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+
+       /* close the gate */
+       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
+       mst->msg[num + 1].addr = mst->i2c_addr;
+       mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
+       mst->msg[num + 1].len = 4;
+
+       ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
+                       num : -EIO);
+
+       mutex_unlock(&mst->i2c_buffer_lock);
+       return ret;
+}
+
+static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
+       .master_xfer = dibx000_i2c_gated_gpio67_xfer,
+       .functionality = dibx000_i2c_func,
+};
+
+static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
+                                       struct i2c_msg msg[], int num)
+{
+       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+       int ret;
+
+       if (num > 32) {
+               dprintk("%s: too much I2C message to be transmitted (%i).\
+                               Maximum is 32", __func__, num);
+               return -ENOMEM;
+       }
+
+       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
+
+       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+       memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+
+       /* open the gate */
+       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
+       mst->msg[0].addr = mst->i2c_addr;
+       mst->msg[0].buf = &mst->i2c_write_buffer[0];
+       mst->msg[0].len = 4;
+
+       memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+
+       /* close the gate */
+       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
+       mst->msg[num + 1].addr = mst->i2c_addr;
+       mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
+       mst->msg[num + 1].len = 4;
+
+       ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
+                       num : -EIO);
+       mutex_unlock(&mst->i2c_buffer_lock);
+       return ret;
+}
+
+static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
+       .master_xfer = dibx000_i2c_gated_tuner_xfer,
+       .functionality = dibx000_i2c_func,
+};
+
+struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
+                                               enum dibx000_i2c_interface intf,
+                                               int gating)
+{
+       struct i2c_adapter *i2c = NULL;
+
+       switch (intf) {
+       case DIBX000_I2C_INTERFACE_TUNER:
+               if (gating)
+                       i2c = &mst->gated_tuner_i2c_adap;
+               break;
+       case DIBX000_I2C_INTERFACE_GPIO_1_2:
+               if (!gating)
+                       i2c = &mst->master_i2c_adap_gpio12;
+               break;
+       case DIBX000_I2C_INTERFACE_GPIO_3_4:
+               if (!gating)
+                       i2c = &mst->master_i2c_adap_gpio34;
+               break;
+       case DIBX000_I2C_INTERFACE_GPIO_6_7:
+               if (gating)
+                       i2c = &mst->master_i2c_adap_gpio67;
+               break;
+       default:
+               printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
+               break;
+       }
+
+       return i2c;
+}
+
+EXPORT_SYMBOL(dibx000_get_i2c_adapter);
+
+void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
+{
+       /* initialize the i2c-master by closing the gate */
+       u8 tx[4];
+       struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
+
+       dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
+       i2c_transfer(mst->i2c_adap, &m, 1);
+       mst->selected_interface = 0xff; // the first time force a select of the I2C
+       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
+}
+
+EXPORT_SYMBOL(dibx000_reset_i2c_master);
+
+static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
+                               struct i2c_algorithm *algo, const char *name,
+                               struct dibx000_i2c_master *mst)
+{
+       strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
+       i2c_adap->algo = algo;
+       i2c_adap->algo_data = NULL;
+       i2c_set_adapdata(i2c_adap, mst);
+       if (i2c_add_adapter(i2c_adap) < 0)
+               return -ENODEV;
+       return 0;
+}
+
+int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
+                               struct i2c_adapter *i2c_adap, u8 i2c_addr)
+{
+       int ret;
+
+       mutex_init(&mst->i2c_buffer_lock);
+       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
+               dprintk("could not acquire lock");
+               return -EINVAL;
+       }
+       memset(mst->msg, 0, sizeof(struct i2c_msg));
+       mst->msg[0].addr = i2c_addr >> 1;
+       mst->msg[0].flags = 0;
+       mst->msg[0].buf = mst->i2c_write_buffer;
+       mst->msg[0].len = 4;
+
+       mst->device_rev = device_rev;
+       mst->i2c_adap = i2c_adap;
+       mst->i2c_addr = i2c_addr >> 1;
+
+       if (device_rev == DIB7000P || device_rev == DIB8000)
+               mst->base_reg = 1024;
+       else
+               mst->base_reg = 768;
+
+       mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
+       if (i2c_adapter_init
+                       (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
+                        "DiBX000 tuner I2C bus", mst) != 0)
+               printk(KERN_ERR
+                               "DiBX000: could not initialize the tuner i2c_adapter\n");
+
+       mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
+       if (i2c_adapter_init
+                       (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
+                        "DiBX000 master GPIO12 I2C bus", mst) != 0)
+               printk(KERN_ERR
+                               "DiBX000: could not initialize the master i2c_adapter\n");
+
+       mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
+       if (i2c_adapter_init
+                       (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
+                        "DiBX000 master GPIO34 I2C bus", mst) != 0)
+               printk(KERN_ERR
+                               "DiBX000: could not initialize the master i2c_adapter\n");
+
+       mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
+       if (i2c_adapter_init
+                       (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
+                        "DiBX000 master GPIO67 I2C bus", mst) != 0)
+               printk(KERN_ERR
+                               "DiBX000: could not initialize the master i2c_adapter\n");
+
+       /* initialize the i2c-master by closing the gate */
+       dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
+
+       ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
+       mutex_unlock(&mst->i2c_buffer_lock);
+
+       return ret;
+}
+
+EXPORT_SYMBOL(dibx000_init_i2c_master);
+
+void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
+{
+       i2c_del_adapter(&mst->gated_tuner_i2c_adap);
+       i2c_del_adapter(&mst->master_i2c_adap_gpio12);
+       i2c_del_adapter(&mst->master_i2c_adap_gpio34);
+       i2c_del_adapter(&mst->master_i2c_adap_gpio67);
+}
+EXPORT_SYMBOL(dibx000_exit_i2c_master);
+
+
+u32 systime(void)
+{
+       struct timespec t;
+
+       t = current_kernel_time();
+       return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
+}
+EXPORT_SYMBOL(systime);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h
new file mode 100644 (file)
index 0000000..5f48488
--- /dev/null
@@ -0,0 +1,280 @@
+#ifndef DIBX000_COMMON_H
+#define DIBX000_COMMON_H
+
+enum dibx000_i2c_interface {
+       DIBX000_I2C_INTERFACE_TUNER = 0,
+       DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
+       DIBX000_I2C_INTERFACE_GPIO_3_4 = 2,
+       DIBX000_I2C_INTERFACE_GPIO_6_7 = 3
+};
+
+struct dibx000_i2c_master {
+#define DIB3000MC 1
+#define DIB7000   2
+#define DIB7000P  11
+#define DIB7000MC 12
+#define DIB8000   13
+       u16 device_rev;
+
+       enum dibx000_i2c_interface selected_interface;
+
+/*     struct i2c_adapter  tuner_i2c_adap; */
+       struct i2c_adapter gated_tuner_i2c_adap;
+       struct i2c_adapter master_i2c_adap_gpio12;
+       struct i2c_adapter master_i2c_adap_gpio34;
+       struct i2c_adapter master_i2c_adap_gpio67;
+
+       struct i2c_adapter *i2c_adap;
+       u8 i2c_addr;
+
+       u16 base_reg;
+
+       /* for the I2C transfer */
+       struct i2c_msg msg[34];
+       u8 i2c_write_buffer[8];
+       u8 i2c_read_buffer[2];
+       struct mutex i2c_buffer_lock;
+};
+
+extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
+                                       u16 device_rev, struct i2c_adapter *i2c_adap,
+                                       u8 i2c_addr);
+extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
+                                                       *mst,
+                                                       enum dibx000_i2c_interface
+                                                       intf, int gating);
+extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
+extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
+extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed);
+
+extern u32 systime(void);
+
+#define BAND_LBAND 0x01
+#define BAND_UHF   0x02
+#define BAND_VHF   0x04
+#define BAND_SBAND 0x08
+#define BAND_FM           0x10
+#define BAND_CBAND 0x20
+
+#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
+                                                                       (freq_kHz) <= 115000 ? BAND_FM : \
+                                                                       (freq_kHz) <= 250000 ? BAND_VHF : \
+                                                                       (freq_kHz) <= 863000 ? BAND_UHF : \
+                                                                       (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
+
+struct dibx000_agc_config {
+       /* defines the capabilities of this AGC-setting - using the BAND_-defines */
+       u8 band_caps;
+
+       u16 setup;
+
+       u16 inv_gain;
+       u16 time_stabiliz;
+
+       u8 alpha_level;
+       u16 thlock;
+
+       u8 wbd_inv;
+       u16 wbd_ref;
+       u8 wbd_sel;
+       u8 wbd_alpha;
+
+       u16 agc1_max;
+       u16 agc1_min;
+       u16 agc2_max;
+       u16 agc2_min;
+
+       u8 agc1_pt1;
+       u8 agc1_pt2;
+       u8 agc1_pt3;
+
+       u8 agc1_slope1;
+       u8 agc1_slope2;
+
+       u8 agc2_pt1;
+       u8 agc2_pt2;
+
+       u8 agc2_slope1;
+       u8 agc2_slope2;
+
+       u8 alpha_mant;
+       u8 alpha_exp;
+
+       u8 beta_mant;
+       u8 beta_exp;
+
+       u8 perform_agc_softsplit;
+
+       struct {
+               u16 min;
+               u16 max;
+               u16 min_thres;
+               u16 max_thres;
+       } split;
+};
+
+struct dibx000_bandwidth_config {
+       u32 internal;
+       u32 sampling;
+
+       u8 pll_prediv;
+       u8 pll_ratio;
+       u8 pll_range;
+       u8 pll_reset;
+       u8 pll_bypass;
+
+       u8 enable_refdiv;
+       u8 bypclk_div;
+       u8 IO_CLK_en_core;
+       u8 ADClkSrc;
+       u8 modulo;
+
+       u16 sad_cfg;
+
+       u32 ifreq;
+       u32 timf;
+
+       u32 xtal_hz;
+};
+
+enum dibx000_adc_states {
+       DIBX000_SLOW_ADC_ON = 0,
+       DIBX000_SLOW_ADC_OFF,
+       DIBX000_ADC_ON,
+       DIBX000_ADC_OFF,
+       DIBX000_VBG_ENABLE,
+       DIBX000_VBG_DISABLE,
+};
+
+#define BANDWIDTH_TO_KHZ(v)    ((v) / 1000)
+#define BANDWIDTH_TO_HZ(v)     ((v) * 1000)
+
+/* Chip output mode. */
+#define OUTMODE_HIGH_Z              0
+#define OUTMODE_MPEG2_PAR_GATED_CLK 1
+#define OUTMODE_MPEG2_PAR_CONT_CLK  2
+#define OUTMODE_MPEG2_SERIAL        7
+#define OUTMODE_DIVERSITY           4
+#define OUTMODE_MPEG2_FIFO          5
+#define OUTMODE_ANALOG_ADC          6
+
+#define INPUT_MODE_OFF                0x11
+#define INPUT_MODE_DIVERSITY          0x12
+#define INPUT_MODE_MPEG               0x13
+
+enum frontend_tune_state {
+       CT_TUNER_START = 10,
+       CT_TUNER_STEP_0,
+       CT_TUNER_STEP_1,
+       CT_TUNER_STEP_2,
+       CT_TUNER_STEP_3,
+       CT_TUNER_STEP_4,
+       CT_TUNER_STEP_5,
+       CT_TUNER_STEP_6,
+       CT_TUNER_STEP_7,
+       CT_TUNER_STOP,
+
+       CT_AGC_START = 20,
+       CT_AGC_STEP_0,
+       CT_AGC_STEP_1,
+       CT_AGC_STEP_2,
+       CT_AGC_STEP_3,
+       CT_AGC_STEP_4,
+       CT_AGC_STOP,
+
+       CT_DEMOD_START = 30,
+       CT_DEMOD_STEP_1,
+       CT_DEMOD_STEP_2,
+       CT_DEMOD_STEP_3,
+       CT_DEMOD_STEP_4,
+       CT_DEMOD_STEP_5,
+       CT_DEMOD_STEP_6,
+       CT_DEMOD_STEP_7,
+       CT_DEMOD_STEP_8,
+       CT_DEMOD_STEP_9,
+       CT_DEMOD_STEP_10,
+       CT_DEMOD_SEARCH_NEXT = 41,
+       CT_DEMOD_STEP_LOCKED,
+       CT_DEMOD_STOP,
+
+       CT_DONE = 100,
+       CT_SHUTDOWN,
+
+};
+
+struct dvb_frontend_parametersContext {
+#define CHANNEL_STATUS_PARAMETERS_UNKNOWN   0x01
+#define CHANNEL_STATUS_PARAMETERS_SET       0x02
+       u8 status;
+       u32 tune_time_estimation[2];
+       s32 tps_available;
+       u16 tps[9];
+};
+
+#define FE_STATUS_TUNE_FAILED          0
+#define FE_STATUS_TUNE_TIMED_OUT      -1
+#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
+#define FE_STATUS_TUNE_PENDING        -3
+#define FE_STATUS_STD_SUCCESS         -4
+#define FE_STATUS_FFT_SUCCESS         -5
+#define FE_STATUS_DEMOD_SUCCESS       -6
+#define FE_STATUS_LOCKED              -7
+#define FE_STATUS_DATA_LOCKED         -8
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
+#define ABS(x) ((x < 0) ? (-x) : (x))
+
+#define DATA_BUS_ACCESS_MODE_8BIT                 0x01
+#define DATA_BUS_ACCESS_MODE_16BIT                0x02
+#define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10
+
+struct dibGPIOFunction {
+#define BOARD_GPIO_COMPONENT_BUS_ADAPTER 1
+#define BOARD_GPIO_COMPONENT_DEMOD       2
+       u8 component;
+
+#define BOARD_GPIO_FUNCTION_BOARD_ON      1
+#define BOARD_GPIO_FUNCTION_BOARD_OFF     2
+#define BOARD_GPIO_FUNCTION_COMPONENT_ON  3
+#define BOARD_GPIO_FUNCTION_COMPONENT_OFF 4
+#define BOARD_GPIO_FUNCTION_SUBBAND_PWM   5
+#define BOARD_GPIO_FUNCTION_SUBBAND_GPIO   6
+       u8 function;
+
+/* mask, direction and value are used specify which GPIO to change GPIO0
+ * is LSB and possible GPIO31 is MSB.  The same bit-position as in the
+ * mask is used for the direction and the value. Direction == 1 is OUT,
+ * 0 == IN. For direction "OUT" value is either 1 or 0, for direction IN
+ * value has no meaning.
+ *
+ * In case of BOARD_GPIO_FUNCTION_PWM mask is giving the GPIO to be
+ * used to do the PWM. Direction gives the PWModulator to be used.
+ * Value gives the PWM value in device-dependent scale.
+ */
+       u32 mask;
+       u32 direction;
+       u32 value;
+};
+
+#define MAX_NB_SUBBANDS   8
+struct dibSubbandSelection {
+       u8  size; /* Actual number of subbands. */
+       struct {
+               u16 f_mhz;
+               struct dibGPIOFunction gpio;
+       } subband[MAX_NB_SUBBANDS];
+};
+
+#define DEMOD_TIMF_SET    0x00
+#define DEMOD_TIMF_GET    0x01
+#define DEMOD_TIMF_UPDATE 0x02
+
+#define MPEG_ON_DIBTX          1
+#define DIV_ON_DIBTX           2
+#define ADC_ON_DIBTX           3
+#define DEMOUT_ON_HOSTBUS      4
+#define DIBTX_ON_HOSTBUS       5
+#define MPEG_ON_HOSTBUS                6
+
+#endif
diff --git a/drivers/media/dvb-frontends/drxd.h b/drivers/media/dvb-frontends/drxd.h
new file mode 100644 (file)
index 0000000..216c8c3
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * drxd.h: DRXD DVB-T demodulator driver
+ *
+ * Copyright (C) 2005-2007 Micronas
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _DRXD_H_
+#define _DRXD_H_
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+struct drxd_config {
+       u8 index;
+
+       u8 pll_address;
+       u8 pll_type;
+#define DRXD_PLL_NONE     0
+#define DRXD_PLL_DTT7520X 1
+#define DRXD_PLL_MT3X0823 2
+
+       u32 clock;
+       u8 insert_rs_byte;
+
+       u8 demod_address;
+       u8 demoda_address;
+       u8 demod_revision;
+
+       /* If the tuner is not behind an i2c gate, be sure to flip this bit
+          or else the i2c bus could get wedged */
+       u8 disable_i2c_gate_ctrl;
+
+       u32 IF;
+        s16(*osc_deviation) (void *priv, s16 dev, int flag);
+};
+
+#if defined(CONFIG_DVB_DRXD) || \
+                       (defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *drxd_attach(const struct drxd_config *config,
+                                void *priv, struct i2c_adapter *i2c,
+                                struct device *dev);
+#else
+static inline
+struct dvb_frontend *drxd_attach(const struct drxd_config *config,
+                                void *priv, struct i2c_adapter *i2c,
+                                struct device *dev)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __func__);
+       return NULL;
+}
+#endif
+
+extern int drxd_config_i2c(struct dvb_frontend *, int);
+#endif
diff --git a/drivers/media/dvb-frontends/drxd_firm.c b/drivers/media/dvb-frontends/drxd_firm.c
new file mode 100644 (file)
index 0000000..5418b0b
--- /dev/null
@@ -0,0 +1,929 @@
+/*
+ * drxd_firm.c : DRXD firmware tables
+ *
+ * Copyright (C) 2006-2007 Micronas
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* TODO: generate this file with a script from a settings file */
+
+/* Contains A2 firmware version: 1.4.2
+ * Contains B1 firmware version: 3.3.33
+ * Contains settings from driver 1.4.23
+*/
+
+#include "drxd_firm.h"
+
+#define ADDRESS(x)     ((x) & 0xFF), (((x)>>8) & 0xFF), (((x)>>16) & 0xFF), (((x)>>24) & 0xFF)
+#define LENGTH(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
+
+/* Is written via block write, must be little endian */
+#define DATA16(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
+
+#define WRBLOCK(a, l) ADDRESS(a), LENGTH(l)
+#define WR16(a, d) ADDRESS(a), LENGTH(1), DATA16(d)
+
+#define END_OF_TABLE      0xFF, 0xFF, 0xFF, 0xFF
+
+/* HI firmware patches */
+
+#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
+#define HI_TR_FUNC_SIZE 9      /* size of this function in instruction words */
+
+u8 DRXD_InitAtomicRead[] = {
+       WRBLOCK(HI_TR_FUNC_ADDR, HI_TR_FUNC_SIZE),
+       0x26, 0x00,             /* 0         -> ring.rdy;           */
+       0x60, 0x04,             /* r0rami.dt -> ring.xba;           */
+       0x61, 0x04,             /* r0rami.dt -> ring.xad;           */
+       0xE3, 0x07,             /* HI_RA_RAM_USR_BEGIN -> ring.iad; */
+       0x40, 0x00,             /* (long immediate)                 */
+       0x64, 0x04,             /* r0rami.dt -> ring.len;           */
+       0x65, 0x04,             /* r0rami.dt -> ring.ctl;           */
+       0x26, 0x00,             /* 0         -> ring.rdy;           */
+       0x38, 0x00,             /* 0         -> jumps.ad;           */
+       END_OF_TABLE
+};
+
+/* Pins D0 and D1 of the parallel MPEG output can be used
+   to set the I2C address of a device. */
+
+#define HI_RST_FUNC_ADDR (HI_IF_RAM_USR_BEGIN__A + HI_TR_FUNC_SIZE)
+#define HI_RST_FUNC_SIZE 54    /* size of this function in instruction words */
+
+/* D0 Version */
+u8 DRXD_HiI2cPatch_1[] = {
+       WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
+       0xC8, 0x07, 0x01, 0x00, /* MASK      -> reg0.dt;                        */
+       0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
+       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+       0xA2, 0x00,             /* M_BNK_ID_DAT -> ring.iba;                    */
+       0x23, 0x00,             /* &data     -> ring.iad;                       */
+       0x24, 0x00,             /* 0         -> ring.len;                       */
+       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
+       0xC0, 0x07, 0xFF, 0x0F, /* -1        -> w0ram.dt;                       */
+       0x63, 0x00,             /* &data+1   -> ring.iad;                       */
+       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
+       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+       0x23, 0x00,             /* &data     -> ring.iad;                       */
+       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
+       0x0F, 0x04,             /* r0ram.dt  -> and.op;                         */
+       0x1C, 0x06,             /* reg0.dt   -> and.tr;                         */
+       0xCF, 0x04,             /* and.rs    -> add.op;                         */
+       0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr;                        */
+       0xD0, 0x04,             /* add.rs    -> add.tr;                         */
+       0xC8, 0x04,             /* add.rs    -> reg0.dt;                        */
+       0x60, 0x00,             /* reg0.dt   -> w0ram.dt;                       */
+       0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
+       0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
+       0xC2, 0x07, 0x30, 0x00, /* CMD_BASE  -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x68, 0x00,             /* M_IC_SEL_PT1 -> i2c.sel;                     */
+       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
+       0x28, 0x00,             /* M_IC_SEL_PT0 -> i2c.sel;                     */
+       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
+       0xF8, 0x07, 0x2F, 0x00, /* 0x2F      -> jumps.ad;                       */
+
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+
+       /* Force quick and dirty reset */
+       WR16(B_HI_CT_REG_COMM_STATE__A, 0),
+       END_OF_TABLE
+};
+
+/* D0,D1 Version */
+u8 DRXD_HiI2cPatch_3[] = {
+       WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
+       0xC8, 0x07, 0x03, 0x00, /* MASK      -> reg0.dt;                        */
+       0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
+       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+       0xA2, 0x00,             /* M_BNK_ID_DAT -> ring.iba;                    */
+       0x23, 0x00,             /* &data     -> ring.iad;                       */
+       0x24, 0x00,             /* 0         -> ring.len;                       */
+       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
+       0xC0, 0x07, 0xFF, 0x0F, /* -1        -> w0ram.dt;                       */
+       0x63, 0x00,             /* &data+1   -> ring.iad;                       */
+       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
+       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+       0x23, 0x00,             /* &data     -> ring.iad;                       */
+       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+       0x26, 0x00,             /* 0         -> ring.rdy;                       */
+       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
+       0x0F, 0x04,             /* r0ram.dt  -> and.op;                         */
+       0x1C, 0x06,             /* reg0.dt   -> and.tr;                         */
+       0xCF, 0x04,             /* and.rs    -> add.op;                         */
+       0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr;                        */
+       0xD0, 0x04,             /* add.rs    -> add.tr;                         */
+       0xC8, 0x04,             /* add.rs    -> reg0.dt;                        */
+       0x60, 0x00,             /* reg0.dt   -> w0ram.dt;                       */
+       0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
+       0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
+       0xC2, 0x07, 0x30, 0x00, /* CMD_BASE  -> w0rami.ad;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
+       0x68, 0x00,             /* M_IC_SEL_PT1 -> i2c.sel;                     */
+       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
+       0x28, 0x00,             /* M_IC_SEL_PT0 -> i2c.sel;                     */
+       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
+       0xF8, 0x07, 0x2F, 0x00, /* 0x2F      -> jumps.ad;                       */
+
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
+            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+
+       /* Force quick and dirty reset */
+       WR16(B_HI_CT_REG_COMM_STATE__A, 0),
+       END_OF_TABLE
+};
+
+u8 DRXD_ResetCEFR[] = {
+       WRBLOCK(CE_REG_FR_TREAL00__A, 57),
+       0x52, 0x00,             /* CE_REG_FR_TREAL00__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG00__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL01__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG01__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL02__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG02__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL03__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG03__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL04__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG04__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL05__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG05__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL06__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG06__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL07__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG07__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL08__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG08__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL09__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG09__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL10__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG10__A */
+       0x52, 0x00,             /* CE_REG_FR_TREAL11__A */
+       0x00, 0x00,             /* CE_REG_FR_TIMAG11__A */
+
+       0x52, 0x00,             /* CE_REG_FR_MID_TAP__A */
+
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G00__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G01__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G02__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G03__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G04__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G05__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G06__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G07__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G08__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G09__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G10__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G11__A */
+       0x0B, 0x00,             /* CE_REG_FR_SQS_G12__A */
+
+       0xFF, 0x01,             /* CE_REG_FR_RIO_G00__A */
+       0x90, 0x01,             /* CE_REG_FR_RIO_G01__A */
+       0x0B, 0x01,             /* CE_REG_FR_RIO_G02__A */
+       0xC8, 0x00,             /* CE_REG_FR_RIO_G03__A */
+       0xA0, 0x00,             /* CE_REG_FR_RIO_G04__A */
+       0x85, 0x00,             /* CE_REG_FR_RIO_G05__A */
+       0x72, 0x00,             /* CE_REG_FR_RIO_G06__A */
+       0x64, 0x00,             /* CE_REG_FR_RIO_G07__A */
+       0x59, 0x00,             /* CE_REG_FR_RIO_G08__A */
+       0x50, 0x00,             /* CE_REG_FR_RIO_G09__A */
+       0x49, 0x00,             /* CE_REG_FR_RIO_G10__A */
+
+       0x10, 0x00,             /* CE_REG_FR_MODE__A     */
+       0x78, 0x00,             /* CE_REG_FR_SQS_TRH__A  */
+       0x00, 0x00,             /* CE_REG_FR_RIO_GAIN__A */
+       0x00, 0x02,             /* CE_REG_FR_BYPASS__A   */
+       0x0D, 0x00,             /* CE_REG_FR_PM_SET__A   */
+       0x07, 0x00,             /* CE_REG_FR_ERR_SH__A   */
+       0x04, 0x00,             /* CE_REG_FR_MAN_SH__A   */
+       0x06, 0x00,             /* CE_REG_FR_TAP_SH__A   */
+
+       END_OF_TABLE
+};
+
+u8 DRXD_InitFEA2_1[] = {
+       WRBLOCK(FE_AD_REG_PD__A, 3),
+       0x00, 0x00,             /* FE_AD_REG_PD__A          */
+       0x01, 0x00,             /* FE_AD_REG_INVEXT__A      */
+       0x00, 0x00,             /* FE_AD_REG_CLKNEG__A      */
+
+       WRBLOCK(FE_AG_REG_DCE_AUR_CNT__A, 2),
+       0x10, 0x00,             /* FE_AG_REG_DCE_AUR_CNT__A */
+       0x10, 0x00,             /* FE_AG_REG_DCE_RUR_CNT__A */
+
+       WRBLOCK(FE_AG_REG_ACE_AUR_CNT__A, 2),
+       0x0E, 0x00,             /* FE_AG_REG_ACE_AUR_CNT__A */
+       0x00, 0x00,             /* FE_AG_REG_ACE_RUR_CNT__A */
+
+       WRBLOCK(FE_AG_REG_EGC_FLA_RGN__A, 5),
+       0x04, 0x00,             /* FE_AG_REG_EGC_FLA_RGN__A */
+       0x1F, 0x00,             /* FE_AG_REG_EGC_SLO_RGN__A */
+       0x00, 0x00,             /* FE_AG_REG_EGC_JMP_PSN__A */
+       0x00, 0x00,             /* FE_AG_REG_EGC_FLA_INC__A */
+       0x00, 0x00,             /* FE_AG_REG_EGC_FLA_DEC__A */
+
+       WRBLOCK(FE_AG_REG_GC1_AGC_MAX__A, 2),
+       0xFF, 0x01,             /* FE_AG_REG_GC1_AGC_MAX__A */
+       0x00, 0xFE,             /* FE_AG_REG_GC1_AGC_MIN__A */
+
+       WRBLOCK(FE_AG_REG_IND_WIN__A, 29),
+       0x00, 0x00,             /* FE_AG_REG_IND_WIN__A     */
+       0x05, 0x00,             /* FE_AG_REG_IND_THD_LOL__A */
+       0x0F, 0x00,             /* FE_AG_REG_IND_THD_HIL__A */
+       0x00, 0x00,             /* FE_AG_REG_IND_DEL__A     don't care */
+       0x1E, 0x00,             /* FE_AG_REG_IND_PD1_WRI__A */
+       0x0C, 0x00,             /* FE_AG_REG_PDA_AUR_CNT__A */
+       0x00, 0x00,             /* FE_AG_REG_PDA_RUR_CNT__A */
+       0x00, 0x00,             /* FE_AG_REG_PDA_AVE_DAT__A don't care  */
+       0x00, 0x00,             /* FE_AG_REG_PDC_RUR_CNT__A */
+       0x01, 0x00,             /* FE_AG_REG_PDC_SET_LVL__A */
+       0x02, 0x00,             /* FE_AG_REG_PDC_FLA_RGN__A */
+       0x00, 0x00,             /* FE_AG_REG_PDC_JMP_PSN__A don't care  */
+       0xFF, 0xFF,             /* FE_AG_REG_PDC_FLA_STP__A */
+       0xFF, 0xFF,             /* FE_AG_REG_PDC_SLO_STP__A */
+       0x00, 0x1F,             /* FE_AG_REG_PDC_PD2_WRI__A don't care  */
+       0x00, 0x00,             /* FE_AG_REG_PDC_MAP_DAT__A don't care  */
+       0x02, 0x00,             /* FE_AG_REG_PDC_MAX__A     */
+       0x0C, 0x00,             /* FE_AG_REG_TGA_AUR_CNT__A */
+       0x00, 0x00,             /* FE_AG_REG_TGA_RUR_CNT__A */
+       0x00, 0x00,             /* FE_AG_REG_TGA_AVE_DAT__A don't care  */
+       0x00, 0x00,             /* FE_AG_REG_TGC_RUR_CNT__A */
+       0x22, 0x00,             /* FE_AG_REG_TGC_SET_LVL__A */
+       0x15, 0x00,             /* FE_AG_REG_TGC_FLA_RGN__A */
+       0x00, 0x00,             /* FE_AG_REG_TGC_JMP_PSN__A don't care  */
+       0x01, 0x00,             /* FE_AG_REG_TGC_FLA_STP__A */
+       0x0A, 0x00,             /* FE_AG_REG_TGC_SLO_STP__A */
+       0x00, 0x00,             /* FE_AG_REG_TGC_MAP_DAT__A don't care  */
+       0x10, 0x00,             /* FE_AG_REG_FGA_AUR_CNT__A */
+       0x10, 0x00,             /* FE_AG_REG_FGA_RUR_CNT__A */
+
+       WRBLOCK(FE_AG_REG_BGC_FGC_WRI__A, 2),
+       0x00, 0x00,             /* FE_AG_REG_BGC_FGC_WRI__A */
+       0x00, 0x00,             /* FE_AG_REG_BGC_CGC_WRI__A */
+
+       WRBLOCK(FE_FD_REG_SCL__A, 3),
+       0x05, 0x00,             /* FE_FD_REG_SCL__A         */
+       0x03, 0x00,             /* FE_FD_REG_MAX_LEV__A     */
+       0x05, 0x00,             /* FE_FD_REG_NR__A          */
+
+       WRBLOCK(FE_CF_REG_SCL__A, 5),
+       0x16, 0x00,             /* FE_CF_REG_SCL__A         */
+       0x04, 0x00,             /* FE_CF_REG_MAX_LEV__A     */
+       0x06, 0x00,             /* FE_CF_REG_NR__A          */
+       0x00, 0x00,             /* FE_CF_REG_IMP_VAL__A     */
+       0x01, 0x00,             /* FE_CF_REG_MEAS_VAL__A    */
+
+       WRBLOCK(FE_CU_REG_FRM_CNT_RST__A, 2),
+       0x00, 0x08,             /* FE_CU_REG_FRM_CNT_RST__A */
+       0x00, 0x00,             /* FE_CU_REG_FRM_CNT_STR__A */
+
+       END_OF_TABLE
+};
+
+   /* with PGA */
+/*   WR16COND( DRXD_WITH_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0004), */
+   /* without PGA */
+/*   WR16COND( DRXD_WITHOUT_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0001), */
+/*   WR16(FE_AG_REG_AG_AGC_SIO__A,  (extAttr -> FeAgRegAgAgcSio), 0x0000 );*/
+/*   WR16(FE_AG_REG_AG_PWD__A        ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
+
+u8 DRXD_InitFEA2_2[] = {
+       WR16(FE_AG_REG_CDR_RUR_CNT__A, 0x0010),
+       WR16(FE_AG_REG_FGM_WRI__A, 48),
+       /* Activate measurement, activate scale */
+       WR16(FE_FD_REG_MEAS_VAL__A, 0x0001),
+
+       WR16(FE_CU_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_CF_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_IF_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_FD_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_FS_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_AD_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_AG_REG_COMM_EXEC__A, 0x0001),
+       WR16(FE_AG_REG_AG_MODE_LOP__A, 0x895E),
+
+       END_OF_TABLE
+};
+
+u8 DRXD_InitFEB1_1[] = {
+       WR16(B_FE_AD_REG_PD__A, 0x0000),
+       WR16(B_FE_AD_REG_CLKNEG__A, 0x0000),
+       WR16(B_FE_AG_REG_BGC_FGC_WRI__A, 0x0000),
+       WR16(B_FE_AG_REG_BGC_CGC_WRI__A, 0x0000),
+       WR16(B_FE_AG_REG_AG_MODE_LOP__A, 0x000a),
+       WR16(B_FE_AG_REG_IND_PD1_WRI__A, 35),
+       WR16(B_FE_AG_REG_IND_WIN__A, 0),
+       WR16(B_FE_AG_REG_IND_THD_LOL__A, 8),
+       WR16(B_FE_AG_REG_IND_THD_HIL__A, 8),
+       WR16(B_FE_CF_REG_IMP_VAL__A, 1),
+       WR16(B_FE_AG_REG_EGC_FLA_RGN__A, 7),
+       END_OF_TABLE
+};
+
+       /* with PGA */
+/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   , 0x0000, 0x0000); */
+       /* without PGA */
+/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   ,
+            B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);*/
+                                                                            /*   WR16(B_FE_AG_REG_AG_AGC_SIO__A,(extAttr -> FeAgRegAgAgcSio), 0x0000 );*//*added HS 23-05-2005 */
+/*   WR16(B_FE_AG_REG_AG_PWD__A    ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
+
+u8 DRXD_InitFEB1_2[] = {
+       WR16(B_FE_COMM_EXEC__A, 0x0001),
+
+       /* RF-AGC setup */
+       WR16(B_FE_AG_REG_PDA_AUR_CNT__A, 0x0C),
+       WR16(B_FE_AG_REG_PDC_SET_LVL__A, 0x01),
+       WR16(B_FE_AG_REG_PDC_FLA_RGN__A, 0x02),
+       WR16(B_FE_AG_REG_PDC_FLA_STP__A, 0xFFFF),
+       WR16(B_FE_AG_REG_PDC_SLO_STP__A, 0xFFFF),
+       WR16(B_FE_AG_REG_PDC_MAX__A, 0x02),
+       WR16(B_FE_AG_REG_TGA_AUR_CNT__A, 0x0C),
+       WR16(B_FE_AG_REG_TGC_SET_LVL__A, 0x22),
+       WR16(B_FE_AG_REG_TGC_FLA_RGN__A, 0x15),
+       WR16(B_FE_AG_REG_TGC_FLA_STP__A, 0x01),
+       WR16(B_FE_AG_REG_TGC_SLO_STP__A, 0x0A),
+
+       WR16(B_FE_CU_REG_DIV_NFC_CLP__A, 0),
+       WR16(B_FE_CU_REG_CTR_NFC_OCR__A, 25000),
+       WR16(B_FE_CU_REG_CTR_NFC_ICR__A, 1),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitCPA2[] = {
+       WRBLOCK(CP_REG_BR_SPL_OFFSET__A, 2),
+       0x07, 0x00,             /* CP_REG_BR_SPL_OFFSET__A  */
+       0x0A, 0x00,             /* CP_REG_BR_STR_DEL__A     */
+
+       WRBLOCK(CP_REG_RT_ANG_INC0__A, 4),
+       0x00, 0x00,             /* CP_REG_RT_ANG_INC0__A    */
+       0x00, 0x00,             /* CP_REG_RT_ANG_INC1__A    */
+       0x03, 0x00,             /* CP_REG_RT_DETECT_ENA__A  */
+       0x03, 0x00,             /* CP_REG_RT_DETECT_TRH__A  */
+
+       WRBLOCK(CP_REG_AC_NEXP_OFFS__A, 5),
+       0x32, 0x00,             /* CP_REG_AC_NEXP_OFFS__A   */
+       0x62, 0x00,             /* CP_REG_AC_AVER_POW__A    */
+       0x82, 0x00,             /* CP_REG_AC_MAX_POW__A     */
+       0x26, 0x00,             /* CP_REG_AC_WEIGHT_MAN__A  */
+       0x0F, 0x00,             /* CP_REG_AC_WEIGHT_EXP__A  */
+
+       WRBLOCK(CP_REG_AC_AMP_MODE__A, 2),
+       0x02, 0x00,             /* CP_REG_AC_AMP_MODE__A    */
+       0x01, 0x00,             /* CP_REG_AC_AMP_FIX__A     */
+
+       WR16(CP_REG_INTERVAL__A, 0x0005),
+       WR16(CP_REG_RT_EXP_MARG__A, 0x0004),
+       WR16(CP_REG_AC_ANG_MODE__A, 0x0003),
+
+       WR16(CP_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitCPB1[] = {
+       WR16(B_CP_REG_BR_SPL_OFFSET__A, 0x0008),
+       WR16(B_CP_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitCEA2[] = {
+       WRBLOCK(CE_REG_AVG_POW__A, 4),
+       0x62, 0x00,             /* CE_REG_AVG_POW__A        */
+       0x78, 0x00,             /* CE_REG_MAX_POW__A        */
+       0x62, 0x00,             /* CE_REG_ATT__A            */
+       0x17, 0x00,             /* CE_REG_NRED__A           */
+
+       WRBLOCK(CE_REG_NE_ERR_SELECT__A, 2),
+       0x07, 0x00,             /* CE_REG_NE_ERR_SELECT__A  */
+       0xEB, 0xFF,             /* CE_REG_NE_TD_CAL__A      */
+
+       WRBLOCK(CE_REG_NE_MIXAVG__A, 2),
+       0x06, 0x00,             /* CE_REG_NE_MIXAVG__A      */
+       0x00, 0x00,             /* CE_REG_NE_NUPD_OFS__A    */
+
+       WRBLOCK(CE_REG_PE_NEXP_OFFS__A, 2),
+       0x00, 0x00,             /* CE_REG_PE_NEXP_OFFS__A   */
+       0x00, 0x00,             /* CE_REG_PE_TIMESHIFT__A   */
+
+       WRBLOCK(CE_REG_TP_A0_TAP_NEW__A, 3),
+       0x00, 0x01,             /* CE_REG_TP_A0_TAP_NEW__A       */
+       0x01, 0x00,             /* CE_REG_TP_A0_TAP_NEW_VALID__A */
+       0x0E, 0x00,             /* CE_REG_TP_A0_MU_LMS_STEP__A   */
+
+       WRBLOCK(CE_REG_TP_A1_TAP_NEW__A, 3),
+       0x00, 0x00,             /* CE_REG_TP_A1_TAP_NEW__A        */
+       0x01, 0x00,             /* CE_REG_TP_A1_TAP_NEW_VALID__A  */
+       0x0A, 0x00,             /* CE_REG_TP_A1_MU_LMS_STEP__A    */
+
+       WRBLOCK(CE_REG_FI_SHT_INCR__A, 2),
+       0x12, 0x00,             /* CE_REG_FI_SHT_INCR__A          */
+       0x0C, 0x00,             /* CE_REG_FI_EXP_NORM__A          */
+
+       WRBLOCK(CE_REG_IR_INPUTSEL__A, 3),
+       0x00, 0x00,             /* CE_REG_IR_INPUTSEL__A          */
+       0x00, 0x00,             /* CE_REG_IR_STARTPOS__A          */
+       0xFF, 0x00,             /* CE_REG_IR_NEXP_THRES__A        */
+
+       WR16(CE_REG_TI_NEXP_OFFS__A, 0x0000),
+
+       END_OF_TABLE
+};
+
+u8 DRXD_InitCEB1[] = {
+       WR16(B_CE_REG_TI_PHN_ENABLE__A, 0x0001),
+       WR16(B_CE_REG_FR_PM_SET__A, 0x000D),
+
+       END_OF_TABLE
+};
+
+u8 DRXD_InitEQA2[] = {
+       WRBLOCK(EQ_REG_OT_QNT_THRES0__A, 4),
+       0x1E, 0x00,             /* EQ_REG_OT_QNT_THRES0__A        */
+       0x1F, 0x00,             /* EQ_REG_OT_QNT_THRES1__A        */
+       0x06, 0x00,             /* EQ_REG_OT_CSI_STEP__A          */
+       0x02, 0x00,             /* EQ_REG_OT_CSI_OFFSET__A        */
+
+       WR16(EQ_REG_TD_REQ_SMB_CNT__A, 0x0200),
+       WR16(EQ_REG_IS_CLIP_EXP__A, 0x001F),
+       WR16(EQ_REG_SN_OFFSET__A, (u16) (-7)),
+       WR16(EQ_REG_RC_SEL_CAR__A, 0x0002),
+       WR16(EQ_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitEQB1[] = {
+       WR16(B_EQ_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_ResetECRAM[] = {
+       /* Reset packet sync bytes in EC_VD ram */
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+       /* Reset packet sync bytes in EC_RS ram */
+       WR16(EC_RS_EC_RAM__A, 0x0000),
+       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitECA2[] = {
+       WRBLOCK(EC_SB_REG_CSI_HI__A, 6),
+       0x1F, 0x00,             /* EC_SB_REG_CSI_HI__A            */
+       0x1E, 0x00,             /* EC_SB_REG_CSI_LO__A            */
+       0x01, 0x00,             /* EC_SB_REG_SMB_TGL__A           */
+       0x7F, 0x00,             /* EC_SB_REG_SNR_HI__A            */
+       0x7F, 0x00,             /* EC_SB_REG_SNR_MID__A           */
+       0x7F, 0x00,             /* EC_SB_REG_SNR_LO__A            */
+
+       WRBLOCK(EC_RS_REG_REQ_PCK_CNT__A, 2),
+       0x00, 0x10,             /* EC_RS_REG_REQ_PCK_CNT__A       */
+       DATA16(EC_RS_REG_VAL_PCK),      /* EC_RS_REG_VAL__A               */
+
+       WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
+       0x03, 0x00,             /* EC_OC_REG_TMD_TOP_MODE__A      */
+       0xF4, 0x01,             /* EC_OC_REG_TMD_TOP_CNT__A       */
+       0xC0, 0x03,             /* EC_OC_REG_TMD_HIL_MAR__A       */
+       0x40, 0x00,             /* EC_OC_REG_TMD_LOL_MAR__A       */
+       0x03, 0x00,             /* EC_OC_REG_TMD_CUR_CNT__A       */
+
+       WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
+       0x06, 0x00,             /* EC_OC_REG_AVR_ASH_CNT__A       */
+       0x02, 0x00,             /* EC_OC_REG_AVR_BSH_CNT__A       */
+
+       WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
+       0x07, 0x00,             /* EC_OC_REG_RCN_MODE__A          */
+       0x00, 0x00,             /* EC_OC_REG_RCN_CRA_LOP__A       */
+       0xc0, 0x00,             /* EC_OC_REG_RCN_CRA_HIP__A       */
+       0x00, 0x10,             /* EC_OC_REG_RCN_CST_LOP__A       */
+       0x00, 0x00,             /* EC_OC_REG_RCN_CST_HIP__A       */
+       0xFF, 0x01,             /* EC_OC_REG_RCN_SET_LVL__A       */
+       0x0D, 0x00,             /* EC_OC_REG_RCN_GAI_LVL__A       */
+
+       WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
+       0x00, 0x00,             /* EC_OC_REG_RCN_CLP_LOP__A       */
+       0xC0, 0x00,             /* EC_OC_REG_RCN_CLP_HIP__A       */
+
+       WR16(EC_SB_REG_CSI_OFS__A, 0x0001),
+       WR16(EC_VD_REG_FORCE__A, 0x0002),
+       WR16(EC_VD_REG_REQ_SMB_CNT__A, 0x0001),
+       WR16(EC_VD_REG_RLK_ENA__A, 0x0001),
+       WR16(EC_OD_REG_SYNC__A, 0x0664),
+       WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
+       WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
+       /* Output zero on monitorbus pads, power saving */
+       WR16(EC_OC_REG_OCR_MON_UOS__A,
+            (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
+       WR16(EC_OC_REG_OCR_MON_WRI__A,
+            EC_OC_REG_OCR_MON_WRI_INIT),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+       /* Reset packet sync bytes in EC_VD ram */
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+       /* Reset packet sync bytes in EC_RS ram */
+       WR16(EC_RS_EC_RAM__A, 0x0000),
+       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+       WR16(EC_SB_REG_COMM_EXEC__A, 0x0001),
+       WR16(EC_VD_REG_COMM_EXEC__A, 0x0001),
+       WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
+       WR16(EC_RS_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitECB1[] = {
+       WR16(B_EC_SB_REG_CSI_OFS0__A, 0x0001),
+       WR16(B_EC_SB_REG_CSI_OFS1__A, 0x0001),
+       WR16(B_EC_SB_REG_CSI_OFS2__A, 0x0001),
+       WR16(B_EC_SB_REG_CSI_LO__A, 0x000c),
+       WR16(B_EC_SB_REG_CSI_HI__A, 0x0018),
+       WR16(B_EC_SB_REG_SNR_HI__A, 0x007f),
+       WR16(B_EC_SB_REG_SNR_MID__A, 0x007f),
+       WR16(B_EC_SB_REG_SNR_LO__A, 0x007f),
+
+       WR16(B_EC_OC_REG_DTO_CLKMODE__A, 0x0002),
+       WR16(B_EC_OC_REG_DTO_PER__A, 0x0006),
+       WR16(B_EC_OC_REG_DTO_BUR__A, 0x0001),
+       WR16(B_EC_OC_REG_RCR_CLKMODE__A, 0x0000),
+       WR16(B_EC_OC_REG_RCN_GAI_LVL__A, 0x000D),
+       WR16(B_EC_OC_REG_OC_MPG_SIO__A, 0x0000),
+
+       /* Needed because shadow registers do not have correct default value */
+       WR16(B_EC_OC_REG_RCN_CST_LOP__A, 0x1000),
+       WR16(B_EC_OC_REG_RCN_CST_HIP__A, 0x0000),
+       WR16(B_EC_OC_REG_RCN_CRA_LOP__A, 0x0000),
+       WR16(B_EC_OC_REG_RCN_CRA_HIP__A, 0x00C0),
+       WR16(B_EC_OC_REG_RCN_CLP_LOP__A, 0x0000),
+       WR16(B_EC_OC_REG_RCN_CLP_HIP__A, 0x00C0),
+       WR16(B_EC_OC_REG_DTO_INC_LOP__A, 0x0000),
+       WR16(B_EC_OC_REG_DTO_INC_HIP__A, 0x00C0),
+
+       WR16(B_EC_OD_REG_SYNC__A, 0x0664),
+       WR16(B_EC_RS_REG_REQ_PCK_CNT__A, 0x1000),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+       /* Reset packet sync bytes in EC_VD ram */
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+       /* Reset packet sync bytes in EC_RS ram */
+       WR16(EC_RS_EC_RAM__A, 0x0000),
+       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+       WR16(B_EC_SB_REG_COMM_EXEC__A, 0x0001),
+       WR16(B_EC_VD_REG_COMM_EXEC__A, 0x0001),
+       WR16(B_EC_OD_REG_COMM_EXEC__A, 0x0001),
+       WR16(B_EC_RS_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_ResetECA2[] = {
+
+       WR16(EC_OC_REG_COMM_EXEC__A, 0x0000),
+       WR16(EC_OD_REG_COMM_EXEC__A, 0x0000),
+
+       WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
+       0x03, 0x00,             /* EC_OC_REG_TMD_TOP_MODE__A      */
+       0xF4, 0x01,             /* EC_OC_REG_TMD_TOP_CNT__A       */
+       0xC0, 0x03,             /* EC_OC_REG_TMD_HIL_MAR__A       */
+       0x40, 0x00,             /* EC_OC_REG_TMD_LOL_MAR__A       */
+       0x03, 0x00,             /* EC_OC_REG_TMD_CUR_CNT__A       */
+
+       WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
+       0x06, 0x00,             /* EC_OC_REG_AVR_ASH_CNT__A       */
+       0x02, 0x00,             /* EC_OC_REG_AVR_BSH_CNT__A       */
+
+       WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
+       0x07, 0x00,             /* EC_OC_REG_RCN_MODE__A          */
+       0x00, 0x00,             /* EC_OC_REG_RCN_CRA_LOP__A       */
+       0xc0, 0x00,             /* EC_OC_REG_RCN_CRA_HIP__A       */
+       0x00, 0x10,             /* EC_OC_REG_RCN_CST_LOP__A       */
+       0x00, 0x00,             /* EC_OC_REG_RCN_CST_HIP__A       */
+       0xFF, 0x01,             /* EC_OC_REG_RCN_SET_LVL__A       */
+       0x0D, 0x00,             /* EC_OC_REG_RCN_GAI_LVL__A       */
+
+       WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
+       0x00, 0x00,             /* EC_OC_REG_RCN_CLP_LOP__A       */
+       0xC0, 0x00,             /* EC_OC_REG_RCN_CLP_HIP__A       */
+
+       WR16(EC_OD_REG_SYNC__A, 0x0664),
+       WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
+       WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
+       /* Output zero on monitorbus pads, power saving */
+       WR16(EC_OC_REG_OCR_MON_UOS__A,
+            (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
+             EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
+       WR16(EC_OC_REG_OCR_MON_WRI__A,
+            EC_OC_REG_OCR_MON_WRI_INIT),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+       /* Reset packet sync bytes in EC_VD ram */
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+       /* Reset packet sync bytes in EC_RS ram */
+       WR16(EC_RS_EC_RAM__A, 0x0000),
+       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+       WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_InitSC[] = {
+       WR16(SC_COMM_EXEC__A, 0),
+       WR16(SC_COMM_STATE__A, 0),
+
+#ifdef COMPILE_FOR_QT
+       WR16(SC_RA_RAM_BE_OPT_DELAY__A, 0x100),
+#endif
+
+       /* SC is not started, this is done in SetChannels() */
+       END_OF_TABLE
+};
+
+/* Diversity settings */
+
+u8 DRXD_InitDiversityFront[] = {
+       /* Start demod ********* RF in , diversity out **************************** */
+       WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
+            B_SC_RA_RAM_CONFIG_FREQSCAN__M),
+
+       WR16(B_SC_RA_RAM_LC_ABS_2K__A, 0x7),
+       WR16(B_SC_RA_RAM_LC_ABS_8K__A, 0x7),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
+
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
+
+       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
+       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
+       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
+
+       WR16(B_CC_REG_DIVERSITY__A, 0x0001),
+       WR16(B_EC_OC_REG_OC_MODE_HIP__A, 0x0010),
+       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |
+            B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
+
+       /*    0x2a ), *//* CE to PASS mux */
+
+       END_OF_TABLE
+};
+
+u8 DRXD_InitDiversityEnd[] = {
+       /* End demod *********** combining RF in and diversity in, MPEG TS out **** */
+       /* disable near/far; switch on timing slave mode */
+       WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
+            B_SC_RA_RAM_CONFIG_FREQSCAN__M |
+            B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M |
+            B_SC_RA_RAM_CONFIG_SLAVE__M |
+            B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M
+/* MV from CtrlDiversity */
+           ),
+#ifdef DRXDDIV_SRMM_SLAVING
+       WR16(SC_RA_RAM_LC_ABS_2K__A, 0x3c7),
+       WR16(SC_RA_RAM_LC_ABS_8K__A, 0x3c7),
+#else
+       WR16(SC_RA_RAM_LC_ABS_2K__A, 0x7),
+       WR16(SC_RA_RAM_LC_ABS_8K__A, 0x7),
+#endif
+
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
+
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
+
+       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
+       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
+       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
+
+       WR16(B_CC_REG_DIVERSITY__A, 0x0001),
+       END_OF_TABLE
+};
+
+u8 DRXD_DisableDiversity[] = {
+       WR16(B_SC_RA_RAM_LC_ABS_2K__A, B_SC_RA_RAM_LC_ABS_2K__PRE),
+       WR16(B_SC_RA_RAM_LC_ABS_8K__A, B_SC_RA_RAM_LC_ABS_8K__PRE),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A,
+            B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A,
+            B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE),
+       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A,
+            B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A,
+            B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A,
+            B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A,
+            B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE),
+
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A,
+            B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A,
+            B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE),
+       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A,
+            B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A,
+            B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A,
+            B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE),
+       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A,
+            B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE),
+
+       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, B_LC_RA_RAM_FILTER_CRMM_A__PRE),
+       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, B_LC_RA_RAM_FILTER_CRMM_B__PRE),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, B_LC_RA_RAM_FILTER_SRMM_A__PRE),
+       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, B_LC_RA_RAM_FILTER_SRMM_B__PRE),
+       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, B_LC_RA_RAM_FILTER_SYM_SET__PRE),
+
+       WR16(B_CC_REG_DIVERSITY__A, 0x0000),
+       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_INIT), /* combining disabled */
+
+       END_OF_TABLE
+};
+
+u8 DRXD_StartDiversityFront[] = {
+       /* Start demod, RF in and diversity out, no combining */
+       WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),
+       WR16(B_FE_AD_REG_FDB_IN__A, 0x0),
+       WR16(B_FE_AD_REG_INVEXT__A, 0x0),
+       WR16(B_EQ_REG_COMM_MB__A, 0x12),        /* EQ to MB out */
+       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |    /* CE to PASS mux */
+            B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
+
+       WR16(SC_RA_RAM_ECHO_SHIFT_LIM__A, 2),
+
+       END_OF_TABLE
+};
+
+u8 DRXD_StartDiversityEnd[] = {
+       /* End demod, combining RF in and diversity in, MPEG TS out */
+       WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),      /* disable impulse noise cruncher */
+       WR16(B_FE_AD_REG_INVEXT__A, 0x0),       /* clock inversion (for sohard board) */
+       WR16(B_CP_REG_BR_STR_DEL__A, 10),       /* apperently no mb delay matching is best */
+
+       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_DIV_ON |       /* org = 0x81 combining enabled */
+            B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
+            B_EQ_REG_RC_SEL_CAR_PASS_A_CC | B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC),
+
+       END_OF_TABLE
+};
+
+u8 DRXD_DiversityDelay8MHZ[] = {
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1150 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1100 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 1000 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 800 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5420 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5200 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4800 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 4000 - 50),
+       END_OF_TABLE
+};
+
+u8 DRXD_DiversityDelay6MHZ[] = /* also used ok for 7 MHz */
+{
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1100 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1000 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 900 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 600 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5300 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5000 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4500 - 50),
+       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 3500 - 50),
+       END_OF_TABLE
+};
diff --git a/drivers/media/dvb-frontends/drxd_firm.h b/drivers/media/dvb-frontends/drxd_firm.h
new file mode 100644 (file)
index 0000000..41597e8
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * drxd_firm.h
+ *
+ * Copyright (C) 2006-2007 Micronas
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _DRXD_FIRM_H_
+#define _DRXD_FIRM_H_
+
+#include <linux/types.h>
+#include "drxd_map_firm.h"
+
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 4
+#define VERSION_PATCH 23
+
+#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
+
+#define DRXD_MAX_RETRIES (1000)
+#define HI_I2C_DELAY     84
+#define HI_I2C_BRIDGE_DELAY   750
+
+#define EQ_TD_TPS_PWR_UNKNOWN          0x00C0  /* Unknown configurations */
+#define EQ_TD_TPS_PWR_QPSK             0x016a
+#define EQ_TD_TPS_PWR_QAM16_ALPHAN     0x0195
+#define EQ_TD_TPS_PWR_QAM16_ALPHA1     0x0195
+#define EQ_TD_TPS_PWR_QAM16_ALPHA2     0x011E
+#define EQ_TD_TPS_PWR_QAM16_ALPHA4     0x01CE
+#define EQ_TD_TPS_PWR_QAM64_ALPHAN     0x019F
+#define EQ_TD_TPS_PWR_QAM64_ALPHA1     0x019F
+#define EQ_TD_TPS_PWR_QAM64_ALPHA2     0x00F8
+#define EQ_TD_TPS_PWR_QAM64_ALPHA4     0x014D
+
+#define DRXD_DEF_AG_PWD_CONSUMER 0x000E
+#define DRXD_DEF_AG_PWD_PRO 0x0000
+#define DRXD_DEF_AG_AGC_SIO 0x0000
+
+#define DRXD_FE_CTRL_MAX 1023
+
+#define DRXD_OSCDEV_DO_SCAN  (16)
+
+#define DRXD_OSCDEV_DONT_SCAN  (0)
+
+#define DRXD_OSCDEV_STEP  (275)
+
+#define DRXD_SCAN_TIMEOUT    (650)
+
+#define DRXD_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
+#define DRXD_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
+#define DRXD_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
+
+#define IRLEN_COARSE_8K       (10)
+#define IRLEN_FINE_8K         (10)
+#define IRLEN_COARSE_2K       (7)
+#define IRLEN_FINE_2K         (9)
+#define DIFF_INVALID          (511)
+#define DIFF_TARGET           (4)
+#define DIFF_MARGIN           (1)
+
+extern u8 DRXD_InitAtomicRead[];
+extern u8 DRXD_HiI2cPatch_1[];
+extern u8 DRXD_HiI2cPatch_3[];
+
+extern u8 DRXD_InitSC[];
+
+extern u8 DRXD_ResetCEFR[];
+extern u8 DRXD_InitFEA2_1[];
+extern u8 DRXD_InitFEA2_2[];
+extern u8 DRXD_InitCPA2[];
+extern u8 DRXD_InitCEA2[];
+extern u8 DRXD_InitEQA2[];
+extern u8 DRXD_InitECA2[];
+extern u8 DRXD_ResetECA2[];
+extern u8 DRXD_ResetECRAM[];
+
+extern u8 DRXD_A2_microcode[];
+extern u32 DRXD_A2_microcode_length;
+
+extern u8 DRXD_InitFEB1_1[];
+extern u8 DRXD_InitFEB1_2[];
+extern u8 DRXD_InitCPB1[];
+extern u8 DRXD_InitCEB1[];
+extern u8 DRXD_InitEQB1[];
+extern u8 DRXD_InitECB1[];
+
+extern u8 DRXD_InitDiversityFront[];
+extern u8 DRXD_InitDiversityEnd[];
+extern u8 DRXD_DisableDiversity[];
+extern u8 DRXD_StartDiversityFront[];
+extern u8 DRXD_StartDiversityEnd[];
+
+extern u8 DRXD_DiversityDelay8MHZ[];
+extern u8 DRXD_DiversityDelay6MHZ[];
+
+extern u8 DRXD_B1_microcode[];
+extern u32 DRXD_B1_microcode_length;
+
+#endif
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
new file mode 100644 (file)
index 0000000..f380eb4
--- /dev/null
@@ -0,0 +1,2992 @@
+/*
+ * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
+ *
+ * Copyright (C) 2003-2007 Micronas
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drxd.h"
+#include "drxd_firm.h"
+
+#define DRX_FW_FILENAME_A2 "drxd-a2-1.1.fw"
+#define DRX_FW_FILENAME_B1 "drxd-b1-1.1.fw"
+
+#define CHUNK_SIZE 48
+
+#define DRX_I2C_RMW           0x10
+#define DRX_I2C_BROADCAST     0x20
+#define DRX_I2C_CLEARCRC      0x80
+#define DRX_I2C_SINGLE_MASTER 0xC0
+#define DRX_I2C_MODEFLAGS     0xC0
+#define DRX_I2C_FLAGS         0xF0
+
+#ifndef SIZEOF_ARRAY
+#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
+#endif
+
+#define DEFAULT_LOCK_TIMEOUT    1100
+
+#define DRX_CHANNEL_AUTO 0
+#define DRX_CHANNEL_HIGH 1
+#define DRX_CHANNEL_LOW  2
+
+#define DRX_LOCK_MPEG  1
+#define DRX_LOCK_FEC   2
+#define DRX_LOCK_DEMOD 4
+
+/****************************************************************************/
+
+enum CSCDState {
+       CSCD_INIT = 0,
+       CSCD_SET,
+       CSCD_SAVED
+};
+
+enum CDrxdState {
+       DRXD_UNINITIALIZED = 0,
+       DRXD_STOPPED,
+       DRXD_STARTED
+};
+
+enum AGC_CTRL_MODE {
+       AGC_CTRL_AUTO = 0,
+       AGC_CTRL_USER,
+       AGC_CTRL_OFF
+};
+
+enum OperationMode {
+       OM_Default,
+       OM_DVBT_Diversity_Front,
+       OM_DVBT_Diversity_End
+};
+
+struct SCfgAgc {
+       enum AGC_CTRL_MODE ctrlMode;
+       u16 outputLevel;        /* range [0, ... , 1023], 1/n of fullscale range */
+       u16 settleLevel;        /* range [0, ... , 1023], 1/n of fullscale range */
+       u16 minOutputLevel;     /* range [0, ... , 1023], 1/n of fullscale range */
+       u16 maxOutputLevel;     /* range [0, ... , 1023], 1/n of fullscale range */
+       u16 speed;              /* range [0, ... , 1023], 1/n of fullscale range */
+
+       u16 R1;
+       u16 R2;
+       u16 R3;
+};
+
+struct SNoiseCal {
+       int cpOpt;
+       short cpNexpOfs;
+       short tdCal2k;
+       short tdCal8k;
+};
+
+enum app_env {
+       APPENV_STATIC = 0,
+       APPENV_PORTABLE = 1,
+       APPENV_MOBILE = 2
+};
+
+enum EIFFilter {
+       IFFILTER_SAW = 0,
+       IFFILTER_DISCRETE = 1
+};
+
+struct drxd_state {
+       struct dvb_frontend frontend;
+       struct dvb_frontend_ops ops;
+       struct dtv_frontend_properties props;
+
+       const struct firmware *fw;
+       struct device *dev;
+
+       struct i2c_adapter *i2c;
+       void *priv;
+       struct drxd_config config;
+
+       int i2c_access;
+       int init_done;
+       struct mutex mutex;
+
+       u8 chip_adr;
+       u16 hi_cfg_timing_div;
+       u16 hi_cfg_bridge_delay;
+       u16 hi_cfg_wakeup_key;
+       u16 hi_cfg_ctrl;
+
+       u16 intermediate_freq;
+       u16 osc_clock_freq;
+
+       enum CSCDState cscd_state;
+       enum CDrxdState drxd_state;
+
+       u16 sys_clock_freq;
+       s16 osc_clock_deviation;
+       u16 expected_sys_clock_freq;
+
+       u16 insert_rs_byte;
+       u16 enable_parallel;
+
+       int operation_mode;
+
+       struct SCfgAgc if_agc_cfg;
+       struct SCfgAgc rf_agc_cfg;
+
+       struct SNoiseCal noise_cal;
+
+       u32 fe_fs_add_incr;
+       u32 org_fe_fs_add_incr;
+       u16 current_fe_if_incr;
+
+       u16 m_FeAgRegAgPwd;
+       u16 m_FeAgRegAgAgcSio;
+
+       u16 m_EcOcRegOcModeLop;
+       u16 m_EcOcRegSncSncLvl;
+       u8 *m_InitAtomicRead;
+       u8 *m_HiI2cPatch;
+
+       u8 *m_ResetCEFR;
+       u8 *m_InitFE_1;
+       u8 *m_InitFE_2;
+       u8 *m_InitCP;
+       u8 *m_InitCE;
+       u8 *m_InitEQ;
+       u8 *m_InitSC;
+       u8 *m_InitEC;
+       u8 *m_ResetECRAM;
+       u8 *m_InitDiversityFront;
+       u8 *m_InitDiversityEnd;
+       u8 *m_DisableDiversity;
+       u8 *m_StartDiversityFront;
+       u8 *m_StartDiversityEnd;
+
+       u8 *m_DiversityDelay8MHZ;
+       u8 *m_DiversityDelay6MHZ;
+
+       u8 *microcode;
+       u32 microcode_length;
+
+       int type_A;
+       int PGA;
+       int diversity;
+       int tuner_mirrors;
+
+       enum app_env app_env_default;
+       enum app_env app_env_diversity;
+
+};
+
+/****************************************************************************/
+/* I2C **********************************************************************/
+/****************************************************************************/
+
+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 * data, int len)
+{
+       struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len };
+
+       if (i2c_transfer(adap, &msg, 1) != 1)
+               return -1;
+       return 0;
+}
+
+static int i2c_read(struct i2c_adapter *adap,
+                   u8 adr, u8 *msg, int len, u8 *answ, int alen)
+{
+       struct i2c_msg msgs[2] = {
+               {
+                       .addr = adr, .flags = 0,
+                       .buf = msg, .len = len
+               }, {
+                       .addr = adr, .flags = I2C_M_RD,
+                       .buf = answ, .len = alen
+               }
+       };
+       if (i2c_transfer(adap, msgs, 2) != 2)
+               return -1;
+       return 0;
+}
+
+static inline u32 MulDiv32(u32 a, u32 b, u32 c)
+{
+       u64 tmp64;
+
+       tmp64 = (u64)a * (u64)b;
+       do_div(tmp64, c);
+
+       return (u32) tmp64;
+}
+
+static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
+{
+       u8 adr = state->config.demod_address;
+       u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
+               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+       };
+       u8 mm2[2];
+       if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2) < 0)
+               return -1;
+       if (data)
+               *data = mm2[0] | (mm2[1] << 8);
+       return mm2[0] | (mm2[1] << 8);
+}
+
+static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
+{
+       u8 adr = state->config.demod_address;
+       u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
+               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+       };
+       u8 mm2[4];
+
+       if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4) < 0)
+               return -1;
+       if (data)
+               *data =
+                   mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
+       return 0;
+}
+
+static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
+{
+       u8 adr = state->config.demod_address;
+       u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
+               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
+               data & 0xff, (data >> 8) & 0xff
+       };
+
+       if (i2c_write(state->i2c, adr, mm, 6) < 0)
+               return -1;
+       return 0;
+}
+
+static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
+{
+       u8 adr = state->config.demod_address;
+       u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
+               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
+               data & 0xff, (data >> 8) & 0xff,
+               (data >> 16) & 0xff, (data >> 24) & 0xff
+       };
+
+       if (i2c_write(state->i2c, adr, mm, 8) < 0)
+               return -1;
+       return 0;
+}
+
+static int write_chunk(struct drxd_state *state,
+                      u32 reg, u8 *data, u32 len, u8 flags)
+{
+       u8 adr = state->config.demod_address;
+       u8 mm[CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
+               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+       };
+       int i;
+
+       for (i = 0; i < len; i++)
+               mm[4 + i] = data[i];
+       if (i2c_write(state->i2c, adr, mm, 4 + len) < 0) {
+               printk(KERN_ERR "error in write_chunk\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int WriteBlock(struct drxd_state *state,
+                     u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
+{
+       while (BlockSize > 0) {
+               u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
+
+               if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
+                       return -1;
+               pBlock += Chunk;
+               Address += (Chunk >> 1);
+               BlockSize -= Chunk;
+       }
+       return 0;
+}
+
+static int WriteTable(struct drxd_state *state, u8 * pTable)
+{
+       int status = 0;
+
+       if (pTable == NULL)
+               return 0;
+
+       while (!status) {
+               u16 Length;
+               u32 Address = pTable[0] | (pTable[1] << 8) |
+                   (pTable[2] << 16) | (pTable[3] << 24);
+
+               if (Address == 0xFFFFFFFF)
+                       break;
+               pTable += sizeof(u32);
+
+               Length = pTable[0] | (pTable[1] << 8);
+               pTable += sizeof(u16);
+               if (!Length)
+                       break;
+               status = WriteBlock(state, Address, Length * 2, pTable, 0);
+               pTable += (Length * 2);
+       }
+       return status;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static int ResetCEFR(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_ResetCEFR);
+}
+
+static int InitCP(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_InitCP);
+}
+
+static int InitCE(struct drxd_state *state)
+{
+       int status;
+       enum app_env AppEnv = state->app_env_default;
+
+       do {
+               status = WriteTable(state, state->m_InitCE);
+               if (status < 0)
+                       break;
+
+               if (state->operation_mode == OM_DVBT_Diversity_Front ||
+                   state->operation_mode == OM_DVBT_Diversity_End) {
+                       AppEnv = state->app_env_diversity;
+               }
+               if (AppEnv == APPENV_STATIC) {
+                       status = Write16(state, CE_REG_TAPSET__A, 0x0000, 0);
+                       if (status < 0)
+                               break;
+               } else if (AppEnv == APPENV_PORTABLE) {
+                       status = Write16(state, CE_REG_TAPSET__A, 0x0001, 0);
+                       if (status < 0)
+                               break;
+               } else if (AppEnv == APPENV_MOBILE && state->type_A) {
+                       status = Write16(state, CE_REG_TAPSET__A, 0x0002, 0);
+                       if (status < 0)
+                               break;
+               } else if (AppEnv == APPENV_MOBILE && !state->type_A) {
+                       status = Write16(state, CE_REG_TAPSET__A, 0x0006, 0);
+                       if (status < 0)
+                               break;
+               }
+
+               /* start ce */
+               status = Write16(state, B_CE_REG_COMM_EXEC__A, 0x0001, 0);
+               if (status < 0)
+                       break;
+       } while (0);
+       return status;
+}
+
+static int StopOC(struct drxd_state *state)
+{
+       int status = 0;
+       u16 ocSyncLvl = 0;
+       u16 ocModeLop = state->m_EcOcRegOcModeLop;
+       u16 dtoIncLop = 0;
+       u16 dtoIncHip = 0;
+
+       do {
+               /* Store output configuration */
+               status = Read16(state, EC_OC_REG_SNC_ISC_LVL__A, &ocSyncLvl, 0);
+               if (status < 0)
+                       break;
+               /* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A, &ocModeLop)); */
+               state->m_EcOcRegSncSncLvl = ocSyncLvl;
+               /* m_EcOcRegOcModeLop = ocModeLop; */
+
+               /* Flush FIFO (byte-boundary) at fixed rate */
+               status = Read16(state, EC_OC_REG_RCN_MAP_LOP__A, &dtoIncLop, 0);
+               if (status < 0)
+                       break;
+               status = Read16(state, EC_OC_REG_RCN_MAP_HIP__A, &dtoIncHip, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_DTO_INC_LOP__A, dtoIncLop, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_DTO_INC_HIP__A, dtoIncHip, 0);
+               if (status < 0)
+                       break;
+               ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
+               ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
+               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
+               if (status < 0)
+                       break;
+
+               msleep(1);
+               /* Output pins to '0' */
+               status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS__M, 0);
+               if (status < 0)
+                       break;
+
+               /* Force the OC out of sync */
+               ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
+               status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, ocSyncLvl, 0);
+               if (status < 0)
+                       break;
+               ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
+               ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
+               ocModeLop |= 0x2;       /* Magically-out-of-sync */
+               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
+               if (status < 0)
+                       break;
+       } while (0);
+
+       return status;
+}
+
+static int StartOC(struct drxd_state *state)
+{
+       int status = 0;
+
+       do {
+               /* Stop OC */
+               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
+               if (status < 0)
+                       break;
+
+               /* Restore output configuration */
+               status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, state->m_EcOcRegSncSncLvl, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, state->m_EcOcRegOcModeLop, 0);
+               if (status < 0)
+                       break;
+
+               /* Output pins active again */
+               status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS_INIT, 0);
+               if (status < 0)
+                       break;
+
+               /* Start OC */
+               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
+               if (status < 0)
+                       break;
+       } while (0);
+       return status;
+}
+
+static int InitEQ(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_InitEQ);
+}
+
+static int InitEC(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_InitEC);
+}
+
+static int InitSC(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_InitSC);
+}
+
+static int InitAtomicRead(struct drxd_state *state)
+{
+       return WriteTable(state, state->m_InitAtomicRead);
+}
+
+static int CorrectSysClockDeviation(struct drxd_state *state);
+
+static int DRX_GetLockStatus(struct drxd_state *state, u32 * pLockStatus)
+{
+       u16 ScRaRamLock = 0;
+       const u16 mpeg_lock_mask = (SC_RA_RAM_LOCK_MPEG__M |
+                                   SC_RA_RAM_LOCK_FEC__M |
+                                   SC_RA_RAM_LOCK_DEMOD__M);
+       const u16 fec_lock_mask = (SC_RA_RAM_LOCK_FEC__M |
+                                  SC_RA_RAM_LOCK_DEMOD__M);
+       const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M;
+
+       int status;
+
+       *pLockStatus = 0;
+
+       status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000);
+       if (status < 0) {
+               printk(KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
+               return status;
+       }
+
+       if (state->drxd_state != DRXD_STARTED)
+               return 0;
+
+       if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
+               *pLockStatus |= DRX_LOCK_MPEG;
+               CorrectSysClockDeviation(state);
+       }
+
+       if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
+               *pLockStatus |= DRX_LOCK_FEC;
+
+       if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
+               *pLockStatus |= DRX_LOCK_DEMOD;
+       return 0;
+}
+
+/****************************************************************************/
+
+static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
+{
+       int status;
+
+       if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
+               return -1;
+
+       if (cfg->ctrlMode == AGC_CTRL_USER) {
+               do {
+                       u16 FeAgRegPm1AgcWri;
+                       u16 FeAgRegAgModeLop;
+
+                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
+                       if (status < 0)
+                               break;
+                       FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
+                       FeAgRegAgModeLop |= FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
+                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
+                       if (status < 0)
+                               break;
+
+                       FeAgRegPm1AgcWri = (u16) (cfg->outputLevel &
+                                                 FE_AG_REG_PM1_AGC_WRI__M);
+                       status = Write16(state, FE_AG_REG_PM1_AGC_WRI__A, FeAgRegPm1AgcWri, 0);
+                       if (status < 0)
+                               break;
+               } while (0);
+       } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
+               if (((cfg->maxOutputLevel) < (cfg->minOutputLevel)) ||
+                   ((cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX) ||
+                   ((cfg->speed) > DRXD_FE_CTRL_MAX) ||
+                   ((cfg->settleLevel) > DRXD_FE_CTRL_MAX)
+                   )
+                       return -1;
+               do {
+                       u16 FeAgRegAgModeLop;
+                       u16 FeAgRegEgcSetLvl;
+                       u16 slope, offset;
+
+                       /* == Mode == */
+
+                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
+                       if (status < 0)
+                               break;
+                       FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
+                       FeAgRegAgModeLop |=
+                           FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
+                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
+                       if (status < 0)
+                               break;
+
+                       /* == Settle level == */
+
+                       FeAgRegEgcSetLvl = (u16) ((cfg->settleLevel >> 1) &
+                                                 FE_AG_REG_EGC_SET_LVL__M);
+                       status = Write16(state, FE_AG_REG_EGC_SET_LVL__A, FeAgRegEgcSetLvl, 0);
+                       if (status < 0)
+                               break;
+
+                       /* == Min/Max == */
+
+                       slope = (u16) ((cfg->maxOutputLevel -
+                                       cfg->minOutputLevel) / 2);
+                       offset = (u16) ((cfg->maxOutputLevel +
+                                        cfg->minOutputLevel) / 2 - 511);
+
+                       status = Write16(state, FE_AG_REG_GC1_AGC_RIC__A, slope, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, FE_AG_REG_GC1_AGC_OFF__A, offset, 0);
+                       if (status < 0)
+                               break;
+
+                       /* == Speed == */
+                       {
+                               const u16 maxRur = 8;
+                               const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
+                               const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
+                                       17, 18, 18, 19,
+                                       20, 21, 22, 23,
+                                       24, 26, 27, 28,
+                                       29, 31
+                               };
+
+                               u16 fineSteps = (DRXD_FE_CTRL_MAX + 1) /
+                                   (maxRur + 1);
+                               u16 fineSpeed = (u16) (cfg->speed -
+                                                      ((cfg->speed /
+                                                        fineSteps) *
+                                                       fineSteps));
+                               u16 invRurCount = (u16) (cfg->speed /
+                                                        fineSteps);
+                               u16 rurCount;
+                               if (invRurCount > maxRur) {
+                                       rurCount = 0;
+                                       fineSpeed += fineSteps;
+                               } else {
+                                       rurCount = maxRur - invRurCount;
+                               }
+
+                               /*
+                                  fastInc = default *
+                                  (2^(fineSpeed/fineSteps))
+                                  => range[default...2*default>
+                                  slowInc = default *
+                                  (2^(fineSpeed/fineSteps))
+                                */
+                               {
+                                       u16 fastIncrDec =
+                                           fastIncrDecLUT[fineSpeed /
+                                                          ((fineSteps /
+                                                            (14 + 1)) + 1)];
+                                       u16 slowIncrDec =
+                                           slowIncrDecLUT[fineSpeed /
+                                                          (fineSteps /
+                                                           (3 + 1))];
+
+                                       status = Write16(state, FE_AG_REG_EGC_RUR_CNT__A, rurCount, 0);
+                                       if (status < 0)
+                                               break;
+                                       status = Write16(state, FE_AG_REG_EGC_FAS_INC__A, fastIncrDec, 0);
+                                       if (status < 0)
+                                               break;
+                                       status = Write16(state, FE_AG_REG_EGC_FAS_DEC__A, fastIncrDec, 0);
+                                       if (status < 0)
+                                               break;
+                                       status = Write16(state, FE_AG_REG_EGC_SLO_INC__A, slowIncrDec, 0);
+                                       if (status < 0)
+                                               break;
+                                       status = Write16(state, FE_AG_REG_EGC_SLO_DEC__A, slowIncrDec, 0);
+                                       if (status < 0)
+                                               break;
+                               }
+                       }
+               } while (0);
+
+       } else {
+               /* No OFF mode for IF control */
+               return -1;
+       }
+       return status;
+}
+
+static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
+{
+       int status = 0;
+
+       if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
+               return -1;
+
+       if (cfg->ctrlMode == AGC_CTRL_USER) {
+               do {
+                       u16 AgModeLop = 0;
+                       u16 level = (cfg->outputLevel);
+
+                       if (level == DRXD_FE_CTRL_MAX)
+                               level++;
+
+                       status = Write16(state, FE_AG_REG_PM2_AGC_WRI__A, level, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /*==== Mode ====*/
+
+                       /* Powerdown PD2, WRI source */
+                       state->m_FeAgRegAgPwd &= ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+                       state->m_FeAgRegAgPwd |=
+                           FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
+                       status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+                                     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
+                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* enable AGC2 pin */
+                       {
+                               u16 FeAgRegAgAgcSio = 0;
+                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                               FeAgRegAgAgcSio &=
+                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+                               FeAgRegAgAgcSio |=
+                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
+                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+
+               } while (0);
+       } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
+               u16 AgModeLop = 0;
+
+               do {
+                       u16 level;
+                       /* Automatic control */
+                       /* Powerup PD2, AGC2 as output, TGC source */
+                       (state->m_FeAgRegAgPwd) &=
+                           ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+                       (state->m_FeAgRegAgPwd) |=
+                           FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
+                       status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
+                       if (status < 0)
+                               break;
+
+                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+                                     FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC);
+                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       /* Settle level */
+                       level = (((cfg->settleLevel) >> 4) &
+                                FE_AG_REG_TGC_SET_LVL__M);
+                       status = Write16(state, FE_AG_REG_TGC_SET_LVL__A, level, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* Min/max: don't care */
+
+                       /* Speed: TODO */
+
+                       /* enable AGC2 pin */
+                       {
+                               u16 FeAgRegAgAgcSio = 0;
+                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                               FeAgRegAgAgcSio &=
+                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+                               FeAgRegAgAgcSio |=
+                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
+                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+
+               } while (0);
+       } else {
+               u16 AgModeLop = 0;
+
+               do {
+                       /* No RF AGC control */
+                       /* Powerdown PD2, AGC2 as output, WRI source */
+                       (state->m_FeAgRegAgPwd) &=
+                           ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+                       (state->m_FeAgRegAgPwd) |=
+                           FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
+                       status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
+                       if (status < 0)
+                               break;
+
+                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+                                     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
+                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* set FeAgRegAgAgcSio AGC2 (RF) as input */
+                       {
+                               u16 FeAgRegAgAgcSio = 0;
+                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                               FeAgRegAgAgcSio &=
+                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+                               FeAgRegAgAgcSio |=
+                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
+                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+               } while (0);
+       }
+       return status;
+}
+
+static int ReadIFAgc(struct drxd_state *state, u32 * pValue)
+{
+       int status = 0;
+
+       *pValue = 0;
+       if (state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF) {
+               u16 Value;
+               status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A, &Value, 0);
+               Value &= FE_AG_REG_GC1_AGC_DAT__M;
+               if (status >= 0) {
+                       /*           3.3V
+                          |
+                          R1
+                          |
+                          Vin - R3 - * -- Vout
+                          |
+                          R2
+                          |
+                          GND
+                        */
+                       u32 R1 = state->if_agc_cfg.R1;
+                       u32 R2 = state->if_agc_cfg.R2;
+                       u32 R3 = state->if_agc_cfg.R3;
+
+                       u32 Vmax, Rpar, Vmin, Vout;
+
+                       if (R2 == 0 && (R1 == 0 || R3 == 0))
+                               return 0;
+
+                       Vmax = (3300 * R2) / (R1 + R2);
+                       Rpar = (R2 * R3) / (R3 + R2);
+                       Vmin = (3300 * Rpar) / (R1 + Rpar);
+                       Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
+
+                       *pValue = Vout;
+               }
+       }
+       return status;
+}
+
+static int load_firmware(struct drxd_state *state, const char *fw_name)
+{
+       const struct firmware *fw;
+
+       if (request_firmware(&fw, fw_name, state->dev) < 0) {
+               printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
+               return -EIO;
+       }
+
+       state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
+       if (state->microcode == NULL) {
+               release_firmware(fw);
+               printk(KERN_ERR "drxd: firmware load failure: no memory\n");
+               return -ENOMEM;
+       }
+
+       state->microcode_length = fw->size;
+       release_firmware(fw);
+       return 0;
+}
+
+static int DownloadMicrocode(struct drxd_state *state,
+                            const u8 *pMCImage, u32 Length)
+{
+       u8 *pSrc;
+       u32 Address;
+       u16 nBlocks;
+       u16 BlockSize;
+       u32 offset = 0;
+       int i, status = 0;
+
+       pSrc = (u8 *) pMCImage;
+       /* We're not using Flags */
+       /* Flags = (pSrc[0] << 8) | pSrc[1]; */
+       pSrc += sizeof(u16);
+       offset += sizeof(u16);
+       nBlocks = (pSrc[0] << 8) | pSrc[1];
+       pSrc += sizeof(u16);
+       offset += sizeof(u16);
+
+       for (i = 0; i < nBlocks; i++) {
+               Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
+                   (pSrc[2] << 8) | pSrc[3];
+               pSrc += sizeof(u32);
+               offset += sizeof(u32);
+
+               BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+               /* We're not using Flags */
+               /* u16 Flags = (pSrc[0] << 8) | pSrc[1]; */
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+               /* We're not using BlockCRC */
+               /* u16 BlockCRC = (pSrc[0] << 8) | pSrc[1]; */
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+               status = WriteBlock(state, Address, BlockSize,
+                                   pSrc, DRX_I2C_CLEARCRC);
+               if (status < 0)
+                       break;
+               pSrc += BlockSize;
+               offset += BlockSize;
+       }
+
+       return status;
+}
+
+static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
+{
+       u32 nrRetries = 0;
+       u16 waitCmd;
+       int status;
+
+       status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
+       if (status < 0)
+               return status;
+
+       do {
+               nrRetries += 1;
+               if (nrRetries > DRXD_MAX_RETRIES) {
+                       status = -1;
+                       break;
+               };
+               status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
+       } while (waitCmd != 0);
+
+       if (status >= 0)
+               status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
+       return status;
+}
+
+static int HI_CfgCommand(struct drxd_state *state)
+{
+       int status = 0;
+
+       mutex_lock(&state->mutex);
+       Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+       Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
+       Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, state->hi_cfg_bridge_delay, 0);
+       Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
+       Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
+
+       Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+
+       if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE) ==
+           HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
+               status = Write16(state, HI_RA_RAM_SRV_CMD__A,
+                                HI_RA_RAM_SRV_CMD_CONFIG, 0);
+       else
+               status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+static int InitHI(struct drxd_state *state)
+{
+       state->hi_cfg_wakeup_key = (state->chip_adr);
+       /* port/bridge/power down ctrl */
+       state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
+       return HI_CfgCommand(state);
+}
+
+static int HI_ResetCommand(struct drxd_state *state)
+{
+       int status;
+
+       mutex_lock(&state->mutex);
+       status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
+                        HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+       if (status == 0)
+               status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
+       mutex_unlock(&state->mutex);
+       msleep(1);
+       return status;
+}
+
+static int DRX_ConfigureI2CBridge(struct drxd_state *state, int bEnableBridge)
+{
+       state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
+       if (bEnableBridge)
+               state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
+       else
+               state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
+
+       return HI_CfgCommand(state);
+}
+
+#define HI_TR_WRITE      0x9
+#define HI_TR_READ       0xA
+#define HI_TR_READ_WRITE 0xB
+#define HI_TR_BROADCAST  0x4
+
+#if 0
+static int AtomicReadBlock(struct drxd_state *state,
+                          u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
+{
+       int status;
+       int i = 0;
+
+       /* Parameter check */
+       if ((!pData) || ((DataSize & 1) != 0))
+               return -1;
+
+       mutex_lock(&state->mutex);
+
+       do {
+               /* Instruct HI to read n bytes */
+               /* TODO use proper names forthese egisters */
+               status = Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, (HI_TR_FUNC_ADDR & 0xFFFF), 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, (u16) (Addr >> 16), 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, (u16) (Addr & 0xFFFF), 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, (u16) ((DataSize / 2) - 1), 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, HI_TR_READ, 0);
+               if (status < 0)
+                       break;
+
+               status = HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE, 0);
+               if (status < 0)
+                       break;
+
+       } while (0);
+
+       if (status >= 0) {
+               for (i = 0; i < (DataSize / 2); i += 1) {
+                       u16 word;
+
+                       status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
+                                       &word, 0);
+                       if (status < 0)
+                               break;
+                       pData[2 * i] = (u8) (word & 0xFF);
+                       pData[(2 * i) + 1] = (u8) (word >> 8);
+               }
+       }
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+static int AtomicReadReg32(struct drxd_state *state,
+                          u32 Addr, u32 *pData, u8 Flags)
+{
+       u8 buf[sizeof(u32)];
+       int status;
+
+       if (!pData)
+               return -1;
+       status = AtomicReadBlock(state, Addr, sizeof(u32), buf, Flags);
+       *pData = (((u32) buf[0]) << 0) +
+           (((u32) buf[1]) << 8) +
+           (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
+       return status;
+}
+#endif
+
+static int StopAllProcessors(struct drxd_state *state)
+{
+       return Write16(state, HI_COMM_EXEC__A,
+                      SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
+}
+
+static int EnableAndResetMB(struct drxd_state *state)
+{
+       if (state->type_A) {
+               /* disable? monitor bus observe @ EC_OC */
+               Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
+       }
+
+       /* do inverse broadcast, followed by explicit write to HI */
+       Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
+       Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
+       return 0;
+}
+
+static int InitCC(struct drxd_state *state)
+{
+       if (state->osc_clock_freq == 0 ||
+           state->osc_clock_freq > 20000 ||
+           (state->osc_clock_freq % 4000) != 0) {
+               printk(KERN_ERR "invalid osc frequency %d\n", state->osc_clock_freq);
+               return -1;
+       }
+
+       Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
+       Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
+               CC_REG_PLL_MODE_PUMP_CUR_12, 0);
+       Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq / 4000, 0);
+       Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
+       Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
+
+       return 0;
+}
+
+static int ResetECOD(struct drxd_state *state)
+{
+       int status = 0;
+
+       if (state->type_A)
+               status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
+       else
+               status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
+
+       if (!(status < 0))
+               status = WriteTable(state, state->m_ResetECRAM);
+       if (!(status < 0))
+               status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
+       return status;
+}
+
+/* Configure PGA switch */
+
+static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
+{
+       int status;
+       u16 AgModeLop = 0;
+       u16 AgModeHip = 0;
+       do {
+               if (pgaSwitch) {
+                       /* PGA on */
+                       /* fine gain */
+                       status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
+                       AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
+                       status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* coarse gain */
+                       status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
+                       AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC;
+                       status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* enable fine and coarse gain, enable AAF,
+                          no ext resistor */
+                       status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN, 0x0000);
+                       if (status < 0)
+                               break;
+               } else {
+                       /* PGA off, bypass */
+
+                       /* fine gain */
+                       status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
+                       AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC;
+                       status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* coarse gain */
+                       status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
+                       if (status < 0)
+                               break;
+                       AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
+                       AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC;
+                       status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       /* disable fine and coarse gain, enable AAF,
+                          no ext resistor */
+                       status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);
+                       if (status < 0)
+                               break;
+               }
+       } while (0);
+       return status;
+}
+
+static int InitFE(struct drxd_state *state)
+{
+       int status;
+
+       do {
+               status = WriteTable(state, state->m_InitFE_1);
+               if (status < 0)
+                       break;
+
+               if (state->type_A) {
+                       status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
+                                        FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
+                                        0);
+               } else {
+                       if (state->PGA)
+                               status = SetCfgPga(state, 0);
+                       else
+                               status =
+                                   Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
+                                           B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
+                                           0);
+               }
+
+               if (status < 0)
+                       break;
+               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, state->m_FeAgRegAgAgcSio, 0x0000);
+               if (status < 0)
+                       break;
+               status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
+               if (status < 0)
+                       break;
+
+               status = WriteTable(state, state->m_InitFE_2);
+               if (status < 0)
+                       break;
+
+       } while (0);
+
+       return status;
+}
+
+static int InitFT(struct drxd_state *state)
+{
+       /*
+          norm OFFSET,  MB says =2 voor 8K en =3 voor 2K waarschijnlijk
+          SC stuff
+        */
+       return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000);
+}
+
+static int SC_WaitForReady(struct drxd_state *state)
+{
+       u16 curCmd;
+       int i;
+
+       for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
+               int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
+               if (status == 0 || curCmd == 0)
+                       return status;
+       }
+       return -1;
+}
+
+static int SC_SendCommand(struct drxd_state *state, u16 cmd)
+{
+       int status = 0;
+       u16 errCode;
+
+       Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
+       SC_WaitForReady(state);
+
+       Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
+
+       if (errCode == 0xFFFF) {
+               printk(KERN_ERR "Command Error\n");
+               status = -1;
+       }
+
+       return status;
+}
+
+static int SC_ProcStartCommand(struct drxd_state *state,
+                              u16 subCmd, u16 param0, u16 param1)
+{
+       int status = 0;
+       u16 scExec;
+
+       mutex_lock(&state->mutex);
+       do {
+               Read16(state, SC_COMM_EXEC__A, &scExec, 0);
+               if (scExec != 1) {
+                       status = -1;
+                       break;
+               }
+               SC_WaitForReady(state);
+               Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
+               Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
+               Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
+
+               SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
+       } while (0);
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+static int SC_SetPrefParamCommand(struct drxd_state *state,
+                                 u16 subCmd, u16 param0, u16 param1)
+{
+       int status;
+
+       mutex_lock(&state->mutex);
+       do {
+               status = SC_WaitForReady(state);
+               if (status < 0)
+                       break;
+               status = Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
+               if (status < 0)
+                       break;
+
+               status = SC_SendCommand(state, SC_RA_RAM_CMD_SET_PREF_PARAM);
+               if (status < 0)
+                       break;
+       } while (0);
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+#if 0
+static int SC_GetOpParamCommand(struct drxd_state *state, u16 * result)
+{
+       int status = 0;
+
+       mutex_lock(&state->mutex);
+       do {
+               status = SC_WaitForReady(state);
+               if (status < 0)
+                       break;
+               status = SC_SendCommand(state, SC_RA_RAM_CMD_GET_OP_PARAM);
+               if (status < 0)
+                       break;
+               status = Read16(state, SC_RA_RAM_PARAM0__A, result, 0);
+               if (status < 0)
+                       break;
+       } while (0);
+       mutex_unlock(&state->mutex);
+       return status;
+}
+#endif
+
+static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
+{
+       int status;
+
+       do {
+               u16 EcOcRegIprInvMpg = 0;
+               u16 EcOcRegOcModeLop = 0;
+               u16 EcOcRegOcModeHip = 0;
+               u16 EcOcRegOcMpgSio = 0;
+
+               /*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A, &EcOcRegOcModeLop, 0)); */
+
+               if (state->operation_mode == OM_DVBT_Diversity_Front) {
+                       if (bEnableOutput) {
+                               EcOcRegOcModeHip |=
+                                   B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
+                       } else
+                               EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
+                       EcOcRegOcModeLop |=
+                           EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
+               } else {
+                       EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
+
+                       if (bEnableOutput)
+                               EcOcRegOcMpgSio &= (~(EC_OC_REG_OC_MPG_SIO__M));
+                       else
+                               EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
+
+                       /* Don't Insert RS Byte */
+                       if (state->insert_rs_byte) {
+                               EcOcRegOcModeLop &=
+                                   (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
+                               EcOcRegOcModeHip &=
+                                   (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
+                               EcOcRegOcModeHip |=
+                                   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
+                       } else {
+                               EcOcRegOcModeLop |=
+                                   EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
+                               EcOcRegOcModeHip &=
+                                   (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
+                               EcOcRegOcModeHip |=
+                                   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
+                       }
+
+                       /* Mode = Parallel */
+                       if (state->enable_parallel)
+                               EcOcRegOcModeLop &=
+                                   (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
+                       else
+                               EcOcRegOcModeLop |=
+                                   EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
+               }
+               /* Invert Data */
+               /* EcOcRegIprInvMpg |= 0x00FF; */
+               EcOcRegIprInvMpg &= (~(0x00FF));
+
+               /* Invert Error ( we don't use the pin ) */
+               /*  EcOcRegIprInvMpg |= 0x0100; */
+               EcOcRegIprInvMpg &= (~(0x0100));
+
+               /* Invert Start ( we don't use the pin ) */
+               /* EcOcRegIprInvMpg |= 0x0200; */
+               EcOcRegIprInvMpg &= (~(0x0200));
+
+               /* Invert Valid ( we don't use the pin ) */
+               /* EcOcRegIprInvMpg |= 0x0400; */
+               EcOcRegIprInvMpg &= (~(0x0400));
+
+               /* Invert Clock */
+               /* EcOcRegIprInvMpg |= 0x0800; */
+               EcOcRegIprInvMpg &= (~(0x0800));
+
+               /* EcOcRegOcModeLop =0x05; */
+               status = Write16(state, EC_OC_REG_IPR_INV_MPG__A, EcOcRegIprInvMpg, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, EcOcRegOcModeLop, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_OC_MODE_HIP__A, EcOcRegOcModeHip, 0x0000);
+               if (status < 0)
+                       break;
+               status = Write16(state, EC_OC_REG_OC_MPG_SIO__A, EcOcRegOcMpgSio, 0);
+               if (status < 0)
+                       break;
+       } while (0);
+       return status;
+}
+
+static int SetDeviceTypeId(struct drxd_state *state)
+{
+       int status = 0;
+       u16 deviceId = 0;
+
+       do {
+               status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
+               if (status < 0)
+                       break;
+               /* TODO: why twice? */
+               status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
+               if (status < 0)
+                       break;
+               printk(KERN_INFO "drxd: deviceId = %04x\n", deviceId);
+
+               state->type_A = 0;
+               state->PGA = 0;
+               state->diversity = 0;
+               if (deviceId == 0) {    /* on A2 only 3975 available */
+                       state->type_A = 1;
+                       printk(KERN_INFO "DRX3975D-A2\n");
+               } else {
+                       deviceId >>= 12;
+                       printk(KERN_INFO "DRX397%dD-B1\n", deviceId);
+                       switch (deviceId) {
+                       case 4:
+                               state->diversity = 1;
+                       case 3:
+                       case 7:
+                               state->PGA = 1;
+                               break;
+                       case 6:
+                               state->diversity = 1;
+                       case 5:
+                       case 8:
+                               break;
+                       default:
+                               status = -1;
+                               break;
+                       }
+               }
+       } while (0);
+
+       if (status < 0)
+               return status;
+
+       /* Init Table selection */
+       state->m_InitAtomicRead = DRXD_InitAtomicRead;
+       state->m_InitSC = DRXD_InitSC;
+       state->m_ResetECRAM = DRXD_ResetECRAM;
+       if (state->type_A) {
+               state->m_ResetCEFR = DRXD_ResetCEFR;
+               state->m_InitFE_1 = DRXD_InitFEA2_1;
+               state->m_InitFE_2 = DRXD_InitFEA2_2;
+               state->m_InitCP = DRXD_InitCPA2;
+               state->m_InitCE = DRXD_InitCEA2;
+               state->m_InitEQ = DRXD_InitEQA2;
+               state->m_InitEC = DRXD_InitECA2;
+               if (load_firmware(state, DRX_FW_FILENAME_A2))
+                       return -EIO;
+       } else {
+               state->m_ResetCEFR = NULL;
+               state->m_InitFE_1 = DRXD_InitFEB1_1;
+               state->m_InitFE_2 = DRXD_InitFEB1_2;
+               state->m_InitCP = DRXD_InitCPB1;
+               state->m_InitCE = DRXD_InitCEB1;
+               state->m_InitEQ = DRXD_InitEQB1;
+               state->m_InitEC = DRXD_InitECB1;
+               if (load_firmware(state, DRX_FW_FILENAME_B1))
+                       return -EIO;
+       }
+       if (state->diversity) {
+               state->m_InitDiversityFront = DRXD_InitDiversityFront;
+               state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
+               state->m_DisableDiversity = DRXD_DisableDiversity;
+               state->m_StartDiversityFront = DRXD_StartDiversityFront;
+               state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
+               state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
+               state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
+       } else {
+               state->m_InitDiversityFront = NULL;
+               state->m_InitDiversityEnd = NULL;
+               state->m_DisableDiversity = NULL;
+               state->m_StartDiversityFront = NULL;
+               state->m_StartDiversityEnd = NULL;
+               state->m_DiversityDelay8MHZ = NULL;
+               state->m_DiversityDelay6MHZ = NULL;
+       }
+
+       return status;
+}
+
+static int CorrectSysClockDeviation(struct drxd_state *state)
+{
+       int status;
+       s32 incr = 0;
+       s32 nomincr = 0;
+       u32 bandwidth = 0;
+       u32 sysClockInHz = 0;
+       u32 sysClockFreq = 0;   /* in kHz */
+       s16 oscClockDeviation;
+       s16 Diff;
+
+       do {
+               /* Retrieve bandwidth and incr, sanity check */
+
+               /* These accesses should be AtomicReadReg32, but that
+                  causes trouble (at least for diversity */
+               status = Read32(state, LC_RA_RAM_IFINCR_NOM_L__A, ((u32 *) &nomincr), 0);
+               if (status < 0)
+                       break;
+               status = Read32(state, FE_IF_REG_INCR0__A, (u32 *) &incr, 0);
+               if (status < 0)
+                       break;
+
+               if (state->type_A) {
+                       if ((nomincr - incr < -500) || (nomincr - incr > 500))
+                               break;
+               } else {
+                       if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
+                               break;
+               }
+
+               switch (state->props.bandwidth_hz) {
+               case 8000000:
+                       bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
+                       break;
+               case 7000000:
+                       bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
+                       break;
+               case 6000000:
+                       bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
+                       break;
+               default:
+                       return -1;
+                       break;
+               }
+
+               /* Compute new sysclock value
+                  sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
+               incr += (1 << 23);
+               sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
+               sysClockFreq = (u32) (sysClockInHz / 1000);
+               /* rounding */
+               if ((sysClockInHz % 1000) > 500)
+                       sysClockFreq++;
+
+               /* Compute clock deviation in ppm */
+               oscClockDeviation = (u16) ((((s32) (sysClockFreq) -
+                                            (s32)
+                                            (state->expected_sys_clock_freq)) *
+                                           1000000L) /
+                                          (s32)
+                                          (state->expected_sys_clock_freq));
+
+               Diff = oscClockDeviation - state->osc_clock_deviation;
+               /*printk(KERN_INFO "sysclockdiff=%d\n", Diff); */
+               if (Diff >= -200 && Diff <= 200) {
+                       state->sys_clock_freq = (u16) sysClockFreq;
+                       if (oscClockDeviation != state->osc_clock_deviation) {
+                               if (state->config.osc_deviation) {
+                                       state->config.osc_deviation(state->priv,
+                                                                   oscClockDeviation,
+                                                                   1);
+                                       state->osc_clock_deviation =
+                                           oscClockDeviation;
+                               }
+                       }
+                       /* switch OFF SRMM scan in SC */
+                       status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DONT_SCAN, 0);
+                       if (status < 0)
+                               break;
+                       /* overrule FE_IF internal value for
+                          proper re-locking */
+                       status = Write16(state, SC_RA_RAM_IF_SAVE__AX, state->current_fe_if_incr, 0);
+                       if (status < 0)
+                               break;
+                       state->cscd_state = CSCD_SAVED;
+               }
+       } while (0);
+
+       return status;
+}
+
+static int DRX_Stop(struct drxd_state *state)
+{
+       int status;
+
+       if (state->drxd_state != DRXD_STARTED)
+               return 0;
+
+       do {
+               if (state->cscd_state != CSCD_SAVED) {
+                       u32 lock;
+                       status = DRX_GetLockStatus(state, &lock);
+                       if (status < 0)
+                               break;
+               }
+
+               status = StopOC(state);
+               if (status < 0)
+                       break;
+
+               state->drxd_state = DRXD_STOPPED;
+
+               status = ConfigureMPEGOutput(state, 0);
+               if (status < 0)
+                       break;
+
+               if (state->type_A) {
+                       /* Stop relevant processors off the device */
+                       status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0x0000);
+                       if (status < 0)
+                               break;
+
+                       status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+               } else {
+                       /* Stop all processors except HI & CC & FE */
+                       status = Write16(state, B_SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_FT_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_CP_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_CE_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_EQ_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0);
+                       if (status < 0)
+                               break;
+               }
+
+       } while (0);
+       return status;
+}
+
+int SetOperationMode(struct drxd_state *state, int oMode)
+{
+       int status;
+
+       do {
+               if (state->drxd_state != DRXD_STOPPED) {
+                       status = -1;
+                       break;
+               }
+
+               if (oMode == state->operation_mode) {
+                       status = 0;
+                       break;
+               }
+
+               if (oMode != OM_Default && !state->diversity) {
+                       status = -1;
+                       break;
+               }
+
+               switch (oMode) {
+               case OM_DVBT_Diversity_Front:
+                       status = WriteTable(state, state->m_InitDiversityFront);
+                       break;
+               case OM_DVBT_Diversity_End:
+                       status = WriteTable(state, state->m_InitDiversityEnd);
+                       break;
+               case OM_Default:
+                       /* We need to check how to
+                          get DRXD out of diversity */
+               default:
+                       status = WriteTable(state, state->m_DisableDiversity);
+                       break;
+               }
+       } while (0);
+
+       if (!status)
+               state->operation_mode = oMode;
+       return status;
+}
+
+static int StartDiversity(struct drxd_state *state)
+{
+       int status = 0;
+       u16 rcControl;
+
+       do {
+               if (state->operation_mode == OM_DVBT_Diversity_Front) {
+                       status = WriteTable(state, state->m_StartDiversityFront);
+                       if (status < 0)
+                               break;
+               } else if (state->operation_mode == OM_DVBT_Diversity_End) {
+                       status = WriteTable(state, state->m_StartDiversityEnd);
+                       if (status < 0)
+                               break;
+                       if (state->props.bandwidth_hz == 8000000) {
+                               status = WriteTable(state, state->m_DiversityDelay8MHZ);
+                               if (status < 0)
+                                       break;
+                       } else {
+                               status = WriteTable(state, state->m_DiversityDelay6MHZ);
+                               if (status < 0)
+                                       break;
+                       }
+
+                       status = Read16(state, B_EQ_REG_RC_SEL_CAR__A, &rcControl, 0);
+                       if (status < 0)
+                               break;
+                       rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
+                       rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
+                           /*  combining enabled */
+                           B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
+                           B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
+                           B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
+                       status = Write16(state, B_EQ_REG_RC_SEL_CAR__A, rcControl, 0);
+                       if (status < 0)
+                               break;
+               }
+       } while (0);
+       return status;
+}
+
+static int SetFrequencyShift(struct drxd_state *state,
+                            u32 offsetFreq, int channelMirrored)
+{
+       int negativeShift = (state->tuner_mirrors == channelMirrored);
+
+       /* Handle all mirroring
+        *
+        * Note: ADC mirroring (aliasing) is implictly handled by limiting
+        * feFsRegAddInc to 28 bits below
+        * (if the result before masking is more than 28 bits, this means
+        *  that the ADC is mirroring.
+        * The masking is in fact the aliasing of the ADC)
+        *
+        */
+
+       /* Compute register value, unsigned computation */
+       state->fe_fs_add_incr = MulDiv32(state->intermediate_freq +
+                                        offsetFreq,
+                                        1 << 28, state->sys_clock_freq);
+       /* Remove integer part */
+       state->fe_fs_add_incr &= 0x0FFFFFFFL;
+       if (negativeShift)
+               state->fe_fs_add_incr = ((1 << 28) - state->fe_fs_add_incr);
+
+       /* Save the frequency shift without tunerOffset compensation
+          for CtrlGetChannel. */
+       state->org_fe_fs_add_incr = MulDiv32(state->intermediate_freq,
+                                            1 << 28, state->sys_clock_freq);
+       /* Remove integer part */
+       state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
+       if (negativeShift)
+               state->org_fe_fs_add_incr = ((1L << 28) -
+                                            state->org_fe_fs_add_incr);
+
+       return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
+                      state->fe_fs_add_incr, 0);
+}
+
+static int SetCfgNoiseCalibration(struct drxd_state *state,
+                                 struct SNoiseCal *noiseCal)
+{
+       u16 beOptEna;
+       int status = 0;
+
+       do {
+               status = Read16(state, SC_RA_RAM_BE_OPT_ENA__A, &beOptEna, 0);
+               if (status < 0)
+                       break;
+               if (noiseCal->cpOpt) {
+                       beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
+               } else {
+                       beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
+                       status = Write16(state, CP_REG_AC_NEXP_OFFS__A, noiseCal->cpNexpOfs, 0);
+                       if (status < 0)
+                               break;
+               }
+               status = Write16(state, SC_RA_RAM_BE_OPT_ENA__A, beOptEna, 0);
+               if (status < 0)
+                       break;
+
+               if (!state->type_A) {
+                       status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_2K__A, noiseCal->tdCal2k, 0);
+                       if (status < 0)
+                               break;
+                       status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_8K__A, noiseCal->tdCal8k, 0);
+                       if (status < 0)
+                               break;
+               }
+       } while (0);
+
+       return status;
+}
+
+static int DRX_Start(struct drxd_state *state, s32 off)
+{
+       struct dtv_frontend_properties *p = &state->props;
+       int status;
+
+       u16 transmissionParams = 0;
+       u16 operationMode = 0;
+       u16 qpskTdTpsPwr = 0;
+       u16 qam16TdTpsPwr = 0;
+       u16 qam64TdTpsPwr = 0;
+       u32 feIfIncr = 0;
+       u32 bandwidth = 0;
+       int mirrorFreqSpect;
+
+       u16 qpskSnCeGain = 0;
+       u16 qam16SnCeGain = 0;
+       u16 qam64SnCeGain = 0;
+       u16 qpskIsGainMan = 0;
+       u16 qam16IsGainMan = 0;
+       u16 qam64IsGainMan = 0;
+       u16 qpskIsGainExp = 0;
+       u16 qam16IsGainExp = 0;
+       u16 qam64IsGainExp = 0;
+       u16 bandwidthParam = 0;
+
+       if (off < 0)
+               off = (off - 500) / 1000;
+       else
+               off = (off + 500) / 1000;
+
+       do {
+               if (state->drxd_state != DRXD_STOPPED)
+                       return -1;
+               status = ResetECOD(state);
+               if (status < 0)
+                       break;
+               if (state->type_A) {
+                       status = InitSC(state);
+                       if (status < 0)
+                               break;
+               } else {
+                       status = InitFT(state);
+                       if (status < 0)
+                               break;
+                       status = InitCP(state);
+                       if (status < 0)
+                               break;
+                       status = InitCE(state);
+                       if (status < 0)
+                               break;
+                       status = InitEQ(state);
+                       if (status < 0)
+                               break;
+                       status = InitSC(state);
+                       if (status < 0)
+                               break;
+               }
+
+               /* Restore current IF & RF AGC settings */
+
+               status = SetCfgIfAgc(state, &state->if_agc_cfg);
+               if (status < 0)
+                       break;
+               status = SetCfgRfAgc(state, &state->rf_agc_cfg);
+               if (status < 0)
+                       break;
+
+               mirrorFreqSpect = (state->props.inversion == INVERSION_ON);
+
+               switch (p->transmission_mode) {
+               default:        /* Not set, detect it automatically */
+                       operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
+                       /* fall through , try first guess DRX_FFTMODE_8K */
+               case TRANSMISSION_MODE_8K:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
+                       if (state->type_A) {
+                               status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_8K, 0x0000);
+                               if (status < 0)
+                                       break;
+                               qpskSnCeGain = 99;
+                               qam16SnCeGain = 83;
+                               qam64SnCeGain = 67;
+                       }
+                       break;
+               case TRANSMISSION_MODE_2K:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
+                       if (state->type_A) {
+                               status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_2K, 0x0000);
+                               if (status < 0)
+                                       break;
+                               qpskSnCeGain = 97;
+                               qam16SnCeGain = 71;
+                               qam64SnCeGain = 65;
+                       }
+                       break;
+               }
+
+               switch (p->guard_interval) {
+               case GUARD_INTERVAL_1_4:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
+                       break;
+               case GUARD_INTERVAL_1_8:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
+                       break;
+               case GUARD_INTERVAL_1_16:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
+                       break;
+               case GUARD_INTERVAL_1_32:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
+                       break;
+               default:        /* Not set, detect it automatically */
+                       operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
+                       /* try first guess 1/4 */
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
+                       break;
+               }
+
+               switch (p->hierarchy) {
+               case HIERARCHY_1:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0001, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0001, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
+                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
+
+                               qpskIsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+                               qam16IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
+                               qam64IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
+
+                               qpskIsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+                               qam16IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
+                               qam64IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
+                       }
+                       break;
+
+               case HIERARCHY_2:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0002, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0002, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
+                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
+
+                               qpskIsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+                               qam16IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
+                               qam64IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
+
+                               qpskIsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+                               qam16IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
+                               qam64IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
+                       }
+                       break;
+               case HIERARCHY_4:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0003, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0003, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
+                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
+
+                               qpskIsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+                               qam16IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
+                               qam64IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
+
+                               qpskIsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+                               qam16IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
+                               qam64IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
+                       }
+                       break;
+               case HIERARCHY_AUTO:
+               default:
+                       /* Not set, detect it automatically, start with none */
+                       operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
+                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
+                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
+
+                               qpskIsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
+                               qam16IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
+                               qam64IsGainMan =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
+
+                               qpskIsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
+                               qam16IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
+                               qam64IsGainExp =
+                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
+                       }
+                       break;
+               }
+               status = status;
+               if (status < 0)
+                       break;
+
+               switch (p->modulation) {
+               default:
+                       operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
+                       /* fall through , try first guess
+                          DRX_CONSTELLATION_QAM64 */
+               case QAM_64:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0002, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_64QAM, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0020, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0008, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0002, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam64TdTpsPwr, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qam64SnCeGain, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam64IsGainMan, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam64IsGainExp, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               case QPSK:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_QPSK, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qpskTdTpsPwr, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qpskSnCeGain, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qpskIsGainMan, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qpskIsGainExp, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+
+               case QAM_16:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
+                       if (state->type_A) {
+                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0001, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_16QAM, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0004, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
+                               if (status < 0)
+                                       break;
+
+                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam16TdTpsPwr, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qam16SnCeGain, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam16IsGainMan, 0x0000);
+                               if (status < 0)
+                                       break;
+                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam16IsGainExp, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+
+               }
+               status = status;
+               if (status < 0)
+                       break;
+
+               switch (DRX_CHANNEL_HIGH) {
+               default:
+               case DRX_CHANNEL_AUTO:
+               case DRX_CHANNEL_LOW:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
+                       status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000);
+                       if (status < 0)
+                               break;
+                       break;
+               case DRX_CHANNEL_HIGH:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
+                       status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000);
+                       if (status < 0)
+                               break;
+                       break;
+
+               }
+
+               switch (p->code_rate_HP) {
+               case FEC_1_2:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
+                       if (state->type_A) {
+                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               default:
+                       operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
+               case FEC_2_3:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
+                       if (state->type_A) {
+                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               case FEC_3_4:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
+                       if (state->type_A) {
+                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               case FEC_5_6:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
+                       if (state->type_A) {
+                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               case FEC_7_8:
+                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
+                       if (state->type_A) {
+                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000);
+                               if (status < 0)
+                                       break;
+                       }
+                       break;
+               }
+               status = status;
+               if (status < 0)
+                       break;
+
+               /* First determine real bandwidth (Hz) */
+               /* Also set delay for impulse noise cruncher (only A2) */
+               /* Also set parameters for EC_OC fix, note
+                  EC_OC_REG_TMD_HIL_MAR is changed
+                  by SC for fix for some 8K,1/8 guard but is restored by
+                  InitEC and ResetEC
+                  functions */
+               switch (p->bandwidth_hz) {
+               case 0:
+                       p->bandwidth_hz = 8000000;
+                       /* fall through */
+               case 8000000:
+                       /* (64/7)*(8/8)*1000000 */
+                       bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
+
+                       bandwidthParam = 0;
+                       status = Write16(state,
+                                        FE_AG_REG_IND_DEL__A, 50, 0x0000);
+                       break;
+               case 7000000:
+                       /* (64/7)*(7/8)*1000000 */
+                       bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
+                       bandwidthParam = 0x4807;        /*binary:0100 1000 0000 0111 */
+                       status = Write16(state,
+                                        FE_AG_REG_IND_DEL__A, 59, 0x0000);
+                       break;
+               case 6000000:
+                       /* (64/7)*(6/8)*1000000 */
+                       bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
+                       bandwidthParam = 0x0F07;        /*binary: 0000 1111 0000 0111 */
+                       status = Write16(state,
+                                        FE_AG_REG_IND_DEL__A, 71, 0x0000);
+                       break;
+               default:
+                       status = -EINVAL;
+               }
+               if (status < 0)
+                       break;
+
+               status = Write16(state, SC_RA_RAM_BAND__A, bandwidthParam, 0x0000);
+               if (status < 0)
+                       break;
+
+               {
+                       u16 sc_config;
+                       status = Read16(state, SC_RA_RAM_CONFIG__A, &sc_config, 0);
+                       if (status < 0)
+                               break;
+
+                       /* enable SLAVE mode in 2k 1/32 to
+                          prevent timing change glitches */
+                       if ((p->transmission_mode == TRANSMISSION_MODE_2K) &&
+                           (p->guard_interval == GUARD_INTERVAL_1_32)) {
+                               /* enable slave */
+                               sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
+                       } else {
+                               /* disable slave */
+                               sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
+                       }
+                       status = Write16(state, SC_RA_RAM_CONFIG__A, sc_config, 0);
+                       if (status < 0)
+                               break;
+               }
+
+               status = SetCfgNoiseCalibration(state, &state->noise_cal);
+               if (status < 0)
+                       break;
+
+               if (state->cscd_state == CSCD_INIT) {
+                       /* switch on SRMM scan in SC */
+                       status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DO_SCAN, 0x0000);
+                       if (status < 0)
+                               break;
+/*            CHK_ERROR(Write16(SC_RA_RAM_SAMPLE_RATE_STEP__A, DRXD_OSCDEV_STEP, 0x0000));*/
+                       state->cscd_state = CSCD_SET;
+               }
+
+               /* Now compute FE_IF_REG_INCR */
+               /*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
+                  ((SysFreq / BandWidth) * (2^21) ) - (2^23) */
+               feIfIncr = MulDiv32(state->sys_clock_freq * 1000,
+                                   (1ULL << 21), bandwidth) - (1 << 23);
+               status = Write16(state, FE_IF_REG_INCR0__A, (u16) (feIfIncr & FE_IF_REG_INCR0__M), 0x0000);
+               if (status < 0)
+                       break;
+               status = Write16(state, FE_IF_REG_INCR1__A, (u16) ((feIfIncr >> FE_IF_REG_INCR0__W) & FE_IF_REG_INCR1__M), 0x0000);
+               if (status < 0)
+                       break;
+               /* Bandwidth setting done */
+
+               /* Mirror & frequency offset */
+               SetFrequencyShift(state, off, mirrorFreqSpect);
+
+               /* Start SC, write channel settings to SC */
+
+               /* Enable SC after setting all other parameters */
+               status = Write16(state, SC_COMM_STATE__A, 0, 0x0000);
+               if (status < 0)
+                       break;
+               status = Write16(state, SC_COMM_EXEC__A, 1, 0x0000);
+               if (status < 0)
+                       break;
+
+               /* Write SC parameter registers, operation mode */
+#if 1
+               operationMode = (SC_RA_RAM_OP_AUTO_MODE__M |
+                                SC_RA_RAM_OP_AUTO_GUARD__M |
+                                SC_RA_RAM_OP_AUTO_CONST__M |
+                                SC_RA_RAM_OP_AUTO_HIER__M |
+                                SC_RA_RAM_OP_AUTO_RATE__M);
+#endif
+               status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
+               if (status < 0)
+                       break;
+
+               /* Start correct processes to get in lock */
+               status = SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK, SC_RA_RAM_SW_EVENT_RUN_NMASK__M, SC_RA_RAM_LOCKTRACK_MIN);
+               if (status < 0)
+                       break;
+
+               status = StartOC(state);
+               if (status < 0)
+                       break;
+
+               if (state->operation_mode != OM_Default) {
+                       status = StartDiversity(state);
+                       if (status < 0)
+                               break;
+               }
+
+               state->drxd_state = DRXD_STARTED;
+       } while (0);
+
+       return status;
+}
+
+static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
+{
+       u32 ulRfAgcOutputLevel = 0xffffffff;
+       u32 ulRfAgcSettleLevel = 528;   /* Optimum value for MT2060 */
+       u32 ulRfAgcMinLevel = 0;        /* Currently unused */
+       u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX; /* Currently unused */
+       u32 ulRfAgcSpeed = 0;   /* Currently unused */
+       u32 ulRfAgcMode = 0;    /*2;   Off */
+       u32 ulRfAgcR1 = 820;
+       u32 ulRfAgcR2 = 2200;
+       u32 ulRfAgcR3 = 150;
+       u32 ulIfAgcMode = 0;    /* Auto */
+       u32 ulIfAgcOutputLevel = 0xffffffff;
+       u32 ulIfAgcSettleLevel = 0xffffffff;
+       u32 ulIfAgcMinLevel = 0xffffffff;
+       u32 ulIfAgcMaxLevel = 0xffffffff;
+       u32 ulIfAgcSpeed = 0xffffffff;
+       u32 ulIfAgcR1 = 820;
+       u32 ulIfAgcR2 = 2200;
+       u32 ulIfAgcR3 = 150;
+       u32 ulClock = state->config.clock;
+       u32 ulSerialMode = 0;
+       u32 ulEcOcRegOcModeLop = 4;     /* Dynamic DTO source */
+       u32 ulHiI2cDelay = HI_I2C_DELAY;
+       u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
+       u32 ulHiI2cPatch = 0;
+       u32 ulEnvironment = APPENV_PORTABLE;
+       u32 ulEnvironmentDiversity = APPENV_MOBILE;
+       u32 ulIFFilter = IFFILTER_SAW;
+
+       state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+       state->if_agc_cfg.outputLevel = 0;
+       state->if_agc_cfg.settleLevel = 140;
+       state->if_agc_cfg.minOutputLevel = 0;
+       state->if_agc_cfg.maxOutputLevel = 1023;
+       state->if_agc_cfg.speed = 904;
+
+       if (ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
+               state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
+               state->if_agc_cfg.outputLevel = (u16) (ulIfAgcOutputLevel);
+       }
+
+       if (ulIfAgcMode == 0 &&
+           ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
+           ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
+           ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
+           ulIfAgcSpeed <= DRXD_FE_CTRL_MAX) {
+               state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+               state->if_agc_cfg.settleLevel = (u16) (ulIfAgcSettleLevel);
+               state->if_agc_cfg.minOutputLevel = (u16) (ulIfAgcMinLevel);
+               state->if_agc_cfg.maxOutputLevel = (u16) (ulIfAgcMaxLevel);
+               state->if_agc_cfg.speed = (u16) (ulIfAgcSpeed);
+       }
+
+       state->if_agc_cfg.R1 = (u16) (ulIfAgcR1);
+       state->if_agc_cfg.R2 = (u16) (ulIfAgcR2);
+       state->if_agc_cfg.R3 = (u16) (ulIfAgcR3);
+
+       state->rf_agc_cfg.R1 = (u16) (ulRfAgcR1);
+       state->rf_agc_cfg.R2 = (u16) (ulRfAgcR2);
+       state->rf_agc_cfg.R3 = (u16) (ulRfAgcR3);
+
+       state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+       /* rest of the RFAgcCfg structure currently unused */
+       if (ulRfAgcMode == 1 && ulRfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
+               state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
+               state->rf_agc_cfg.outputLevel = (u16) (ulRfAgcOutputLevel);
+       }
+
+       if (ulRfAgcMode == 0 &&
+           ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
+           ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
+           ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
+           ulRfAgcSpeed <= DRXD_FE_CTRL_MAX) {
+               state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+               state->rf_agc_cfg.settleLevel = (u16) (ulRfAgcSettleLevel);
+               state->rf_agc_cfg.minOutputLevel = (u16) (ulRfAgcMinLevel);
+               state->rf_agc_cfg.maxOutputLevel = (u16) (ulRfAgcMaxLevel);
+               state->rf_agc_cfg.speed = (u16) (ulRfAgcSpeed);
+       }
+
+       if (ulRfAgcMode == 2)
+               state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
+
+       if (ulEnvironment <= 2)
+               state->app_env_default = (enum app_env)
+                   (ulEnvironment);
+       if (ulEnvironmentDiversity <= 2)
+               state->app_env_diversity = (enum app_env)
+                   (ulEnvironmentDiversity);
+
+       if (ulIFFilter == IFFILTER_DISCRETE) {
+               /* discrete filter */
+               state->noise_cal.cpOpt = 0;
+               state->noise_cal.cpNexpOfs = 40;
+               state->noise_cal.tdCal2k = -40;
+               state->noise_cal.tdCal8k = -24;
+       } else {
+               /* SAW filter */
+               state->noise_cal.cpOpt = 1;
+               state->noise_cal.cpNexpOfs = 0;
+               state->noise_cal.tdCal2k = -21;
+               state->noise_cal.tdCal8k = -24;
+       }
+       state->m_EcOcRegOcModeLop = (u16) (ulEcOcRegOcModeLop);
+
+       state->chip_adr = (state->config.demod_address << 1) | 1;
+       switch (ulHiI2cPatch) {
+       case 1:
+               state->m_HiI2cPatch = DRXD_HiI2cPatch_1;
+               break;
+       case 3:
+               state->m_HiI2cPatch = DRXD_HiI2cPatch_3;
+               break;
+       default:
+               state->m_HiI2cPatch = NULL;
+       }
+
+       /* modify tuner and clock attributes */
+       state->intermediate_freq = (u16) (IntermediateFrequency / 1000);
+       /* expected system clock frequency in kHz */
+       state->expected_sys_clock_freq = 48000;
+       /* real system clock frequency in kHz */
+       state->sys_clock_freq = 48000;
+       state->osc_clock_freq = (u16) ulClock;
+       state->osc_clock_deviation = 0;
+       state->cscd_state = CSCD_INIT;
+       state->drxd_state = DRXD_UNINITIALIZED;
+
+       state->PGA = 0;
+       state->type_A = 0;
+       state->tuner_mirrors = 0;
+
+       /* modify MPEG output attributes */
+       state->insert_rs_byte = state->config.insert_rs_byte;
+       state->enable_parallel = (ulSerialMode != 1);
+
+       /* Timing div, 250ns/Psys */
+       /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
+
+       state->hi_cfg_timing_div = (u16) ((state->sys_clock_freq / 1000) *
+                                         ulHiI2cDelay) / 1000;
+       /* Bridge delay, uses oscilator clock */
+       /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
+       state->hi_cfg_bridge_delay = (u16) ((state->osc_clock_freq / 1000) *
+                                           ulHiI2cBridgeDelay) / 1000;
+
+       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
+       /* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
+       state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
+       return 0;
+}
+
+int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
+{
+       int status = 0;
+       u32 driverVersion;
+
+       if (state->init_done)
+               return 0;
+
+       CDRXD(state, state->config.IF ? state->config.IF : 36000000);
+
+       do {
+               state->operation_mode = OM_Default;
+
+               status = SetDeviceTypeId(state);
+               if (status < 0)
+                       break;
+
+               /* Apply I2c address patch to B1 */
+               if (!state->type_A && state->m_HiI2cPatch != NULL)
+                       status = WriteTable(state, state->m_HiI2cPatch);
+                       if (status < 0)
+                               break;
+
+               if (state->type_A) {
+                       /* HI firmware patch for UIO readout,
+                          avoid clearing of result register */
+                       status = Write16(state, 0x43012D, 0x047f, 0);
+                       if (status < 0)
+                               break;
+               }
+
+               status = HI_ResetCommand(state);
+               if (status < 0)
+                       break;
+
+               status = StopAllProcessors(state);
+               if (status < 0)
+                       break;
+               status = InitCC(state);
+               if (status < 0)
+                       break;
+
+               state->osc_clock_deviation = 0;
+
+               if (state->config.osc_deviation)
+                       state->osc_clock_deviation =
+                           state->config.osc_deviation(state->priv, 0, 0);
+               {
+                       /* Handle clock deviation */
+                       s32 devB;
+                       s32 devA = (s32) (state->osc_clock_deviation) *
+                           (s32) (state->expected_sys_clock_freq);
+                       /* deviation in kHz */
+                       s32 deviation = (devA / (1000000L));
+                       /* rounding, signed */
+                       if (devA > 0)
+                               devB = (2);
+                       else
+                               devB = (-2);
+                       if ((devB * (devA % 1000000L) > 1000000L)) {
+                               /* add +1 or -1 */
+                               deviation += (devB / 2);
+                       }
+
+                       state->sys_clock_freq =
+                           (u16) ((state->expected_sys_clock_freq) +
+                                  deviation);
+               }
+               status = InitHI(state);
+               if (status < 0)
+                       break;
+               status = InitAtomicRead(state);
+               if (status < 0)
+                       break;
+
+               status = EnableAndResetMB(state);
+               if (status < 0)
+                       break;
+               if (state->type_A)
+                       status = ResetCEFR(state);
+                       if (status < 0)
+                               break;
+
+               if (fw) {
+                       status = DownloadMicrocode(state, fw, fw_size);
+                       if (status < 0)
+                               break;
+               } else {
+                       status = DownloadMicrocode(state, state->microcode, state->microcode_length);
+                       if (status < 0)
+                               break;
+               }
+
+               if (state->PGA) {
+                       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
+                       SetCfgPga(state, 0);    /* PGA = 0 dB */
+               } else {
+                       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
+               }
+
+               state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
+
+               status = InitFE(state);
+               if (status < 0)
+                       break;
+               status = InitFT(state);
+               if (status < 0)
+                       break;
+               status = InitCP(state);
+               if (status < 0)
+                       break;
+               status = InitCE(state);
+               if (status < 0)
+                       break;
+               status = InitEQ(state);
+               if (status < 0)
+                       break;
+               status = InitEC(state);
+               if (status < 0)
+                       break;
+               status = InitSC(state);
+               if (status < 0)
+                       break;
+
+               status = SetCfgIfAgc(state, &state->if_agc_cfg);
+               if (status < 0)
+                       break;
+               status = SetCfgRfAgc(state, &state->rf_agc_cfg);
+               if (status < 0)
+                       break;
+
+               state->cscd_state = CSCD_INIT;
+               status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+               if (status < 0)
+                       break;
+               status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+               if (status < 0)
+                       break;
+
+               driverVersion = (((VERSION_MAJOR / 10) << 4) +
+                                (VERSION_MAJOR % 10)) << 24;
+               driverVersion += (((VERSION_MINOR / 10) << 4) +
+                                 (VERSION_MINOR % 10)) << 16;
+               driverVersion += ((VERSION_PATCH / 1000) << 12) +
+                   ((VERSION_PATCH / 100) << 8) +
+                   ((VERSION_PATCH / 10) << 4) + (VERSION_PATCH % 10);
+
+               status = Write32(state, SC_RA_RAM_DRIVER_VERSION__AX, driverVersion, 0);
+               if (status < 0)
+                       break;
+
+               status = StopOC(state);
+               if (status < 0)
+                       break;
+
+               state->drxd_state = DRXD_STOPPED;
+               state->init_done = 1;
+               status = 0;
+       } while (0);
+       return status;
+}
+
+int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
+{
+       DRX_GetLockStatus(state, pLockStatus);
+
+       /*if (*pLockStatus&DRX_LOCK_MPEG) */
+       if (*pLockStatus & DRX_LOCK_FEC) {
+               ConfigureMPEGOutput(state, 1);
+               /* Get status again, in case we have MPEG lock now */
+               /*DRX_GetLockStatus(state, pLockStatus); */
+       }
+
+       return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+       u32 value;
+       int res;
+
+       res = ReadIFAgc(state, &value);
+       if (res < 0)
+               *strength = 0;
+       else
+               *strength = 0xffff - (value << 4);
+       return 0;
+}
+
+static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+       u32 lock;
+
+       DRXD_status(state, &lock);
+       *status = 0;
+       /* No MPEG lock in V255 firmware, bug ? */
+#if 1
+       if (lock & DRX_LOCK_MPEG)
+               *status |= FE_HAS_LOCK;
+#else
+       if (lock & DRX_LOCK_FEC)
+               *status |= FE_HAS_LOCK;
+#endif
+       if (lock & DRX_LOCK_FEC)
+               *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
+       if (lock & DRX_LOCK_DEMOD)
+               *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+       return 0;
+}
+
+static int drxd_init(struct dvb_frontend *fe)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+       int err = 0;
+
+/*     if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
+       return DRXD_init(state, 0, 0);
+
+       err = DRXD_init(state, state->fw->data, state->fw->size);
+       release_firmware(state->fw);
+       return err;
+}
+
+int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+
+       if (state->config.disable_i2c_gate_ctrl == 1)
+               return 0;
+
+       return DRX_ConfigureI2CBridge(state, onoff);
+}
+EXPORT_SYMBOL(drxd_config_i2c);
+
+static int drxd_get_tune_settings(struct dvb_frontend *fe,
+                                 struct dvb_frontend_tune_settings *sets)
+{
+       sets->min_delay_ms = 10000;
+       sets->max_drift = 0;
+       sets->step_size = 0;
+       return 0;
+}
+
+static int drxd_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       *ber = 0;
+       return 0;
+}
+
+static int drxd_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       *snr = 0;
+       return 0;
+}
+
+static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+static int drxd_sleep(struct dvb_frontend *fe)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+
+       ConfigureMPEGOutput(state, 0);
+       return 0;
+}
+
+static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       return drxd_config_i2c(fe, enable);
+}
+
+static int drxd_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct drxd_state *state = fe->demodulator_priv;
+       s32 off = 0;
+
+       state->props = *p;
+       DRX_Stop(state);
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       msleep(200);
+
+       return DRX_Start(state, off);
+}
+
+static void drxd_release(struct dvb_frontend *fe)
+{
+       struct drxd_state *state = fe->demodulator_priv;
+
+       kfree(state);
+}
+
+static struct dvb_frontend_ops drxd_ops = {
+       .delsys = { SYS_DVBT},
+       .info = {
+                .name = "Micronas DRXD DVB-T",
+                .frequency_min = 47125000,
+                .frequency_max = 855250000,
+                .frequency_stepsize = 166667,
+                .frequency_tolerance = 0,
+                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                FE_CAN_FEC_AUTO |
+                FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                FE_CAN_QAM_AUTO |
+                FE_CAN_TRANSMISSION_MODE_AUTO |
+                FE_CAN_GUARD_INTERVAL_AUTO |
+                FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
+
+       .release = drxd_release,
+       .init = drxd_init,
+       .sleep = drxd_sleep,
+       .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
+
+       .set_frontend = drxd_set_frontend,
+       .get_tune_settings = drxd_get_tune_settings,
+
+       .read_status = drxd_read_status,
+       .read_ber = drxd_read_ber,
+       .read_signal_strength = drxd_read_signal_strength,
+       .read_snr = drxd_read_snr,
+       .read_ucblocks = drxd_read_ucblocks,
+};
+
+struct dvb_frontend *drxd_attach(const struct drxd_config *config,
+                                void *priv, struct i2c_adapter *i2c,
+                                struct device *dev)
+{
+       struct drxd_state *state = NULL;
+
+       state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+       memset(state, 0, sizeof(*state));
+
+       memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
+       state->dev = dev;
+       state->config = *config;
+       state->i2c = i2c;
+       state->priv = priv;
+
+       mutex_init(&state->mutex);
+
+       if (Read16(state, 0, 0, 0) < 0)
+               goto error;
+
+       memcpy(&state->frontend.ops, &drxd_ops,
+              sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       ConfigureMPEGOutput(state, 0);
+       return &state->frontend;
+
+error:
+       printk(KERN_ERR "drxd: not found\n");
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(drxd_attach);
+
+MODULE_DESCRIPTION("DRXD driver");
+MODULE_AUTHOR("Micronas");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/drxd_map_firm.h b/drivers/media/dvb-frontends/drxd_map_firm.h
new file mode 100644 (file)
index 0000000..6bc553a
--- /dev/null
@@ -0,0 +1,1013 @@
+/*
+ * drx3973d_map_firm.h
+ *
+ * Copyright (C) 2006-2007 Micronas
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DRX3973D_MAP__H__
+#define __DRX3973D_MAP__H__
+
+/*
+ * Note: originally, this file contained 12000+ lines of data
+ * Probably a few lines for every firwmare assembler instruction. However,
+ * only a few defines were actually used. So, removed all uneeded lines.
+ * If ever needed, the other lines can be easily obtained via git history.
+ */
+
+#define HI_COMM_EXEC__A                                              0x400000
+#define HI_COMM_MB__A                                                0x400002
+#define HI_CT_REG_COMM_STATE__A                                      0x410001
+#define HI_RA_RAM_SRV_RES__A                                         0x420031
+#define HI_RA_RAM_SRV_CMD__A                                         0x420032
+#define   HI_RA_RAM_SRV_CMD_RESET                                    0x2
+#define   HI_RA_RAM_SRV_CMD_CONFIG                                   0x3
+#define   HI_RA_RAM_SRV_CMD_EXECUTE                                  0x6
+#define HI_RA_RAM_SRV_RST_KEY__A                                     0x420033
+#define   HI_RA_RAM_SRV_RST_KEY_ACT                                  0x3973
+#define HI_RA_RAM_SRV_CFG_KEY__A                                     0x420033
+#define HI_RA_RAM_SRV_CFG_DIV__A                                     0x420034
+#define HI_RA_RAM_SRV_CFG_BDL__A                                     0x420035
+#define HI_RA_RAM_SRV_CFG_WUP__A                                     0x420036
+#define HI_RA_RAM_SRV_CFG_ACT__A                                     0x420037
+#define     HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                            0x1
+#define   HI_RA_RAM_SRV_CFG_ACT_BRD__M                               0x4
+#define     HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                            0x0
+#define     HI_RA_RAM_SRV_CFG_ACT_BRD_ON                             0x4
+#define     HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                            0x8
+#define HI_RA_RAM_USR_BEGIN__A                                       0x420040
+#define HI_IF_RAM_TRP_BPT0__AX                                       0x430000
+#define HI_IF_RAM_USR_BEGIN__A                                       0x430200
+#define SC_COMM_EXEC__A                                              0x800000
+#define     SC_COMM_EXEC_CTL_STOP                                    0x0
+#define SC_COMM_STATE__A                                             0x800001
+#define SC_RA_RAM_PARAM0__A                                          0x820040
+#define SC_RA_RAM_PARAM1__A                                          0x820041
+#define SC_RA_RAM_CMD_ADDR__A                                        0x820042
+#define SC_RA_RAM_CMD__A                                             0x820043
+#define   SC_RA_RAM_CMD_PROC_START                                   0x1
+#define   SC_RA_RAM_CMD_SET_PREF_PARAM                               0x3
+#define   SC_RA_RAM_CMD_GET_OP_PARAM                                 0x5
+#define   SC_RA_RAM_SW_EVENT_RUN_NMASK__M                            0x1
+#define   SC_RA_RAM_LOCKTRACK_MIN                                    0x1
+#define     SC_RA_RAM_OP_PARAM_MODE_2K                               0x0
+#define     SC_RA_RAM_OP_PARAM_MODE_8K                               0x1
+#define     SC_RA_RAM_OP_PARAM_GUARD_32                              0x0
+#define     SC_RA_RAM_OP_PARAM_GUARD_16                              0x4
+#define     SC_RA_RAM_OP_PARAM_GUARD_8                               0x8
+#define     SC_RA_RAM_OP_PARAM_GUARD_4                               0xC
+#define     SC_RA_RAM_OP_PARAM_CONST_QPSK                            0x0
+#define     SC_RA_RAM_OP_PARAM_CONST_QAM16                           0x10
+#define     SC_RA_RAM_OP_PARAM_CONST_QAM64                           0x20
+#define     SC_RA_RAM_OP_PARAM_HIER_NO                               0x0
+#define     SC_RA_RAM_OP_PARAM_HIER_A1                               0x40
+#define     SC_RA_RAM_OP_PARAM_HIER_A2                               0x80
+#define     SC_RA_RAM_OP_PARAM_HIER_A4                               0xC0
+#define     SC_RA_RAM_OP_PARAM_RATE_1_2                              0x0
+#define     SC_RA_RAM_OP_PARAM_RATE_2_3                              0x200
+#define     SC_RA_RAM_OP_PARAM_RATE_3_4                              0x400
+#define     SC_RA_RAM_OP_PARAM_RATE_5_6                              0x600
+#define     SC_RA_RAM_OP_PARAM_RATE_7_8                              0x800
+#define     SC_RA_RAM_OP_PARAM_PRIO_HI                               0x0
+#define     SC_RA_RAM_OP_PARAM_PRIO_LO                               0x1000
+#define   SC_RA_RAM_OP_AUTO_MODE__M                                  0x1
+#define   SC_RA_RAM_OP_AUTO_GUARD__M                                 0x2
+#define   SC_RA_RAM_OP_AUTO_CONST__M                                 0x4
+#define   SC_RA_RAM_OP_AUTO_HIER__M                                  0x8
+#define   SC_RA_RAM_OP_AUTO_RATE__M                                  0x10
+#define SC_RA_RAM_LOCK__A                                            0x82004B
+#define   SC_RA_RAM_LOCK_DEMOD__M                                    0x1
+#define   SC_RA_RAM_LOCK_FEC__M                                      0x2
+#define   SC_RA_RAM_LOCK_MPEG__M                                     0x4
+#define SC_RA_RAM_BE_OPT_ENA__A                                      0x82004C
+#define   SC_RA_RAM_BE_OPT_ENA_CP_OPT                                0x1
+#define SC_RA_RAM_BE_OPT_DELAY__A                                    0x82004D
+#define SC_RA_RAM_CONFIG__A                                          0x820050
+#define   SC_RA_RAM_CONFIG_FR_ENABLE__M                              0x4
+#define   SC_RA_RAM_CONFIG_FREQSCAN__M                               0x10
+#define   SC_RA_RAM_CONFIG_SLAVE__M                                  0x20
+#define SC_RA_RAM_IF_SAVE__AX                                        0x82008E
+#define SC_RA_RAM_IR_COARSE_2K_LENGTH__A                             0x8200D1
+#define SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                           0x9
+#define SC_RA_RAM_IR_COARSE_2K_FREQINC__A                            0x8200D2
+#define SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                          0x4
+#define SC_RA_RAM_IR_COARSE_2K_KAISINC__A                            0x8200D3
+#define SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                          0x100
+#define SC_RA_RAM_IR_COARSE_8K_LENGTH__A                             0x8200D4
+#define SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                           0x8
+#define SC_RA_RAM_IR_COARSE_8K_FREQINC__A                            0x8200D5
+#define SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                          0x8
+#define SC_RA_RAM_IR_COARSE_8K_KAISINC__A                            0x8200D6
+#define SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                          0x200
+#define SC_RA_RAM_IR_FINE_2K_LENGTH__A                               0x8200D7
+#define SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                             0x9
+#define SC_RA_RAM_IR_FINE_2K_FREQINC__A                              0x8200D8
+#define SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                            0x4
+#define SC_RA_RAM_IR_FINE_2K_KAISINC__A                              0x8200D9
+#define SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                            0x100
+#define SC_RA_RAM_IR_FINE_8K_LENGTH__A                               0x8200DA
+#define SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                             0xB
+#define SC_RA_RAM_IR_FINE_8K_FREQINC__A                              0x8200DB
+#define SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                            0x1
+#define SC_RA_RAM_IR_FINE_8K_KAISINC__A                              0x8200DC
+#define SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                            0x40
+#define SC_RA_RAM_ECHO_SHIFT_LIM__A                                  0x8200DD
+#define SC_RA_RAM_SAMPLE_RATE_COUNT__A                               0x8200E8
+#define SC_RA_RAM_SAMPLE_RATE_STEP__A                                0x8200E9
+#define SC_RA_RAM_BAND__A                                            0x8200EC
+#define SC_RA_RAM_LC_ABS_2K__A                                       0x8200F4
+#define SC_RA_RAM_LC_ABS_2K__PRE                                     0x1F
+#define SC_RA_RAM_LC_ABS_8K__A                                       0x8200F5
+#define SC_RA_RAM_LC_ABS_8K__PRE                                     0x1F
+#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                        0x1D6
+#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                        0x4
+#define SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                           0x1BB
+#define SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                           0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                          0x1EF
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                          0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                       0x15E
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                       0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                       0x11A
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                       0x6
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                          0x1FB
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                          0x5
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                       0x12F
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                       0x5
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                       0x197
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                       0x5
+#define SC_RA_RAM_DRIVER_VERSION__AX                                 0x8201FE
+#define   SC_RA_RAM_PROC_LOCKTRACK                                   0x0
+#define FE_COMM_EXEC__A                                              0xC00000
+#define FE_AD_REG_COMM_EXEC__A                                       0xC10000
+#define FE_AD_REG_FDB_IN__A                                          0xC10012
+#define FE_AD_REG_PD__A                                              0xC10013
+#define FE_AD_REG_INVEXT__A                                          0xC10014
+#define FE_AD_REG_CLKNEG__A                                          0xC10015
+#define FE_AG_REG_COMM_EXEC__A                                       0xC20000
+#define FE_AG_REG_AG_MODE_LOP__A                                     0xC20010
+#define   FE_AG_REG_AG_MODE_LOP_MODE_4__M                            0x10
+#define     FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                     0x10
+#define   FE_AG_REG_AG_MODE_LOP_MODE_5__M                            0x20
+#define     FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                      0x0
+#define   FE_AG_REG_AG_MODE_LOP_MODE_C__M                            0x1000
+#define     FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                     0x1000
+#define   FE_AG_REG_AG_MODE_LOP_MODE_E__M                            0x4000
+#define     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                     0x4000
+#define FE_AG_REG_AG_MODE_HIP__A                                     0xC20011
+#define FE_AG_REG_AG_PGA_MODE__A                                     0xC20012
+#define   FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                      0x0
+#define   FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                      0x1
+#define FE_AG_REG_AG_AGC_SIO__A                                      0xC20013
+#define   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                          0x2
+#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                    0x0
+#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                     0x2
+#define FE_AG_REG_AG_PWD__A                                          0xC20015
+#define   FE_AG_REG_AG_PWD_PWD_PD2__M                                0x2
+#define     FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                         0x0
+#define     FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                          0x2
+#define FE_AG_REG_DCE_AUR_CNT__A                                     0xC20016
+#define FE_AG_REG_DCE_RUR_CNT__A                                     0xC20017
+#define FE_AG_REG_ACE_AUR_CNT__A                                     0xC2001A
+#define FE_AG_REG_ACE_RUR_CNT__A                                     0xC2001B
+#define FE_AG_REG_CDR_RUR_CNT__A                                     0xC20020
+#define FE_AG_REG_EGC_RUR_CNT__A                                     0xC20024
+#define FE_AG_REG_EGC_SET_LVL__A                                     0xC20025
+#define FE_AG_REG_EGC_SET_LVL__M                                     0x1FF
+#define FE_AG_REG_EGC_FLA_RGN__A                                     0xC20026
+#define FE_AG_REG_EGC_SLO_RGN__A                                     0xC20027
+#define FE_AG_REG_EGC_JMP_PSN__A                                     0xC20028
+#define FE_AG_REG_EGC_FLA_INC__A                                     0xC20029
+#define FE_AG_REG_EGC_FLA_DEC__A                                     0xC2002A
+#define FE_AG_REG_EGC_SLO_INC__A                                     0xC2002B
+#define FE_AG_REG_EGC_SLO_DEC__A                                     0xC2002C
+#define FE_AG_REG_EGC_FAS_INC__A                                     0xC2002D
+#define FE_AG_REG_EGC_FAS_DEC__A                                     0xC2002E
+#define FE_AG_REG_PM1_AGC_WRI__A                                     0xC20030
+#define FE_AG_REG_PM1_AGC_WRI__M                                     0x7FF
+#define FE_AG_REG_GC1_AGC_RIC__A                                     0xC20031
+#define FE_AG_REG_GC1_AGC_OFF__A                                     0xC20032
+#define FE_AG_REG_GC1_AGC_MAX__A                                     0xC20033
+#define FE_AG_REG_GC1_AGC_MIN__A                                     0xC20034
+#define FE_AG_REG_GC1_AGC_DAT__A                                     0xC20035
+#define FE_AG_REG_GC1_AGC_DAT__M                                     0x3FF
+#define FE_AG_REG_PM2_AGC_WRI__A                                     0xC20036
+#define FE_AG_REG_IND_WIN__A                                         0xC2003C
+#define FE_AG_REG_IND_THD_LOL__A                                     0xC2003D
+#define FE_AG_REG_IND_THD_HIL__A                                     0xC2003E
+#define FE_AG_REG_IND_DEL__A                                         0xC2003F
+#define FE_AG_REG_IND_PD1_WRI__A                                     0xC20040
+#define FE_AG_REG_PDA_AUR_CNT__A                                     0xC20041
+#define FE_AG_REG_PDA_RUR_CNT__A                                     0xC20042
+#define FE_AG_REG_PDA_AVE_DAT__A                                     0xC20043
+#define FE_AG_REG_PDC_RUR_CNT__A                                     0xC20044
+#define FE_AG_REG_PDC_SET_LVL__A                                     0xC20045
+#define FE_AG_REG_PDC_FLA_RGN__A                                     0xC20046
+#define FE_AG_REG_PDC_JMP_PSN__A                                     0xC20047
+#define FE_AG_REG_PDC_FLA_STP__A                                     0xC20048
+#define FE_AG_REG_PDC_SLO_STP__A                                     0xC20049
+#define FE_AG_REG_PDC_PD2_WRI__A                                     0xC2004A
+#define FE_AG_REG_PDC_MAP_DAT__A                                     0xC2004B
+#define FE_AG_REG_PDC_MAX__A                                         0xC2004C
+#define FE_AG_REG_TGA_AUR_CNT__A                                     0xC2004D
+#define FE_AG_REG_TGA_RUR_CNT__A                                     0xC2004E
+#define FE_AG_REG_TGA_AVE_DAT__A                                     0xC2004F
+#define FE_AG_REG_TGC_RUR_CNT__A                                     0xC20050
+#define FE_AG_REG_TGC_SET_LVL__A                                     0xC20051
+#define FE_AG_REG_TGC_SET_LVL__M                                     0x3F
+#define FE_AG_REG_TGC_FLA_RGN__A                                     0xC20052
+#define FE_AG_REG_TGC_JMP_PSN__A                                     0xC20053
+#define FE_AG_REG_TGC_FLA_STP__A                                     0xC20054
+#define FE_AG_REG_TGC_SLO_STP__A                                     0xC20055
+#define FE_AG_REG_TGC_MAP_DAT__A                                     0xC20056
+#define FE_AG_REG_FGA_AUR_CNT__A                                     0xC20057
+#define FE_AG_REG_FGA_RUR_CNT__A                                     0xC20058
+#define FE_AG_REG_FGM_WRI__A                                         0xC20061
+#define FE_AG_REG_BGC_FGC_WRI__A                                     0xC20068
+#define FE_AG_REG_BGC_CGC_WRI__A                                     0xC20069
+#define FE_FS_REG_COMM_EXEC__A                                       0xC30000
+#define FE_FS_REG_ADD_INC_LOP__A                                     0xC30010
+#define FE_FD_REG_COMM_EXEC__A                                       0xC40000
+#define FE_FD_REG_SCL__A                                             0xC40010
+#define FE_FD_REG_MAX_LEV__A                                         0xC40011
+#define FE_FD_REG_NR__A                                              0xC40012
+#define FE_FD_REG_MEAS_VAL__A                                        0xC40014
+#define FE_IF_REG_COMM_EXEC__A                                       0xC50000
+#define FE_IF_REG_INCR0__A                                           0xC50010
+#define FE_IF_REG_INCR0__W                                           16
+#define FE_IF_REG_INCR0__M                                           0xFFFF
+#define FE_IF_REG_INCR1__A                                           0xC50011
+#define FE_IF_REG_INCR1__M                                           0xFF
+#define FE_CF_REG_COMM_EXEC__A                                       0xC60000
+#define FE_CF_REG_SCL__A                                             0xC60010
+#define FE_CF_REG_MAX_LEV__A                                         0xC60011
+#define FE_CF_REG_NR__A                                              0xC60012
+#define FE_CF_REG_IMP_VAL__A                                         0xC60013
+#define FE_CF_REG_MEAS_VAL__A                                        0xC60014
+#define FE_CU_REG_COMM_EXEC__A                                       0xC70000
+#define FE_CU_REG_FRM_CNT_RST__A                                     0xC70011
+#define FE_CU_REG_FRM_CNT_STR__A                                     0xC70012
+#define FT_COMM_EXEC__A                                              0x1000000
+#define FT_REG_COMM_EXEC__A                                          0x1010000
+#define CP_COMM_EXEC__A                                              0x1400000
+#define CP_REG_COMM_EXEC__A                                          0x1410000
+#define CP_REG_INTERVAL__A                                           0x1410011
+#define CP_REG_BR_SPL_OFFSET__A                                      0x1410023
+#define CP_REG_BR_STR_DEL__A                                         0x1410024
+#define CP_REG_RT_ANG_INC0__A                                        0x1410030
+#define CP_REG_RT_ANG_INC1__A                                        0x1410031
+#define CP_REG_RT_DETECT_ENA__A                                      0x1410032
+#define CP_REG_RT_DETECT_TRH__A                                      0x1410033
+#define CP_REG_RT_EXP_MARG__A                                        0x141003E
+#define CP_REG_AC_NEXP_OFFS__A                                       0x1410040
+#define CP_REG_AC_AVER_POW__A                                        0x1410041
+#define CP_REG_AC_MAX_POW__A                                         0x1410042
+#define CP_REG_AC_WEIGHT_MAN__A                                      0x1410043
+#define CP_REG_AC_WEIGHT_EXP__A                                      0x1410044
+#define CP_REG_AC_AMP_MODE__A                                        0x1410047
+#define CP_REG_AC_AMP_FIX__A                                         0x1410048
+#define CP_REG_AC_ANG_MODE__A                                        0x141004A
+#define CE_COMM_EXEC__A                                              0x1800000
+#define CE_REG_COMM_EXEC__A                                          0x1810000
+#define CE_REG_TAPSET__A                                             0x1810011
+#define CE_REG_AVG_POW__A                                            0x1810012
+#define CE_REG_MAX_POW__A                                            0x1810013
+#define CE_REG_ATT__A                                                0x1810014
+#define CE_REG_NRED__A                                               0x1810015
+#define CE_REG_NE_ERR_SELECT__A                                      0x1810043
+#define CE_REG_NE_TD_CAL__A                                          0x1810044
+#define CE_REG_NE_MIXAVG__A                                          0x1810046
+#define CE_REG_NE_NUPD_OFS__A                                        0x1810047
+#define CE_REG_PE_NEXP_OFFS__A                                       0x1810050
+#define CE_REG_PE_TIMESHIFT__A                                       0x1810051
+#define CE_REG_TP_A0_TAP_NEW__A                                      0x1810064
+#define CE_REG_TP_A0_TAP_NEW_VALID__A                                0x1810065
+#define CE_REG_TP_A0_MU_LMS_STEP__A                                  0x1810066
+#define CE_REG_TP_A1_TAP_NEW__A                                      0x1810068
+#define CE_REG_TP_A1_TAP_NEW_VALID__A                                0x1810069
+#define CE_REG_TP_A1_MU_LMS_STEP__A                                  0x181006A
+#define CE_REG_TI_NEXP_OFFS__A                                       0x1810070
+#define CE_REG_FI_SHT_INCR__A                                        0x1810090
+#define CE_REG_FI_EXP_NORM__A                                        0x1810091
+#define CE_REG_IR_INPUTSEL__A                                        0x18100A0
+#define CE_REG_IR_STARTPOS__A                                        0x18100A1
+#define CE_REG_IR_NEXP_THRES__A                                      0x18100A2
+#define CE_REG_FR_TREAL00__A                                         0x1820010
+#define CE_REG_FR_TIMAG00__A                                         0x1820011
+#define CE_REG_FR_TREAL01__A                                         0x1820012
+#define CE_REG_FR_TIMAG01__A                                         0x1820013
+#define CE_REG_FR_TREAL02__A                                         0x1820014
+#define CE_REG_FR_TIMAG02__A                                         0x1820015
+#define CE_REG_FR_TREAL03__A                                         0x1820016
+#define CE_REG_FR_TIMAG03__A                                         0x1820017
+#define CE_REG_FR_TREAL04__A                                         0x1820018
+#define CE_REG_FR_TIMAG04__A                                         0x1820019
+#define CE_REG_FR_TREAL05__A                                         0x182001A
+#define CE_REG_FR_TIMAG05__A                                         0x182001B
+#define CE_REG_FR_TREAL06__A                                         0x182001C
+#define CE_REG_FR_TIMAG06__A                                         0x182001D
+#define CE_REG_FR_TREAL07__A                                         0x182001E
+#define CE_REG_FR_TIMAG07__A                                         0x182001F
+#define CE_REG_FR_TREAL08__A                                         0x1820020
+#define CE_REG_FR_TIMAG08__A                                         0x1820021
+#define CE_REG_FR_TREAL09__A                                         0x1820022
+#define CE_REG_FR_TIMAG09__A                                         0x1820023
+#define CE_REG_FR_TREAL10__A                                         0x1820024
+#define CE_REG_FR_TIMAG10__A                                         0x1820025
+#define CE_REG_FR_TREAL11__A                                         0x1820026
+#define CE_REG_FR_TIMAG11__A                                         0x1820027
+#define CE_REG_FR_MID_TAP__A                                         0x1820028
+#define CE_REG_FR_SQS_G00__A                                         0x1820029
+#define CE_REG_FR_SQS_G01__A                                         0x182002A
+#define CE_REG_FR_SQS_G02__A                                         0x182002B
+#define CE_REG_FR_SQS_G03__A                                         0x182002C
+#define CE_REG_FR_SQS_G04__A                                         0x182002D
+#define CE_REG_FR_SQS_G05__A                                         0x182002E
+#define CE_REG_FR_SQS_G06__A                                         0x182002F
+#define CE_REG_FR_SQS_G07__A                                         0x1820030
+#define CE_REG_FR_SQS_G08__A                                         0x1820031
+#define CE_REG_FR_SQS_G09__A                                         0x1820032
+#define CE_REG_FR_SQS_G10__A                                         0x1820033
+#define CE_REG_FR_SQS_G11__A                                         0x1820034
+#define CE_REG_FR_SQS_G12__A                                         0x1820035
+#define CE_REG_FR_RIO_G00__A                                         0x1820036
+#define CE_REG_FR_RIO_G01__A                                         0x1820037
+#define CE_REG_FR_RIO_G02__A                                         0x1820038
+#define CE_REG_FR_RIO_G03__A                                         0x1820039
+#define CE_REG_FR_RIO_G04__A                                         0x182003A
+#define CE_REG_FR_RIO_G05__A                                         0x182003B
+#define CE_REG_FR_RIO_G06__A                                         0x182003C
+#define CE_REG_FR_RIO_G07__A                                         0x182003D
+#define CE_REG_FR_RIO_G08__A                                         0x182003E
+#define CE_REG_FR_RIO_G09__A                                         0x182003F
+#define CE_REG_FR_RIO_G10__A                                         0x1820040
+#define CE_REG_FR_MODE__A                                            0x1820041
+#define CE_REG_FR_SQS_TRH__A                                         0x1820042
+#define CE_REG_FR_RIO_GAIN__A                                        0x1820043
+#define CE_REG_FR_BYPASS__A                                          0x1820044
+#define CE_REG_FR_PM_SET__A                                          0x1820045
+#define CE_REG_FR_ERR_SH__A                                          0x1820046
+#define CE_REG_FR_MAN_SH__A                                          0x1820047
+#define CE_REG_FR_TAP_SH__A                                          0x1820048
+#define EQ_COMM_EXEC__A                                              0x1C00000
+#define EQ_REG_COMM_EXEC__A                                          0x1C10000
+#define EQ_REG_COMM_MB__A                                            0x1C10002
+#define EQ_REG_IS_GAIN_MAN__A                                        0x1C10015
+#define EQ_REG_IS_GAIN_EXP__A                                        0x1C10016
+#define EQ_REG_IS_CLIP_EXP__A                                        0x1C10017
+#define EQ_REG_SN_CEGAIN__A                                          0x1C1002A
+#define EQ_REG_SN_OFFSET__A                                          0x1C1002B
+#define EQ_REG_RC_SEL_CAR__A                                         0x1C10032
+#define   EQ_REG_RC_SEL_CAR_INIT                                     0x0
+#define     EQ_REG_RC_SEL_CAR_DIV_ON                                 0x1
+#define     EQ_REG_RC_SEL_CAR_PASS_A_CC                              0x0
+#define     EQ_REG_RC_SEL_CAR_PASS_B_CE                              0x2
+#define     EQ_REG_RC_SEL_CAR_LOCAL_A_CC                             0x0
+#define     EQ_REG_RC_SEL_CAR_LOCAL_B_CE                             0x8
+#define     EQ_REG_RC_SEL_CAR_MEAS_A_CC                              0x0
+#define     EQ_REG_RC_SEL_CAR_MEAS_B_CE                              0x20
+#define EQ_REG_OT_CONST__A                                           0x1C10046
+#define EQ_REG_OT_ALPHA__A                                           0x1C10047
+#define EQ_REG_OT_QNT_THRES0__A                                      0x1C10048
+#define EQ_REG_OT_QNT_THRES1__A                                      0x1C10049
+#define EQ_REG_OT_CSI_STEP__A                                        0x1C1004A
+#define EQ_REG_OT_CSI_OFFSET__A                                      0x1C1004B
+#define EQ_REG_TD_REQ_SMB_CNT__A                                     0x1C10061
+#define EQ_REG_TD_TPS_PWR_OFS__A                                     0x1C10062
+#define EC_SB_REG_COMM_EXEC__A                                       0x2010000
+#define EC_SB_REG_TR_MODE__A                                         0x2010010
+#define   EC_SB_REG_TR_MODE_8K                                       0x0
+#define   EC_SB_REG_TR_MODE_2K                                       0x1
+#define EC_SB_REG_CONST__A                                           0x2010011
+#define   EC_SB_REG_CONST_QPSK                                       0x0
+#define   EC_SB_REG_CONST_16QAM                                      0x1
+#define   EC_SB_REG_CONST_64QAM                                      0x2
+#define EC_SB_REG_ALPHA__A                                           0x2010012
+#define EC_SB_REG_PRIOR__A                                           0x2010013
+#define   EC_SB_REG_PRIOR_HI                                         0x0
+#define   EC_SB_REG_PRIOR_LO                                         0x1
+#define EC_SB_REG_CSI_HI__A                                          0x2010014
+#define EC_SB_REG_CSI_LO__A                                          0x2010015
+#define EC_SB_REG_SMB_TGL__A                                         0x2010016
+#define EC_SB_REG_SNR_HI__A                                          0x2010017
+#define EC_SB_REG_SNR_MID__A                                         0x2010018
+#define EC_SB_REG_SNR_LO__A                                          0x2010019
+#define EC_SB_REG_SCALE_MSB__A                                       0x201001A
+#define EC_SB_REG_SCALE_BIT2__A                                      0x201001B
+#define EC_SB_REG_SCALE_LSB__A                                       0x201001C
+#define EC_SB_REG_CSI_OFS__A                                         0x201001D
+#define EC_VD_REG_COMM_EXEC__A                                       0x2090000
+#define EC_VD_REG_FORCE__A                                           0x2090010
+#define EC_VD_REG_SET_CODERATE__A                                    0x2090011
+#define   EC_VD_REG_SET_CODERATE_C1_2                                0x0
+#define   EC_VD_REG_SET_CODERATE_C2_3                                0x1
+#define   EC_VD_REG_SET_CODERATE_C3_4                                0x2
+#define   EC_VD_REG_SET_CODERATE_C5_6                                0x3
+#define   EC_VD_REG_SET_CODERATE_C7_8                                0x4
+#define EC_VD_REG_REQ_SMB_CNT__A                                     0x2090012
+#define EC_VD_REG_RLK_ENA__A                                         0x2090014
+#define EC_OD_REG_COMM_EXEC__A                                       0x2110000
+#define EC_OD_REG_SYNC__A                                            0x2110010
+#define EC_OD_DEINT_RAM__A                                           0x2120000
+#define EC_RS_REG_COMM_EXEC__A                                       0x2130000
+#define EC_RS_REG_REQ_PCK_CNT__A                                     0x2130010
+#define EC_RS_REG_VAL__A                                             0x2130011
+#define   EC_RS_REG_VAL_PCK                                          0x1
+#define EC_RS_EC_RAM__A                                              0x2140000
+#define EC_OC_REG_COMM_EXEC__A                                       0x2150000
+#define     EC_OC_REG_COMM_EXEC_CTL_ACTIVE                           0x1
+#define     EC_OC_REG_COMM_EXEC_CTL_HOLD                             0x2
+#define EC_OC_REG_COMM_INT_STA__A                                    0x2150007
+#define EC_OC_REG_OC_MODE_LOP__A                                     0x2150010
+#define   EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                           0x1
+#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                     0x0
+#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                    0x1
+#define   EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                       0x4
+#define     EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC                 0x0
+#define   EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                       0x80
+#define     EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL                 0x80
+#define EC_OC_REG_OC_MODE_HIP__A                                     0x2150011
+#define     EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR                0x10
+#define   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                       0x200
+#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE                0x0
+#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE                 0x200
+#define EC_OC_REG_OC_MPG_SIO__A                                      0x2150012
+#define EC_OC_REG_OC_MPG_SIO__M                                      0xFFF
+#define EC_OC_REG_OC_MON_SIO__A                                      0x2150013
+#define EC_OC_REG_DTO_INC_LOP__A                                     0x2150014
+#define EC_OC_REG_DTO_INC_HIP__A                                     0x2150015
+#define EC_OC_REG_SNC_ISC_LVL__A                                     0x2150016
+#define   EC_OC_REG_SNC_ISC_LVL_OSC__M                               0xF0
+#define EC_OC_REG_TMD_TOP_MODE__A                                    0x215001D
+#define EC_OC_REG_TMD_TOP_CNT__A                                     0x215001E
+#define EC_OC_REG_TMD_HIL_MAR__A                                     0x215001F
+#define EC_OC_REG_TMD_LOL_MAR__A                                     0x2150020
+#define EC_OC_REG_TMD_CUR_CNT__A                                     0x2150021
+#define EC_OC_REG_AVR_ASH_CNT__A                                     0x2150023
+#define EC_OC_REG_AVR_BSH_CNT__A                                     0x2150024
+#define EC_OC_REG_RCN_MODE__A                                        0x2150027
+#define EC_OC_REG_RCN_CRA_LOP__A                                     0x2150028
+#define EC_OC_REG_RCN_CRA_HIP__A                                     0x2150029
+#define EC_OC_REG_RCN_CST_LOP__A                                     0x215002A
+#define EC_OC_REG_RCN_CST_HIP__A                                     0x215002B
+#define EC_OC_REG_RCN_SET_LVL__A                                     0x215002C
+#define EC_OC_REG_RCN_GAI_LVL__A                                     0x215002D
+#define EC_OC_REG_RCN_CLP_LOP__A                                     0x2150032
+#define EC_OC_REG_RCN_CLP_HIP__A                                     0x2150033
+#define EC_OC_REG_RCN_MAP_LOP__A                                     0x2150034
+#define EC_OC_REG_RCN_MAP_HIP__A                                     0x2150035
+#define EC_OC_REG_OCR_MPG_UOS__A                                     0x2150036
+#define EC_OC_REG_OCR_MPG_UOS__M                                     0xFFF
+#define   EC_OC_REG_OCR_MPG_UOS_INIT                                 0x0
+#define EC_OC_REG_OCR_MPG_USR_DAT__A                                 0x2150038
+#define EC_OC_REG_OCR_MON_UOS__A                                     0x2150039
+#define     EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE                       0x1
+#define     EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE                       0x2
+#define     EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE                       0x4
+#define     EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE                       0x8
+#define     EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE                       0x10
+#define     EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE                       0x20
+#define     EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE                       0x40
+#define     EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE                       0x80
+#define     EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE                       0x100
+#define     EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE                       0x200
+#define     EC_OC_REG_OCR_MON_UOS_VAL_ENABLE                         0x400
+#define     EC_OC_REG_OCR_MON_UOS_CLK_ENABLE                         0x800
+#define EC_OC_REG_OCR_MON_WRI__A                                     0x215003A
+#define   EC_OC_REG_OCR_MON_WRI_INIT                                 0x0
+#define EC_OC_REG_IPR_INV_MPG__A                                     0x2150045
+#define CC_REG_OSC_MODE__A                                           0x2410010
+#define   CC_REG_OSC_MODE_M20                                        0x1
+#define CC_REG_PLL_MODE__A                                           0x2410011
+#define     CC_REG_PLL_MODE_BYPASS_PLL                               0x1
+#define     CC_REG_PLL_MODE_PUMP_CUR_12                              0x14
+#define CC_REG_REF_DIVIDE__A                                         0x2410012
+#define CC_REG_PWD_MODE__A                                           0x2410015
+#define   CC_REG_PWD_MODE_DOWN_PLL                                   0x2
+#define CC_REG_UPDATE__A                                             0x2410017
+#define   CC_REG_UPDATE_KEY                                          0x3973
+#define CC_REG_JTAGID_L__A                                           0x2410019
+#define LC_COMM_EXEC__A                                              0x2800000
+#define LC_RA_RAM_IFINCR_NOM_L__A                                    0x282000C
+#define LC_RA_RAM_FILTER_SYM_SET__A                                  0x282001A
+#define LC_RA_RAM_FILTER_SYM_SET__PRE                                0x3E8
+#define LC_RA_RAM_FILTER_CRMM_A__A                                   0x2820060
+#define LC_RA_RAM_FILTER_CRMM_A__PRE                                 0x4
+#define LC_RA_RAM_FILTER_CRMM_B__A                                   0x2820061
+#define LC_RA_RAM_FILTER_CRMM_B__PRE                                 0x1
+#define LC_RA_RAM_FILTER_SRMM_A__A                                   0x2820068
+#define LC_RA_RAM_FILTER_SRMM_A__PRE                                 0x4
+#define LC_RA_RAM_FILTER_SRMM_B__A                                   0x2820069
+#define LC_RA_RAM_FILTER_SRMM_B__PRE                                 0x1
+#define B_HI_COMM_EXEC__A                                            0x400000
+#define B_HI_COMM_MB__A                                              0x400002
+#define B_HI_CT_REG_COMM_STATE__A                                    0x410001
+#define B_HI_RA_RAM_SRV_RES__A                                       0x420031
+#define B_HI_RA_RAM_SRV_CMD__A                                       0x420032
+#define   B_HI_RA_RAM_SRV_CMD_RESET                                  0x2
+#define   B_HI_RA_RAM_SRV_CMD_CONFIG                                 0x3
+#define   B_HI_RA_RAM_SRV_CMD_EXECUTE                                0x6
+#define B_HI_RA_RAM_SRV_RST_KEY__A                                   0x420033
+#define   B_HI_RA_RAM_SRV_RST_KEY_ACT                                0x3973
+#define B_HI_RA_RAM_SRV_CFG_KEY__A                                   0x420033
+#define B_HI_RA_RAM_SRV_CFG_DIV__A                                   0x420034
+#define B_HI_RA_RAM_SRV_CFG_BDL__A                                   0x420035
+#define B_HI_RA_RAM_SRV_CFG_WUP__A                                   0x420036
+#define B_HI_RA_RAM_SRV_CFG_ACT__A                                   0x420037
+#define     B_HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                          0x1
+#define   B_HI_RA_RAM_SRV_CFG_ACT_BRD__M                             0x4
+#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                          0x0
+#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_ON                           0x4
+#define     B_HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                          0x8
+#define B_HI_RA_RAM_USR_BEGIN__A                                     0x420040
+#define B_HI_IF_RAM_TRP_BPT0__AX                                     0x430000
+#define B_HI_IF_RAM_USR_BEGIN__A                                     0x430200
+#define B_SC_COMM_EXEC__A                                            0x800000
+#define     B_SC_COMM_EXEC_CTL_STOP                                  0x0
+#define B_SC_COMM_STATE__A                                           0x800001
+#define B_SC_RA_RAM_PARAM0__A                                        0x820040
+#define B_SC_RA_RAM_PARAM1__A                                        0x820041
+#define B_SC_RA_RAM_CMD_ADDR__A                                      0x820042
+#define B_SC_RA_RAM_CMD__A                                           0x820043
+#define   B_SC_RA_RAM_CMD_PROC_START                                 0x1
+#define   B_SC_RA_RAM_CMD_SET_PREF_PARAM                             0x3
+#define   B_SC_RA_RAM_CMD_GET_OP_PARAM                               0x5
+#define   B_SC_RA_RAM_SW_EVENT_RUN_NMASK__M                          0x1
+#define   B_SC_RA_RAM_LOCKTRACK_MIN                                  0x1
+#define     B_SC_RA_RAM_OP_PARAM_MODE_2K                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_MODE_8K                             0x1
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_32                            0x0
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_16                            0x4
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_8                             0x8
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_4                             0xC
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QPSK                          0x0
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM16                         0x10
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM64                         0x20
+#define     B_SC_RA_RAM_OP_PARAM_HIER_NO                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A1                             0x40
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A2                             0x80
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A4                             0xC0
+#define     B_SC_RA_RAM_OP_PARAM_RATE_1_2                            0x0
+#define     B_SC_RA_RAM_OP_PARAM_RATE_2_3                            0x200
+#define     B_SC_RA_RAM_OP_PARAM_RATE_3_4                            0x400
+#define     B_SC_RA_RAM_OP_PARAM_RATE_5_6                            0x600
+#define     B_SC_RA_RAM_OP_PARAM_RATE_7_8                            0x800
+#define     B_SC_RA_RAM_OP_PARAM_PRIO_HI                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_PRIO_LO                             0x1000
+#define   B_SC_RA_RAM_OP_AUTO_MODE__M                                0x1
+#define   B_SC_RA_RAM_OP_AUTO_GUARD__M                               0x2
+#define   B_SC_RA_RAM_OP_AUTO_CONST__M                               0x4
+#define   B_SC_RA_RAM_OP_AUTO_HIER__M                                0x8
+#define   B_SC_RA_RAM_OP_AUTO_RATE__M                                0x10
+#define B_SC_RA_RAM_LOCK__A                                          0x82004B
+#define   B_SC_RA_RAM_LOCK_DEMOD__M                                  0x1
+#define   B_SC_RA_RAM_LOCK_FEC__M                                    0x2
+#define   B_SC_RA_RAM_LOCK_MPEG__M                                   0x4
+#define B_SC_RA_RAM_BE_OPT_ENA__A                                    0x82004C
+#define   B_SC_RA_RAM_BE_OPT_ENA_CP_OPT                              0x1
+#define B_SC_RA_RAM_BE_OPT_DELAY__A                                  0x82004D
+#define B_SC_RA_RAM_CONFIG__A                                        0x820050
+#define   B_SC_RA_RAM_CONFIG_FR_ENABLE__M                            0x4
+#define   B_SC_RA_RAM_CONFIG_FREQSCAN__M                             0x10
+#define   B_SC_RA_RAM_CONFIG_SLAVE__M                                0x20
+#define   B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M                     0x200
+#define   B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M                      0x400
+#define B_SC_RA_RAM_CO_TD_CAL_2K__A                                  0x82005D
+#define B_SC_RA_RAM_CO_TD_CAL_8K__A                                  0x82005E
+#define B_SC_RA_RAM_IF_SAVE__AX                                      0x82008E
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A                         0x820098
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A                         0x820099
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A                          0x82009A
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A                          0x82009B
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A                         0x82009C
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A                         0x82009D
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A                          0x82009E
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A                          0x82009F
+#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A                           0x8200D1
+#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                         0x9
+#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A                          0x8200D2
+#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                        0x4
+#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A                          0x8200D3
+#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                        0x100
+#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A                           0x8200D4
+#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                         0x8
+#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A                          0x8200D5
+#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                        0x8
+#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A                          0x8200D6
+#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                        0x200
+#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__A                             0x8200D7
+#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                           0x9
+#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__A                            0x8200D8
+#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                          0x4
+#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__A                            0x8200D9
+#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                          0x100
+#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__A                             0x8200DA
+#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                           0xB
+#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__A                            0x8200DB
+#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                          0x1
+#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__A                            0x8200DC
+#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                          0x40
+#define B_SC_RA_RAM_ECHO_SHIFT_LIM__A                                0x8200DD
+#define B_SC_RA_RAM_SAMPLE_RATE_COUNT__A                             0x8200E8
+#define B_SC_RA_RAM_SAMPLE_RATE_STEP__A                              0x8200E9
+#define B_SC_RA_RAM_BAND__A                                          0x8200EC
+#define B_SC_RA_RAM_LC_ABS_2K__A                                     0x8200F4
+#define B_SC_RA_RAM_LC_ABS_2K__PRE                                   0x1F
+#define B_SC_RA_RAM_LC_ABS_8K__A                                     0x8200F5
+#define B_SC_RA_RAM_LC_ABS_8K__PRE                                   0x1F
+#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                      0x100
+#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                      0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                         0x1E2
+#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                         0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                        0x10D
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                        0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                     0x17D
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                     0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                     0x133
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                     0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                        0x114
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                        0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                     0x14A
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                     0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                     0x1BB
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                     0x4
+#define B_SC_RA_RAM_DRIVER_VERSION__AX                               0x8201FE
+#define   B_SC_RA_RAM_PROC_LOCKTRACK                                 0x0
+#define B_FE_COMM_EXEC__A                                            0xC00000
+#define B_FE_AD_REG_COMM_EXEC__A                                     0xC10000
+#define B_FE_AD_REG_FDB_IN__A                                        0xC10012
+#define B_FE_AD_REG_PD__A                                            0xC10013
+#define B_FE_AD_REG_INVEXT__A                                        0xC10014
+#define B_FE_AD_REG_CLKNEG__A                                        0xC10015
+#define B_FE_AG_REG_COMM_EXEC__A                                     0xC20000
+#define B_FE_AG_REG_AG_MODE_LOP__A                                   0xC20010
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_4__M                          0x10
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                   0x10
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_5__M                          0x20
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                    0x0
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_C__M                          0x1000
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                   0x1000
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_E__M                          0x4000
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                   0x4000
+#define B_FE_AG_REG_AG_MODE_HIP__A                                   0xC20011
+#define   B_FE_AG_REG_AG_MODE_HIP_MODE_J__M                          0x8
+#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC                   0x8
+#define B_FE_AG_REG_AG_PGA_MODE__A                                   0xC20012
+#define   B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                    0x0
+#define   B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                    0x1
+#define B_FE_AG_REG_AG_AGC_SIO__A                                    0xC20013
+#define   B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                        0x2
+#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                  0x0
+#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                   0x2
+#define B_FE_AG_REG_AG_PWD__A                                        0xC20015
+#define   B_FE_AG_REG_AG_PWD_PWD_PD2__M                              0x2
+#define     B_FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                       0x0
+#define     B_FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                        0x2
+#define B_FE_AG_REG_DCE_AUR_CNT__A                                   0xC20016
+#define B_FE_AG_REG_DCE_RUR_CNT__A                                   0xC20017
+#define B_FE_AG_REG_ACE_AUR_CNT__A                                   0xC2001A
+#define B_FE_AG_REG_ACE_RUR_CNT__A                                   0xC2001B
+#define B_FE_AG_REG_CDR_RUR_CNT__A                                   0xC20020
+#define B_FE_AG_REG_EGC_RUR_CNT__A                                   0xC20024
+#define B_FE_AG_REG_EGC_SET_LVL__A                                   0xC20025
+#define B_FE_AG_REG_EGC_SET_LVL__M                                   0x1FF
+#define B_FE_AG_REG_EGC_FLA_RGN__A                                   0xC20026
+#define B_FE_AG_REG_EGC_SLO_RGN__A                                   0xC20027
+#define B_FE_AG_REG_EGC_JMP_PSN__A                                   0xC20028
+#define B_FE_AG_REG_EGC_FLA_INC__A                                   0xC20029
+#define B_FE_AG_REG_EGC_FLA_DEC__A                                   0xC2002A
+#define B_FE_AG_REG_EGC_SLO_INC__A                                   0xC2002B
+#define B_FE_AG_REG_EGC_SLO_DEC__A                                   0xC2002C
+#define B_FE_AG_REG_EGC_FAS_INC__A                                   0xC2002D
+#define B_FE_AG_REG_EGC_FAS_DEC__A                                   0xC2002E
+#define B_FE_AG_REG_PM1_AGC_WRI__A                                   0xC20030
+#define B_FE_AG_REG_PM1_AGC_WRI__M                                   0x7FF
+#define B_FE_AG_REG_GC1_AGC_RIC__A                                   0xC20031
+#define B_FE_AG_REG_GC1_AGC_OFF__A                                   0xC20032
+#define B_FE_AG_REG_GC1_AGC_MAX__A                                   0xC20033
+#define B_FE_AG_REG_GC1_AGC_MIN__A                                   0xC20034
+#define B_FE_AG_REG_GC1_AGC_DAT__A                                   0xC20035
+#define B_FE_AG_REG_GC1_AGC_DAT__M                                   0x3FF
+#define B_FE_AG_REG_PM2_AGC_WRI__A                                   0xC20036
+#define B_FE_AG_REG_IND_WIN__A                                       0xC2003C
+#define B_FE_AG_REG_IND_THD_LOL__A                                   0xC2003D
+#define B_FE_AG_REG_IND_THD_HIL__A                                   0xC2003E
+#define B_FE_AG_REG_IND_DEL__A                                       0xC2003F
+#define B_FE_AG_REG_IND_PD1_WRI__A                                   0xC20040
+#define B_FE_AG_REG_PDA_AUR_CNT__A                                   0xC20041
+#define B_FE_AG_REG_PDA_RUR_CNT__A                                   0xC20042
+#define B_FE_AG_REG_PDA_AVE_DAT__A                                   0xC20043
+#define B_FE_AG_REG_PDC_RUR_CNT__A                                   0xC20044
+#define B_FE_AG_REG_PDC_SET_LVL__A                                   0xC20045
+#define B_FE_AG_REG_PDC_FLA_RGN__A                                   0xC20046
+#define B_FE_AG_REG_PDC_JMP_PSN__A                                   0xC20047
+#define B_FE_AG_REG_PDC_FLA_STP__A                                   0xC20048
+#define B_FE_AG_REG_PDC_SLO_STP__A                                   0xC20049
+#define B_FE_AG_REG_PDC_PD2_WRI__A                                   0xC2004A
+#define B_FE_AG_REG_PDC_MAP_DAT__A                                   0xC2004B
+#define B_FE_AG_REG_PDC_MAX__A                                       0xC2004C
+#define B_FE_AG_REG_TGA_AUR_CNT__A                                   0xC2004D
+#define B_FE_AG_REG_TGA_RUR_CNT__A                                   0xC2004E
+#define B_FE_AG_REG_TGA_AVE_DAT__A                                   0xC2004F
+#define B_FE_AG_REG_TGC_RUR_CNT__A                                   0xC20050
+#define B_FE_AG_REG_TGC_SET_LVL__A                                   0xC20051
+#define B_FE_AG_REG_TGC_SET_LVL__M                                   0x3F
+#define B_FE_AG_REG_TGC_FLA_RGN__A                                   0xC20052
+#define B_FE_AG_REG_TGC_JMP_PSN__A                                   0xC20053
+#define B_FE_AG_REG_TGC_FLA_STP__A                                   0xC20054
+#define B_FE_AG_REG_TGC_SLO_STP__A                                   0xC20055
+#define B_FE_AG_REG_TGC_MAP_DAT__A                                   0xC20056
+#define B_FE_AG_REG_FGM_WRI__A                                       0xC20061
+#define B_FE_AG_REG_BGC_FGC_WRI__A                                   0xC20068
+#define B_FE_AG_REG_BGC_CGC_WRI__A                                   0xC20069
+#define B_FE_FS_REG_COMM_EXEC__A                                     0xC30000
+#define B_FE_FS_REG_ADD_INC_LOP__A                                   0xC30010
+#define B_FE_FD_REG_COMM_EXEC__A                                     0xC40000
+#define B_FE_FD_REG_SCL__A                                           0xC40010
+#define B_FE_FD_REG_MAX_LEV__A                                       0xC40011
+#define B_FE_FD_REG_NR__A                                            0xC40012
+#define B_FE_FD_REG_MEAS_VAL__A                                      0xC40014
+#define B_FE_IF_REG_COMM_EXEC__A                                     0xC50000
+#define B_FE_IF_REG_INCR0__A                                         0xC50010
+#define B_FE_IF_REG_INCR0__W                                         16
+#define B_FE_IF_REG_INCR0__M                                         0xFFFF
+#define B_FE_IF_REG_INCR1__A                                         0xC50011
+#define B_FE_IF_REG_INCR1__M                                         0xFF
+#define B_FE_CF_REG_COMM_EXEC__A                                     0xC60000
+#define B_FE_CF_REG_SCL__A                                           0xC60010
+#define B_FE_CF_REG_MAX_LEV__A                                       0xC60011
+#define B_FE_CF_REG_NR__A                                            0xC60012
+#define B_FE_CF_REG_IMP_VAL__A                                       0xC60013
+#define B_FE_CF_REG_MEAS_VAL__A                                      0xC60014
+#define B_FE_CU_REG_COMM_EXEC__A                                     0xC70000
+#define B_FE_CU_REG_FRM_CNT_RST__A                                   0xC70011
+#define B_FE_CU_REG_FRM_CNT_STR__A                                   0xC70012
+#define B_FE_CU_REG_CTR_NFC_ICR__A                                   0xC70020
+#define B_FE_CU_REG_CTR_NFC_OCR__A                                   0xC70021
+#define B_FE_CU_REG_DIV_NFC_CLP__A                                   0xC70027
+#define B_FT_COMM_EXEC__A                                            0x1000000
+#define B_FT_REG_COMM_EXEC__A                                        0x1010000
+#define B_CP_COMM_EXEC__A                                            0x1400000
+#define B_CP_REG_COMM_EXEC__A                                        0x1410000
+#define B_CP_REG_INTERVAL__A                                         0x1410011
+#define B_CP_REG_BR_SPL_OFFSET__A                                    0x1410023
+#define B_CP_REG_BR_STR_DEL__A                                       0x1410024
+#define B_CP_REG_RT_ANG_INC0__A                                      0x1410030
+#define B_CP_REG_RT_ANG_INC1__A                                      0x1410031
+#define B_CP_REG_RT_DETECT_TRH__A                                    0x1410033
+#define B_CP_REG_AC_NEXP_OFFS__A                                     0x1410040
+#define B_CP_REG_AC_AVER_POW__A                                      0x1410041
+#define B_CP_REG_AC_MAX_POW__A                                       0x1410042
+#define B_CP_REG_AC_WEIGHT_MAN__A                                    0x1410043
+#define B_CP_REG_AC_WEIGHT_EXP__A                                    0x1410044
+#define B_CP_REG_AC_AMP_MODE__A                                      0x1410047
+#define B_CP_REG_AC_AMP_FIX__A                                       0x1410048
+#define B_CP_REG_AC_ANG_MODE__A                                      0x141004A
+#define B_CE_COMM_EXEC__A                                            0x1800000
+#define B_CE_REG_COMM_EXEC__A                                        0x1810000
+#define B_CE_REG_TAPSET__A                                           0x1810011
+#define B_CE_REG_AVG_POW__A                                          0x1810012
+#define B_CE_REG_MAX_POW__A                                          0x1810013
+#define B_CE_REG_ATT__A                                              0x1810014
+#define B_CE_REG_NRED__A                                             0x1810015
+#define B_CE_REG_NE_ERR_SELECT__A                                    0x1810043
+#define B_CE_REG_NE_TD_CAL__A                                        0x1810044
+#define B_CE_REG_NE_MIXAVG__A                                        0x1810046
+#define B_CE_REG_NE_NUPD_OFS__A                                      0x1810047
+#define B_CE_REG_PE_NEXP_OFFS__A                                     0x1810050
+#define B_CE_REG_PE_TIMESHIFT__A                                     0x1810051
+#define B_CE_REG_TP_A0_TAP_NEW__A                                    0x1810064
+#define B_CE_REG_TP_A0_TAP_NEW_VALID__A                              0x1810065
+#define B_CE_REG_TP_A0_MU_LMS_STEP__A                                0x1810066
+#define B_CE_REG_TP_A1_TAP_NEW__A                                    0x1810068
+#define B_CE_REG_TP_A1_TAP_NEW_VALID__A                              0x1810069
+#define B_CE_REG_TP_A1_MU_LMS_STEP__A                                0x181006A
+#define B_CE_REG_TI_PHN_ENABLE__A                                    0x1810073
+#define B_CE_REG_FI_SHT_INCR__A                                      0x1810090
+#define B_CE_REG_FI_EXP_NORM__A                                      0x1810091
+#define B_CE_REG_IR_INPUTSEL__A                                      0x18100A0
+#define B_CE_REG_IR_STARTPOS__A                                      0x18100A1
+#define B_CE_REG_IR_NEXP_THRES__A                                    0x18100A2
+#define B_CE_REG_FR_TREAL00__A                                       0x1820010
+#define B_CE_REG_FR_TIMAG00__A                                       0x1820011
+#define B_CE_REG_FR_TREAL01__A                                       0x1820012
+#define B_CE_REG_FR_TIMAG01__A                                       0x1820013
+#define B_CE_REG_FR_TREAL02__A                                       0x1820014
+#define B_CE_REG_FR_TIMAG02__A                                       0x1820015
+#define B_CE_REG_FR_TREAL03__A                                       0x1820016
+#define B_CE_REG_FR_TIMAG03__A                                       0x1820017
+#define B_CE_REG_FR_TREAL04__A                                       0x1820018
+#define B_CE_REG_FR_TIMAG04__A                                       0x1820019
+#define B_CE_REG_FR_TREAL05__A                                       0x182001A
+#define B_CE_REG_FR_TIMAG05__A                                       0x182001B
+#define B_CE_REG_FR_TREAL06__A                                       0x182001C
+#define B_CE_REG_FR_TIMAG06__A                                       0x182001D
+#define B_CE_REG_FR_TREAL07__A                                       0x182001E
+#define B_CE_REG_FR_TIMAG07__A                                       0x182001F
+#define B_CE_REG_FR_TREAL08__A                                       0x1820020
+#define B_CE_REG_FR_TIMAG08__A                                       0x1820021
+#define B_CE_REG_FR_TREAL09__A                                       0x1820022
+#define B_CE_REG_FR_TIMAG09__A                                       0x1820023
+#define B_CE_REG_FR_TREAL10__A                                       0x1820024
+#define B_CE_REG_FR_TIMAG10__A                                       0x1820025
+#define B_CE_REG_FR_TREAL11__A                                       0x1820026
+#define B_CE_REG_FR_TIMAG11__A                                       0x1820027
+#define B_CE_REG_FR_MID_TAP__A                                       0x1820028
+#define B_CE_REG_FR_SQS_G00__A                                       0x1820029
+#define B_CE_REG_FR_SQS_G01__A                                       0x182002A
+#define B_CE_REG_FR_SQS_G02__A                                       0x182002B
+#define B_CE_REG_FR_SQS_G03__A                                       0x182002C
+#define B_CE_REG_FR_SQS_G04__A                                       0x182002D
+#define B_CE_REG_FR_SQS_G05__A                                       0x182002E
+#define B_CE_REG_FR_SQS_G06__A                                       0x182002F
+#define B_CE_REG_FR_SQS_G07__A                                       0x1820030
+#define B_CE_REG_FR_SQS_G08__A                                       0x1820031
+#define B_CE_REG_FR_SQS_G09__A                                       0x1820032
+#define B_CE_REG_FR_SQS_G10__A                                       0x1820033
+#define B_CE_REG_FR_SQS_G11__A                                       0x1820034
+#define B_CE_REG_FR_SQS_G12__A                                       0x1820035
+#define B_CE_REG_FR_RIO_G00__A                                       0x1820036
+#define B_CE_REG_FR_RIO_G01__A                                       0x1820037
+#define B_CE_REG_FR_RIO_G02__A                                       0x1820038
+#define B_CE_REG_FR_RIO_G03__A                                       0x1820039
+#define B_CE_REG_FR_RIO_G04__A                                       0x182003A
+#define B_CE_REG_FR_RIO_G05__A                                       0x182003B
+#define B_CE_REG_FR_RIO_G06__A                                       0x182003C
+#define B_CE_REG_FR_RIO_G07__A                                       0x182003D
+#define B_CE_REG_FR_RIO_G08__A                                       0x182003E
+#define B_CE_REG_FR_RIO_G09__A                                       0x182003F
+#define B_CE_REG_FR_RIO_G10__A                                       0x1820040
+#define B_CE_REG_FR_MODE__A                                          0x1820041
+#define B_CE_REG_FR_SQS_TRH__A                                       0x1820042
+#define B_CE_REG_FR_RIO_GAIN__A                                      0x1820043
+#define B_CE_REG_FR_BYPASS__A                                        0x1820044
+#define B_CE_REG_FR_PM_SET__A                                        0x1820045
+#define B_CE_REG_FR_ERR_SH__A                                        0x1820046
+#define B_CE_REG_FR_MAN_SH__A                                        0x1820047
+#define B_CE_REG_FR_TAP_SH__A                                        0x1820048
+#define B_EQ_COMM_EXEC__A                                            0x1C00000
+#define B_EQ_REG_COMM_EXEC__A                                        0x1C10000
+#define B_EQ_REG_COMM_MB__A                                          0x1C10002
+#define B_EQ_REG_IS_GAIN_MAN__A                                      0x1C10015
+#define B_EQ_REG_IS_GAIN_EXP__A                                      0x1C10016
+#define B_EQ_REG_IS_CLIP_EXP__A                                      0x1C10017
+#define B_EQ_REG_SN_CEGAIN__A                                        0x1C1002A
+#define B_EQ_REG_SN_OFFSET__A                                        0x1C1002B
+#define B_EQ_REG_RC_SEL_CAR__A                                       0x1C10032
+#define   B_EQ_REG_RC_SEL_CAR_INIT                                   0x2
+#define     B_EQ_REG_RC_SEL_CAR_DIV_ON                               0x1
+#define     B_EQ_REG_RC_SEL_CAR_PASS_A_CC                            0x0
+#define     B_EQ_REG_RC_SEL_CAR_PASS_B_CE                            0x2
+#define     B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC                           0x0
+#define     B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE                           0x8
+#define     B_EQ_REG_RC_SEL_CAR_MEAS_A_CC                            0x0
+#define     B_EQ_REG_RC_SEL_CAR_MEAS_B_CE                            0x20
+#define   B_EQ_REG_RC_SEL_CAR_FFTMODE__M                             0x80
+#define B_EQ_REG_OT_CONST__A                                         0x1C10046
+#define B_EQ_REG_OT_ALPHA__A                                         0x1C10047
+#define B_EQ_REG_OT_QNT_THRES0__A                                    0x1C10048
+#define B_EQ_REG_OT_QNT_THRES1__A                                    0x1C10049
+#define B_EQ_REG_OT_CSI_STEP__A                                      0x1C1004A
+#define B_EQ_REG_OT_CSI_OFFSET__A                                    0x1C1004B
+#define B_EQ_REG_TD_REQ_SMB_CNT__A                                   0x1C10061
+#define B_EQ_REG_TD_TPS_PWR_OFS__A                                   0x1C10062
+#define B_EC_SB_REG_COMM_EXEC__A                                     0x2010000
+#define B_EC_SB_REG_TR_MODE__A                                       0x2010010
+#define   B_EC_SB_REG_TR_MODE_8K                                     0x0
+#define   B_EC_SB_REG_TR_MODE_2K                                     0x1
+#define B_EC_SB_REG_CONST__A                                         0x2010011
+#define   B_EC_SB_REG_CONST_QPSK                                     0x0
+#define   B_EC_SB_REG_CONST_16QAM                                    0x1
+#define   B_EC_SB_REG_CONST_64QAM                                    0x2
+#define B_EC_SB_REG_ALPHA__A                                         0x2010012
+#define B_EC_SB_REG_PRIOR__A                                         0x2010013
+#define   B_EC_SB_REG_PRIOR_HI                                       0x0
+#define   B_EC_SB_REG_PRIOR_LO                                       0x1
+#define B_EC_SB_REG_CSI_HI__A                                        0x2010014
+#define B_EC_SB_REG_CSI_LO__A                                        0x2010015
+#define B_EC_SB_REG_SMB_TGL__A                                       0x2010016
+#define B_EC_SB_REG_SNR_HI__A                                        0x2010017
+#define B_EC_SB_REG_SNR_MID__A                                       0x2010018
+#define B_EC_SB_REG_SNR_LO__A                                        0x2010019
+#define B_EC_SB_REG_SCALE_MSB__A                                     0x201001A
+#define B_EC_SB_REG_SCALE_BIT2__A                                    0x201001B
+#define B_EC_SB_REG_SCALE_LSB__A                                     0x201001C
+#define B_EC_SB_REG_CSI_OFS0__A                                      0x201001D
+#define B_EC_SB_REG_CSI_OFS1__A                                      0x201001E
+#define B_EC_SB_REG_CSI_OFS2__A                                      0x201001F
+#define B_EC_VD_REG_COMM_EXEC__A                                     0x2090000
+#define B_EC_VD_REG_FORCE__A                                         0x2090010
+#define B_EC_VD_REG_SET_CODERATE__A                                  0x2090011
+#define   B_EC_VD_REG_SET_CODERATE_C1_2                              0x0
+#define   B_EC_VD_REG_SET_CODERATE_C2_3                              0x1
+#define   B_EC_VD_REG_SET_CODERATE_C3_4                              0x2
+#define   B_EC_VD_REG_SET_CODERATE_C5_6                              0x3
+#define   B_EC_VD_REG_SET_CODERATE_C7_8                              0x4
+#define B_EC_VD_REG_REQ_SMB_CNT__A                                   0x2090012
+#define B_EC_VD_REG_RLK_ENA__A                                       0x2090014
+#define B_EC_OD_REG_COMM_EXEC__A                                     0x2110000
+#define B_EC_OD_REG_SYNC__A                                          0x2110664
+#define B_EC_OD_DEINT_RAM__A                                         0x2120000
+#define B_EC_RS_REG_COMM_EXEC__A                                     0x2130000
+#define B_EC_RS_REG_REQ_PCK_CNT__A                                   0x2130010
+#define B_EC_RS_REG_VAL__A                                           0x2130011
+#define   B_EC_RS_REG_VAL_PCK                                        0x1
+#define B_EC_RS_EC_RAM__A                                            0x2140000
+#define B_EC_OC_REG_COMM_EXEC__A                                     0x2150000
+#define     B_EC_OC_REG_COMM_EXEC_CTL_ACTIVE                         0x1
+#define     B_EC_OC_REG_COMM_EXEC_CTL_HOLD                           0x2
+#define B_EC_OC_REG_COMM_INT_STA__A                                  0x2150007
+#define B_EC_OC_REG_OC_MODE_LOP__A                                   0x2150010
+#define   B_EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                         0x1
+#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                   0x0
+#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                  0x1
+#define   B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                     0x4
+#define     B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC               0x0
+#define   B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                     0x80
+#define     B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL               0x80
+#define B_EC_OC_REG_OC_MODE_HIP__A                                   0x2150011
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR              0x10
+#define   B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                     0x200
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE              0x0
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE               0x200
+#define B_EC_OC_REG_OC_MPG_SIO__A                                    0x2150012
+#define B_EC_OC_REG_OC_MPG_SIO__M                                    0xFFF
+#define B_EC_OC_REG_DTO_INC_LOP__A                                   0x2150014
+#define B_EC_OC_REG_DTO_INC_HIP__A                                   0x2150015
+#define B_EC_OC_REG_SNC_ISC_LVL__A                                   0x2150016
+#define   B_EC_OC_REG_SNC_ISC_LVL_OSC__M                             0xF0
+#define B_EC_OC_REG_TMD_TOP_MODE__A                                  0x215001D
+#define B_EC_OC_REG_TMD_TOP_CNT__A                                   0x215001E
+#define B_EC_OC_REG_TMD_HIL_MAR__A                                   0x215001F
+#define B_EC_OC_REG_TMD_LOL_MAR__A                                   0x2150020
+#define B_EC_OC_REG_TMD_CUR_CNT__A                                   0x2150021
+#define B_EC_OC_REG_AVR_ASH_CNT__A                                   0x2150023
+#define B_EC_OC_REG_AVR_BSH_CNT__A                                   0x2150024
+#define B_EC_OC_REG_RCN_MODE__A                                      0x2150027
+#define B_EC_OC_REG_RCN_CRA_LOP__A                                   0x2150028
+#define B_EC_OC_REG_RCN_CRA_HIP__A                                   0x2150029
+#define B_EC_OC_REG_RCN_CST_LOP__A                                   0x215002A
+#define B_EC_OC_REG_RCN_CST_HIP__A                                   0x215002B
+#define B_EC_OC_REG_RCN_SET_LVL__A                                   0x215002C
+#define B_EC_OC_REG_RCN_GAI_LVL__A                                   0x215002D
+#define B_EC_OC_REG_RCN_CLP_LOP__A                                   0x2150032
+#define B_EC_OC_REG_RCN_CLP_HIP__A                                   0x2150033
+#define B_EC_OC_REG_RCN_MAP_LOP__A                                   0x2150034
+#define B_EC_OC_REG_RCN_MAP_HIP__A                                   0x2150035
+#define B_EC_OC_REG_OCR_MPG_UOS__A                                   0x2150036
+#define B_EC_OC_REG_OCR_MPG_UOS__M                                   0xFFF
+#define   B_EC_OC_REG_OCR_MPG_UOS_INIT                               0x0
+#define B_EC_OC_REG_OCR_MPG_USR_DAT__A                               0x2150038
+#define B_EC_OC_REG_IPR_INV_MPG__A                                   0x2150045
+#define B_EC_OC_REG_DTO_CLKMODE__A                                   0x2150047
+#define B_EC_OC_REG_DTO_PER__A                                       0x2150048
+#define B_EC_OC_REG_DTO_BUR__A                                       0x2150049
+#define B_EC_OC_REG_RCR_CLKMODE__A                                   0x215004A
+#define B_CC_REG_OSC_MODE__A                                         0x2410010
+#define   B_CC_REG_OSC_MODE_M20                                      0x1
+#define B_CC_REG_PLL_MODE__A                                         0x2410011
+#define     B_CC_REG_PLL_MODE_BYPASS_PLL                             0x1
+#define     B_CC_REG_PLL_MODE_PUMP_CUR_12                            0x14
+#define B_CC_REG_REF_DIVIDE__A                                       0x2410012
+#define B_CC_REG_PWD_MODE__A                                         0x2410015
+#define   B_CC_REG_PWD_MODE_DOWN_PLL                                 0x2
+#define B_CC_REG_UPDATE__A                                           0x2410017
+#define   B_CC_REG_UPDATE_KEY                                        0x3973
+#define B_CC_REG_JTAGID_L__A                                         0x2410019
+#define B_CC_REG_DIVERSITY__A                                        0x241001B
+#define B_LC_COMM_EXEC__A                                            0x2800000
+#define B_LC_RA_RAM_IFINCR_NOM_L__A                                  0x282000C
+#define B_LC_RA_RAM_FILTER_SYM_SET__A                                0x282001A
+#define B_LC_RA_RAM_FILTER_SYM_SET__PRE                              0x3E8
+#define B_LC_RA_RAM_FILTER_CRMM_A__A                                 0x2820060
+#define B_LC_RA_RAM_FILTER_CRMM_A__PRE                               0x4
+#define B_LC_RA_RAM_FILTER_CRMM_B__A                                 0x2820061
+#define B_LC_RA_RAM_FILTER_CRMM_B__PRE                               0x1
+#define B_LC_RA_RAM_FILTER_SRMM_A__A                                 0x2820068
+#define B_LC_RA_RAM_FILTER_SRMM_A__PRE                               0x4
+#define B_LC_RA_RAM_FILTER_SRMM_B__A                                 0x2820069
+#define B_LC_RA_RAM_FILTER_SRMM_B__PRE                               0x1
+
+#endif
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
new file mode 100644 (file)
index 0000000..d615d7d
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef _DRXK_H_
+#define _DRXK_H_
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+/**
+ * struct drxk_config - Configure the initial parameters for DRX-K
+ *
+ * @adr:               I2C Address of the DRX-K
+ * @parallel_ts:       True means that the device uses parallel TS,
+ *                     Serial otherwise.
+ * @dynamic_clk:       True means that the clock will be dynamically
+ *                     adjusted. Static clock otherwise.
+ * @enable_merr_cfg:   Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
+ * @single_master:     Device is on the single master mode
+ * @no_i2c_bridge:     Don't switch the I2C bridge to talk with tuner
+ * @antenna_gpio:      GPIO bit used to control the antenna
+ * @antenna_dvbt:      GPIO bit for changing antenna to DVB-C. A value of 1
+ *                     means that 1=DVBC, 0 = DVBT. Zero means the opposite.
+ * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
+ * @microcode_name:    Name of the firmware file with the microcode
+ * @qam_demod_parameter_count: The number of parameters used for the command
+ *                             to set the demodulator parameters. All
+ *                             firmwares are using the 2-parameter commmand.
+ *                             An exception is the "drxk_a3.mc" firmware,
+ *                             which uses the 4-parameter command.
+ *                             A value of 0 (default) or lower indicates that
+ *                             the correct number of parameters will be
+ *                             automatically detected.
+ *
+ * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
+ * UIO-3.
+ */
+struct drxk_config {
+       u8      adr;
+       bool    single_master;
+       bool    no_i2c_bridge;
+       bool    parallel_ts;
+       bool    dynamic_clk;
+       bool    enable_merr_cfg;
+
+       bool    antenna_dvbt;
+       u16     antenna_gpio;
+
+       u8      mpeg_out_clk_strength;
+       int     chunk_size;
+
+       const char      *microcode_name;
+       int              qam_demod_parameter_count;
+};
+
+#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
+        && defined(MODULE))
+extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
+                                       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
+                                       struct i2c_adapter *i2c)
+{
+        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+        return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
new file mode 100644 (file)
index 0000000..1ab8154
--- /dev/null
@@ -0,0 +1,6637 @@
+/*
+ * drxk_hard: DRX-K DVB-C/T demodulator driver
+ *
+ * Copyright (C) 2010-2011 Digital Devices GmbH
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/hardirq.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drxk.h"
+#include "drxk_hard.h"
+
+static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
+static int PowerDownQAM(struct drxk_state *state);
+static int SetDVBTStandard(struct drxk_state *state,
+                          enum OperationMode oMode);
+static int SetQAMStandard(struct drxk_state *state,
+                         enum OperationMode oMode);
+static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
+                 s32 tunerFreqOffset);
+static int SetDVBTStandard(struct drxk_state *state,
+                          enum OperationMode oMode);
+static int DVBTStart(struct drxk_state *state);
+static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
+                  s32 tunerFreqOffset);
+static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
+static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
+static int SwitchAntennaToQAM(struct drxk_state *state);
+static int SwitchAntennaToDVBT(struct drxk_state *state);
+
+static bool IsDVBT(struct drxk_state *state)
+{
+       return state->m_OperationMode == OM_DVBT;
+}
+
+static bool IsQAM(struct drxk_state *state)
+{
+       return state->m_OperationMode == OM_QAM_ITU_A ||
+           state->m_OperationMode == OM_QAM_ITU_B ||
+           state->m_OperationMode == OM_QAM_ITU_C;
+}
+
+bool IsA1WithPatchCode(struct drxk_state *state)
+{
+       return state->m_DRXK_A1_PATCH_CODE;
+}
+
+bool IsA1WithRomCode(struct drxk_state *state)
+{
+       return state->m_DRXK_A1_ROM_CODE;
+}
+
+#define NOA1ROM 0
+
+#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
+#define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
+
+#define DEFAULT_MER_83  165
+#define DEFAULT_MER_93  250
+
+#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
+#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
+#endif
+
+#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
+#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
+#endif
+
+#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
+#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
+
+#ifndef DRXK_KI_RAGC_ATV
+#define DRXK_KI_RAGC_ATV   4
+#endif
+#ifndef DRXK_KI_IAGC_ATV
+#define DRXK_KI_IAGC_ATV   6
+#endif
+#ifndef DRXK_KI_DAGC_ATV
+#define DRXK_KI_DAGC_ATV   7
+#endif
+
+#ifndef DRXK_KI_RAGC_QAM
+#define DRXK_KI_RAGC_QAM   3
+#endif
+#ifndef DRXK_KI_IAGC_QAM
+#define DRXK_KI_IAGC_QAM   4
+#endif
+#ifndef DRXK_KI_DAGC_QAM
+#define DRXK_KI_DAGC_QAM   7
+#endif
+#ifndef DRXK_KI_RAGC_DVBT
+#define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
+#endif
+#ifndef DRXK_KI_IAGC_DVBT
+#define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
+#endif
+#ifndef DRXK_KI_DAGC_DVBT
+#define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
+#endif
+
+#ifndef DRXK_AGC_DAC_OFFSET
+#define DRXK_AGC_DAC_OFFSET (0x800)
+#endif
+
+#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
+#define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
+#endif
+
+#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
+#define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
+#endif
+
+#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
+#define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
+#endif
+
+#ifndef DRXK_QAM_SYMBOLRATE_MAX
+#define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
+#endif
+
+#define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
+#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
+#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
+#define DRXK_BL_ROM_OFFSET_TAPS_BG      24
+#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
+#define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
+#define DRXK_BL_ROM_OFFSET_TAPS_FM      48
+#define DRXK_BL_ROM_OFFSET_UCODE        0
+
+#define DRXK_BLC_TIMEOUT                100
+
+#define DRXK_BLCC_NR_ELEMENTS_TAPS      2
+#define DRXK_BLCC_NR_ELEMENTS_UCODE     6
+
+#define DRXK_BLDC_NR_ELEMENTS_TAPS      28
+
+#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
+#define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
+#endif
+
+#define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
+#define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
+#define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
+#define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
+#define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+#define dprintk(level, fmt, arg...) do {                       \
+if (debug >= level)                                            \
+       printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg);    \
+} while (0)
+
+
+static inline u32 MulDiv32(u32 a, u32 b, u32 c)
+{
+       u64 tmp64;
+
+       tmp64 = (u64) a * (u64) b;
+       do_div(tmp64, c);
+
+       return (u32) tmp64;
+}
+
+inline u32 Frac28a(u32 a, u32 c)
+{
+       int i = 0;
+       u32 Q1 = 0;
+       u32 R0 = 0;
+
+       R0 = (a % c) << 4;      /* 32-28 == 4 shifts possible at max */
+       Q1 = a / c;             /* integer part, only the 4 least significant bits
+                                  will be visible in the result */
+
+       /* division using radix 16, 7 nibbles in the result */
+       for (i = 0; i < 7; i++) {
+               Q1 = (Q1 << 4) | (R0 / c);
+               R0 = (R0 % c) << 4;
+       }
+       /* rounding */
+       if ((R0 >> 3) >= c)
+               Q1++;
+
+       return Q1;
+}
+
+static u32 Log10Times100(u32 x)
+{
+       static const u8 scale = 15;
+       static const u8 indexWidth = 5;
+       u8 i = 0;
+       u32 y = 0;
+       u32 d = 0;
+       u32 k = 0;
+       u32 r = 0;
+       /*
+          log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
+          0 <= n < ((1<<INDEXWIDTH)+1)
+        */
+
+       static const u32 log2lut[] = {
+               0,              /* 0.000000 */
+               290941,         /* 290941.300628 */
+               573196,         /* 573196.476418 */
+               847269,         /* 847269.179851 */
+               1113620,        /* 1113620.489452 */
+               1372674,        /* 1372673.576986 */
+               1624818,        /* 1624817.752104 */
+               1870412,        /* 1870411.981536 */
+               2109788,        /* 2109787.962654 */
+               2343253,        /* 2343252.817465 */
+               2571091,        /* 2571091.461923 */
+               2793569,        /* 2793568.696416 */
+               3010931,        /* 3010931.055901 */
+               3223408,        /* 3223408.452106 */
+               3431216,        /* 3431215.635215 */
+               3634553,        /* 3634553.498355 */
+               3833610,        /* 3833610.244726 */
+               4028562,        /* 4028562.434393 */
+               4219576,        /* 4219575.925308 */
+               4406807,        /* 4406806.721144 */
+               4590402,        /* 4590401.736809 */
+               4770499,        /* 4770499.491025 */
+               4947231,        /* 4947230.734179 */
+               5120719,        /* 5120719.018555 */
+               5291081,        /* 5291081.217197 */
+               5458428,        /* 5458427.996830 */
+               5622864,        /* 5622864.249668 */
+               5784489,        /* 5784489.488298 */
+               5943398,        /* 5943398.207380 */
+               6099680,        /* 6099680.215452 */
+               6253421,        /* 6253420.939751 */
+               6404702,        /* 6404701.706649 */
+               6553600,        /* 6553600.000000 */
+       };
+
+
+       if (x == 0)
+               return 0;
+
+       /* Scale x (normalize) */
+       /* computing y in log(x/y) = log(x) - log(y) */
+       if ((x & ((0xffffffff) << (scale + 1))) == 0) {
+               for (k = scale; k > 0; k--) {
+                       if (x & (((u32) 1) << scale))
+                               break;
+                       x <<= 1;
+               }
+       } else {
+               for (k = scale; k < 31; k++) {
+                       if ((x & (((u32) (-1)) << (scale + 1))) == 0)
+                               break;
+                       x >>= 1;
+               }
+       }
+       /*
+          Now x has binary point between bit[scale] and bit[scale-1]
+          and 1.0 <= x < 2.0 */
+
+       /* correction for divison: log(x) = log(x/y)+log(y) */
+       y = k * ((((u32) 1) << scale) * 200);
+
+       /* remove integer part */
+       x &= ((((u32) 1) << scale) - 1);
+       /* get index */
+       i = (u8) (x >> (scale - indexWidth));
+       /* compute delta (x - a) */
+       d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
+       /* compute log, multiplication (d* (..)) must be within range ! */
+       y += log2lut[i] +
+           ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
+       /* Conver to log10() */
+       y /= 108853;            /* (log2(10) << scale) */
+       r = (y >> 1);
+       /* rounding */
+       if (y & ((u32) 1))
+               r++;
+       return r;
+}
+
+/****************************************************************************/
+/* I2C **********************************************************************/
+/****************************************************************************/
+
+static int drxk_i2c_lock(struct drxk_state *state)
+{
+       i2c_lock_adapter(state->i2c);
+       state->drxk_i2c_exclusive_lock = true;
+
+       return 0;
+}
+
+static void drxk_i2c_unlock(struct drxk_state *state)
+{
+       if (!state->drxk_i2c_exclusive_lock)
+               return;
+
+       i2c_unlock_adapter(state->i2c);
+       state->drxk_i2c_exclusive_lock = false;
+}
+
+static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
+                            unsigned len)
+{
+       if (state->drxk_i2c_exclusive_lock)
+               return __i2c_transfer(state->i2c, msgs, len);
+       else
+               return i2c_transfer(state->i2c, msgs, len);
+}
+
+static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
+{
+       struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
+                                   .buf = val, .len = 1}
+       };
+
+       return drxk_i2c_transfer(state, msgs, 1);
+}
+
+static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
+{
+       int status;
+       struct i2c_msg msg = {
+           .addr = adr, .flags = 0, .buf = data, .len = len };
+
+       dprintk(3, ":");
+       if (debug > 2) {
+               int i;
+               for (i = 0; i < len; i++)
+                       printk(KERN_CONT " %02x", data[i]);
+               printk(KERN_CONT "\n");
+       }
+       status = drxk_i2c_transfer(state, &msg, 1);
+       if (status >= 0 && status != 1)
+               status = -EIO;
+
+       if (status < 0)
+               printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
+
+       return status;
+}
+
+static int i2c_read(struct drxk_state *state,
+                   u8 adr, u8 *msg, int len, u8 *answ, int alen)
+{
+       int status;
+       struct i2c_msg msgs[2] = {
+               {.addr = adr, .flags = 0,
+                                   .buf = msg, .len = len},
+               {.addr = adr, .flags = I2C_M_RD,
+                .buf = answ, .len = alen}
+       };
+
+       status = drxk_i2c_transfer(state, msgs, 2);
+       if (status != 2) {
+               if (debug > 2)
+                       printk(KERN_CONT ": ERROR!\n");
+               if (status >= 0)
+                       status = -EIO;
+
+               printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
+               return status;
+       }
+       if (debug > 2) {
+               int i;
+               dprintk(2, ": read from");
+               for (i = 0; i < len; i++)
+                       printk(KERN_CONT " %02x", msg[i]);
+               printk(KERN_CONT ", value = ");
+               for (i = 0; i < alen; i++)
+                       printk(KERN_CONT " %02x", answ[i]);
+               printk(KERN_CONT "\n");
+       }
+       return 0;
+}
+
+static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
+{
+       int status;
+       u8 adr = state->demod_address, mm1[4], mm2[2], len;
+
+       if (state->single_master)
+               flags |= 0xC0;
+
+       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
+               mm1[0] = (((reg << 1) & 0xFF) | 0x01);
+               mm1[1] = ((reg >> 16) & 0xFF);
+               mm1[2] = ((reg >> 24) & 0xFF) | flags;
+               mm1[3] = ((reg >> 7) & 0xFF);
+               len = 4;
+       } else {
+               mm1[0] = ((reg << 1) & 0xFF);
+               mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
+               len = 2;
+       }
+       dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
+       status = i2c_read(state, adr, mm1, len, mm2, 2);
+       if (status < 0)
+               return status;
+       if (data)
+               *data = mm2[0] | (mm2[1] << 8);
+
+       return 0;
+}
+
+static int read16(struct drxk_state *state, u32 reg, u16 *data)
+{
+       return read16_flags(state, reg, data, 0);
+}
+
+static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
+{
+       int status;
+       u8 adr = state->demod_address, mm1[4], mm2[4], len;
+
+       if (state->single_master)
+               flags |= 0xC0;
+
+       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
+               mm1[0] = (((reg << 1) & 0xFF) | 0x01);
+               mm1[1] = ((reg >> 16) & 0xFF);
+               mm1[2] = ((reg >> 24) & 0xFF) | flags;
+               mm1[3] = ((reg >> 7) & 0xFF);
+               len = 4;
+       } else {
+               mm1[0] = ((reg << 1) & 0xFF);
+               mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
+               len = 2;
+       }
+       dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
+       status = i2c_read(state, adr, mm1, len, mm2, 4);
+       if (status < 0)
+               return status;
+       if (data)
+               *data = mm2[0] | (mm2[1] << 8) |
+                   (mm2[2] << 16) | (mm2[3] << 24);
+
+       return 0;
+}
+
+static int read32(struct drxk_state *state, u32 reg, u32 *data)
+{
+       return read32_flags(state, reg, data, 0);
+}
+
+static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
+{
+       u8 adr = state->demod_address, mm[6], len;
+
+       if (state->single_master)
+               flags |= 0xC0;
+       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
+               mm[0] = (((reg << 1) & 0xFF) | 0x01);
+               mm[1] = ((reg >> 16) & 0xFF);
+               mm[2] = ((reg >> 24) & 0xFF) | flags;
+               mm[3] = ((reg >> 7) & 0xFF);
+               len = 4;
+       } else {
+               mm[0] = ((reg << 1) & 0xFF);
+               mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
+               len = 2;
+       }
+       mm[len] = data & 0xff;
+       mm[len + 1] = (data >> 8) & 0xff;
+
+       dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
+       return i2c_write(state, adr, mm, len + 2);
+}
+
+static int write16(struct drxk_state *state, u32 reg, u16 data)
+{
+       return write16_flags(state, reg, data, 0);
+}
+
+static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
+{
+       u8 adr = state->demod_address, mm[8], len;
+
+       if (state->single_master)
+               flags |= 0xC0;
+       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
+               mm[0] = (((reg << 1) & 0xFF) | 0x01);
+               mm[1] = ((reg >> 16) & 0xFF);
+               mm[2] = ((reg >> 24) & 0xFF) | flags;
+               mm[3] = ((reg >> 7) & 0xFF);
+               len = 4;
+       } else {
+               mm[0] = ((reg << 1) & 0xFF);
+               mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
+               len = 2;
+       }
+       mm[len] = data & 0xff;
+       mm[len + 1] = (data >> 8) & 0xff;
+       mm[len + 2] = (data >> 16) & 0xff;
+       mm[len + 3] = (data >> 24) & 0xff;
+       dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
+
+       return i2c_write(state, adr, mm, len + 4);
+}
+
+static int write32(struct drxk_state *state, u32 reg, u32 data)
+{
+       return write32_flags(state, reg, data, 0);
+}
+
+static int write_block(struct drxk_state *state, u32 Address,
+                     const int BlockSize, const u8 pBlock[])
+{
+       int status = 0, BlkSize = BlockSize;
+       u8 Flags = 0;
+
+       if (state->single_master)
+               Flags |= 0xC0;
+
+       while (BlkSize > 0) {
+               int Chunk = BlkSize > state->m_ChunkSize ?
+                   state->m_ChunkSize : BlkSize;
+               u8 *AdrBuf = &state->Chunk[0];
+               u32 AdrLength = 0;
+
+               if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
+                       AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
+                       AdrBuf[1] = ((Address >> 16) & 0xFF);
+                       AdrBuf[2] = ((Address >> 24) & 0xFF);
+                       AdrBuf[3] = ((Address >> 7) & 0xFF);
+                       AdrBuf[2] |= Flags;
+                       AdrLength = 4;
+                       if (Chunk == state->m_ChunkSize)
+                               Chunk -= 2;
+               } else {
+                       AdrBuf[0] = ((Address << 1) & 0xFF);
+                       AdrBuf[1] = (((Address >> 16) & 0x0F) |
+                                    ((Address >> 18) & 0xF0));
+                       AdrLength = 2;
+               }
+               memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
+               dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
+               if (debug > 1) {
+                       int i;
+                       if (pBlock)
+                               for (i = 0; i < Chunk; i++)
+                                       printk(KERN_CONT " %02x", pBlock[i]);
+                       printk(KERN_CONT "\n");
+               }
+               status = i2c_write(state, state->demod_address,
+                                  &state->Chunk[0], Chunk + AdrLength);
+               if (status < 0) {
+                       printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
+                              __func__, Address);
+                       break;
+               }
+               pBlock += Chunk;
+               Address += (Chunk >> 1);
+               BlkSize -= Chunk;
+       }
+       return status;
+}
+
+#ifndef DRXK_MAX_RETRIES_POWERUP
+#define DRXK_MAX_RETRIES_POWERUP 20
+#endif
+
+int PowerUpDevice(struct drxk_state *state)
+{
+       int status;
+       u8 data = 0;
+       u16 retryCount = 0;
+
+       dprintk(1, "\n");
+
+       status = i2c_read1(state, state->demod_address, &data);
+       if (status < 0) {
+               do {
+                       data = 0;
+                       status = i2c_write(state, state->demod_address,
+                                          &data, 1);
+                       msleep(10);
+                       retryCount++;
+                       if (status < 0)
+                               continue;
+                       status = i2c_read1(state, state->demod_address,
+                                          &data);
+               } while (status < 0 &&
+                        (retryCount < DRXK_MAX_RETRIES_POWERUP));
+               if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
+                       goto error;
+       }
+
+       /* Make sure all clk domains are active */
+       status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
+       if (status < 0)
+               goto error;
+       /* Enable pll lock tests */
+       status = write16(state, SIO_CC_PLL_LOCK__A, 1);
+       if (status < 0)
+               goto error;
+
+       state->m_currentPowerMode = DRX_POWER_UP;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+
+static int init_state(struct drxk_state *state)
+{
+       /*
+        * FIXME: most (all?) of the values bellow should be moved into
+        * struct drxk_config, as they are probably board-specific
+        */
+       u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
+       u32 ulVSBIfAgcOutputLevel = 0;
+       u32 ulVSBIfAgcMinLevel = 0;
+       u32 ulVSBIfAgcMaxLevel = 0x7FFF;
+       u32 ulVSBIfAgcSpeed = 3;
+
+       u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
+       u32 ulVSBRfAgcOutputLevel = 0;
+       u32 ulVSBRfAgcMinLevel = 0;
+       u32 ulVSBRfAgcMaxLevel = 0x7FFF;
+       u32 ulVSBRfAgcSpeed = 3;
+       u32 ulVSBRfAgcTop = 9500;
+       u32 ulVSBRfAgcCutOffCurrent = 4000;
+
+       u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
+       u32 ulATVIfAgcOutputLevel = 0;
+       u32 ulATVIfAgcMinLevel = 0;
+       u32 ulATVIfAgcMaxLevel = 0;
+       u32 ulATVIfAgcSpeed = 3;
+
+       u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
+       u32 ulATVRfAgcOutputLevel = 0;
+       u32 ulATVRfAgcMinLevel = 0;
+       u32 ulATVRfAgcMaxLevel = 0;
+       u32 ulATVRfAgcTop = 9500;
+       u32 ulATVRfAgcCutOffCurrent = 4000;
+       u32 ulATVRfAgcSpeed = 3;
+
+       u32 ulQual83 = DEFAULT_MER_83;
+       u32 ulQual93 = DEFAULT_MER_93;
+
+       u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+       u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+
+       /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
+       /* io_pad_cfg_mode output mode is drive always */
+       /* io_pad_cfg_drive is set to power 2 (23 mA) */
+       u32 ulGPIOCfg = 0x0113;
+       u32 ulInvertTSClock = 0;
+       u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
+       u32 ulDVBTBitrate = 50000000;
+       u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
+
+       u32 ulInsertRSByte = 0;
+
+       u32 ulRfMirror = 1;
+       u32 ulPowerDown = 0;
+
+       dprintk(1, "\n");
+
+       state->m_hasLNA = false;
+       state->m_hasDVBT = false;
+       state->m_hasDVBC = false;
+       state->m_hasATV = false;
+       state->m_hasOOB = false;
+       state->m_hasAudio = false;
+
+       if (!state->m_ChunkSize)
+               state->m_ChunkSize = 124;
+
+       state->m_oscClockFreq = 0;
+       state->m_smartAntInverted = false;
+       state->m_bPDownOpenBridge = false;
+
+       /* real system clock frequency in kHz */
+       state->m_sysClockFreq = 151875;
+       /* Timing div, 250ns/Psys */
+       /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
+       state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
+                                  HI_I2C_DELAY) / 1000;
+       /* Clipping */
+       if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
+               state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
+       state->m_HICfgWakeUpKey = (state->demod_address << 1);
+       /* port/bridge/power down ctrl */
+       state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+
+       state->m_bPowerDown = (ulPowerDown != 0);
+
+       state->m_DRXK_A1_PATCH_CODE = false;
+       state->m_DRXK_A1_ROM_CODE = false;
+       state->m_DRXK_A2_ROM_CODE = false;
+       state->m_DRXK_A3_ROM_CODE = false;
+       state->m_DRXK_A2_PATCH_CODE = false;
+       state->m_DRXK_A3_PATCH_CODE = false;
+
+       /* Init AGC and PGA parameters */
+       /* VSB IF */
+       state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
+       state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
+       state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
+       state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
+       state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
+       state->m_vsbPgaCfg = 140;
+
+       /* VSB RF */
+       state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
+       state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
+       state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
+       state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
+       state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
+       state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
+       state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
+       state->m_vsbPreSawCfg.reference = 0x07;
+       state->m_vsbPreSawCfg.usePreSaw = true;
+
+       state->m_Quality83percent = DEFAULT_MER_83;
+       state->m_Quality93percent = DEFAULT_MER_93;
+       if (ulQual93 <= 500 && ulQual83 < ulQual93) {
+               state->m_Quality83percent = ulQual83;
+               state->m_Quality93percent = ulQual93;
+       }
+
+       /* ATV IF */
+       state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
+       state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
+       state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
+       state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
+       state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
+
+       /* ATV RF */
+       state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
+       state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
+       state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
+       state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
+       state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
+       state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
+       state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
+       state->m_atvPreSawCfg.reference = 0x04;
+       state->m_atvPreSawCfg.usePreSaw = true;
+
+
+       /* DVBT RF */
+       state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
+       state->m_dvbtRfAgcCfg.outputLevel = 0;
+       state->m_dvbtRfAgcCfg.minOutputLevel = 0;
+       state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
+       state->m_dvbtRfAgcCfg.top = 0x2100;
+       state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
+       state->m_dvbtRfAgcCfg.speed = 1;
+
+
+       /* DVBT IF */
+       state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
+       state->m_dvbtIfAgcCfg.outputLevel = 0;
+       state->m_dvbtIfAgcCfg.minOutputLevel = 0;
+       state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
+       state->m_dvbtIfAgcCfg.top = 13424;
+       state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
+       state->m_dvbtIfAgcCfg.speed = 3;
+       state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
+       state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
+       /* state->m_dvbtPgaCfg = 140; */
+
+       state->m_dvbtPreSawCfg.reference = 4;
+       state->m_dvbtPreSawCfg.usePreSaw = false;
+
+       /* QAM RF */
+       state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
+       state->m_qamRfAgcCfg.outputLevel = 0;
+       state->m_qamRfAgcCfg.minOutputLevel = 6023;
+       state->m_qamRfAgcCfg.maxOutputLevel = 27000;
+       state->m_qamRfAgcCfg.top = 0x2380;
+       state->m_qamRfAgcCfg.cutOffCurrent = 4000;
+       state->m_qamRfAgcCfg.speed = 3;
+
+       /* QAM IF */
+       state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
+       state->m_qamIfAgcCfg.outputLevel = 0;
+       state->m_qamIfAgcCfg.minOutputLevel = 0;
+       state->m_qamIfAgcCfg.maxOutputLevel = 9000;
+       state->m_qamIfAgcCfg.top = 0x0511;
+       state->m_qamIfAgcCfg.cutOffCurrent = 0;
+       state->m_qamIfAgcCfg.speed = 3;
+       state->m_qamIfAgcCfg.IngainTgtMax = 5119;
+       state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
+
+       state->m_qamPgaCfg = 140;
+       state->m_qamPreSawCfg.reference = 4;
+       state->m_qamPreSawCfg.usePreSaw = false;
+
+       state->m_OperationMode = OM_NONE;
+       state->m_DrxkState = DRXK_UNINITIALIZED;
+
+       /* MPEG output configuration */
+       state->m_enableMPEGOutput = true;       /* If TRUE; enable MPEG ouput */
+       state->m_insertRSByte = false;  /* If TRUE; insert RS byte */
+       state->m_invertDATA = false;    /* If TRUE; invert DATA signals */
+       state->m_invertERR = false;     /* If TRUE; invert ERR signal */
+       state->m_invertSTR = false;     /* If TRUE; invert STR signals */
+       state->m_invertVAL = false;     /* If TRUE; invert VAL signals */
+       state->m_invertCLK = (ulInvertTSClock != 0);    /* If TRUE; invert CLK signals */
+
+       /* If TRUE; static MPEG clockrate will be used;
+          otherwise clockrate will adapt to the bitrate of the TS */
+
+       state->m_DVBTBitrate = ulDVBTBitrate;
+       state->m_DVBCBitrate = ulDVBCBitrate;
+
+       state->m_TSDataStrength = (ulTSDataStrength & 0x07);
+
+       /* Maximum bitrate in b/s in case static clockrate is selected */
+       state->m_mpegTsStaticBitrate = 19392658;
+       state->m_disableTEIhandling = false;
+
+       if (ulInsertRSByte)
+               state->m_insertRSByte = true;
+
+       state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+       if (ulMpegLockTimeOut < 10000)
+               state->m_MpegLockTimeOut = ulMpegLockTimeOut;
+       state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+       if (ulDemodLockTimeOut < 10000)
+               state->m_DemodLockTimeOut = ulDemodLockTimeOut;
+
+       /* QAM defaults */
+       state->m_Constellation = DRX_CONSTELLATION_AUTO;
+       state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
+       state->m_fecRsPlen = 204 * 8;   /* fecRsPlen  annex A */
+       state->m_fecRsPrescale = 1;
+
+       state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
+       state->m_agcFastClipCtrlDelay = 0;
+
+       state->m_GPIOCfg = (ulGPIOCfg);
+
+       state->m_bPowerDown = false;
+       state->m_currentPowerMode = DRX_POWER_DOWN;
+
+       state->m_rfmirror = (ulRfMirror == 0);
+       state->m_IfAgcPol = false;
+       return 0;
+}
+
+static int DRXX_Open(struct drxk_state *state)
+{
+       int status = 0;
+       u32 jtag = 0;
+       u16 bid = 0;
+       u16 key = 0;
+
+       dprintk(1, "\n");
+       /* stop lock indicator process */
+       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+       if (status < 0)
+               goto error;
+       /* Check device id */
+       status = read16(state, SIO_TOP_COMM_KEY__A, &key);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
+       if (status < 0)
+               goto error;
+       status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
+       if (status < 0)
+               goto error;
+       status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_TOP_COMM_KEY__A, key);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int GetDeviceCapabilities(struct drxk_state *state)
+{
+       u16 sioPdrOhwCfg = 0;
+       u32 sioTopJtagidLo = 0;
+       int status;
+       const char *spin = "";
+
+       dprintk(1, "\n");
+
+       /* driver 0.9.0 */
+       /* stop lock indicator process */
+       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
+       if (status < 0)
+               goto error;
+       status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
+       if (status < 0)
+               goto error;
+
+       switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
+       case 0:
+               /* ignore (bypass ?) */
+               break;
+       case 1:
+               /* 27 MHz */
+               state->m_oscClockFreq = 27000;
+               break;
+       case 2:
+               /* 20.25 MHz */
+               state->m_oscClockFreq = 20250;
+               break;
+       case 3:
+               /* 4 MHz */
+               state->m_oscClockFreq = 20250;
+               break;
+       default:
+               printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
+               return -EINVAL;
+       }
+       /*
+               Determine device capabilities
+               Based on pinning v14
+               */
+       status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
+       if (status < 0)
+               goto error;
+
+       printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
+
+       /* driver 0.9.0 */
+       switch ((sioTopJtagidLo >> 29) & 0xF) {
+       case 0:
+               state->m_deviceSpin = DRXK_SPIN_A1;
+               spin = "A1";
+               break;
+       case 2:
+               state->m_deviceSpin = DRXK_SPIN_A2;
+               spin = "A2";
+               break;
+       case 3:
+               state->m_deviceSpin = DRXK_SPIN_A3;
+               spin = "A3";
+               break;
+       default:
+               state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
+               status = -EINVAL;
+               printk(KERN_ERR "drxk: Spin %d unknown\n",
+                      (sioTopJtagidLo >> 29) & 0xF);
+               goto error2;
+       }
+       switch ((sioTopJtagidLo >> 12) & 0xFF) {
+       case 0x13:
+               /* typeId = DRX3913K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = false;
+               state->m_hasAudio = false;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = true;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = false;
+               state->m_hasGPIO1 = false;
+               state->m_hasIRQN = false;
+               break;
+       case 0x15:
+               /* typeId = DRX3915K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = false;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = false;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x16:
+               /* typeId = DRX3916K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = false;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = false;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x18:
+               /* typeId = DRX3918K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = true;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = false;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x21:
+               /* typeId = DRX3921K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = true;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = true;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x23:
+               /* typeId = DRX3923K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = true;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = true;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x25:
+               /* typeId = DRX3925K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = true;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = true;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       case 0x26:
+               /* typeId = DRX3926K_TYPE_ID */
+               state->m_hasLNA = false;
+               state->m_hasOOB = false;
+               state->m_hasATV = true;
+               state->m_hasAudio = false;
+               state->m_hasDVBT = true;
+               state->m_hasDVBC = true;
+               state->m_hasSAWSW = true;
+               state->m_hasGPIO2 = true;
+               state->m_hasGPIO1 = true;
+               state->m_hasIRQN = false;
+               break;
+       default:
+               printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
+                       ((sioTopJtagidLo >> 12) & 0xFF));
+               status = -EINVAL;
+               goto error2;
+       }
+
+       printk(KERN_INFO
+              "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
+              ((sioTopJtagidLo >> 12) & 0xFF), spin,
+              state->m_oscClockFreq / 1000,
+              state->m_oscClockFreq % 1000);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+error2:
+       return status;
+}
+
+static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
+{
+       int status;
+       bool powerdown_cmd;
+
+       dprintk(1, "\n");
+
+       /* Write command */
+       status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
+       if (status < 0)
+               goto error;
+       if (cmd == SIO_HI_RA_RAM_CMD_RESET)
+               msleep(1);
+
+       powerdown_cmd =
+           (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
+                   ((state->m_HICfgCtrl) &
+                    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
+                   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
+       if (powerdown_cmd == false) {
+               /* Wait until command rdy */
+               u32 retryCount = 0;
+               u16 waitCmd;
+
+               do {
+                       msleep(1);
+                       retryCount += 1;
+                       status = read16(state, SIO_HI_RA_RAM_CMD__A,
+                                         &waitCmd);
+               } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
+                        && (waitCmd != 0));
+               if (status < 0)
+                       goto error;
+               status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int HI_CfgCommand(struct drxk_state *state)
+{
+       int status;
+
+       dprintk(1, "\n");
+
+       mutex_lock(&state->mutex);
+
+       status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+       if (status < 0)
+               goto error;
+       status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
+       if (status < 0)
+               goto error;
+
+       state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+error:
+       mutex_unlock(&state->mutex);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int InitHI(struct drxk_state *state)
+{
+       dprintk(1, "\n");
+
+       state->m_HICfgWakeUpKey = (state->demod_address << 1);
+       state->m_HICfgTimeout = 0x96FF;
+       /* port/bridge/power down ctrl */
+       state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+
+       return HI_CfgCommand(state);
+}
+
+static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
+{
+       int status = -1;
+       u16 sioPdrMclkCfg = 0;
+       u16 sioPdrMdxCfg = 0;
+       u16 err_cfg = 0;
+
+       dprintk(1, ": mpeg %s, %s mode\n",
+               mpegEnable ? "enable" : "disable",
+               state->m_enableParallel ? "parallel" : "serial");
+
+       /* stop lock indicator process */
+       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+       if (status < 0)
+               goto error;
+
+       /*  MPEG TS pad configuration */
+       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
+       if (status < 0)
+               goto error;
+
+       if (mpegEnable == false) {
+               /*  Set MPEG TS pads to inputmode */
+               status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
+               if (status < 0)
+                       goto error;
+       } else {
+               /* Enable MPEG output */
+               sioPdrMdxCfg =
+                       ((state->m_TSDataStrength <<
+                       SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
+               sioPdrMclkCfg = ((state->m_TSClockkStrength <<
+                                       SIO_PDR_MCLK_CFG_DRIVE__B) |
+                                       0x0003);
+
+               status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
+               if (status < 0)
+                       goto error;
+
+               if (state->enable_merr_cfg)
+                       err_cfg = sioPdrMdxCfg;
+
+               status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
+               if (status < 0)
+                       goto error;
+
+               if (state->m_enableParallel == true) {
+                       /* paralel -> enable MD1 to MD7 */
+                       status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
+                       if (status < 0)
+                               goto error;
+               } else {
+                       sioPdrMdxCfg = ((state->m_TSDataStrength <<
+                                               SIO_PDR_MD0_CFG_DRIVE__B)
+                                       | 0x0003);
+                       /* serial -> disable MD1 to MD7 */
+                       status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+                       status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
+                       if (status < 0)
+                               goto error;
+               }
+               status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
+               if (status < 0)
+                       goto error;
+       }
+       /*  Enable MB output over MPEG pads and ctl input */
+       status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
+       if (status < 0)
+               goto error;
+       /*  Write nomagic word to enable pdr reg write */
+       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int MPEGTSDisable(struct drxk_state *state)
+{
+       dprintk(1, "\n");
+
+       return MPEGTSConfigurePins(state, false);
+}
+
+static int BLChainCmd(struct drxk_state *state,
+                     u16 romOffset, u16 nrOfElements, u32 timeOut)
+{
+       u16 blStatus = 0;
+       int status;
+       unsigned long end;
+
+       dprintk(1, "\n");
+       mutex_lock(&state->mutex);
+       status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
+       if (status < 0)
+               goto error;
+
+       end = jiffies + msecs_to_jiffies(timeOut);
+       do {
+               msleep(1);
+               status = read16(state, SIO_BL_STATUS__A, &blStatus);
+               if (status < 0)
+                       goto error;
+       } while ((blStatus == 0x1) &&
+                       ((time_is_after_jiffies(end))));
+
+       if (blStatus == 0x1) {
+               printk(KERN_ERR "drxk: SIO not ready\n");
+               status = -EINVAL;
+               goto error2;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+error2:
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+
+static int DownloadMicrocode(struct drxk_state *state,
+                            const u8 pMCImage[], u32 Length)
+{
+       const u8 *pSrc = pMCImage;
+       u32 Address;
+       u16 nBlocks;
+       u16 BlockSize;
+       u32 offset = 0;
+       u32 i;
+       int status = 0;
+
+       dprintk(1, "\n");
+
+       /* down the drain (we don't care about MAGIC_WORD) */
+#if 0
+       /* For future reference */
+       Drain = (pSrc[0] << 8) | pSrc[1];
+#endif
+       pSrc += sizeof(u16);
+       offset += sizeof(u16);
+       nBlocks = (pSrc[0] << 8) | pSrc[1];
+       pSrc += sizeof(u16);
+       offset += sizeof(u16);
+
+       for (i = 0; i < nBlocks; i += 1) {
+               Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
+                   (pSrc[2] << 8) | pSrc[3];
+               pSrc += sizeof(u32);
+               offset += sizeof(u32);
+
+               BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+#if 0
+               /* For future reference */
+               Flags = (pSrc[0] << 8) | pSrc[1];
+#endif
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+#if 0
+               /* For future reference */
+               BlockCRC = (pSrc[0] << 8) | pSrc[1];
+#endif
+               pSrc += sizeof(u16);
+               offset += sizeof(u16);
+
+               if (offset + BlockSize > Length) {
+                       printk(KERN_ERR "drxk: Firmware is corrupted.\n");
+                       return -EINVAL;
+               }
+
+               status = write_block(state, Address, BlockSize, pSrc);
+               if (status < 0) {
+                       printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
+                       break;
+               }
+               pSrc += BlockSize;
+               offset += BlockSize;
+       }
+       return status;
+}
+
+static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
+{
+       int status;
+       u16 data = 0;
+       u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
+       u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
+       unsigned long end;
+
+       dprintk(1, "\n");
+
+       if (enable == false) {
+               desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
+               desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
+       }
+
+       status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
+       if (status >= 0 && data == desiredStatus) {
+               /* tokenring already has correct status */
+               return status;
+       }
+       /* Disable/enable dvbt tokenring bridge   */
+       status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
+
+       end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
+       do {
+               status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
+               if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
+                       break;
+               msleep(1);
+       } while (1);
+       if (data != desiredStatus) {
+               printk(KERN_ERR "drxk: SIO not ready\n");
+               return -EINVAL;
+       }
+       return status;
+}
+
+static int MPEGTSStop(struct drxk_state *state)
+{
+       int status = 0;
+       u16 fecOcSncMode = 0;
+       u16 fecOcIprMode = 0;
+
+       dprintk(1, "\n");
+
+       /* Gracefull shutdown (byte boundaries) */
+       status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+       if (status < 0)
+               goto error;
+       fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
+       status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+       if (status < 0)
+               goto error;
+
+       /* Suppress MCLK during absence of data */
+       status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
+       if (status < 0)
+               goto error;
+       fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
+       status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int scu_command(struct drxk_state *state,
+                      u16 cmd, u8 parameterLen,
+                      u16 *parameter, u8 resultLen, u16 *result)
+{
+#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
+#error DRXK register mapping no longer compatible with this routine!
+#endif
+       u16 curCmd = 0;
+       int status = -EINVAL;
+       unsigned long end;
+       u8 buffer[34];
+       int cnt = 0, ii;
+       const char *p;
+       char errname[30];
+
+       dprintk(1, "\n");
+
+       if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
+           ((resultLen > 0) && (result == NULL))) {
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+               return status;
+       }
+
+       mutex_lock(&state->mutex);
+
+       /* assume that the command register is ready
+               since it is checked afterwards */
+       for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
+               buffer[cnt++] = (parameter[ii] & 0xFF);
+               buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
+       }
+       buffer[cnt++] = (cmd & 0xFF);
+       buffer[cnt++] = ((cmd >> 8) & 0xFF);
+
+       write_block(state, SCU_RAM_PARAM_0__A -
+                       (parameterLen - 1), cnt, buffer);
+       /* Wait until SCU has processed command */
+       end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
+       do {
+               msleep(1);
+               status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
+               if (status < 0)
+                       goto error;
+       } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
+       if (curCmd != DRX_SCU_READY) {
+               printk(KERN_ERR "drxk: SCU not ready\n");
+               status = -EIO;
+               goto error2;
+       }
+       /* read results */
+       if ((resultLen > 0) && (result != NULL)) {
+               s16 err;
+               int ii;
+
+               for (ii = resultLen - 1; ii >= 0; ii -= 1) {
+                       status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
+                       if (status < 0)
+                               goto error;
+               }
+
+               /* Check if an error was reported by SCU */
+               err = (s16)result[0];
+               if (err >= 0)
+                       goto error;
+
+               /* check for the known error codes */
+               switch (err) {
+               case SCU_RESULT_UNKCMD:
+                       p = "SCU_RESULT_UNKCMD";
+                       break;
+               case SCU_RESULT_UNKSTD:
+                       p = "SCU_RESULT_UNKSTD";
+                       break;
+               case SCU_RESULT_SIZE:
+                       p = "SCU_RESULT_SIZE";
+                       break;
+               case SCU_RESULT_INVPAR:
+                       p = "SCU_RESULT_INVPAR";
+                       break;
+               default: /* Other negative values are errors */
+                       sprintf(errname, "ERROR: %d\n", err);
+                       p = errname;
+               }
+               printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
+               print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
+               status = -EINVAL;
+               goto error2;
+       }
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+error2:
+       mutex_unlock(&state->mutex);
+       return status;
+}
+
+static int SetIqmAf(struct drxk_state *state, bool active)
+{
+       u16 data = 0;
+       int status;
+
+       dprintk(1, "\n");
+
+       /* Configure IQM */
+       status = read16(state, IQM_AF_STDBY__A, &data);
+       if (status < 0)
+               goto error;
+
+       if (!active) {
+               data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
+                               | IQM_AF_STDBY_STDBY_AMP_STANDBY
+                               | IQM_AF_STDBY_STDBY_PD_STANDBY
+                               | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
+                               | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
+       } else {
+               data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
+                               & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
+                               & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
+                               & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
+                               & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
+                       );
+       }
+       status = write16(state, IQM_AF_STDBY__A, data);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
+{
+       int status = 0;
+       u16 sioCcPwdMode = 0;
+
+       dprintk(1, "\n");
+
+       /* Check arguments */
+       if (mode == NULL)
+               return -EINVAL;
+
+       switch (*mode) {
+       case DRX_POWER_UP:
+               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
+               break;
+       case DRXK_POWER_DOWN_OFDM:
+               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
+               break;
+       case DRXK_POWER_DOWN_CORE:
+               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
+               break;
+       case DRXK_POWER_DOWN_PLL:
+               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
+               break;
+       case DRX_POWER_DOWN:
+               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
+               break;
+       default:
+               /* Unknow sleep mode */
+               return -EINVAL;
+       }
+
+       /* If already in requested power mode, do nothing */
+       if (state->m_currentPowerMode == *mode)
+               return 0;
+
+       /* For next steps make sure to start from DRX_POWER_UP mode */
+       if (state->m_currentPowerMode != DRX_POWER_UP) {
+               status = PowerUpDevice(state);
+               if (status < 0)
+                       goto error;
+               status = DVBTEnableOFDMTokenRing(state, true);
+               if (status < 0)
+                       goto error;
+       }
+
+       if (*mode == DRX_POWER_UP) {
+               /* Restore analog & pin configuartion */
+       } else {
+               /* Power down to requested mode */
+               /* Backup some register settings */
+               /* Set pins with possible pull-ups connected
+                  to them in input mode */
+               /* Analog power down */
+               /* ADC power down */
+               /* Power down device */
+               /* stop all comm_exec */
+               /* Stop and power down previous standard */
+               switch (state->m_OperationMode) {
+               case OM_DVBT:
+                       status = MPEGTSStop(state);
+                       if (status < 0)
+                               goto error;
+                       status = PowerDownDVBT(state, false);
+                       if (status < 0)
+                               goto error;
+                       break;
+               case OM_QAM_ITU_A:
+               case OM_QAM_ITU_C:
+                       status = MPEGTSStop(state);
+                       if (status < 0)
+                               goto error;
+                       status = PowerDownQAM(state);
+                       if (status < 0)
+                               goto error;
+                       break;
+               default:
+                       break;
+               }
+               status = DVBTEnableOFDMTokenRing(state, false);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
+               if (status < 0)
+                       goto error;
+
+               if (*mode != DRXK_POWER_DOWN_OFDM) {
+                       state->m_HICfgCtrl |=
+                               SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+                       status = HI_CfgCommand(state);
+                       if (status < 0)
+                               goto error;
+               }
+       }
+       state->m_currentPowerMode = *mode;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
+{
+       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+       u16 cmdResult = 0;
+       u16 data = 0;
+       int status;
+
+       dprintk(1, "\n");
+
+       status = read16(state, SCU_COMM_EXEC__A, &data);
+       if (status < 0)
+               goto error;
+       if (data == SCU_COMM_EXEC_ACTIVE) {
+               /* Send OFDM stop command */
+               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+               if (status < 0)
+                       goto error;
+               /* Send OFDM reset command */
+               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+               if (status < 0)
+                       goto error;
+       }
+
+       /* Reset datapath for OFDM, processors first */
+       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
+       if (status < 0)
+               goto error;
+
+       /* powerdown AFE                   */
+       status = SetIqmAf(state, false);
+       if (status < 0)
+               goto error;
+
+       /* powerdown to OFDM mode          */
+       if (setPowerMode) {
+               status = CtrlPowerMode(state, &powerMode);
+               if (status < 0)
+                       goto error;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SetOperationMode(struct drxk_state *state,
+                           enum OperationMode oMode)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+       /*
+          Stop and power down previous standard
+          TODO investigate total power down instead of partial
+          power down depending on "previous" standard.
+        */
+
+       /* disable HW lock indicator */
+       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+       if (status < 0)
+               goto error;
+
+       /* Device is already at the required mode */
+       if (state->m_OperationMode == oMode)
+               return 0;
+
+       switch (state->m_OperationMode) {
+               /* OM_NONE was added for start up */
+       case OM_NONE:
+               break;
+       case OM_DVBT:
+               status = MPEGTSStop(state);
+               if (status < 0)
+                       goto error;
+               status = PowerDownDVBT(state, true);
+               if (status < 0)
+                       goto error;
+               state->m_OperationMode = OM_NONE;
+               break;
+       case OM_QAM_ITU_A:      /* fallthrough */
+       case OM_QAM_ITU_C:
+               status = MPEGTSStop(state);
+               if (status < 0)
+                       goto error;
+               status = PowerDownQAM(state);
+               if (status < 0)
+                       goto error;
+               state->m_OperationMode = OM_NONE;
+               break;
+       case OM_QAM_ITU_B:
+       default:
+               status = -EINVAL;
+               goto error;
+       }
+
+       /*
+               Power up new standard
+               */
+       switch (oMode) {
+       case OM_DVBT:
+               dprintk(1, ": DVB-T\n");
+               state->m_OperationMode = oMode;
+               status = SetDVBTStandard(state, oMode);
+               if (status < 0)
+                       goto error;
+               break;
+       case OM_QAM_ITU_A:      /* fallthrough */
+       case OM_QAM_ITU_C:
+               dprintk(1, ": DVB-C Annex %c\n",
+                       (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
+               state->m_OperationMode = oMode;
+               status = SetQAMStandard(state, oMode);
+               if (status < 0)
+                       goto error;
+               break;
+       case OM_QAM_ITU_B:
+       default:
+               status = -EINVAL;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int Start(struct drxk_state *state, s32 offsetFreq,
+                s32 IntermediateFrequency)
+{
+       int status = -EINVAL;
+
+       u16 IFreqkHz;
+       s32 OffsetkHz = offsetFreq / 1000;
+
+       dprintk(1, "\n");
+       if (state->m_DrxkState != DRXK_STOPPED &&
+               state->m_DrxkState != DRXK_DTV_STARTED)
+               goto error;
+
+       state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
+
+       if (IntermediateFrequency < 0) {
+               state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
+               IntermediateFrequency = -IntermediateFrequency;
+       }
+
+       switch (state->m_OperationMode) {
+       case OM_QAM_ITU_A:
+       case OM_QAM_ITU_C:
+               IFreqkHz = (IntermediateFrequency / 1000);
+               status = SetQAM(state, IFreqkHz, OffsetkHz);
+               if (status < 0)
+                       goto error;
+               state->m_DrxkState = DRXK_DTV_STARTED;
+               break;
+       case OM_DVBT:
+               IFreqkHz = (IntermediateFrequency / 1000);
+               status = MPEGTSStop(state);
+               if (status < 0)
+                       goto error;
+               status = SetDVBT(state, IFreqkHz, OffsetkHz);
+               if (status < 0)
+                       goto error;
+               status = DVBTStart(state);
+               if (status < 0)
+                       goto error;
+               state->m_DrxkState = DRXK_DTV_STARTED;
+               break;
+       default:
+               break;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int ShutDown(struct drxk_state *state)
+{
+       dprintk(1, "\n");
+
+       MPEGTSStop(state);
+       return 0;
+}
+
+static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
+                        u32 Time)
+{
+       int status = -EINVAL;
+
+       dprintk(1, "\n");
+
+       if (pLockStatus == NULL)
+               goto error;
+
+       *pLockStatus = NOT_LOCKED;
+
+       /* define the SCU command code */
+       switch (state->m_OperationMode) {
+       case OM_QAM_ITU_A:
+       case OM_QAM_ITU_B:
+       case OM_QAM_ITU_C:
+               status = GetQAMLockStatus(state, pLockStatus);
+               break;
+       case OM_DVBT:
+               status = GetDVBTLockStatus(state, pLockStatus);
+               break;
+       default:
+               break;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int MPEGTSStart(struct drxk_state *state)
+{
+       int status;
+
+       u16 fecOcSncMode = 0;
+
+       /* Allow OC to sync again */
+       status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+       if (status < 0)
+               goto error;
+       fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
+       status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int MPEGTSDtoInit(struct drxk_state *state)
+{
+       int status;
+
+       dprintk(1, "\n");
+
+       /* Rate integration settings */
+       status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
+       if (status < 0)
+               goto error;
+
+       /* Additional configuration */
+       status = write16(state, FEC_OC_OCR_INVERT__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_SNC_LWM__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_SNC_HWM__A, 12);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int MPEGTSDtoSetup(struct drxk_state *state,
+                         enum OperationMode oMode)
+{
+       int status;
+
+       u16 fecOcRegMode = 0;   /* FEC_OC_MODE       register value */
+       u16 fecOcRegIprMode = 0;        /* FEC_OC_IPR_MODE   register value */
+       u16 fecOcDtoMode = 0;   /* FEC_OC_IPR_INVERT register value */
+       u16 fecOcFctMode = 0;   /* FEC_OC_IPR_INVERT register value */
+       u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
+       u16 fecOcDtoBurstLen = 188;     /* FEC_OC_IPR_INVERT register value */
+       u32 fecOcRcnCtlRate = 0;        /* FEC_OC_IPR_INVERT register value */
+       u16 fecOcTmdMode = 0;
+       u16 fecOcTmdIntUpdRate = 0;
+       u32 maxBitRate = 0;
+       bool staticCLK = false;
+
+       dprintk(1, "\n");
+
+       /* Check insertion of the Reed-Solomon parity bytes */
+       status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
+       if (status < 0)
+               goto error;
+       status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
+       if (status < 0)
+               goto error;
+       fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
+       fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
+       if (state->m_insertRSByte == true) {
+               /* enable parity symbol forward */
+               fecOcRegMode |= FEC_OC_MODE_PARITY__M;
+               /* MVAL disable during parity bytes */
+               fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
+               /* TS burst length to 204 */
+               fecOcDtoBurstLen = 204;
+       }
+
+       /* Check serial or parrallel output */
+       fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
+       if (state->m_enableParallel == false) {
+               /* MPEG data output is serial -> set ipr_mode[0] */
+               fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
+       }
+
+       switch (oMode) {
+       case OM_DVBT:
+               maxBitRate = state->m_DVBTBitrate;
+               fecOcTmdMode = 3;
+               fecOcRcnCtlRate = 0xC00000;
+               staticCLK = state->m_DVBTStaticCLK;
+               break;
+       case OM_QAM_ITU_A:      /* fallthrough */
+       case OM_QAM_ITU_C:
+               fecOcTmdMode = 0x0004;
+               fecOcRcnCtlRate = 0xD2B4EE;     /* good for >63 Mb/s */
+               maxBitRate = state->m_DVBCBitrate;
+               staticCLK = state->m_DVBCStaticCLK;
+               break;
+       default:
+               status = -EINVAL;
+       }               /* switch (standard) */
+       if (status < 0)
+               goto error;
+
+       /* Configure DTO's */
+       if (staticCLK) {
+               u32 bitRate = 0;
+
+               /* Rational DTO for MCLK source (static MCLK rate),
+                       Dynamic DTO for optimal grouping
+                       (avoid intra-packet gaps),
+                       DTO offset enable to sync TS burst with MSTRT */
+               fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
+                               FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
+               fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
+                               FEC_OC_FCT_MODE_VIRT_ENA__M);
+
+               /* Check user defined bitrate */
+               bitRate = maxBitRate;
+               if (bitRate > 75900000UL) {     /* max is 75.9 Mb/s */
+                       bitRate = 75900000UL;
+               }
+               /* Rational DTO period:
+                       dto_period = (Fsys / bitrate) - 2
+
+                       Result should be floored,
+                       to make sure >= requested bitrate
+                       */
+               fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
+                                               * 1000) / bitRate);
+               if (fecOcDtoPeriod <= 2)
+                       fecOcDtoPeriod = 0;
+               else
+                       fecOcDtoPeriod -= 2;
+               fecOcTmdIntUpdRate = 8;
+       } else {
+               /* (commonAttr->staticCLK == false) => dynamic mode */
+               fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
+               fecOcFctMode = FEC_OC_FCT_MODE__PRE;
+               fecOcTmdIntUpdRate = 5;
+       }
+
+       /* Write appropriate registers with requested configuration */
+       status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
+       if (status < 0)
+               goto error;
+
+       /* Rate integration settings */
+       status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int MPEGTSConfigurePolarity(struct drxk_state *state)
+{
+       u16 fecOcRegIprInvert = 0;
+
+       /* Data mask for the output data byte */
+       u16 InvertDataMask =
+           FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
+           FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
+           FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
+           FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
+
+       dprintk(1, "\n");
+
+       /* Control selective inversion of output bits */
+       fecOcRegIprInvert &= (~(InvertDataMask));
+       if (state->m_invertDATA == true)
+               fecOcRegIprInvert |= InvertDataMask;
+       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
+       if (state->m_invertERR == true)
+               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
+       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
+       if (state->m_invertSTR == true)
+               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
+       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
+       if (state->m_invertVAL == true)
+               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
+       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
+       if (state->m_invertCLK == true)
+               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
+
+       return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
+}
+
+#define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
+
+static int SetAgcRf(struct drxk_state *state,
+                   struct SCfgAgc *pAgcCfg, bool isDTV)
+{
+       int status = -EINVAL;
+       u16 data = 0;
+       struct SCfgAgc *pIfAgcSettings;
+
+       dprintk(1, "\n");
+
+       if (pAgcCfg == NULL)
+               goto error;
+
+       switch (pAgcCfg->ctrlMode) {
+       case DRXK_AGC_CTRL_AUTO:
+               /* Enable RF AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+
+               /* Enable SCU RF AGC loop */
+               data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
+
+               /* Polarity */
+               if (state->m_RfAgcPol)
+                       data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
+               else
+                       data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Set speed (using complementary reduction value) */
+               status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
+               if (status < 0)
+                       goto error;
+
+               data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
+               data |= (~(pAgcCfg->speed <<
+                               SCU_RAM_AGC_KI_RED_RAGC_RED__B)
+                               & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
+
+               status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
+               if (status < 0)
+                       goto error;
+
+               if (IsDVBT(state))
+                       pIfAgcSettings = &state->m_dvbtIfAgcCfg;
+               else if (IsQAM(state))
+                       pIfAgcSettings = &state->m_qamIfAgcCfg;
+               else
+                       pIfAgcSettings = &state->m_atvIfAgcCfg;
+               if (pIfAgcSettings == NULL) {
+                       status = -EINVAL;
+                       goto error;
+               }
+
+               /* Set TOP, only if IF-AGC is in AUTO mode */
+               if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
+                       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
+                       if (status < 0)
+                               goto error;
+
+               /* Cut-Off current */
+               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
+               if (status < 0)
+                       goto error;
+
+               /* Max. output level */
+               status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
+               if (status < 0)
+                       goto error;
+
+               break;
+
+       case DRXK_AGC_CTRL_USER:
+               /* Enable RF AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Disable SCU RF AGC loop */
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+               data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
+               if (state->m_RfAgcPol)
+                       data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
+               else
+                       data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* SCU c.o.c. to 0, enabling full control range */
+               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
+               if (status < 0)
+                       goto error;
+
+               /* Write value to output pin */
+               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
+               if (status < 0)
+                       goto error;
+               break;
+
+       case DRXK_AGC_CTRL_OFF:
+               /* Disable RF AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Disable SCU RF AGC loop */
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+               data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+               break;
+
+       default:
+               status = -EINVAL;
+
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
+
+static int SetAgcIf(struct drxk_state *state,
+                   struct SCfgAgc *pAgcCfg, bool isDTV)
+{
+       u16 data = 0;
+       int status = 0;
+       struct SCfgAgc *pRfAgcSettings;
+
+       dprintk(1, "\n");
+
+       switch (pAgcCfg->ctrlMode) {
+       case DRXK_AGC_CTRL_AUTO:
+
+               /* Enable IF AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+
+               /* Enable SCU IF AGC loop */
+               data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
+
+               /* Polarity */
+               if (state->m_IfAgcPol)
+                       data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
+               else
+                       data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Set speed (using complementary reduction value) */
+               status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
+               if (status < 0)
+                       goto error;
+               data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
+               data |= (~(pAgcCfg->speed <<
+                               SCU_RAM_AGC_KI_RED_IAGC_RED__B)
+                               & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
+
+               status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
+               if (status < 0)
+                       goto error;
+
+               if (IsQAM(state))
+                       pRfAgcSettings = &state->m_qamRfAgcCfg;
+               else
+                       pRfAgcSettings = &state->m_atvRfAgcCfg;
+               if (pRfAgcSettings == NULL)
+                       return -1;
+               /* Restore TOP */
+               status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
+               if (status < 0)
+                       goto error;
+               break;
+
+       case DRXK_AGC_CTRL_USER:
+
+               /* Enable IF AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+
+               /* Disable SCU IF AGC loop */
+               data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
+
+               /* Polarity */
+               if (state->m_IfAgcPol)
+                       data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
+               else
+                       data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Write value to output pin */
+               status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
+               if (status < 0)
+                       goto error;
+               break;
+
+       case DRXK_AGC_CTRL_OFF:
+
+               /* Disable If AGC DAC */
+               status = read16(state, IQM_AF_STDBY__A, &data);
+               if (status < 0)
+                       goto error;
+               data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
+               status = write16(state, IQM_AF_STDBY__A, data);
+               if (status < 0)
+                       goto error;
+
+               /* Disable SCU IF AGC loop */
+               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
+               if (status < 0)
+                       goto error;
+               data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
+               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
+               if (status < 0)
+                       goto error;
+               break;
+       }               /* switch (agcSettingsIf->ctrlMode) */
+
+       /* always set the top to support
+               configurations without if-loop */
+       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
+{
+       u16 agcDacLvl;
+       int status;
+       u16 Level = 0;
+
+       dprintk(1, "\n");
+
+       status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
+       if (status < 0) {
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+               return status;
+       }
+
+       *pValue = 0;
+
+       if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
+               Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
+       if (Level < 14000)
+               *pValue = (14000 - Level) / 4;
+       else
+               *pValue = 0;
+
+       return status;
+}
+
+static int GetQAMSignalToNoise(struct drxk_state *state,
+                              s32 *pSignalToNoise)
+{
+       int status = 0;
+       u16 qamSlErrPower = 0;  /* accum. error between
+                                       raw and sliced symbols */
+       u32 qamSlSigPower = 0;  /* used for MER, depends of
+                                       QAM modulation */
+       u32 qamSlMer = 0;       /* QAM MER */
+
+       dprintk(1, "\n");
+
+       /* MER calculation */
+
+       /* get the register value needed for MER */
+       status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
+       if (status < 0) {
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+               return -EINVAL;
+       }
+
+       switch (state->props.modulation) {
+       case QAM_16:
+               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
+               break;
+       case QAM_32:
+               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
+               break;
+       case QAM_64:
+               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
+               break;
+       case QAM_128:
+               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
+               break;
+       default:
+       case QAM_256:
+               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
+               break;
+       }
+
+       if (qamSlErrPower > 0) {
+               qamSlMer = Log10Times100(qamSlSigPower) -
+                       Log10Times100((u32) qamSlErrPower);
+       }
+       *pSignalToNoise = qamSlMer;
+
+       return status;
+}
+
+static int GetDVBTSignalToNoise(struct drxk_state *state,
+                               s32 *pSignalToNoise)
+{
+       int status;
+       u16 regData = 0;
+       u32 EqRegTdSqrErrI = 0;
+       u32 EqRegTdSqrErrQ = 0;
+       u16 EqRegTdSqrErrExp = 0;
+       u16 EqRegTdTpsPwrOfs = 0;
+       u16 EqRegTdReqSmbCnt = 0;
+       u32 tpsCnt = 0;
+       u32 SqrErrIQ = 0;
+       u32 a = 0;
+       u32 b = 0;
+       u32 c = 0;
+       u32 iMER = 0;
+       u16 transmissionParams = 0;
+
+       dprintk(1, "\n");
+
+       status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
+       if (status < 0)
+               goto error;
+       status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
+       if (status < 0)
+               goto error;
+       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
+       if (status < 0)
+               goto error;
+       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
+       if (status < 0)
+               goto error;
+       /* Extend SQR_ERR_I operational range */
+       EqRegTdSqrErrI = (u32) regData;
+       if ((EqRegTdSqrErrExp > 11) &&
+               (EqRegTdSqrErrI < 0x00000FFFUL)) {
+               EqRegTdSqrErrI += 0x00010000UL;
+       }
+       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
+       if (status < 0)
+               goto error;
+       /* Extend SQR_ERR_Q operational range */
+       EqRegTdSqrErrQ = (u32) regData;
+       if ((EqRegTdSqrErrExp > 11) &&
+               (EqRegTdSqrErrQ < 0x00000FFFUL))
+               EqRegTdSqrErrQ += 0x00010000UL;
+
+       status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
+       if (status < 0)
+               goto error;
+
+       /* Check input data for MER */
+
+       /* MER calculation (in 0.1 dB) without math.h */
+       if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
+               iMER = 0;
+       else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
+               /* No error at all, this must be the HW reset value
+                       * Apparently no first measurement yet
+                       * Set MER to 0.0 */
+               iMER = 0;
+       } else {
+               SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
+                       EqRegTdSqrErrExp;
+               if ((transmissionParams &
+                       OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
+                       == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
+                       tpsCnt = 17;
+               else
+                       tpsCnt = 68;
+
+               /* IMER = 100 * log10 (x)
+                       where x = (EqRegTdTpsPwrOfs^2 *
+                       EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
+
+                       => IMER = a + b -c
+                       where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
+                       b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
+                       c = 100 * log10 (SqrErrIQ)
+                       */
+
+               /* log(x) x = 9bits * 9bits->18 bits  */
+               a = Log10Times100(EqRegTdTpsPwrOfs *
+                                       EqRegTdTpsPwrOfs);
+               /* log(x) x = 16bits * 7bits->23 bits  */
+               b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
+               /* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
+               c = Log10Times100(SqrErrIQ);
+
+               iMER = a + b;
+               /* No negative MER, clip to zero */
+               if (iMER > c)
+                       iMER -= c;
+               else
+                       iMER = 0;
+       }
+       *pSignalToNoise = iMER;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
+{
+       dprintk(1, "\n");
+
+       *pSignalToNoise = 0;
+       switch (state->m_OperationMode) {
+       case OM_DVBT:
+               return GetDVBTSignalToNoise(state, pSignalToNoise);
+       case OM_QAM_ITU_A:
+       case OM_QAM_ITU_C:
+               return GetQAMSignalToNoise(state, pSignalToNoise);
+       default:
+               break;
+       }
+       return 0;
+}
+
+#if 0
+static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
+{
+       /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
+       int status = 0;
+
+       dprintk(1, "\n");
+
+       static s32 QE_SN[] = {
+               51,             /* QPSK 1/2 */
+               69,             /* QPSK 2/3 */
+               79,             /* QPSK 3/4 */
+               89,             /* QPSK 5/6 */
+               97,             /* QPSK 7/8 */
+               108,            /* 16-QAM 1/2 */
+               131,            /* 16-QAM 2/3 */
+               146,            /* 16-QAM 3/4 */
+               156,            /* 16-QAM 5/6 */
+               160,            /* 16-QAM 7/8 */
+               165,            /* 64-QAM 1/2 */
+               187,            /* 64-QAM 2/3 */
+               202,            /* 64-QAM 3/4 */
+               216,            /* 64-QAM 5/6 */
+               225,            /* 64-QAM 7/8 */
+       };
+
+       *pQuality = 0;
+
+       do {
+               s32 SignalToNoise = 0;
+               u16 Constellation = 0;
+               u16 CodeRate = 0;
+               u32 SignalToNoiseRel;
+               u32 BERQuality;
+
+               status = GetDVBTSignalToNoise(state, &SignalToNoise);
+               if (status < 0)
+                       break;
+               status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
+               if (status < 0)
+                       break;
+               Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
+
+               status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
+               if (status < 0)
+                       break;
+               CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
+
+               if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
+                   CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
+                       break;
+               SignalToNoiseRel = SignalToNoise -
+                   QE_SN[Constellation * 5 + CodeRate];
+               BERQuality = 100;
+
+               if (SignalToNoiseRel < -70)
+                       *pQuality = 0;
+               else if (SignalToNoiseRel < 30)
+                       *pQuality = ((SignalToNoiseRel + 70) *
+                                    BERQuality) / 100;
+               else
+                       *pQuality = BERQuality;
+       } while (0);
+       return 0;
+};
+
+static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
+{
+       int status = 0;
+       *pQuality = 0;
+
+       dprintk(1, "\n");
+
+       do {
+               u32 SignalToNoise = 0;
+               u32 BERQuality = 100;
+               u32 SignalToNoiseRel = 0;
+
+               status = GetQAMSignalToNoise(state, &SignalToNoise);
+               if (status < 0)
+                       break;
+
+               switch (state->props.modulation) {
+               case QAM_16:
+                       SignalToNoiseRel = SignalToNoise - 200;
+                       break;
+               case QAM_32:
+                       SignalToNoiseRel = SignalToNoise - 230;
+                       break;  /* Not in NorDig */
+               case QAM_64:
+                       SignalToNoiseRel = SignalToNoise - 260;
+                       break;
+               case QAM_128:
+                       SignalToNoiseRel = SignalToNoise - 290;
+                       break;
+               default:
+               case QAM_256:
+                       SignalToNoiseRel = SignalToNoise - 320;
+                       break;
+               }
+
+               if (SignalToNoiseRel < -70)
+                       *pQuality = 0;
+               else if (SignalToNoiseRel < 30)
+                       *pQuality = ((SignalToNoiseRel + 70) *
+                                    BERQuality) / 100;
+               else
+                       *pQuality = BERQuality;
+       } while (0);
+
+       return status;
+}
+
+static int GetQuality(struct drxk_state *state, s32 *pQuality)
+{
+       dprintk(1, "\n");
+
+       switch (state->m_OperationMode) {
+       case OM_DVBT:
+               return GetDVBTQuality(state, pQuality);
+       case OM_QAM_ITU_A:
+               return GetDVBCQuality(state, pQuality);
+       default:
+               break;
+       }
+
+       return 0;
+}
+#endif
+
+/* Free data ram in SIO HI */
+#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
+#define SIO_HI_RA_RAM_USR_END__A   0x420060
+
+#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
+#define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
+#define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
+#define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
+
+#define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
+#define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
+#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
+
+static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
+{
+       int status = -EINVAL;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return 0;
+       if (state->m_DrxkState == DRXK_POWERED_DOWN)
+               goto error;
+
+       if (state->no_i2c_bridge)
+               return 0;
+
+       status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+       if (status < 0)
+               goto error;
+       if (bEnableBridge) {
+               status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
+               if (status < 0)
+                       goto error;
+       } else {
+               status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
+               if (status < 0)
+                       goto error;
+       }
+
+       status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SetPreSaw(struct drxk_state *state,
+                    struct SCfgPreSaw *pPreSawCfg)
+{
+       int status = -EINVAL;
+
+       dprintk(1, "\n");
+
+       if ((pPreSawCfg == NULL)
+           || (pPreSawCfg->reference > IQM_AF_PDREF__M))
+               goto error;
+
+       status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
+                      u16 romOffset, u16 nrOfElements, u32 timeOut)
+{
+       u16 blStatus = 0;
+       u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
+       u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
+       int status;
+       unsigned long end;
+
+       dprintk(1, "\n");
+
+       mutex_lock(&state->mutex);
+       status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_TGT_ADDR__A, offset);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
+       if (status < 0)
+               goto error;
+
+       end = jiffies + msecs_to_jiffies(timeOut);
+       do {
+               status = read16(state, SIO_BL_STATUS__A, &blStatus);
+               if (status < 0)
+                       goto error;
+       } while ((blStatus == 0x1) && time_is_after_jiffies(end));
+       if (blStatus == 0x1) {
+               printk(KERN_ERR "drxk: SIO not ready\n");
+               status = -EINVAL;
+               goto error2;
+       }
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+error2:
+       mutex_unlock(&state->mutex);
+       return status;
+
+}
+
+static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
+{
+       u16 data = 0;
+       int status;
+
+       dprintk(1, "\n");
+
+       /* Start measurement */
+       status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_START_LOCK__A, 1);
+       if (status < 0)
+               goto error;
+
+       *count = 0;
+       status = read16(state, IQM_AF_PHASE0__A, &data);
+       if (status < 0)
+               goto error;
+       if (data == 127)
+               *count = *count + 1;
+       status = read16(state, IQM_AF_PHASE1__A, &data);
+       if (status < 0)
+               goto error;
+       if (data == 127)
+               *count = *count + 1;
+       status = read16(state, IQM_AF_PHASE2__A, &data);
+       if (status < 0)
+               goto error;
+       if (data == 127)
+               *count = *count + 1;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int ADCSynchronization(struct drxk_state *state)
+{
+       u16 count = 0;
+       int status;
+
+       dprintk(1, "\n");
+
+       status = ADCSyncMeasurement(state, &count);
+       if (status < 0)
+               goto error;
+
+       if (count == 1) {
+               /* Try sampling on a diffrent edge */
+               u16 clkNeg = 0;
+
+               status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
+               if (status < 0)
+                       goto error;
+               if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
+                       IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
+                       clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+                       clkNeg |=
+                               IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
+               } else {
+                       clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+                       clkNeg |=
+                               IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
+               }
+               status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
+               if (status < 0)
+                       goto error;
+               status = ADCSyncMeasurement(state, &count);
+               if (status < 0)
+                       goto error;
+       }
+
+       if (count < 2)
+               status = -EINVAL;
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SetFrequencyShifter(struct drxk_state *state,
+                              u16 intermediateFreqkHz,
+                              s32 tunerFreqOffset, bool isDTV)
+{
+       bool selectPosImage = false;
+       u32 rfFreqResidual = tunerFreqOffset;
+       u32 fmFrequencyShift = 0;
+       bool tunerMirror = !state->m_bMirrorFreqSpect;
+       u32 adcFreq;
+       bool adcFlip;
+       int status;
+       u32 ifFreqActual;
+       u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
+       u32 frequencyShift;
+       bool imageToSelect;
+
+       dprintk(1, "\n");
+
+       /*
+          Program frequency shifter
+          No need to account for mirroring on RF
+        */
+       if (isDTV) {
+               if ((state->m_OperationMode == OM_QAM_ITU_A) ||
+                   (state->m_OperationMode == OM_QAM_ITU_C) ||
+                   (state->m_OperationMode == OM_DVBT))
+                       selectPosImage = true;
+               else
+                       selectPosImage = false;
+       }
+       if (tunerMirror)
+               /* tuner doesn't mirror */
+               ifFreqActual = intermediateFreqkHz +
+                   rfFreqResidual + fmFrequencyShift;
+       else
+               /* tuner mirrors */
+               ifFreqActual = intermediateFreqkHz -
+                   rfFreqResidual - fmFrequencyShift;
+       if (ifFreqActual > samplingFrequency / 2) {
+               /* adc mirrors */
+               adcFreq = samplingFrequency - ifFreqActual;
+               adcFlip = true;
+       } else {
+               /* adc doesn't mirror */
+               adcFreq = ifFreqActual;
+               adcFlip = false;
+       }
+
+       frequencyShift = adcFreq;
+       imageToSelect = state->m_rfmirror ^ tunerMirror ^
+           adcFlip ^ selectPosImage;
+       state->m_IqmFsRateOfs =
+           Frac28a((frequencyShift), samplingFrequency);
+
+       if (imageToSelect)
+               state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
+
+       /* Program frequency shifter with tuner offset compensation */
+       /* frequencyShift += tunerFreqOffset; TODO */
+       status = write32(state, IQM_FS_RATE_OFS_LO__A,
+                        state->m_IqmFsRateOfs);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int InitAGC(struct drxk_state *state, bool isDTV)
+{
+       u16 ingainTgt = 0;
+       u16 ingainTgtMin = 0;
+       u16 ingainTgtMax = 0;
+       u16 clpCyclen = 0;
+       u16 clpSumMin = 0;
+       u16 clpDirTo = 0;
+       u16 snsSumMin = 0;
+       u16 snsSumMax = 0;
+       u16 clpSumMax = 0;
+       u16 snsDirTo = 0;
+       u16 kiInnergainMin = 0;
+       u16 ifIaccuHiTgt = 0;
+       u16 ifIaccuHiTgtMin = 0;
+       u16 ifIaccuHiTgtMax = 0;
+       u16 data = 0;
+       u16 fastClpCtrlDelay = 0;
+       u16 clpCtrlMode = 0;
+       int status = 0;
+
+       dprintk(1, "\n");
+
+       /* Common settings */
+       snsSumMax = 1023;
+       ifIaccuHiTgtMin = 2047;
+       clpCyclen = 500;
+       clpSumMax = 1023;
+
+       /* AGCInit() not available for DVBT; init done in microcode */
+       if (!IsQAM(state)) {
+               printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
+               return -EINVAL;
+       }
+
+       /* FIXME: Analog TV AGC require different settings */
+
+       /* Standard specific settings */
+       clpSumMin = 8;
+       clpDirTo = (u16) -9;
+       clpCtrlMode = 0;
+       snsSumMin = 8;
+       snsDirTo = (u16) -9;
+       kiInnergainMin = (u16) -1030;
+       ifIaccuHiTgtMax = 0x2380;
+       ifIaccuHiTgt = 0x2380;
+       ingainTgtMin = 0x0511;
+       ingainTgt = 0x0511;
+       ingainTgtMax = 5119;
+       fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
+
+       status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
+       if (status < 0)
+               goto error;
+
+       /* Initialize inner-loop KI gain factors */
+       status = read16(state, SCU_RAM_AGC_KI__A, &data);
+       if (status < 0)
+               goto error;
+
+       data = 0x0657;
+       data &= ~SCU_RAM_AGC_KI_RF__M;
+       data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
+       data &= ~SCU_RAM_AGC_KI_IF__M;
+       data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
+
+       status = write16(state, SCU_RAM_AGC_KI__A, data);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
+{
+       int status;
+
+       dprintk(1, "\n");
+       if (packetErr == NULL)
+               status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
+       else
+               status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int DVBTScCommand(struct drxk_state *state,
+                        u16 cmd, u16 subcmd,
+                        u16 param0, u16 param1, u16 param2,
+                        u16 param3, u16 param4)
+{
+       u16 curCmd = 0;
+       u16 errCode = 0;
+       u16 retryCnt = 0;
+       u16 scExec = 0;
+       int status;
+
+       dprintk(1, "\n");
+       status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
+       if (scExec != 1) {
+               /* SC is not running */
+               status = -EINVAL;
+       }
+       if (status < 0)
+               goto error;
+
+       /* Wait until sc is ready to receive command */
+       retryCnt = 0;
+       do {
+               msleep(1);
+               status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
+               retryCnt++;
+       } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
+       if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+               goto error;
+
+       /* Write sub-command */
+       switch (cmd) {
+               /* All commands using sub-cmd */
+       case OFDM_SC_RA_RAM_CMD_PROC_START:
+       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
+       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
+               status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
+               if (status < 0)
+                       goto error;
+               break;
+       default:
+               /* Do nothing */
+               break;
+       }
+
+       /* Write needed parameters and the command */
+       switch (cmd) {
+               /* All commands using 5 parameters */
+               /* All commands using 4 parameters */
+               /* All commands using 3 parameters */
+               /* All commands using 2 parameters */
+       case OFDM_SC_RA_RAM_CMD_PROC_START:
+       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
+       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
+               status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
+               /* All commands using 1 parameters */
+       case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
+       case OFDM_SC_RA_RAM_CMD_USER_IO:
+               status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
+               /* All commands using 0 parameters */
+       case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
+       case OFDM_SC_RA_RAM_CMD_NULL:
+               /* Write command */
+               status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
+               break;
+       default:
+               /* Unknown command */
+               status = -EINVAL;
+       }
+       if (status < 0)
+               goto error;
+
+       /* Wait until sc is ready processing command */
+       retryCnt = 0;
+       do {
+               msleep(1);
+               status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
+               retryCnt++;
+       } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
+       if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+               goto error;
+
+       /* Check for illegal cmd */
+       status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
+       if (errCode == 0xFFFF) {
+               /* illegal command */
+               status = -EINVAL;
+       }
+       if (status < 0)
+               goto error;
+
+       /* Retreive results parameters from SC */
+       switch (cmd) {
+               /* All commands yielding 5 results */
+               /* All commands yielding 4 results */
+               /* All commands yielding 3 results */
+               /* All commands yielding 2 results */
+               /* All commands yielding 1 result */
+       case OFDM_SC_RA_RAM_CMD_USER_IO:
+       case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
+               status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
+               /* All commands yielding 0 results */
+       case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
+       case OFDM_SC_RA_RAM_CMD_SET_TIMER:
+       case OFDM_SC_RA_RAM_CMD_PROC_START:
+       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
+       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
+       case OFDM_SC_RA_RAM_CMD_NULL:
+               break;
+       default:
+               /* Unknown command */
+               status = -EINVAL;
+               break;
+       }                       /* switch (cmd->cmd) */
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int PowerUpDVBT(struct drxk_state *state)
+{
+       enum DRXPowerMode powerMode = DRX_POWER_UP;
+       int status;
+
+       dprintk(1, "\n");
+       status = CtrlPowerMode(state, &powerMode);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
+{
+       int status;
+
+       dprintk(1, "\n");
+       if (*enabled == true)
+               status = write16(state, IQM_CF_BYPASSDET__A, 0);
+       else
+               status = write16(state, IQM_CF_BYPASSDET__A, 1);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+#define DEFAULT_FR_THRES_8K     4000
+static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
+{
+
+       int status;
+
+       dprintk(1, "\n");
+       if (*enabled == true) {
+               /* write mask to 1 */
+               status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
+                                  DEFAULT_FR_THRES_8K);
+       } else {
+               /* write mask to 0 */
+               status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
+       }
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
+                                   struct DRXKCfgDvbtEchoThres_t *echoThres)
+{
+       u16 data = 0;
+       int status;
+
+       dprintk(1, "\n");
+       status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
+       if (status < 0)
+               goto error;
+
+       switch (echoThres->fftMode) {
+       case DRX_FFTMODE_2K:
+               data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
+               data |= ((echoThres->threshold <<
+                       OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
+                       & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
+               break;
+       case DRX_FFTMODE_8K:
+               data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
+               data |= ((echoThres->threshold <<
+                       OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
+                       & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
+                              enum DRXKCfgDvbtSqiSpeed *speed)
+{
+       int status = -EINVAL;
+
+       dprintk(1, "\n");
+
+       switch (*speed) {
+       case DRXK_DVBT_SQI_SPEED_FAST:
+       case DRXK_DVBT_SQI_SPEED_MEDIUM:
+       case DRXK_DVBT_SQI_SPEED_SLOW:
+               break;
+       default:
+               goto error;
+       }
+       status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
+                          (u16) *speed);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Activate DVBT specific presets
+* \param demod instance of demodulator.
+* \return DRXStatus_t.
+*
+* Called in DVBTSetStandard
+*
+*/
+static int DVBTActivatePresets(struct drxk_state *state)
+{
+       int status;
+       bool setincenable = false;
+       bool setfrenable = true;
+
+       struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
+       struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
+
+       dprintk(1, "\n");
+       status = DVBTCtrlSetIncEnable(state, &setincenable);
+       if (status < 0)
+               goto error;
+       status = DVBTCtrlSetFrEnable(state, &setfrenable);
+       if (status < 0)
+               goto error;
+       status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
+       if (status < 0)
+               goto error;
+       status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Initialize channelswitch-independent settings for DVBT.
+* \param demod instance of demodulator.
+* \return DRXStatus_t.
+*
+* For ROM code channel filter taps are loaded from the bootloader. For microcode
+* the DVB-T taps from the drxk_filters.h are used.
+*/
+static int SetDVBTStandard(struct drxk_state *state,
+                          enum OperationMode oMode)
+{
+       u16 cmdResult = 0;
+       u16 data = 0;
+       int status;
+
+       dprintk(1, "\n");
+
+       PowerUpDVBT(state);
+       /* added antenna switch */
+       SwitchAntennaToDVBT(state);
+       /* send OFDM reset command */
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+       if (status < 0)
+               goto error;
+
+       /* send OFDM setenv command */
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
+       if (status < 0)
+               goto error;
+
+       /* reset datapath for OFDM, processors first */
+       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
+       if (status < 0)
+               goto error;
+
+       /* IQM setup */
+       /* synchronize on ofdstate->m_festart */
+       status = write16(state, IQM_AF_UPD_SEL__A, 1);
+       if (status < 0)
+               goto error;
+       /* window size for clipping ADC detection */
+       status = write16(state, IQM_AF_CLP_LEN__A, 0);
+       if (status < 0)
+               goto error;
+       /* window size for for sense pre-SAW detection */
+       status = write16(state, IQM_AF_SNS_LEN__A, 0);
+       if (status < 0)
+               goto error;
+       /* sense threshold for sense pre-SAW detection */
+       status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
+       if (status < 0)
+               goto error;
+       status = SetIqmAf(state, true);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_AF_AGC_RF__A, 0);
+       if (status < 0)
+               goto error;
+
+       /* Impulse noise cruncher setup */
+       status = write16(state, IQM_AF_INC_LCT__A, 0);  /* crunch in IQM_CF */
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_DET_LCT__A, 0);  /* detect in IQM_CF */
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_WND_LEN__A, 3);  /* peak detector window length */
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_RC_STRETCH__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_OUT_ENA__A, 0x4);        /* enable output 2 */
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_SCALE__A, 1600);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_SCALE_SH__A, 0);
+       if (status < 0)
+               goto error;
+
+       /* virtual clipping threshold for clipping ADC detection */
+       status = write16(state, IQM_AF_CLP_TH__A, 448);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
+       if (status < 0)
+               goto error;
+
+       status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_CF_PKDTH__A, 2);    /* peak detector threshold */
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
+       if (status < 0)
+               goto error;
+       /* enable power measurement interrupt */
+       status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
+       if (status < 0)
+               goto error;
+
+       /* IQM will not be reset from here, sync ADC and update/init AGC */
+       status = ADCSynchronization(state);
+       if (status < 0)
+               goto error;
+       status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
+       if (status < 0)
+               goto error;
+
+       /* Halt SCU to enable safe non-atomic accesses */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
+       if (status < 0)
+               goto error;
+
+       status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
+       if (status < 0)
+               goto error;
+       status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
+       if (status < 0)
+               goto error;
+
+       /* Set Noise Estimation notch width and enable DC fix */
+       status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
+       if (status < 0)
+               goto error;
+       data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
+       status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
+       if (status < 0)
+               goto error;
+
+       /* Activate SCU to enable SCU commands */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+
+       if (!state->m_DRXK_A3_ROM_CODE) {
+               /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay  */
+               status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
+               if (status < 0)
+                       goto error;
+       }
+
+       /* OFDM_SC setup */
+#ifdef COMPILE_FOR_NONRT
+       status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
+       if (status < 0)
+               goto error;
+#endif
+
+       /* FEC setup */
+       status = write16(state, FEC_DI_INPUT_CTL__A, 1);        /* OFDM input */
+       if (status < 0)
+               goto error;
+
+
+#ifdef COMPILE_FOR_NONRT
+       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
+       if (status < 0)
+               goto error;
+#else
+       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
+       if (status < 0)
+               goto error;
+#endif
+       status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
+       if (status < 0)
+               goto error;
+
+       /* Setup MPEG bus */
+       status = MPEGTSDtoSetup(state, OM_DVBT);
+       if (status < 0)
+               goto error;
+       /* Set DVBT Presets */
+       status = DVBTActivatePresets(state);
+       if (status < 0)
+               goto error;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+/**
+* \brief Start dvbt demodulating for channel.
+* \param demod instance of demodulator.
+* \return DRXStatus_t.
+*/
+static int DVBTStart(struct drxk_state *state)
+{
+       u16 param1;
+       int status;
+       /* DRXKOfdmScCmd_t scCmd; */
+
+       dprintk(1, "\n");
+       /* Start correct processes to get in lock */
+       /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
+       param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
+       status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
+       if (status < 0)
+               goto error;
+       /* Start FEC OC */
+       status = MPEGTSStart(state);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+
+/*============================================================================*/
+
+/**
+* \brief Set up dvbt demodulator for channel.
+* \param demod instance of demodulator.
+* \return DRXStatus_t.
+* // original DVBTSetChannel()
+*/
+static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
+                  s32 tunerFreqOffset)
+{
+       u16 cmdResult = 0;
+       u16 transmissionParams = 0;
+       u16 operationMode = 0;
+       u32 iqmRcRateOfs = 0;
+       u32 bandwidth = 0;
+       u16 param1;
+       int status;
+
+       dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
+
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+       if (status < 0)
+               goto error;
+
+       /* Halt SCU to enable safe non-atomic accesses */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
+       if (status < 0)
+               goto error;
+
+       /* Stop processors */
+       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+
+       /* Mandatory fix, always stop CP, required to set spl offset back to
+               hardware default (is set to 0 by ucode during pilot detection */
+       status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+
+       /*== Write channel settings to device =====================================*/
+
+       /* mode */
+       switch (state->props.transmission_mode) {
+       case TRANSMISSION_MODE_AUTO:
+       default:
+               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
+               /* fall through , try first guess DRX_FFTMODE_8K */
+       case TRANSMISSION_MODE_8K:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
+               break;
+       case TRANSMISSION_MODE_2K:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
+               break;
+       }
+
+       /* guard */
+       switch (state->props.guard_interval) {
+       default:
+       case GUARD_INTERVAL_AUTO:
+               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
+               /* fall through , try first guess DRX_GUARD_1DIV4 */
+       case GUARD_INTERVAL_1_4:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
+               break;
+       case GUARD_INTERVAL_1_32:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
+               break;
+       case GUARD_INTERVAL_1_16:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
+               break;
+       case GUARD_INTERVAL_1_8:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
+               break;
+       }
+
+       /* hierarchy */
+       switch (state->props.hierarchy) {
+       case HIERARCHY_AUTO:
+       case HIERARCHY_NONE:
+       default:
+               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
+               /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
+               /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
+               /* break; */
+       case HIERARCHY_1:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
+               break;
+       case HIERARCHY_2:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
+               break;
+       case HIERARCHY_4:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
+               break;
+       }
+
+
+       /* modulation */
+       switch (state->props.modulation) {
+       case QAM_AUTO:
+       default:
+               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
+               /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
+       case QAM_64:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
+               break;
+       case QPSK:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
+               break;
+       case QAM_16:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
+               break;
+       }
+#if 0
+       /* No hierachical channels support in BDA */
+       /* Priority (only for hierarchical channels) */
+       switch (channel->priority) {
+       case DRX_PRIORITY_LOW:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
+               WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+                       OFDM_EC_SB_PRIOR_LO);
+               break;
+       case DRX_PRIORITY_HIGH:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+               WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+                       OFDM_EC_SB_PRIOR_HI));
+               break;
+       case DRX_PRIORITY_UNKNOWN:      /* fall through */
+       default:
+               status = -EINVAL;
+               goto error;
+       }
+#else
+       /* Set Priorty high */
+       transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+       status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
+       if (status < 0)
+               goto error;
+#endif
+
+       /* coderate */
+       switch (state->props.code_rate_HP) {
+       case FEC_AUTO:
+       default:
+               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
+               /* fall through , try first guess DRX_CODERATE_2DIV3 */
+       case FEC_2_3:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
+               break;
+       case FEC_1_2:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
+               break;
+       case FEC_3_4:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
+               break;
+       case FEC_5_6:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
+               break;
+       case FEC_7_8:
+               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
+               break;
+       }
+
+       /* SAW filter selection: normaly not necesarry, but if wanted
+               the application can select a SAW filter via the driver by using UIOs */
+       /* First determine real bandwidth (Hz) */
+       /* Also set delay for impulse noise cruncher */
+       /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
+               by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
+               functions */
+       switch (state->props.bandwidth_hz) {
+       case 0:
+               state->props.bandwidth_hz = 8000000;
+               /* fall though */
+       case 8000000:
+               bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
+               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
+               if (status < 0)
+                       goto error;
+               /* cochannel protection for PAL 8 MHz */
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+               if (status < 0)
+                       goto error;
+               break;
+       case 7000000:
+               bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
+               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
+               if (status < 0)
+                       goto error;
+               /* cochannel protection for PAL 7 MHz */
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+               if (status < 0)
+                       goto error;
+               break;
+       case 6000000:
+               bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
+               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
+               if (status < 0)
+                       goto error;
+               /* cochannel protection for NTSC 6 MHz */
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
+               if (status < 0)
+                       goto error;
+               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+               if (status < 0)
+                       goto error;
+               break;
+       default:
+               status = -EINVAL;
+               goto error;
+       }
+
+       if (iqmRcRateOfs == 0) {
+               /* Now compute IQM_RC_RATE_OFS
+                       (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
+                       =>
+                       ((SysFreq / BandWidth) * (2^21)) - (2^23)
+                       */
+               /* (SysFreq / BandWidth) * (2^28)  */
+               /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
+                       => assert(MAX(sysClk) < 16*MIN(bandwidth))
+                       => assert(109714272 > 48000000) = true so Frac 28 can be used  */
+               iqmRcRateOfs = Frac28a((u32)
+                                       ((state->m_sysClockFreq *
+                                               1000) / 3), bandwidth);
+               /* (SysFreq / BandWidth) * (2^21), rounding before truncating  */
+               if ((iqmRcRateOfs & 0x7fL) >= 0x40)
+                       iqmRcRateOfs += 0x80L;
+               iqmRcRateOfs = iqmRcRateOfs >> 7;
+               /* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
+               iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
+       }
+
+       iqmRcRateOfs &=
+               ((((u32) IQM_RC_RATE_OFS_HI__M) <<
+               IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
+       status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
+       if (status < 0)
+               goto error;
+
+       /* Bandwidth setting done */
+
+#if 0
+       status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
+       if (status < 0)
+               goto error;
+#endif
+       status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+       if (status < 0)
+               goto error;
+
+       /*== Start SC, write channel settings to SC ===============================*/
+
+       /* Activate SCU to enable SCU commands */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+
+       /* Enable SC after setting all other parameters */
+       status = write16(state, OFDM_SC_COMM_STATE__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
+       if (status < 0)
+               goto error;
+
+
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+       if (status < 0)
+               goto error;
+
+       /* Write SC parameter registers, set all AUTO flags in operation mode */
+       param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
+                       OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
+                       OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
+                       OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
+                       OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
+       status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
+                               0, transmissionParams, param1, 0, 0, 0);
+       if (status < 0)
+               goto error;
+
+       if (!state->m_DRXK_A3_ROM_CODE)
+               status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+
+/*============================================================================*/
+
+/**
+* \brief Retreive lock status .
+* \param demod    Pointer to demodulator instance.
+* \param lockStat Pointer to lock status structure.
+* \return DRXStatus_t.
+*
+*/
+static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
+{
+       int status;
+       const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
+                                   OFDM_SC_RA_RAM_LOCK_FEC__M);
+       const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
+       const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
+
+       u16 ScRaRamLock = 0;
+       u16 ScCommExec = 0;
+
+       dprintk(1, "\n");
+
+       *pLockStatus = NOT_LOCKED;
+       /* driver 0.9.0 */
+       /* Check if SC is running */
+       status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
+       if (status < 0)
+               goto end;
+       if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
+               goto end;
+
+       status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
+       if (status < 0)
+               goto end;
+
+       if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
+               *pLockStatus = MPEG_LOCK;
+       else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
+               *pLockStatus = FEC_LOCK;
+       else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
+               *pLockStatus = DEMOD_LOCK;
+       else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
+               *pLockStatus = NEVER_LOCK;
+end:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int PowerUpQAM(struct drxk_state *state)
+{
+       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+       int status;
+
+       dprintk(1, "\n");
+       status = CtrlPowerMode(state, &powerMode);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+
+/** Power Down QAM */
+static int PowerDownQAM(struct drxk_state *state)
+{
+       u16 data = 0;
+       u16 cmdResult;
+       int status = 0;
+
+       dprintk(1, "\n");
+       status = read16(state, SCU_COMM_EXEC__A, &data);
+       if (status < 0)
+               goto error;
+       if (data == SCU_COMM_EXEC_ACTIVE) {
+               /*
+                       STOP demodulator
+                       QAM and HW blocks
+                       */
+               /* stop all comstate->m_exec */
+               status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
+               if (status < 0)
+                       goto error;
+               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+               if (status < 0)
+                       goto error;
+       }
+       /* powerdown AFE                   */
+       status = SetIqmAf(state, false);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Setup of the QAM Measurement intervals for signal quality
+* \param demod instance of demod.
+* \param modulation current modulation.
+* \return DRXStatus_t.
+*
+*  NOTE:
+*  Take into account that for certain settings the errorcounters can overflow.
+*  The implementation does not check this.
+*
+*/
+static int SetQAMMeasurement(struct drxk_state *state,
+                            enum EDrxkConstellation modulation,
+                            u32 symbolRate)
+{
+       u32 fecBitsDesired = 0; /* BER accounting period */
+       u32 fecRsPeriodTotal = 0;       /* Total period */
+       u16 fecRsPrescale = 0;  /* ReedSolomon Measurement Prescale */
+       u16 fecRsPeriod = 0;    /* Value for corresponding I2C register */
+       int status = 0;
+
+       dprintk(1, "\n");
+
+       fecRsPrescale = 1;
+       /* fecBitsDesired = symbolRate [kHz] *
+               FrameLenght [ms] *
+               (modulation + 1) *
+               SyncLoss (== 1) *
+               ViterbiLoss (==1)
+               */
+       switch (modulation) {
+       case DRX_CONSTELLATION_QAM16:
+               fecBitsDesired = 4 * symbolRate;
+               break;
+       case DRX_CONSTELLATION_QAM32:
+               fecBitsDesired = 5 * symbolRate;
+               break;
+       case DRX_CONSTELLATION_QAM64:
+               fecBitsDesired = 6 * symbolRate;
+               break;
+       case DRX_CONSTELLATION_QAM128:
+               fecBitsDesired = 7 * symbolRate;
+               break;
+       case DRX_CONSTELLATION_QAM256:
+               fecBitsDesired = 8 * symbolRate;
+               break;
+       default:
+               status = -EINVAL;
+       }
+       if (status < 0)
+               goto error;
+
+       fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz]  */
+       fecBitsDesired *= 500;  /* meas. period [ms] */
+
+       /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
+       /* fecRsPeriodTotal = fecBitsDesired / 1632 */
+       fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1;       /* roughly ceil */
+
+       /* fecRsPeriodTotal =  fecRsPrescale * fecRsPeriod  */
+       fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
+       if (fecRsPrescale == 0) {
+               /* Divide by zero (though impossible) */
+               status = -EINVAL;
+               if (status < 0)
+                       goto error;
+       }
+       fecRsPeriod =
+               ((u16) fecRsPeriodTotal +
+               (fecRsPrescale >> 1)) / fecRsPrescale;
+
+       /* write corresponding registers */
+       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SetQAM16(struct drxk_state *state)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+       /* QAM Equalizer Setup */
+       /* Equalizer */
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
+       if (status < 0)
+               goto error;
+       /* Decision Feedback Equalizer */
+       status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
+       if (status < 0)
+               goto error;
+
+       /* QAM Slicer Settings */
+       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
+       if (status < 0)
+               goto error;
+
+       /* QAM Loop Controller Coeficients */
+       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM State Machine (FSM) Thresholds */
+
+       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM FSM Tracking Parameters */
+
+       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
+       if (status < 0)
+               goto error;
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief QAM32 specific setup
+* \param demod instance of demod.
+* \return DRXStatus_t.
+*/
+static int SetQAM32(struct drxk_state *state)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+
+       /* QAM Equalizer Setup */
+       /* Equalizer */
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
+       if (status < 0)
+               goto error;
+
+       /* Decision Feedback Equalizer */
+       status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_SY_SYNC_HWM__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_AWM__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
+       if (status < 0)
+               goto error;
+
+       /* QAM Slicer Settings */
+
+       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM Loop Controller Coeficients */
+
+       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM State Machine (FSM) Thresholds */
+
+       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM FSM Tracking Parameters */
+
+       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief QAM64 specific setup
+* \param demod instance of demod.
+* \return DRXStatus_t.
+*/
+static int SetQAM64(struct drxk_state *state)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+       /* QAM Equalizer Setup */
+       /* Equalizer */
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
+       if (status < 0)
+               goto error;
+
+       /* Decision Feedback Equalizer */
+       status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
+       if (status < 0)
+               goto error;
+
+       /* QAM Slicer Settings */
+       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM Loop Controller Coeficients */
+
+       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM State Machine (FSM) Thresholds */
+
+       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM FSM Tracking Parameters */
+
+       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief QAM128 specific setup
+* \param demod: instance of demod.
+* \return DRXStatus_t.
+*/
+static int SetQAM128(struct drxk_state *state)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+       /* QAM Equalizer Setup */
+       /* Equalizer */
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
+       if (status < 0)
+               goto error;
+
+       /* Decision Feedback Equalizer */
+       status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_SY_SYNC_HWM__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_AWM__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM Slicer Settings */
+
+       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM Loop Controller Coeficients */
+
+       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM State Machine (FSM) Thresholds */
+
+       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
+       if (status < 0)
+               goto error;
+
+       /* QAM FSM Tracking Parameters */
+
+       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief QAM256 specific setup
+* \param demod: instance of demod.
+* \return DRXStatus_t.
+*/
+static int SetQAM256(struct drxk_state *state)
+{
+       int status = 0;
+
+       dprintk(1, "\n");
+       /* QAM Equalizer Setup */
+       /* Equalizer */
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
+       if (status < 0)
+               goto error;
+
+       /* Decision Feedback Equalizer */
+       status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
+       if (status < 0)
+               goto error;
+
+       /* QAM Slicer Settings */
+
+       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM Loop Controller Coeficients */
+
+       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM State Machine (FSM) Thresholds */
+
+       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
+       if (status < 0)
+               goto error;
+
+
+       /* QAM FSM Tracking Parameters */
+
+       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+
+/*============================================================================*/
+/**
+* \brief Reset QAM block.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \return DRXStatus_t.
+*/
+static int QAMResetQAM(struct drxk_state *state)
+{
+       int status;
+       u16 cmdResult;
+
+       dprintk(1, "\n");
+       /* Stop QAM comstate->m_exec */
+       status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Set QAM symbolrate.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \return DRXStatus_t.
+*/
+static int QAMSetSymbolrate(struct drxk_state *state)
+{
+       u32 adcFrequency = 0;
+       u32 symbFreq = 0;
+       u32 iqmRcRate = 0;
+       u16 ratesel = 0;
+       u32 lcSymbRate = 0;
+       int status;
+
+       dprintk(1, "\n");
+       /* Select & calculate correct IQM rate */
+       adcFrequency = (state->m_sysClockFreq * 1000) / 3;
+       ratesel = 0;
+       /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
+       if (state->props.symbol_rate <= 1188750)
+               ratesel = 3;
+       else if (state->props.symbol_rate <= 2377500)
+               ratesel = 2;
+       else if (state->props.symbol_rate <= 4755000)
+               ratesel = 1;
+       status = write16(state, IQM_FD_RATESEL__A, ratesel);
+       if (status < 0)
+               goto error;
+
+       /*
+               IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
+               */
+       symbFreq = state->props.symbol_rate * (1 << ratesel);
+       if (symbFreq == 0) {
+               /* Divide by zero */
+               status = -EINVAL;
+               goto error;
+       }
+       iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
+               (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
+               (1 << 23);
+       status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
+       if (status < 0)
+               goto error;
+       state->m_iqmRcRate = iqmRcRate;
+       /*
+               LcSymbFreq = round (.125 *  symbolrate / adcFreq * (1<<15))
+               */
+       symbFreq = state->props.symbol_rate;
+       if (adcFrequency == 0) {
+               /* Divide by zero */
+               status = -EINVAL;
+               goto error;
+       }
+       lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
+               (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
+               16);
+       if (lcSymbRate > 511)
+               lcSymbRate = 511;
+       status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+/*============================================================================*/
+
+/**
+* \brief Get QAM lock status.
+* \param demod:   instance of demod.
+* \param channel: pointer to channel data.
+* \return DRXStatus_t.
+*/
+
+static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
+{
+       int status;
+       u16 Result[2] = { 0, 0 };
+
+       dprintk(1, "\n");
+       *pLockStatus = NOT_LOCKED;
+       status = scu_command(state,
+                       SCU_RAM_COMMAND_STANDARD_QAM |
+                       SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
+                       Result);
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
+               /* 0x0000 NOT LOCKED */
+       } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
+               /* 0x4000 DEMOD LOCKED */
+               *pLockStatus = DEMOD_LOCK;
+       } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
+               /* 0x8000 DEMOD + FEC LOCKED (system lock) */
+               *pLockStatus = MPEG_LOCK;
+       } else {
+               /* 0xC000 NEVER LOCKED */
+               /* (system will never be able to lock to the signal) */
+               /* TODO: check this, intermediate & standard specific lock states are not
+                  taken into account here */
+               *pLockStatus = NEVER_LOCK;
+       }
+       return status;
+}
+
+#define QAM_MIRROR__M         0x03
+#define QAM_MIRROR_NORMAL     0x00
+#define QAM_MIRRORED          0x01
+#define QAM_MIRROR_AUTO_ON    0x02
+#define QAM_LOCKRANGE__M      0x10
+#define QAM_LOCKRANGE_NORMAL  0x10
+
+static int QAMDemodulatorCommand(struct drxk_state *state,
+                                int numberOfParameters)
+{
+       int status;
+       u16 cmdResult;
+       u16 setParamParameters[4] = { 0, 0, 0, 0 };
+
+       setParamParameters[0] = state->m_Constellation; /* modulation     */
+       setParamParameters[1] = DRXK_QAM_I12_J17;       /* interleave mode   */
+
+       if (numberOfParameters == 2) {
+               u16 setEnvParameters[1] = { 0 };
+
+               if (state->m_OperationMode == OM_QAM_ITU_C)
+                       setEnvParameters[0] = QAM_TOP_ANNEX_C;
+               else
+                       setEnvParameters[0] = QAM_TOP_ANNEX_A;
+
+               status = scu_command(state,
+                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+                                    1, setEnvParameters, 1, &cmdResult);
+               if (status < 0)
+                       goto error;
+
+               status = scu_command(state,
+                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+                                    numberOfParameters, setParamParameters,
+                                    1, &cmdResult);
+       } else if (numberOfParameters == 4) {
+               if (state->m_OperationMode == OM_QAM_ITU_C)
+                       setParamParameters[2] = QAM_TOP_ANNEX_C;
+               else
+                       setParamParameters[2] = QAM_TOP_ANNEX_A;
+
+               setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
+               /* Env parameters */
+               /* check for LOCKRANGE Extented */
+               /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
+
+               status = scu_command(state,
+                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+                                    numberOfParameters, setParamParameters,
+                                    1, &cmdResult);
+       } else {
+               printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
+                       "count %d\n", numberOfParameters);
+       }
+
+error:
+       if (status < 0)
+               printk(KERN_WARNING "drxk: Warning %d on %s\n",
+                      status, __func__);
+       return status;
+}
+
+static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
+                 s32 tunerFreqOffset)
+{
+       int status;
+       u16 cmdResult;
+       int qamDemodParamCount = state->qam_demod_parameter_count;
+
+       dprintk(1, "\n");
+       /*
+        * STEP 1: reset demodulator
+        *      resets FEC DI and FEC RS
+        *      resets QAM block
+        *      resets SCU variables
+        */
+       status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
+       if (status < 0)
+               goto error;
+       status = QAMResetQAM(state);
+       if (status < 0)
+               goto error;
+
+       /*
+        * STEP 2: configure demodulator
+        *      -set params; resets IQM,QAM,FEC HW; initializes some
+        *       SCU variables
+        */
+       status = QAMSetSymbolrate(state);
+       if (status < 0)
+               goto error;
+
+       /* Set params */
+       switch (state->props.modulation) {
+       case QAM_256:
+               state->m_Constellation = DRX_CONSTELLATION_QAM256;
+               break;
+       case QAM_AUTO:
+       case QAM_64:
+               state->m_Constellation = DRX_CONSTELLATION_QAM64;
+               break;
+       case QAM_16:
+               state->m_Constellation = DRX_CONSTELLATION_QAM16;
+               break;
+       case QAM_32:
+               state->m_Constellation = DRX_CONSTELLATION_QAM32;
+               break;
+       case QAM_128:
+               state->m_Constellation = DRX_CONSTELLATION_QAM128;
+               break;
+       default:
+               status = -EINVAL;
+               break;
+       }
+       if (status < 0)
+               goto error;
+
+       /* Use the 4-parameter if it's requested or we're probing for
+        * the correct command. */
+       if (state->qam_demod_parameter_count == 4
+               || !state->qam_demod_parameter_count) {
+               qamDemodParamCount = 4;
+               status = QAMDemodulatorCommand(state, qamDemodParamCount);
+       }
+
+       /* Use the 2-parameter command if it was requested or if we're
+        * probing for the correct command and the 4-parameter command
+        * failed. */
+       if (state->qam_demod_parameter_count == 2
+               || (!state->qam_demod_parameter_count && status < 0)) {
+               qamDemodParamCount = 2;
+               status = QAMDemodulatorCommand(state, qamDemodParamCount);
+       }
+
+       if (status < 0) {
+               dprintk(1, "Could not set demodulator parameters. Make "
+                       "sure qam_demod_parameter_count (%d) is correct for "
+                       "your firmware (%s).\n",
+                       state->qam_demod_parameter_count,
+                       state->microcode_name);
+               goto error;
+       } else if (!state->qam_demod_parameter_count) {
+               dprintk(1, "Auto-probing the correct QAM demodulator command "
+                       "parameters was successful - using %d parameters.\n",
+                       qamDemodParamCount);
+
+               /*
+                * One of our commands was successful. We don't need to
+                * auto-probe anymore, now that we got the correct command.
+                */
+               state->qam_demod_parameter_count = qamDemodParamCount;
+       }
+
+       /*
+        * STEP 3: enable the system in a mode where the ADC provides valid
+        * signal setup modulation independent registers
+        */
+#if 0
+       status = SetFrequency(channel, tunerFreqOffset));
+       if (status < 0)
+               goto error;
+#endif
+       status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+       if (status < 0)
+               goto error;
+
+       /* Setup BER measurement */
+       status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
+       if (status < 0)
+               goto error;
+
+       /* Reset default values */
+       status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
+       if (status < 0)
+               goto error;
+
+       /* Reset default LC values */
+       status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_MODE__A, 7);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
+       if (status < 0)
+               goto error;
+
+       /* Mirroring, QAM-block starting point not inverted */
+       status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
+       if (status < 0)
+               goto error;
+
+       /* Halt SCU to enable safe non-atomic accesses */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
+       if (status < 0)
+               goto error;
+
+       /* STEP 4: modulation specific setup */
+       switch (state->props.modulation) {
+       case QAM_16:
+               status = SetQAM16(state);
+               break;
+       case QAM_32:
+               status = SetQAM32(state);
+               break;
+       case QAM_AUTO:
+       case QAM_64:
+               status = SetQAM64(state);
+               break;
+       case QAM_128:
+               status = SetQAM128(state);
+               break;
+       case QAM_256:
+               status = SetQAM256(state);
+               break;
+       default:
+               status = -EINVAL;
+               break;
+       }
+       if (status < 0)
+               goto error;
+
+       /* Activate SCU to enable SCU commands */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+
+       /* Re-configure MPEG output, requires knowledge of channel bitrate */
+       /* extAttr->currentChannel.modulation = channel->modulation; */
+       /* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
+       status = MPEGTSDtoSetup(state, state->m_OperationMode);
+       if (status < 0)
+               goto error;
+
+       /* Start processes */
+       status = MPEGTSStart(state);
+       if (status < 0)
+               goto error;
+       status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+       status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
+       if (status < 0)
+               goto error;
+
+       /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
+       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+       if (status < 0)
+               goto error;
+
+       /* update global DRXK data container */
+/*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
+
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SetQAMStandard(struct drxk_state *state,
+                         enum OperationMode oMode)
+{
+       int status;
+#ifdef DRXK_QAM_TAPS
+#define DRXK_QAMA_TAPS_SELECT
+#include "drxk_filters.h"
+#undef DRXK_QAMA_TAPS_SELECT
+#endif
+
+       dprintk(1, "\n");
+
+       /* added antenna switch */
+       SwitchAntennaToQAM(state);
+
+       /* Ensure correct power-up mode */
+       status = PowerUpQAM(state);
+       if (status < 0)
+               goto error;
+       /* Reset QAM block */
+       status = QAMResetQAM(state);
+       if (status < 0)
+               goto error;
+
+       /* Setup IQM */
+
+       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
+       if (status < 0)
+               goto error;
+
+       /* Upload IQM Channel Filter settings by
+               boot loader from ROM table */
+       switch (oMode) {
+       case OM_QAM_ITU_A:
+               status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+               break;
+       case OM_QAM_ITU_C:
+               status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+               if (status < 0)
+                       goto error;
+               status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+               break;
+       default:
+               status = -EINVAL;
+       }
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_SYMMETRIC__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_RC_STRETCH__A, 21);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_CLP_LEN__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_CLP_TH__A, 448);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_SNS_LEN__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, IQM_FS_ADJ_SEL__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_RC_ADJ_SEL__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_ADJ_SEL__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_UPD_SEL__A, 0);
+       if (status < 0)
+               goto error;
+
+       /* IQM Impulse Noise Processing Unit */
+       status = write16(state, IQM_CF_CLP_VAL__A, 500);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_DATATH__A, 1000);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_BYPASSDET__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_DET_LCT__A, 0);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_WND_LEN__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_CF_PKDTH__A, 1);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_INC_BYPASS__A, 1);
+       if (status < 0)
+               goto error;
+
+       /* turn on IQMAF. Must be done before setAgc**() */
+       status = SetIqmAf(state, true);
+       if (status < 0)
+               goto error;
+       status = write16(state, IQM_AF_START_LOCK__A, 0x01);
+       if (status < 0)
+               goto error;
+
+       /* IQM will not be reset from here, sync ADC and update/init AGC */
+       status = ADCSynchronization(state);
+       if (status < 0)
+               goto error;
+
+       /* Set the FSM step period */
+       status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
+       if (status < 0)
+               goto error;
+
+       /* Halt SCU to enable safe non-atomic accesses */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
+       if (status < 0)
+               goto error;
+
+       /* No more resets of the IQM, current standard correctly set =>
+               now AGCs can be configured. */
+
+       status = InitAGC(state, true);
+       if (status < 0)
+               goto error;
+       status = SetPreSaw(state, &(state->m_qamPreSawCfg));
+       if (status < 0)
+               goto error;
+
+       /* Configure AGC's */
+       status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
+       if (status < 0)
+               goto error;
+       status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
+       if (status < 0)
+               goto error;
+
+       /* Activate SCU to enable SCU commands */
+       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int WriteGPIO(struct drxk_state *state)
+{
+       int status;
+       u16 value = 0;
+
+       dprintk(1, "\n");
+       /* stop lock indicator process */
+       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+       if (status < 0)
+               goto error;
+
+       /*  Write magic word to enable pdr reg write               */
+       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
+       if (status < 0)
+               goto error;
+
+       if (state->m_hasSAWSW) {
+               if (state->UIO_mask & 0x0001) { /* UIO-1 */
+                       /* write to io pad configuration register - output mode */
+                       status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
+                       if (status < 0)
+                               goto error;
+
+                       /* use corresponding bit in io data output registar */
+                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
+                       if (status < 0)
+                               goto error;
+                       if ((state->m_GPIO & 0x0001) == 0)
+                               value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
+                       else
+                               value |= 0x8000;        /* write one to 15th bit - 1st UIO */
+                       /* write back to io data output register */
+                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
+                       if (status < 0)
+                               goto error;
+               }
+               if (state->UIO_mask & 0x0002) { /* UIO-2 */
+                       /* write to io pad configuration register - output mode */
+                       status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
+                       if (status < 0)
+                               goto error;
+
+                       /* use corresponding bit in io data output registar */
+                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
+                       if (status < 0)
+                               goto error;
+                       if ((state->m_GPIO & 0x0002) == 0)
+                               value &= 0xBFFF;        /* write zero to 14th bit - 2st UIO */
+                       else
+                               value |= 0x4000;        /* write one to 14th bit - 2st UIO */
+                       /* write back to io data output register */
+                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
+                       if (status < 0)
+                               goto error;
+               }
+               if (state->UIO_mask & 0x0004) { /* UIO-3 */
+                       /* write to io pad configuration register - output mode */
+                       status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
+                       if (status < 0)
+                               goto error;
+
+                       /* use corresponding bit in io data output registar */
+                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
+                       if (status < 0)
+                               goto error;
+                       if ((state->m_GPIO & 0x0004) == 0)
+                               value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
+                       else
+                               value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
+                       /* write back to io data output register */
+                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
+                       if (status < 0)
+                               goto error;
+               }
+       }
+       /*  Write magic word to disable pdr reg write               */
+       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SwitchAntennaToQAM(struct drxk_state *state)
+{
+       int status = 0;
+       bool gpio_state;
+
+       dprintk(1, "\n");
+
+       if (!state->antenna_gpio)
+               return 0;
+
+       gpio_state = state->m_GPIO & state->antenna_gpio;
+
+       if (state->antenna_dvbt ^ gpio_state) {
+               /* Antenna is on DVB-T mode. Switch */
+               if (state->antenna_dvbt)
+                       state->m_GPIO &= ~state->antenna_gpio;
+               else
+                       state->m_GPIO |= state->antenna_gpio;
+               status = WriteGPIO(state);
+       }
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+static int SwitchAntennaToDVBT(struct drxk_state *state)
+{
+       int status = 0;
+       bool gpio_state;
+
+       dprintk(1, "\n");
+
+       if (!state->antenna_gpio)
+               return 0;
+
+       gpio_state = state->m_GPIO & state->antenna_gpio;
+
+       if (!(state->antenna_dvbt ^ gpio_state)) {
+               /* Antenna is on DVB-C mode. Switch */
+               if (state->antenna_dvbt)
+                       state->m_GPIO |= state->antenna_gpio;
+               else
+                       state->m_GPIO &= ~state->antenna_gpio;
+               status = WriteGPIO(state);
+       }
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       return status;
+}
+
+
+static int PowerDownDevice(struct drxk_state *state)
+{
+       /* Power down to requested mode */
+       /* Backup some register settings */
+       /* Set pins with possible pull-ups connected to them in input mode */
+       /* Analog power down */
+       /* ADC power down */
+       /* Power down device */
+       int status;
+
+       dprintk(1, "\n");
+       if (state->m_bPDownOpenBridge) {
+               /* Open I2C bridge before power down of DRXK */
+               status = ConfigureI2CBridge(state, true);
+               if (status < 0)
+                       goto error;
+       }
+       /* driver 0.9.0 */
+       status = DVBTEnableOFDMTokenRing(state, false);
+       if (status < 0)
+               goto error;
+
+       status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
+       if (status < 0)
+               goto error;
+       status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
+       if (status < 0)
+               goto error;
+       state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+       status = HI_CfgCommand(state);
+error:
+       if (status < 0)
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+
+       return status;
+}
+
+static int init_drxk(struct drxk_state *state)
+{
+       int status = 0, n = 0;
+       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+       u16 driverVersion;
+
+       dprintk(1, "\n");
+       if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
+               drxk_i2c_lock(state);
+               status = PowerUpDevice(state);
+               if (status < 0)
+                       goto error;
+               status = DRXX_Open(state);
+               if (status < 0)
+                       goto error;
+               /* Soft reset of OFDM-, sys- and osc-clockdomain */
+               status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
+               if (status < 0)
+                       goto error;
+               /* TODO is this needed, if yes how much delay in worst case scenario */
+               msleep(1);
+               state->m_DRXK_A3_PATCH_CODE = true;
+               status = GetDeviceCapabilities(state);
+               if (status < 0)
+                       goto error;
+
+               /* Bridge delay, uses oscilator clock */
+               /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
+               /* SDA brdige delay */
+               state->m_HICfgBridgeDelay =
+                       (u16) ((state->m_oscClockFreq / 1000) *
+                               HI_I2C_BRIDGE_DELAY) / 1000;
+               /* Clipping */
+               if (state->m_HICfgBridgeDelay >
+                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
+                       state->m_HICfgBridgeDelay =
+                               SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
+               }
+               /* SCL bridge delay, same as SDA for now */
+               state->m_HICfgBridgeDelay +=
+                       state->m_HICfgBridgeDelay <<
+                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
+
+               status = InitHI(state);
+               if (status < 0)
+                       goto error;
+               /* disable various processes */
+#if NOA1ROM
+               if (!(state->m_DRXK_A1_ROM_CODE)
+                       && !(state->m_DRXK_A2_ROM_CODE))
+#endif
+               {
+                       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+                       if (status < 0)
+                               goto error;
+               }
+
+               /* disable MPEG port */
+               status = MPEGTSDisable(state);
+               if (status < 0)
+                       goto error;
+
+               /* Stop AUD and SCU */
+               status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
+               if (status < 0)
+                       goto error;
+               status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
+               if (status < 0)
+                       goto error;
+
+               /* enable token-ring bus through OFDM block for possible ucode upload */
+               status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
+               if (status < 0)
+                       goto error;
+
+               /* include boot loader section */
+               status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
+               if (status < 0)
+                       goto error;
+               status = BLChainCmd(state, 0, 6, 100);
+               if (status < 0)
+                       goto error;
+
+               if (state->fw) {
+                       status = DownloadMicrocode(state, state->fw->data,
+                                                  state->fw->size);
+                       if (status < 0)
+                               goto error;
+               }
+
+               /* disable token-ring bus through OFDM block for possible ucode upload */
+               status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
+               if (status < 0)
+                       goto error;
+
+               /* Run SCU for a little while to initialize microcode version numbers */
+               status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
+               if (status < 0)
+                       goto error;
+               status = DRXX_Open(state);
+               if (status < 0)
+                       goto error;
+               /* added for test */
+               msleep(30);
+
+               powerMode = DRXK_POWER_DOWN_OFDM;
+               status = CtrlPowerMode(state, &powerMode);
+               if (status < 0)
+                       goto error;
+
+               /* Stamp driver version number in SCU data RAM in BCD code
+                       Done to enable field application engineers to retreive drxdriver version
+                       via I2C from SCU RAM.
+                       Not using SCU command interface for SCU register access since no
+                       microcode may be present.
+                       */
+               driverVersion =
+                       (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
+                       (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
+                       ((DRXK_VERSION_MAJOR % 10) << 4) +
+                       (DRXK_VERSION_MINOR % 10);
+               status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
+               if (status < 0)
+                       goto error;
+               driverVersion =
+                       (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
+                       (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
+                       (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
+                       (DRXK_VERSION_PATCH % 10);
+               status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
+               if (status < 0)
+                       goto error;
+
+               printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
+                       DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
+                       DRXK_VERSION_PATCH);
+
+               /* Dirty fix of default values for ROM/PATCH microcode
+                       Dirty because this fix makes it impossible to setup suitable values
+                       before calling DRX_Open. This solution requires changes to RF AGC speed
+                       to be done via the CTRL function after calling DRX_Open */
+
+               /* m_dvbtRfAgcCfg.speed = 3; */
+
+               /* Reset driver debug flags to 0 */
+               status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
+               if (status < 0)
+                       goto error;
+               /* driver 0.9.0 */
+               /* Setup FEC OC:
+                       NOTE: No more full FEC resets allowed afterwards!! */
+               status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
+               if (status < 0)
+                       goto error;
+               /* MPEGTS functions are still the same */
+               status = MPEGTSDtoInit(state);
+               if (status < 0)
+                       goto error;
+               status = MPEGTSStop(state);
+               if (status < 0)
+                       goto error;
+               status = MPEGTSConfigurePolarity(state);
+               if (status < 0)
+                       goto error;
+               status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
+               if (status < 0)
+                       goto error;
+               /* added: configure GPIO */
+               status = WriteGPIO(state);
+               if (status < 0)
+                       goto error;
+
+               state->m_DrxkState = DRXK_STOPPED;
+
+               if (state->m_bPowerDown) {
+                       status = PowerDownDevice(state);
+                       if (status < 0)
+                               goto error;
+                       state->m_DrxkState = DRXK_POWERED_DOWN;
+               } else
+                       state->m_DrxkState = DRXK_STOPPED;
+
+               /* Initialize the supported delivery systems */
+               n = 0;
+               if (state->m_hasDVBC) {
+                       state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
+                       state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
+                       strlcat(state->frontend.ops.info.name, " DVB-C",
+                               sizeof(state->frontend.ops.info.name));
+               }
+               if (state->m_hasDVBT) {
+                       state->frontend.ops.delsys[n++] = SYS_DVBT;
+                       strlcat(state->frontend.ops.info.name, " DVB-T",
+                               sizeof(state->frontend.ops.info.name));
+               }
+               drxk_i2c_unlock(state);
+       }
+error:
+       if (status < 0) {
+               state->m_DrxkState = DRXK_NO_DEV;
+               drxk_i2c_unlock(state);
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       }
+
+       return status;
+}
+
+static void load_firmware_cb(const struct firmware *fw,
+                            void *context)
+{
+       struct drxk_state *state = context;
+
+       dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
+       if (!fw) {
+               printk(KERN_ERR
+                      "drxk: Could not load firmware file %s.\n",
+                       state->microcode_name);
+               printk(KERN_INFO
+                      "drxk: Copy %s to your hotplug directory!\n",
+                       state->microcode_name);
+               state->microcode_name = NULL;
+
+               /*
+                * As firmware is now load asynchronous, it is not possible
+                * anymore to fail at frontend attach. We might silently
+                * return here, and hope that the driver won't crash.
+                * We might also change all DVB callbacks to return -ENODEV
+                * if the device is not initialized.
+                * As the DRX-K devices have their own internal firmware,
+                * let's just hope that it will match a firmware revision
+                * compatible with this driver and proceed.
+                */
+       }
+       state->fw = fw;
+
+       init_drxk(state);
+}
+
+static void drxk_release(struct dvb_frontend *fe)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+
+       dprintk(1, "\n");
+       if (state->fw)
+               release_firmware(state->fw);
+
+       kfree(state);
+}
+
+static int drxk_sleep(struct dvb_frontend *fe)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return 0;
+
+       ShutDown(state);
+       return 0;
+}
+
+static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+
+       dprintk(1, ": %s\n", enable ? "enable" : "disable");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+
+       return ConfigureI2CBridge(state, enable ? true : false);
+}
+
+static int drxk_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u32 delsys  = p->delivery_system, old_delsys;
+       struct drxk_state *state = fe->demodulator_priv;
+       u32 IF;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       if (!fe->ops.tuner_ops.get_if_frequency) {
+               printk(KERN_ERR
+                      "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
+               return -EINVAL;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       old_delsys = state->props.delivery_system;
+       state->props = *p;
+
+       if (old_delsys != delsys) {
+               ShutDown(state);
+               switch (delsys) {
+               case SYS_DVBC_ANNEX_A:
+               case SYS_DVBC_ANNEX_C:
+                       if (!state->m_hasDVBC)
+                               return -EINVAL;
+                       state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
+                       if (state->m_itut_annex_c)
+                               SetOperationMode(state, OM_QAM_ITU_C);
+                       else
+                               SetOperationMode(state, OM_QAM_ITU_A);
+                       break;
+               case SYS_DVBT:
+                       if (!state->m_hasDVBT)
+                               return -EINVAL;
+                       SetOperationMode(state, OM_DVBT);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       fe->ops.tuner_ops.get_if_frequency(fe, &IF);
+       Start(state, 0, IF);
+
+       /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
+
+       return 0;
+}
+
+static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+       u32 stat;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       *status = 0;
+       GetLockStatus(state, &stat, 0);
+       if (stat == MPEG_LOCK)
+               *status |= 0x1f;
+       if (stat == FEC_LOCK)
+               *status |= 0x0f;
+       if (stat == DEMOD_LOCK)
+               *status |= 0x07;
+       return 0;
+}
+
+static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       *ber = 0;
+       return 0;
+}
+
+static int drxk_read_signal_strength(struct dvb_frontend *fe,
+                                    u16 *strength)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+       u32 val = 0;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       ReadIFAgc(state, &val);
+       *strength = val & 0xffff;
+       return 0;
+}
+
+static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+       s32 snr2;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       GetSignalToNoise(state, &snr2);
+       *snr = snr2 & 0xffff;
+       return 0;
+}
+
+static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+       u16 err;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       DVBTQAMGetAccPktErr(state, &err);
+       *ucblocks = (u32) err;
+       return 0;
+}
+
+static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
+                                   *sets)
+{
+       struct drxk_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       dprintk(1, "\n");
+
+       if (state->m_DrxkState == DRXK_NO_DEV)
+               return -ENODEV;
+       if (state->m_DrxkState == DRXK_UNINITIALIZED)
+               return -EAGAIN;
+
+       switch (p->delivery_system) {
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+       case SYS_DVBT:
+               sets->min_delay_ms = 3000;
+               sets->max_drift = 0;
+               sets->step_size = 0;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static struct dvb_frontend_ops drxk_ops = {
+       /* .delsys will be filled dynamically */
+       .info = {
+               .name = "DRXK",
+               .frequency_min = 47000000,
+               .frequency_max = 865000000,
+                /* For DVB-C */
+               .symbol_rate_min = 870000,
+               .symbol_rate_max = 11700000,
+               /* For DVB-T */
+               .frequency_stepsize = 166667,
+
+               .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
+       },
+
+       .release = drxk_release,
+       .sleep = drxk_sleep,
+       .i2c_gate_ctrl = drxk_gate_ctrl,
+
+       .set_frontend = drxk_set_parameters,
+       .get_tune_settings = drxk_get_tune_settings,
+
+       .read_status = drxk_read_status,
+       .read_ber = drxk_read_ber,
+       .read_signal_strength = drxk_read_signal_strength,
+       .read_snr = drxk_read_snr,
+       .read_ucblocks = drxk_read_ucblocks,
+};
+
+struct dvb_frontend *drxk_attach(const struct drxk_config *config,
+                                struct i2c_adapter *i2c)
+{
+       struct drxk_state *state = NULL;
+       u8 adr = config->adr;
+       int status;
+
+       dprintk(1, "\n");
+       state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       state->i2c = i2c;
+       state->demod_address = adr;
+       state->single_master = config->single_master;
+       state->microcode_name = config->microcode_name;
+       state->qam_demod_parameter_count = config->qam_demod_parameter_count;
+       state->no_i2c_bridge = config->no_i2c_bridge;
+       state->antenna_gpio = config->antenna_gpio;
+       state->antenna_dvbt = config->antenna_dvbt;
+       state->m_ChunkSize = config->chunk_size;
+       state->enable_merr_cfg = config->enable_merr_cfg;
+
+       if (config->dynamic_clk) {
+               state->m_DVBTStaticCLK = 0;
+               state->m_DVBCStaticCLK = 0;
+       } else {
+               state->m_DVBTStaticCLK = 1;
+               state->m_DVBCStaticCLK = 1;
+       }
+
+
+       if (config->mpeg_out_clk_strength)
+               state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
+       else
+               state->m_TSClockkStrength = 0x06;
+
+       if (config->parallel_ts)
+               state->m_enableParallel = true;
+       else
+               state->m_enableParallel = false;
+
+       /* NOTE: as more UIO bits will be used, add them to the mask */
+       state->UIO_mask = config->antenna_gpio;
+
+       /* Default gpio to DVB-C */
+       if (!state->antenna_dvbt && state->antenna_gpio)
+               state->m_GPIO |= state->antenna_gpio;
+       else
+               state->m_GPIO &= ~state->antenna_gpio;
+
+       mutex_init(&state->mutex);
+
+       memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
+       state->frontend.demodulator_priv = state;
+
+       init_state(state);
+
+       /* Load firmware and initialize DRX-K */
+       if (state->microcode_name) {
+               status = request_firmware_nowait(THIS_MODULE, 1,
+                                             state->microcode_name,
+                                             state->i2c->dev.parent,
+                                             GFP_KERNEL,
+                                             state, load_firmware_cb);
+               if (status < 0) {
+                       printk(KERN_ERR
+                       "drxk: failed to request a firmware\n");
+                       return NULL;
+               }
+       } else if (init_drxk(state) < 0)
+               goto error;
+
+       printk(KERN_INFO "drxk: frontend initialized.\n");
+       return &state->frontend;
+
+error:
+       printk(KERN_ERR "drxk: not found\n");
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(drxk_attach);
+
+MODULE_DESCRIPTION("DRX-K driver");
+MODULE_AUTHOR("Ralph Metzler");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h
new file mode 100644 (file)
index 0000000..6bb9fc4
--- /dev/null
@@ -0,0 +1,364 @@
+#include "drxk_map.h"
+
+#define DRXK_VERSION_MAJOR 0
+#define DRXK_VERSION_MINOR 9
+#define DRXK_VERSION_PATCH 4300
+
+#define HI_I2C_DELAY        42
+#define HI_I2C_BRIDGE_DELAY 350
+#define DRXK_MAX_RETRIES    100
+
+#define DRIVER_4400 1
+
+#define DRXX_JTAGID   0x039210D9
+#define DRXX_J_JTAGID 0x239310D9
+#define DRXX_K_JTAGID 0x039210D9
+
+#define DRX_UNKNOWN     254
+#define DRX_AUTO        255
+
+#define DRX_SCU_READY   0
+#define DRXK_MAX_WAITTIME (200)
+#define SCU_RESULT_OK      0
+#define SCU_RESULT_SIZE   -4
+#define SCU_RESULT_INVPAR -3
+#define SCU_RESULT_UNKSTD -2
+#define SCU_RESULT_UNKCMD -1
+
+#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
+#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
+#endif
+
+#define DRXK_8VSB_MPEG_BIT_RATE     19392658UL  /*bps*/
+#define DRXK_DVBT_MPEG_BIT_RATE     32000000UL  /*bps*/
+#define DRXK_QAM16_MPEG_BIT_RATE    27000000UL  /*bps*/
+#define DRXK_QAM32_MPEG_BIT_RATE    33000000UL  /*bps*/
+#define DRXK_QAM64_MPEG_BIT_RATE    40000000UL  /*bps*/
+#define DRXK_QAM128_MPEG_BIT_RATE   46000000UL  /*bps*/
+#define DRXK_QAM256_MPEG_BIT_RATE   52000000UL  /*bps*/
+#define DRXK_MAX_MPEG_BIT_RATE      52000000UL  /*bps*/
+
+#define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
+#define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
+#define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
+#define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
+#define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
+#define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
+#define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
+
+enum OperationMode {
+       OM_NONE,
+       OM_QAM_ITU_A,
+       OM_QAM_ITU_B,
+       OM_QAM_ITU_C,
+       OM_DVBT
+};
+
+enum DRXPowerMode {
+       DRX_POWER_UP = 0,
+       DRX_POWER_MODE_1,
+       DRX_POWER_MODE_2,
+       DRX_POWER_MODE_3,
+       DRX_POWER_MODE_4,
+       DRX_POWER_MODE_5,
+       DRX_POWER_MODE_6,
+       DRX_POWER_MODE_7,
+       DRX_POWER_MODE_8,
+
+       DRX_POWER_MODE_9,
+       DRX_POWER_MODE_10,
+       DRX_POWER_MODE_11,
+       DRX_POWER_MODE_12,
+       DRX_POWER_MODE_13,
+       DRX_POWER_MODE_14,
+       DRX_POWER_MODE_15,
+       DRX_POWER_MODE_16,
+       DRX_POWER_DOWN = 255
+};
+
+
+/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
+#ifndef DRXK_POWER_DOWN_OFDM
+#define DRXK_POWER_DOWN_OFDM        DRX_POWER_MODE_1
+#endif
+
+/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
+#ifndef DRXK_POWER_DOWN_CORE
+#define DRXK_POWER_DOWN_CORE        DRX_POWER_MODE_9
+#endif
+
+/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
+#ifndef DRXK_POWER_DOWN_PLL
+#define DRXK_POWER_DOWN_PLL         DRX_POWER_MODE_10
+#endif
+
+
+enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
+enum EDrxkState {
+       DRXK_UNINITIALIZED = 0,
+       DRXK_STOPPED,
+       DRXK_DTV_STARTED,
+       DRXK_ATV_STARTED,
+       DRXK_POWERED_DOWN,
+       DRXK_NO_DEV                     /* If drxk init failed */
+};
+
+enum EDrxkCoefArrayIndex {
+       DRXK_COEF_IDX_MN = 0,
+       DRXK_COEF_IDX_FM    ,
+       DRXK_COEF_IDX_L     ,
+       DRXK_COEF_IDX_LP    ,
+       DRXK_COEF_IDX_BG    ,
+       DRXK_COEF_IDX_DK    ,
+       DRXK_COEF_IDX_I     ,
+       DRXK_COEF_IDX_MAX
+};
+enum EDrxkSifAttenuation {
+       DRXK_SIF_ATTENUATION_0DB,
+       DRXK_SIF_ATTENUATION_3DB,
+       DRXK_SIF_ATTENUATION_6DB,
+       DRXK_SIF_ATTENUATION_9DB
+};
+enum EDrxkConstellation {
+       DRX_CONSTELLATION_BPSK = 0,
+       DRX_CONSTELLATION_QPSK,
+       DRX_CONSTELLATION_PSK8,
+       DRX_CONSTELLATION_QAM16,
+       DRX_CONSTELLATION_QAM32,
+       DRX_CONSTELLATION_QAM64,
+       DRX_CONSTELLATION_QAM128,
+       DRX_CONSTELLATION_QAM256,
+       DRX_CONSTELLATION_QAM512,
+       DRX_CONSTELLATION_QAM1024,
+       DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
+       DRX_CONSTELLATION_AUTO    = DRX_AUTO
+};
+enum EDrxkInterleaveMode {
+       DRXK_QAM_I12_J17    = 16,
+       DRXK_QAM_I_UNKNOWN  = DRX_UNKNOWN
+};
+enum {
+       DRXK_SPIN_A1 = 0,
+       DRXK_SPIN_A2,
+       DRXK_SPIN_A3,
+       DRXK_SPIN_UNKNOWN
+};
+
+enum DRXKCfgDvbtSqiSpeed {
+       DRXK_DVBT_SQI_SPEED_FAST = 0,
+       DRXK_DVBT_SQI_SPEED_MEDIUM,
+       DRXK_DVBT_SQI_SPEED_SLOW,
+       DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
+} ;
+
+enum DRXFftmode_t {
+       DRX_FFTMODE_2K = 0,
+       DRX_FFTMODE_4K,
+       DRX_FFTMODE_8K,
+       DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
+       DRX_FFTMODE_AUTO    = DRX_AUTO
+};
+
+enum DRXMPEGStrWidth_t {
+       DRX_MPEG_STR_WIDTH_1,
+       DRX_MPEG_STR_WIDTH_8
+};
+
+enum DRXQamLockRange_t {
+       DRX_QAM_LOCKRANGE_NORMAL,
+       DRX_QAM_LOCKRANGE_EXTENDED
+};
+
+struct DRXKCfgDvbtEchoThres_t {
+       u16             threshold;
+       enum DRXFftmode_t      fftMode;
+} ;
+
+struct SCfgAgc {
+       enum AGC_CTRL_MODE     ctrlMode;        /* off, user, auto */
+       u16            outputLevel;     /* range dependent on AGC */
+       u16            minOutputLevel;  /* range dependent on AGC */
+       u16            maxOutputLevel;  /* range dependent on AGC */
+       u16            speed;           /* range dependent on AGC */
+       u16            top;             /* rf-agc take over point */
+       u16            cutOffCurrent;   /* rf-agc is accelerated if output current
+                                          is below cut-off current */
+       u16            IngainTgtMax;
+       u16            FastClipCtrlDelay;
+};
+
+struct SCfgPreSaw {
+       u16        reference; /* pre SAW reference value, range 0 .. 31 */
+       bool          usePreSaw; /* TRUE algorithms must use pre SAW sense */
+};
+
+struct DRXKOfdmScCmd_t {
+       u16 cmd;        /**< Command number */
+       u16 subcmd;     /**< Sub-command parameter*/
+       u16 param0;     /**< General purpous param */
+       u16 param1;     /**< General purpous param */
+       u16 param2;     /**< General purpous param */
+       u16 param3;     /**< General purpous param */
+       u16 param4;     /**< General purpous param */
+};
+
+struct drxk_state {
+       struct dvb_frontend frontend;
+       struct dtv_frontend_properties props;
+       struct device *dev;
+
+       struct i2c_adapter *i2c;
+       u8     demod_address;
+       void  *priv;
+
+       struct mutex mutex;
+
+       u32    m_Instance;           /**< Channel 1,2,3 or 4 */
+
+       int    m_ChunkSize;
+       u8 Chunk[256];
+
+       bool   m_hasLNA;
+       bool   m_hasDVBT;
+       bool   m_hasDVBC;
+       bool   m_hasAudio;
+       bool   m_hasATV;
+       bool   m_hasOOB;
+       bool   m_hasSAWSW;         /**< TRUE if mat_tx is available */
+       bool   m_hasGPIO1;         /**< TRUE if mat_rx is available */
+       bool   m_hasGPIO2;         /**< TRUE if GPIO is available */
+       bool   m_hasIRQN;          /**< TRUE if IRQN is available */
+       u16    m_oscClockFreq;
+       u16    m_HICfgTimingDiv;
+       u16    m_HICfgBridgeDelay;
+       u16    m_HICfgWakeUpKey;
+       u16    m_HICfgTimeout;
+       u16    m_HICfgCtrl;
+       s32    m_sysClockFreq;      /**< system clock frequency in kHz */
+
+       enum EDrxkState    m_DrxkState;      /**< State of Drxk (init,stopped,started) */
+       enum OperationMode m_OperationMode;  /**< digital standards */
+       struct SCfgAgc     m_vsbRfAgcCfg;    /**< settings for VSB RF-AGC */
+       struct SCfgAgc     m_vsbIfAgcCfg;    /**< settings for VSB IF-AGC */
+       u16                m_vsbPgaCfg;      /**< settings for VSB PGA */
+       struct SCfgPreSaw  m_vsbPreSawCfg;   /**< settings for pre SAW sense */
+       s32    m_Quality83percent;  /**< MER level (*0.1 dB) for 83% quality indication */
+       s32    m_Quality93percent;  /**< MER level (*0.1 dB) for 93% quality indication */
+       bool   m_smartAntInverted;
+       bool   m_bDebugEnableBridge;
+       bool   m_bPDownOpenBridge;  /**< only open DRXK bridge before power-down once it has been accessed */
+       bool   m_bPowerDown;        /**< Power down when not used */
+
+       u32    m_IqmFsRateOfs;      /**< frequency shift as written to DRXK register (28bit fixpoint) */
+
+       bool   m_enableMPEGOutput;  /**< If TRUE, enable MPEG output */
+       bool   m_insertRSByte;      /**< If TRUE, insert RS byte */
+       bool   m_enableParallel;    /**< If TRUE, parallel out otherwise serial */
+       bool   m_invertDATA;        /**< If TRUE, invert DATA signals */
+       bool   m_invertERR;         /**< If TRUE, invert ERR signal */
+       bool   m_invertSTR;         /**< If TRUE, invert STR signals */
+       bool   m_invertVAL;         /**< If TRUE, invert VAL signals */
+       bool   m_invertCLK;         /**< If TRUE, invert CLK signals */
+       bool   m_DVBCStaticCLK;
+       bool   m_DVBTStaticCLK;     /**< If TRUE, static MPEG clockrate will
+                                        be used, otherwise clockrate will
+                                        adapt to the bitrate of the TS */
+       u32    m_DVBTBitrate;
+       u32    m_DVBCBitrate;
+
+       u8     m_TSDataStrength;
+       u8     m_TSClockkStrength;
+
+       bool   m_itut_annex_c;      /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
+
+       enum DRXMPEGStrWidth_t  m_widthSTR;    /**< MPEG start width */
+       u32    m_mpegTsStaticBitrate;          /**< Maximum bitrate in b/s in case
+                                                   static clockrate is selected */
+
+       /* LARGE_INTEGER   m_StartTime; */     /**< Contains the time of the last demod start */
+       s32    m_MpegLockTimeOut;      /**< WaitForLockStatus Timeout (counts from start time) */
+       s32    m_DemodLockTimeOut;     /**< WaitForLockStatus Timeout (counts from start time) */
+
+       bool   m_disableTEIhandling;
+
+       bool   m_RfAgcPol;
+       bool   m_IfAgcPol;
+
+       struct SCfgAgc    m_atvRfAgcCfg;  /**< settings for ATV RF-AGC */
+       struct SCfgAgc    m_atvIfAgcCfg;  /**< settings for ATV IF-AGC */
+       struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
+       bool              m_phaseCorrectionBypass;
+       s16               m_atvTopVidPeak;
+       u16               m_atvTopNoiseTh;
+       enum EDrxkSifAttenuation m_sifAttenuation;
+       bool              m_enableCVBSOutput;
+       bool              m_enableSIFOutput;
+       bool              m_bMirrorFreqSpect;
+       enum EDrxkConstellation  m_Constellation; /**< Constellation type of the channel */
+       u32               m_CurrSymbolRate;       /**< Current QAM symbol rate */
+       struct SCfgAgc    m_qamRfAgcCfg;          /**< settings for QAM RF-AGC */
+       struct SCfgAgc    m_qamIfAgcCfg;          /**< settings for QAM IF-AGC */
+       u16               m_qamPgaCfg;            /**< settings for QAM PGA */
+       struct SCfgPreSaw m_qamPreSawCfg;         /**< settings for QAM pre SAW sense */
+       enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
+       u16               m_fecRsPlen;
+       u16               m_fecRsPrescale;
+
+       enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
+
+       u16               m_GPIO;
+       u16               m_GPIOCfg;
+
+       struct SCfgAgc    m_dvbtRfAgcCfg;     /**< settings for QAM RF-AGC */
+       struct SCfgAgc    m_dvbtIfAgcCfg;     /**< settings for QAM IF-AGC */
+       struct SCfgPreSaw m_dvbtPreSawCfg;    /**< settings for QAM pre SAW sense */
+
+       u16               m_agcFastClipCtrlDelay;
+       bool              m_adcCompPassed;
+       u16               m_adcCompCoef[64];
+       u16               m_adcState;
+
+       u8               *m_microcode;
+       int               m_microcode_length;
+       bool              m_DRXK_A1_PATCH_CODE;
+       bool              m_DRXK_A1_ROM_CODE;
+       bool              m_DRXK_A2_ROM_CODE;
+       bool              m_DRXK_A3_ROM_CODE;
+       bool              m_DRXK_A2_PATCH_CODE;
+       bool              m_DRXK_A3_PATCH_CODE;
+
+       bool              m_rfmirror;
+       u8                m_deviceSpin;
+       u32               m_iqmRcRate;
+
+       enum DRXPowerMode m_currentPowerMode;
+
+       /* when true, avoids other devices to use the I2C bus */
+       bool              drxk_i2c_exclusive_lock;
+
+       /*
+        * Configurable parameters at the driver. They stores the values found
+        * at struct drxk_config.
+        */
+
+       u16     UIO_mask;       /* Bits used by UIO */
+
+       bool    enable_merr_cfg;
+       bool    single_master;
+       bool    no_i2c_bridge;
+       bool    antenna_dvbt;
+       u16     antenna_gpio;
+
+       /* Firmware */
+       const char *microcode_name;
+       struct completion fw_wait_load;
+       const struct firmware *fw;
+       int qam_demod_parameter_count;
+};
+
+#define NEVER_LOCK 0
+#define NOT_LOCKED 1
+#define DEMOD_LOCK 2
+#define FEC_LOCK   3
+#define MPEG_LOCK  4
+
diff --git a/drivers/media/dvb-frontends/drxk_map.h b/drivers/media/dvb-frontends/drxk_map.h
new file mode 100644 (file)
index 0000000..23e16c1
--- /dev/null
@@ -0,0 +1,451 @@
+#define  AUD_COMM_EXEC__A                                                  0x1000000
+#define    AUD_COMM_EXEC_STOP                                              0x0
+#define  FEC_COMM_EXEC__A                                                  0x1C00000
+#define    FEC_COMM_EXEC_STOP                                              0x0
+#define    FEC_COMM_EXEC_ACTIVE                                            0x1
+#define  FEC_DI_COMM_EXEC__A                                               0x1C20000
+#define    FEC_DI_COMM_EXEC_STOP                                           0x0
+#define  FEC_DI_INPUT_CTL__A                                               0x1C20016
+#define  FEC_RS_COMM_EXEC__A                                               0x1C30000
+#define    FEC_RS_COMM_EXEC_STOP                                           0x0
+#define  FEC_RS_MEASUREMENT_PERIOD__A                                      0x1C30012
+#define  FEC_RS_MEASUREMENT_PRESCALE__A                                    0x1C30013
+#define  FEC_OC_MODE__A                                                    0x1C40011
+#define    FEC_OC_MODE_PARITY__M                                           0x1
+#define  FEC_OC_DTO_MODE__A                                                0x1C40014
+#define    FEC_OC_DTO_MODE_DYNAMIC__M                                      0x1
+#define    FEC_OC_DTO_MODE_OFFSET_ENABLE__M                                0x4
+#define  FEC_OC_DTO_PERIOD__A                                              0x1C40015
+#define  FEC_OC_DTO_BURST_LEN__A                                           0x1C40018
+#define  FEC_OC_FCT_MODE__A                                                0x1C4001A
+#define  FEC_OC_FCT_MODE__PRE                                              0x0
+#define    FEC_OC_FCT_MODE_RAT_ENA__M                                      0x1
+#define    FEC_OC_FCT_MODE_VIRT_ENA__M                                     0x2
+#define  FEC_OC_TMD_MODE__A                                                0x1C4001E
+#define  FEC_OC_TMD_COUNT__A                                               0x1C4001F
+#define  FEC_OC_TMD_HI_MARGIN__A                                           0x1C40020
+#define  FEC_OC_TMD_LO_MARGIN__A                                           0x1C40021
+#define  FEC_OC_TMD_INT_UPD_RATE__A                                        0x1C40023
+#define  FEC_OC_AVR_PARM_A__A                                              0x1C40026
+#define  FEC_OC_AVR_PARM_B__A                                              0x1C40027
+#define  FEC_OC_RCN_GAIN__A                                                0x1C4002E
+#define  FEC_OC_RCN_CTL_RATE_LO__A                                         0x1C40030
+#define  FEC_OC_RCN_CTL_STEP_LO__A                                         0x1C40032
+#define  FEC_OC_RCN_CTL_STEP_HI__A                                         0x1C40033
+#define  FEC_OC_SNC_MODE__A                                                0x1C40040
+#define    FEC_OC_SNC_MODE_SHUTDOWN__M                                     0x10
+#define  FEC_OC_SNC_LWM__A                                                 0x1C40041
+#define  FEC_OC_SNC_HWM__A                                                 0x1C40042
+#define  FEC_OC_SNC_UNLOCK__A                                              0x1C40043
+#define  FEC_OC_SNC_FAIL_PERIOD__A                                         0x1C40046
+#define  FEC_OC_IPR_MODE__A                                                0x1C40048
+#define    FEC_OC_IPR_MODE_SERIAL__M                                       0x1
+#define    FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M                             0x4
+#define    FEC_OC_IPR_MODE_MVAL_DIS_PAR__M                                 0x10
+#define  FEC_OC_IPR_INVERT__A                                              0x1C40049
+#define    FEC_OC_IPR_INVERT_MD0__M                                        0x1
+#define    FEC_OC_IPR_INVERT_MD1__M                                        0x2
+#define    FEC_OC_IPR_INVERT_MD2__M                                        0x4
+#define    FEC_OC_IPR_INVERT_MD3__M                                        0x8
+#define    FEC_OC_IPR_INVERT_MD4__M                                        0x10
+#define    FEC_OC_IPR_INVERT_MD5__M                                        0x20
+#define    FEC_OC_IPR_INVERT_MD6__M                                        0x40
+#define    FEC_OC_IPR_INVERT_MD7__M                                        0x80
+#define    FEC_OC_IPR_INVERT_MERR__M                                       0x100
+#define    FEC_OC_IPR_INVERT_MSTRT__M                                      0x200
+#define    FEC_OC_IPR_INVERT_MVAL__M                                       0x400
+#define    FEC_OC_IPR_INVERT_MCLK__M                                       0x800
+#define  FEC_OC_OCR_INVERT__A                                              0x1C40052
+#define  IQM_COMM_EXEC__A                                                  0x1800000
+#define      IQM_COMM_EXEC_B_STOP                                          0x0
+#define      IQM_COMM_EXEC_B_ACTIVE                                        0x1
+#define  IQM_FS_RATE_OFS_LO__A                                             0x1820010
+#define  IQM_FS_ADJ_SEL__A                                                 0x1820014
+#define      IQM_FS_ADJ_SEL_B_OFF                                          0x0
+#define      IQM_FS_ADJ_SEL_B_QAM                                          0x1
+#define      IQM_FS_ADJ_SEL_B_VSB                                          0x2
+#define  IQM_FD_RATESEL__A                                                 0x1830010
+#define  IQM_RC_RATE_OFS_LO__A                                             0x1840010
+#define  IQM_RC_RATE_OFS_LO__W                                             16
+#define  IQM_RC_RATE_OFS_LO__M                                             0xFFFF
+#define  IQM_RC_RATE_OFS_HI__M                                             0xFF
+#define  IQM_RC_ADJ_SEL__A                                                 0x1840014
+#define      IQM_RC_ADJ_SEL_B_OFF                                          0x0
+#define      IQM_RC_ADJ_SEL_B_QAM                                          0x1
+#define      IQM_RC_ADJ_SEL_B_VSB                                          0x2
+#define  IQM_RC_STRETCH__A                                                 0x1840016
+#define  IQM_CF_COMM_INT_MSK__A                                            0x1860006
+#define  IQM_CF_SYMMETRIC__A                                               0x1860010
+#define  IQM_CF_MIDTAP__A                                                  0x1860011
+#define    IQM_CF_MIDTAP_RE__B                                             0
+#define    IQM_CF_MIDTAP_IM__B                                             1
+#define  IQM_CF_OUT_ENA__A                                                 0x1860012
+#define    IQM_CF_OUT_ENA_QAM__B                                           1
+#define    IQM_CF_OUT_ENA_OFDM__M                                          0x4
+#define  IQM_CF_ADJ_SEL__A                                                 0x1860013
+#define  IQM_CF_SCALE__A                                                   0x1860014
+#define  IQM_CF_SCALE_SH__A                                                0x1860015
+#define  IQM_CF_SCALE_SH__PRE                                              0x0
+#define  IQM_CF_POW_MEAS_LEN__A                                            0x1860017
+#define  IQM_CF_DS_ENA__A                                                  0x1860019
+#define  IQM_CF_TAP_RE0__A                                                 0x1860020
+#define  IQM_CF_TAP_IM0__A                                                 0x1860040
+#define  IQM_CF_CLP_VAL__A                                                 0x1860060
+#define  IQM_CF_DATATH__A                                                  0x1860061
+#define  IQM_CF_PKDTH__A                                                   0x1860062
+#define  IQM_CF_WND_LEN__A                                                 0x1860063
+#define  IQM_CF_DET_LCT__A                                                 0x1860064
+#define  IQM_CF_BYPASSDET__A                                               0x1860067
+#define  IQM_AF_COMM_EXEC__A                                               0x1870000
+#define    IQM_AF_COMM_EXEC_ACTIVE                                         0x1
+#define  IQM_AF_CLKNEG__A                                                  0x1870012
+#define    IQM_AF_CLKNEG_CLKNEGDATA__M                                     0x2
+#define      IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS                     0x0
+#define      IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG                     0x2
+#define  IQM_AF_START_LOCK__A                                              0x187001B
+#define  IQM_AF_PHASE0__A                                                  0x187001C
+#define  IQM_AF_PHASE1__A                                                  0x187001D
+#define  IQM_AF_PHASE2__A                                                  0x187001E
+#define  IQM_AF_CLP_LEN__A                                                 0x1870023
+#define  IQM_AF_CLP_TH__A                                                  0x1870024
+#define  IQM_AF_SNS_LEN__A                                                 0x1870026
+#define  IQM_AF_AGC_IF__A                                                  0x1870028
+#define  IQM_AF_AGC_RF__A                                                  0x1870029
+#define  IQM_AF_PDREF__A                                                   0x187002B
+#define  IQM_AF_PDREF__M                                                   0x1F
+#define  IQM_AF_STDBY__A                                                   0x187002C
+#define      IQM_AF_STDBY_STDBY_ADC_STANDBY                                0x2
+#define      IQM_AF_STDBY_STDBY_AMP_STANDBY                                0x4
+#define      IQM_AF_STDBY_STDBY_PD_STANDBY                                 0x8
+#define      IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY                            0x10
+#define      IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY                            0x20
+#define  IQM_AF_AMUX__A                                                    0x187002D
+#define    IQM_AF_AMUX_SIGNAL2ADC                                          0x1
+#define  IQM_AF_UPD_SEL__A                                                 0x187002F
+#define  IQM_AF_INC_LCT__A                                                 0x1870034
+#define  IQM_AF_INC_BYPASS__A                                              0x1870036
+#define  OFDM_CP_COMM_EXEC__A                                              0x2800000
+#define    OFDM_CP_COMM_EXEC_STOP                                          0x0
+#define  OFDM_EC_SB_PRIOR__A                                               0x3410013
+#define    OFDM_EC_SB_PRIOR_HI                                             0x0
+#define    OFDM_EC_SB_PRIOR_LO                                             0x1
+#define  OFDM_EQ_TOP_TD_TPS_CONST__A                                       0x3010054
+#define  OFDM_EQ_TOP_TD_TPS_CONST__M                                       0x3
+#define    OFDM_EQ_TOP_TD_TPS_CONST_64QAM                                  0x2
+#define  OFDM_EQ_TOP_TD_TPS_CODE_HP__A                                     0x3010056
+#define  OFDM_EQ_TOP_TD_TPS_CODE_HP__M                                     0x7
+#define    OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8                                  0x4
+#define  OFDM_EQ_TOP_TD_SQR_ERR_I__A                                       0x301005E
+#define  OFDM_EQ_TOP_TD_SQR_ERR_Q__A                                       0x301005F
+#define  OFDM_EQ_TOP_TD_SQR_ERR_EXP__A                                     0x3010060
+#define  OFDM_EQ_TOP_TD_REQ_SMB_CNT__A                                     0x3010061
+#define  OFDM_EQ_TOP_TD_TPS_PWR_OFS__A                                     0x3010062
+#define  OFDM_LC_COMM_EXEC__A                                              0x3800000
+#define    OFDM_LC_COMM_EXEC_STOP                                          0x0
+#define  OFDM_SC_COMM_EXEC__A                                              0x3C00000
+#define    OFDM_SC_COMM_EXEC_STOP                                          0x0
+#define  OFDM_SC_COMM_STATE__A                                             0x3C00001
+#define  OFDM_SC_RA_RAM_PARAM0__A                                          0x3C20040
+#define  OFDM_SC_RA_RAM_PARAM1__A                                          0x3C20041
+#define  OFDM_SC_RA_RAM_CMD_ADDR__A                                        0x3C20042
+#define  OFDM_SC_RA_RAM_CMD__A                                             0x3C20043
+#define    OFDM_SC_RA_RAM_CMD_NULL                                         0x0
+#define    OFDM_SC_RA_RAM_CMD_PROC_START                                   0x1
+#define    OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM                               0x3
+#define    OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM                                0x4
+#define    OFDM_SC_RA_RAM_CMD_GET_OP_PARAM                                 0x5
+#define    OFDM_SC_RA_RAM_CMD_USER_IO                                      0x6
+#define    OFDM_SC_RA_RAM_CMD_SET_TIMER                                    0x7
+#define    OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING                              0x8
+#define    OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M                            0x1
+#define    OFDM_SC_RA_RAM_LOCKTRACK_MIN                                    0x1
+#define  OFDM_SC_RA_RAM_OP_PARAM__A                                        0x3C20048
+#define    OFDM_SC_RA_RAM_OP_PARAM_MODE__M                                 0x3
+#define      OFDM_SC_RA_RAM_OP_PARAM_MODE_2K                               0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_MODE_8K                               0x1
+#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_32                              0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_16                              0x4
+#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_8                               0x8
+#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_4                               0xC
+#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK                            0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16                           0x10
+#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64                           0x20
+#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_NO                               0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A1                               0x40
+#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A2                               0x80
+#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A4                               0xC0
+#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2                              0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3                              0x200
+#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4                              0x400
+#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6                              0x600
+#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8                              0x800
+#define      OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI                               0x0
+#define      OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO                               0x1000
+#define    OFDM_SC_RA_RAM_OP_AUTO_MODE__M                                  0x1
+#define    OFDM_SC_RA_RAM_OP_AUTO_GUARD__M                                 0x2
+#define    OFDM_SC_RA_RAM_OP_AUTO_CONST__M                                 0x4
+#define    OFDM_SC_RA_RAM_OP_AUTO_HIER__M                                  0x8
+#define    OFDM_SC_RA_RAM_OP_AUTO_RATE__M                                  0x10
+#define  OFDM_SC_RA_RAM_LOCK__A                                            0x3C2004B
+#define    OFDM_SC_RA_RAM_LOCK_DEMOD__M                                    0x1
+#define    OFDM_SC_RA_RAM_LOCK_FEC__M                                      0x2
+#define    OFDM_SC_RA_RAM_LOCK_MPEG__M                                     0x4
+#define    OFDM_SC_RA_RAM_LOCK_NODVBT__M                                   0x8
+#define  OFDM_SC_RA_RAM_BE_OPT_DELAY__A                                    0x3C2004D
+#define  OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A                               0x3C2004E
+#define  OFDM_SC_RA_RAM_ECHO_THRES__A                                      0x3C2004F
+#define    OFDM_SC_RA_RAM_ECHO_THRES_8K__B                                 0
+#define    OFDM_SC_RA_RAM_ECHO_THRES_8K__M                                 0xFF
+#define    OFDM_SC_RA_RAM_ECHO_THRES_2K__B                                 8
+#define    OFDM_SC_RA_RAM_ECHO_THRES_2K__M                                 0xFF00
+#define  OFDM_SC_RA_RAM_CONFIG__A                                          0x3C20050
+#define    OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M                          0x800
+#define  OFDM_SC_RA_RAM_FR_THRES_8K__A                                     0x3C2007D
+#define  OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A                             0x3C200E0
+#define  OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A                            0x3C200E1
+#define  OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A                             0x3C200E3
+#define  OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A                            0x3C200E4
+#define  OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A                                0x3C200F8
+#define  QAM_COMM_EXEC__A                                                  0x1400000
+#define    QAM_COMM_EXEC_STOP                                              0x0
+#define    QAM_COMM_EXEC_ACTIVE                                            0x1
+#define    QAM_TOP_ANNEX_A                                                 0x0
+#define    QAM_TOP_ANNEX_C                                                 0x2
+#define  QAM_SL_ERR_POWER__A                                               0x1430017
+#define  QAM_DQ_QUAL_FUN0__A                                               0x1440018
+#define  QAM_DQ_QUAL_FUN1__A                                               0x1440019
+#define  QAM_DQ_QUAL_FUN2__A                                               0x144001A
+#define  QAM_DQ_QUAL_FUN3__A                                               0x144001B
+#define  QAM_DQ_QUAL_FUN4__A                                               0x144001C
+#define  QAM_DQ_QUAL_FUN5__A                                               0x144001D
+#define  QAM_LC_MODE__A                                                    0x1450010
+#define  QAM_LC_QUAL_TAB0__A                                               0x1450018
+#define  QAM_LC_QUAL_TAB1__A                                               0x1450019
+#define  QAM_LC_QUAL_TAB2__A                                               0x145001A
+#define  QAM_LC_QUAL_TAB3__A                                               0x145001B
+#define  QAM_LC_QUAL_TAB4__A                                               0x145001C
+#define  QAM_LC_QUAL_TAB5__A                                               0x145001D
+#define  QAM_LC_QUAL_TAB6__A                                               0x145001E
+#define  QAM_LC_QUAL_TAB8__A                                               0x145001F
+#define  QAM_LC_QUAL_TAB9__A                                               0x1450020
+#define  QAM_LC_QUAL_TAB10__A                                              0x1450021
+#define  QAM_LC_QUAL_TAB12__A                                              0x1450022
+#define  QAM_LC_QUAL_TAB15__A                                              0x1450023
+#define  QAM_LC_QUAL_TAB16__A                                              0x1450024
+#define  QAM_LC_QUAL_TAB20__A                                              0x1450025
+#define  QAM_LC_QUAL_TAB25__A                                              0x1450026
+#define  QAM_LC_LPF_FACTORP__A                                             0x1450028
+#define  QAM_LC_LPF_FACTORI__A                                             0x1450029
+#define  QAM_LC_RATE_LIMIT__A                                              0x145002A
+#define  QAM_LC_SYMBOL_FREQ__A                                             0x145002B
+#define  QAM_SY_TIMEOUT__A                                                 0x1470011
+#define  QAM_SY_TIMEOUT__PRE                                               0x3A98
+#define  QAM_SY_SYNC_LWM__A                                                0x1470012
+#define  QAM_SY_SYNC_AWM__A                                                0x1470013
+#define  QAM_SY_SYNC_HWM__A                                                0x1470014
+#define  QAM_SY_SP_INV__A                                                  0x1470017
+#define    QAM_SY_SP_INV_SPECTRUM_INV_DIS                                  0x0
+#define  SCU_COMM_EXEC__A                                                  0x800000
+#define    SCU_COMM_EXEC_STOP                                              0x0
+#define    SCU_COMM_EXEC_ACTIVE                                            0x1
+#define    SCU_COMM_EXEC_HOLD                                              0x2
+#define  SCU_RAM_DRIVER_DEBUG__A                                           0x831EBF
+#define  SCU_RAM_QAM_FSM_STEP_PERIOD__A                                    0x831EC4
+#define  SCU_RAM_GPIO__A                                                   0x831EC7
+#define      SCU_RAM_GPIO_HW_LOCK_IND_DISABLE                              0x0
+#define  SCU_RAM_AGC_CLP_CTRL_MODE__A                                      0x831EC8
+#define  SCU_RAM_FEC_ACCUM_PKT_FAILURES__A                                 0x831ECB
+#define  SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A                               0x831F05
+#define  SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A                                0x831F15
+#define  SCU_RAM_AGC_KI_CYCLEN__A                                          0x831F17
+#define  SCU_RAM_AGC_SNS_CYCLEN__A                                         0x831F18
+#define  SCU_RAM_AGC_RF_SNS_DEV_MAX__A                                     0x831F19
+#define  SCU_RAM_AGC_RF_SNS_DEV_MIN__A                                     0x831F1A
+#define  SCU_RAM_AGC_RF_MAX__A                                             0x831F1B
+#define  SCU_RAM_AGC_CONFIG__A                                             0x831F24
+#define    SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M                            0x1
+#define    SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M                            0x2
+#define    SCU_RAM_AGC_CONFIG_INV_IF_POL__M                                0x100
+#define    SCU_RAM_AGC_CONFIG_INV_RF_POL__M                                0x200
+#define  SCU_RAM_AGC_KI__A                                                 0x831F25
+#define    SCU_RAM_AGC_KI_RF__B                                            4
+#define    SCU_RAM_AGC_KI_RF__M                                            0xF0
+#define    SCU_RAM_AGC_KI_IF__B                                            8
+#define    SCU_RAM_AGC_KI_IF__M                                            0xF00
+#define  SCU_RAM_AGC_KI_RED__A                                             0x831F26
+#define    SCU_RAM_AGC_KI_RED_RAGC_RED__B                                  2
+#define    SCU_RAM_AGC_KI_RED_RAGC_RED__M                                  0xC
+#define    SCU_RAM_AGC_KI_RED_IAGC_RED__B                                  4
+#define    SCU_RAM_AGC_KI_RED_IAGC_RED__M                                  0x30
+#define  SCU_RAM_AGC_KI_INNERGAIN_MIN__A                                   0x831F27
+#define  SCU_RAM_AGC_KI_MINGAIN__A                                         0x831F28
+#define  SCU_RAM_AGC_KI_MAXGAIN__A                                         0x831F29
+#define  SCU_RAM_AGC_KI_MAXMINGAIN_TH__A                                   0x831F2A
+#define  SCU_RAM_AGC_KI_MIN__A                                             0x831F2B
+#define  SCU_RAM_AGC_KI_MAX__A                                             0x831F2C
+#define  SCU_RAM_AGC_CLP_SUM__A                                            0x831F2D
+#define  SCU_RAM_AGC_CLP_SUM_MIN__A                                        0x831F2E
+#define  SCU_RAM_AGC_CLP_SUM_MAX__A                                        0x831F2F
+#define  SCU_RAM_AGC_CLP_CYCLEN__A                                         0x831F30
+#define  SCU_RAM_AGC_CLP_CYCCNT__A                                         0x831F31
+#define  SCU_RAM_AGC_CLP_DIR_TO__A                                         0x831F32
+#define  SCU_RAM_AGC_CLP_DIR_WD__A                                         0x831F33
+#define  SCU_RAM_AGC_CLP_DIR_STP__A                                        0x831F34
+#define  SCU_RAM_AGC_SNS_SUM__A                                            0x831F35
+#define  SCU_RAM_AGC_SNS_SUM_MIN__A                                        0x831F36
+#define  SCU_RAM_AGC_SNS_SUM_MAX__A                                        0x831F37
+#define  SCU_RAM_AGC_SNS_CYCCNT__A                                         0x831F38
+#define  SCU_RAM_AGC_SNS_DIR_TO__A                                         0x831F39
+#define  SCU_RAM_AGC_SNS_DIR_WD__A                                         0x831F3A
+#define  SCU_RAM_AGC_SNS_DIR_STP__A                                        0x831F3B
+#define  SCU_RAM_AGC_INGAIN_TGT__A                                         0x831F3D
+#define  SCU_RAM_AGC_INGAIN_TGT_MIN__A                                     0x831F3E
+#define  SCU_RAM_AGC_INGAIN_TGT_MAX__A                                     0x831F3F
+#define  SCU_RAM_AGC_IF_IACCU_HI__A                                        0x831F40
+#define  SCU_RAM_AGC_IF_IACCU_LO__A                                        0x831F41
+#define  SCU_RAM_AGC_IF_IACCU_HI_TGT__A                                    0x831F42
+#define  SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A                                0x831F43
+#define  SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A                                0x831F44
+#define  SCU_RAM_AGC_RF_IACCU_HI__A                                        0x831F45
+#define  SCU_RAM_AGC_RF_IACCU_LO__A                                        0x831F46
+#define  SCU_RAM_AGC_RF_IACCU_HI_CO__A                                     0x831F47
+#define  SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A                                 0x831F84
+#define  SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A                                0x831F85
+#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A                                  0x831F86
+#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A                                  0x831F87
+#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A                                  0x831F88
+#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A                                  0x831F89
+#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A                                  0x831F8A
+#define  SCU_RAM_QAM_FSM_RTH__A                                            0x831F8E
+#define  SCU_RAM_QAM_FSM_FTH__A                                            0x831F8F
+#define  SCU_RAM_QAM_FSM_PTH__A                                            0x831F90
+#define  SCU_RAM_QAM_FSM_MTH__A                                            0x831F91
+#define  SCU_RAM_QAM_FSM_CTH__A                                            0x831F92
+#define  SCU_RAM_QAM_FSM_QTH__A                                            0x831F93
+#define  SCU_RAM_QAM_FSM_RATE_LIM__A                                       0x831F94
+#define  SCU_RAM_QAM_FSM_FREQ_LIM__A                                       0x831F95
+#define  SCU_RAM_QAM_FSM_COUNT_LIM__A                                      0x831F96
+#define  SCU_RAM_QAM_LC_CA_COARSE__A                                       0x831F97
+#define  SCU_RAM_QAM_LC_CA_FINE__A                                         0x831F99
+#define  SCU_RAM_QAM_LC_CP_COARSE__A                                       0x831F9A
+#define  SCU_RAM_QAM_LC_CP_MEDIUM__A                                       0x831F9B
+#define  SCU_RAM_QAM_LC_CP_FINE__A                                         0x831F9C
+#define  SCU_RAM_QAM_LC_CI_COARSE__A                                       0x831F9D
+#define  SCU_RAM_QAM_LC_CI_MEDIUM__A                                       0x831F9E
+#define  SCU_RAM_QAM_LC_CI_FINE__A                                         0x831F9F
+#define  SCU_RAM_QAM_LC_EP_COARSE__A                                       0x831FA0
+#define  SCU_RAM_QAM_LC_EP_MEDIUM__A                                       0x831FA1
+#define  SCU_RAM_QAM_LC_EP_FINE__A                                         0x831FA2
+#define  SCU_RAM_QAM_LC_EI_COARSE__A                                       0x831FA3
+#define  SCU_RAM_QAM_LC_EI_MEDIUM__A                                       0x831FA4
+#define  SCU_RAM_QAM_LC_EI_FINE__A                                         0x831FA5
+#define  SCU_RAM_QAM_LC_CF_COARSE__A                                       0x831FA6
+#define  SCU_RAM_QAM_LC_CF_MEDIUM__A                                       0x831FA7
+#define  SCU_RAM_QAM_LC_CF_FINE__A                                         0x831FA8
+#define  SCU_RAM_QAM_LC_CF1_COARSE__A                                      0x831FA9
+#define  SCU_RAM_QAM_LC_CF1_MEDIUM__A                                      0x831FAA
+#define  SCU_RAM_QAM_LC_CF1_FINE__A                                        0x831FAB
+#define  SCU_RAM_QAM_SL_SIG_POWER__A                                       0x831FAC
+#define  SCU_RAM_QAM_EQ_CMA_RAD0__A                                        0x831FAD
+#define  SCU_RAM_QAM_EQ_CMA_RAD1__A                                        0x831FAE
+#define  SCU_RAM_QAM_EQ_CMA_RAD2__A                                        0x831FAF
+#define  SCU_RAM_QAM_EQ_CMA_RAD3__A                                        0x831FB0
+#define  SCU_RAM_QAM_EQ_CMA_RAD4__A                                        0x831FB1
+#define  SCU_RAM_QAM_EQ_CMA_RAD5__A                                        0x831FB2
+#define      SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED                        0x4000
+#define      SCU_RAM_QAM_LOCKED_LOCKED_LOCKED                              0x8000
+#define      SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK                          0xC000
+#define  SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A                                0x831FEA
+#define  SCU_RAM_DRIVER_VER_HI__A                                          0x831FEB
+#define  SCU_RAM_DRIVER_VER_LO__A                                          0x831FEC
+#define  SCU_RAM_PARAM_15__A                                               0x831FED
+#define  SCU_RAM_PARAM_0__A                                                0x831FFC
+#define  SCU_RAM_COMMAND__A                                                0x831FFD
+#define    SCU_RAM_COMMAND_CMD_DEMOD_RESET                                 0x1
+#define    SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV                               0x2
+#define    SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM                             0x3
+#define    SCU_RAM_COMMAND_CMD_DEMOD_START                                 0x4
+#define    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK                              0x5
+#define    SCU_RAM_COMMAND_CMD_DEMOD_STOP                                  0x9
+#define      SCU_RAM_COMMAND_STANDARD_QAM                                  0x200
+#define      SCU_RAM_COMMAND_STANDARD_OFDM                                 0x400
+#define  SIO_TOP_COMM_KEY__A                                               0x41000F
+#define    SIO_TOP_COMM_KEY_KEY                                            0xFABA
+#define  SIO_TOP_JTAGID_LO__A                                              0x410012
+#define  SIO_HI_RA_RAM_RES__A                                              0x420031
+#define  SIO_HI_RA_RAM_CMD__A                                              0x420032
+#define    SIO_HI_RA_RAM_CMD_RESET                                         0x2
+#define    SIO_HI_RA_RAM_CMD_CONFIG                                        0x3
+#define    SIO_HI_RA_RAM_CMD_BRDCTRL                                       0x7
+#define  SIO_HI_RA_RAM_PAR_1__A                                            0x420033
+#define      SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY                              0x3945
+#define  SIO_HI_RA_RAM_PAR_2__A                                            0x420034
+#define    SIO_HI_RA_RAM_PAR_2_CFG_DIV__M                                  0x7F
+#define      SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN                              0x0
+#define      SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED                            0x4
+#define  SIO_HI_RA_RAM_PAR_3__A                                            0x420035
+#define    SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M                              0x7F
+#define    SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B                              7
+#define      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ                               0x0
+#define      SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE                              0x8
+#define  SIO_HI_RA_RAM_PAR_4__A                                            0x420036
+#define  SIO_HI_RA_RAM_PAR_5__A                                            0x420037
+#define      SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE                            0x1
+#define    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M                                0x8
+#define      SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ                             0x8
+#define  SIO_HI_RA_RAM_PAR_6__A                                            0x420038
+#define  SIO_CC_PLL_LOCK__A                                                0x450012
+#define  SIO_CC_PWD_MODE__A                                                0x450015
+#define      SIO_CC_PWD_MODE_LEVEL_NONE                                    0x0
+#define      SIO_CC_PWD_MODE_LEVEL_OFDM                                    0x1
+#define      SIO_CC_PWD_MODE_LEVEL_CLOCK                                   0x2
+#define      SIO_CC_PWD_MODE_LEVEL_PLL                                     0x3
+#define      SIO_CC_PWD_MODE_LEVEL_OSC                                     0x4
+#define  SIO_CC_SOFT_RST__A                                                0x450016
+#define    SIO_CC_SOFT_RST_OFDM__M                                         0x1
+#define    SIO_CC_SOFT_RST_SYS__M                                          0x2
+#define    SIO_CC_SOFT_RST_OSC__M                                          0x4
+#define  SIO_CC_UPDATE__A                                                  0x450017
+#define    SIO_CC_UPDATE_KEY                                               0xFABA
+#define  SIO_OFDM_SH_OFDM_RING_ENABLE__A                                   0x470010
+#define    SIO_OFDM_SH_OFDM_RING_ENABLE_OFF                                0x0
+#define    SIO_OFDM_SH_OFDM_RING_ENABLE_ON                                 0x1
+#define  SIO_OFDM_SH_OFDM_RING_STATUS__A                                   0x470012
+#define    SIO_OFDM_SH_OFDM_RING_STATUS_DOWN                               0x0
+#define    SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED                            0x1
+#define  SIO_BL_COMM_EXEC__A                                               0x480000
+#define    SIO_BL_COMM_EXEC_ACTIVE                                         0x1
+#define  SIO_BL_STATUS__A                                                  0x480010
+#define  SIO_BL_MODE__A                                                    0x480011
+#define    SIO_BL_MODE_DIRECT                                              0x0
+#define    SIO_BL_MODE_CHAIN                                               0x1
+#define  SIO_BL_ENABLE__A                                                  0x480012
+#define    SIO_BL_ENABLE_ON                                                0x1
+#define  SIO_BL_TGT_HDR__A                                                 0x480014
+#define  SIO_BL_TGT_ADDR__A                                                0x480015
+#define  SIO_BL_SRC_ADDR__A                                                0x480016
+#define  SIO_BL_SRC_LEN__A                                                 0x480017
+#define  SIO_BL_CHAIN_ADDR__A                                              0x480018
+#define  SIO_BL_CHAIN_LEN__A                                               0x480019
+#define  SIO_PDR_MON_CFG__A                                                0x7F0010
+#define  SIO_PDR_UIO_IN_HI__A                                              0x7F0015
+#define  SIO_PDR_UIO_OUT_LO__A                                             0x7F0016
+#define  SIO_PDR_OHW_CFG__A                                                0x7F001F
+#define    SIO_PDR_OHW_CFG_FREF_SEL__M                                     0x3
+#define  SIO_PDR_GPIO_CFG__A                                               0x7F0021
+#define  SIO_PDR_MSTRT_CFG__A                                              0x7F0025
+#define  SIO_PDR_MERR_CFG__A                                               0x7F0026
+#define  SIO_PDR_MCLK_CFG__A                                               0x7F0028
+#define    SIO_PDR_MCLK_CFG_DRIVE__B                                       3
+#define  SIO_PDR_MVAL_CFG__A                                               0x7F0029
+#define  SIO_PDR_MD0_CFG__A                                                0x7F002A
+#define    SIO_PDR_MD0_CFG_DRIVE__B                                        3
+#define  SIO_PDR_MD1_CFG__A                                                0x7F002B
+#define  SIO_PDR_MD2_CFG__A                                                0x7F002C
+#define  SIO_PDR_MD3_CFG__A                                                0x7F002D
+#define  SIO_PDR_MD4_CFG__A                                                0x7F002F
+#define  SIO_PDR_MD5_CFG__A                                                0x7F0030
+#define  SIO_PDR_MD6_CFG__A                                                0x7F0031
+#define  SIO_PDR_MD7_CFG__A                                                0x7F0032
+#define  SIO_PDR_SMA_RX_CFG__A                                             0x7F0037
+#define  SIO_PDR_SMA_TX_CFG__A                                             0x7F0038
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
new file mode 100644 (file)
index 0000000..4c8ac26
--- /dev/null
@@ -0,0 +1,1312 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "ds3000.h"
+
+static int debug;
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(args); \
+       } while (0)
+
+/* as of March 2009 current DS3000 firmware version is 1.78 */
+/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
+#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
+
+#define DS3000_SAMPLE_RATE 96000 /* in kHz */
+#define DS3000_XTAL_FREQ   27000 /* in kHz */
+
+/* Register values to initialise the demod in DVB-S mode */
+static u8 ds3000_dvbs_init_tab[] = {
+       0x23, 0x05,
+       0x08, 0x03,
+       0x0c, 0x00,
+       0x21, 0x54,
+       0x25, 0x82,
+       0x27, 0x31,
+       0x30, 0x08,
+       0x31, 0x40,
+       0x32, 0x32,
+       0x33, 0x35,
+       0x35, 0xff,
+       0x3a, 0x00,
+       0x37, 0x10,
+       0x38, 0x10,
+       0x39, 0x02,
+       0x42, 0x60,
+       0x4a, 0x40,
+       0x4b, 0x04,
+       0x4d, 0x91,
+       0x5d, 0xc8,
+       0x50, 0x77,
+       0x51, 0x77,
+       0x52, 0x36,
+       0x53, 0x36,
+       0x56, 0x01,
+       0x63, 0x43,
+       0x64, 0x30,
+       0x65, 0x40,
+       0x68, 0x26,
+       0x69, 0x4c,
+       0x70, 0x20,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x40,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x60,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x80,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0xa0,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x1f,
+       0x76, 0x00,
+       0x77, 0xd1,
+       0x78, 0x0c,
+       0x79, 0x80,
+       0x7f, 0x04,
+       0x7c, 0x00,
+       0x80, 0x86,
+       0x81, 0xa6,
+       0x85, 0x04,
+       0xcd, 0xf4,
+       0x90, 0x33,
+       0xa0, 0x44,
+       0xc0, 0x18,
+       0xc3, 0x10,
+       0xc4, 0x08,
+       0xc5, 0x80,
+       0xc6, 0x80,
+       0xc7, 0x0a,
+       0xc8, 0x1a,
+       0xc9, 0x80,
+       0xfe, 0x92,
+       0xe0, 0xf8,
+       0xe6, 0x8b,
+       0xd0, 0x40,
+       0xf8, 0x20,
+       0xfa, 0x0f,
+       0xfd, 0x20,
+       0xad, 0x20,
+       0xae, 0x07,
+       0xb8, 0x00,
+};
+
+/* Register values to initialise the demod in DVB-S2 mode */
+static u8 ds3000_dvbs2_init_tab[] = {
+       0x23, 0x0f,
+       0x08, 0x07,
+       0x0c, 0x00,
+       0x21, 0x54,
+       0x25, 0x82,
+       0x27, 0x31,
+       0x30, 0x08,
+       0x31, 0x32,
+       0x32, 0x32,
+       0x33, 0x35,
+       0x35, 0xff,
+       0x3a, 0x00,
+       0x37, 0x10,
+       0x38, 0x10,
+       0x39, 0x02,
+       0x42, 0x60,
+       0x4a, 0x80,
+       0x4b, 0x04,
+       0x4d, 0x81,
+       0x5d, 0x88,
+       0x50, 0x36,
+       0x51, 0x36,
+       0x52, 0x36,
+       0x53, 0x36,
+       0x63, 0x60,
+       0x64, 0x10,
+       0x65, 0x10,
+       0x68, 0x04,
+       0x69, 0x29,
+       0x70, 0x20,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x40,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x60,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x80,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0xa0,
+       0x71, 0x70,
+       0x72, 0x04,
+       0x73, 0x00,
+       0x70, 0x1f,
+       0xa0, 0x44,
+       0xc0, 0x08,
+       0xc1, 0x10,
+       0xc2, 0x08,
+       0xc3, 0x10,
+       0xc4, 0x08,
+       0xc5, 0xf0,
+       0xc6, 0xf0,
+       0xc7, 0x0a,
+       0xc8, 0x1a,
+       0xc9, 0x80,
+       0xca, 0x23,
+       0xcb, 0x24,
+       0xce, 0x74,
+       0x90, 0x03,
+       0x76, 0x80,
+       0x77, 0x42,
+       0x78, 0x0a,
+       0x79, 0x80,
+       0xad, 0x40,
+       0xae, 0x07,
+       0x7f, 0xd4,
+       0x7c, 0x00,
+       0x80, 0xa8,
+       0x81, 0xda,
+       0x7c, 0x01,
+       0x80, 0xda,
+       0x81, 0xec,
+       0x7c, 0x02,
+       0x80, 0xca,
+       0x81, 0xeb,
+       0x7c, 0x03,
+       0x80, 0xba,
+       0x81, 0xdb,
+       0x85, 0x08,
+       0x86, 0x00,
+       0x87, 0x02,
+       0x89, 0x80,
+       0x8b, 0x44,
+       0x8c, 0xaa,
+       0x8a, 0x10,
+       0xba, 0x00,
+       0xf5, 0x04,
+       0xfe, 0x44,
+       0xd2, 0x32,
+       0xb8, 0x00,
+};
+
+struct ds3000_state {
+       struct i2c_adapter *i2c;
+       const struct ds3000_config *config;
+       struct dvb_frontend frontend;
+       u8 skip_fw_load;
+       /* previous uncorrected block counter for DVB-S2 */
+       u16 prevUCBS2;
+};
+
+static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+               .flags = 0, .buf = buf, .len = 2 };
+       int err;
+
+       dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
+                        " value == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = 0x60,
+               .flags = 0, .buf = buf, .len = 2 };
+       int err;
+
+       dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+       ds3000_writereg(state, 0x03, 0x11);
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("%s: writereg error(err == %i, reg == 0x%02x,"
+                        " value == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+/* I2C write for 8k firmware load */
+static int ds3000_writeFW(struct ds3000_state *state, int reg,
+                               const u8 *data, u16 len)
+{
+       int i, ret = -EREMOTEIO;
+       struct i2c_msg msg;
+       u8 *buf;
+
+       buf = kmalloc(33, GFP_KERNEL);
+       if (buf == NULL) {
+               printk(KERN_ERR "Unable to kmalloc\n");
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       *(buf) = reg;
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.buf = buf;
+       msg.len = 33;
+
+       for (i = 0; i < len; i += 32) {
+               memcpy(buf + 1, data + i, 32);
+
+               dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
+
+               ret = i2c_transfer(state->i2c, &msg, 1);
+               if (ret != 1) {
+                       printk(KERN_ERR "%s: write error(err == %i, "
+                               "reg == 0x%02x\n", __func__, ret, reg);
+                       ret = -EREMOTEIO;
+               }
+       }
+
+error:
+       kfree(buf);
+
+       return ret;
+}
+
+static int ds3000_readreg(struct ds3000_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+               return ret;
+       }
+
+       dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+       return b1[0];
+}
+
+static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = 0x60,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = 0x60,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+
+       ds3000_writereg(state, 0x03, 0x12);
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+               return ret;
+       }
+
+       dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+       return b1[0];
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+                                       const struct firmware *fw);
+
+static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       const struct firmware *fw;
+       int ret = 0;
+
+       dprintk("%s()\n", __func__);
+
+       if (ds3000_readreg(state, 0xb2) <= 0)
+               return ret;
+
+       if (state->skip_fw_load)
+               return 0;
+       /* Load firmware */
+       /* request the firmware, this will block until someone uploads it */
+       printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
+                               DS3000_DEFAULT_FIRMWARE);
+       ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
+                               state->i2c->dev.parent);
+       printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+       if (ret) {
+               printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
+                               "found?)\n", __func__);
+               return ret;
+       }
+
+       /* Make sure we don't recurse back through here during loading */
+       state->skip_fw_load = 1;
+
+       ret = ds3000_load_firmware(fe, fw);
+       if (ret)
+               printk("%s: Writing firmware to device failed\n", __func__);
+
+       release_firmware(fw);
+
+       dprintk("%s: Firmware upload %s\n", __func__,
+                       ret == 0 ? "complete" : "failed");
+
+       /* Ensure firmware is always loaded if required */
+       state->skip_fw_load = 0;
+
+       return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+                                       const struct firmware *fw)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+       dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+                       fw->size,
+                       fw->data[0],
+                       fw->data[1],
+                       fw->data[fw->size - 2],
+                       fw->data[fw->size - 1]);
+
+       /* Begin the firmware load process */
+       ds3000_writereg(state, 0xb2, 0x01);
+       /* write the entire firmware */
+       ds3000_writeFW(state, 0xb0, fw->data, fw->size);
+       ds3000_writereg(state, 0xb2, 0x00);
+
+       return 0;
+}
+
+static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       u8 data;
+
+       dprintk("%s(%d)\n", __func__, voltage);
+
+       data = ds3000_readreg(state, 0xa2);
+       data |= 0x03; /* bit0 V/H, bit1 off/on */
+
+       switch (voltage) {
+       case SEC_VOLTAGE_18:
+               data &= ~0x03;
+               break;
+       case SEC_VOLTAGE_13:
+               data &= ~0x03;
+               data |= 0x01;
+               break;
+       case SEC_VOLTAGE_OFF:
+               break;
+       }
+
+       ds3000_writereg(state, 0xa2, data);
+
+       return 0;
+}
+
+static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int lock;
+
+       *status = 0;
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               lock = ds3000_readreg(state, 0xd1);
+               if ((lock & 0x07) == 0x07)
+                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC |
+                               FE_HAS_LOCK;
+
+               break;
+       case SYS_DVBS2:
+               lock = ds3000_readreg(state, 0x0d);
+               if ((lock & 0x8f) == 0x8f)
+                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC |
+                               FE_HAS_LOCK;
+
+               break;
+       default:
+               return 1;
+       }
+
+       dprintk("%s: status = 0x%02x\n", __func__, lock);
+
+       return 0;
+}
+
+/* read DS3000 BER value */
+static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 data;
+       u32 ber_reading, lpdc_frames;
+
+       dprintk("%s()\n", __func__);
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               /* set the number of bytes checked during
+               BER estimation */
+               ds3000_writereg(state, 0xf9, 0x04);
+               /* read BER estimation status */
+               data = ds3000_readreg(state, 0xf8);
+               /* check if BER estimation is ready */
+               if ((data & 0x10) == 0) {
+                       /* this is the number of error bits,
+                       to calculate the bit error rate
+                       divide to 8388608 */
+                       *ber = (ds3000_readreg(state, 0xf7) << 8) |
+                               ds3000_readreg(state, 0xf6);
+                       /* start counting error bits */
+                       /* need to be set twice
+                       otherwise it fails sometimes */
+                       data |= 0x10;
+                       ds3000_writereg(state, 0xf8, data);
+                       ds3000_writereg(state, 0xf8, data);
+               } else
+                       /* used to indicate that BER estimation
+                       is not ready, i.e. BER is unknown */
+                       *ber = 0xffffffff;
+               break;
+       case SYS_DVBS2:
+               /* read the number of LPDC decoded frames */
+               lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
+                               (ds3000_readreg(state, 0xd6) << 8) |
+                               ds3000_readreg(state, 0xd5);
+               /* read the number of packets with bad CRC */
+               ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
+                               ds3000_readreg(state, 0xf7);
+               if (lpdc_frames > 750) {
+                       /* clear LPDC frame counters */
+                       ds3000_writereg(state, 0xd1, 0x01);
+                       /* clear bad packets counter */
+                       ds3000_writereg(state, 0xf9, 0x01);
+                       /* enable bad packets counter */
+                       ds3000_writereg(state, 0xf9, 0x00);
+                       /* enable LPDC frame counters */
+                       ds3000_writereg(state, 0xd1, 0x00);
+                       *ber = ber_reading;
+               } else
+                       /* used to indicate that BER estimation is not ready,
+                       i.e. BER is unknown */
+                       *ber = 0xffffffff;
+               break;
+       default:
+               return 1;
+       }
+
+       return 0;
+}
+
+/* read TS2020 signal strength */
+static int ds3000_read_signal_strength(struct dvb_frontend *fe,
+                                               u16 *signal_strength)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       u16 sig_reading, sig_strength;
+       u8 rfgain, bbgain;
+
+       dprintk("%s()\n", __func__);
+
+       rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
+       bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
+
+       if (rfgain > 15)
+               rfgain = 15;
+       if (bbgain > 13)
+               bbgain = 13;
+
+       sig_reading = rfgain * 2 + bbgain * 3;
+
+       sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
+
+       /* cook the value to be suitable for szap-s2 human readable output */
+       *signal_strength = sig_strength * 1000;
+
+       dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
+                       sig_reading, *signal_strength);
+
+       return 0;
+}
+
+/* calculate DS3000 snr value in dB */
+static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 snr_reading, snr_value;
+       u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
+       static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
+               0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
+               0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
+               0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
+       };
+       static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
+               0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
+               0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
+               0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
+               0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
+               0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
+               0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
+               0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
+               0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
+               0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
+               0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
+               0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
+               0x49e9, 0x4a20, 0x4a57
+       };
+
+       dprintk("%s()\n", __func__);
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               snr_reading = ds3000_readreg(state, 0xff);
+               snr_reading /= 8;
+               if (snr_reading == 0)
+                       *snr = 0x0000;
+               else {
+                       if (snr_reading > 20)
+                               snr_reading = 20;
+                       snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
+                       /* cook the value to be suitable for szap-s2
+                       human readable output */
+                       *snr = snr_value * 8 * 655;
+               }
+               dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+                               snr_reading, *snr);
+               break;
+       case SYS_DVBS2:
+               dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
+                               (ds3000_readreg(state, 0x8d) << 4);
+               dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
+               tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
+               if (tmp == 0) {
+                       *snr = 0x0000;
+                       return 0;
+               }
+               if (dvbs2_noise_reading == 0) {
+                       snr_value = 0x0013;
+                       /* cook the value to be suitable for szap-s2
+                       human readable output */
+                       *snr = 0xffff;
+                       return 0;
+               }
+               if (tmp > dvbs2_noise_reading) {
+                       snr_reading = tmp / dvbs2_noise_reading;
+                       if (snr_reading > 80)
+                               snr_reading = 80;
+                       snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
+                       /* cook the value to be suitable for szap-s2
+                       human readable output */
+                       *snr = snr_value * 5 * 655;
+               } else {
+                       snr_reading = dvbs2_noise_reading / tmp;
+                       if (snr_reading > 80)
+                               snr_reading = 80;
+                       *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
+               }
+               dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
+                               snr_reading, *snr);
+               break;
+       default:
+               return 1;
+       }
+
+       return 0;
+}
+
+/* read DS3000 uncorrected blocks */
+static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 data;
+       u16 _ucblocks;
+
+       dprintk("%s()\n", __func__);
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
+                               ds3000_readreg(state, 0xf4);
+               data = ds3000_readreg(state, 0xf8);
+               /* clear packet counters */
+               data &= ~0x20;
+               ds3000_writereg(state, 0xf8, data);
+               /* enable packet counters */
+               data |= 0x20;
+               ds3000_writereg(state, 0xf8, data);
+               break;
+       case SYS_DVBS2:
+               _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
+                               ds3000_readreg(state, 0xe1);
+               if (_ucblocks > state->prevUCBS2)
+                       *ucblocks = _ucblocks - state->prevUCBS2;
+               else
+                       *ucblocks = state->prevUCBS2 - _ucblocks;
+               state->prevUCBS2 = _ucblocks;
+               break;
+       default:
+               return 1;
+       }
+
+       return 0;
+}
+
+static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       u8 data;
+
+       dprintk("%s(%d)\n", __func__, tone);
+       if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
+               printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
+               return -EINVAL;
+       }
+
+       data = ds3000_readreg(state, 0xa2);
+       data &= ~0xc0;
+       ds3000_writereg(state, 0xa2, data);
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               dprintk("%s: setting tone on\n", __func__);
+               data = ds3000_readreg(state, 0xa1);
+               data &= ~0x43;
+               data |= 0x04;
+               ds3000_writereg(state, 0xa1, data);
+               break;
+       case SEC_TONE_OFF:
+               dprintk("%s: setting tone off\n", __func__);
+               data = ds3000_readreg(state, 0xa2);
+               data |= 0x80;
+               ds3000_writereg(state, 0xa2, data);
+               break;
+       }
+
+       return 0;
+}
+
+static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
+                               struct dvb_diseqc_master_cmd *d)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       int i;
+       u8 data;
+
+       /* Dump DiSEqC message */
+       dprintk("%s(", __func__);
+       for (i = 0 ; i < d->msg_len;) {
+               dprintk("0x%02x", d->msg[i]);
+               if (++i < d->msg_len)
+                       dprintk(", ");
+       }
+
+       /* enable DiSEqC message send pin */
+       data = ds3000_readreg(state, 0xa2);
+       data &= ~0xc0;
+       ds3000_writereg(state, 0xa2, data);
+
+       /* DiSEqC message */
+       for (i = 0; i < d->msg_len; i++)
+               ds3000_writereg(state, 0xa3 + i, d->msg[i]);
+
+       data = ds3000_readreg(state, 0xa1);
+       /* clear DiSEqC message length and status,
+       enable DiSEqC message send */
+       data &= ~0xf8;
+       /* set DiSEqC mode, modulation active during 33 pulses,
+       set DiSEqC message length */
+       data |= ((d->msg_len - 1) << 3) | 0x07;
+       ds3000_writereg(state, 0xa1, data);
+
+       /* wait up to 150ms for DiSEqC transmission to complete */
+       for (i = 0; i < 15; i++) {
+               data = ds3000_readreg(state, 0xa1);
+               if ((data & 0x40) == 0)
+                       break;
+               msleep(10);
+       }
+
+       /* DiSEqC timeout after 150ms */
+       if (i == 15) {
+               data = ds3000_readreg(state, 0xa1);
+               data &= ~0x80;
+               data |= 0x40;
+               ds3000_writereg(state, 0xa1, data);
+
+               data = ds3000_readreg(state, 0xa2);
+               data &= ~0xc0;
+               data |= 0x80;
+               ds3000_writereg(state, 0xa2, data);
+
+               return 1;
+       }
+
+       data = ds3000_readreg(state, 0xa2);
+       data &= ~0xc0;
+       data |= 0x80;
+       ds3000_writereg(state, 0xa2, data);
+
+       return 0;
+}
+
+/* Send DiSEqC burst */
+static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
+                                       fe_sec_mini_cmd_t burst)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       int i;
+       u8 data;
+
+       dprintk("%s()\n", __func__);
+
+       data = ds3000_readreg(state, 0xa2);
+       data &= ~0xc0;
+       ds3000_writereg(state, 0xa2, data);
+
+       /* DiSEqC burst */
+       if (burst == SEC_MINI_A)
+               /* Unmodulated tone burst */
+               ds3000_writereg(state, 0xa1, 0x02);
+       else if (burst == SEC_MINI_B)
+               /* Modulated tone burst */
+               ds3000_writereg(state, 0xa1, 0x01);
+       else
+               return -EINVAL;
+
+       msleep(13);
+       for (i = 0; i < 5; i++) {
+               data = ds3000_readreg(state, 0xa1);
+               if ((data & 0x40) == 0)
+                       break;
+               msleep(1);
+       }
+
+       if (i == 5) {
+               data = ds3000_readreg(state, 0xa1);
+               data &= ~0x80;
+               data |= 0x40;
+               ds3000_writereg(state, 0xa1, data);
+
+               data = ds3000_readreg(state, 0xa2);
+               data &= ~0xc0;
+               data |= 0x80;
+               ds3000_writereg(state, 0xa2, data);
+
+               return 1;
+       }
+
+       data = ds3000_readreg(state, 0xa2);
+       data &= ~0xc0;
+       data |= 0x80;
+       ds3000_writereg(state, 0xa2, data);
+
+       return 0;
+}
+
+static void ds3000_release(struct dvb_frontend *fe)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       dprintk("%s\n", __func__);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops ds3000_ops;
+
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct ds3000_state *state = NULL;
+       int ret;
+
+       dprintk("%s\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
+       if (state == NULL) {
+               printk(KERN_ERR "Unable to kmalloc\n");
+               goto error2;
+       }
+
+       state->config = config;
+       state->i2c = i2c;
+       state->prevUCBS2 = 0;
+
+       /* check if the demod is present */
+       ret = ds3000_readreg(state, 0x00) & 0xfe;
+       if (ret != 0xe0) {
+               printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
+               goto error3;
+       }
+
+       printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
+                       ds3000_readreg(state, 0x02),
+                       ds3000_readreg(state, 0x01));
+
+       memcpy(&state->frontend.ops, &ds3000_ops,
+                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error3:
+       kfree(state);
+error2:
+       return NULL;
+}
+EXPORT_SYMBOL(ds3000_attach);
+
+static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
+                                       s32 carrier_offset_khz)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       s32 tmp;
+
+       tmp = carrier_offset_khz;
+       tmp *= 65536;
+       tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
+
+       if (tmp < 0)
+               tmp += 65536;
+
+       ds3000_writereg(state, 0x5f, tmp >> 8);
+       ds3000_writereg(state, 0x5e, tmp & 0xff);
+
+       return 0;
+}
+
+static int ds3000_set_frontend(struct dvb_frontend *fe)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       int i;
+       fe_status_t status;
+       u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf, div4;
+       s32 offset_khz;
+       u16 value, ndiv;
+       u32 f3db;
+
+       dprintk("%s() ", __func__);
+
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+       /* Tune */
+       /* unknown */
+       ds3000_tuner_writereg(state, 0x07, 0x02);
+       ds3000_tuner_writereg(state, 0x10, 0x00);
+       ds3000_tuner_writereg(state, 0x60, 0x79);
+       ds3000_tuner_writereg(state, 0x08, 0x01);
+       ds3000_tuner_writereg(state, 0x00, 0x01);
+       div4 = 0;
+
+       /* calculate and set freq divider */
+       if (c->frequency < 1146000) {
+               ds3000_tuner_writereg(state, 0x10, 0x11);
+               div4 = 1;
+               ndiv = ((c->frequency * (6 + 8) * 4) +
+                               (DS3000_XTAL_FREQ / 2)) /
+                               DS3000_XTAL_FREQ - 1024;
+       } else {
+               ds3000_tuner_writereg(state, 0x10, 0x01);
+               ndiv = ((c->frequency * (6 + 8) * 2) +
+                               (DS3000_XTAL_FREQ / 2)) /
+                               DS3000_XTAL_FREQ - 1024;
+       }
+
+       ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
+       ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
+
+       /* set pll */
+       ds3000_tuner_writereg(state, 0x03, 0x06);
+       ds3000_tuner_writereg(state, 0x51, 0x0f);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x10);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+       msleep(5);
+
+       /* unknown */
+       ds3000_tuner_writereg(state, 0x51, 0x17);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x08);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+       msleep(5);
+
+       value = ds3000_tuner_readreg(state, 0x3d);
+       value &= 0x0f;
+       if ((value > 4) && (value < 15)) {
+               value -= 3;
+               if (value < 4)
+                       value = 4;
+               value = ((value << 3) | 0x01) & 0x79;
+       }
+
+       ds3000_tuner_writereg(state, 0x60, value);
+       ds3000_tuner_writereg(state, 0x51, 0x17);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x08);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+
+       /* set low-pass filter period */
+       ds3000_tuner_writereg(state, 0x04, 0x2e);
+       ds3000_tuner_writereg(state, 0x51, 0x1b);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x04);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+       msleep(5);
+
+       f3db = ((c->symbol_rate / 1000) << 2) / 5 + 2000;
+       if ((c->symbol_rate / 1000) < 5000)
+               f3db += 3000;
+       if (f3db < 7000)
+               f3db = 7000;
+       if (f3db > 40000)
+               f3db = 40000;
+
+       /* set low-pass filter baseband */
+       value = ds3000_tuner_readreg(state, 0x26);
+       mlpf = 0x2e * 207 / ((value << 1) + 151);
+       mlpf_max = mlpf * 135 / 100;
+       mlpf_min = mlpf * 78 / 100;
+       if (mlpf_max > 63)
+               mlpf_max = 63;
+
+       /* rounded to the closest integer */
+       nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
+                       / (2766 * DS3000_XTAL_FREQ);
+       if (nlpf > 23)
+               nlpf = 23;
+       if (nlpf < 1)
+               nlpf = 1;
+
+       /* rounded to the closest integer */
+       mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+                       (1000 * f3db / 2)) / (1000 * f3db);
+
+       if (mlpf_new < mlpf_min) {
+               nlpf++;
+               mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
+                               (1000 * f3db / 2)) / (1000 * f3db);
+       }
+
+       if (mlpf_new > mlpf_max)
+               mlpf_new = mlpf_max;
+
+       ds3000_tuner_writereg(state, 0x04, mlpf_new);
+       ds3000_tuner_writereg(state, 0x06, nlpf);
+       ds3000_tuner_writereg(state, 0x51, 0x1b);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x04);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+       msleep(5);
+
+       /* unknown */
+       ds3000_tuner_writereg(state, 0x51, 0x1e);
+       ds3000_tuner_writereg(state, 0x51, 0x1f);
+       ds3000_tuner_writereg(state, 0x50, 0x01);
+       ds3000_tuner_writereg(state, 0x50, 0x00);
+       msleep(60);
+
+       offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ
+               / (6 + 8) / (div4 + 1) / 2 - c->frequency;
+
+       /* ds3000 global reset */
+       ds3000_writereg(state, 0x07, 0x80);
+       ds3000_writereg(state, 0x07, 0x00);
+       /* ds3000 build-in uC reset */
+       ds3000_writereg(state, 0xb2, 0x01);
+       /* ds3000 software reset */
+       ds3000_writereg(state, 0x00, 0x01);
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               /* initialise the demod in DVB-S mode */
+               for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
+                       ds3000_writereg(state,
+                               ds3000_dvbs_init_tab[i],
+                               ds3000_dvbs_init_tab[i + 1]);
+               value = ds3000_readreg(state, 0xfe);
+               value &= 0xc0;
+               value |= 0x1b;
+               ds3000_writereg(state, 0xfe, value);
+               break;
+       case SYS_DVBS2:
+               /* initialise the demod in DVB-S2 mode */
+               for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
+                       ds3000_writereg(state,
+                               ds3000_dvbs2_init_tab[i],
+                               ds3000_dvbs2_init_tab[i + 1]);
+               if (c->symbol_rate >= 30000000)
+                       ds3000_writereg(state, 0xfe, 0x54);
+               else
+                       ds3000_writereg(state, 0xfe, 0x98);
+               break;
+       default:
+               return 1;
+       }
+
+       /* enable 27MHz clock output */
+       ds3000_writereg(state, 0x29, 0x80);
+       /* enable ac coupling */
+       ds3000_writereg(state, 0x25, 0x8a);
+
+       /* enhance symbol rate performance */
+       if ((c->symbol_rate / 1000) <= 5000) {
+               value = 29777 / (c->symbol_rate / 1000) + 1;
+               if (value % 2 != 0)
+                       value++;
+               ds3000_writereg(state, 0xc3, 0x0d);
+               ds3000_writereg(state, 0xc8, value);
+               ds3000_writereg(state, 0xc4, 0x10);
+               ds3000_writereg(state, 0xc7, 0x0e);
+       } else if ((c->symbol_rate / 1000) <= 10000) {
+               value = 92166 / (c->symbol_rate / 1000) + 1;
+               if (value % 2 != 0)
+                       value++;
+               ds3000_writereg(state, 0xc3, 0x07);
+               ds3000_writereg(state, 0xc8, value);
+               ds3000_writereg(state, 0xc4, 0x09);
+               ds3000_writereg(state, 0xc7, 0x12);
+       } else if ((c->symbol_rate / 1000) <= 20000) {
+               value = 64516 / (c->symbol_rate / 1000) + 1;
+               ds3000_writereg(state, 0xc3, value);
+               ds3000_writereg(state, 0xc8, 0x0e);
+               ds3000_writereg(state, 0xc4, 0x07);
+               ds3000_writereg(state, 0xc7, 0x18);
+       } else {
+               value = 129032 / (c->symbol_rate / 1000) + 1;
+               ds3000_writereg(state, 0xc3, value);
+               ds3000_writereg(state, 0xc8, 0x0a);
+               ds3000_writereg(state, 0xc4, 0x05);
+               ds3000_writereg(state, 0xc7, 0x24);
+       }
+
+       /* normalized symbol rate rounded to the closest integer */
+       value = (((c->symbol_rate / 1000) << 16) +
+                       (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
+       ds3000_writereg(state, 0x61, value & 0x00ff);
+       ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
+
+       /* co-channel interference cancellation disabled */
+       ds3000_writereg(state, 0x56, 0x00);
+
+       /* equalizer disabled */
+       ds3000_writereg(state, 0x76, 0x00);
+
+       /*ds3000_writereg(state, 0x08, 0x03);
+       ds3000_writereg(state, 0xfd, 0x22);
+       ds3000_writereg(state, 0x08, 0x07);
+       ds3000_writereg(state, 0xfd, 0x42);
+       ds3000_writereg(state, 0x08, 0x07);*/
+
+       if (state->config->ci_mode) {
+               switch (c->delivery_system) {
+               case SYS_DVBS:
+               default:
+                       ds3000_writereg(state, 0xfd, 0x80);
+               break;
+               case SYS_DVBS2:
+                       ds3000_writereg(state, 0xfd, 0x01);
+                       break;
+               }
+       }
+
+       /* ds3000 out of software reset */
+       ds3000_writereg(state, 0x00, 0x00);
+       /* start ds3000 build-in uC */
+       ds3000_writereg(state, 0xb2, 0x00);
+
+       ds3000_set_carrier_offset(fe, offset_khz);
+
+       for (i = 0; i < 30 ; i++) {
+               ds3000_read_status(fe, &status);
+               if (status & FE_HAS_LOCK)
+                       break;
+
+               msleep(10);
+       }
+
+       return 0;
+}
+
+static int ds3000_tune(struct dvb_frontend *fe,
+                       bool re_tune,
+                       unsigned int mode_flags,
+                       unsigned int *delay,
+                       fe_status_t *status)
+{
+       if (re_tune) {
+               int ret = ds3000_set_frontend(fe);
+               if (ret)
+                       return ret;
+       }
+
+       *delay = HZ / 5;
+
+       return ds3000_read_status(fe, status);
+}
+
+static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
+{
+       dprintk("%s()\n", __func__);
+       return DVBFE_ALGO_HW;
+}
+
+/*
+ * Initialise or wake up device
+ *
+ * Power config will reset and load initial firmware if required
+ */
+static int ds3000_initfe(struct dvb_frontend *fe)
+{
+       struct ds3000_state *state = fe->demodulator_priv;
+       int ret;
+
+       dprintk("%s()\n", __func__);
+       /* hard reset */
+       ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
+       msleep(1);
+
+       /* TS2020 init */
+       ds3000_tuner_writereg(state, 0x42, 0x73);
+       ds3000_tuner_writereg(state, 0x05, 0x01);
+       ds3000_tuner_writereg(state, 0x62, 0xf5);
+       /* Load the firmware if required */
+       ret = ds3000_firmware_ondemand(fe);
+       if (ret != 0) {
+               printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+/* Put device to sleep */
+static int ds3000_sleep(struct dvb_frontend *fe)
+{
+       dprintk("%s()\n", __func__);
+       return 0;
+}
+
+static struct dvb_frontend_ops ds3000_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2},
+       .info = {
+               .name = "Montage Technology DS3000/TS2020",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
+               .frequency_tolerance = 5000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_INVERSION_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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_2G_MODULATION |
+                       FE_CAN_QPSK | FE_CAN_RECOVER
+       },
+
+       .release = ds3000_release,
+
+       .init = ds3000_initfe,
+       .sleep = ds3000_sleep,
+       .read_status = ds3000_read_status,
+       .read_ber = ds3000_read_ber,
+       .read_signal_strength = ds3000_read_signal_strength,
+       .read_snr = ds3000_read_snr,
+       .read_ucblocks = ds3000_read_ucblocks,
+       .set_voltage = ds3000_set_voltage,
+       .set_tone = ds3000_set_tone,
+       .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
+       .diseqc_send_burst = ds3000_diseqc_send_burst,
+       .get_frontend_algo = ds3000_get_algo,
+
+       .set_frontend = ds3000_set_frontend,
+       .tune = ds3000_tune,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
+                       "DS3000/TS2020 hardware");
+MODULE_AUTHOR("Konstantin Dimitrov");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/ds3000.h b/drivers/media/dvb-frontends/ds3000.h
new file mode 100644 (file)
index 0000000..1b73688
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
+    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+
+    Copyright (C) 2009 TurboSight.com
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef DS3000_H
+#define DS3000_H
+
+#include <linux/dvb/frontend.h>
+
+struct ds3000_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+       u8 ci_mode;
+       /* Set device param to start dma */
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+};
+
+#if defined(CONFIG_DVB_DS3000) || \
+                       (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+                                       struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_DS3000 */
+#endif /* DS3000_H */
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
new file mode 100644 (file)
index 0000000..6d8fe88
--- /dev/null
@@ -0,0 +1,820 @@
+/*
+ * descriptions + helper functions for simple dvb plls.
+ *
+ * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "dvb-pll.h"
+
+struct dvb_pll_priv {
+       /* pll number */
+       int nr;
+
+       /* i2c details */
+       int pll_i2c_address;
+       struct i2c_adapter *i2c;
+
+       /* the PLL descriptor */
+       struct dvb_pll_desc *pll_desc;
+
+       /* cached frequency/bandwidth */
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#define DVB_PLL_MAX 64
+
+static unsigned int dvb_pll_devcount;
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+static unsigned int id[DVB_PLL_MAX] =
+       { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
+module_param_array(id, int, NULL, 0644);
+MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
+
+/* ----------------------------------------------------------- */
+
+struct dvb_pll_desc {
+       char *name;
+       u32  min;
+       u32  max;
+       u32  iffreq;
+       void (*set)(struct dvb_frontend *fe, u8 *buf);
+       u8   *initdata;
+       u8   *initdata2;
+       u8   *sleepdata;
+       int  count;
+       struct {
+               u32 limit;
+               u32 stepsize;
+               u8  config;
+               u8  cb;
+       } entries[12];
+};
+
+/* ----------------------------------------------------------- */
+/* descriptions                                                */
+
+static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
+       .name  = "Thomson dtt7579",
+       .min   = 177000000,
+       .max   = 858000000,
+       .iffreq= 36166667,
+       .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
+       .count = 4,
+       .entries = {
+               {  443250000, 166667, 0xb4, 0x02 },
+               {  542000000, 166667, 0xb4, 0x08 },
+               {  771000000, 166667, 0xbc, 0x08 },
+               {  999999999, 166667, 0xf4, 0x08 },
+       },
+};
+
+static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       if (bw == 7000000)
+               buf[3] |= 0x10;
+}
+
+static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
+       .name  = "Thomson dtt759x",
+       .min   = 177000000,
+       .max   = 896000000,
+       .set   = thomson_dtt759x_bw,
+       .iffreq= 36166667,
+       .sleepdata = (u8[]){ 2, 0x84, 0x03 },
+       .count = 5,
+       .entries = {
+               {  264000000, 166667, 0xb4, 0x02 },
+               {  470000000, 166667, 0xbc, 0x02 },
+               {  735000000, 166667, 0xbc, 0x08 },
+               {  835000000, 166667, 0xf4, 0x08 },
+               {  999999999, 166667, 0xfc, 0x08 },
+       },
+};
+
+static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       if (bw == 8000000)
+               buf[3] ^= 0x10;
+}
+
+static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
+       .name  = "Thomson dtt7520x",
+       .min   = 185000000,
+       .max   = 900000000,
+       .set   = thomson_dtt7520x_bw,
+       .iffreq = 36166667,
+       .count = 7,
+       .entries = {
+               {  305000000, 166667, 0xb4, 0x12 },
+               {  405000000, 166667, 0xbc, 0x12 },
+               {  445000000, 166667, 0xbc, 0x12 },
+               {  465000000, 166667, 0xf4, 0x18 },
+               {  735000000, 166667, 0xfc, 0x18 },
+               {  835000000, 166667, 0xbc, 0x18 },
+               {  999999999, 166667, 0xfc, 0x18 },
+       },
+};
+
+static struct dvb_pll_desc dvb_pll_lg_z201 = {
+       .name  = "LG z201",
+       .min   = 174000000,
+       .max   = 862000000,
+       .iffreq= 36166667,
+       .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
+       .count = 5,
+       .entries = {
+               {  157500000, 166667, 0xbc, 0x01 },
+               {  443250000, 166667, 0xbc, 0x02 },
+               {  542000000, 166667, 0xbc, 0x04 },
+               {  830000000, 166667, 0xf4, 0x04 },
+               {  999999999, 166667, 0xfc, 0x04 },
+       },
+};
+
+static struct dvb_pll_desc dvb_pll_unknown_1 = {
+       .name  = "unknown 1", /* used by dntv live dvb-t */
+       .min   = 174000000,
+       .max   = 862000000,
+       .iffreq= 36166667,
+       .count = 9,
+       .entries = {
+               {  150000000, 166667, 0xb4, 0x01 },
+               {  173000000, 166667, 0xbc, 0x01 },
+               {  250000000, 166667, 0xb4, 0x02 },
+               {  400000000, 166667, 0xbc, 0x02 },
+               {  420000000, 166667, 0xf4, 0x02 },
+               {  470000000, 166667, 0xfc, 0x02 },
+               {  600000000, 166667, 0xbc, 0x08 },
+               {  730000000, 166667, 0xf4, 0x08 },
+               {  999999999, 166667, 0xfc, 0x08 },
+       },
+};
+
+/* Infineon TUA6010XS
+ * used in Thomson Cable Tuner
+ */
+static struct dvb_pll_desc dvb_pll_tua6010xs = {
+       .name  = "Infineon TUA6010XS",
+       .min   =  44250000,
+       .max   = 858000000,
+       .iffreq= 36125000,
+       .count = 3,
+       .entries = {
+               {  115750000, 62500, 0x8e, 0x03 },
+               {  403250000, 62500, 0x8e, 0x06 },
+               {  999999999, 62500, 0x8e, 0x85 },
+       },
+};
+
+/* Panasonic env57h1xd5 (some Philips PLL ?) */
+static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
+       .name  = "Panasonic ENV57H1XD5",
+       .min   =  44250000,
+       .max   = 858000000,
+       .iffreq= 36125000,
+       .count = 4,
+       .entries = {
+               {  153000000, 166667, 0xc2, 0x41 },
+               {  470000000, 166667, 0xc2, 0x42 },
+               {  526000000, 166667, 0xc2, 0x84 },
+               {  999999999, 166667, 0xc2, 0xa4 },
+       },
+};
+
+/* Philips TDA6650/TDA6651
+ * used in Panasonic ENV77H11D5
+ */
+static void tda665x_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       if (bw == 8000000)
+               buf[3] |= 0x08;
+}
+
+static struct dvb_pll_desc dvb_pll_tda665x = {
+       .name  = "Philips TDA6650/TDA6651",
+       .min   =  44250000,
+       .max   = 858000000,
+       .set   = tda665x_bw,
+       .iffreq= 36166667,
+       .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
+       .count = 12,
+       .entries = {
+               {   93834000, 166667, 0xca, 0x61 /* 011 0 0 0  01 */ },
+               {  123834000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
+               {  161000000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
+               {  163834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
+               {  253834000, 166667, 0xca, 0x62 /* 011 0 0 0  10 */ },
+               {  383834000, 166667, 0xca, 0xa2 /* 101 0 0 0  10 */ },
+               {  443834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
+               {  444000000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
+               {  583834000, 166667, 0xca, 0x64 /* 011 0 0 1  00 */ },
+               {  793834000, 166667, 0xca, 0xa4 /* 101 0 0 1  00 */ },
+               {  444834000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
+               {  861000000, 166667, 0xca, 0xe4 /* 111 0 0 1  00 */ },
+       }
+};
+
+/* Infineon TUA6034
+ * used in LG TDTP E102P
+ */
+static void tua6034_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       if (bw == 7000000)
+               buf[3] |= 0x08;
+}
+
+static struct dvb_pll_desc dvb_pll_tua6034 = {
+       .name  = "Infineon TUA6034",
+       .min   =  44250000,
+       .max   = 858000000,
+       .iffreq= 36166667,
+       .count = 3,
+       .set   = tua6034_bw,
+       .entries = {
+               {  174500000, 62500, 0xce, 0x01 },
+               {  230000000, 62500, 0xce, 0x02 },
+               {  999999999, 62500, 0xce, 0x04 },
+       },
+};
+
+/* ALPS TDED4
+ * used in Nebula-Cards and USB boxes
+ */
+static void tded4_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       if (bw == 8000000)
+               buf[3] |= 0x04;
+}
+
+static struct dvb_pll_desc dvb_pll_tded4 = {
+       .name = "ALPS TDED4",
+       .min = 47000000,
+       .max = 863000000,
+       .iffreq= 36166667,
+       .set   = tded4_bw,
+       .count = 4,
+       .entries = {
+               { 153000000, 166667, 0x85, 0x01 },
+               { 470000000, 166667, 0x85, 0x02 },
+               { 823000000, 166667, 0x85, 0x08 },
+               { 999999999, 166667, 0x85, 0x88 },
+       }
+};
+
+/* ALPS TDHU2
+ * used in AverTVHD MCE A180
+ */
+static struct dvb_pll_desc dvb_pll_tdhu2 = {
+       .name = "ALPS TDHU2",
+       .min = 54000000,
+       .max = 864000000,
+       .iffreq= 44000000,
+       .count = 4,
+       .entries = {
+               { 162000000, 62500, 0x85, 0x01 },
+               { 426000000, 62500, 0x85, 0x02 },
+               { 782000000, 62500, 0x85, 0x08 },
+               { 999999999, 62500, 0x85, 0x88 },
+       }
+};
+
+/* Samsung TBMV30111IN / TBMV30712IN1
+ * used in Air2PC ATSC - 2nd generation (nxt2002)
+ */
+static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
+       .name = "Samsung TBMV30111IN / TBMV30712IN1",
+       .min = 54000000,
+       .max = 860000000,
+       .iffreq= 44000000,
+       .count = 6,
+       .entries = {
+               { 172000000, 166667, 0xb4, 0x01 },
+               { 214000000, 166667, 0xb4, 0x02 },
+               { 467000000, 166667, 0xbc, 0x02 },
+               { 721000000, 166667, 0xbc, 0x08 },
+               { 841000000, 166667, 0xf4, 0x08 },
+               { 999999999, 166667, 0xfc, 0x02 },
+       }
+};
+
+/*
+ * Philips SD1878 Tuner.
+ */
+static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
+       .name  = "Philips SD1878",
+       .min   =  950000,
+       .max   = 2150000,
+       .iffreq= 249, /* zero-IF, offset 249 is to round up */
+       .count = 4,
+       .entries = {
+               { 1250000, 500, 0xc4, 0x00},
+               { 1450000, 500, 0xc4, 0x40},
+               { 2050000, 500, 0xc4, 0x80},
+               { 2150000, 500, 0xc4, 0xc0},
+       },
+};
+
+static void opera1_bw(struct dvb_frontend *fe, u8 *buf)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       u32 b_w  = (c->symbol_rate * 27) / 32000;
+       struct i2c_msg msg = {
+               .addr = priv->pll_i2c_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 4
+       };
+       int result;
+       u8 lpf;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       result = i2c_transfer(priv->i2c, &msg, 1);
+       if (result != 1)
+               printk(KERN_ERR "%s: i2c_transfer failed:%d",
+                       __func__, result);
+
+       if (b_w <= 10000)
+               lpf = 0xc;
+       else if (b_w <= 12000)
+               lpf = 0x2;
+       else if (b_w <= 14000)
+               lpf = 0xa;
+       else if (b_w <= 16000)
+               lpf = 0x6;
+       else if (b_w <= 18000)
+               lpf = 0xe;
+       else if (b_w <= 20000)
+               lpf = 0x1;
+       else if (b_w <= 22000)
+               lpf = 0x9;
+       else if (b_w <= 24000)
+               lpf = 0x5;
+       else if (b_w <= 26000)
+               lpf = 0xd;
+       else if (b_w <= 28000)
+               lpf = 0x3;
+               else
+               lpf = 0xb;
+       buf[2] ^= 0x1c; /* Flip bits 3-5 */
+       /* Set lpf */
+       buf[2] |= ((lpf >> 2) & 0x3) << 3;
+       buf[3] |= (lpf & 0x3) << 2;
+
+       return;
+}
+
+static struct dvb_pll_desc dvb_pll_opera1 = {
+       .name  = "Opera Tuner",
+       .min   =  900000,
+       .max   = 2250000,
+       .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
+       .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
+       .iffreq= 0,
+       .set   = opera1_bw,
+       .count = 8,
+       .entries = {
+               { 1064000, 500, 0xf9, 0xc2 },
+               { 1169000, 500, 0xf9, 0xe2 },
+               { 1299000, 500, 0xf9, 0x20 },
+               { 1444000, 500, 0xf9, 0x40 },
+               { 1606000, 500, 0xf9, 0x60 },
+               { 1777000, 500, 0xf9, 0x80 },
+               { 1941000, 500, 0xf9, 0xa0 },
+               { 2250000, 500, 0xf9, 0xc0 },
+       }
+};
+
+static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       struct i2c_msg msg = {
+               .addr = priv->pll_i2c_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 4
+       };
+       int result;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       result = i2c_transfer(priv->i2c, &msg, 1);
+       if (result != 1)
+               printk(KERN_ERR "%s: i2c_transfer failed:%d",
+                       __func__, result);
+
+       buf[2] = 0x9e;
+       buf[3] = 0x90;
+
+       return;
+}
+
+/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
+static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
+       .name   = "Samsung DTOS403IH102A",
+       .min    =  44250000,
+       .max    = 858000000,
+       .iffreq =  36125000,
+       .count  = 8,
+       .set    = samsung_dtos403ih102a_set,
+       .entries = {
+               { 135000000, 62500, 0xbe, 0x01 },
+               { 177000000, 62500, 0xf6, 0x01 },
+               { 370000000, 62500, 0xbe, 0x02 },
+               { 450000000, 62500, 0xf6, 0x02 },
+               { 466000000, 62500, 0xfe, 0x02 },
+               { 538000000, 62500, 0xbe, 0x08 },
+               { 826000000, 62500, 0xf6, 0x08 },
+               { 999999999, 62500, 0xfe, 0x08 },
+       }
+};
+
+/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
+static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
+       .name   = "Samsung TDTC9251DH0",
+       .min    =  48000000,
+       .max    = 863000000,
+       .iffreq =  36166667,
+       .count  = 3,
+       .entries = {
+               { 157500000, 166667, 0xcc, 0x09 },
+               { 443000000, 166667, 0xcc, 0x0a },
+               { 863000000, 166667, 0xcc, 0x08 },
+       }
+};
+
+/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
+static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
+       .name = "Samsung TBDU18132",
+       .min    =  950000,
+       .max    = 2150000, /* guesses */
+       .iffreq = 0,
+       .count = 2,
+       .entries = {
+               { 1550000, 125, 0x84, 0x82 },
+               { 4095937, 125, 0x84, 0x80 },
+       }
+       /* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
+        * by this driver.  The two extra bits are 0x60 in the third byte.  15
+        * bits is enough for over 4 GHz, which is enough to cover the range
+        * of this tuner.  We could use the additional divisor bits by adding
+        * more entries, e.g.
+        { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
+        { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
+        { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
+};
+
+/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
+static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
+       .name = "Samsung TBMU24112",
+       .min    =  950000,
+       .max    = 2150000, /* guesses */
+       .iffreq = 0,
+       .count = 2,
+       .entries = {
+               { 1500000, 125, 0x84, 0x18 },
+               { 9999999, 125, 0x84, 0x08 },
+       }
+};
+
+/* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
+/* byte 4 : 1  *   *   AGD R3  R2  R1  R0
+ * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
+ * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
+ * Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
+ *  47 - 153   0  *  0   0   0   0   0   1   0x01
+ * 153 - 430   0  *  0   0   0   0   1   0   0x02
+ * 430 - 822   0  *  0   0   1   0   0   0   0x08
+ * 822 - 862   1  *  0   0   1   0   0   0   0x88 */
+static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
+       .name = "ALPS TDEE4",
+       .min    =  47000000,
+       .max    = 862000000,
+       .iffreq =  36125000,
+       .count = 4,
+       .entries = {
+               { 153000000, 62500, 0x95, 0x01 },
+               { 430000000, 62500, 0x95, 0x02 },
+               { 822000000, 62500, 0x95, 0x08 },
+               { 999999999, 62500, 0x95, 0x88 },
+       }
+};
+
+/* ----------------------------------------------------------- */
+
+static struct dvb_pll_desc *pll_list[] = {
+       [DVB_PLL_UNDEFINED]              = NULL,
+       [DVB_PLL_THOMSON_DTT7579]        = &dvb_pll_thomson_dtt7579,
+       [DVB_PLL_THOMSON_DTT759X]        = &dvb_pll_thomson_dtt759x,
+       [DVB_PLL_THOMSON_DTT7520X]       = &dvb_pll_thomson_dtt7520x,
+       [DVB_PLL_LG_Z201]                = &dvb_pll_lg_z201,
+       [DVB_PLL_UNKNOWN_1]              = &dvb_pll_unknown_1,
+       [DVB_PLL_TUA6010XS]              = &dvb_pll_tua6010xs,
+       [DVB_PLL_ENV57H1XD5]             = &dvb_pll_env57h1xd5,
+       [DVB_PLL_TUA6034]                = &dvb_pll_tua6034,
+       [DVB_PLL_TDA665X]                = &dvb_pll_tda665x,
+       [DVB_PLL_TDED4]                  = &dvb_pll_tded4,
+       [DVB_PLL_TDEE4]                  = &dvb_pll_alps_tdee4,
+       [DVB_PLL_TDHU2]                  = &dvb_pll_tdhu2,
+       [DVB_PLL_SAMSUNG_TBMV]           = &dvb_pll_samsung_tbmv,
+       [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
+       [DVB_PLL_OPERA1]                 = &dvb_pll_opera1,
+       [DVB_PLL_SAMSUNG_DTOS403IH102A]  = &dvb_pll_samsung_dtos403ih102a,
+       [DVB_PLL_SAMSUNG_TDTC9251DH0]    = &dvb_pll_samsung_tdtc9251dh0,
+       [DVB_PLL_SAMSUNG_TBDU18132]      = &dvb_pll_samsung_tbdu18132,
+       [DVB_PLL_SAMSUNG_TBMU24112]      = &dvb_pll_samsung_tbmu24112,
+};
+
+/* ----------------------------------------------------------- */
+/* code                                                        */
+
+static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
+                            const u32 frequency)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       struct dvb_pll_desc *desc = priv->pll_desc;
+       u32 div;
+       int i;
+
+       if (frequency && (frequency < desc->min || frequency > desc->max))
+               return -EINVAL;
+
+       for (i = 0; i < desc->count; i++) {
+               if (frequency > desc->entries[i].limit)
+                       continue;
+               break;
+       }
+
+       if (debug)
+               printk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
+                      frequency, i, desc->count);
+       if (i == desc->count)
+               return -EINVAL;
+
+       div = (frequency + desc->iffreq +
+              desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
+       buf[0] = div >> 8;
+       buf[1] = div & 0xff;
+       buf[2] = desc->entries[i].config;
+       buf[3] = desc->entries[i].cb;
+
+       if (desc->set)
+               desc->set(fe, buf);
+
+       if (debug)
+               printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
+                      desc->name, div, buf[0], buf[1], buf[2], buf[3]);
+
+       // calculate the frequency we set it to
+       return (div * desc->entries[i].stepsize) - desc->iffreq;
+}
+
+static int dvb_pll_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int dvb_pll_sleep(struct dvb_frontend *fe)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+
+       if (priv->i2c == NULL)
+               return -EINVAL;
+
+       if (priv->pll_desc->sleepdata) {
+               struct i2c_msg msg = { .flags = 0,
+                       .addr = priv->pll_i2c_address,
+                       .buf = priv->pll_desc->sleepdata + 1,
+                       .len = priv->pll_desc->sleepdata[0] };
+
+               int result;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+                       return result;
+               }
+               return 0;
+       }
+       /* Shouldn't be called when initdata is NULL, maybe BUG()? */
+       return -EINVAL;
+}
+
+static int dvb_pll_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       u8 buf[4];
+       struct i2c_msg msg =
+               { .addr = priv->pll_i2c_address, .flags = 0,
+                 .buf = buf, .len = sizeof(buf) };
+       int result;
+       u32 frequency = 0;
+
+       if (priv->i2c == NULL)
+               return -EINVAL;
+
+       result = dvb_pll_configure(fe, buf, c->frequency);
+       if (result < 0)
+               return result;
+       else
+               frequency = result;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+               return result;
+       }
+
+       priv->frequency = frequency;
+       priv->bandwidth = c->bandwidth_hz;
+
+       return 0;
+}
+
+static int dvb_pll_calc_regs(struct dvb_frontend *fe,
+                            u8 *buf, int buf_len)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       int result;
+       u32 frequency = 0;
+
+       if (buf_len < 5)
+               return -EINVAL;
+
+       result = dvb_pll_configure(fe, buf + 1, c->frequency);
+       if (result < 0)
+               return result;
+       else
+               frequency = result;
+
+       buf[0] = priv->pll_i2c_address;
+
+       priv->frequency = frequency;
+       priv->bandwidth = c->bandwidth_hz;
+
+       return 5;
+}
+
+static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int dvb_pll_init(struct dvb_frontend *fe)
+{
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+
+       if (priv->i2c == NULL)
+               return -EINVAL;
+
+       if (priv->pll_desc->initdata) {
+               struct i2c_msg msg = { .flags = 0,
+                       .addr = priv->pll_i2c_address,
+                       .buf = priv->pll_desc->initdata + 1,
+                       .len = priv->pll_desc->initdata[0] };
+
+               int result;
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               result = i2c_transfer(priv->i2c, &msg, 1);
+               if (result != 1)
+                       return result;
+               if (priv->pll_desc->initdata2) {
+                       msg.buf = priv->pll_desc->initdata2 + 1;
+                       msg.len = priv->pll_desc->initdata2[0];
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 1);
+                       result = i2c_transfer(priv->i2c, &msg, 1);
+                       if (result != 1)
+                               return result;
+               }
+               return 0;
+       }
+       /* Shouldn't be called when initdata is NULL, maybe BUG()? */
+       return -EINVAL;
+}
+
+static struct dvb_tuner_ops dvb_pll_tuner_ops = {
+       .release = dvb_pll_release,
+       .sleep = dvb_pll_sleep,
+       .init = dvb_pll_init,
+       .set_params = dvb_pll_set_params,
+       .calc_regs = dvb_pll_calc_regs,
+       .get_frequency = dvb_pll_get_frequency,
+       .get_bandwidth = dvb_pll_get_bandwidth,
+};
+
+struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
+                                   struct i2c_adapter *i2c,
+                                   unsigned int pll_desc_id)
+{
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
+                              .buf = b1, .len = 1 };
+       struct dvb_pll_priv *priv = NULL;
+       int ret;
+       struct dvb_pll_desc *desc;
+
+       if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
+           (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
+               pll_desc_id = id[dvb_pll_devcount];
+
+       BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
+
+       desc = pll_list[pll_desc_id];
+
+       if (i2c != NULL) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = i2c_transfer (i2c, &msg, 1);
+               if (ret != 1)
+                       return NULL;
+               if (fe->ops.i2c_gate_ctrl)
+                            fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->pll_i2c_address = pll_addr;
+       priv->i2c = i2c;
+       priv->pll_desc = desc;
+       priv->nr = dvb_pll_devcount++;
+
+       memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       strncpy(fe->ops.tuner_ops.info.name, desc->name,
+               sizeof(fe->ops.tuner_ops.info.name));
+       fe->ops.tuner_ops.info.frequency_min = desc->min;
+       fe->ops.tuner_ops.info.frequency_max = desc->max;
+       if (!desc->initdata)
+               fe->ops.tuner_ops.init = NULL;
+       if (!desc->sleepdata)
+               fe->ops.tuner_ops.sleep = NULL;
+
+       fe->tuner_priv = priv;
+
+       if ((debug) || (id[priv->nr] == pll_desc_id)) {
+               printk("dvb-pll[%d]", priv->nr);
+               if (i2c != NULL)
+                       printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
+               printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
+                      id[priv->nr] == pll_desc_id ?
+                               "insmod option" : "autodetected");
+       }
+
+       return fe;
+}
+EXPORT_SYMBOL(dvb_pll_attach);
+
+MODULE_DESCRIPTION("dvb pll library");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h
new file mode 100644 (file)
index 0000000..4de754f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * descriptions + helper functions for simple dvb plls.
+ */
+
+#ifndef __DVB_PLL_H__
+#define __DVB_PLL_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#define DVB_PLL_UNDEFINED               0
+#define DVB_PLL_THOMSON_DTT7579         1
+#define DVB_PLL_THOMSON_DTT759X         2
+#define DVB_PLL_LG_Z201                 3
+#define DVB_PLL_UNKNOWN_1               4
+#define DVB_PLL_TUA6010XS               5
+#define DVB_PLL_ENV57H1XD5              6
+#define DVB_PLL_TUA6034                 7
+#define DVB_PLL_TDA665X                 8
+#define DVB_PLL_TDED4                   9
+#define DVB_PLL_TDHU2                  10
+#define DVB_PLL_SAMSUNG_TBMV           11
+#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
+#define DVB_PLL_OPERA1                 13
+#define DVB_PLL_SAMSUNG_DTOS403IH102A  14
+#define DVB_PLL_SAMSUNG_TDTC9251DH0    15
+#define DVB_PLL_SAMSUNG_TBDU18132      16
+#define DVB_PLL_SAMSUNG_TBMU24112      17
+#define DVB_PLL_TDEE4                 18
+#define DVB_PLL_THOMSON_DTT7520X       19
+
+/**
+ * Attach a dvb-pll to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param pll_addr i2c address of the PLL (if used).
+ * @param i2c i2c adapter to use (set to NULL if not used).
+ * @param pll_desc_id dvb_pll_desc to use.
+ * @return Frontend pointer on success, NULL on failure
+ */
+#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
+                                          int pll_addr,
+                                          struct i2c_adapter *i2c,
+                                          unsigned int pll_desc_id);
+#else
+static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
+                                          int pll_addr,
+                                          struct i2c_adapter *i2c,
+                                          unsigned int pll_desc_id)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c
new file mode 100644 (file)
index 0000000..dcfc902
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ *  Driver for Dummy Frontend
+ *
+ *  Written by Emard <emard@softhome.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "dvb_dummy_fe.h"
+
+
+struct dvb_dummy_fe_state {
+       struct dvb_frontend frontend;
+};
+
+
+static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       *status = FE_HAS_SIGNAL
+               | FE_HAS_CARRIER
+               | FE_HAS_VITERBI
+               | FE_HAS_SYNC
+               | FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       *ber = 0;
+       return 0;
+}
+
+static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       *strength = 0;
+       return 0;
+}
+
+static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       *snr = 0;
+       return 0;
+}
+
+static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+/*
+ * Only needed if it actually reads something from the hardware
+ */
+static int dvb_dummy_fe_get_frontend(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe)
+{
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       return 0;
+}
+
+static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int dvb_dummy_fe_init(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       return 0;
+}
+
+static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       return 0;
+}
+
+static void dvb_dummy_fe_release(struct dvb_frontend* fe)
+{
+       struct dvb_dummy_fe_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
+
+struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
+{
+       struct dvb_dummy_fe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
+
+struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+       struct dvb_dummy_fe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
+
+struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+       struct dvb_dummy_fe_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Dummy DVB-T",
+               .frequency_min          = 0,
+               .frequency_max          = 863250000,
+               .frequency_stepsize     = 62500,
+               .caps = 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_6_7 |
+                               FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                               FE_CAN_TRANSMISSION_MODE_AUTO |
+                               FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = dvb_dummy_fe_release,
+
+       .init = dvb_dummy_fe_init,
+       .sleep = dvb_dummy_fe_sleep,
+
+       .set_frontend = dvb_dummy_fe_set_frontend,
+       .get_frontend = dvb_dummy_fe_get_frontend,
+
+       .read_status = dvb_dummy_fe_read_status,
+       .read_ber = dvb_dummy_fe_read_ber,
+       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
+       .read_snr = dvb_dummy_fe_read_snr,
+       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
+};
+
+static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A },
+       .info = {
+               .name                   = "Dummy DVB-C",
+               .frequency_stepsize     = 62500,
+               .frequency_min          = 51000000,
+               .frequency_max          = 858000000,
+               .symbol_rate_min        = (57840000/2)/64,     /* SACLK/64 == (XIN/2)/64 */
+               .symbol_rate_max        = (57840000/2)/4,      /* SACLK/4 */
+               .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+                       FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
+       },
+
+       .release = dvb_dummy_fe_release,
+
+       .init = dvb_dummy_fe_init,
+       .sleep = dvb_dummy_fe_sleep,
+
+       .set_frontend = dvb_dummy_fe_set_frontend,
+       .get_frontend = dvb_dummy_fe_get_frontend,
+
+       .read_status = dvb_dummy_fe_read_status,
+       .read_ber = dvb_dummy_fe_read_ber,
+       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
+       .read_snr = dvb_dummy_fe_read_snr,
+       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
+};
+
+static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "Dummy DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 250,           /* kHz for QPSK frontends */
+               .frequency_tolerance    = 29500,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK
+       },
+
+       .release = dvb_dummy_fe_release,
+
+       .init = dvb_dummy_fe_init,
+       .sleep = dvb_dummy_fe_sleep,
+
+       .set_frontend = dvb_dummy_fe_set_frontend,
+       .get_frontend = dvb_dummy_fe_get_frontend,
+
+       .read_status = dvb_dummy_fe_read_status,
+       .read_ber = dvb_dummy_fe_read_ber,
+       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
+       .read_snr = dvb_dummy_fe_read_snr,
+       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
+
+       .set_voltage = dvb_dummy_fe_set_voltage,
+       .set_tone = dvb_dummy_fe_set_tone,
+};
+
+MODULE_DESCRIPTION("DVB DUMMY Frontend");
+MODULE_AUTHOR("Emard");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
+EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
+EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.h b/drivers/media/dvb-frontends/dvb_dummy_fe.h
new file mode 100644 (file)
index 0000000..1fcb987
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Driver for Dummy Frontend
+ *
+ *  Written by Emard <emard@softhome.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef DVB_DUMMY_FE_H
+#define DVB_DUMMY_FE_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
+defined(MODULE))
+extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
+extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
+extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
+#else
+static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_DUMMY_FE */
+
+#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c
new file mode 100644 (file)
index 0000000..c56fddb
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "dvb_frontend.h"
+#include "ec100_priv.h"
+#include "ec100.h"
+
+int ec100_debug;
+module_param_named(debug, ec100_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+struct ec100_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend frontend;
+       struct ec100_config config;
+
+       u16 ber;
+};
+
+/* write single register */
+static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
+{
+       u8 buf[2] = {reg, val};
+       struct i2c_msg msg = {
+               .addr = state->config.demod_address,
+               .flags = 0,
+               .len = 2,
+               .buf = buf};
+
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               warn("I2C write failed reg:%02x", reg);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* read single register */
+static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = state->config.demod_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg
+               }, {
+                       .addr = state->config.demod_address,
+                       .flags = I2C_M_RD,
+                       .len = 1,
+                       .buf = val
+               }
+       };
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               warn("I2C read failed reg:%02x", reg);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int ec100_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct ec100_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp, tmp2;
+
+       deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency,
+               c->bandwidth_hz);
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       ret = ec100_write_reg(state, 0x04, 0x06);
+       if (ret)
+               goto error;
+       ret = ec100_write_reg(state, 0x67, 0x58);
+       if (ret)
+               goto error;
+       ret = ec100_write_reg(state, 0x05, 0x18);
+       if (ret)
+               goto error;
+
+       /* reg/bw |   6  |   7  |   8
+          -------+------+------+------
+          A 0x1b | 0xa1 | 0xe7 | 0x2c
+          A 0x1c | 0x55 | 0x63 | 0x72
+          -------+------+------+------
+          B 0x1b | 0xb7 | 0x00 | 0x49
+          B 0x1c | 0x55 | 0x64 | 0x72 */
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               tmp = 0xb7;
+               tmp2 = 0x55;
+               break;
+       case 7000000:
+               tmp = 0x00;
+               tmp2 = 0x64;
+               break;
+       case 8000000:
+       default:
+               tmp = 0x49;
+               tmp2 = 0x72;
+       }
+
+       ret = ec100_write_reg(state, 0x1b, tmp);
+       if (ret)
+               goto error;
+       ret = ec100_write_reg(state, 0x1c, tmp2);
+       if (ret)
+               goto error;
+
+       ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
+       if (ret)
+               goto error;
+       ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
+       if (ret)
+               goto error;
+
+       ret = ec100_write_reg(state, 0x08, 0x24);
+       if (ret)
+               goto error;
+
+       ret = ec100_write_reg(state, 0x00, 0x00); /* go */
+       if (ret)
+               goto error;
+       ret = ec100_write_reg(state, 0x00, 0x20); /* go */
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       deb_info("%s: failed:%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec100_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 300;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+
+       return 0;
+}
+
+static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct ec100_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+       *status = 0;
+
+       ret = ec100_read_reg(state, 0x42, &tmp);
+       if (ret)
+               goto error;
+
+       if (tmp & 0x80) {
+               /* bit7 set - have lock */
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+                       FE_HAS_SYNC | FE_HAS_LOCK;
+       } else {
+               ret = ec100_read_reg(state, 0x01, &tmp);
+               if (ret)
+                       goto error;
+
+               if (tmp & 0x10) {
+                       /* bit4 set - have signal */
+                       *status |= FE_HAS_SIGNAL;
+                       if (!(tmp & 0x01)) {
+                               /* bit0 clear - have ~valid signal */
+                               *status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
+                       }
+               }
+       }
+
+       return ret;
+error:
+       deb_info("%s: failed:%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct ec100_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp, tmp2;
+       u16 ber2;
+
+       *ber = 0;
+
+       ret = ec100_read_reg(state, 0x65, &tmp);
+       if (ret)
+               goto error;
+       ret = ec100_read_reg(state, 0x66, &tmp2);
+       if (ret)
+               goto error;
+
+       ber2 = (tmp2 << 8) | tmp;
+
+       /* if counter overflow or clear */
+       if (ber2 < state->ber)
+               *ber = ber2;
+       else
+               *ber = ber2 - state->ber;
+
+       state->ber = ber2;
+
+       return ret;
+error:
+       deb_info("%s: failed:%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct ec100_state *state = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+
+       ret = ec100_read_reg(state, 0x24, &tmp);
+       if (ret) {
+               *strength = 0;
+               goto error;
+       }
+
+       *strength = ((tmp << 8) | tmp);
+
+       return ret;
+error:
+       deb_info("%s: failed:%d\n", __func__, ret);
+       return ret;
+}
+
+static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       *snr = 0;
+       return 0;
+}
+
+static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+static void ec100_release(struct dvb_frontend *fe)
+{
+       struct ec100_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops ec100_ops;
+
+struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+       struct i2c_adapter *i2c)
+{
+       int ret;
+       struct ec100_state *state = NULL;
+       u8 tmp;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config, config, sizeof(struct ec100_config));
+
+       /* check if the demod is there */
+       ret = ec100_read_reg(state, 0x33, &tmp);
+       if (ret || tmp != 0x0b)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &ec100_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(ec100_attach);
+
+static struct dvb_frontend_ops ec100_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "E3C EC100 DVB-T",
+               .caps =
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = ec100_release,
+       .set_frontend = ec100_set_frontend,
+       .get_tune_settings = ec100_get_tune_settings,
+       .read_status = ec100_read_status,
+       .read_ber = ec100_read_ber,
+       .read_signal_strength = ec100_read_signal_strength,
+       .read_snr = ec100_read_snr,
+       .read_ucblocks = ec100_read_ucblocks,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/ec100.h b/drivers/media/dvb-frontends/ec100.h
new file mode 100644 (file)
index 0000000..ee8e524
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef EC100_H
+#define EC100_H
+
+#include <linux/dvb/frontend.h>
+
+struct ec100_config {
+       /* demodulator's I2C address */
+       u8 demod_address;
+};
+
+
+#if defined(CONFIG_DVB_EC100) || \
+       (defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *ec100_attach(
+       const struct ec100_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* EC100_H */
diff --git a/drivers/media/dvb-frontends/ec100_priv.h b/drivers/media/dvb-frontends/ec100_priv.h
new file mode 100644 (file)
index 0000000..5c99014
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * E3C EC100 demodulator driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef EC100_PRIV
+#define EC100_PRIV
+
+#define LOG_PREFIX "ec100"
+
+#define dprintk(var, level, args...) \
+       do { if ((var & level)) printk(args); } while (0)
+
+#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
+
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb-frontends/eds1547.h b/drivers/media/dvb-frontends/eds1547.h
new file mode 100644 (file)
index 0000000..c983f2f
--- /dev/null
@@ -0,0 +1,133 @@
+/* eds1547.h Earda EDS-1547 tuner support
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+*      This program is free software; you can redistribute it and/or modify it
+*      under the terms of the GNU General Public License as published by the
+*      Free Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#ifndef EDS1547
+#define EDS1547
+
+static u8 stv0288_earda_inittab[] = {
+       0x01, 0x57,
+       0x02, 0x20,
+       0x03, 0x8e,
+       0x04, 0x8e,
+       0x05, 0x12,
+       0x06, 0x00,
+       0x07, 0x00,
+       0x09, 0x00,
+       0x0a, 0x04,
+       0x0b, 0x00,
+       0x0c, 0x00,
+       0x0d, 0x00,
+       0x0e, 0xd4,
+       0x0f, 0x30,
+       0x11, 0x44,
+       0x12, 0x03,
+       0x13, 0x48,
+       0x14, 0x84,
+       0x15, 0x45,
+       0x16, 0xb7,
+       0x17, 0x9c,
+       0x18, 0x00,
+       0x19, 0xa6,
+       0x1a, 0x88,
+       0x1b, 0x8f,
+       0x1c, 0xf0,
+       0x20, 0x0b,
+       0x21, 0x54,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x2b, 0xff,
+       0x2c, 0xf7,
+       0x30, 0x00,
+       0x31, 0x1e,
+       0x32, 0x14,
+       0x33, 0x0f,
+       0x34, 0x09,
+       0x35, 0x0c,
+       0x36, 0x05,
+       0x37, 0x2f,
+       0x38, 0x16,
+       0x39, 0xbd,
+       0x3a, 0x00,
+       0x3b, 0x13,
+       0x3c, 0x11,
+       0x3d, 0x30,
+       0x40, 0x63,
+       0x41, 0x04,
+       0x42, 0x20,
+       0x43, 0x00,
+       0x44, 0x00,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x47, 0x00,
+       0x4a, 0x00,
+       0x50, 0x10,
+       0x51, 0x36,
+       0x52, 0x09,
+       0x53, 0x94,
+       0x54, 0x62,
+       0x55, 0x29,
+       0x56, 0x64,
+       0x57, 0x2b,
+       0x58, 0x54,
+       0x59, 0x86,
+       0x5a, 0x00,
+       0x5b, 0x9b,
+       0x5c, 0x08,
+       0x5d, 0x7f,
+       0x5e, 0x00,
+       0x5f, 0xff,
+       0x70, 0x00,
+       0x71, 0x00,
+       0x72, 0x00,
+       0x74, 0x00,
+       0x75, 0x00,
+       0x76, 0x00,
+       0x81, 0x00,
+       0x82, 0x3f,
+       0x83, 0x3f,
+       0x84, 0x00,
+       0x85, 0x00,
+       0x88, 0x00,
+       0x89, 0x00,
+       0x8a, 0x00,
+       0x8b, 0x00,
+       0x8c, 0x00,
+       0x90, 0x00,
+       0x91, 0x00,
+       0x92, 0x00,
+       0x93, 0x00,
+       0x94, 0x1c,
+       0x97, 0x00,
+       0xa0, 0x48,
+       0xa1, 0x00,
+       0xb0, 0xb8,
+       0xb1, 0x3a,
+       0xb2, 0x10,
+       0xb3, 0x82,
+       0xb4, 0x80,
+       0xb5, 0x82,
+       0xb6, 0x82,
+       0xb7, 0x82,
+       0xb8, 0x20,
+       0xb9, 0x00,
+       0xf0, 0x00,
+       0xf1, 0x00,
+       0xf2, 0xc0,
+       0xff,0xff,
+};
+
+static struct stv0288_config earda_config = {
+       .demod_address = 0x68,
+       .min_delay_ms = 100,
+       .inittab = stv0288_earda_inittab,
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c
new file mode 100644 (file)
index 0000000..a003181
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * HDIC HD29L2 DMB-TH demodulator driver
+ *
+ * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
+ *
+ * Author: Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "hd29l2_priv.h"
+
+int hd29l2_debug;
+module_param_named(debug, hd29l2_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+/* write multiple registers */
+static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       u8 buf[2 + len];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = 0x00;
+       buf[1] = reg;
+       memcpy(&buf[2], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* read multiple registers */
+static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       u8 buf[2] = { 0x00, reg };
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 2,
+                       .buf = buf,
+               }, {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* write single register */
+static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val)
+{
+       return hd29l2_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val)
+{
+       return hd29l2_rd_regs(priv, reg, val, 1);
+}
+
+/* write single register with mask */
+static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return hd29l2_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register with mask */
+int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+static int hd29l2_soft_reset(struct hd29l2_priv *priv)
+{
+       int ret;
+       u8 tmp;
+
+       ret = hd29l2_rd_reg(priv, 0x26, &tmp);
+       if (ret)
+               goto err;
+
+       ret = hd29l2_wr_reg(priv, 0x26, 0x0d);
+       if (ret)
+               goto err;
+
+       usleep_range(10000, 20000);
+
+       ret = hd29l2_wr_reg(priv, 0x26, tmp);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       int ret, i;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 tmp;
+
+       dbg("%s: enable=%d", __func__, enable);
+
+       /* set tuner address for demod */
+       if (!priv->tuner_i2c_addr_programmed && enable) {
+               /* no need to set tuner address every time, once is enough */
+               ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1);
+               if (ret)
+                       goto err;
+
+               priv->tuner_i2c_addr_programmed = true;
+       }
+
+       /* open / close gate */
+       ret = hd29l2_wr_reg(priv, 0x9f, enable);
+       if (ret)
+               goto err;
+
+       /* wait demod ready */
+       for (i = 10; i; i--) {
+               ret = hd29l2_rd_reg(priv, 0x9e, &tmp);
+               if (ret)
+                       goto err;
+
+               if (tmp == enable)
+                       break;
+
+               usleep_range(5000, 10000);
+       }
+
+       dbg("%s: loop=%d", __func__, i);
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       int ret;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 buf[2];
+
+       *status = 0;
+
+       ret = hd29l2_rd_reg(priv, 0x05, &buf[0]);
+       if (ret)
+               goto err;
+
+       if (buf[0] & 0x01) {
+               /* full lock */
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+                       FE_HAS_SYNC | FE_HAS_LOCK;
+       } else {
+               ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]);
+               if (ret)
+                       goto err;
+
+               if ((buf[1] & 0xfe) == 0x78)
+                       /* partial lock */
+                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC;
+       }
+
+       priv->fe_status = *status;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       int ret;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 buf[2];
+       u16 tmp;
+
+       if (!(priv->fe_status & FE_HAS_LOCK)) {
+               *snr = 0;
+               ret = 0;
+               goto err;
+       }
+
+       ret = hd29l2_rd_regs(priv, 0x0b, buf, 2);
+       if (ret)
+               goto err;
+
+       tmp = (buf[0] << 8) | buf[1];
+
+       /* report SNR in dB * 10 */
+       #define LOG10_20736_24 72422627 /* log10(20736) << 24 */
+       if (tmp)
+               *snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100);
+       else
+               *snr = 0;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       int ret;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 buf[2];
+       u16 tmp;
+
+       *strength = 0;
+
+       ret = hd29l2_rd_regs(priv, 0xd5, buf, 2);
+       if (ret)
+               goto err;
+
+       tmp = buf[0] << 8 | buf[1];
+       tmp = ~tmp & 0x0fff;
+
+       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
+       *strength = tmp * 0xffff / 0x0fff;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       int ret;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 buf[2];
+
+       if (!(priv->fe_status & FE_HAS_SYNC)) {
+               *ber = 0;
+               ret = 0;
+               goto err;
+       }
+
+       ret = hd29l2_rd_regs(priv, 0xd9, buf, 2);
+       if (ret) {
+               *ber = 0;
+               goto err;
+       }
+
+       /* LDPC BER */
+       *ber = ((buf[0] & 0x0f) << 8) | buf[1];
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       /* no way to read? */
+       *ucblocks = 0;
+       return 0;
+}
+
+static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
+{
+       int ret, i;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 tmp, buf[3];
+       u8 modulation, carrier, guard_interval, interleave, code_rate;
+       u64 num64;
+       u32 if_freq, if_ctl;
+       bool auto_mode;
+
+       dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d " \
+               "modulation=%d inversion=%d fec_inner=%d guard_interval=%d",
+                __func__,
+               c->delivery_system, c->frequency, c->bandwidth_hz,
+               c->modulation, c->inversion, c->fec_inner, c->guard_interval);
+
+       /* as for now we detect always params automatically */
+       auto_mode = true;
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       /* get and program IF */
+       if (fe->ops.tuner_ops.get_if_frequency)
+               fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+       else
+               if_freq = 0;
+
+       if (if_freq) {
+               /* normal IF */
+
+               /* calc IF control value */
+               num64 = if_freq;
+               num64 *= 0x800000;
+               num64 = div_u64(num64, HD29L2_XTAL);
+               num64 -= 0x800000;
+               if_ctl = num64;
+
+               tmp = 0xfc; /* tuner type normal */
+       } else {
+               /* zero IF */
+               if_ctl = 0;
+               tmp = 0xfe; /* tuner type Zero-IF */
+       }
+
+       buf[0] = ((if_ctl >>  0) & 0xff);
+       buf[1] = ((if_ctl >>  8) & 0xff);
+       buf[2] = ((if_ctl >> 16) & 0xff);
+
+       /* program IF control */
+       ret = hd29l2_wr_regs(priv, 0x14, buf, 3);
+       if (ret)
+               goto err;
+
+       /* program tuner type */
+       ret = hd29l2_wr_reg(priv, 0xab, tmp);
+       if (ret)
+               goto err;
+
+       dbg("%s: if_freq=%d if_ctl=%x", __func__, if_freq, if_ctl);
+
+       if (auto_mode) {
+               /*
+                * use auto mode
+                */
+
+               /* disable quick mode */
+               ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80);
+               if (ret)
+                       goto err;
+
+               ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02);
+               if (ret)
+                       goto err;
+
+               /* enable auto mode */
+               ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40);
+               if (ret)
+                       goto err;
+
+               ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08);
+               if (ret)
+                       goto err;
+
+               /* soft reset */
+               ret = hd29l2_soft_reset(priv);
+               if (ret)
+                       goto err;
+
+               /* detect modulation */
+               for (i = 30; i; i--) {
+                       msleep(100);
+
+                       ret = hd29l2_rd_reg(priv, 0x0d, &tmp);
+                       if (ret)
+                               goto err;
+
+                       if ((((tmp & 0xf0) >= 0x10) &&
+                               ((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c))
+                               break;
+               }
+
+               dbg("%s: loop=%d", __func__, i);
+
+               if (i == 0)
+                       /* detection failed */
+                       return DVBFE_ALGO_SEARCH_FAILED;
+
+               /* read modulation */
+               ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07);
+               if (ret)
+                       goto err;
+       } else {
+               /*
+                * use manual mode
+                */
+
+               modulation = HD29L2_QAM64;
+               carrier = HD29L2_CARRIER_MULTI;
+               guard_interval = HD29L2_PN945;
+               interleave = HD29L2_INTERLEAVER_420;
+               code_rate = HD29L2_CODE_RATE_08;
+
+               tmp = (code_rate << 3) | modulation;
+               ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f);
+               if (ret)
+                       goto err;
+
+               tmp = (carrier << 2) | guard_interval;
+               ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f);
+               if (ret)
+                       goto err;
+
+               tmp = interleave;
+               ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03);
+               if (ret)
+                       goto err;
+       }
+
+       /* ensure modulation validy */
+       /* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */
+       if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
+               dbg("%s: modulation=%d not valid", __func__, modulation);
+               goto err;
+       }
+
+       /* program registers according to modulation */
+       for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) {
+               ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg,
+                       reg_mod_vals_tab[i].val[modulation]);
+               if (ret)
+                       goto err;
+       }
+
+       /* read guard interval */
+       ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03);
+       if (ret)
+               goto err;
+
+       /* read carrier mode */
+       ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04);
+       if (ret)
+               goto err;
+
+       dbg("%s: modulation=%d guard_interval=%d carrier=%d",
+               __func__, modulation, guard_interval, carrier);
+
+       if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
+               (guard_interval == HD29L2_PN945)) {
+               dbg("%s: C=3780 && QAM64 && PN945", __func__);
+
+               ret = hd29l2_wr_reg(priv, 0x42, 0x33);
+               if (ret)
+                       goto err;
+
+               ret = hd29l2_wr_reg(priv, 0xdd, 0x01);
+               if (ret)
+                       goto err;
+       }
+
+       usleep_range(10000, 20000);
+
+       /* soft reset */
+       ret = hd29l2_soft_reset(priv);
+       if (ret)
+               goto err;
+
+       /* wait demod lock */
+       for (i = 30; i; i--) {
+               msleep(100);
+
+               /* read lock bit */
+               ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01);
+               if (ret)
+                       goto err;
+
+               if (tmp)
+                       break;
+       }
+
+       dbg("%s: loop=%d", __func__, i);
+
+       if (i == 0)
+               return DVBFE_ALGO_SEARCH_AGAIN;
+
+       return DVBFE_ALGO_SEARCH_SUCCESS;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int hd29l2_get_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+static int hd29l2_get_frontend(struct dvb_frontend *fe)
+{
+       int ret;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 buf[3];
+       u32 if_ctl;
+       char *str_constellation, *str_code_rate, *str_constellation_code_rate,
+               *str_guard_interval, *str_carrier, *str_guard_interval_carrier,
+               *str_interleave, *str_interleave_;
+
+       ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]);
+       if (ret)
+               goto err;
+
+       ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2);
+       if (ret)
+               goto err;
+
+       /* constellation, 0x7d[2:0] */
+       switch ((buf[0] >> 0) & 0x07) {
+       case 0: /* QAM4NR */
+               str_constellation = "QAM4NR";
+               c->modulation = QAM_AUTO; /* FIXME */
+               break;
+       case 1: /* QAM4 */
+               str_constellation = "QAM4";
+               c->modulation = QPSK; /* FIXME */
+               break;
+       case 2:
+               str_constellation = "QAM16";
+               c->modulation = QAM_16;
+               break;
+       case 3:
+               str_constellation = "QAM32";
+               c->modulation = QAM_32;
+               break;
+       case 4:
+               str_constellation = "QAM64";
+               c->modulation = QAM_64;
+               break;
+       default:
+               str_constellation = "?";
+       }
+
+       /* LDPC code rate, 0x7d[4:3] */
+       switch ((buf[0] >> 3) & 0x03) {
+       case 0: /* 0.4 */
+               str_code_rate = "0.4";
+               c->fec_inner = FEC_AUTO; /* FIXME */
+               break;
+       case 1: /* 0.6 */
+               str_code_rate = "0.6";
+               c->fec_inner = FEC_3_5;
+               break;
+       case 2: /* 0.8 */
+               str_code_rate = "0.8";
+               c->fec_inner = FEC_4_5;
+               break;
+       default:
+               str_code_rate = "?";
+       }
+
+       /* constellation & code rate set, 0x7d[6] */
+       switch ((buf[0] >> 6) & 0x01) {
+       case 0:
+               str_constellation_code_rate = "manual";
+               break;
+       case 1:
+               str_constellation_code_rate = "auto";
+               break;
+       default:
+               str_constellation_code_rate = "?";
+       }
+
+       /* frame header, 0x81[1:0] */
+       switch ((buf[1] >> 0) & 0x03) {
+       case 0: /* PN945 */
+               str_guard_interval = "PN945";
+               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
+               break;
+       case 1: /* PN595 */
+               str_guard_interval = "PN595";
+               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
+               break;
+       case 2: /* PN420 */
+               str_guard_interval = "PN420";
+               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
+               break;
+       default:
+               str_guard_interval = "?";
+       }
+
+       /* carrier, 0x81[2] */
+       switch ((buf[1] >> 2) & 0x01) {
+       case 0:
+               str_carrier = "C=1";
+               break;
+       case 1:
+               str_carrier = "C=3780";
+               break;
+       default:
+               str_carrier = "?";
+       }
+
+       /* frame header & carrier set, 0x81[3] */
+       switch ((buf[1] >> 3) & 0x01) {
+       case 0:
+               str_guard_interval_carrier = "manual";
+               break;
+       case 1:
+               str_guard_interval_carrier = "auto";
+               break;
+       default:
+               str_guard_interval_carrier = "?";
+       }
+
+       /* interleave, 0x82[0] */
+       switch ((buf[2] >> 0) & 0x01) {
+       case 0:
+               str_interleave = "M=720";
+               break;
+       case 1:
+               str_interleave = "M=240";
+               break;
+       default:
+               str_interleave = "?";
+       }
+
+       /* interleave set, 0x82[1] */
+       switch ((buf[2] >> 1) & 0x01) {
+       case 0:
+               str_interleave_ = "manual";
+               break;
+       case 1:
+               str_interleave_ = "auto";
+               break;
+       default:
+               str_interleave_ = "?";
+       }
+
+       /*
+        * We can read out current detected NCO and use that value next
+        * time instead of calculating new value from targed IF.
+        * I think it will not effect receiver sensitivity but gaining lock
+        * after tune could be easier...
+        */
+       ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3);
+       if (ret)
+               goto err;
+
+       if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];
+
+       dbg("%s: %s %s %s | %s %s %s | %s %s | NCO=%06x", __func__,
+               str_constellation, str_code_rate, str_constellation_code_rate,
+               str_guard_interval, str_carrier, str_guard_interval_carrier,
+               str_interleave, str_interleave_, if_ctl);
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int hd29l2_init(struct dvb_frontend *fe)
+{
+       int ret, i;
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       u8 tmp;
+       static const struct reg_val tab[] = {
+               { 0x3a, 0x06 },
+               { 0x3b, 0x03 },
+               { 0x3c, 0x04 },
+               { 0xaf, 0x06 },
+               { 0xb0, 0x1b },
+               { 0x80, 0x64 },
+               { 0x10, 0x38 },
+       };
+
+       dbg("%s:", __func__);
+
+       /* reset demod */
+       /* it is recommended to HW reset chip using RST_N pin */
+       if (fe->callback) {
+               ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0);
+               if (ret)
+                       goto err;
+
+               /* reprogramming needed because HW reset clears registers */
+               priv->tuner_i2c_addr_programmed = false;
+       }
+
+       /* init */
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val);
+               if (ret)
+                       goto err;
+       }
+
+       /* TS params */
+       ret = hd29l2_rd_reg(priv, 0x36, &tmp);
+       if (ret)
+               goto err;
+
+       tmp &= 0x1b;
+       tmp |= priv->cfg.ts_mode;
+       ret = hd29l2_wr_reg(priv, 0x36, tmp);
+       if (ret)
+               goto err;
+
+       ret = hd29l2_rd_reg(priv, 0x31, &tmp);
+       tmp &= 0xef;
+
+       if (!(priv->cfg.ts_mode >> 7))
+               /* set b4 for serial TS */
+               tmp |= 0x10;
+
+       ret = hd29l2_wr_reg(priv, 0x31, tmp);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static void hd29l2_release(struct dvb_frontend *fe)
+{
+       struct hd29l2_priv *priv = fe->demodulator_priv;
+       kfree(priv);
+}
+
+static struct dvb_frontend_ops hd29l2_ops;
+
+struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
+       struct i2c_adapter *i2c)
+{
+       int ret;
+       struct hd29l2_priv *priv = NULL;
+       u8 tmp;
+
+       /* allocate memory for the internal state */
+       priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL);
+       if (priv == NULL)
+               goto err;
+
+       /* setup the state */
+       priv->i2c = i2c;
+       memcpy(&priv->cfg, config, sizeof(struct hd29l2_config));
+
+
+       /* check if the demod is there */
+       ret = hd29l2_rd_reg(priv, 0x00, &tmp);
+       if (ret)
+               goto err;
+
+       /* create dvb_frontend */
+       memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops));
+       priv->fe.demodulator_priv = priv;
+
+       return &priv->fe;
+err:
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(hd29l2_attach);
+
+static struct dvb_frontend_ops hd29l2_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "HDIC HD29L2 DMB-TH",
+               .frequency_min = 474000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 10000,
+               .caps = FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_32 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_BANDWIDTH_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER
+       },
+
+       .release = hd29l2_release,
+
+       .init = hd29l2_init,
+
+       .get_frontend_algo = hd29l2_get_frontend_algo,
+       .search = hd29l2_search,
+       .get_frontend = hd29l2_get_frontend,
+
+       .read_status = hd29l2_read_status,
+       .read_snr = hd29l2_read_snr,
+       .read_signal_strength = hd29l2_read_signal_strength,
+       .read_ber = hd29l2_read_ber,
+       .read_ucblocks = hd29l2_read_ucblocks,
+
+       .i2c_gate_ctrl = hd29l2_i2c_gate_ctrl,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/hd29l2.h b/drivers/media/dvb-frontends/hd29l2.h
new file mode 100644 (file)
index 0000000..a7a6443
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * HDIC HD29L2 DMB-TH demodulator driver
+ *
+ * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
+ *
+ * Author: Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef HD29L2_H
+#define HD29L2_H
+
+#include <linux/dvb/frontend.h>
+
+struct hd29l2_config {
+       /*
+        * demodulator I2C address
+        */
+       u8 i2c_addr;
+
+       /*
+        * tuner I2C address
+        * only needed when tuner is behind demod I2C-gate
+        */
+       u8 tuner_i2c_addr;
+
+       /*
+        * TS settings
+        */
+#define HD29L2_TS_SERIAL            0x00
+#define HD29L2_TS_PARALLEL          0x80
+#define HD29L2_TS_CLK_NORMAL        0x40
+#define HD29L2_TS_CLK_INVERTED      0x00
+#define HD29L2_TS_CLK_GATED         0x20
+#define HD29L2_TS_CLK_FREE          0x00
+       u8 ts_mode;
+};
+
+
+#if defined(CONFIG_DVB_HD29L2) || \
+       (defined(CONFIG_DVB_HD29L2_MODULE) && defined(MODULE))
+extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *hd29l2_attach(
+const struct hd29l2_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* HD29L2_H */
diff --git a/drivers/media/dvb-frontends/hd29l2_priv.h b/drivers/media/dvb-frontends/hd29l2_priv.h
new file mode 100644 (file)
index 0000000..ba16dc3
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * HDIC HD29L2 DMB-TH demodulator driver
+ *
+ * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
+ *
+ * Author: Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef HD29L2_PRIV
+#define HD29L2_PRIV
+
+#include <linux/dvb/version.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "hd29l2.h"
+
+#define LOG_PREFIX "hd29l2"
+
+#undef dbg
+#define dbg(f, arg...) \
+       if (hd29l2_debug) \
+               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#define HD29L2_XTAL 30400000 /* Hz */
+
+
+#define HD29L2_QAM4NR 0x00
+#define HD29L2_QAM4   0x01
+#define HD29L2_QAM16  0x02
+#define HD29L2_QAM32  0x03
+#define HD29L2_QAM64  0x04
+
+#define HD29L2_CODE_RATE_04 0x00
+#define HD29L2_CODE_RATE_06 0x08
+#define HD29L2_CODE_RATE_08 0x10
+
+#define HD29L2_PN945 0x00
+#define HD29L2_PN595 0x01
+#define HD29L2_PN420 0x02
+
+#define HD29L2_CARRIER_SINGLE 0x00
+#define HD29L2_CARRIER_MULTI  0x01
+
+#define HD29L2_INTERLEAVER_720 0x00
+#define HD29L2_INTERLEAVER_420 0x01
+
+struct reg_val {
+       u8 reg;
+       u8 val;
+};
+
+struct reg_mod_vals {
+       u8 reg;
+       u8 val[5];
+};
+
+struct hd29l2_priv {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct hd29l2_config cfg;
+       u8 tuner_i2c_addr_programmed:1;
+
+       fe_status_t fe_status;
+};
+
+static const struct reg_mod_vals reg_mod_vals_tab[] = {
+       /* REG, QAM4NR, QAM4,QAM16,QAM32,QAM64 */
+       { 0x01, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
+       { 0x02, { 0x07, 0x07, 0x07, 0x07, 0x07 } },
+       { 0x03, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
+       { 0x04, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x05, { 0x61, 0x60, 0x60, 0x61, 0x60 } },
+       { 0x06, { 0xff, 0xff, 0xff, 0xff, 0xff } },
+       { 0x07, { 0xff, 0xff, 0xff, 0xff, 0xff } },
+       { 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x09, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x0a, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
+       { 0x0d, { 0x78, 0x78, 0x88, 0x78, 0x78 } },
+       { 0x0e, { 0xa0, 0x90, 0xa0, 0xa0, 0xa0 } },
+       { 0x0f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x10, { 0xa0, 0xa0, 0x58, 0x38, 0x38 } },
+       { 0x11, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x12, { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a } },
+       { 0x13, { 0xa2, 0xa2, 0xa2, 0xa2, 0xa2 } },
+       { 0x17, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
+       { 0x18, { 0x21, 0x21, 0x42, 0x52, 0x42 } },
+       { 0x19, { 0x21, 0x21, 0x62, 0x72, 0x62 } },
+       { 0x1a, { 0x32, 0x43, 0xa9, 0xb9, 0xa9 } },
+       { 0x1b, { 0x32, 0x43, 0xb9, 0xd8, 0xb9 } },
+       { 0x1c, { 0x02, 0x02, 0x03, 0x02, 0x03 } },
+       { 0x1d, { 0x0c, 0x0c, 0x01, 0x02, 0x02 } },
+       { 0x1e, { 0x02, 0x02, 0x02, 0x01, 0x02 } },
+       { 0x1f, { 0x02, 0x02, 0x01, 0x02, 0x04 } },
+       { 0x20, { 0x01, 0x02, 0x01, 0x01, 0x01 } },
+       { 0x21, { 0x08, 0x08, 0x0a, 0x0a, 0x0a } },
+       { 0x22, { 0x06, 0x06, 0x04, 0x05, 0x05 } },
+       { 0x23, { 0x06, 0x06, 0x05, 0x03, 0x05 } },
+       { 0x24, { 0x08, 0x08, 0x05, 0x07, 0x07 } },
+       { 0x25, { 0x16, 0x10, 0x10, 0x0a, 0x10 } },
+       { 0x26, { 0x14, 0x14, 0x04, 0x04, 0x04 } },
+       { 0x27, { 0x58, 0x58, 0x58, 0x5c, 0x58 } },
+       { 0x28, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0x29, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0x2a, { 0x08, 0x0a, 0x08, 0x08, 0x08 } },
+       { 0x2b, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
+       { 0x2c, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
+       { 0x2d, { 0x05, 0x06, 0x06, 0x06, 0x06 } },
+       { 0x2e, { 0x21, 0x21, 0x21, 0x21, 0x21 } },
+       { 0x2f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x30, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
+       { 0x33, { 0xb7, 0xb7, 0xb7, 0xb7, 0xb7 } },
+       { 0x34, { 0x81, 0x81, 0x81, 0x81, 0x81 } },
+       { 0x35, { 0x80, 0x80, 0x80, 0x80, 0x80 } },
+       { 0x37, { 0x70, 0x70, 0x70, 0x70, 0x70 } },
+       { 0x38, { 0x04, 0x04, 0x02, 0x02, 0x02 } },
+       { 0x39, { 0x07, 0x07, 0x05, 0x05, 0x05 } },
+       { 0x3a, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
+       { 0x3b, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
+       { 0x3c, { 0x07, 0x06, 0x04, 0x04, 0x04 } },
+       { 0x3d, { 0xf0, 0xf0, 0xf0, 0xf0, 0x80 } },
+       { 0x3e, { 0x60, 0x60, 0x60, 0x60, 0xff } },
+       { 0x3f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x40, { 0x5b, 0x5b, 0x5b, 0x57, 0x50 } },
+       { 0x41, { 0x30, 0x30, 0x30, 0x30, 0x18 } },
+       { 0x42, { 0x20, 0x20, 0x20, 0x00, 0x30 } },
+       { 0x43, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x44, { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f } },
+       { 0x45, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x46, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0x47, { 0x00, 0x00, 0x95, 0x00, 0x95 } },
+       { 0x48, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
+       { 0x49, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
+       { 0x4a, { 0x40, 0x40, 0x33, 0x11, 0x11 } },
+       { 0x4b, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
+       { 0x4c, { 0x40, 0x40, 0x99, 0x11, 0x11 } },
+       { 0x4d, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
+       { 0x4e, { 0x40, 0x40, 0x66, 0x77, 0x77 } },
+       { 0x4f, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
+       { 0x50, { 0x40, 0x40, 0x88, 0x33, 0x11 } },
+       { 0x51, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
+       { 0x52, { 0x40, 0x40, 0x88, 0x02, 0x02 } },
+       { 0x53, { 0x40, 0x40, 0x00, 0x02, 0x02 } },
+       { 0x54, { 0x00, 0x00, 0x88, 0x33, 0x33 } },
+       { 0x55, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
+       { 0x56, { 0x00, 0x00, 0x00, 0x0b, 0x00 } },
+       { 0x57, { 0x40, 0x40, 0x0a, 0x0b, 0x0a } },
+       { 0x58, { 0xaa, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x59, { 0x7a, 0x40, 0x02, 0x02, 0x02 } },
+       { 0x5a, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
+       { 0x5b, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
+       { 0x5c, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
+       { 0x5d, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
+       { 0x5e, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
+       { 0x5f, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
+       { 0x60, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
+       { 0x61, { 0x40, 0x40, 0x10, 0x30, 0x30 } },
+       { 0x62, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
+       { 0x63, { 0x40, 0x40, 0x05, 0x30, 0x30 } },
+       { 0x64, { 0x40, 0x40, 0x06, 0x00, 0x30 } },
+       { 0x65, { 0x40, 0x40, 0x06, 0x08, 0x30 } },
+       { 0x66, { 0x40, 0x40, 0x00, 0x00, 0x20 } },
+       { 0x67, { 0x40, 0x40, 0x01, 0x04, 0x20 } },
+       { 0x68, { 0x00, 0x00, 0x30, 0x00, 0x20 } },
+       { 0x69, { 0xa0, 0xa0, 0x00, 0x08, 0x20 } },
+       { 0x6a, { 0x00, 0x00, 0x30, 0x00, 0x25 } },
+       { 0x6b, { 0xa0, 0xa0, 0x00, 0x06, 0x25 } },
+       { 0x6c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x6d, { 0xa0, 0x60, 0x0c, 0x03, 0x0c } },
+       { 0x6e, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x6f, { 0xa0, 0x60, 0x04, 0x01, 0x04 } },
+       { 0x70, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
+       { 0x71, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
+       { 0x72, { 0x58, 0x58, 0xff, 0xff, 0xff } },
+       { 0x73, { 0x58, 0x58, 0xff, 0xff, 0xff } },
+       { 0x74, { 0x06, 0x06, 0x09, 0x05, 0x05 } },
+       { 0x75, { 0x06, 0x06, 0x0a, 0x10, 0x10 } },
+       { 0x76, { 0x10, 0x10, 0x06, 0x0a, 0x0a } },
+       { 0x77, { 0x12, 0x18, 0x28, 0x10, 0x28 } },
+       { 0x78, { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8 } },
+       { 0x79, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
+       { 0x7a, { 0x02, 0x02, 0x01, 0x04, 0x03 } },
+       { 0x7b, { 0x01, 0x02, 0x03, 0x03, 0x03 } },
+       { 0x7c, { 0x28, 0x28, 0x28, 0x28, 0x28 } },
+       { 0x7f, { 0x25, 0x92, 0x5f, 0x17, 0x2d } },
+       { 0x80, { 0x64, 0x64, 0x64, 0x74, 0x64 } },
+       { 0x83, { 0x06, 0x03, 0x04, 0x04, 0x04 } },
+       { 0x84, { 0xff, 0xff, 0xff, 0xff, 0xff } },
+       { 0x85, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
+       { 0x86, { 0x00, 0x00, 0x11, 0x11, 0x11 } },
+       { 0x87, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
+       { 0x88, { 0x09, 0x09, 0x09, 0x09, 0x09 } },
+       { 0x89, { 0x20, 0x20, 0x30, 0x20, 0x20 } },
+       { 0x8a, { 0x03, 0x03, 0x02, 0x03, 0x02 } },
+       { 0x8b, { 0x00, 0x07, 0x09, 0x00, 0x09 } },
+       { 0x8c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x8d, { 0x4f, 0x4f, 0x4f, 0x3f, 0x4f } },
+       { 0x8e, { 0xf0, 0xf0, 0x60, 0xf0, 0xa0 } },
+       { 0x8f, { 0xe8, 0xe8, 0xe8, 0xe8, 0xe8 } },
+       { 0x90, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
+       { 0x91, { 0x40, 0x40, 0x70, 0x70, 0x10 } },
+       { 0x92, { 0x00, 0x00, 0x00, 0x00, 0x04 } },
+       { 0x93, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
+       { 0x94, { 0x00, 0x00, 0x00, 0x00, 0x03 } },
+       { 0x95, { 0x09, 0x09, 0x47, 0x47, 0x47 } },
+       { 0x96, { 0x80, 0xa0, 0xa0, 0x40, 0xa0 } },
+       { 0x97, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
+       { 0x98, { 0x50, 0x50, 0x50, 0x30, 0x50 } },
+       { 0x99, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
+       { 0x9a, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0x9b, { 0x40, 0x40, 0x40, 0x30, 0x40 } },
+       { 0x9c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa0, { 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 } },
+       { 0xa1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa2, { 0x30, 0x30, 0x00, 0x30, 0x00 } },
+       { 0xa3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa5, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xa8, { 0x77, 0x77, 0x77, 0x77, 0x77 } },
+       { 0xa9, { 0x02, 0x02, 0x02, 0x02, 0x02 } },
+       { 0xaa, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
+       { 0xac, { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f } },
+       { 0xad, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
+       { 0xae, { 0x78, 0x78, 0x78, 0x78, 0x78 } },
+       { 0xaf, { 0x06, 0x06, 0x06, 0x06, 0x07 } },
+       { 0xb0, { 0x1b, 0x1b, 0x1b, 0x19, 0x1b } },
+       { 0xb1, { 0x18, 0x17, 0x17, 0x18, 0x17 } },
+       { 0xb2, { 0x35, 0x82, 0x82, 0x38, 0x82 } },
+       { 0xb3, { 0xb6, 0xce, 0xc7, 0x5c, 0xb0 } },
+       { 0xb4, { 0x3f, 0x3e, 0x3e, 0x3f, 0x3e } },
+       { 0xb5, { 0x70, 0x58, 0x50, 0x68, 0x50 } },
+       { 0xb6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xb7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xb8, { 0x03, 0x03, 0x01, 0x01, 0x01 } },
+       { 0xb9, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xba, { 0x06, 0x06, 0x0a, 0x05, 0x0a } },
+       { 0xbb, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xbc, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xbd, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xbe, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xbf, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc3, { 0x00, 0x00, 0x88, 0x66, 0x88 } },
+       { 0xc4, { 0x10, 0x10, 0x00, 0x00, 0x00 } },
+       { 0xc5, { 0x00, 0x00, 0x44, 0x60, 0x44 } },
+       { 0xc6, { 0x10, 0x0a, 0x00, 0x00, 0x00 } },
+       { 0xc7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc8, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xc9, { 0x90, 0x04, 0x00, 0x00, 0x00 } },
+       { 0xca, { 0x90, 0x08, 0x01, 0x01, 0x01 } },
+       { 0xcb, { 0xa0, 0x04, 0x00, 0x44, 0x00 } },
+       { 0xcc, { 0xa0, 0x10, 0x03, 0x00, 0x03 } },
+       { 0xcd, { 0x06, 0x06, 0x06, 0x05, 0x06 } },
+       { 0xce, { 0x05, 0x05, 0x01, 0x01, 0x01 } },
+       { 0xcf, { 0x40, 0x20, 0x18, 0x18, 0x18 } },
+       { 0xd0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xd1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xd2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xd3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xd4, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
+       { 0xd5, { 0x05, 0x05, 0x05, 0x03, 0x05 } },
+       { 0xd6, { 0xac, 0x22, 0xca, 0x8f, 0xca } },
+       { 0xd7, { 0x20, 0x20, 0x20, 0x20, 0x20 } },
+       { 0xd8, { 0x01, 0x01, 0x01, 0x01, 0x01 } },
+       { 0xd9, { 0x00, 0x00, 0x0f, 0x00, 0x0f } },
+       { 0xda, { 0x00, 0xff, 0xff, 0x0e, 0xff } },
+       { 0xdb, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0xdc, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0xdd, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
+       { 0xde, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0xdf, { 0x42, 0x42, 0x44, 0x44, 0x04 } },
+       { 0xe0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xe1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xe2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xe3, { 0x00, 0x00, 0x26, 0x06, 0x26 } },
+       { 0xe4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xe5, { 0x01, 0x0a, 0x01, 0x01, 0x01 } },
+       { 0xe6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xe7, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
+       { 0xe8, { 0x63, 0x63, 0x63, 0x63, 0x63 } },
+       { 0xe9, { 0x59, 0x59, 0x59, 0x59, 0x59 } },
+       { 0xea, { 0x80, 0x80, 0x20, 0x80, 0x80 } },
+       { 0xeb, { 0x37, 0x37, 0x78, 0x37, 0x77 } },
+       { 0xec, { 0x1f, 0x1f, 0x25, 0x25, 0x25 } },
+       { 0xed, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
+       { 0xee, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+       { 0xef, { 0x70, 0x70, 0x58, 0x38, 0x58 } },
+       { 0xf0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
+};
+
+#endif /* HD29L2_PRIV */
diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c
new file mode 100644 (file)
index 0000000..33d33f4
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * isl6405.c - driver for dual lnb supply and control ic ISL6405
+ *
+ * Copyright (C) 2008 Hartmut Hackmann
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6405.h"
+
+struct isl6405 {
+       u8                      config;
+       u8                      override_or;
+       u8                      override_and;
+       struct i2c_adapter      *i2c;
+       u8                      i2c_addr;
+};
+
+static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = isl6405->i2c_addr, .flags = 0,
+                               .buf = &isl6405->config,
+                               .len = sizeof(isl6405->config) };
+
+       if (isl6405->override_or & 0x80) {
+               isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2);
+               switch (voltage) {
+               case SEC_VOLTAGE_OFF:
+                       break;
+               case SEC_VOLTAGE_13:
+                       isl6405->config |= ISL6405_EN2;
+                       break;
+               case SEC_VOLTAGE_18:
+                       isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1);
+               switch (voltage) {
+               case SEC_VOLTAGE_OFF:
+                       break;
+               case SEC_VOLTAGE_13:
+                       isl6405->config |= ISL6405_EN1;
+                       break;
+               case SEC_VOLTAGE_18:
+                       isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1);
+                       break;
+               default:
+                       return -EINVAL;
+               };
+       }
+       isl6405->config |= isl6405->override_or;
+       isl6405->config &= isl6405->override_and;
+
+       return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = isl6405->i2c_addr, .flags = 0,
+                               .buf = &isl6405->config,
+                               .len = sizeof(isl6405->config) };
+
+       if (isl6405->override_or & 0x80) {
+               if (arg)
+                       isl6405->config |= ISL6405_LLC2;
+               else
+                       isl6405->config &= ~ISL6405_LLC2;
+       } else {
+               if (arg)
+                       isl6405->config |= ISL6405_LLC1;
+               else
+                       isl6405->config &= ~ISL6405_LLC1;
+       }
+       isl6405->config |= isl6405->override_or;
+       isl6405->config &= isl6405->override_and;
+
+       return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void isl6405_release(struct dvb_frontend *fe)
+{
+       /* power off */
+       isl6405_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free */
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
+                                   u8 i2c_addr, u8 override_set, u8 override_clear)
+{
+       struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL);
+       if (!isl6405)
+               return NULL;
+
+       /* default configuration */
+       if (override_set & 0x80)
+               isl6405->config = ISL6405_ISEL2;
+       else
+               isl6405->config = ISL6405_ISEL1;
+       isl6405->i2c = i2c;
+       isl6405->i2c_addr = i2c_addr;
+       fe->sec_priv = isl6405;
+
+       /* bits which should be forced to '1' */
+       isl6405->override_or = override_set;
+
+       /* bits which should be forced to '0' */
+       isl6405->override_and = ~override_clear;
+
+       /* detect if it is present or not */
+       if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+               kfree(isl6405);
+               fe->sec_priv = NULL;
+               return NULL;
+       }
+
+       /* install release callback */
+       fe->ops.release_sec = isl6405_release;
+
+       /* override frontend ops */
+       fe->ops.set_voltage = isl6405_set_voltage;
+       fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage;
+
+       return fe;
+}
+EXPORT_SYMBOL(isl6405_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405");
+MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/isl6405.h b/drivers/media/dvb-frontends/isl6405.h
new file mode 100644 (file)
index 0000000..1c793d3
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * isl6405.h - driver for dual lnb supply and control ic ISL6405
+ *
+ * Copyright (C) 2008 Hartmut Hackmann
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _ISL6405_H
+#define _ISL6405_H
+
+#include <linux/dvb/frontend.h>
+
+/* system register bits */
+
+/* this bit selects register (control) 1 or 2
+   note that the bit maps are different */
+
+#define ISL6405_SR     0x80
+
+/* SR = 0 */
+#define ISL6405_OLF1   0x01
+#define ISL6405_EN1    0x02
+#define ISL6405_VSEL1  0x04
+#define ISL6405_LLC1   0x08
+#define ISL6405_ENT1   0x10
+#define ISL6405_ISEL1  0x20
+#define ISL6405_DCL    0x40
+
+/* SR = 1 */
+#define ISL6405_OLF2   0x01
+#define ISL6405_OTF    0x02
+#define ISL6405_EN2    0x04
+#define ISL6405_VSEL2  0x08
+#define ISL6405_LLC2   0x10
+#define ISL6405_ENT2   0x20
+#define ISL6405_ISEL2  0x40
+
+#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE))
+/* override_set and override_clear control which system register bits (above)
+ * to always set & clear
+ */
+extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
+                                          u8 i2c_addr, u8 override_set, u8 override_clear);
+#else
+static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe,
+                                                 struct i2c_adapter *i2c, u8 i2c_addr,
+                                                 u8 override_set, u8 override_clear)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_ISL6405 */
+
+#endif
diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c
new file mode 100644 (file)
index 0000000..684c8ec
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * isl6421.h - driver for lnb supply and control ic ISL6421
+ *
+ * Copyright (C) 2006 Andrew de Quincey
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6421.h"
+
+struct isl6421 {
+       u8                      config;
+       u8                      override_or;
+       u8                      override_and;
+       struct i2c_adapter      *i2c;
+       u8                      i2c_addr;
+};
+
+static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = isl6421->i2c_addr, .flags = 0,
+                               .buf = &isl6421->config,
+                               .len = sizeof(isl6421->config) };
+
+       isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
+
+       switch(voltage) {
+       case SEC_VOLTAGE_OFF:
+               break;
+       case SEC_VOLTAGE_13:
+               isl6421->config |= ISL6421_EN1;
+               break;
+       case SEC_VOLTAGE_18:
+               isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       isl6421->config |= isl6421->override_or;
+       isl6421->config &= isl6421->override_and;
+
+       return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = isl6421->i2c_addr, .flags = 0,
+                               .buf = &isl6421->config,
+                               .len = sizeof(isl6421->config) };
+
+       if (arg)
+               isl6421->config |= ISL6421_LLC1;
+       else
+               isl6421->config &= ~ISL6421_LLC1;
+
+       isl6421->config |= isl6421->override_or;
+       isl6421->config &= isl6421->override_and;
+
+       return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void isl6421_release(struct dvb_frontend *fe)
+{
+       /* power off */
+       isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free */
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+                  u8 override_set, u8 override_clear)
+{
+       struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
+       if (!isl6421)
+               return NULL;
+
+       /* default configuration */
+       isl6421->config = ISL6421_ISEL1;
+       isl6421->i2c = i2c;
+       isl6421->i2c_addr = i2c_addr;
+       fe->sec_priv = isl6421;
+
+       /* bits which should be forced to '1' */
+       isl6421->override_or = override_set;
+
+       /* bits which should be forced to '0' */
+       isl6421->override_and = ~override_clear;
+
+       /* detect if it is present or not */
+       if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+               kfree(isl6421);
+               fe->sec_priv = NULL;
+               return NULL;
+       }
+
+       /* install release callback */
+       fe->ops.release_sec = isl6421_release;
+
+       /* override frontend ops */
+       fe->ops.set_voltage = isl6421_set_voltage;
+       fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
+
+       return fe;
+}
+EXPORT_SYMBOL(isl6421_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
+MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/isl6421.h b/drivers/media/dvb-frontends/isl6421.h
new file mode 100644 (file)
index 0000000..47e4518
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * isl6421.h - driver for lnb supply and control ic ISL6421
+ *
+ * Copyright (C) 2006 Andrew de Quincey
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _ISL6421_H
+#define _ISL6421_H
+
+#include <linux/dvb/frontend.h>
+
+/* system register bits */
+#define ISL6421_OLF1   0x01
+#define ISL6421_EN1    0x02
+#define ISL6421_VSEL1  0x04
+#define ISL6421_LLC1   0x08
+#define ISL6421_ENT1   0x10
+#define ISL6421_ISEL1  0x20
+#define ISL6421_DCL    0x40
+
+#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE))
+/* override_set and override_clear control which system register bits (above) to always set & clear */
+extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+                         u8 override_set, u8 override_clear);
+#else
+static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+                                                 u8 override_set, u8 override_clear)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_ISL6421
+
+#endif
diff --git a/drivers/media/dvb-frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c
new file mode 100644 (file)
index 0000000..dca5beb
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+       Intersil ISL6423 SEC and LNB Power supply controller
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6423.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+#define FE_ERROR                               0
+#define FE_NOTICE                              1
+#define FE_INFO                                        2
+#define FE_DEBUG                               3
+#define FE_DEBUGREG                            4
+
+#define dprintk(__y, __z, format, arg...) do {                                         \
+       if (__z) {                                                                      \
+               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
+               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((verbose > FE_INFO) && (verbose > __y))                        \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
+               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (verbose > __y)                                                      \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while (0)
+
+struct isl6423_dev {
+       const struct isl6423_config     *config;
+       struct i2c_adapter              *i2c;
+
+       u8 reg_3;
+       u8 reg_4;
+
+       unsigned int verbose;
+};
+
+static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
+{
+       struct i2c_adapter *i2c = isl6423->i2c;
+       u8 addr                 = isl6423->config->addr;
+       int err = 0;
+
+       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
+
+       dprintk(FE_DEBUG, 1, "write reg %02X", reg);
+       err = i2c_transfer(i2c, &msg, 1);
+       if (err < 0)
+               goto exit;
+       return 0;
+
+exit:
+       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+       return err;
+}
+
+static int isl6423_set_modulation(struct dvb_frontend *fe)
+{
+       struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
+       const struct isl6423_config *config     = isl6423->config;
+       int err = 0;
+       u8 reg_2 = 0;
+
+       reg_2 = 0x01 << 5;
+
+       if (config->mod_extern)
+               reg_2 |= (1 << 3);
+       else
+               reg_2 |= (1 << 4);
+
+       err = isl6423_write(isl6423, reg_2);
+       if (err < 0)
+               goto exit;
+       return 0;
+
+exit:
+       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+       return err;
+}
+
+static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
+{
+       struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+       u8 reg_3 = isl6423->reg_3;
+       u8 reg_4 = isl6423->reg_4;
+       int err = 0;
+
+       if (arg) {
+               /* EN = 1, VSPEN = 1, VBOT = 1 */
+               reg_4 |= (1 << 4);
+               reg_4 |= 0x1;
+               reg_3 |= (1 << 3);
+       } else {
+               /* EN = 1, VSPEN = 1, VBOT = 0 */
+               reg_4 |= (1 << 4);
+               reg_4 &= ~0x1;
+               reg_3 |= (1 << 3);
+       }
+       err = isl6423_write(isl6423, reg_3);
+       if (err < 0)
+               goto exit;
+
+       err = isl6423_write(isl6423, reg_4);
+       if (err < 0)
+               goto exit;
+
+       isl6423->reg_3 = reg_3;
+       isl6423->reg_4 = reg_4;
+
+       return 0;
+exit:
+       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+       return err;
+}
+
+
+static int isl6423_set_voltage(struct dvb_frontend *fe,
+                              enum fe_sec_voltage voltage)
+{
+       struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
+       u8 reg_3 = isl6423->reg_3;
+       u8 reg_4 = isl6423->reg_4;
+       int err = 0;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_OFF:
+               /* EN = 0 */
+               reg_4 &= ~(1 << 4);
+               break;
+
+       case SEC_VOLTAGE_13:
+               /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
+               reg_4 |= (1 << 4);
+               reg_4 &= ~0x3;
+               reg_3 |= (1 << 3);
+               break;
+
+       case SEC_VOLTAGE_18:
+               /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
+               reg_4 |= (1 << 4);
+               reg_4 |=  0x2;
+               reg_4 &= ~0x1;
+               reg_3 |= (1 << 3);
+               break;
+
+       default:
+               break;
+       }
+       err = isl6423_write(isl6423, reg_3);
+       if (err < 0)
+               goto exit;
+
+       err = isl6423_write(isl6423, reg_4);
+       if (err < 0)
+               goto exit;
+
+       isl6423->reg_3 = reg_3;
+       isl6423->reg_4 = reg_4;
+
+       return 0;
+exit:
+       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+       return err;
+}
+
+static int isl6423_set_current(struct dvb_frontend *fe)
+{
+       struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
+       u8 reg_3 = isl6423->reg_3;
+       const struct isl6423_config *config     = isl6423->config;
+       int err = 0;
+
+       switch (config->current_max) {
+       case SEC_CURRENT_275m:
+               /* 275mA */
+               /* ISELH = 0, ISELL = 0 */
+               reg_3 &= ~0x3;
+               break;
+
+       case SEC_CURRENT_515m:
+               /* 515mA */
+               /* ISELH = 0, ISELL = 1 */
+               reg_3 &= ~0x2;
+               reg_3 |=  0x1;
+               break;
+
+       case SEC_CURRENT_635m:
+               /* 635mA */
+               /* ISELH = 1, ISELL = 0 */
+               reg_3 &= ~0x1;
+               reg_3 |=  0x2;
+               break;
+
+       case SEC_CURRENT_800m:
+               /* 800mA */
+               /* ISELH = 1, ISELL = 1 */
+               reg_3 |= 0x3;
+               break;
+       }
+
+       err = isl6423_write(isl6423, reg_3);
+       if (err < 0)
+               goto exit;
+
+       switch (config->curlim) {
+       case SEC_CURRENT_LIM_ON:
+               /* DCL = 0 */
+               reg_3 &= ~0x10;
+               break;
+
+       case SEC_CURRENT_LIM_OFF:
+               /* DCL = 1 */
+               reg_3 |= 0x10;
+               break;
+       }
+
+       err = isl6423_write(isl6423, reg_3);
+       if (err < 0)
+               goto exit;
+
+       isl6423->reg_3 = reg_3;
+
+       return 0;
+exit:
+       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
+       return err;
+}
+
+static void isl6423_release(struct dvb_frontend *fe)
+{
+       isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   const struct isl6423_config *config)
+{
+       struct isl6423_dev *isl6423;
+
+       isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
+       if (!isl6423)
+               return NULL;
+
+       isl6423->config = config;
+       isl6423->i2c    = i2c;
+       fe->sec_priv    = isl6423;
+
+       /* SR3H = 0, SR3M = 1, SR3L = 0 */
+       isl6423->reg_3 = 0x02 << 5;
+       /* SR4H = 0, SR4M = 1, SR4L = 1 */
+       isl6423->reg_4 = 0x03 << 5;
+
+       if (isl6423_set_current(fe))
+               goto exit;
+
+       if (isl6423_set_modulation(fe))
+               goto exit;
+
+       fe->ops.release_sec             = isl6423_release;
+       fe->ops.set_voltage             = isl6423_set_voltage;
+       fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
+       isl6423->verbose                = verbose;
+
+       return fe;
+
+exit:
+       kfree(isl6423);
+       fe->sec_priv = NULL;
+       return NULL;
+}
+EXPORT_SYMBOL(isl6423_attach);
+
+MODULE_DESCRIPTION("ISL6423 SEC");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/isl6423.h b/drivers/media/dvb-frontends/isl6423.h
new file mode 100644 (file)
index 0000000..e1a37fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+       Intersil ISL6423 SEC and LNB Power supply controller
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ISL_6423_H
+#define __ISL_6423_H
+
+#include <linux/dvb/frontend.h>
+
+enum isl6423_current {
+       SEC_CURRENT_275m = 0,
+       SEC_CURRENT_515m,
+       SEC_CURRENT_635m,
+       SEC_CURRENT_800m,
+};
+
+enum isl6423_curlim {
+       SEC_CURRENT_LIM_ON = 1,
+       SEC_CURRENT_LIM_OFF
+};
+
+struct isl6423_config {
+       enum isl6423_current current_max;
+       enum isl6423_curlim curlim;
+       u8 addr;
+       u8 mod_extern;
+};
+
+#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE))
+
+
+extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter *i2c,
+                                          const struct isl6423_config *config);
+
+#else
+static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
+                                                 struct i2c_adapter *i2c,
+                                                 const struct isl6423_config *config)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif /* CONFIG_DVB_ISL6423 */
+
+#endif /* __ISL_6423_H */
diff --git a/drivers/media/dvb-frontends/it913x-fe-priv.h b/drivers/media/dvb-frontends/it913x-fe-priv.h
new file mode 100644 (file)
index 0000000..eb6fd8a
--- /dev/null
@@ -0,0 +1,1051 @@
+
+struct it913xset {     u32 pro;
+                       u32 address;
+                       u8 reg[15];
+                       u8 count;
+};
+
+struct adctable {      u32 adcFrequency;
+                       u32 bandwidth;
+                       u32 coeff_1_2048;
+                       u32 coeff_1_4096;
+                       u32 coeff_1_8191;
+                       u32 coeff_1_8192;
+                       u32 coeff_1_8193;
+                       u32 coeff_2_2k;
+                       u32 coeff_2_4k;
+                       u32 coeff_2_8k;
+                       u16 bfsfcw_fftinx_ratio;
+                       u16 fftinx_bfsfcw_ratio;
+};
+
+/* clock and coeff tables only table 3 is used with IT9137*/
+/* TODO other tables relate AF9035 may be removed */
+static struct adctable tab1[] = {
+       {       20156250, 6000000,
+               0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b, 0x00ae292a,
+               0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c      },
+       {       20156250, 7000000,
+               0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660, 0x00cb3007,
+               0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196      },
+       {       20156250, 8000000,
+               0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25, 0x00e836e3,
+               0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0      },
+       {       20156250, 5000000,
+               0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7, 0x0091224e,
+               0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122      }
+};
+
+static struct adctable tab2[] = {
+       {       20187500, 6000000,
+               0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995, 0x00ade426,
+               0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c      },
+       {       20187500, 7000000,
+               0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8, 0x00cadf81,
+               0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196      },
+       {       20187500, 8000000,
+               0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c, 0x00e7dadd,
+               0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0      },
+       {       20187500, 5000000,
+               0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51, 0x0090e8ca,
+               0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122      }
+
+};
+
+static struct adctable tab3[] = {
+       {       20250000, 6000000,
+               0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b, 0x00ad5ac1,
+               0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b      },
+       {       20250000, 7000000,
+               0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588, 0x00ca3f36,
+               0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195      },
+       {       20250000, 8000000,
+               0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4, 0x00e723ab,
+               0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce      },
+       {       20250000, 5000000,
+               0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf, 0x0090764b,
+               0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121      }
+
+};
+
+static struct adctable tab4[] = {
+       {       20583333, 6000000,
+               0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166, 0x00aa8c12,
+               0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155      },
+       {       20583333, 7000000,
+               0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7, 0x00c6f8bf,
+               0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e      },
+       {       20583333, 8000000,
+               0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88, 0x00e3656d,
+               0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7      },
+       {       20583333, 5000000,
+               0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5, 0x008e1f64,
+               0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c      }
+
+};
+
+static struct adctable tab5[] = {
+       {       20416667, 6000000,
+               0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9, 0x00abf07a,
+               0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158      },
+       {       20416667, 7000000,
+               0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3, 0x00c8988e,
+               0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191      },
+       {       20416667, 8000000,
+               0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc, 0x00e540a2,
+               0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb      },
+       {       20416667, 5000000,
+               0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0, 0x008f4865,
+               0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f      }
+
+};
+
+static struct adctable tab6[] = {
+       {       20480000, 6000000,
+               0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7, 0x00ab685c,
+               0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157      },
+       {       20480000, 7000000,
+               0x03200000, 0x01900000, 0x00c80640, 0x00c80000, 0x00c7f9c0,
+               0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190      },
+       {       20480000, 8000000,
+               0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249, 0x00e48b25,
+               0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9      },
+       {       20480000, 5000000,
+               0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e, 0x008ed6f7,
+               0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e      }
+};
+
+static struct adctable tab7[] = {
+       {       20500000, 6000000,
+               0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6, 0x00ab3d8c,
+               0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157      },
+       {       20500000, 7000000,
+               0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c, 0x00c7c7ce,
+               0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190      },
+       {       20500000, 8000000,
+               0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933, 0x00e45210,
+               0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9      },
+       {       20500000, 5000000,
+               0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0, 0x008eb34a,
+               0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d      }
+
+};
+
+static struct adctable tab8[] = {
+       {       20625000, 6000000,
+               0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f, 0x00aa33de,
+               0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154      },
+       {       20625000, 7000000,
+               0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c, 0x00c691d8,
+               0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d      },
+       {       20625000, 8000000,
+               0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea, 0x00e2efd2,
+               0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6      },
+       {       20625000, 5000000,
+               0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52, 0x008dd5e3,
+               0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c      }
+
+};
+
+struct table {
+               u32 xtal;
+               struct adctable *table;
+};
+
+static struct table fe_clockTable[] = {
+               {12000000, tab3},       /* 12.00MHz */
+               {20480000, tab6},       /* 20.48MHz */
+               {36000000, tab3},       /* 36.00MHz */
+               {30000000, tab1},       /* 30.00MHz */
+               {26000000, tab4},       /* 26.00MHz */
+               {28000000, tab5},       /* 28.00MHz */
+               {32000000, tab7},       /* 32.00MHz */
+               {34000000, tab2},       /* 34.00MHz */
+               {24000000, tab1},       /* 24.00MHz */
+               {22000000, tab8},       /* 22.00MHz */
+};
+
+/* fe get */
+fe_code_rate_t fe_code[] = {
+       FEC_1_2,
+       FEC_2_3,
+       FEC_3_4,
+       FEC_5_6,
+       FEC_7_8,
+       FEC_NONE,
+};
+
+fe_guard_interval_t fe_gi[] = {
+       GUARD_INTERVAL_1_32,
+       GUARD_INTERVAL_1_16,
+       GUARD_INTERVAL_1_8,
+       GUARD_INTERVAL_1_4,
+};
+
+fe_hierarchy_t fe_hi[] = {
+       HIERARCHY_NONE,
+       HIERARCHY_1,
+       HIERARCHY_2,
+       HIERARCHY_4,
+};
+
+fe_transmit_mode_t fe_mode[] = {
+       TRANSMISSION_MODE_2K,
+       TRANSMISSION_MODE_8K,
+       TRANSMISSION_MODE_4K,
+};
+
+fe_modulation_t fe_con[] = {
+       QPSK,
+       QAM_16,
+       QAM_64,
+};
+
+enum {
+       PRIORITY_HIGH = 0,      /* High-priority stream */
+       PRIORITY_LOW,   /* Low-priority stream */
+};
+
+/* Standard demodulator functions */
+static struct it913xset set_solo_fe[] = {
+       {PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
+       {PRO_LINK, GPIOH5_ON, {0x01}, 0x01},
+       {PRO_LINK, GPIOH5_O, {0x00}, 0x01},
+       {PRO_LINK, GPIOH5_O, {0x01}, 0x01},
+       {PRO_LINK, DVBT_INTEN, {0x04}, 0x01},
+       {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01},
+       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
+       {PRO_LINK, HOSTB_MPEG_SER_MODE, {0x00}, 0x01},
+       {PRO_LINK, HOSTB_MPEG_PAR_MODE, {0x00}, 0x01},
+       {PRO_DMOD, DCA_UPPER_CHIP, {0x00}, 0x01},
+       {PRO_LINK, HOSTB_DCA_UPPER, {0x00}, 0x01},
+       {PRO_DMOD, DCA_LOWER_CHIP, {0x00}, 0x01},
+       {PRO_LINK, HOSTB_DCA_LOWER, {0x00}, 0x01},
+       {PRO_DMOD, DCA_PLATCH, {0x00}, 0x01},
+       {PRO_DMOD, DCA_FPGA_LATCH, {0x00}, 0x01},
+       {PRO_DMOD, DCA_STAND_ALONE, {0x01}, 0x01},
+       {PRO_DMOD, DCA_ENABLE, {0x00}, 0x01},
+       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
+       {PRO_DMOD, BFS_FCW, {0x00, 0x00, 0x00}, 0x03},
+       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+};
+
+
+static struct it913xset init_1[] = {
+       {PRO_LINK, LOCK3_OUT, {0x01}, 0x01},
+       {PRO_LINK, PADMISCDRSR, {0x01}, 0x01},
+       {PRO_LINK, PADMISCDR2, {0x00}, 0x01},
+       {PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02},
+       {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */
+       {PRO_LINK, PADMISCDR8, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+
+/* Version 1 types */
+static struct it913xset it9135_v1[] = {
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
+       {PRO_DMOD, 0x007e, {0x04}, 0x01},
+       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
+       {PRO_DMOD, 0x008a, {0x01}, 0x01},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06}, 0x01},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
+       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
+       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
+       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
+       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf016, {0x10}, 0x01},
+       {PRO_DMOD, 0xf017, {0x04}, 0x01},
+       {PRO_DMOD, 0xf018, {0x05}, 0x01},
+       {PRO_DMOD, 0xf019, {0x04}, 0x01},
+       {PRO_DMOD, 0xf01a, {0x05}, 0x01},
+       {PRO_DMOD, 0xf021, {0x03}, 0x01},
+       {PRO_DMOD, 0xf022, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf023, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
+       {PRO_DMOD, 0xf02c, {0x01}, 0x01},
+       {PRO_DMOD, 0xf064, {0x03}, 0x01},
+       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
+       {PRO_DMOD, 0xf066, {0x03}, 0x01},
+       {PRO_DMOD, 0xf067, {0x01}, 0x01},
+       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
+       {PRO_DMOD, 0xf070, {0x03}, 0x01},
+       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf073, {0x03}, 0x01},
+       {PRO_DMOD, 0xf078, {0x00}, 0x01},
+       {PRO_DMOD, 0xf087, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
+       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
+       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
+       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
+       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
+       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01}, 0x01},
+       {PRO_DMOD, 0xf167, {0x40}, 0x01},
+       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
+       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
+       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
+       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
+       {PRO_DMOD, 0xf410, {0x08}, 0x01},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15}, 0x01},
+       {PRO_DMOD, 0xf562, {0x20}, 0x01},
+       {PRO_DMOD, 0xf5df, {0xfb}, 0x01},
+       {PRO_DMOD, 0xf5e0, {0x00}, 0x01},
+       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
+       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+       {PRO_DMOD, 0xf600, {0x05}, 0x01},
+       {PRO_DMOD, 0xf601, {0x08}, 0x01},
+       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
+       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
+       {PRO_DMOD, 0xf604, {0x11}, 0x01},
+       {PRO_DMOD, 0xf605, {0x14}, 0x01},
+       {PRO_DMOD, 0xf606, {0x17}, 0x01},
+       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
+       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
+       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf610, {0x32}, 0x01},
+       {PRO_DMOD, 0xf611, {0x10}, 0x01},
+       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
+       {PRO_DMOD, 0xf708, {0x00}, 0x01},
+       {PRO_DMOD, 0xf709, {0x37}, 0x01},
+       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
+       {PRO_DMOD, 0xf810, {0x54}, 0x01},
+       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_38[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x38}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
+       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8,
+                               0xd0, 0xc3, 0x01}, 0x0a},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x32}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
+       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
+       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77,
+                               0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+       {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04},
+       {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03},
+       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
+       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
+       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+                               0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_51[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x51}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
+       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96,
+                               0xcf, 0xc3, 0x01}, 0x0a},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
+       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
+       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77,
+                               0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+       {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04},
+       {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03},
+       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
+       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
+       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+                               0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_52[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x52}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x10}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
+       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97,
+                               0xc0, 0x9e, 0x01}, 0x0a},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
+       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
+       {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77,
+                               0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+       {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04},
+       {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03},
+       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
+       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+       {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05},
+       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+                               0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+/* Version 2 types */
+static struct it913xset it9135_v2[] = {
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
+       {PRO_DMOD, 0x007e, {0x04}, 0x01},
+       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
+       {PRO_DMOD, 0x008a, {0x01}, 0x01},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06}, 0x01},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
+       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
+       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
+       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
+       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
+       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
+       {PRO_DMOD, 0xf064, {0x03}, 0x01},
+       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
+       {PRO_DMOD, 0xf066, {0x03}, 0x01},
+       {PRO_DMOD, 0xf067, {0x01}, 0x01},
+       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
+       {PRO_DMOD, 0xf070, {0x03}, 0x01},
+       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf073, {0x03}, 0x01},
+       {PRO_DMOD, 0xf078, {0x00}, 0x01},
+       {PRO_DMOD, 0xf087, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
+       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
+       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
+       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
+       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
+       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01}, 0x01},
+       {PRO_DMOD, 0xf167, {0x40}, 0x01},
+       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
+       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
+       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
+       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
+       {PRO_DMOD, 0xf410, {0x08}, 0x01},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15}, 0x01},
+       {PRO_DMOD, 0xf562, {0x20}, 0x01},
+       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
+       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
+       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
+       {PRO_DMOD, 0xf600, {0x05}, 0x01},
+       {PRO_DMOD, 0xf601, {0x08}, 0x01},
+       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
+       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
+       {PRO_DMOD, 0xf604, {0x11}, 0x01},
+       {PRO_DMOD, 0xf605, {0x14}, 0x01},
+       {PRO_DMOD, 0xf606, {0x17}, 0x01},
+       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
+       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
+       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf610, {0x32}, 0x01},
+       {PRO_DMOD, 0xf611, {0x10}, 0x01},
+       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
+       {PRO_DMOD, 0xf708, {0x00}, 0x01},
+       {PRO_DMOD, 0xf709, {0x37}, 0x01},
+       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
+       {PRO_DMOD, 0xf810, {0x54}, 0x01},
+       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_60[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x60}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
+       {PRO_DMOD, 0x006a, {0x03}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04}, 0x01},
+       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c,
+                               0x00, 0x02, 0xbe, 0x00}, 0x0b},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+       {PRO_DMOD, 0x011a, {0xbe}, 0x01},
+       {PRO_DMOD, 0x0124, {0xae}, 0x01},
+       {PRO_DMOD, 0x0127, {0x00}, 0x01},
+       {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04},
+       {PRO_DMOD, 0x0137, {0x00}, 0x01},
+       {PRO_DMOD, 0x013b, {0x08}, 0x01},
+       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
+       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c,
+                               0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6,
+                               0x33}, 0x0f},
+       {PRO_DMOD, 0x0151, {0x28}, 0x01},
+       {PRO_DMOD, 0x0153, {0xbc}, 0x01},
+       {PRO_DMOD, 0x0178, {0x09}, 0x01},
+       {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02},
+       {PRO_DMOD, 0x0185, {0x24}, 0x01},
+       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05},
+       {PRO_DMOD, 0xed02, {0xff}, 0x01},
+       {PRO_DMOD, 0xee42, {0xff}, 0x01},
+       {PRO_DMOD, 0xee82, {0xff}, 0x01},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf087, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17
+               , 0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_61[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x61}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x06}, 0x01},
+       {PRO_DMOD, 0x006a, {0x03}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04}, 0x01},
+       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c,
+                               0x01, 0x02, 0xc8, 0x00}, 0x0b},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+       {PRO_DMOD, 0x011a, {0xc6}, 0x01},
+       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
+       {PRO_DMOD, 0x0127, {0x00}, 0x01},
+       {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04},
+       {PRO_DMOD, 0x0137, {0x00}, 0x01},
+       {PRO_DMOD, 0x013b, {0x05}, 0x01},
+       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
+       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c,
+                               0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6,
+                               0x33}, 0x0f},
+       {PRO_DMOD, 0x0151, {0x28}, 0x01},
+       {PRO_DMOD, 0x0153, {0xcc}, 0x01},
+       {PRO_DMOD, 0x0178, {0x09}, 0x01},
+       {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02},
+       {PRO_DMOD, 0x0185, {0x28}, 0x01},
+       {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05},
+       {PRO_DMOD, 0xed02, {0xff}, 0x01},
+       {PRO_DMOD, 0xee42, {0xff}, 0x01},
+       {PRO_DMOD, 0xee82, {0xff}, 0x01},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf087, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+                               0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_62[] = {
+       {PRO_DMOD, 0x0043, {0x00}, 0x01},
+       {PRO_DMOD, 0x0046, {0x62}, 0x01},
+       {PRO_DMOD, 0x0051, {0x01}, 0x01},
+       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
+       {PRO_DMOD, 0x006a, {0x03}, 0x01},
+       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
+       {PRO_DMOD, 0x007e, {0x04}, 0x01},
+       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+       {PRO_DMOD, 0x0084, {    0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01},
+                               0x07},
+       {PRO_DMOD, 0x008e, {0x01}, 0x01},
+       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+       {PRO_DMOD, 0x0099, {0x01}, 0x01},
+       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
+       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
+       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
+       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+       {PRO_DMOD, 0x00fc, {    0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c,
+                               0x02, 0x02, 0xc2, 0x00}, 0x0b},
+       {PRO_DMOD, 0x0109, {0x02}, 0x01},
+       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+       {PRO_DMOD, 0x011a, {0xb8}, 0x01},
+       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
+       {PRO_DMOD, 0x0127, {0x00}, 0x01},
+       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+       {PRO_DMOD, 0x0137, {0x00}, 0x01},
+       {PRO_DMOD, 0x013b, {0x05}, 0x01},
+       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
+       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c,
+                               0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0,
+                               0x33}, 0x0f},
+       {PRO_DMOD, 0x0151, {0x28}, 0x01},
+       {PRO_DMOD, 0x0153, {0xb2}, 0x01},
+       {PRO_DMOD, 0x0178, {0x09}, 0x01},
+       {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02},
+       {PRO_DMOD, 0x0185, {0x24}, 0x01},
+       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05},
+       {PRO_DMOD, 0xed02, {0xff}, 0x01},
+       {PRO_DMOD, 0xee42, {0xff}, 0x01},
+       {PRO_DMOD, 0xee82, {0xff}, 0x01},
+       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
+       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+       {PRO_DMOD, 0xf087, {0x00}, 0x01},
+       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+       {PRO_DMOD, 0xf130, {0x04}, 0x01},
+       {PRO_DMOD, 0xf132, {0x04}, 0x01},
+       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
+       {PRO_DMOD, 0xf146, {0x00}, 0x01},
+       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
+       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
+       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
+       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+       {PRO_DMOD, 0xf163, {0x05}, 0x01},
+       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+       {PRO_DMOD, 0xf183, {0x01}, 0x01},
+       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
+       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+       {PRO_DMOD, 0xf204, {0x10}, 0x01},
+       {PRO_DMOD, 0xf214, {0x00}, 0x01},
+       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+                               0x1f}, 0x08},
+       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
+       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+       {PRO_DMOD, 0xf905, {0x01}, 0x01},
+       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
+       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+/* Tuner setting scripts (still keeping it9137) */
+static struct it913xset it9137_tuner_off[] = {
+       {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off  */
+       {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */
+       {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04},
+       {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                               0x00, 0x00, 0x00, 0x00}, 0x0c},
+       {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04},
+       {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                               0x00}, 0x09},
+       {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                               0x00, 0x00}, 0x0a},
+       {PRO_DMOD, 0xec20, {0x00}, 0x01},
+       {PRO_DMOD, 0xec3f, {0x01}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+};
+
+static struct it913xset set_it9135_template[] = {
+       {PRO_DMOD, 0xee06, {0x00}, 0x01},
+       {PRO_DMOD, 0xec56, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
+       {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */
+       {PRO_DMOD, 0x011f, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+};
+
+static struct it913xset set_it9137_template[] = {
+       {PRO_DMOD, 0xee06, {0x00}, 0x01},
+       {PRO_DMOD, 0xec56, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
+       {PRO_DMOD, 0xec4f, {0x00}, 0x01},
+       {PRO_DMOD, 0xec50, {0x00}, 0x01},
+       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+};
diff --git a/drivers/media/dvb-frontends/it913x-fe.c b/drivers/media/dvb-frontends/it913x-fe.c
new file mode 100644 (file)
index 0000000..708cbf1
--- /dev/null
@@ -0,0 +1,1045 @@
+/*
+ *  Driver for it913x-fe Frontend
+ *
+ *  with support for on chip it9137 integral tuner
+ *
+ *  Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
+ *  IT9137 Copyright (C) ITE Tech Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "dvb_frontend.h"
+#include "it913x-fe.h"
+#include "it913x-fe-priv.h"
+
+static int it913x_debug;
+
+module_param_named(debug, it913x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define dprintk(level, args...) do { \
+       if (level & it913x_debug) \
+               printk(KERN_DEBUG "it913x-fe: " args); \
+} while (0)
+
+#define deb_info(args...)  dprintk(0x01, args)
+#define debug_data_snipet(level, name, p) \
+         dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
+               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
+                       *(p+5), *(p+6), *(p+7));
+#define info(format, arg...) \
+       printk(KERN_INFO "it913x-fe: " format "\n" , ## arg)
+
+struct it913x_fe_state {
+       struct dvb_frontend frontend;
+       struct i2c_adapter *i2c_adap;
+       struct ite_config *config;
+       u8 i2c_addr;
+       u32 frequency;
+       fe_modulation_t constellation;
+       fe_transmit_mode_t transmission_mode;
+       u8 priority;
+       u32 crystalFrequency;
+       u32 adcFrequency;
+       u8 tuner_type;
+       struct adctable *table;
+       fe_status_t it913x_status;
+       u16 tun_xtal;
+       u8 tun_fdiv;
+       u8 tun_clk_mode;
+       u32 tun_fn_min;
+       u32 ucblocks;
+};
+
+static int it913x_read_reg(struct it913x_fe_state *state,
+               u32 reg, u8 *data, u8 count)
+{
+       int ret;
+       u8 pro = PRO_DMOD; /* All reads from demodulator */
+       u8 b[4];
+       struct i2c_msg msg[2] = {
+               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
+                       .buf = b, .len = sizeof(b) },
+               { .addr = state->i2c_addr + (pro << 1), .flags = I2C_M_RD,
+                       .buf = data, .len = count }
+       };
+       b[0] = (u8) reg >> 24;
+       b[1] = (u8)(reg >> 16) & 0xff;
+       b[2] = (u8)(reg >> 8) & 0xff;
+       b[3] = (u8) reg & 0xff;
+
+       ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+       return ret;
+}
+
+static int it913x_read_reg_u8(struct it913x_fe_state *state, u32 reg)
+{
+       int ret;
+       u8 b[1];
+       ret = it913x_read_reg(state, reg, &b[0], sizeof(b));
+       return (ret < 0) ? -ENODEV : b[0];
+}
+
+static int it913x_write(struct it913x_fe_state *state,
+               u8 pro, u32 reg, u8 buf[], u8 count)
+{
+       u8 b[256];
+       struct i2c_msg msg[1] = {
+               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
+                 .buf = b, .len = count + 4 }
+       };
+       int ret;
+
+       b[0] = (u8) reg >> 24;
+       b[1] = (u8)(reg >> 16) & 0xff;
+       b[2] = (u8)(reg >> 8) & 0xff;
+       b[3] = (u8) reg & 0xff;
+       memcpy(&b[4], buf, count);
+
+       ret = i2c_transfer(state->i2c_adap, msg, 1);
+
+       if (ret < 0)
+               return -EIO;
+
+       return 0;
+}
+
+static int it913x_write_reg(struct it913x_fe_state *state,
+               u8 pro, u32 reg, u32 data)
+{
+       int ret;
+       u8 b[4];
+       u8 s;
+
+       b[0] = data >> 24;
+       b[1] = (data >> 16) & 0xff;
+       b[2] = (data >> 8) & 0xff;
+       b[3] = data & 0xff;
+       /* expand write as needed */
+       if (data < 0x100)
+               s = 3;
+       else if (data < 0x1000)
+               s = 2;
+       else if (data < 0x100000)
+               s = 1;
+       else
+               s = 0;
+
+       ret = it913x_write(state, pro, reg, &b[s], sizeof(b) - s);
+
+       return ret;
+}
+
+static int it913x_fe_script_loader(struct it913x_fe_state *state,
+               struct it913xset *loadscript)
+{
+       int ret, i;
+       if (loadscript == NULL)
+               return -EINVAL;
+
+       for (i = 0; i < 1000; ++i) {
+               if (loadscript[i].pro == 0xff)
+                       break;
+               ret = it913x_write(state, loadscript[i].pro,
+                       loadscript[i].address,
+                       loadscript[i].reg, loadscript[i].count);
+               if (ret < 0)
+                       return -ENODEV;
+       }
+       return 0;
+}
+
+static int it913x_init_tuner(struct it913x_fe_state *state)
+{
+       int ret, i, reg;
+       u8 val, nv_val;
+       u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
+       u8 b[2];
+
+       reg = it913x_read_reg_u8(state, 0xec86);
+       switch (reg) {
+       case 0:
+               state->tun_clk_mode = reg;
+               state->tun_xtal = 2000;
+               state->tun_fdiv = 3;
+               val = 16;
+               break;
+       case -ENODEV:
+               return -ENODEV;
+       case 1:
+       default:
+               state->tun_clk_mode = reg;
+               state->tun_xtal = 640;
+               state->tun_fdiv = 1;
+               val = 6;
+               break;
+       }
+
+       reg = it913x_read_reg_u8(state, 0xed03);
+
+       if (reg < 0)
+               return -ENODEV;
+       else if (reg < sizeof(nv))
+               nv_val = nv[reg];
+       else
+               nv_val = 2;
+
+       for (i = 0; i < 50; i++) {
+               ret = it913x_read_reg(state, 0xed23, &b[0], sizeof(b));
+               reg = (b[1] << 8) + b[0];
+               if (reg > 0)
+                       break;
+               if (ret < 0)
+                       return -ENODEV;
+               udelay(2000);
+       }
+       state->tun_fn_min = state->tun_xtal * reg;
+       state->tun_fn_min /= (state->tun_fdiv * nv_val);
+       deb_info("Tuner fn_min %d", state->tun_fn_min);
+
+       if (state->config->chip_ver > 1)
+               msleep(50);
+       else {
+               for (i = 0; i < 50; i++) {
+                       reg = it913x_read_reg_u8(state, 0xec82);
+                       if (reg > 0)
+                               break;
+                       if (reg < 0)
+                               return -ENODEV;
+                       udelay(2000);
+               }
+       }
+
+       return it913x_write_reg(state, PRO_DMOD, 0xed81, val);
+}
+
+static int it9137_set_tuner(struct it913x_fe_state *state,
+               u32 bandwidth, u32 frequency_m)
+{
+       struct it913xset *set_tuner = set_it9137_template;
+       int ret, reg;
+       u32 frequency = frequency_m / 1000;
+       u32 freq, temp_f, tmp;
+       u16 iqik_m_cal;
+       u16 n_div;
+       u8 n;
+       u8 l_band;
+       u8 lna_band;
+       u8 bw;
+
+       if (state->config->firmware_ver == 1)
+               set_tuner = set_it9135_template;
+       else
+               set_tuner = set_it9137_template;
+
+       deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth);
+
+       if (frequency >= 51000 && frequency <= 440000) {
+               l_band = 0;
+               lna_band = 0;
+       } else if (frequency > 440000 && frequency <= 484000) {
+               l_band = 1;
+               lna_band = 1;
+       } else if (frequency > 484000 && frequency <= 533000) {
+               l_band = 1;
+               lna_band = 2;
+       } else if (frequency > 533000 && frequency <= 587000) {
+               l_band = 1;
+               lna_band = 3;
+       } else if (frequency > 587000 && frequency <= 645000) {
+               l_band = 1;
+               lna_band = 4;
+       } else if (frequency > 645000 && frequency <= 710000) {
+               l_band = 1;
+               lna_band = 5;
+       } else if (frequency > 710000 && frequency <= 782000) {
+               l_band = 1;
+               lna_band = 6;
+       } else if (frequency > 782000 && frequency <= 860000) {
+               l_band = 1;
+               lna_band = 7;
+       } else if (frequency > 1450000 && frequency <= 1492000) {
+               l_band = 1;
+               lna_band = 0;
+       } else if (frequency > 1660000 && frequency <= 1685000) {
+               l_band = 1;
+               lna_band = 1;
+       } else
+               return -EINVAL;
+       set_tuner[0].reg[0] = lna_band;
+
+       switch (bandwidth) {
+       case 5000000:
+               bw = 0;
+               break;
+       case 6000000:
+               bw = 2;
+               break;
+       case 7000000:
+               bw = 4;
+               break;
+       default:
+       case 8000000:
+               bw = 6;
+               break;
+       }
+
+       set_tuner[1].reg[0] = bw;
+       set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
+
+       if (frequency > 53000 && frequency <= 74000) {
+               n_div = 48;
+               n = 0;
+       } else if (frequency > 74000 && frequency <= 111000) {
+               n_div = 32;
+               n = 1;
+       } else if (frequency > 111000 && frequency <= 148000) {
+               n_div = 24;
+               n = 2;
+       } else if (frequency > 148000 && frequency <= 222000) {
+               n_div = 16;
+               n = 3;
+       } else if (frequency > 222000 && frequency <= 296000) {
+               n_div = 12;
+               n = 4;
+       } else if (frequency > 296000 && frequency <= 445000) {
+               n_div = 8;
+               n = 5;
+       } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
+               n_div = 6;
+               n = 6;
+       } else if (frequency > state->tun_fn_min && frequency <= 950000) {
+               n_div = 4;
+               n = 7;
+       } else if (frequency > 1450000 && frequency <= 1680000) {
+               n_div = 2;
+               n = 0;
+       } else
+               return -EINVAL;
+
+       reg = it913x_read_reg_u8(state, 0xed81);
+       iqik_m_cal = (u16)reg * n_div;
+
+       if (reg < 0x20) {
+               if (state->tun_clk_mode == 0)
+                       iqik_m_cal = (iqik_m_cal * 9) >> 5;
+               else
+                       iqik_m_cal >>= 1;
+       } else {
+               iqik_m_cal = 0x40 - iqik_m_cal;
+               if (state->tun_clk_mode == 0)
+                       iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
+               else
+                       iqik_m_cal = ~(iqik_m_cal >> 1);
+       }
+
+       temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
+       freq = temp_f / state->tun_xtal;
+       tmp = freq * state->tun_xtal;
+
+       if ((temp_f - tmp) >= (state->tun_xtal >> 1))
+               freq++;
+
+       freq += (u32) n << 13;
+       /* Frequency OMEGA_IQIK_M_CAL_MID*/
+       temp_f = freq + (u32)iqik_m_cal;
+
+       set_tuner[3].reg[0] =  temp_f & 0xff;
+       set_tuner[4].reg[0] =  (temp_f >> 8) & 0xff;
+
+       deb_info("High Frequency = %04x", temp_f);
+
+       /* Lower frequency */
+       set_tuner[5].reg[0] =  freq & 0xff;
+       set_tuner[6].reg[0] =  (freq >> 8) & 0xff;
+
+       deb_info("low Frequency = %04x", freq);
+
+       ret = it913x_fe_script_loader(state, set_tuner);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_fe_select_bw(struct it913x_fe_state *state,
+                       u32 bandwidth, u32 adcFrequency)
+{
+       int ret, i;
+       u8 buffer[256];
+       u32 coeff[8];
+       u16 bfsfcw_fftinx_ratio;
+       u16 fftinx_bfsfcw_ratio;
+       u8 count;
+       u8 bw;
+       u8 adcmultiplier;
+
+       deb_info("Bandwidth %d Adc %d", bandwidth, adcFrequency);
+
+       switch (bandwidth) {
+       case 5000000:
+               bw = 3;
+               break;
+       case 6000000:
+               bw = 0;
+               break;
+       case 7000000:
+               bw = 1;
+               break;
+       default:
+       case 8000000:
+               bw = 2;
+               break;
+       }
+       ret = it913x_write_reg(state, PRO_DMOD, REG_BW, bw);
+
+       if (state->table == NULL)
+               return -EINVAL;
+
+       /* In write order */
+       coeff[0] = state->table[bw].coeff_1_2048;
+       coeff[1] = state->table[bw].coeff_2_2k;
+       coeff[2] = state->table[bw].coeff_1_8191;
+       coeff[3] = state->table[bw].coeff_1_8192;
+       coeff[4] = state->table[bw].coeff_1_8193;
+       coeff[5] = state->table[bw].coeff_2_8k;
+       coeff[6] = state->table[bw].coeff_1_4096;
+       coeff[7] = state->table[bw].coeff_2_4k;
+       bfsfcw_fftinx_ratio = state->table[bw].bfsfcw_fftinx_ratio;
+       fftinx_bfsfcw_ratio = state->table[bw].fftinx_bfsfcw_ratio;
+
+       /* ADC multiplier */
+       ret = it913x_read_reg_u8(state, ADC_X_2);
+       if (ret < 0)
+               return -EINVAL;
+
+       adcmultiplier = ret;
+
+       count = 0;
+
+       /*  Build Buffer for COEFF Registers */
+       for (i = 0; i < 8; i++) {
+               if (adcmultiplier == 1)
+                       coeff[i] /= 2;
+               buffer[count++] = (coeff[i] >> 24) & 0x3;
+               buffer[count++] = (coeff[i] >> 16) & 0xff;
+               buffer[count++] = (coeff[i] >> 8) & 0xff;
+               buffer[count++] = coeff[i] & 0xff;
+       }
+
+       /* bfsfcw_fftinx_ratio register 0x21-0x22 */
+       buffer[count++] = bfsfcw_fftinx_ratio & 0xff;
+       buffer[count++] = (bfsfcw_fftinx_ratio >> 8) & 0xff;
+       /* fftinx_bfsfcw_ratio register 0x23-0x24 */
+       buffer[count++] = fftinx_bfsfcw_ratio & 0xff;
+       buffer[count++] = (fftinx_bfsfcw_ratio >> 8) & 0xff;
+       /* start at COEFF_1_2048 and write through to fftinx_bfsfcw_ratio*/
+       ret = it913x_write(state, PRO_DMOD, COEFF_1_2048, buffer, count);
+
+       for (i = 0; i < 42; i += 8)
+               debug_data_snipet(0x1, "Buffer", &buffer[i]);
+
+       return ret;
+}
+
+
+
+static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int ret, i;
+       fe_status_t old_status = state->it913x_status;
+       *status = 0;
+
+       if (state->it913x_status == 0) {
+               ret = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
+               if (ret == 0x1) {
+                       *status |= FE_HAS_SIGNAL;
+                       for (i = 0; i < 40; i++) {
+                               ret = it913x_read_reg_u8(state, MP2IF_SYNC_LK);
+                               if (ret == 0x1)
+                                       break;
+                               msleep(25);
+                       }
+                       if (ret == 0x1)
+                               *status |= FE_HAS_CARRIER
+                                       | FE_HAS_VITERBI
+                                       | FE_HAS_SYNC;
+                       state->it913x_status = *status;
+               }
+       }
+
+       if (state->it913x_status & FE_HAS_SYNC) {
+               ret = it913x_read_reg_u8(state, TPSD_LOCK);
+               if (ret == 0x1)
+                       *status |= FE_HAS_LOCK
+                               | state->it913x_status;
+               else
+                       state->it913x_status = 0;
+               if (old_status != state->it913x_status)
+                       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, ret);
+       }
+
+       return 0;
+}
+
+/* FEC values based on fe_code_rate_t non supported values 0*/
+int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88};
+int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82};
+int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76};
+
+static int it913x_get_signal_strength(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       u8 code_rate;
+       int ret, temp;
+       u8 lna_gain_os;
+
+       ret = it913x_read_reg_u8(state, VAR_P_INBAND);
+       if (ret < 0)
+               return ret;
+
+       /* VHF/UHF gain offset */
+       if (state->frequency < 300000000)
+               lna_gain_os = 7;
+       else
+               lna_gain_os = 14;
+
+       temp = (ret - 100) - lna_gain_os;
+
+       if (state->priority == PRIORITY_HIGH)
+               code_rate = p->code_rate_HP;
+       else
+               code_rate = p->code_rate_LP;
+
+       if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval))
+               return -EINVAL;
+
+       deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp);
+
+       /* Apply FEC offset values*/
+       switch (p->modulation) {
+       case QPSK:
+               temp -= it913x_qpsk_pval[code_rate];
+               break;
+       case QAM_16:
+               temp -= it913x_16qam_pval[code_rate];
+               break;
+       case QAM_64:
+               temp -= it913x_64qam_pval[code_rate];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (temp < -15)
+               ret = 0;
+       else if ((-15 <= temp) && (temp < 0))
+               ret = (2 * (temp + 15)) / 3;
+       else if ((0 <= temp) && (temp < 20))
+               ret = 4 * temp + 10;
+       else if ((20 <= temp) && (temp < 35))
+               ret = (2 * (temp - 20)) / 3 + 90;
+       else if (temp >= 35)
+               ret = 100;
+
+       deb_info("Signal Strength :%d", ret);
+
+       return ret;
+}
+
+static int it913x_fe_read_signal_strength(struct dvb_frontend *fe,
+               u16 *strength)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int ret = 0;
+       if (state->config->read_slevel) {
+               if (state->it913x_status & FE_HAS_SIGNAL)
+                       ret = it913x_read_reg_u8(state, SIGNAL_LEVEL);
+       } else
+               ret = it913x_get_signal_strength(fe);
+
+       if (ret >= 0)
+               *strength = (u16)((u32)ret * 0xffff / 0x64);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 reg[3];
+       u32 snr_val, snr_min, snr_max;
+       u32 temp;
+
+       ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg));
+
+       snr_val = (u32)(reg[2] << 16) | (reg[1] << 8) | reg[0];
+
+       ret |= it913x_read_reg(state, 0xf78b, reg, 1);
+       if (reg[0])
+               snr_val /= reg[0];
+
+       if (state->transmission_mode == TRANSMISSION_MODE_2K)
+               snr_val *= 4;
+       else if (state->transmission_mode == TRANSMISSION_MODE_4K)
+               snr_val *= 2;
+
+       if (state->constellation == QPSK) {
+               snr_min = 0xb4711;
+               snr_max = 0x191451;
+       } else if (state->constellation == QAM_16) {
+               snr_min = 0x4f0d5;
+               snr_max = 0xc7925;
+       } else if (state->constellation == QAM_64) {
+               snr_min = 0x256d0;
+               snr_max = 0x626be;
+       } else
+               return -EINVAL;
+
+       if (snr_val < snr_min)
+               *snr = 0;
+       else if (snr_val < snr_max) {
+               temp = (snr_val - snr_min) >> 5;
+               temp *= 0xffff;
+               temp /= (snr_max - snr_min) >> 5;
+               *snr = (u16)temp;
+       } else
+               *snr = 0xffff;
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       u8 reg[5];
+       /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */
+       it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
+       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
+       *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2];
+       return 0;
+}
+
+static int it913x_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int ret;
+       u8 reg[2];
+       /* Aborted Packets */
+       ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
+       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
+       *ucblocks = state->ucblocks;
+       return ret;
+}
+
+static int it913x_fe_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       u8 reg[8];
+
+       it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg));
+
+       if (reg[3] < 3)
+               p->modulation = fe_con[reg[3]];
+
+       if (reg[0] < 3)
+               p->transmission_mode = fe_mode[reg[0]];
+
+       if (reg[1] < 4)
+               p->guard_interval = fe_gi[reg[1]];
+
+       if (reg[2] < 4)
+               p->hierarchy = fe_hi[reg[2]];
+
+       state->priority = reg[5];
+
+       p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE;
+       p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE;
+
+       /* Update internal state to reflect the autodetected props */
+       state->constellation = p->modulation;
+       state->transmission_mode = p->transmission_mode;
+
+       return 0;
+}
+
+static int it913x_fe_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int i;
+       u8 empty_ch, last_ch;
+
+       state->it913x_status = 0;
+
+       /* Set bw*/
+       it913x_fe_select_bw(state, p->bandwidth_hz,
+               state->adcFrequency);
+
+       /* Training Mode Off */
+       it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0);
+
+       /* Clear Empty Channel */
+       it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0);
+
+       /* Clear bits */
+       it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0);
+       /* LED on */
+       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
+       /* Select Band*/
+       if ((p->frequency >= 51000000) && (p->frequency <= 230000000))
+               i = 0;
+       else if ((p->frequency >= 350000000) && (p->frequency <= 900000000))
+                       i = 1;
+       else if ((p->frequency >= 1450000000) && (p->frequency <= 1680000000))
+                       i = 2;
+       else
+               return -EOPNOTSUPP;
+
+       it913x_write_reg(state, PRO_DMOD, FREE_BAND, i);
+
+       deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
+       switch (state->tuner_type) {
+       case IT9135_38:
+       case IT9135_51:
+       case IT9135_52:
+       case IT9135_60:
+       case IT9135_61:
+       case IT9135_62:
+               it9137_set_tuner(state,
+                       p->bandwidth_hz, p->frequency);
+               break;
+       default:
+               if (fe->ops.tuner_ops.set_params) {
+                       fe->ops.tuner_ops.set_params(fe);
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               break;
+       }
+       /* LED off */
+       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
+       /* Trigger ofsm */
+       it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
+       last_ch = 2;
+       for (i = 0; i < 40; ++i) {
+               empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
+               if (last_ch == 1 && empty_ch == 1)
+                       break;
+               if (last_ch == 2 && empty_ch == 2)
+                       return 0;
+               last_ch = empty_ch;
+               msleep(25);
+       }
+       for (i = 0; i < 40; ++i) {
+               if (it913x_read_reg_u8(state, D_TPSD_LOCK) == 1)
+                       break;
+               msleep(25);
+       }
+
+       state->frequency = p->frequency;
+       return 0;
+}
+
+static int it913x_fe_suspend(struct it913x_fe_state *state)
+{
+       int ret, i;
+       u8 b;
+
+       ret = it913x_write_reg(state, PRO_DMOD, SUSPEND_FLAG, 0x1);
+
+       ret |= it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
+
+       for (i = 0; i < 128; i++) {
+               ret = it913x_read_reg(state, SUSPEND_FLAG, &b, 1);
+               if (ret < 0)
+                       return -ENODEV;
+               if (b == 0)
+                       break;
+
+       }
+
+       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x8);
+       /* Turn LED off */
+       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
+
+       ret |= it913x_fe_script_loader(state, it9137_tuner_off);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+/* Power sequence */
+/* Power Up    Tuner on -> Frontend suspend off -> Tuner clk on */
+/* Power Down  Frontend suspend on -> Tuner clk off -> Tuner off */
+
+static int it913x_fe_sleep(struct dvb_frontend *fe)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       return it913x_fe_suspend(state);
+}
+
+static u32 compute_div(u32 a, u32 b, u32 x)
+{
+       u32 res = 0;
+       u32 c = 0;
+       u32 i = 0;
+
+       if (a > b) {
+               c = a / b;
+               a = a - c * b;
+       }
+
+       for (i = 0; i < x; i++) {
+               if (a >= b) {
+                       res += 1;
+                       a -= b;
+               }
+               a <<= 1;
+               res <<= 1;
+       }
+
+       res = (c << x) + res;
+
+       return res;
+}
+
+static int it913x_fe_start(struct it913x_fe_state *state)
+{
+       struct it913xset *set_lna;
+       struct it913xset *set_mode;
+       int ret;
+       u8 adf = (state->config->adf & 0xf);
+       u32 adc, xtal;
+       u8 b[4];
+
+       if (state->config->chip_ver == 1)
+               ret = it913x_init_tuner(state);
+
+       info("ADF table value   :%02x", adf);
+
+       if (adf < 10) {
+               state->crystalFrequency = fe_clockTable[adf].xtal ;
+               state->table = fe_clockTable[adf].table;
+               state->adcFrequency = state->table->adcFrequency;
+
+               adc = compute_div(state->adcFrequency, 1000000ul, 19ul);
+               xtal = compute_div(state->crystalFrequency, 1000000ul, 19ul);
+
+       } else
+               return -EINVAL;
+
+       /* Set LED indicator on GPIOH3 */
+       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1);
+       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
+       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
+
+       ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type);
+       ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01);
+       ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01);
+
+       b[0] = xtal & 0xff;
+       b[1] = (xtal >> 8) & 0xff;
+       b[2] = (xtal >> 16) & 0xff;
+       b[3] = (xtal >> 24);
+       ret |= it913x_write(state, PRO_DMOD, XTAL_CLK, b , 4);
+
+       b[0] = adc & 0xff;
+       b[1] = (adc >> 8) & 0xff;
+       b[2] = (adc >> 16) & 0xff;
+       ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3);
+
+       if (state->config->adc_x2)
+               ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01);
+       b[0] = 0;
+       b[1] = 0;
+       b[2] = 0;
+       ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3);
+
+       info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x",
+               state->crystalFrequency, state->adcFrequency,
+                       state->config->adc_x2);
+       deb_info("Xtal value :%04x Adc value :%04x", xtal, adc);
+
+       if (ret < 0)
+               return -ENODEV;
+
+       /* v1 or v2 tuner script */
+       if (state->config->chip_ver > 1)
+               ret = it913x_fe_script_loader(state, it9135_v2);
+       else
+               ret = it913x_fe_script_loader(state, it9135_v1);
+       if (ret < 0)
+               return ret;
+
+       /* LNA Scripts */
+       switch (state->tuner_type) {
+       case IT9135_51:
+               set_lna = it9135_51;
+               break;
+       case IT9135_52:
+               set_lna = it9135_52;
+               break;
+       case IT9135_60:
+               set_lna = it9135_60;
+               break;
+       case IT9135_61:
+               set_lna = it9135_61;
+               break;
+       case IT9135_62:
+               set_lna = it9135_62;
+               break;
+       case IT9135_38:
+       default:
+               set_lna = it9135_38;
+       }
+       info("Tuner LNA type :%02x", state->tuner_type);
+
+       ret = it913x_fe_script_loader(state, set_lna);
+       if (ret < 0)
+               return ret;
+
+       if (state->config->chip_ver == 2) {
+               ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1);
+               ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0);
+               ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0);
+               ret |= it913x_init_tuner(state);
+       }
+       if (ret < 0)
+               return -ENODEV;
+
+       /* Always solo frontend */
+       set_mode = set_solo_fe;
+       ret |= it913x_fe_script_loader(state, set_mode);
+
+       ret |= it913x_fe_suspend(state);
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_fe_init(struct dvb_frontend *fe)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       int ret = 0;
+       /* Power Up Tuner - common all versions */
+       ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1);
+
+       ret |= it913x_fe_script_loader(state, init_1);
+
+       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
+
+       ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
+
+       return (ret < 0) ? -ENODEV : 0;
+}
+
+static void it913x_fe_release(struct dvb_frontend *fe)
+{
+       struct it913x_fe_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops it913x_fe_ofdm_ops;
+
+struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
+               u8 i2c_addr, struct ite_config *config)
+{
+       struct it913x_fe_state *state = NULL;
+       int ret;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+       if (config == NULL)
+               goto error;
+
+       state->i2c_adap = i2c_adap;
+       state->i2c_addr = i2c_addr;
+       state->config = config;
+
+       switch (state->config->tuner_id_0) {
+       case IT9135_51:
+       case IT9135_52:
+       case IT9135_60:
+       case IT9135_61:
+       case IT9135_62:
+               state->tuner_type = state->config->tuner_id_0;
+               break;
+       default:
+       case IT9135_38:
+               state->tuner_type = IT9135_38;
+       }
+
+       ret = it913x_fe_start(state);
+       if (ret < 0)
+               goto error;
+
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &it913x_fe_ofdm_ops,
+                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(it913x_fe_attach);
+
+static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "it913x-fe DVB-T",
+               .frequency_min          = 51000000,
+               .frequency_max          = 1680000000,
+               .frequency_stepsize     = 62500,
+               .caps = 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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = it913x_fe_release,
+
+       .init = it913x_fe_init,
+       .sleep = it913x_fe_sleep,
+
+       .set_frontend = it913x_fe_set_frontend,
+       .get_frontend = it913x_fe_get_frontend,
+
+       .read_status = it913x_fe_read_status,
+       .read_signal_strength = it913x_fe_read_signal_strength,
+       .read_snr = it913x_fe_read_snr,
+       .read_ber = it913x_fe_read_ber,
+       .read_ucblocks = it913x_fe_read_ucblocks,
+};
+
+MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
+MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
+MODULE_VERSION("1.15");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/it913x-fe.h b/drivers/media/dvb-frontends/it913x-fe.h
new file mode 100644 (file)
index 0000000..07fa459
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ *  Driver for it913x Frontend
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef IT913X_FE_H
+#define IT913X_FE_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct ite_config {
+       u8 chip_ver;
+       u16 chip_type;
+       u32 firmware;
+       u8 firmware_ver;
+       u8 adc_x2;
+       u8 tuner_id_0;
+       u8 tuner_id_1;
+       u8 dual_mode;
+       u8 adf;
+       /* option to read SIGNAL_LEVEL */
+       u8 read_slevel;
+};
+
+#if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \
+defined(MODULE))
+extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
+                       u8 i2c_addr, struct ite_config *config);
+#else
+static inline struct dvb_frontend *it913x_fe_attach(
+               struct i2c_adapter *i2c_adap,
+                       u8 i2c_addr, struct ite_config *config)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_IT913X_FE */
+#define I2C_BASE_ADDR          0x10
+#define DEV_0                  0x0
+#define DEV_1                  0x10
+#define PRO_LINK               0x0
+#define PRO_DMOD               0x1
+#define DEV_0_DMOD             (PRO_DMOD << 0x7)
+#define DEV_1_DMOD             (DEV_0_DMOD | DEV_1)
+#define CHIP2_I2C_ADDR         0x3a
+
+#define AFE_MEM0               0xfb24
+
+#define MP2_SW_RST             0xf99d
+#define MP2IF2_SW_RST          0xf9a4
+
+#define        PADODPU                 0xd827
+#define THIRDODPU              0xd828
+#define AGC_O_D                        0xd829
+
+#define EP0_TX_EN              0xdd11
+#define EP0_TX_NAK             0xdd13
+#define EP4_TX_LEN_LSB         0xdd88
+#define EP4_TX_LEN_MSB         0xdd89
+#define EP4_MAX_PKT            0xdd0c
+#define EP5_TX_LEN_LSB         0xdd8a
+#define EP5_TX_LEN_MSB         0xdd8b
+#define EP5_MAX_PKT            0xdd0d
+
+#define IO_MUX_POWER_CLK       0xd800
+#define CLK_O_EN               0xd81a
+#define I2C_CLK                        0xf103
+#define I2C_CLK_100            0x7
+#define I2C_CLK_400            0x1a
+
+#define D_TPSD_LOCK            0xf5a9
+#define MP2IF2_EN              0xf9a3
+#define MP2IF_SERIAL           0xf985
+#define TSIS_ENABLE            0xf9cd
+#define MP2IF2_HALF_PSB                0xf9a5
+#define MP2IF_STOP_EN          0xf9b5
+#define MPEG_FULL_SPEED                0xf990
+#define TOP_HOSTB_SER_MODE     0xd91c
+
+#define PID_RST                        0xf992
+#define PID_EN                 0xf993
+#define PID_INX_EN             0xf994
+#define PID_INX                        0xf995
+#define PID_LSB                        0xf996
+#define PID_MSB                        0xf997
+
+#define MP2IF_MPEG_PAR_MODE    0xf986
+#define DCA_UPPER_CHIP         0xf731
+#define DCA_LOWER_CHIP         0xf732
+#define DCA_PLATCH             0xf730
+#define DCA_FPGA_LATCH         0xf778
+#define DCA_STAND_ALONE                0xf73c
+#define DCA_ENABLE             0xf776
+
+#define DVBT_INTEN             0xf41f
+#define DVBT_ENABLE            0xf41a
+#define HOSTB_DCA_LOWER                0xd91f
+#define HOSTB_MPEG_PAR_MODE    0xd91b
+#define HOSTB_MPEG_SER_MODE    0xd91c
+#define HOSTB_MPEG_SER_DO7     0xd91d
+#define HOSTB_DCA_UPPER                0xd91e
+#define PADMISCDR2             0xd830
+#define PADMISCDR4             0xd831
+#define PADMISCDR8             0xd832
+#define PADMISCDRSR            0xd833
+#define LOCK3_OUT              0xd8fd
+
+#define GPIOH1_O               0xd8af
+#define GPIOH1_EN              0xd8b0
+#define GPIOH1_ON              0xd8b1
+#define GPIOH3_O               0xd8b3
+#define GPIOH3_EN              0xd8b4
+#define GPIOH3_ON              0xd8b5
+#define GPIOH5_O               0xd8bb
+#define GPIOH5_EN              0xd8bc
+#define GPIOH5_ON              0xd8bd
+
+#define AFE_MEM0               0xfb24
+
+#define REG_TPSD_TX_MODE       0xf900
+#define REG_TPSD_GI            0xf901
+#define REG_TPSD_HIER          0xf902
+#define REG_TPSD_CONST         0xf903
+#define REG_BW                 0xf904
+#define REG_PRIV               0xf905
+#define REG_TPSD_HP_CODE       0xf906
+#define REG_TPSD_LP_CODE       0xf907
+
+#define MP2IF_SYNC_LK          0xf999
+#define ADC_FREQ               0xf1cd
+
+#define TRIGGER_OFSM           0x0000
+/* COEFF Registers start at 0x0001 to 0x0020 */
+#define COEFF_1_2048           0x0001
+#define XTAL_CLK               0x0025
+#define BFS_FCW                        0x0029
+
+/* Error Regs */
+#define RSD_ABORT_PKT_LSB      0x0032
+#define RSD_ABORT_PKT_MSB      0x0033
+#define RSD_BIT_ERR_0_7                0x0034
+#define RSD_BIT_ERR_8_15       0x0035
+#define RSD_BIT_ERR_23_16      0x0036
+#define RSD_BIT_COUNT_LSB      0x0037
+#define RSD_BIT_COUNT_MSB      0x0038
+
+#define TPSD_LOCK              0x003c
+#define TRAINING_MODE          0x0040
+#define ADC_X_2                        0x0045
+#define TUNER_ID               0x0046
+#define EMPTY_CHANNEL_STATUS   0x0047
+#define SIGNAL_LEVEL           0x0048
+#define SIGNAL_QUALITY         0x0049
+#define EST_SIGNAL_LEVEL       0x004a
+#define FREE_BAND              0x004b
+#define SUSPEND_FLAG           0x004c
+#define VAR_P_INBAND           0x00f7
+
+/* Build in tuner types */
+#define IT9137 0x38
+#define IT9135_38 0x38
+#define IT9135_51 0x51
+#define IT9135_52 0x52
+#define IT9135_60 0x60
+#define IT9135_61 0x61
+#define IT9135_62 0x62
+
+enum {
+       CMD_DEMOD_READ = 0,
+       CMD_DEMOD_WRITE,
+       CMD_TUNER_READ,
+       CMD_TUNER_WRITE,
+       CMD_REG_EEPROM_READ,
+       CMD_REG_EEPROM_WRITE,
+       CMD_DATA_READ,
+       CMD_VAR_READ = 8,
+       CMD_VAR_WRITE,
+       CMD_PLATFORM_GET,
+       CMD_PLATFORM_SET,
+       CMD_IP_CACHE,
+       CMD_IP_ADD,
+       CMD_IP_REMOVE,
+       CMD_PID_ADD,
+       CMD_PID_REMOVE,
+       CMD_SIPSI_GET,
+       CMD_SIPSI_MPE_RESET,
+       CMD_H_PID_ADD = 0x15,
+       CMD_H_PID_REMOVE,
+       CMD_ABORT,
+       CMD_IR_GET,
+       CMD_IR_SET,
+       CMD_FW_DOWNLOAD = 0x21,
+       CMD_QUERYINFO,
+       CMD_BOOT,
+       CMD_FW_DOWNLOAD_BEGIN,
+       CMD_FW_DOWNLOAD_END,
+       CMD_RUN_CODE,
+       CMD_SCATTER_READ = 0x28,
+       CMD_SCATTER_WRITE,
+       CMD_GENERIC_READ,
+       CMD_GENERIC_WRITE
+};
+
+enum {
+       READ_LONG,
+       WRITE_LONG,
+       READ_SHORT,
+       WRITE_SHORT,
+       READ_DATA,
+       WRITE_DATA,
+       WRITE_CMD,
+};
+
+enum {
+       IT9135_AUTO = 0,
+       IT9137_FW,
+       IT9135_V1_FW,
+       IT9135_V2_FW,
+};
+
+#endif /* IT913X_FE_H */
diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
new file mode 100644 (file)
index 0000000..3164575
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "itd1000.h"
+#include "itd1000_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define itd_dbg(args...)  do { \
+       if (debug) { \
+               printk(KERN_DEBUG   "ITD1000: " args);\
+       } \
+} while (0)
+
+#define itd_warn(args...) do { \
+       printk(KERN_WARNING "ITD1000: " args); \
+} while (0)
+
+#define itd_info(args...) do { \
+       printk(KERN_INFO    "ITD1000: " args); \
+} while (0)
+
+/* don't write more than one byte with flexcop behind */
+static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len)
+{
+       u8 buf[1+len];
+       struct i2c_msg msg = {
+               .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1
+       };
+       buf[0] = reg;
+       memcpy(&buf[1], v, len);
+
+       /* itd_dbg("wr %02x: %02x\n", reg, v[0]); */
+
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "itd1000 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
+{
+       u8 val;
+       struct i2c_msg msg[2] = {
+               { .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 },
+       };
+
+       /* ugly flexcop workaround */
+       itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1);
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               itd_warn("itd1000 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return val;
+}
+
+static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+{
+       int ret = itd1000_write_regs(state, r, &v, 1);
+       state->shadow[r] = v;
+       return ret;
+}
+
+
+static struct {
+       u32 symbol_rate;
+       u8  pgaext  : 4; /* PLLFH */
+       u8  bbgvmin : 4; /* BBGVMIN */
+} itd1000_lpf_pga[] = {
+       {        0, 0x8, 0x3 },
+       {  5200000, 0x8, 0x3 },
+       { 12200000, 0x4, 0x3 },
+       { 15400000, 0x2, 0x3 },
+       { 19800000, 0x2, 0x3 },
+       { 21500000, 0x2, 0x3 },
+       { 24500000, 0x2, 0x3 },
+       { 28400000, 0x2, 0x3 },
+       { 33400000, 0x2, 0x3 },
+       { 34400000, 0x1, 0x4 },
+       { 34400000, 0x1, 0x4 },
+       { 38400000, 0x1, 0x4 },
+       { 38400000, 0x1, 0x4 },
+       { 40400000, 0x1, 0x4 },
+       { 45400000, 0x1, 0x4 },
+};
+
+static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate)
+{
+       u8 i;
+       u8 con1    = itd1000_read_reg(state, CON1)    & 0xfd;
+       u8 pllfh   = itd1000_read_reg(state, PLLFH)   & 0x0f;
+       u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0;
+       u8 bw      = itd1000_read_reg(state, BW)      & 0xf0;
+
+       itd_dbg("symbol_rate = %d\n", symbol_rate);
+
+       /* not sure what is that ? - starting to download the table */
+       itd1000_write_reg(state, CON1, con1 | (1 << 1));
+
+       for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++)
+               if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) {
+                       itd_dbg("symrate: index: %d pgaext: %x, bbgvmin: %x\n", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin);
+                       itd1000_write_reg(state, PLLFH,   pllfh | (itd1000_lpf_pga[i].pgaext << 4));
+                       itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin));
+                       itd1000_write_reg(state, BW,      bw | (i & 0x0f));
+                       break;
+               }
+
+       itd1000_write_reg(state, CON1, con1 | (0 << 1));
+}
+
+static struct {
+       u8 vcorg;
+       u32 fmax_rg;
+} itd1000_vcorg[] = {
+       {  1,  920000 },
+       {  2,  971000 },
+       {  3, 1031000 },
+       {  4, 1091000 },
+       {  5, 1171000 },
+       {  6, 1281000 },
+       {  7, 1381000 },
+       {  8,  500000 },        /* this is intentional. */
+       {  9, 1451000 },
+       { 10, 1531000 },
+       { 11, 1631000 },
+       { 12, 1741000 },
+       { 13, 1891000 },
+       { 14, 2071000 },
+       { 15, 2250000 },
+};
+
+static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
+{
+       u8 i;
+       u8 gvbb_i2c     = itd1000_read_reg(state, GVBB_I2C) & 0xbf;
+       u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f;
+       u8 adcout;
+
+       /* reserved bit again (reset ?) */
+       itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6));
+
+       for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) {
+               if (freq_khz < itd1000_vcorg[i].fmax_rg) {
+                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4));
+                       msleep(1);
+
+                       adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f;
+
+                       itd_dbg("VCO: %dkHz: %d -> ADCOUT: %d %02x\n", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c);
+
+                       if (adcout > 13) {
+                               if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15))
+                                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4));
+                       } else if (adcout < 2) {
+                               if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9))
+                                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4));
+                       }
+                       break;
+               }
+       }
+}
+
+static const struct {
+       u32 freq;
+       u8 values[10]; /* RFTR, RFST1 - RFST9 */
+} itd1000_fre_values[] = {
+       { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+       { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+       { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+       { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+       { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+       { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+       { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+       { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } },
+       { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } },
+       { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } }
+};
+
+
+#define FREF 16
+
+static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
+{
+       int i, j;
+       u32 plln, pllf;
+       u64 tmp;
+
+       plln = (freq_khz * 1000) / 2 / FREF;
+
+       /* Compute the factional part times 1000 */
+       tmp  = plln % 1000000;
+       plln /= 1000000;
+
+       tmp *= 1048576;
+       do_div(tmp, 1000000);
+       pllf = (u32) tmp;
+
+       state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
+       itd_dbg("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d\n", freq_khz, state->frequency, pllf, plln);
+
+       itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
+       itd1000_write_reg(state, PLLNL, plln & 0xff);
+       itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
+       itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
+       itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff);
+
+       for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) {
+               if (freq_khz <= itd1000_fre_values[i].freq) {
+                       itd_dbg("fre_values: %d\n", i);
+                       itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]);
+                       for (j = 0; j < 9; j++)
+                               itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]);
+                       break;
+               }
+       }
+
+       itd1000_set_vco(state, freq_khz);
+}
+
+static int itd1000_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct itd1000_state *state = fe->tuner_priv;
+       u8 pllcon1;
+
+       itd1000_set_lo(state, c->frequency);
+       itd1000_set_lpf_bw(state, c->symbol_rate);
+
+       pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f;
+       itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7));
+       itd1000_write_reg(state, PLLCON1, pllcon1);
+
+       return 0;
+}
+
+static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct itd1000_state *state = fe->tuner_priv;
+       *frequency = state->frequency;
+       return 0;
+}
+
+static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       return 0;
+}
+
+static u8 itd1000_init_tab[][2] = {
+       { PLLCON1,       0x65 }, /* Register does not change */
+       { PLLNH,         0x80 }, /* Bits [7:6] do not change */
+       { RESERVED_0X6D, 0x3b },
+       { VCO_CHP2_I2C,  0x12 },
+       { 0x72,          0xf9 }, /* No such regsister defined */
+       { RESERVED_0X73, 0xff },
+       { RESERVED_0X74, 0xb2 },
+       { RESERVED_0X75, 0xc7 },
+       { EXTGVBBRF,     0xf0 },
+       { DIVAGCCK,      0x80 },
+       { BBTR,          0xa0 },
+       { RESERVED_0X7E, 0x4f },
+       { 0x82,          0x88 }, /* No such regsister defined */
+       { 0x83,          0x80 }, /* No such regsister defined */
+       { 0x84,          0x80 }, /* No such regsister defined */
+       { RESERVED_0X85, 0x74 },
+       { RESERVED_0X86, 0xff },
+       { RESERVED_0X88, 0x02 },
+       { RESERVED_0X89, 0x16 },
+       { RFST0,         0x1f },
+       { RESERVED_0X94, 0x66 },
+       { RESERVED_0X95, 0x66 },
+       { RESERVED_0X96, 0x77 },
+       { RESERVED_0X97, 0x99 },
+       { RESERVED_0X98, 0xff },
+       { RESERVED_0X99, 0xfc },
+       { RESERVED_0X9A, 0xba },
+       { RESERVED_0X9B, 0xaa },
+};
+
+static u8 itd1000_reinit_tab[][2] = {
+       { VCO_CHP1_I2C, 0x8a },
+       { BW,           0x87 },
+       { GVBB_I2C,     0x03 },
+       { BBGVMIN,      0x03 },
+       { CON1,         0x2e },
+};
+
+
+static int itd1000_init(struct dvb_frontend *fe)
+{
+       struct itd1000_state *state = fe->tuner_priv;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++)
+               itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]);
+
+       for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++)
+               itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]);
+
+       return 0;
+}
+
+static int itd1000_sleep(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int itd1000_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops itd1000_tuner_ops = {
+       .info = {
+               .name           = "Integrant ITD1000",
+               .frequency_min  = 950000,
+               .frequency_max  = 2150000,
+               .frequency_step = 125,     /* kHz for QPSK frontends */
+       },
+
+       .release       = itd1000_release,
+
+       .init          = itd1000_init,
+       .sleep         = itd1000_sleep,
+
+       .set_params    = itd1000_set_parameters,
+       .get_frequency = itd1000_get_frequency,
+       .get_bandwidth = itd1000_get_bandwidth
+};
+
+
+struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
+{
+       struct itd1000_state *state = NULL;
+       u8 i = 0;
+
+       state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->cfg = cfg;
+       state->i2c = i2c;
+
+       i = itd1000_read_reg(state, 0);
+       if (i != 0) {
+               kfree(state);
+               return NULL;
+       }
+       itd_info("successfully identified (ID: %d)\n", i);
+
+       memset(state->shadow, 0xff, sizeof(state->shadow));
+       for (i = 0x65; i < 0x9c; i++)
+               state->shadow[i] = itd1000_read_reg(state, i);
+
+       memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = state;
+
+       return fe;
+}
+EXPORT_SYMBOL(itd1000_attach);
+
+MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
+MODULE_DESCRIPTION("Integrant ITD1000 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/itd1000.h b/drivers/media/dvb-frontends/itd1000.h
new file mode 100644 (file)
index 0000000..5e18df0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef ITD1000_H
+#define ITD1000_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct itd1000_config {
+       u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
+#else
+static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/itd1000_priv.h b/drivers/media/dvb-frontends/itd1000_priv.h
new file mode 100644 (file)
index 0000000..08ca851
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef ITD1000_PRIV_H
+#define ITD1000_PRIV_H
+
+struct itd1000_state {
+       struct itd1000_config *cfg;
+       struct i2c_adapter    *i2c;
+
+       u32 frequency; /* contains the value resulting from the LO-setting */
+
+       /* ugly workaround for flexcop's incapable i2c-controller
+        * FIXME, if possible
+        */
+       u8 shadow[256];
+};
+
+enum itd1000_register {
+       VCO_CHP1 = 0x65,
+       VCO_CHP2,
+       PLLCON1,
+       PLLNH,
+       PLLNL,
+       PLLFH,
+       PLLFM,
+       PLLFL,
+       RESERVED_0X6D,
+       PLLLOCK,
+       VCO_CHP2_I2C,
+       VCO_CHP1_I2C,
+       BW,
+       RESERVED_0X73 = 0x73,
+       RESERVED_0X74,
+       RESERVED_0X75,
+       GVBB,
+       GVRF,
+       GVBB_I2C,
+       EXTGVBBRF,
+       DIVAGCCK,
+       BBTR,
+       RFTR,
+       BBGVMIN,
+       RESERVED_0X7E,
+       RESERVED_0X85 = 0x85,
+       RESERVED_0X86,
+       CON1,
+       RESERVED_0X88,
+       RESERVED_0X89,
+       RFST0,
+       RFST1,
+       RFST2,
+       RFST3,
+       RFST4,
+       RFST5,
+       RFST6,
+       RFST7,
+       RFST8,
+       RFST9,
+       RESERVED_0X94,
+       RESERVED_0X95,
+       RESERVED_0X96,
+       RESERVED_0X97,
+       RESERVED_0X98,
+       RESERVED_0X99,
+       RESERVED_0X9A,
+       RESERVED_0X9B,
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c
new file mode 100644 (file)
index 0000000..bc5a820
--- /dev/null
@@ -0,0 +1,325 @@
+/**
+ * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
+ *
+ * Copyright (C) 2010 Malcolm Priestley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "ix2505v.h"
+
+static int ix2505v_debug;
+#define dprintk(level, args...) do { \
+       if (ix2505v_debug & level) \
+               printk(KERN_DEBUG "ix2505v: " args); \
+} while (0)
+
+#define deb_info(args...)  dprintk(0x01, args)
+#define deb_i2c(args...)  dprintk(0x02, args)
+
+struct ix2505v_state {
+       struct i2c_adapter *i2c;
+       const struct ix2505v_config *config;
+       u32 frequency;
+};
+
+/**
+ *  Data read format of the Sharp IX2505V B0017
+ *
+ *  byte1:   1   |   1   |   0   |   0   |   0   |  MA1  |  MA0  |  1
+ *  byte2:  POR  |   FL  |  RD2  |  RD1  |  RD0  |   X   |   X   |  X
+ *
+ *  byte1 = address
+ *  byte2;
+ *     POR = Power on Reset (VCC H=<2.2v L=>2.2v)
+ *     FL  = Phase Lock (H=lock L=unlock)
+ *     RD0-2 = Reserved internal operations
+ *
+ * Only POR can be used to check the tuner is present
+ *
+ * Caution: after byte2 the I2C reverts to write mode continuing to read
+ *          may corrupt tuning data.
+ *
+ */
+
+static int ix2505v_read_status_reg(struct ix2505v_state *state)
+{
+       u8 addr = state->config->tuner_address;
+       u8 b2[] = {0};
+       int ret;
+
+       struct i2c_msg msg[1] = {
+               { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 1);
+       deb_i2c("Read %s ", __func__);
+
+       return (ret == 1) ? (int) b2[0] : -1;
+}
+
+static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
+{
+       struct i2c_msg msg[1] = {
+               { .addr = state->config->tuner_address, .flags = 0,
+                 .buf = buf, .len = count },
+       };
+
+       int ret;
+
+       ret = i2c_transfer(state->i2c, msg, 1);
+
+       if (ret != 1) {
+               deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int ix2505v_release(struct dvb_frontend *fe)
+{
+       struct ix2505v_state *state = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+
+       return 0;
+}
+
+/**
+ *  Data write format of the Sharp IX2505V B0017
+ *
+ *  byte1:   1   |   1   |   0   |   0   |   0   | 0(MA1)| 0(MA0)|  0
+ *  byte2:   0   |  BG1  |  BG2  |   N8  |   N7  |   N6  |  N5   |  N4
+ *  byte3:   N3  |   N2  |   N1  |   A5  |   A4  |   A3  |   A2  |  A1
+ *  byte4:   1   | 1(C1) | 1(C0) |  PD5  |  PD4  |   TM  | 0(RTS)| 1(REF)
+ *  byte5:   BA2 |   BA1 |  BA0  |  PSC  |  PD3  |PD2/TS2|DIV/TS1|PD0/TS0
+ *
+ *  byte1 = address
+ *
+ *  Write order
+ *  1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
+ *  2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
+ *  3) byte1 -> byte2 -> byte3 -> byte4
+ *  4) byte1 -> byte4 -> byte5 -> byte2
+ *  5) byte1 -> byte2 -> byte3
+ *  6) byte1 -> byte4 -> byte5
+ *  7) byte1 -> byte2
+ *  8) byte1 -> byte4
+ *
+ *  Recommended Setup
+ *  1 -> 8 -> 6
+ */
+
+static int ix2505v_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct ix2505v_state *state = fe->tuner_priv;
+       u32 frequency = c->frequency;
+       u32 b_w  = (c->symbol_rate * 27) / 32000;
+       u32 div_factor, N , A, x;
+       int ret = 0, len;
+       u8 gain, cc, ref, psc, local_osc, lpf;
+       u8 data[4] = {0};
+
+       if ((frequency < fe->ops.info.frequency_min)
+       ||  (frequency > fe->ops.info.frequency_max))
+               return -EINVAL;
+
+       if (state->config->tuner_gain)
+               gain = (state->config->tuner_gain < 4)
+                       ? state->config->tuner_gain : 0;
+       else
+               gain = 0x0;
+
+       if (state->config->tuner_chargepump)
+               cc = state->config->tuner_chargepump;
+       else
+               cc = 0x3;
+
+       ref = 8; /* REF =1 */
+       psc = 32; /* PSC = 0 */
+
+       div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
+       x = div_factor / psc;
+       N = x/100;
+       A = ((x - (N * 100)) * psc) / 100;
+
+       data[0] = ((gain & 0x3) << 5) | (N >> 3);
+       data[1] = (N << 5) | (A & 0x1f);
+       data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
+
+       deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
+
+       if (frequency <= 1065000)
+               local_osc = (6 << 5) | 2;
+       else if (frequency <= 1170000)
+               local_osc = (7 << 5) | 2;
+       else if (frequency <= 1300000)
+               local_osc = (1 << 5);
+       else if (frequency <= 1445000)
+               local_osc = (2 << 5);
+       else if (frequency <= 1607000)
+               local_osc = (3 << 5);
+       else if (frequency <= 1778000)
+               local_osc = (4 << 5);
+       else if (frequency <= 1942000)
+               local_osc = (5 << 5);
+       else            /*frequency up to 2150000*/
+               local_osc = (6 << 5);
+
+       data[3] = local_osc; /* all other bits set 0 */
+
+       if (b_w <= 10000)
+               lpf = 0xc;
+       else if (b_w <= 12000)
+               lpf = 0x2;
+       else if (b_w <= 14000)
+               lpf = 0xa;
+       else if (b_w <= 16000)
+               lpf = 0x6;
+       else if (b_w <= 18000)
+               lpf = 0xe;
+       else if (b_w <= 20000)
+               lpf = 0x1;
+       else if (b_w <= 22000)
+               lpf = 0x9;
+       else if (b_w <= 24000)
+               lpf = 0x5;
+       else if (b_w <= 26000)
+               lpf = 0xd;
+       else if (b_w <= 28000)
+               lpf = 0x3;
+               else
+               lpf = 0xb;
+
+       deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
+       deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       len = sizeof(data);
+       ret |= ix2505v_write(state, data, len);
+
+       data[2] |= 0x4; /* set TM = 1 other bits same */
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       len = 1;
+       ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
+
+       msleep(10);
+
+       data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
+       data[3] |= (lpf & 0x3) << 2;
+
+       deb_info("Data 2=[%x%x]\n", data[2], data[3]);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       len = 2;
+       ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
+
+       if (state->config->min_delay_ms)
+               msleep(state->config->min_delay_ms);
+
+       state->frequency = frequency;
+
+       return ret;
+}
+
+static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct ix2505v_state *state = fe->tuner_priv;
+
+       *frequency = state->frequency;
+
+       return 0;
+}
+
+static struct dvb_tuner_ops ix2505v_tuner_ops = {
+       .info = {
+               .name = "Sharp IX2505V (B0017)",
+               .frequency_min = 950000,
+               .frequency_max = 2175000
+       },
+       .release = ix2505v_release,
+       .set_params = ix2505v_set_params,
+       .get_frequency = ix2505v_get_frequency,
+};
+
+struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+                                   const struct ix2505v_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct ix2505v_state *state = NULL;
+       int ret;
+
+       if (NULL == config) {
+               deb_i2c("%s: no config ", __func__);
+               goto error;
+       }
+
+       state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL);
+       if (NULL == state)
+               return NULL;
+
+       state->config = config;
+       state->i2c = i2c;
+
+       if (state->config->tuner_write_only) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = ix2505v_read_status_reg(state);
+
+               if (ret & 0x80) {
+                       deb_i2c("%s: No IX2505V found\n", __func__);
+                       goto error;
+               }
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       fe->tuner_priv = state;
+
+       memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+       deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
+               __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+       return fe;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(ix2505v_attach);
+
+module_param_named(debug, ix2505v_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB IX2505V tuner driver");
+MODULE_AUTHOR("Malcolm Priestley");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h
new file mode 100644 (file)
index 0000000..67e89d6
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
+ *
+ * Copyright (C) 2010 Malcolm Priestley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_IX2505V_H
+#define DVB_IX2505V_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a ix2505v tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config ix2505v_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct ix2505v_config {
+       u8 tuner_address;
+
+       /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
+       u8 tuner_gain;
+
+       /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
+       u8 tuner_chargepump;
+
+       /* delay after tune */
+       int min_delay_ms;
+
+       /* disables reads*/
+       u8 tuner_write_only;
+
+};
+
+#if defined(CONFIG_DVB_IX2505V) || \
+       (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+       const struct ix2505v_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+       const struct ix2505v_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* DVB_IX2505V_H */
diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
new file mode 100644 (file)
index 0000000..36fcf55
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+    driver for LSI L64781 COFDM demodulator
+
+    Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
+                      Marko Kohtala <marko.kohtala@luukku.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "dvb_frontend.h"
+#include "l64781.h"
+
+
+struct l64781_state {
+       struct i2c_adapter* i2c;
+       const struct l64781_config* config;
+       struct dvb_frontend frontend;
+
+       /* private demodulator data */
+       unsigned int first:1;
+};
+
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "l64781: " args); \
+       } while (0)
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+
+static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf [] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+
+       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
+               dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
+                        __func__, reg, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static int l64781_readreg (struct l64781_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) return ret;
+
+       return b1[0];
+}
+
+static void apply_tps (struct l64781_state* state)
+{
+       l64781_writereg (state, 0x2a, 0x00);
+       l64781_writereg (state, 0x2a, 0x01);
+
+       /* This here is a little bit questionable because it enables
+          the automatic update of TPS registers. I think we'd need to
+          handle the IRQ from FE to update some other registers as
+          well, or at least implement some magic to tuning to correct
+          to the TPS received from transmission. */
+       l64781_writereg (state, 0x2a, 0x02);
+}
+
+
+static void reset_afc (struct l64781_state* state)
+{
+       /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
+          timing offset */
+       l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
+       l64781_writereg (state, 0x08, 0);    /* AFC INIT FREQ */
+       l64781_writereg (state, 0x09, 0);
+       l64781_writereg (state, 0x0a, 0);
+       l64781_writereg (state, 0x07, 0x8e);
+       l64781_writereg (state, 0x0e, 0);    /* AGC gain to zero in beginning */
+       l64781_writereg (state, 0x11, 0x80); /* stall TIM */
+       l64781_writereg (state, 0x10, 0);    /* TIM_OFFSET_LSB */
+       l64781_writereg (state, 0x12, 0);
+       l64781_writereg (state, 0x13, 0);
+       l64781_writereg (state, 0x11, 0x00);
+}
+
+static int reset_and_configure (struct l64781_state* state)
+{
+       u8 buf [] = { 0x06 };
+       struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
+       // NOTE: this is correct in writing to address 0x00
+
+       return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
+}
+
+static int apply_frontend_param(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct l64781_state* state = fe->demodulator_priv;
+       /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
+       static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
+       /* QPSK, QAM_16, QAM_64 */
+       static const u8 qam_tab [] = { 2, 4, 0, 6 };
+       static const u8 guard_tab [] = { 1, 2, 4, 8 };
+       /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
+       static const u32 ppm = 8000;
+       u32 ddfs_offset_fixed;
+/*     u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
+/*                     bw_tab[p->bandWidth]<<10)/15625; */
+       u32 init_freq;
+       u32 spi_bias;
+       u8 val0x04;
+       u8 val0x05;
+       u8 val0x06;
+       int bw;
+
+       switch (p->bandwidth_hz) {
+       case 8000000:
+               bw = 8;
+               break;
+       case 7000000:
+               bw = 7;
+               break;
+       case 6000000:
+               bw = 6;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       if (p->inversion != INVERSION_ON &&
+           p->inversion != INVERSION_OFF)
+               return -EINVAL;
+
+       if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
+           p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
+           p->code_rate_HP != FEC_7_8)
+               return -EINVAL;
+
+       if (p->hierarchy != HIERARCHY_NONE &&
+           (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
+            p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
+            p->code_rate_LP != FEC_7_8))
+               return -EINVAL;
+
+       if (p->modulation != QPSK && p->modulation != QAM_16 &&
+           p->modulation != QAM_64)
+               return -EINVAL;
+
+       if (p->transmission_mode != TRANSMISSION_MODE_2K &&
+           p->transmission_mode != TRANSMISSION_MODE_8K)
+               return -EINVAL;
+
+       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
+           p->guard_interval > GUARD_INTERVAL_1_4)
+               return -EINVAL;
+
+       if (p->hierarchy < HIERARCHY_NONE ||
+           p->hierarchy > HIERARCHY_4)
+               return -EINVAL;
+
+       ddfs_offset_fixed = 0x4000-(ppm<<16)/bw/1000000;
+
+       /* This works up to 20000 ppm, it overflows if too large ppm! */
+       init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
+                       bw & 0xFFFFFF);
+
+       /* SPI bias calculation is slightly modified to fit in 32bit */
+       /* will work for high ppm only... */
+       spi_bias = 378 * (1 << 10);
+       spi_bias *= 16;
+       spi_bias *= bw;
+       spi_bias *= qam_tab[p->modulation];
+       spi_bias /= p->code_rate_HP + 1;
+       spi_bias /= (guard_tab[p->guard_interval] + 32);
+       spi_bias *= 1000;
+       spi_bias /= 1000 + ppm/1000;
+       spi_bias *= p->code_rate_HP;
+
+       val0x04 = (p->transmission_mode << 2) | p->guard_interval;
+       val0x05 = fec_tab[p->code_rate_HP];
+
+       if (p->hierarchy != HIERARCHY_NONE)
+               val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
+
+       val0x06 = (p->hierarchy << 2) | p->modulation;
+
+       l64781_writereg (state, 0x04, val0x04);
+       l64781_writereg (state, 0x05, val0x05);
+       l64781_writereg (state, 0x06, val0x06);
+
+       reset_afc (state);
+
+       /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
+       l64781_writereg (state, 0x15,
+                        p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
+       l64781_writereg (state, 0x16, init_freq & 0xff);
+       l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
+       l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
+
+       l64781_writereg (state, 0x1b, spi_bias & 0xff);
+       l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
+       l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
+               (p->inversion == INVERSION_ON ? 0x80 : 0x00));
+
+       l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
+       l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
+
+       l64781_readreg (state, 0x00);  /*  clear interrupt registers... */
+       l64781_readreg (state, 0x01);  /*  dto. */
+
+       apply_tps (state);
+
+       return 0;
+}
+
+static int get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct l64781_state* state = fe->demodulator_priv;
+       int tmp;
+
+
+       tmp = l64781_readreg(state, 0x04);
+       switch(tmp & 3) {
+       case 0:
+               p->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               p->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               p->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               p->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+       switch((tmp >> 2) & 3) {
+       case 0:
+               p->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               p->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       default:
+               printk(KERN_WARNING "Unexpected value for transmission_mode\n");
+       }
+
+       tmp = l64781_readreg(state, 0x05);
+       switch(tmp & 7) {
+       case 0:
+               p->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_HP = FEC_7_8;
+               break;
+       default:
+               printk("Unexpected value for code_rate_HP\n");
+       }
+       switch((tmp >> 3) & 7) {
+       case 0:
+               p->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_LP = FEC_7_8;
+               break;
+       default:
+               printk("Unexpected value for code_rate_LP\n");
+       }
+
+       tmp = l64781_readreg(state, 0x06);
+       switch(tmp & 3) {
+       case 0:
+               p->modulation = QPSK;
+               break;
+       case 1:
+               p->modulation = QAM_16;
+               break;
+       case 2:
+               p->modulation = QAM_64;
+               break;
+       default:
+               printk(KERN_WARNING "Unexpected value for modulation\n");
+       }
+       switch((tmp >> 2) & 7) {
+       case 0:
+               p->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               p->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               p->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               p->hierarchy = HIERARCHY_4;
+               break;
+       default:
+               printk("Unexpected value for hierarchy\n");
+       }
+
+
+       tmp = l64781_readreg (state, 0x1d);
+       p->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
+
+       tmp = (int) (l64781_readreg (state, 0x08) |
+                    (l64781_readreg (state, 0x09) << 8) |
+                    (l64781_readreg (state, 0x0a) << 16));
+       p->frequency += tmp;
+
+       return 0;
+}
+
+static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+       int sync = l64781_readreg (state, 0x32);
+       int gain = l64781_readreg (state, 0x0e);
+
+       l64781_readreg (state, 0x00);  /*  clear interrupt registers... */
+       l64781_readreg (state, 0x01);  /*  dto. */
+
+       *status = 0;
+
+       if (gain > 5)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 0x02) /* VCXO locked, this criteria should be ok */
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 0x20)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 0x40)
+               *status |= FE_HAS_SYNC;
+
+       if (sync == 0x7f)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       /*   XXX FIXME: set up counting period (reg 0x26...0x28)
+        */
+       *ber = l64781_readreg (state, 0x39)
+           | (l64781_readreg (state, 0x3a) << 8);
+
+       return 0;
+}
+
+static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       u8 gain = l64781_readreg (state, 0x0e);
+       *signal_strength = (gain << 8) | gain;
+
+       return 0;
+}
+
+static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
+       *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
+
+       return 0;
+}
+
+static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       *ucblocks = l64781_readreg (state, 0x37)
+          | (l64781_readreg (state, 0x38) << 8);
+
+       return 0;
+}
+
+static int l64781_sleep(struct dvb_frontend* fe)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       /* Power down */
+       return l64781_writereg (state, 0x3e, 0x5a);
+}
+
+static int l64781_init(struct dvb_frontend* fe)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+
+       reset_and_configure (state);
+
+       /* Power up */
+       l64781_writereg (state, 0x3e, 0xa5);
+
+       /* Reset hard */
+       l64781_writereg (state, 0x2a, 0x04);
+       l64781_writereg (state, 0x2a, 0x00);
+
+       /* Set tuner specific things */
+       /* AFC_POL, set also in reset_afc */
+       l64781_writereg (state, 0x07, 0x8e);
+
+       /* Use internal ADC */
+       l64781_writereg (state, 0x0b, 0x81);
+
+       /* AGC loop gain, and polarity is positive */
+       l64781_writereg (state, 0x0c, 0x84);
+
+       /* Internal ADC outputs two's complement */
+       l64781_writereg (state, 0x0d, 0x8c);
+
+       /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
+          value of 2 with all possible bandwidths and guard
+          intervals, which is the initial value anyway. */
+       /*l64781_writereg (state, 0x19, 0x92);*/
+
+       /* Everything is two's complement, soft bit and CSI_OUT too */
+       l64781_writereg (state, 0x1e, 0x09);
+
+       /* delay a bit after first init attempt */
+       if (state->first) {
+               state->first = 0;
+               msleep(200);
+       }
+
+       return 0;
+}
+
+static int l64781_get_tune_settings(struct dvb_frontend* fe,
+                                   struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 4000;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void l64781_release(struct dvb_frontend* fe)
+{
+       struct l64781_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops l64781_ops;
+
+struct dvb_frontend* l64781_attach(const struct l64781_config* config,
+                                  struct i2c_adapter* i2c)
+{
+       struct l64781_state* state = NULL;
+       int reg0x3e = -1;
+       u8 b0 [] = { 0x1a };
+       u8 b1 [] = { 0x00 };
+       struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                          { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->first = 1;
+
+       /**
+        *  the L64781 won't show up before we send the reset_and_configure()
+        *  broadcast. If nothing responds there is no L64781 on the bus...
+        */
+       if (reset_and_configure(state) < 0) {
+               dprintk("No response to reset and configure broadcast...\n");
+               goto error;
+       }
+
+       /* The chip always responds to reads */
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               dprintk("No response to read on I2C bus\n");
+               goto error;
+       }
+
+       /* Save current register contents for bailout */
+       reg0x3e = l64781_readreg(state, 0x3e);
+
+       /* Reading the POWER_DOWN register always returns 0 */
+       if (reg0x3e != 0) {
+               dprintk("Device doesn't look like L64781\n");
+               goto error;
+       }
+
+       /* Turn the chip off */
+       l64781_writereg (state, 0x3e, 0x5a);
+
+       /* Responds to all reads with 0 */
+       if (l64781_readreg(state, 0x1a) != 0) {
+               dprintk("Read 1 returned unexpcted value\n");
+               goto error;
+       }
+
+       /* Turn the chip on */
+       l64781_writereg (state, 0x3e, 0xa5);
+
+       /* Responds with register default value */
+       if (l64781_readreg(state, 0x1a) != 0xa1) {
+               dprintk("Read 2 returned unexpcted value\n");
+               goto error;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       if (reg0x3e >= 0)
+               l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops l64781_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "LSI L64781 DVB-T",
+       /*      .frequency_min = ???,*/
+       /*      .frequency_max = ???,*/
+               .frequency_stepsize = 166666,
+       /*      .frequency_tolerance = ???,*/
+       /*      .symbol_rate_tolerance = ???,*/
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                     FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                     FE_CAN_MUTE_TS
+       },
+
+       .release = l64781_release,
+
+       .init = l64781_init,
+       .sleep = l64781_sleep,
+
+       .set_frontend = apply_frontend_param,
+       .get_frontend = get_frontend,
+       .get_tune_settings = l64781_get_tune_settings,
+
+       .read_status = l64781_read_status,
+       .read_ber = l64781_read_ber,
+       .read_signal_strength = l64781_read_signal_strength,
+       .read_snr = l64781_read_snr,
+       .read_ucblocks = l64781_read_ucblocks,
+};
+
+MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
+MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb-frontends/l64781.h b/drivers/media/dvb-frontends/l64781.h
new file mode 100644 (file)
index 0000000..1305a9e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    driver for LSI L64781 COFDM demodulator
+
+    Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
+                      Marko Kohtala <marko.kohtala@luukku.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef L64781_H
+#define L64781_H
+
+#include <linux/dvb/frontend.h>
+
+struct l64781_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE))
+extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
+                                         struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
+                                         struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_L64781
+
+#endif // L64781_H
diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c
new file mode 100644 (file)
index 0000000..cc11260
--- /dev/null
@@ -0,0 +1,1468 @@
+/*
+ *    Support for LG2160 - ATSC/MH
+ *
+ *    Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/jiffies.h>
+#include <linux/dvb/frontend.h>
+#include "lg2160.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG  2
+
+#define lg_printk(kern, fmt, arg...)                                   \
+       printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...)   printk(KERN_INFO "lg2160: " fmt, ##arg)
+#define lg_warn(fmt, arg...)   lg_printk(KERN_WARNING,       fmt, ##arg)
+#define lg_err(fmt, arg...)    lg_printk(KERN_ERR,           fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)                      \
+                               lg_printk(KERN_DEBUG,         fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG)                       \
+                               lg_printk(KERN_DEBUG,         fmt, ##arg)
+
+#define lg_fail(ret)                                                   \
+({                                                                     \
+       int __ret;                                                      \
+       __ret = (ret < 0);                                              \
+       if (__ret)                                                      \
+               lg_err("error %d on line %d\n", ret, __LINE__);         \
+       __ret;                                                          \
+})
+
+struct lg216x_state {
+       struct i2c_adapter *i2c_adap;
+       const struct lg2160_config *cfg;
+
+       struct dvb_frontend frontend;
+
+       u32 current_frequency;
+       u8 parade_id;
+       u8 fic_ver;
+       unsigned int last_reset;
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val)
+{
+       int ret;
+       u8 buf[] = { reg >> 8, reg & 0xff, val };
+       struct i2c_msg msg = {
+               .addr = state->cfg->i2c_addr, .flags = 0,
+               .buf = buf, .len = 3,
+       };
+
+       lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+       ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+       if (ret != 1) {
+               lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+                      msg.buf[0], msg.buf[1], msg.buf[2], ret);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val)
+{
+       int ret;
+       u8 reg_buf[] = { reg >> 8, reg & 0xff };
+       struct i2c_msg msg[] = {
+               { .addr = state->cfg->i2c_addr,
+                 .flags = 0, .buf = reg_buf, .len = 2 },
+               { .addr = state->cfg->i2c_addr,
+                 .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       lg_reg("reg: 0x%04x\n", reg);
+
+       ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+       if (ret != 2) {
+               lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+                      state->cfg->i2c_addr, reg, ret);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EREMOTEIO;
+       }
+       return 0;
+}
+
+struct lg216x_reg {
+       u16 reg;
+       u8 val;
+};
+
+static int lg216x_write_regs(struct lg216x_state *state,
+                            struct lg216x_reg *regs, int len)
+{
+       int i, ret;
+
+       lg_reg("writing %d registers...\n", len);
+
+       for (i = 0; i < len; i++) {
+               ret = lg216x_write_reg(state, regs[i].reg, regs[i].val);
+               if (lg_fail(ret))
+                       return ret;
+       }
+       return 0;
+}
+
+static int lg216x_set_reg_bit(struct lg216x_state *state,
+                             u16 reg, int bit, int onoff)
+{
+       u8 val;
+       int ret;
+
+       lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+       ret = lg216x_read_reg(state, reg, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= ~(1 << bit);
+       val |= (onoff & 1) << bit;
+
+       ret = lg216x_write_reg(state, reg, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       int ret;
+
+       if (state->cfg->deny_i2c_rptr)
+               return 0;
+
+       lg_dbg("(%d)\n", enable);
+
+       ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1);
+
+       msleep(1);
+
+       return ret;
+}
+
+static int lg216x_soft_reset(struct lg216x_state *state)
+{
+       int ret;
+
+       lg_dbg("\n");
+
+       ret = lg216x_write_reg(state, 0x0002, 0x00);
+       if (lg_fail(ret))
+               goto fail;
+
+       msleep(20);
+       ret = lg216x_write_reg(state, 0x0002, 0x01);
+       if (lg_fail(ret))
+               goto fail;
+
+       state->last_reset = jiffies_to_msecs(jiffies);
+fail:
+       return ret;
+}
+
+static int lg216x_initialize(struct lg216x_state *state)
+{
+       int ret;
+
+       static struct lg216x_reg lg2160_init[] = {
+#if 0
+               { .reg = 0x0015, .val = 0xe6 },
+#else
+               { .reg = 0x0015, .val = 0xf7 },
+               { .reg = 0x001b, .val = 0x52 },
+               { .reg = 0x0208, .val = 0x00 },
+               { .reg = 0x0209, .val = 0x82 },
+               { .reg = 0x0210, .val = 0xf9 },
+               { .reg = 0x020a, .val = 0x00 },
+               { .reg = 0x020b, .val = 0x82 },
+               { .reg = 0x020d, .val = 0x28 },
+               { .reg = 0x020f, .val = 0x14 },
+#endif
+       };
+
+       static struct lg216x_reg lg2161_init[] = {
+               { .reg = 0x0000, .val = 0x41 },
+               { .reg = 0x0001, .val = 0xfb },
+               { .reg = 0x0216, .val = 0x00 },
+               { .reg = 0x0219, .val = 0x00 },
+               { .reg = 0x021b, .val = 0x55 },
+               { .reg = 0x0606, .val = 0x0a },
+       };
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_write_regs(state,
+                                       lg2160_init, ARRAY_SIZE(lg2160_init));
+               break;
+       case LG2161:
+               ret = lg216x_write_regs(state,
+                                       lg2161_init, ARRAY_SIZE(lg2161_init));
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_soft_reset(state);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_set_if(struct lg216x_state *state)
+{
+       u8 val;
+       int ret;
+
+       lg_dbg("%d KHz\n", state->cfg->if_khz);
+
+       ret = lg216x_read_reg(state, 0x0132, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xfb;
+       val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0132, val);
+       lg_fail(ret);
+
+       /* if NOT zero IF, 6 MHz is the default */
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg2160_agc_fix(struct lg216x_state *state,
+                         int if_agc_fix, int rf_agc_fix)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0100, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xf3;
+       val |= (if_agc_fix) ? 0x08 : 0x00;
+       val |= (rf_agc_fix) ? 0x04 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0100, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+#if 0
+static int lg2160_agc_freeze(struct lg216x_state *state,
+                            int if_agc_freeze, int rf_agc_freeze)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0100, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xcf;
+       val |= (if_agc_freeze) ? 0x20 : 0x00;
+       val |= (rf_agc_freeze) ? 0x10 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0100, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+#endif
+
+static int lg2160_agc_polarity(struct lg216x_state *state,
+                              int if_agc_polarity, int rf_agc_polarity)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0100, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xfc;
+       val |= (if_agc_polarity) ? 0x02 : 0x00;
+       val |= (rf_agc_polarity) ? 0x01 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0100, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state,
+                                         int polarity)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0008, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xfe;
+       val |= (polarity) ? 0x01 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0008, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg2160_spectrum_polarity(struct lg216x_state *state,
+                                   int inverted)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0132, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xfd;
+       val |= (inverted) ? 0x02 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0132, val);
+       lg_fail(ret);
+fail:
+       return lg216x_soft_reset(state);
+}
+
+static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0007, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xbf;
+       val |= (onoff) ? 0x40 : 0x00;
+
+       ret = lg216x_write_reg(state, 0x0007, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg216x_set_parade(struct lg216x_state *state, int id)
+{
+       int ret;
+
+       ret = lg216x_write_reg(state, 0x013e, id & 0x7f);
+       if (lg_fail(ret))
+               goto fail;
+
+       state->parade_id = id & 0x7f;
+fail:
+       return ret;
+}
+
+static int lg216x_set_ensemble(struct lg216x_state *state, int id)
+{
+       int ret;
+       u16 reg;
+       u8 val;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               reg = 0x0400;
+               break;
+       case LG2161:
+       default:
+               reg = 0x0500;
+               break;
+       }
+
+       ret = lg216x_read_reg(state, reg, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xfe;
+       val |= (id) ? 0x01 : 0x00;
+
+       ret = lg216x_write_reg(state, reg, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg2160_set_spi_clock(struct lg216x_state *state)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0014, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0xf3;
+       val |= (state->cfg->spi_clock << 2);
+
+       ret = lg216x_write_reg(state, 0x0014, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg2161_set_output_interface(struct lg216x_state *state)
+{
+       u8 val;
+       int ret;
+
+       ret = lg216x_read_reg(state, 0x0014, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= ~0x07;
+       val |= state->cfg->output_if; /* FIXME: needs sanity check */
+
+       ret = lg216x_write_reg(state, 0x0014, val);
+       lg_fail(ret);
+fail:
+       return ret;
+}
+
+static int lg216x_enable_fic(struct lg216x_state *state, int onoff)
+{
+       int ret;
+
+       ret = lg216x_write_reg(state, 0x0017, 0x23);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_write_reg(state, 0x0016, 0xfc);
+       if (lg_fail(ret))
+               goto fail;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_write_reg(state, 0x0016,
+                                      0xfc | ((onoff) ? 0x02 : 0x00));
+               break;
+       case LG2161:
+               ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00);
+               break;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_initialize(state);
+       if (lg_fail(ret))
+               goto fail;
+
+       if (onoff) {
+               ret = lg216x_write_reg(state, 0x0017, 0x03);
+               lg_fail(ret);
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver)
+{
+       u8 val;
+       int ret;
+
+       *ficver = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0128, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *ficver = (val >> 3) & 0x1f;
+fail:
+       return ret;
+}
+
+#if 0
+static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id)
+{
+       u8 val;
+       int ret;
+
+       *id = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0123, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *id = val & 0x7f;
+fail:
+       return ret;
+}
+#endif
+
+static int lg216x_get_nog(struct lg216x_state *state, u8 *nog)
+{
+       u8 val;
+       int ret;
+
+       *nog = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0124, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *nog = ((val >> 4) & 0x07) + 1;
+fail:
+       return ret;
+}
+
+static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog)
+{
+       u8 val;
+       int ret;
+
+       *tnog = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0125, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *tnog = val & 0x1f;
+fail:
+       return ret;
+}
+
+static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn)
+{
+       u8 val;
+       int ret;
+
+       *sgn = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0124, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *sgn = val & 0x0f;
+fail:
+       return ret;
+}
+
+static int lg216x_get_prc(struct lg216x_state *state, u8 *prc)
+{
+       u8 val;
+       int ret;
+
+       *prc = 0xff; /* invalid value */
+
+       ret = lg216x_read_reg(state, 0x0125, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *prc = ((val >> 5) & 0x07) + 1;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_get_rs_frame_mode(struct lg216x_state *state,
+                                   enum atscmh_rs_frame_mode *rs_framemode)
+{
+       u8 val;
+       int ret;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0410, &val);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x0513, &val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       switch ((val >> 4) & 0x03) {
+#if 1
+       default:
+#endif
+       case 0x00:
+               *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY;
+               break;
+       case 0x01:
+               *rs_framemode = ATSCMH_RSFRAME_PRI_SEC;
+               break;
+#if 0
+       default:
+               *rs_framemode = ATSCMH_RSFRAME_RES;
+               break;
+#endif
+       }
+fail:
+       return ret;
+}
+
+static
+int lg216x_get_rs_frame_ensemble(struct lg216x_state *state,
+                                enum atscmh_rs_frame_ensemble *rs_frame_ens)
+{
+       u8 val;
+       int ret;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0400, &val);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x0500, &val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= 0x01;
+       *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val;
+fail:
+       return ret;
+}
+
+static int lg216x_get_rs_code_mode(struct lg216x_state *state,
+                                  enum atscmh_rs_code_mode *rs_code_pri,
+                                  enum atscmh_rs_code_mode *rs_code_sec)
+{
+       u8 val;
+       int ret;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0410, &val);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x0513, &val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03);
+       *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03);
+fail:
+       return ret;
+}
+
+static int lg216x_get_sccc_block_mode(struct lg216x_state *state,
+                                     enum atscmh_sccc_block_mode *sccc_block)
+{
+       u8 val;
+       int ret;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0315, &val);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x0511, &val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       switch (val & 0x03) {
+       case 0x00:
+               *sccc_block = ATSCMH_SCCC_BLK_SEP;
+               break;
+       case 0x01:
+               *sccc_block = ATSCMH_SCCC_BLK_COMB;
+               break;
+       default:
+               *sccc_block = ATSCMH_SCCC_BLK_RES;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static int lg216x_get_sccc_code_mode(struct lg216x_state *state,
+                                    enum atscmh_sccc_code_mode *mode_a,
+                                    enum atscmh_sccc_code_mode *mode_b,
+                                    enum atscmh_sccc_code_mode *mode_c,
+                                    enum atscmh_sccc_code_mode *mode_d)
+{
+       u8 val;
+       int ret;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0316, &val);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x0512, &val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       switch ((val >> 6) & 0x03) {
+       case 0x00:
+               *mode_a = ATSCMH_SCCC_CODE_HLF;
+               break;
+       case 0x01:
+               *mode_a = ATSCMH_SCCC_CODE_QTR;
+               break;
+       default:
+               *mode_a = ATSCMH_SCCC_CODE_RES;
+               break;
+       }
+
+       switch ((val >> 4) & 0x03) {
+       case 0x00:
+               *mode_b = ATSCMH_SCCC_CODE_HLF;
+               break;
+       case 0x01:
+               *mode_b = ATSCMH_SCCC_CODE_QTR;
+               break;
+       default:
+               *mode_b = ATSCMH_SCCC_CODE_RES;
+               break;
+       }
+
+       switch ((val >> 2) & 0x03) {
+       case 0x00:
+               *mode_c = ATSCMH_SCCC_CODE_HLF;
+               break;
+       case 0x01:
+               *mode_c = ATSCMH_SCCC_CODE_QTR;
+               break;
+       default:
+               *mode_c = ATSCMH_SCCC_CODE_RES;
+               break;
+       }
+
+       switch (val & 0x03) {
+       case 0x00:
+               *mode_d = ATSCMH_SCCC_CODE_HLF;
+               break;
+       case 0x01:
+               *mode_d = ATSCMH_SCCC_CODE_QTR;
+               break;
+       default:
+               *mode_d = ATSCMH_SCCC_CODE_RES;
+               break;
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err)
+{
+       u8 fic_err;
+       int ret;
+
+       *err = 0;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg216x_read_reg(state, 0x0012, &fic_err);
+               break;
+       case LG2161:
+               ret = lg216x_read_reg(state, 0x001e, &fic_err);
+               break;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       *err = fic_err;
+fail:
+       return ret;
+}
+
+static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err)
+{
+       u8 crc_err1, crc_err2;
+       int ret;
+
+       *err = 0;
+
+       ret = lg216x_read_reg(state, 0x0411, &crc_err1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_read_reg(state, 0x0412, &crc_err2);
+       if (lg_fail(ret))
+               goto fail;
+
+       *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1);
+fail:
+       return ret;
+}
+
+static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err)
+{
+       u8 crc_err;
+       int ret;
+
+       *err = 0;
+
+       ret = lg216x_read_reg(state, 0x0612, &crc_err);
+       if (lg_fail(ret))
+               goto fail;
+
+       *err = (u16)crc_err;
+fail:
+       return ret;
+}
+
+static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err)
+{
+       int ret;
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg2160_read_crc_err_count(state, err);
+               break;
+       case LG2161:
+               ret = lg2161_read_crc_err_count(state, err);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err)
+{
+       u8 rs_err1, rs_err2;
+       int ret;
+
+       *err = 0;
+
+       ret = lg216x_read_reg(state, 0x0413, &rs_err1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_read_reg(state, 0x0414, &rs_err2);
+       if (lg_fail(ret))
+               goto fail;
+
+       *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1);
+fail:
+       return ret;
+}
+
+static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err)
+{
+       u8 rs_err1, rs_err2;
+       int ret;
+
+       *err = 0;
+
+       ret = lg216x_read_reg(state, 0x0613, &rs_err1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_read_reg(state, 0x0614, &rs_err2);
+       if (lg_fail(ret))
+               goto fail;
+
+       *err = (u16)((rs_err1 << 8) | rs_err2);
+fail:
+       return ret;
+}
+
+static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err)
+{
+       int ret;
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg2160_read_rs_err_count(state, err);
+               break;
+       case LG2161:
+               ret = lg2161_read_rs_err_count(state, err);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_get_frontend(struct dvb_frontend *fe)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       int ret;
+
+       lg_dbg("\n");
+
+       fe->dtv_property_cache.modulation = VSB_8;
+       fe->dtv_property_cache.frequency = state->current_frequency;
+       fe->dtv_property_cache.delivery_system = SYS_ATSCMH;
+
+       ret = lg216x_get_fic_version(state,
+                                    &fe->dtv_property_cache.atscmh_fic_ver);
+       if (lg_fail(ret))
+               goto fail;
+       if (state->fic_ver != fe->dtv_property_cache.atscmh_fic_ver) {
+               state->fic_ver = fe->dtv_property_cache.atscmh_fic_ver;
+
+#if 0
+               ret = lg2160_get_parade_id(state,
+                               &fe->dtv_property_cache.atscmh_parade_id);
+               if (lg_fail(ret))
+                       goto fail;
+/* #else */
+               fe->dtv_property_cache.atscmh_parade_id = state->parade_id;
+#endif
+               ret = lg216x_get_nog(state,
+                                    &fe->dtv_property_cache.atscmh_nog);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_tnog(state,
+                                     &fe->dtv_property_cache.atscmh_tnog);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_sgn(state,
+                                    &fe->dtv_property_cache.atscmh_sgn);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_prc(state,
+                                    &fe->dtv_property_cache.atscmh_prc);
+               if (lg_fail(ret))
+                       goto fail;
+
+               ret = lg216x_get_rs_frame_mode(state,
+                       (enum atscmh_rs_frame_mode *)
+                       &fe->dtv_property_cache.atscmh_rs_frame_mode);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_rs_frame_ensemble(state,
+                       (enum atscmh_rs_frame_ensemble *)
+                       &fe->dtv_property_cache.atscmh_rs_frame_ensemble);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_rs_code_mode(state,
+                       (enum atscmh_rs_code_mode *)
+                       &fe->dtv_property_cache.atscmh_rs_code_mode_pri,
+                       (enum atscmh_rs_code_mode *)
+                       &fe->dtv_property_cache.atscmh_rs_code_mode_sec);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_sccc_block_mode(state,
+                       (enum atscmh_sccc_block_mode *)
+                       &fe->dtv_property_cache.atscmh_sccc_block_mode);
+               if (lg_fail(ret))
+                       goto fail;
+               ret = lg216x_get_sccc_code_mode(state,
+                       (enum atscmh_sccc_code_mode *)
+                       &fe->dtv_property_cache.atscmh_sccc_code_mode_a,
+                       (enum atscmh_sccc_code_mode *)
+                       &fe->dtv_property_cache.atscmh_sccc_code_mode_b,
+                       (enum atscmh_sccc_code_mode *)
+                       &fe->dtv_property_cache.atscmh_sccc_code_mode_c,
+                       (enum atscmh_sccc_code_mode *)
+                       &fe->dtv_property_cache.atscmh_sccc_code_mode_d);
+               if (lg_fail(ret))
+                       goto fail;
+       }
+#if 0
+       ret = lg216x_read_fic_err_count(state,
+                               (u8 *)&fe->dtv_property_cache.atscmh_fic_err);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg216x_read_crc_err_count(state,
+                               &fe->dtv_property_cache.atscmh_crc_err);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg216x_read_rs_err_count(state,
+                               &fe->dtv_property_cache.atscmh_rs_err);
+       if (lg_fail(ret))
+               goto fail;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               if (((fe->dtv_property_cache.atscmh_rs_err >= 240) &&
+                    (fe->dtv_property_cache.atscmh_crc_err >= 240)) &&
+                   ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000))
+                       ret = lg216x_soft_reset(state);
+               break;
+       case LG2161:
+               /* no fix needed here (as far as we know) */
+               ret = 0;
+               break;
+       }
+       lg_fail(ret);
+#endif
+fail:
+       return ret;
+}
+
+static int lg216x_get_property(struct dvb_frontend *fe,
+                              struct dtv_property *tvp)
+{
+       return (DTV_ATSCMH_FIC_VER == tvp->cmd) ?
+               lg216x_get_frontend(fe) : 0;
+}
+
+
+static int lg2160_set_frontend(struct dvb_frontend *fe)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       int ret;
+
+       lg_dbg("(%d)\n", fe->dtv_property_cache.frequency);
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+               if (lg_fail(ret))
+                       goto fail;
+               state->current_frequency = fe->dtv_property_cache.frequency;
+       }
+
+       ret = lg2160_agc_fix(state, 0, 0);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg2160_agc_polarity(state, 0, 0);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg2160_tuner_pwr_save_polarity(state, 1);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg216x_set_if(state);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion);
+       if (lg_fail(ret))
+               goto fail;
+
+       /* be tuned before this point */
+       ret = lg216x_soft_reset(state);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg2160_tuner_pwr_save(state, 0);
+       if (lg_fail(ret))
+               goto fail;
+
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg2160_set_spi_clock(state);
+               if (lg_fail(ret))
+                       goto fail;
+               break;
+       case LG2161:
+               ret = lg2161_set_output_interface(state);
+               if (lg_fail(ret))
+                       goto fail;
+               break;
+       }
+
+       ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_set_ensemble(state,
+                       fe->dtv_property_cache.atscmh_rs_frame_ensemble);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_initialize(state);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_enable_fic(state, 1);
+       lg_fail(ret);
+
+       lg216x_get_frontend(fe);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg2160_read_lock_status(struct lg216x_state *state,
+                                  int *acq_lock, int *sync_lock)
+{
+       u8 val;
+       int ret;
+
+       *acq_lock = 0;
+       *sync_lock = 0;
+
+       ret = lg216x_read_reg(state, 0x011b, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *sync_lock = (val & 0x20) ? 0 : 1;
+       *acq_lock  = (val & 0x40) ? 0 : 1;
+fail:
+       return ret;
+}
+
+#ifdef USE_LG2161_LOCK_BITS
+static int lg2161_read_lock_status(struct lg216x_state *state,
+                                  int *acq_lock, int *sync_lock)
+{
+       u8 val;
+       int ret;
+
+       *acq_lock = 0;
+       *sync_lock = 0;
+
+       ret = lg216x_read_reg(state, 0x0304, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *sync_lock = (val & 0x80) ? 0 : 1;
+
+       ret = lg216x_read_reg(state, 0x011b, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       *acq_lock  = (val & 0x40) ? 0 : 1;
+fail:
+       return ret;
+}
+#endif
+
+static int lg216x_read_lock_status(struct lg216x_state *state,
+                                  int *acq_lock, int *sync_lock)
+{
+#ifdef USE_LG2161_LOCK_BITS
+       int ret;
+       switch (state->cfg->lg_chip) {
+       case LG2160:
+               ret = lg2160_read_lock_status(state, acq_lock, sync_lock);
+               break;
+       case LG2161:
+               ret = lg2161_read_lock_status(state, acq_lock, sync_lock);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+#else
+       return lg2160_read_lock_status(state, acq_lock, sync_lock);
+#endif
+}
+
+static int lg216x_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       int ret, acq_lock, sync_lock;
+
+       *status = 0;
+
+       ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock);
+       if (lg_fail(ret))
+               goto fail;
+
+       lg_dbg("%s%s\n",
+              acq_lock  ? "SIGNALEXIST " : "",
+              sync_lock ? "SYNCLOCK"     : "");
+
+       if (acq_lock)
+               *status |= FE_HAS_SIGNAL;
+       if (sync_lock)
+               *status |= FE_HAS_SYNC;
+
+       if (*status)
+               *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
+
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       u8 snr1, snr2;
+       int ret;
+
+       *snr = 0;
+
+       ret = lg216x_read_reg(state, 0x0202, &snr1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_read_reg(state, 0x0203, &snr2);
+       if (lg_fail(ret))
+               goto fail;
+
+       if ((snr1 == 0xba) || (snr2 == 0xdf))
+               *snr = 0;
+       else
+#if 1
+       *snr =  ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4);
+#else /* BCD */
+       *snr =  (snr2 | (snr1 << 8));
+#endif
+fail:
+       return ret;
+}
+
+static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       u8 snr1, snr2;
+       int ret;
+
+       *snr = 0;
+
+       ret = lg216x_read_reg(state, 0x0302, &snr1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lg216x_read_reg(state, 0x0303, &snr2);
+       if (lg_fail(ret))
+               goto fail;
+
+       if ((snr1 == 0xba) || (snr2 == 0xfd))
+               *snr = 0;
+       else
+
+       *snr =  ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f);
+fail:
+       return ret;
+}
+
+static int lg216x_read_signal_strength(struct dvb_frontend *fe,
+                                      u16 *strength)
+{
+#if 0
+       /* borrowed from lgdt330x.c
+        *
+        * Calculate strength from SNR up to 35dB
+        * Even though the SNR can go higher than 35dB,
+        * there is some comfort factor in having a range of
+        * strong signals that can show at 100%
+        */
+       struct lg216x_state *state = fe->demodulator_priv;
+       u16 snr;
+       int ret;
+#endif
+       *strength = 0;
+#if 0
+       ret = fe->ops.read_snr(fe, &snr);
+       if (lg_fail(ret))
+               goto fail;
+       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+       /* scale the range 0 - 35*2^24 into 0 - 65535 */
+       if (state->snr >= 8960 * 0x10000)
+               *strength = 0xffff;
+       else
+               *strength = state->snr / 8960;
+fail:
+       return ret;
+#else
+       return 0;
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+#if 0
+       struct lg216x_state *state = fe->demodulator_priv;
+       int ret;
+
+       ret = lg216x_read_rs_err_count(state,
+                                      &fe->dtv_property_cache.atscmh_rs_err);
+       if (lg_fail(ret))
+               goto fail;
+
+       *ucblocks = fe->dtv_property_cache.atscmh_rs_err;
+fail:
+#else
+       *ucblocks = 0;
+#endif
+       return 0;
+}
+
+static int lg216x_get_tune_settings(struct dvb_frontend *fe,
+                                   struct dvb_frontend_tune_settings
+                                   *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 500;
+       lg_dbg("\n");
+       return 0;
+}
+
+static void lg216x_release(struct dvb_frontend *fe)
+{
+       struct lg216x_state *state = fe->demodulator_priv;
+       lg_dbg("\n");
+       kfree(state);
+}
+
+static struct dvb_frontend_ops lg2160_ops = {
+       .delsys = { SYS_ATSCMH },
+       .info = {
+               .name = "LG Electronics LG2160 ATSC/MH Frontend",
+               .frequency_min      = 54000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 62500,
+       },
+       .i2c_gate_ctrl        = lg216x_i2c_gate_ctrl,
+#if 0
+       .init                 = lg216x_init,
+       .sleep                = lg216x_sleep,
+#endif
+       .get_property         = lg216x_get_property,
+
+       .set_frontend         = lg2160_set_frontend,
+       .get_frontend         = lg216x_get_frontend,
+       .get_tune_settings    = lg216x_get_tune_settings,
+       .read_status          = lg216x_read_status,
+#if 0
+       .read_ber             = lg216x_read_ber,
+#endif
+       .read_signal_strength = lg216x_read_signal_strength,
+       .read_snr             = lg2160_read_snr,
+       .read_ucblocks        = lg216x_read_ucblocks,
+       .release              = lg216x_release,
+};
+
+static struct dvb_frontend_ops lg2161_ops = {
+       .delsys = { SYS_ATSCMH },
+       .info = {
+               .name = "LG Electronics LG2161 ATSC/MH Frontend",
+               .frequency_min      = 54000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 62500,
+       },
+       .i2c_gate_ctrl        = lg216x_i2c_gate_ctrl,
+#if 0
+       .init                 = lg216x_init,
+       .sleep                = lg216x_sleep,
+#endif
+       .get_property         = lg216x_get_property,
+
+       .set_frontend         = lg2160_set_frontend,
+       .get_frontend         = lg216x_get_frontend,
+       .get_tune_settings    = lg216x_get_tune_settings,
+       .read_status          = lg216x_read_status,
+#if 0
+       .read_ber             = lg216x_read_ber,
+#endif
+       .read_signal_strength = lg216x_read_signal_strength,
+       .read_snr             = lg2161_read_snr,
+       .read_ucblocks        = lg216x_read_ucblocks,
+       .release              = lg216x_release,
+};
+
+struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
+                                  struct i2c_adapter *i2c_adap)
+{
+       struct lg216x_state *state = NULL;
+
+       lg_dbg("(%d-%04x)\n",
+              i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+              config ? config->i2c_addr : 0);
+
+       state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL);
+       if (state == NULL)
+               goto fail;
+
+       state->cfg = config;
+       state->i2c_adap = i2c_adap;
+       state->fic_ver = 0xff;
+       state->parade_id = 0xff;
+
+       switch (config->lg_chip) {
+       default:
+               lg_warn("invalid chip requested, defaulting to LG2160");
+               /* fall-thru */
+       case LG2160:
+               memcpy(&state->frontend.ops, &lg2160_ops,
+                      sizeof(struct dvb_frontend_ops));
+               break;
+       case LG2161:
+               memcpy(&state->frontend.ops, &lg2161_ops,
+                      sizeof(struct dvb_frontend_ops));
+               break;
+       }
+
+       state->frontend.demodulator_priv = state;
+       state->current_frequency = -1;
+       /* parade 1 by default */
+       state->frontend.dtv_property_cache.atscmh_parade_id = 1;
+
+       return &state->frontend;
+fail:
+       lg_warn("unable to detect LG216x hardware\n");
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(lg2160_attach);
+
+MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.3");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/lg2160.h b/drivers/media/dvb-frontends/lg2160.h
new file mode 100644 (file)
index 0000000..9e2c0f4
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *    Support for LG2160 - ATSC/MH
+ *
+ *    Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LG2160_H_
+#define _LG2160_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+enum lg_chip_type {
+       LG2160 = 0,
+       LG2161 = 1,
+};
+
+#define LG2161_1019 LG2161
+#define LG2161_1040 LG2161
+
+enum lg2160_spi_clock {
+       LG2160_SPI_3_125_MHZ = 0,
+       LG2160_SPI_6_25_MHZ = 1,
+       LG2160_SPI_12_5_MHZ = 2,
+};
+
+#if 0
+enum lg2161_oif {
+       LG2161_OIF_EBI2_SLA  = 1,
+       LG2161_OIF_SDIO_SLA  = 2,
+       LG2161_OIF_SPI_SLA   = 3,
+       LG2161_OIF_SPI_MAS   = 4,
+       LG2161_OIF_SERIAL_TS = 7,
+};
+#endif
+
+struct lg2160_config {
+       u8 i2c_addr;
+
+       /* user defined IF frequency in KHz */
+       u16 if_khz;
+
+       /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+       int deny_i2c_rptr:1;
+
+       /* spectral inversion - 0:disabled 1:enabled */
+       int spectral_inversion:1;
+
+       unsigned int output_if;
+       enum lg2160_spi_clock spi_clock;
+       enum lg_chip_type lg_chip;
+};
+
+#if defined(CONFIG_DVB_LG2160) || (defined(CONFIG_DVB_LG2160_MODULE) && \
+                                    defined(MODULE))
+extern
+struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
+                                    struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
+                                    struct i2c_adapter *i2c_adap)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_LG2160 */
+
+#endif /* _LG2160_H_ */
diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c
new file mode 100644 (file)
index 0000000..1d2c473
--- /dev/null
@@ -0,0 +1,1222 @@
+/*
+ *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
+ *
+ *    Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    LGDT3304 support by Jarod Wilson <jarod@redhat.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/div64.h>
+#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
+#include "dvb_math.h"
+#include "lgdt3305.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG  2
+
+#define lg_printk(kern, fmt, arg...)                                   \
+       printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...)   printk(KERN_INFO "lgdt3305: " fmt, ##arg)
+#define lg_warn(fmt, arg...)   lg_printk(KERN_WARNING,       fmt, ##arg)
+#define lg_err(fmt, arg...)    lg_printk(KERN_ERR,           fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)                      \
+                               lg_printk(KERN_DEBUG,         fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG)                       \
+                               lg_printk(KERN_DEBUG,         fmt, ##arg)
+
+#define lg_fail(ret)                                                   \
+({                                                                     \
+       int __ret;                                                      \
+       __ret = (ret < 0);                                              \
+       if (__ret)                                                      \
+               lg_err("error %d on line %d\n", ret, __LINE__);         \
+       __ret;                                                          \
+})
+
+struct lgdt3305_state {
+       struct i2c_adapter *i2c_adap;
+       const struct lgdt3305_config *cfg;
+
+       struct dvb_frontend frontend;
+
+       fe_modulation_t current_modulation;
+       u32 current_frequency;
+       u32 snr;
+};
+
+/* ------------------------------------------------------------------------ */
+
+/* FIXME: verify & document the LGDT3304 registers */
+
+#define LGDT3305_GEN_CTRL_1                   0x0000
+#define LGDT3305_GEN_CTRL_2                   0x0001
+#define LGDT3305_GEN_CTRL_3                   0x0002
+#define LGDT3305_GEN_STATUS                   0x0003
+#define LGDT3305_GEN_CONTROL                  0x0007
+#define LGDT3305_GEN_CTRL_4                   0x000a
+#define LGDT3305_DGTL_AGC_REF_1               0x0012
+#define LGDT3305_DGTL_AGC_REF_2               0x0013
+#define LGDT3305_CR_CTR_FREQ_1                0x0106
+#define LGDT3305_CR_CTR_FREQ_2                0x0107
+#define LGDT3305_CR_CTR_FREQ_3                0x0108
+#define LGDT3305_CR_CTR_FREQ_4                0x0109
+#define LGDT3305_CR_MSE_1                     0x011b
+#define LGDT3305_CR_MSE_2                     0x011c
+#define LGDT3305_CR_LOCK_STATUS               0x011d
+#define LGDT3305_CR_CTRL_7                    0x0126
+#define LGDT3305_AGC_POWER_REF_1              0x0300
+#define LGDT3305_AGC_POWER_REF_2              0x0301
+#define LGDT3305_AGC_DELAY_PT_1               0x0302
+#define LGDT3305_AGC_DELAY_PT_2               0x0303
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_1         0x0306
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_2         0x0307
+#define LGDT3305_IFBW_1                       0x0308
+#define LGDT3305_IFBW_2                       0x0309
+#define LGDT3305_AGC_CTRL_1                   0x030c
+#define LGDT3305_AGC_CTRL_4                   0x0314
+#define LGDT3305_EQ_MSE_1                     0x0413
+#define LGDT3305_EQ_MSE_2                     0x0414
+#define LGDT3305_EQ_MSE_3                     0x0415
+#define LGDT3305_PT_MSE_1                     0x0417
+#define LGDT3305_PT_MSE_2                     0x0418
+#define LGDT3305_PT_MSE_3                     0x0419
+#define LGDT3305_FEC_BLOCK_CTRL               0x0504
+#define LGDT3305_FEC_LOCK_STATUS              0x050a
+#define LGDT3305_FEC_PKT_ERR_1                0x050c
+#define LGDT3305_FEC_PKT_ERR_2                0x050d
+#define LGDT3305_TP_CTRL_1                    0x050e
+#define LGDT3305_BERT_PERIOD                  0x0801
+#define LGDT3305_BERT_ERROR_COUNT_1           0x080a
+#define LGDT3305_BERT_ERROR_COUNT_2           0x080b
+#define LGDT3305_BERT_ERROR_COUNT_3           0x080c
+#define LGDT3305_BERT_ERROR_COUNT_4           0x080d
+
+static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
+{
+       int ret;
+       u8 buf[] = { reg >> 8, reg & 0xff, val };
+       struct i2c_msg msg = {
+               .addr = state->cfg->i2c_addr, .flags = 0,
+               .buf = buf, .len = 3,
+       };
+
+       lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+       ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+       if (ret != 1) {
+               lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+                      msg.buf[0], msg.buf[1], msg.buf[2], ret);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
+{
+       int ret;
+       u8 reg_buf[] = { reg >> 8, reg & 0xff };
+       struct i2c_msg msg[] = {
+               { .addr = state->cfg->i2c_addr,
+                 .flags = 0, .buf = reg_buf, .len = 2 },
+               { .addr = state->cfg->i2c_addr,
+                 .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       lg_reg("reg: 0x%04x\n", reg);
+
+       ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+       if (ret != 2) {
+               lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+                      state->cfg->i2c_addr, reg, ret);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EREMOTEIO;
+       }
+       return 0;
+}
+
+#define read_reg(state, reg)                                           \
+({                                                                     \
+       u8 __val;                                                       \
+       int ret = lgdt3305_read_reg(state, reg, &__val);                \
+       if (lg_fail(ret))                                               \
+               __val = 0;                                              \
+       __val;                                                          \
+})
+
+static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
+                               u16 reg, int bit, int onoff)
+{
+       u8 val;
+       int ret;
+
+       lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+       ret = lgdt3305_read_reg(state, reg, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= ~(1 << bit);
+       val |= (onoff & 1) << bit;
+
+       ret = lgdt3305_write_reg(state, reg, val);
+fail:
+       return ret;
+}
+
+struct lgdt3305_reg {
+       u16 reg;
+       u8 val;
+};
+
+static int lgdt3305_write_regs(struct lgdt3305_state *state,
+                              struct lgdt3305_reg *regs, int len)
+{
+       int i, ret;
+
+       lg_reg("writing %d registers...\n", len);
+
+       for (i = 0; i < len - 1; i++) {
+               ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
+               if (lg_fail(ret))
+                       return ret;
+       }
+       return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_soft_reset(struct lgdt3305_state *state)
+{
+       int ret;
+
+       lg_dbg("\n");
+
+       ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
+       if (lg_fail(ret))
+               goto fail;
+
+       msleep(20);
+       ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
+fail:
+       return ret;
+}
+
+static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
+                                    enum lgdt3305_mpeg_mode mode)
+{
+       lg_dbg("(%d)\n", mode);
+       return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
+}
+
+static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
+                                      enum lgdt3305_tp_clock_edge edge,
+                                      enum lgdt3305_tp_valid_polarity valid)
+{
+       u8 val;
+       int ret;
+
+       lg_dbg("edge = %d, valid = %d\n", edge, valid);
+
+       ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       val &= ~0x09;
+
+       if (edge)
+               val |= 0x08;
+       if (valid)
+               val |= 0x01;
+
+       ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_soft_reset(state);
+fail:
+       return ret;
+}
+
+static int lgdt3305_set_modulation(struct lgdt3305_state *state,
+                                  struct dtv_frontend_properties *p)
+{
+       u8 opermode;
+       int ret;
+
+       lg_dbg("\n");
+
+       ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
+       if (lg_fail(ret))
+               goto fail;
+
+       opermode &= ~0x03;
+
+       switch (p->modulation) {
+       case VSB_8:
+               opermode |= 0x03;
+               break;
+       case QAM_64:
+               opermode |= 0x00;
+               break;
+       case QAM_256:
+               opermode |= 0x01;
+               break;
+       default:
+               return -EINVAL;
+       }
+       ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
+fail:
+       return ret;
+}
+
+static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
+                                        struct dtv_frontend_properties *p)
+{
+       int val;
+
+       switch (p->modulation) {
+       case VSB_8:
+               val = 0;
+               break;
+       case QAM_64:
+       case QAM_256:
+               val = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+       lg_dbg("val = %d\n", val);
+
+       return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
+                                        struct dtv_frontend_properties *p)
+{
+       u16 agc_ref;
+
+       switch (p->modulation) {
+       case VSB_8:
+               agc_ref = 0x32c4;
+               break;
+       case QAM_64:
+               agc_ref = 0x2a00;
+               break;
+       case QAM_256:
+               agc_ref = 0x2a80;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       lg_dbg("agc ref: 0x%04x\n", agc_ref);
+
+       lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
+       lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
+
+       return 0;
+}
+
+static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
+                              struct dtv_frontend_properties *p)
+{
+       u16 ifbw, rfbw, agcdelay;
+
+       switch (p->modulation) {
+       case VSB_8:
+               agcdelay = 0x04c0;
+               rfbw     = 0x8000;
+               ifbw     = 0x8000;
+               break;
+       case QAM_64:
+       case QAM_256:
+               agcdelay = 0x046b;
+               rfbw     = 0x8889;
+               /* FIXME: investigate optimal ifbw & rfbw values for the
+                *        DT3304 and re-write this switch..case block */
+               if (state->cfg->demod_chip == LGDT3304)
+                       ifbw = 0x6666;
+               else /* (state->cfg->demod_chip == LGDT3305) */
+                       ifbw = 0x8888;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (state->cfg->rf_agc_loop) {
+               lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
+
+               /* rf agc loop filter bandwidth */
+               lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
+                                  agcdelay >> 8);
+               lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
+                                  agcdelay & 0xff);
+
+               lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+                                  rfbw >> 8);
+               lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+                                  rfbw & 0xff);
+       } else {
+               lg_dbg("ifbw: 0x%04x\n", ifbw);
+
+               /* if agc loop filter bandwidth */
+               lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
+               lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
+       }
+
+       return 0;
+}
+
+static int lgdt3305_agc_setup(struct lgdt3305_state *state,
+                             struct dtv_frontend_properties *p)
+{
+       int lockdten, acqen;
+
+       switch (p->modulation) {
+       case VSB_8:
+               lockdten = 0;
+               acqen = 0;
+               break;
+       case QAM_64:
+       case QAM_256:
+               lockdten = 1;
+               acqen = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
+
+       /* control agc function */
+       switch (state->cfg->demod_chip) {
+       case LGDT3304:
+               lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
+               lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
+               break;
+       case LGDT3305:
+               lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+               lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return lgdt3305_rfagc_loop(state, p);
+}
+
+static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
+                                     struct dtv_frontend_properties *p)
+{
+       u16 usref = 0;
+
+       switch (p->modulation) {
+       case VSB_8:
+               if (state->cfg->usref_8vsb)
+                       usref = state->cfg->usref_8vsb;
+               break;
+       case QAM_64:
+               if (state->cfg->usref_qam64)
+                       usref = state->cfg->usref_qam64;
+               break;
+       case QAM_256:
+               if (state->cfg->usref_qam256)
+                       usref = state->cfg->usref_qam256;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (usref) {
+               lg_dbg("set manual mode: 0x%04x\n", usref);
+
+               lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
+
+               lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
+                                  0xff & (usref >> 8));
+               lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
+                                  0xff & (usref >> 0));
+       }
+       return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
+                                      struct dtv_frontend_properties *p,
+                                      int inversion)
+{
+       int ret;
+
+       lg_dbg("(%d)\n", inversion);
+
+       switch (p->modulation) {
+       case VSB_8:
+               ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
+                                        inversion ? 0xf9 : 0x79);
+               break;
+       case QAM_64:
+       case QAM_256:
+               ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
+                                        inversion ? 0xfd : 0xff);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       return ret;
+}
+
+static int lgdt3305_set_if(struct lgdt3305_state *state,
+                          struct dtv_frontend_properties *p)
+{
+       u16 if_freq_khz;
+       u8 nco1, nco2, nco3, nco4;
+       u64 nco;
+
+       switch (p->modulation) {
+       case VSB_8:
+               if_freq_khz = state->cfg->vsb_if_khz;
+               break;
+       case QAM_64:
+       case QAM_256:
+               if_freq_khz = state->cfg->qam_if_khz;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       nco = if_freq_khz / 10;
+
+       switch (p->modulation) {
+       case VSB_8:
+               nco <<= 24;
+               do_div(nco, 625);
+               break;
+       case QAM_64:
+       case QAM_256:
+               nco <<= 28;
+               do_div(nco, 625);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       nco1 = (nco >> 24) & 0x3f;
+       nco1 |= 0x40;
+       nco2 = (nco >> 16) & 0xff;
+       nco3 = (nco >> 8) & 0xff;
+       nco4 = nco & 0xff;
+
+       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
+       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
+       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
+       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
+
+       lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
+              if_freq_khz, nco1, nco2, nco3, nco4);
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+
+       if (state->cfg->deny_i2c_rptr)
+               return 0;
+
+       lg_dbg("(%d)\n", enable);
+
+       return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
+                                   enable ? 0 : 1);
+}
+
+static int lgdt3305_sleep(struct dvb_frontend *fe)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       u8 gen_ctrl_3, gen_ctrl_4;
+
+       lg_dbg("\n");
+
+       gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
+       gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
+
+       /* hold in software reset while sleeping */
+       gen_ctrl_3 &= ~0x01;
+       /* tristate the IF-AGC pin */
+       gen_ctrl_3 |=  0x02;
+       /* tristate the RF-AGC pin */
+       gen_ctrl_3 |=  0x04;
+
+       /* disable vsb/qam module */
+       gen_ctrl_4 &= ~0x01;
+       /* disable adc module */
+       gen_ctrl_4 &= ~0x02;
+
+       lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
+       lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
+
+       return 0;
+}
+
+static int lgdt3305_init(struct dvb_frontend *fe)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       int ret;
+
+       static struct lgdt3305_reg lgdt3304_init_data[] = {
+               { .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
+               { .reg = 0x000d,                        .val = 0x02, },
+               { .reg = 0x000e,                        .val = 0x02, },
+               { .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
+               { .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
+               { .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTRL_7,            .val = 0xf9, },
+               { .reg = 0x0112,                        .val = 0x17, },
+               { .reg = 0x0113,                        .val = 0x15, },
+               { .reg = 0x0114,                        .val = 0x18, },
+               { .reg = 0x0115,                        .val = 0xff, },
+               { .reg = 0x0116,                        .val = 0x3c, },
+               { .reg = 0x0214,                        .val = 0x67, },
+               { .reg = 0x0424,                        .val = 0x8d, },
+               { .reg = 0x0427,                        .val = 0x12, },
+               { .reg = 0x0428,                        .val = 0x4f, },
+               { .reg = LGDT3305_IFBW_1,               .val = 0x80, },
+               { .reg = LGDT3305_IFBW_2,               .val = 0x00, },
+               { .reg = 0x030a,                        .val = 0x08, },
+               { .reg = 0x030b,                        .val = 0x9b, },
+               { .reg = 0x030d,                        .val = 0x00, },
+               { .reg = 0x030e,                        .val = 0x1c, },
+               { .reg = 0x0314,                        .val = 0xe1, },
+               { .reg = 0x000d,                        .val = 0x82, },
+               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
+               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
+       };
+
+       static struct lgdt3305_reg lgdt3305_init_data[] = {
+               { .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
+               { .reg = LGDT3305_GEN_CTRL_2,           .val = 0xb0, },
+               { .reg = LGDT3305_GEN_CTRL_3,           .val = 0x01, },
+               { .reg = LGDT3305_GEN_CONTROL,          .val = 0x6f, },
+               { .reg = LGDT3305_GEN_CTRL_4,           .val = 0x03, },
+               { .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
+               { .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
+               { .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
+               { .reg = LGDT3305_CR_CTRL_7,            .val = 0x79, },
+               { .reg = LGDT3305_AGC_POWER_REF_1,      .val = 0x32, },
+               { .reg = LGDT3305_AGC_POWER_REF_2,      .val = 0xc4, },
+               { .reg = LGDT3305_AGC_DELAY_PT_1,       .val = 0x0d, },
+               { .reg = LGDT3305_AGC_DELAY_PT_2,       .val = 0x30, },
+               { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, },
+               { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, },
+               { .reg = LGDT3305_IFBW_1,               .val = 0x80, },
+               { .reg = LGDT3305_IFBW_2,               .val = 0x00, },
+               { .reg = LGDT3305_AGC_CTRL_1,           .val = 0x30, },
+               { .reg = LGDT3305_AGC_CTRL_4,           .val = 0x61, },
+               { .reg = LGDT3305_FEC_BLOCK_CTRL,       .val = 0xff, },
+               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x1b, },
+       };
+
+       lg_dbg("\n");
+
+       switch (state->cfg->demod_chip) {
+       case LGDT3304:
+               ret = lgdt3305_write_regs(state, lgdt3304_init_data,
+                                         ARRAY_SIZE(lgdt3304_init_data));
+               break;
+       case LGDT3305:
+               ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+                                         ARRAY_SIZE(lgdt3305_init_data));
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_soft_reset(state);
+fail:
+       return ret;
+}
+
+static int lgdt3304_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       int ret;
+
+       lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+               if (lg_fail(ret))
+                       goto fail;
+               state->current_frequency = p->frequency;
+       }
+
+       ret = lgdt3305_set_modulation(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_passband_digital_agc(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_agc_setup(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
+       switch (p->modulation) {
+       case VSB_8:
+               lgdt3305_write_reg(state, 0x030d, 0x00);
+               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
+               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
+               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
+               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
+               break;
+       case QAM_64:
+       case QAM_256:
+               lgdt3305_write_reg(state, 0x030d, 0x14);
+               ret = lgdt3305_set_if(state, p);
+               if (lg_fail(ret))
+                       goto fail;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+
+       ret = lgdt3305_spectral_inversion(state, p,
+                                         state->cfg->spectral_inversion
+                                         ? 1 : 0);
+       if (lg_fail(ret))
+               goto fail;
+
+       state->current_modulation = p->modulation;
+
+       ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+       if (lg_fail(ret))
+               goto fail;
+
+       /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+       ret = lgdt3305_mpeg_mode_polarity(state,
+                                         state->cfg->tpclk_edge,
+                                         state->cfg->tpvalid_polarity);
+fail:
+       return ret;
+}
+
+static int lgdt3305_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       int ret;
+
+       lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+               if (lg_fail(ret))
+                       goto fail;
+               state->current_frequency = p->frequency;
+       }
+
+       ret = lgdt3305_set_modulation(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_passband_digital_agc(state, p);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lgdt3305_set_agc_power_ref(state, p);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lgdt3305_agc_setup(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       /* low if */
+       ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_set_if(state, p);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lgdt3305_spectral_inversion(state, p,
+                                         state->cfg->spectral_inversion
+                                         ? 1 : 0);
+       if (lg_fail(ret))
+               goto fail;
+
+       ret = lgdt3305_set_filter_extension(state, p);
+       if (lg_fail(ret))
+               goto fail;
+
+       state->current_modulation = p->modulation;
+
+       ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+       if (lg_fail(ret))
+               goto fail;
+
+       /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+       ret = lgdt3305_mpeg_mode_polarity(state,
+                                         state->cfg->tpclk_edge,
+                                         state->cfg->tpvalid_polarity);
+fail:
+       return ret;
+}
+
+static int lgdt3305_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgdt3305_state *state = fe->demodulator_priv;
+
+       lg_dbg("\n");
+
+       p->modulation = state->current_modulation;
+       p->frequency = state->current_frequency;
+       return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
+                                       int *locked)
+{
+       u8 val;
+       int ret;
+       char *cr_lock_state = "";
+
+       *locked = 0;
+
+       ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       switch (state->current_modulation) {
+       case QAM_256:
+       case QAM_64:
+               if (val & (1 << 1))
+                       *locked = 1;
+
+               switch (val & 0x07) {
+               case 0:
+                       cr_lock_state = "QAM UNLOCK";
+                       break;
+               case 4:
+                       cr_lock_state = "QAM 1stLock";
+                       break;
+               case 6:
+                       cr_lock_state = "QAM 2ndLock";
+                       break;
+               case 7:
+                       cr_lock_state = "QAM FinalLock";
+                       break;
+               default:
+                       cr_lock_state = "CLOCKQAM-INVALID!";
+                       break;
+               }
+               break;
+       case VSB_8:
+               if (val & (1 << 7)) {
+                       *locked = 1;
+                       cr_lock_state = "CLOCKVSB";
+               }
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       lg_dbg("(%d) %s\n", *locked, cr_lock_state);
+fail:
+       return ret;
+}
+
+static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
+                                        int *locked)
+{
+       u8 val;
+       int ret, mpeg_lock, fec_lock, viterbi_lock;
+
+       *locked = 0;
+
+       switch (state->current_modulation) {
+       case QAM_256:
+       case QAM_64:
+               ret = lgdt3305_read_reg(state,
+                                       LGDT3305_FEC_LOCK_STATUS, &val);
+               if (lg_fail(ret))
+                       goto fail;
+
+               mpeg_lock    = (val & (1 << 0)) ? 1 : 0;
+               fec_lock     = (val & (1 << 2)) ? 1 : 0;
+               viterbi_lock = (val & (1 << 3)) ? 1 : 0;
+
+               *locked = mpeg_lock && fec_lock && viterbi_lock;
+
+               lg_dbg("(%d) %s%s%s\n", *locked,
+                      mpeg_lock    ? "mpeg lock  "  : "",
+                      fec_lock     ? "fec lock  "   : "",
+                      viterbi_lock ? "viterbi lock" : "");
+               break;
+       case VSB_8:
+       default:
+               ret = -EINVAL;
+       }
+fail:
+       return ret;
+}
+
+static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       u8 val;
+       int ret, signal, inlock, nofecerr, snrgood,
+               cr_lock, fec_lock, sync_lock;
+
+       *status = 0;
+
+       ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
+       if (lg_fail(ret))
+               goto fail;
+
+       signal    = (val & (1 << 4)) ? 1 : 0;
+       inlock    = (val & (1 << 3)) ? 0 : 1;
+       sync_lock = (val & (1 << 2)) ? 1 : 0;
+       nofecerr  = (val & (1 << 1)) ? 1 : 0;
+       snrgood   = (val & (1 << 0)) ? 1 : 0;
+
+       lg_dbg("%s%s%s%s%s\n",
+              signal    ? "SIGNALEXIST " : "",
+              inlock    ? "INLOCK "      : "",
+              sync_lock ? "SYNCLOCK "    : "",
+              nofecerr  ? "NOFECERR "    : "",
+              snrgood   ? "SNRGOOD "     : "");
+
+       ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
+       if (lg_fail(ret))
+               goto fail;
+
+       if (signal)
+               *status |= FE_HAS_SIGNAL;
+       if (cr_lock)
+               *status |= FE_HAS_CARRIER;
+       if (nofecerr)
+               *status |= FE_HAS_VITERBI;
+       if (sync_lock)
+               *status |= FE_HAS_SYNC;
+
+       switch (state->current_modulation) {
+       case QAM_256:
+       case QAM_64:
+               /* signal bit is unreliable on the DT3304 in QAM mode */
+               if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock))
+                       *status |= FE_HAS_SIGNAL;
+
+               ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
+               if (lg_fail(ret))
+                       goto fail;
+
+               if (fec_lock)
+                       *status |= FE_HAS_LOCK;
+               break;
+       case VSB_8:
+               if (inlock)
+                       *status |= FE_HAS_LOCK;
+               break;
+       default:
+               ret = -EINVAL;
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* borrowed from lgdt330x.c */
+static u32 calculate_snr(u32 mse, u32 c)
+{
+       if (mse == 0) /* no signal */
+               return 0;
+
+       mse = intlog10(mse);
+       if (mse > c) {
+               /* Negative SNR, which is possible, but realisticly the
+               demod will lose lock before the signal gets this bad.  The
+               API only allows for unsigned values, so just return 0 */
+               return 0;
+       }
+       return 10*(c - mse);
+}
+
+static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       u32 noise;      /* noise value */
+       u32 c;          /* per-modulation SNR calculation constant */
+
+       switch (state->current_modulation) {
+       case VSB_8:
+#ifdef USE_PTMSE
+               /* Use Phase Tracker Mean-Square Error Register */
+               /* SNR for ranges from -13.11 to +44.08 */
+               noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
+                       (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
+                       (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
+               c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+               /* Use Equalizer Mean-Square Error Register */
+               /* SNR for ranges from -16.12 to +44.08 */
+               noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
+                       (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
+                       (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
+               c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+               break;
+       case QAM_64:
+       case QAM_256:
+               noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
+                       (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
+
+               c = (state->current_modulation == QAM_64) ?
+                       97939837 : 98026066;
+               /* log10(688128)*2^24 and log10(696320)*2^24 */
+               break;
+       default:
+               return -EINVAL;
+       }
+       state->snr = calculate_snr(noise, c);
+       /* report SNR in dB * 10 */
+       *snr = (state->snr / ((1 << 24) / 10));
+       lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
+              state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+       return 0;
+}
+
+static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
+                                        u16 *strength)
+{
+       /* borrowed from lgdt330x.c
+        *
+        * Calculate strength from SNR up to 35dB
+        * Even though the SNR can go higher than 35dB,
+        * there is some comfort factor in having a range of
+        * strong signals that can show at 100%
+        */
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       u16 snr;
+       int ret;
+
+       *strength = 0;
+
+       ret = fe->ops.read_snr(fe, &snr);
+       if (lg_fail(ret))
+               goto fail;
+       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+       /* scale the range 0 - 35*2^24 into 0 - 65535 */
+       if (state->snr >= 8960 * 0x10000)
+               *strength = 0xffff;
+       else
+               *strength = state->snr / 8960;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       *ber = 0;
+       return 0;
+}
+
+static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+
+       *ucblocks =
+               (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
+               (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
+
+       return 0;
+}
+
+static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
+                                     struct dvb_frontend_tune_settings
+                                       *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 500;
+       lg_dbg("\n");
+       return 0;
+}
+
+static void lgdt3305_release(struct dvb_frontend *fe)
+{
+       struct lgdt3305_state *state = fe->demodulator_priv;
+       lg_dbg("\n");
+       kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3304_ops;
+static struct dvb_frontend_ops lgdt3305_ops;
+
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+                                    struct i2c_adapter *i2c_adap)
+{
+       struct lgdt3305_state *state = NULL;
+       int ret;
+       u8 val;
+
+       lg_dbg("(%d-%04x)\n",
+              i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+              config ? config->i2c_addr : 0);
+
+       state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
+       if (state == NULL)
+               goto fail;
+
+       state->cfg = config;
+       state->i2c_adap = i2c_adap;
+
+       switch (config->demod_chip) {
+       case LGDT3304:
+               memcpy(&state->frontend.ops, &lgdt3304_ops,
+                      sizeof(struct dvb_frontend_ops));
+               break;
+       case LGDT3305:
+               memcpy(&state->frontend.ops, &lgdt3305_ops,
+                      sizeof(struct dvb_frontend_ops));
+               break;
+       default:
+               goto fail;
+       }
+       state->frontend.demodulator_priv = state;
+
+       /* verify that we're talking to a lg dt3304/5 */
+       ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
+       if ((lg_fail(ret)) | (val == 0))
+               goto fail;
+       ret = lgdt3305_write_reg(state, 0x0808, 0x80);
+       if (lg_fail(ret))
+               goto fail;
+       ret = lgdt3305_read_reg(state, 0x0808, &val);
+       if ((lg_fail(ret)) | (val != 0x80))
+               goto fail;
+       ret = lgdt3305_write_reg(state, 0x0808, 0x00);
+       if (lg_fail(ret))
+               goto fail;
+
+       state->current_frequency = -1;
+       state->current_modulation = -1;
+
+       return &state->frontend;
+fail:
+       lg_warn("unable to detect %s hardware\n",
+               config->demod_chip ? "LGDT3304" : "LGDT3305");
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(lgdt3305_attach);
+
+static struct dvb_frontend_ops lgdt3304_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name = "LG Electronics LGDT3304 VSB/QAM Frontend",
+               .frequency_min      = 54000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+       .i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
+       .init                 = lgdt3305_init,
+       .set_frontend         = lgdt3304_set_parameters,
+       .get_frontend         = lgdt3305_get_frontend,
+       .get_tune_settings    = lgdt3305_get_tune_settings,
+       .read_status          = lgdt3305_read_status,
+       .read_ber             = lgdt3305_read_ber,
+       .read_signal_strength = lgdt3305_read_signal_strength,
+       .read_snr             = lgdt3305_read_snr,
+       .read_ucblocks        = lgdt3305_read_ucblocks,
+       .release              = lgdt3305_release,
+};
+
+static struct dvb_frontend_ops lgdt3305_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
+               .frequency_min      = 54000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+       .i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
+       .init                 = lgdt3305_init,
+       .sleep                = lgdt3305_sleep,
+       .set_frontend         = lgdt3305_set_parameters,
+       .get_frontend         = lgdt3305_get_frontend,
+       .get_tune_settings    = lgdt3305_get_tune_settings,
+       .read_status          = lgdt3305_read_status,
+       .read_ber             = lgdt3305_read_ber,
+       .read_signal_strength = lgdt3305_read_signal_strength,
+       .read_snr             = lgdt3305_read_snr,
+       .read_ucblocks        = lgdt3305_read_ucblocks,
+       .release              = lgdt3305_release,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.2");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/lgdt3305.h b/drivers/media/dvb-frontends/lgdt3305.h
new file mode 100644 (file)
index 0000000..02172ec
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
+ *
+ *    Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT3305_H_
+#define _LGDT3305_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3305_mpeg_mode {
+       LGDT3305_MPEG_PARALLEL = 0,
+       LGDT3305_MPEG_SERIAL = 1,
+};
+
+enum lgdt3305_tp_clock_edge {
+       LGDT3305_TPCLK_RISING_EDGE = 0,
+       LGDT3305_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3305_tp_valid_polarity {
+       LGDT3305_TP_VALID_LOW = 0,
+       LGDT3305_TP_VALID_HIGH = 1,
+};
+
+enum lgdt_demod_chip_type {
+       LGDT3305 = 0,
+       LGDT3304 = 1,
+};
+
+struct lgdt3305_config {
+       u8 i2c_addr;
+
+       /* user defined IF frequency in KHz */
+       u16 qam_if_khz;
+       u16 vsb_if_khz;
+
+       /* AGC Power reference - defaults are used if left unset */
+       u16 usref_8vsb;   /* default: 0x32c4 */
+       u16 usref_qam64;  /* default: 0x5400 */
+       u16 usref_qam256; /* default: 0x2a80 */
+
+       /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+       unsigned int deny_i2c_rptr:1;
+
+       /* spectral inversion - 0:disabled 1:enabled */
+       unsigned int spectral_inversion:1;
+
+       /* use RF AGC loop - 0:disabled 1:enabled */
+       unsigned int rf_agc_loop:1;
+
+       enum lgdt3305_mpeg_mode mpeg_mode;
+       enum lgdt3305_tp_clock_edge tpclk_edge;
+       enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+       enum lgdt_demod_chip_type demod_chip;
+};
+
+#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
+                                    defined(MODULE))
+extern
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+                                    struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+                                    struct i2c_adapter *i2c_adap)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3305 */
+
+#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c
new file mode 100644 (file)
index 0000000..e046622
--- /dev/null
@@ -0,0 +1,831 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ *                      NOTES ABOUT THIS DRIVER
+ *
+ * This Linux driver supports:
+ *   DViCO FusionHDTV 3 Gold-Q
+ *   DViCO FusionHDTV 3 Gold-T
+ *   DViCO FusionHDTV 5 Gold
+ *   DViCO FusionHDTV 5 Lite
+ *   DViCO FusionHDTV 5 USB Gold
+ *   Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
+ *   pcHDTV HD5500
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "lgdt330x_priv.h"
+#include "lgdt330x.h"
+
+/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
+/* #define USE_EQMSE */
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
+#define dprintk(args...) \
+do { \
+if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
+} while (0)
+
+struct lgdt330x_state
+{
+       struct i2c_adapter* i2c;
+
+       /* Configuration settings */
+       const struct lgdt330x_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* Demodulator private data */
+       fe_modulation_t current_modulation;
+       u32 snr; /* Result of last SNR calculation */
+
+       /* Tuner private data */
+       u32 current_frequency;
+};
+
+static int i2c_write_demod_bytes (struct lgdt330x_state* state,
+                                 u8 *buf, /* data bytes to send */
+                                 int len  /* number of bytes to send */ )
+{
+       struct i2c_msg msg =
+               { .addr = state->config->demod_address,
+                 .flags = 0,
+                 .buf = buf,
+                 .len = 2 };
+       int i;
+       int err;
+
+       for (i=0; i<len-1; i+=2){
+               if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+                       printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err);
+                       if (err < 0)
+                               return err;
+                       else
+                               return -EREMOTEIO;
+               }
+               msg.buf += 2;
+       }
+       return 0;
+}
+
+/*
+ * This routine writes the register (reg) to the demod bus
+ * then reads the data returned for (len) bytes.
+ */
+
+static int i2c_read_demod_bytes(struct lgdt330x_state *state,
+                               enum I2C_REG reg, u8 *buf, int len)
+{
+       u8 wr [] = { reg };
+       struct i2c_msg msg [] = {
+               { .addr = state->config->demod_address,
+                 .flags = 0, .buf = wr,  .len = 1 },
+               { .addr = state->config->demod_address,
+                 .flags = I2C_M_RD, .buf = buf, .len = len },
+       };
+       int ret;
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2) {
+               printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret);
+               if (ret >= 0)
+                       ret = -EIO;
+       } else {
+               ret = 0;
+       }
+       return ret;
+}
+
+/* Software reset */
+static int lgdt3302_SwReset(struct lgdt330x_state* state)
+{
+       u8 ret;
+       u8 reset[] = {
+               IRQ_MASK,
+               0x00 /* bit 6 is active low software reset
+                     * bits 5-0 are 1 to mask interrupts */
+       };
+
+       ret = i2c_write_demod_bytes(state,
+                                   reset, sizeof(reset));
+       if (ret == 0) {
+
+               /* force reset high (inactive) and unmask interrupts */
+               reset[1] = 0x7f;
+               ret = i2c_write_demod_bytes(state,
+                                           reset, sizeof(reset));
+       }
+       return ret;
+}
+
+static int lgdt3303_SwReset(struct lgdt330x_state* state)
+{
+       u8 ret;
+       u8 reset[] = {
+               0x02,
+               0x00 /* bit 0 is active low software reset */
+       };
+
+       ret = i2c_write_demod_bytes(state,
+                                   reset, sizeof(reset));
+       if (ret == 0) {
+
+               /* force reset high (inactive) */
+               reset[1] = 0x01;
+               ret = i2c_write_demod_bytes(state,
+                                           reset, sizeof(reset));
+       }
+       return ret;
+}
+
+static int lgdt330x_SwReset(struct lgdt330x_state* state)
+{
+       switch (state->config->demod_chip) {
+       case LGDT3302:
+               return lgdt3302_SwReset(state);
+       case LGDT3303:
+               return lgdt3303_SwReset(state);
+       default:
+               return -ENODEV;
+       }
+}
+
+static int lgdt330x_init(struct dvb_frontend* fe)
+{
+       /* Hardware reset is done using gpio[0] of cx23880x chip.
+        * I'd like to do it here, but don't know how to find chip address.
+        * cx88-cards.c arranges for the reset bit to be inactive (high).
+        * Maybe there needs to be a callable function in cx88-core or
+        * the caller of this function needs to do it. */
+
+       /*
+        * Array of byte pairs <address, value>
+        * to initialize each different chip
+        */
+       static u8 lgdt3302_init_data[] = {
+               /* Use 50MHz parameter values from spec sheet since xtal is 50 */
+               /* Change the value of NCOCTFV[25:0] of carrier
+                  recovery center frequency register */
+               VSB_CARRIER_FREQ0, 0x00,
+               VSB_CARRIER_FREQ1, 0x87,
+               VSB_CARRIER_FREQ2, 0x8e,
+               VSB_CARRIER_FREQ3, 0x01,
+               /* Change the TPCLK pin polarity
+                  data is valid on falling clock */
+               DEMUX_CONTROL, 0xfb,
+               /* Change the value of IFBW[11:0] of
+                  AGC IF/RF loop filter bandwidth register */
+               AGC_RF_BANDWIDTH0, 0x40,
+               AGC_RF_BANDWIDTH1, 0x93,
+               AGC_RF_BANDWIDTH2, 0x00,
+               /* Change the value of bit 6, 'nINAGCBY' and
+                  'NSSEL[1:0] of ACG function control register 2 */
+               AGC_FUNC_CTRL2, 0xc6,
+               /* Change the value of bit 6 'RFFIX'
+                  of AGC function control register 3 */
+               AGC_FUNC_CTRL3, 0x40,
+               /* Set the value of 'INLVTHD' register 0x2a/0x2c
+                  to 0x7fe */
+               AGC_DELAY0, 0x07,
+               AGC_DELAY2, 0xfe,
+               /* Change the value of IAGCBW[15:8]
+                  of inner AGC loop filter bandwidth */
+               AGC_LOOP_BANDWIDTH0, 0x08,
+               AGC_LOOP_BANDWIDTH1, 0x9a
+       };
+
+       static u8 lgdt3303_init_data[] = {
+               0x4c, 0x14
+       };
+
+       static u8 flip_1_lgdt3303_init_data[] = {
+               0x4c, 0x14,
+               0x87, 0xf3
+       };
+
+       static u8 flip_2_lgdt3303_init_data[] = {
+               0x4c, 0x14,
+               0x87, 0xda
+       };
+
+       struct lgdt330x_state* state = fe->demodulator_priv;
+       char  *chip_name;
+       int    err;
+
+       switch (state->config->demod_chip) {
+       case LGDT3302:
+               chip_name = "LGDT3302";
+               err = i2c_write_demod_bytes(state, lgdt3302_init_data,
+                                           sizeof(lgdt3302_init_data));
+               break;
+       case LGDT3303:
+               chip_name = "LGDT3303";
+               switch (state->config->clock_polarity_flip) {
+               case 2:
+                       err = i2c_write_demod_bytes(state,
+                                       flip_2_lgdt3303_init_data,
+                                       sizeof(flip_2_lgdt3303_init_data));
+                       break;
+               case 1:
+                       err = i2c_write_demod_bytes(state,
+                                       flip_1_lgdt3303_init_data,
+                                       sizeof(flip_1_lgdt3303_init_data));
+                       break;
+               case 0:
+               default:
+                       err = i2c_write_demod_bytes(state, lgdt3303_init_data,
+                                                   sizeof(lgdt3303_init_data));
+               }
+               break;
+       default:
+               chip_name = "undefined";
+               printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
+               err = -ENODEV;
+       }
+       dprintk("%s entered as %s\n", __func__, chip_name);
+       if (err < 0)
+               return err;
+       return lgdt330x_SwReset(state);
+}
+
+static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       *ber = 0; /* Not supplied by the demod chips */
+       return 0;
+}
+
+static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct lgdt330x_state* state = fe->demodulator_priv;
+       int err;
+       u8 buf[2];
+
+       *ucblocks = 0;
+
+       switch (state->config->demod_chip) {
+       case LGDT3302:
+               err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
+                                          buf, sizeof(buf));
+               break;
+       case LGDT3303:
+               err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
+                                          buf, sizeof(buf));
+               break;
+       default:
+               printk(KERN_WARNING
+                      "Only LGDT3302 and LGDT3303 are supported chips.\n");
+               err = -ENODEV;
+       }
+       if (err < 0)
+               return err;
+
+       *ucblocks = (buf[0] << 8) | buf[1];
+       return 0;
+}
+
+static int lgdt330x_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       /*
+        * Array of byte pairs <address, value>
+        * to initialize 8VSB for lgdt3303 chip 50 MHz IF
+        */
+       static u8 lgdt3303_8vsb_44_data[] = {
+               0x04, 0x00,
+               0x0d, 0x40,
+               0x0e, 0x87,
+               0x0f, 0x8e,
+               0x10, 0x01,
+               0x47, 0x8b };
+
+       /*
+        * Array of byte pairs <address, value>
+        * to initialize QAM for lgdt3303 chip
+        */
+       static u8 lgdt3303_qam_data[] = {
+               0x04, 0x00,
+               0x0d, 0x00,
+               0x0e, 0x00,
+               0x0f, 0x00,
+               0x10, 0x00,
+               0x51, 0x63,
+               0x47, 0x66,
+               0x48, 0x66,
+               0x4d, 0x1a,
+               0x49, 0x08,
+               0x4a, 0x9b };
+
+       struct lgdt330x_state* state = fe->demodulator_priv;
+
+       static u8 top_ctrl_cfg[]   = { TOP_CONTROL, 0x03 };
+
+       int err = 0;
+       /* Change only if we are actually changing the modulation */
+       if (state->current_modulation != p->modulation) {
+               switch (p->modulation) {
+               case VSB_8:
+                       dprintk("%s: VSB_8 MODE\n", __func__);
+
+                       /* Select VSB mode */
+                       top_ctrl_cfg[1] = 0x03;
+
+                       /* Select ANT connector if supported by card */
+                       if (state->config->pll_rf_set)
+                               state->config->pll_rf_set(fe, 1);
+
+                       if (state->config->demod_chip == LGDT3303) {
+                               err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
+                                                           sizeof(lgdt3303_8vsb_44_data));
+                       }
+                       break;
+
+               case QAM_64:
+                       dprintk("%s: QAM_64 MODE\n", __func__);
+
+                       /* Select QAM_64 mode */
+                       top_ctrl_cfg[1] = 0x00;
+
+                       /* Select CABLE connector if supported by card */
+                       if (state->config->pll_rf_set)
+                               state->config->pll_rf_set(fe, 0);
+
+                       if (state->config->demod_chip == LGDT3303) {
+                               err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+                                                                                       sizeof(lgdt3303_qam_data));
+                       }
+                       break;
+
+               case QAM_256:
+                       dprintk("%s: QAM_256 MODE\n", __func__);
+
+                       /* Select QAM_256 mode */
+                       top_ctrl_cfg[1] = 0x01;
+
+                       /* Select CABLE connector if supported by card */
+                       if (state->config->pll_rf_set)
+                               state->config->pll_rf_set(fe, 0);
+
+                       if (state->config->demod_chip == LGDT3303) {
+                               err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+                                                                                       sizeof(lgdt3303_qam_data));
+                       }
+                       break;
+               default:
+                       printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, p->modulation);
+                       return -1;
+               }
+               if (err < 0)
+                       printk(KERN_WARNING "lgdt330x: %s: error blasting "
+                              "bytes to lgdt3303 for modulation type(%d)\n",
+                              __func__, p->modulation);
+
+               /*
+                * select serial or parallel MPEG harware interface
+                * Serial:   0x04 for LGDT3302 or 0x40 for LGDT3303
+                * Parallel: 0x00
+                */
+               top_ctrl_cfg[1] |= state->config->serial_mpeg;
+
+               /* Select the requested mode */
+               i2c_write_demod_bytes(state, top_ctrl_cfg,
+                                     sizeof(top_ctrl_cfg));
+               if (state->config->set_ts_params)
+                       state->config->set_ts_params(fe, 0);
+               state->current_modulation = p->modulation;
+       }
+
+       /* Tune to the specified frequency */
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* Keep track of the new frequency */
+       /* FIXME this is the wrong way to do this...           */
+       /* The tuner is shared with the video4linux analog API */
+       state->current_frequency = p->frequency;
+
+       lgdt330x_SwReset(state);
+       return 0;
+}
+
+static int lgdt330x_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgdt330x_state *state = fe->demodulator_priv;
+       p->frequency = state->current_frequency;
+       return 0;
+}
+
+static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct lgdt330x_state* state = fe->demodulator_priv;
+       u8 buf[3];
+
+       *status = 0; /* Reset status result */
+
+       /* AGC status register */
+       i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
+       dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
+       if ((buf[0] & 0x0c) == 0x8){
+               /* Test signal does not exist flag */
+               /* as well as the AGC lock flag.   */
+               *status |= FE_HAS_SIGNAL;
+       }
+
+       /*
+        * You must set the Mask bits to 1 in the IRQ_MASK in order
+        * to see that status bit in the IRQ_STATUS register.
+        * This is done in SwReset();
+        */
+       /* signal status */
+       i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
+       dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]);
+
+
+       /* sync status */
+       if ((buf[2] & 0x03) == 0x01) {
+               *status |= FE_HAS_SYNC;
+       }
+
+       /* FEC error status */
+       if ((buf[2] & 0x0c) == 0x08) {
+               *status |= FE_HAS_LOCK;
+               *status |= FE_HAS_VITERBI;
+       }
+
+       /* Carrier Recovery Lock Status Register */
+       i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
+       dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
+       switch (state->current_modulation) {
+       case QAM_256:
+       case QAM_64:
+               /* Need to understand why there are 3 lock levels here */
+               if ((buf[0] & 0x07) == 0x07)
+                       *status |= FE_HAS_CARRIER;
+               break;
+       case VSB_8:
+               if ((buf[0] & 0x80) == 0x80)
+                       *status |= FE_HAS_CARRIER;
+               break;
+       default:
+               printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
+       }
+
+       return 0;
+}
+
+static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct lgdt330x_state* state = fe->demodulator_priv;
+       int err;
+       u8 buf[3];
+
+       *status = 0; /* Reset status result */
+
+       /* lgdt3303 AGC status register */
+       err = i2c_read_demod_bytes(state, 0x58, buf, 1);
+       if (err < 0)
+               return err;
+
+       dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
+       if ((buf[0] & 0x21) == 0x01){
+               /* Test input signal does not exist flag */
+               /* as well as the AGC lock flag.   */
+               *status |= FE_HAS_SIGNAL;
+       }
+
+       /* Carrier Recovery Lock Status Register */
+       i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
+       dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
+       switch (state->current_modulation) {
+       case QAM_256:
+       case QAM_64:
+               /* Need to understand why there are 3 lock levels here */
+               if ((buf[0] & 0x07) == 0x07)
+                       *status |= FE_HAS_CARRIER;
+               else
+                       break;
+               i2c_read_demod_bytes(state, 0x8a, buf, 1);
+               if ((buf[0] & 0x04) == 0x04)
+                       *status |= FE_HAS_SYNC;
+               if ((buf[0] & 0x01) == 0x01)
+                       *status |= FE_HAS_LOCK;
+               if ((buf[0] & 0x08) == 0x08)
+                       *status |= FE_HAS_VITERBI;
+               break;
+       case VSB_8:
+               if ((buf[0] & 0x80) == 0x80)
+                       *status |= FE_HAS_CARRIER;
+               else
+                       break;
+               i2c_read_demod_bytes(state, 0x38, buf, 1);
+               if ((buf[0] & 0x02) == 0x00)
+                       *status |= FE_HAS_SYNC;
+               if ((buf[0] & 0x01) == 0x01) {
+                       *status |= FE_HAS_LOCK;
+                       *status |= FE_HAS_VITERBI;
+               }
+               break;
+       default:
+               printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
+       }
+       return 0;
+}
+
+/* Calculate SNR estimation (scaled by 2^24)
+
+   8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
+   equations from LGDT3303 datasheet.  VSB is the same between the '02
+   and '03, so maybe QAM is too?  Perhaps someone with a newer datasheet
+   that has QAM information could verify?
+
+   For 8-VSB: (two ways, take your pick)
+   LGDT3302:
+     SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
+   LGDT3303:
+     SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
+   LGDT3302 & LGDT3303:
+     SNR_PT = 10 * log10(25 * 32^2 / PT_MSE)  (we use this one)
+   For 64-QAM:
+     SNR    = 10 * log10( 688128   / MSEQAM)
+   For 256-QAM:
+     SNR    = 10 * log10( 696320   / MSEQAM)
+
+   We re-write the snr equation as:
+     SNR * 2^24 = 10*(c - intlog10(MSE))
+   Where for 256-QAM, c = log10(696320) * 2^24, and so on. */
+
+static u32 calculate_snr(u32 mse, u32 c)
+{
+       if (mse == 0) /* No signal */
+               return 0;
+
+       mse = intlog10(mse);
+       if (mse > c) {
+               /* Negative SNR, which is possible, but realisticly the
+               demod will lose lock before the signal gets this bad.  The
+               API only allows for unsigned values, so just return 0 */
+               return 0;
+       }
+       return 10*(c - mse);
+}
+
+static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+       u8 buf[5];      /* read data buffer */
+       u32 noise;      /* noise value */
+       u32 c;          /* per-modulation SNR calculation constant */
+
+       switch(state->current_modulation) {
+       case VSB_8:
+               i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
+#ifdef USE_EQMSE
+               /* Use Equalizer Mean-Square Error Register */
+               /* SNR for ranges from -15.61 to +41.58 */
+               noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
+               c = 69765745; /* log10(25*24^2)*2^24 */
+#else
+               /* Use Phase Tracker Mean-Square Error Register */
+               /* SNR for ranges from -13.11 to +44.08 */
+               noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+               c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+               break;
+       case QAM_64:
+       case QAM_256:
+               i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
+               noise = ((buf[0] & 3) << 8) | buf[1];
+               c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
+               /* log10(688128)*2^24 and log10(696320)*2^24 */
+               break;
+       default:
+               printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
+                      __func__);
+               return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
+       }
+
+       state->snr = calculate_snr(noise, c);
+       *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
+
+       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
+               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
+
+       return 0;
+}
+
+static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+       u8 buf[5];      /* read data buffer */
+       u32 noise;      /* noise value */
+       u32 c;          /* per-modulation SNR calculation constant */
+
+       switch(state->current_modulation) {
+       case VSB_8:
+               i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
+#ifdef USE_EQMSE
+               /* Use Equalizer Mean-Square Error Register */
+               /* SNR for ranges from -16.12 to +44.08 */
+               noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
+               c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+               /* Use Phase Tracker Mean-Square Error Register */
+               /* SNR for ranges from -13.11 to +44.08 */
+               noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
+               c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+               break;
+       case QAM_64:
+       case QAM_256:
+               i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
+               noise = (buf[0] << 8) | buf[1];
+               c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
+               /* log10(688128)*2^24 and log10(696320)*2^24 */
+               break;
+       default:
+               printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
+                      __func__);
+               return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
+       }
+
+       state->snr = calculate_snr(noise, c);
+       *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
+
+       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
+               state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+       return 0;
+}
+
+static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       /* Calculate Strength from SNR up to 35dB */
+       /* Even though the SNR can go higher than 35dB, there is some comfort */
+       /* factor in having a range of strong signals that can show at 100%   */
+       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+       u16 snr;
+       int ret;
+
+       ret = fe->ops.read_snr(fe, &snr);
+       if (ret != 0)
+               return ret;
+       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+       /* scale the range 0 - 35*2^24 into 0 - 65535 */
+       if (state->snr >= 8960 * 0x10000)
+               *strength = 0xffff;
+       else
+               *strength = state->snr / 8960;
+
+       return 0;
+}
+
+static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
+{
+       /* I have no idea about this - it may not be needed */
+       fe_tune_settings->min_delay_ms = 500;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+       return 0;
+}
+
+static void lgdt330x_release(struct dvb_frontend* fe)
+{
+       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3302_ops;
+static struct dvb_frontend_ops lgdt3303_ops;
+
+struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct lgdt330x_state* state = NULL;
+       u8 buf[1];
+
+       /* Allocate memory for the internal state */
+       state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* Setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* Create dvb_frontend */
+       switch (config->demod_chip) {
+       case LGDT3302:
+               memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       case LGDT3303:
+               memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
+               break;
+       default:
+               goto error;
+       }
+       state->frontend.demodulator_priv = state;
+
+       /* Verify communication with demod chip */
+       if (i2c_read_demod_bytes(state, 2, buf, 1))
+               goto error;
+
+       state->current_frequency = -1;
+       state->current_modulation = -1;
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       dprintk("%s: ERROR\n",__func__);
+       return NULL;
+}
+
+static struct dvb_frontend_ops lgdt3302_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
+               .frequency_min= 54000000,
+               .frequency_max= 858000000,
+               .frequency_stepsize= 62500,
+               .symbol_rate_min    = 5056941,  /* QAM 64 */
+               .symbol_rate_max    = 10762000, /* VSB 8  */
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+       .init                 = lgdt330x_init,
+       .set_frontend         = lgdt330x_set_parameters,
+       .get_frontend         = lgdt330x_get_frontend,
+       .get_tune_settings    = lgdt330x_get_tune_settings,
+       .read_status          = lgdt3302_read_status,
+       .read_ber             = lgdt330x_read_ber,
+       .read_signal_strength = lgdt330x_read_signal_strength,
+       .read_snr             = lgdt3302_read_snr,
+       .read_ucblocks        = lgdt330x_read_ucblocks,
+       .release              = lgdt330x_release,
+};
+
+static struct dvb_frontend_ops lgdt3303_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
+               .frequency_min= 54000000,
+               .frequency_max= 858000000,
+               .frequency_stepsize= 62500,
+               .symbol_rate_min    = 5056941,  /* QAM 64 */
+               .symbol_rate_max    = 10762000, /* VSB 8  */
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+       .init                 = lgdt330x_init,
+       .set_frontend         = lgdt330x_set_parameters,
+       .get_frontend         = lgdt330x_get_frontend,
+       .get_tune_settings    = lgdt330x_get_tune_settings,
+       .read_status          = lgdt3303_read_status,
+       .read_ber             = lgdt330x_read_ber,
+       .read_signal_strength = lgdt330x_read_signal_strength,
+       .read_snr             = lgdt3303_read_snr,
+       .read_ucblocks        = lgdt330x_read_ucblocks,
+       .release              = lgdt330x_release,
+};
+
+MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_AUTHOR("Wilson Michaels");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(lgdt330x_attach);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/lgdt330x.h b/drivers/media/dvb-frontends/lgdt330x.h
new file mode 100644 (file)
index 0000000..9012504
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef LGDT330X_H
+#define LGDT330X_H
+
+#include <linux/dvb/frontend.h>
+
+typedef enum lg_chip_t {
+               UNDEFINED,
+               LGDT3302,
+               LGDT3303
+}lg_chip_type;
+
+struct lgdt330x_config
+{
+       /* The demodulator's i2c address */
+       u8 demod_address;
+
+       /* LG demodulator chip LGDT3302 or LGDT3303 */
+       lg_chip_type demod_chip;
+
+       /* MPEG hardware interface - 0:parallel 1:serial */
+       int serial_mpeg;
+
+       /* PLL interface */
+       int (*pll_rf_set) (struct dvb_frontend* fe, int index);
+
+       /* Need to set device param for start_dma */
+       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+
+       /* Flip the polarity of the mpeg data transfer clock using alternate init data
+        * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
+       int clock_polarity_flip;
+};
+
+#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+                                           struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+                                           struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_LGDT330X
+
+#endif /* LGDT330X_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/lgdt330x_priv.h b/drivers/media/dvb-frontends/lgdt330x_priv.h
new file mode 100644 (file)
index 0000000..38c7669
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT330X_PRIV_
+#define _LGDT330X_PRIV_
+
+/* i2c control register addresses */
+enum I2C_REG {
+       TOP_CONTROL= 0x00,
+       IRQ_MASK= 0x01,
+       IRQ_STATUS= 0x02,
+       VSB_CARRIER_FREQ0= 0x16,
+       VSB_CARRIER_FREQ1= 0x17,
+       VSB_CARRIER_FREQ2= 0x18,
+       VSB_CARRIER_FREQ3= 0x19,
+       CARRIER_MSEQAM1= 0x1a,
+       CARRIER_MSEQAM2= 0x1b,
+       CARRIER_LOCK= 0x1c,
+       TIMING_RECOVERY= 0x1d,
+       AGC_DELAY0= 0x2a,
+       AGC_DELAY1= 0x2b,
+       AGC_DELAY2= 0x2c,
+       AGC_RF_BANDWIDTH0= 0x2d,
+       AGC_RF_BANDWIDTH1= 0x2e,
+       AGC_RF_BANDWIDTH2= 0x2f,
+       AGC_LOOP_BANDWIDTH0= 0x30,
+       AGC_LOOP_BANDWIDTH1= 0x31,
+       AGC_FUNC_CTRL1= 0x32,
+       AGC_FUNC_CTRL2= 0x33,
+       AGC_FUNC_CTRL3= 0x34,
+       AGC_RFIF_ACC0= 0x39,
+       AGC_RFIF_ACC1= 0x3a,
+       AGC_RFIF_ACC2= 0x3b,
+       AGC_STATUS= 0x3f,
+       SYNC_STATUS_VSB= 0x43,
+       DEMUX_CONTROL= 0x66,
+       LGDT3302_EQPH_ERR0= 0x47,
+       LGDT3302_EQ_ERR1= 0x48,
+       LGDT3302_EQ_ERR2= 0x49,
+       LGDT3302_PH_ERR1= 0x4a,
+       LGDT3302_PH_ERR2= 0x4b,
+       LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
+       LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
+       LGDT3303_EQPH_ERR0= 0x6e,
+       LGDT3303_EQ_ERR1= 0x6f,
+       LGDT3303_EQ_ERR2= 0x70,
+       LGDT3303_PH_ERR1= 0x71,
+       LGDT3303_PH_ERR2= 0x72,
+       LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
+       LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
+};
+
+#endif /* _LGDT330X_PRIV_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c
new file mode 100644 (file)
index 0000000..416cce3
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+    Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
+
+    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+       Timothy Lee <timothy.lee@siriushk.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "dvb_frontend.h"
+#include "lgs8gl5.h"
+
+
+#define REG_RESET              0x02
+#define REG_RESET_OFF                  0x01
+#define REG_03                 0x03
+#define REG_04                 0x04
+#define REG_07                 0x07
+#define REG_09                 0x09
+#define REG_0A                 0x0a
+#define REG_0B                 0x0b
+#define REG_0C                 0x0c
+#define REG_37                 0x37
+#define REG_STRENGTH           0x4b
+#define REG_STRENGTH_MASK              0x7f
+#define REG_STRENGTH_CARRIER           0x80
+#define REG_INVERSION          0x7c
+#define REG_INVERSION_ON               0x80
+#define REG_7D                 0x7d
+#define REG_7E                 0x7e
+#define REG_A2                 0xa2
+#define REG_STATUS             0xa4
+#define REG_STATUS_SYNC                0x04
+#define REG_STATUS_LOCK                0x01
+
+
+struct lgs8gl5_state {
+       struct i2c_adapter *i2c;
+       const struct lgs8gl5_config *config;
+       struct dvb_frontend frontend;
+};
+
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "lgs8gl5: " args); \
+       } while (0)
+
+
+/* Writes into demod's register */
+static int
+lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = {reg, data};
+       struct i2c_msg msg = {
+               .addr  = state->config->demod_address,
+               .flags = 0,
+               .buf   = buf,
+               .len   = 2
+       };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+       if (ret != 1)
+               dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n",
+                       __func__, reg, data, ret);
+       return (ret != 1) ? -1 : 0;
+}
+
+
+/* Reads from demod's register */
+static int
+lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = {reg};
+       u8 b1[] = {0};
+       struct i2c_msg msg[2] = {
+               {
+                       .addr  = state->config->demod_address,
+                       .flags = 0,
+                       .buf   = b0,
+                       .len   = 1
+               },
+               {
+                       .addr  = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf   = b1,
+                       .len   = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2)
+               return -EIO;
+
+       return b1[0];
+}
+
+
+static int
+lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
+{
+       lgs8gl5_read_reg(state, reg);
+       lgs8gl5_write_reg(state, reg, data);
+       return 0;
+}
+
+
+/* Writes into alternate device's register */
+/* TODO:  Find out what that device is for! */
+static int
+lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 b0[] = {reg};
+       u8 b1[] = {0};
+       u8 b2[] = {reg, data};
+       struct i2c_msg msg[3] = {
+               {
+                       .addr  = state->config->demod_address + 2,
+                       .flags = 0,
+                       .buf   = b0,
+                       .len   = 1
+               },
+               {
+                       .addr  = state->config->demod_address + 2,
+                       .flags = I2C_M_RD,
+                       .buf   = b1,
+                       .len   = 1
+               },
+               {
+                       .addr  = state->config->demod_address + 2,
+                       .flags = 0,
+                       .buf   = b2,
+                       .len   = 2
+               },
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 3);
+       return (ret != 3) ? -1 : 0;
+}
+
+
+static void
+lgs8gl5_soft_reset(struct lgs8gl5_state *state)
+{
+       u8 val;
+
+       dprintk("%s\n", __func__);
+
+       val = lgs8gl5_read_reg(state, REG_RESET);
+       lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF);
+       lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF);
+       msleep(5);
+}
+
+
+/* Starts demodulation */
+static void
+lgs8gl5_start_demod(struct lgs8gl5_state *state)
+{
+       u8  val;
+       int n;
+
+       dprintk("%s\n", __func__);
+
+       lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
+       lgs8gl5_soft_reset(state);
+       lgs8gl5_update_reg(state, REG_07, 0x10);
+       lgs8gl5_update_reg(state, REG_07, 0x10);
+       lgs8gl5_write_reg(state, REG_09, 0x0e);
+       lgs8gl5_write_reg(state, REG_0A, 0xe5);
+       lgs8gl5_write_reg(state, REG_0B, 0x35);
+       lgs8gl5_write_reg(state, REG_0C, 0x30);
+
+       lgs8gl5_update_reg(state, REG_03, 0x00);
+       lgs8gl5_update_reg(state, REG_7E, 0x01);
+       lgs8gl5_update_alt_reg(state, 0xc5, 0x00);
+       lgs8gl5_update_reg(state, REG_04, 0x02);
+       lgs8gl5_update_reg(state, REG_37, 0x01);
+       lgs8gl5_soft_reset(state);
+
+       /* Wait for carrier */
+       for (n = 0;  n < 10;  n++) {
+               val = lgs8gl5_read_reg(state, REG_STRENGTH);
+               dprintk("Wait for carrier[%d] 0x%02X\n", n, val);
+               if (val & REG_STRENGTH_CARRIER)
+                       break;
+               msleep(4);
+       }
+       if (!(val & REG_STRENGTH_CARRIER))
+               return;
+
+       /* Wait for lock */
+       for (n = 0;  n < 20;  n++) {
+               val = lgs8gl5_read_reg(state, REG_STATUS);
+               dprintk("Wait for lock[%d] 0x%02X\n", n, val);
+               if (val & REG_STATUS_LOCK)
+                       break;
+               msleep(12);
+       }
+       if (!(val & REG_STATUS_LOCK))
+               return;
+
+       lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2));
+       lgs8gl5_soft_reset(state);
+}
+
+
+static int
+lgs8gl5_init(struct dvb_frontend *fe)
+{
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
+       lgs8gl5_soft_reset(state);
+       lgs8gl5_update_reg(state, REG_07, 0x10);
+       lgs8gl5_update_reg(state, REG_07, 0x10);
+       lgs8gl5_write_reg(state, REG_09, 0x0e);
+       lgs8gl5_write_reg(state, REG_0A, 0xe5);
+       lgs8gl5_write_reg(state, REG_0B, 0x35);
+       lgs8gl5_write_reg(state, REG_0C, 0x30);
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
+       u8 flags = lgs8gl5_read_reg(state, REG_STATUS);
+
+       *status = 0;
+
+       if ((level & REG_STRENGTH_MASK) > 0)
+               *status |= FE_HAS_SIGNAL;
+       if (level & REG_STRENGTH_CARRIER)
+               *status |= FE_HAS_CARRIER;
+       if (flags & REG_STATUS_SYNC)
+               *status |= FE_HAS_SYNC;
+       if (flags & REG_STATUS_LOCK)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       *ber = 0;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength)
+{
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
+       *signal_strength = (level & REG_STRENGTH_MASK) << 8;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
+       *snr = (level & REG_STRENGTH_MASK) << 8;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (p->bandwidth_hz != 8000000)
+               return -EINVAL;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* lgs8gl5_set_inversion(state, p->inversion); */
+
+       lgs8gl5_start_demod(state);
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+       u8 inv = lgs8gl5_read_reg(state, REG_INVERSION);
+
+       p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF;
+
+       p->code_rate_HP = FEC_1_2;
+       p->code_rate_LP = FEC_7_8;
+       p->guard_interval = GUARD_INTERVAL_1_32;
+       p->transmission_mode = TRANSMISSION_MODE_2K;
+       p->modulation = QAM_64;
+       p->hierarchy = HIERARCHY_NONE;
+       p->bandwidth_hz = 8000000;
+
+       return 0;
+}
+
+
+static int
+lgs8gl5_get_tune_settings(struct dvb_frontend *fe,
+               struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 240;
+       fesettings->step_size    = 0;
+       fesettings->max_drift    = 0;
+       return 0;
+}
+
+
+static void
+lgs8gl5_release(struct dvb_frontend *fe)
+{
+       struct lgs8gl5_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+
+static struct dvb_frontend_ops lgs8gl5_ops;
+
+
+struct dvb_frontend*
+lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
+{
+       struct lgs8gl5_state *state = NULL;
+
+       dprintk("%s\n", __func__);
+
+       /* Allocate memory for the internal state */
+       state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* Setup the state */
+       state->config = config;
+       state->i2c    = i2c;
+
+       /* Check if the demod is there */
+       if (lgs8gl5_read_reg(state, REG_RESET) < 0)
+               goto error;
+
+       /* Create dvb_frontend */
+       memcpy(&state->frontend.ops, &lgs8gl5_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(lgs8gl5_attach);
+
+
+static struct dvb_frontend_ops lgs8gl5_ops = {
+       .delsys = { SYS_DTMB },
+       .info = {
+               .name                   = "Legend Silicon LGS-8GL5 DMB-TH",
+               .frequency_min          = 474000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 10000,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
+                       FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_BANDWIDTH_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER
+       },
+
+       .release = lgs8gl5_release,
+
+       .init = lgs8gl5_init,
+
+       .set_frontend = lgs8gl5_set_frontend,
+       .get_frontend = lgs8gl5_get_frontend,
+       .get_tune_settings = lgs8gl5_get_tune_settings,
+
+       .read_status = lgs8gl5_read_status,
+       .read_ber = lgs8gl5_read_ber,
+       .read_signal_strength = lgs8gl5_read_signal_strength,
+       .read_snr = lgs8gl5_read_snr,
+       .read_ucblocks = lgs8gl5_read_ucblocks,
+};
+
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver");
+MODULE_AUTHOR("Timothy Lee");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/lgs8gl5.h b/drivers/media/dvb-frontends/lgs8gl5.h
new file mode 100644 (file)
index 0000000..d141767
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
+
+    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+       Timothy Lee <timothy.lee@siriushk.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef LGS8GL5_H
+#define LGS8GL5_H
+
+#include <linux/dvb/frontend.h>
+
+struct lgs8gl5_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_LGS8GL5) || \
+       (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
+extern struct dvb_frontend *lgs8gl5_attach(
+       const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *lgs8gl5_attach(
+       const struct lgs8gl5_config *config, struct i2c_adapter *i2c) {
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_LGS8GL5 */
+
+#endif /* LGS8GL5_H */
diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c
new file mode 100644 (file)
index 0000000..3c92f36
--- /dev/null
@@ -0,0 +1,1075 @@
+/*
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/div64.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+
+#include "lgs8gxx.h"
+#include "lgs8gxx_priv.h"
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "lgs8gxx: " args); \
+       } while (0)
+
+static int debug;
+static int fake_signal_str = 1;
+
+#define LGS8GXX_FIRMWARE "lgs8g75.fw"
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+module_param(fake_signal_str, int, 0644);
+MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
+"Signal strength calculation is slow.(default:on).");
+
+/* LGS8GXX internal helper functions */
+
+static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+       msg.addr = priv->config->demod_address;
+       if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
+               msg.addr += 0x02;
+
+       if (debug >= 2)
+               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
+
+       ret = i2c_transfer(priv->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
+                       __func__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
+{
+       int ret;
+       u8 dev_addr;
+
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               { .flags = 0, .buf = b0, .len = 1 },
+               { .flags = I2C_M_RD, .buf = b1, .len = 1 },
+       };
+
+       dev_addr = priv->config->demod_address;
+       if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
+               dev_addr += 0x02;
+       msg[1].addr =  msg[0].addr = dev_addr;
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret != 2) {
+               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
+               return -1;
+       }
+
+       *p_data = b1[0];
+       if (debug >= 2)
+               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
+       return 0;
+}
+
+static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
+{
+       lgs8gxx_write_reg(priv, 0x02, 0x00);
+       msleep(1);
+       lgs8gxx_write_reg(priv, 0x02, 0x01);
+       msleep(100);
+
+       return 0;
+}
+
+static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
+       u8 val, u8 delay, u8 tries)
+{
+       u8 t;
+       int i;
+
+       for (i = 0; i < tries; i++) {
+               lgs8gxx_read_reg(priv, reg, &t);
+
+               if ((t & mask) == val)
+                       return 0;
+               msleep(delay);
+       }
+
+       return 1;
+}
+
+static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
+{
+       const struct lgs8gxx_config *config = priv->config;
+       u8 if_conf;
+
+       if_conf = 0x10; /* AGC output on, RF_AGC output off; */
+
+       if_conf |=
+               ((config->ext_adc) ? 0x80 : 0x00) |
+               ((config->if_neg_center) ? 0x04 : 0x00) |
+               ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
+               ((config->adc_signed) ? 0x02 : 0x00) |
+               ((config->if_neg_edge) ? 0x01 : 0x00);
+
+       if (config->ext_adc &&
+               (config->prod == LGS8GXX_PROD_LGS8G52)) {
+               lgs8gxx_write_reg(priv, 0xBA, 0x40);
+       }
+
+       lgs8gxx_write_reg(priv, 0x07, if_conf);
+
+       return 0;
+}
+
+static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
+{
+       u64 val;
+       u32 v32;
+       u32 if_clk;
+
+       if_clk = priv->config->if_clk_freq;
+
+       val = freq;
+       if (freq != 0) {
+               val <<= 32;
+               if (if_clk != 0)
+                       do_div(val, if_clk);
+               v32 = val & 0xFFFFFFFF;
+               dprintk("Set IF Freq to %dkHz\n", freq);
+       } else {
+               v32 = 0;
+               dprintk("Set IF Freq to baseband\n");
+       }
+       dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
+               lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
+               lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
+               lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
+       } else {
+               lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
+               lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
+               lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
+               lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
+       }
+
+       return 0;
+}
+
+static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
+{
+       u64 val;
+       u32 v32 = 0;
+       u8 reg_addr, t;
+       int i;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+               reg_addr = 0x23;
+       else
+               reg_addr = 0x48;
+
+       for (i = 0; i < 4; i++) {
+               lgs8gxx_read_reg(priv, reg_addr, &t);
+               v32 <<= 8;
+               v32 |= t;
+               reg_addr--;
+       }
+
+       val = v32;
+       val *= priv->config->if_clk_freq;
+       val >>= 32;
+       dprintk("AFC = %u kHz\n", (u32)val);
+       return 0;
+}
+
+static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
+{
+       u8 t;
+       u8 prod = priv->config->prod;
+
+       if (prod == LGS8GXX_PROD_LGS8913)
+               lgs8gxx_write_reg(priv, 0xC6, 0x01);
+
+       if (prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_read_reg(priv, 0x0C, &t);
+               t &= (~0x04);
+               lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
+               lgs8gxx_write_reg(priv, 0x39, 0x00);
+               lgs8gxx_write_reg(priv, 0x3D, 0x04);
+       } else if (prod == LGS8GXX_PROD_LGS8913 ||
+               prod == LGS8GXX_PROD_LGS8GL5 ||
+               prod == LGS8GXX_PROD_LGS8G42 ||
+               prod == LGS8GXX_PROD_LGS8G52 ||
+               prod == LGS8GXX_PROD_LGS8G54) {
+               lgs8gxx_read_reg(priv, 0x7E, &t);
+               lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
+
+               /* clear FEC self reset */
+               lgs8gxx_read_reg(priv, 0xC5, &t);
+               lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
+       }
+
+       if (prod == LGS8GXX_PROD_LGS8913) {
+               /* FEC auto detect */
+               lgs8gxx_write_reg(priv, 0xC1, 0x03);
+
+               lgs8gxx_read_reg(priv, 0x7C, &t);
+               t = (t & 0x8C) | 0x03;
+               lgs8gxx_write_reg(priv, 0x7C, t);
+
+               /* BER test mode */
+               lgs8gxx_read_reg(priv, 0xC3, &t);
+               t = (t & 0xEF) |  0x10;
+               lgs8gxx_write_reg(priv, 0xC3, t);
+       }
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
+               lgs8gxx_write_reg(priv, 0xD9, 0x40);
+
+       return 0;
+}
+
+static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
+{
+       u8 t;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               u8 t2;
+               lgs8gxx_read_reg(priv, 0x0C, &t);
+               t &= (~0x80);
+               lgs8gxx_write_reg(priv, 0x0C, t);
+
+               lgs8gxx_read_reg(priv, 0x0C, &t);
+               lgs8gxx_read_reg(priv, 0x19, &t2);
+
+               if (((t&0x03) == 0x01) && (t2&0x01)) {
+                       lgs8gxx_write_reg(priv, 0x6E, 0x05);
+                       lgs8gxx_write_reg(priv, 0x39, 0x02);
+                       lgs8gxx_write_reg(priv, 0x39, 0x03);
+                       lgs8gxx_write_reg(priv, 0x3D, 0x05);
+                       lgs8gxx_write_reg(priv, 0x3E, 0x28);
+                       lgs8gxx_write_reg(priv, 0x53, 0x80);
+               } else {
+                       lgs8gxx_write_reg(priv, 0x6E, 0x3F);
+                       lgs8gxx_write_reg(priv, 0x39, 0x00);
+                       lgs8gxx_write_reg(priv, 0x3D, 0x04);
+               }
+
+               lgs8gxx_soft_reset(priv);
+               return 0;
+       }
+
+       /* turn off auto-detect; manual settings */
+       lgs8gxx_write_reg(priv, 0x7E, 0);
+       if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+               lgs8gxx_write_reg(priv, 0xC1, 0);
+
+       lgs8gxx_read_reg(priv, 0xC5, &t);
+       t = (t & 0xE0) | 0x06;
+       lgs8gxx_write_reg(priv, 0xC5, t);
+
+       lgs8gxx_soft_reset(priv);
+
+       return 0;
+}
+
+static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
+{
+       int ret = 0;
+       u8 t;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+               ret = lgs8gxx_read_reg(priv, 0x13, &t);
+       else
+               ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+       if (ret != 0)
+               return ret;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+               *locked = ((t & 0x80) == 0x80) ? 1 : 0;
+       else
+               *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
+       return 0;
+}
+
+/* Wait for Code Acquisition Lock */
+static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
+{
+       int ret = 0;
+       u8 reg, mask, val;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               reg = 0x13;
+               mask = 0x80;
+               val = 0x80;
+       } else {
+               reg = 0x4B;
+               mask = 0xC0;
+               val = 0xC0;
+       }
+
+       ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
+       *locked = (ret == 0) ? 1 : 0;
+
+       return 0;
+}
+
+static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
+                                         u8 *finished)
+{
+       int ret = 0;
+       u8 reg, mask, val;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               reg = 0x1f;
+               mask = 0xC0;
+               val = 0x80;
+       } else {
+               reg = 0xA4;
+               mask = 0x03;
+               val = 0x01;
+       }
+
+       ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
+       *finished = (ret == 0) ? 1 : 0;
+
+       return 0;
+}
+
+static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
+       u8 *locked)
+{
+       int err = 0;
+       u8 ad_fini = 0;
+       u8 t1, t2;
+
+       if (gi == GI_945)
+               dprintk("try GI 945\n");
+       else if (gi == GI_595)
+               dprintk("try GI 595\n");
+       else if (gi == GI_420)
+               dprintk("try GI 420\n");
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_read_reg(priv, 0x0C, &t1);
+               lgs8gxx_read_reg(priv, 0x18, &t2);
+               t1 &= ~(GI_MASK);
+               t1 |= gi;
+               t2 &= 0xFE;
+               t2 |= cpn ? 0x01 : 0x00;
+               lgs8gxx_write_reg(priv, 0x0C, t1);
+               lgs8gxx_write_reg(priv, 0x18, t2);
+       } else {
+               lgs8gxx_write_reg(priv, 0x04, gi);
+       }
+       lgs8gxx_soft_reset(priv);
+       err = lgs8gxx_wait_ca_lock(priv, locked);
+       if (err || !(*locked))
+               return err;
+       err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
+       if (err != 0)
+               return err;
+       if (ad_fini) {
+               dprintk("auto detect finished\n");
+       } else
+               *locked = 0;
+
+       return 0;
+}
+
+static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
+                              u8 *detected_param, u8 *gi)
+{
+       int i, j;
+       int err = 0;
+       u8 locked = 0, tmp_gi;
+
+       dprintk("%s\n", __func__);
+
+       lgs8gxx_set_mode_auto(priv);
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_write_reg(priv, 0x67, 0xAA);
+               lgs8gxx_write_reg(priv, 0x6E, 0x3F);
+       } else {
+               /* Guard Interval */
+               lgs8gxx_write_reg(priv, 0x03, 00);
+       }
+
+       for (i = 0; i < 2; i++) {
+               for (j = 0; j < 2; j++) {
+                       tmp_gi = GI_945;
+                       err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
+                       if (err)
+                               goto out;
+                       if (locked)
+                               goto locked;
+               }
+               for (j = 0; j < 2; j++) {
+                       tmp_gi = GI_420;
+                       err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
+                       if (err)
+                               goto out;
+                       if (locked)
+                               goto locked;
+               }
+               tmp_gi = GI_595;
+               err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
+               if (err)
+                       goto out;
+               if (locked)
+                       goto locked;
+       }
+
+locked:
+       if ((err == 0) && (locked == 1)) {
+               u8 t;
+
+               if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
+                       lgs8gxx_read_reg(priv, 0xA2, &t);
+                       *detected_param = t;
+               } else {
+                       lgs8gxx_read_reg(priv, 0x1F, &t);
+                       *detected_param = t & 0x3F;
+               }
+
+               if (tmp_gi == GI_945)
+                       dprintk("GI 945 locked\n");
+               else if (tmp_gi == GI_595)
+                       dprintk("GI 595 locked\n");
+               else if (tmp_gi == GI_420)
+                       dprintk("GI 420 locked\n");
+               *gi = tmp_gi;
+       }
+       if (!locked)
+               err = -1;
+
+out:
+       return err;
+}
+
+static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
+{
+       s8 err;
+       u8 gi = 0x2;
+       u8 detected_param = 0;
+
+       err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
+
+       if (err != 0) {
+               dprintk("lgs8gxx_auto_detect failed\n");
+       } else
+               dprintk("detected param = 0x%02X\n", detected_param);
+
+       /* Apply detected parameters */
+       if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+               u8 inter_leave_len = detected_param & TIM_MASK ;
+               /* Fix 8913 time interleaver detection bug */
+               inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
+               detected_param &= CF_MASK | SC_MASK  | LGS_FEC_MASK;
+               detected_param |= inter_leave_len;
+       }
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               u8 t;
+               lgs8gxx_read_reg(priv, 0x19, &t);
+               t &= 0x81;
+               t |= detected_param << 1;
+               lgs8gxx_write_reg(priv, 0x19, t);
+       } else {
+               lgs8gxx_write_reg(priv, 0x7D, detected_param);
+               if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+                       lgs8gxx_write_reg(priv, 0xC0, detected_param);
+       }
+       /* lgs8gxx_soft_reset(priv); */
+
+       /* Enter manual mode */
+       lgs8gxx_set_mode_manual(priv);
+
+       switch (gi) {
+       case GI_945:
+               priv->curr_gi = 945; break;
+       case GI_595:
+               priv->curr_gi = 595; break;
+       case GI_420:
+               priv->curr_gi = 420; break;
+       default:
+               priv->curr_gi = 945; break;
+       }
+}
+
+static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
+       u8 serial, u8 clk_pol, u8 clk_gated)
+{
+       int ret = 0;
+       u8 t, reg_addr;
+
+       reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
+       ret = lgs8gxx_read_reg(priv, reg_addr, &t);
+       if (ret != 0)
+               return ret;
+
+       t &= 0xF8;
+       t |= serial ? TS_SERIAL : TS_PARALLEL;
+       t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
+       t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
+
+       ret = lgs8gxx_write_reg(priv, reg_addr, t);
+       if (ret != 0)
+               return ret;
+
+       return 0;
+}
+
+/* A/D input peak-to-peak voltage range */
+static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
+       u8 sel)
+{
+       u8 r26 = 0x73, r27 = 0x90;
+
+       if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
+               return 0;
+
+       r26 |= (sel & 0x01) << 7;
+       r27 |= (sel & 0x02) >> 1;
+       lgs8gxx_write_reg(priv, 0x26, r26);
+       lgs8gxx_write_reg(priv, 0x27, r27);
+
+       return 0;
+}
+
+/* LGS8913 demod frontend functions */
+
+static int lgs8913_init(struct lgs8gxx_state *priv)
+{
+       u8 t;
+
+       /* LGS8913 specific */
+       lgs8gxx_write_reg(priv, 0xc1, 0x3);
+
+       lgs8gxx_read_reg(priv, 0x7c, &t);
+       lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
+
+       /* LGS8913 specific */
+       lgs8gxx_read_reg(priv, 0xc3, &t);
+       lgs8gxx_write_reg(priv, 0xc3, t&0x10);
+
+
+       return 0;
+}
+
+static int lgs8g75_init_data(struct lgs8gxx_state *priv)
+{
+       const struct firmware *fw;
+       int rc;
+       int i;
+
+       rc = request_firmware(&fw, LGS8GXX_FIRMWARE, &priv->i2c->dev);
+       if (rc)
+               return rc;
+
+       lgs8gxx_write_reg(priv, 0xC6, 0x40);
+
+       lgs8gxx_write_reg(priv, 0x3D, 0x04);
+       lgs8gxx_write_reg(priv, 0x39, 0x00);
+
+       lgs8gxx_write_reg(priv, 0x3A, 0x00);
+       lgs8gxx_write_reg(priv, 0x38, 0x00);
+       lgs8gxx_write_reg(priv, 0x3B, 0x00);
+       lgs8gxx_write_reg(priv, 0x38, 0x00);
+
+       for (i = 0; i < fw->size; i++) {
+               lgs8gxx_write_reg(priv, 0x38, 0x00);
+               lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
+               lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
+               lgs8gxx_write_reg(priv, 0x3C, fw->data[i]);
+       }
+
+       lgs8gxx_write_reg(priv, 0x38, 0x00);
+
+       release_firmware(fw);
+       return 0;
+}
+
+static int lgs8gxx_init(struct dvb_frontend *fe)
+{
+       struct lgs8gxx_state *priv =
+               (struct lgs8gxx_state *)fe->demodulator_priv;
+       const struct lgs8gxx_config *config = priv->config;
+       u8 data = 0;
+       s8 err;
+       dprintk("%s\n", __func__);
+
+       lgs8gxx_read_reg(priv, 0, &data);
+       dprintk("reg 0 = 0x%02X\n", data);
+
+       if (config->prod == LGS8GXX_PROD_LGS8G75)
+               lgs8g75_set_adc_vpp(priv, config->adc_vpp);
+
+       /* Setup MPEG output format */
+       err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
+                                   config->ts_clk_pol,
+                                   config->ts_clk_gated);
+       if (err != 0)
+               return -EIO;
+
+       if (config->prod == LGS8GXX_PROD_LGS8913)
+               lgs8913_init(priv);
+       lgs8gxx_set_if_freq(priv, priv->config->if_freq);
+       lgs8gxx_set_ad_mode(priv);
+
+       return 0;
+}
+
+static void lgs8gxx_release(struct dvb_frontend *fe)
+{
+       struct lgs8gxx_state *state = fe->demodulator_priv;
+       dprintk("%s\n", __func__);
+
+       kfree(state);
+}
+
+
+static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return lgs8gxx_write_reg(priv, buf[0], buf[1]);
+}
+
+static int lgs8gxx_set_fe(struct dvb_frontend *fe)
+{
+
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       /* set frequency */
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* start auto lock */
+       lgs8gxx_auto_lock(priv);
+
+       msleep(10);
+
+       return 0;
+}
+
+static int lgs8gxx_get_fe(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
+       dprintk("%s\n", __func__);
+
+       /* TODO: get real readings from device */
+       /* inversion status */
+       fe_params->inversion = INVERSION_OFF;
+
+       /* bandwidth */
+       fe_params->bandwidth_hz = 8000000;
+
+       fe_params->code_rate_HP = FEC_AUTO;
+       fe_params->code_rate_LP = FEC_AUTO;
+
+       fe_params->modulation = QAM_AUTO;
+
+       /* transmission mode */
+       fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
+
+       /* guard interval */
+       fe_params->guard_interval = GUARD_INTERVAL_AUTO;
+
+       /* hierarchy */
+       fe_params->hierarchy = HIERARCHY_NONE;
+
+       return 0;
+}
+
+static
+int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
+                             struct dvb_frontend_tune_settings *fesettings)
+{
+       /* FIXME: copy from tda1004x.c */
+       fesettings->min_delay_ms = 800;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+       s8 ret;
+       u8 t, locked = 0;
+
+       dprintk("%s\n", __func__);
+       *fe_status = 0;
+
+       lgs8gxx_get_afc_phase(priv);
+       lgs8gxx_is_locked(priv, &locked);
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               if (locked)
+                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+               return 0;
+       }
+
+       ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+       if (ret != 0)
+               return -EIO;
+
+       dprintk("Reg 0x4B: 0x%02X\n", t);
+
+       *fe_status = 0;
+       if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+               if ((t & 0x40) == 0x40)
+                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+               if ((t & 0x80) == 0x80)
+                       *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
+                               FE_HAS_LOCK;
+       } else {
+               if ((t & 0x80) == 0x80)
+                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       }
+
+       /* success */
+       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+       return 0;
+}
+
+static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
+{
+       u16 v;
+       u8 agc_lvl[2], cat;
+
+       dprintk("%s()\n", __func__);
+       lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
+       lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
+
+       v = agc_lvl[0];
+       v <<= 8;
+       v |= agc_lvl[1];
+
+       dprintk("agc_lvl: 0x%04X\n", v);
+
+       if (v < 0x100)
+               cat = 0;
+       else if (v < 0x190)
+               cat = 5;
+       else if (v < 0x2A8)
+               cat = 4;
+       else if (v < 0x381)
+               cat = 3;
+       else if (v < 0x400)
+               cat = 2;
+       else if (v == 0x400)
+               cat = 1;
+       else
+               cat = 0;
+
+       *signal = cat * 65535 / 5;
+
+       return 0;
+}
+
+static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
+{
+       u8 t; s8 ret;
+       s16 max_strength = 0;
+       u8 str;
+       u16 i, gi = priv->curr_gi;
+
+       dprintk("%s\n", __func__);
+
+       ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+       if (ret != 0)
+               return -EIO;
+
+       if (fake_signal_str) {
+               if ((t & 0xC0) == 0xC0) {
+                       dprintk("Fake signal strength\n");
+                       *signal = 0x7FFF;
+               } else
+                       *signal = 0;
+               return 0;
+       }
+
+       dprintk("gi = %d\n", gi);
+       for (i = 0; i < gi; i++) {
+
+               if ((i & 0xFF) == 0)
+                       lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
+               lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
+
+               lgs8gxx_read_reg(priv, 0x94, &str);
+               if (max_strength < str)
+                       max_strength = str;
+       }
+
+       *signal = max_strength;
+       dprintk("%s: signal=0x%02X\n", __func__, *signal);
+
+       lgs8gxx_read_reg(priv, 0x95, &t);
+       dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
+
+       return 0;
+}
+
+static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
+{
+       u8 t;
+       s16 v = 0;
+
+       dprintk("%s\n", __func__);
+
+       lgs8gxx_read_reg(priv, 0xB1, &t);
+       v |= t;
+       v <<= 8;
+       lgs8gxx_read_reg(priv, 0xB0, &t);
+       v |= t;
+
+       *signal = v;
+       dprintk("%s: signal=0x%02X\n", __func__, *signal);
+
+       return 0;
+}
+
+static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+               return lgs8913_read_signal_strength(priv, signal);
+       else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+               return lgs8g75_read_signal_strength(priv, signal);
+       else
+               return lgs8gxx_read_signal_agc(priv, signal);
+}
+
+static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+       u8 t;
+       *snr = 0;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+               lgs8gxx_read_reg(priv, 0x34, &t);
+       else
+               lgs8gxx_read_reg(priv, 0x95, &t);
+       dprintk("AVG Noise=0x%02X\n", t);
+       *snr = 256 - t;
+       *snr <<= 8;
+       dprintk("snr=0x%x\n", *snr);
+
+       return 0;
+}
+
+static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
+       return 0;
+}
+
+static void packet_counter_start(struct lgs8gxx_state *priv)
+{
+       u8 orig, t;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_read_reg(priv, 0x30, &orig);
+               orig &= 0xE7;
+               t = orig | 0x10;
+               lgs8gxx_write_reg(priv, 0x30, t);
+               t = orig | 0x18;
+               lgs8gxx_write_reg(priv, 0x30, t);
+               t = orig | 0x10;
+               lgs8gxx_write_reg(priv, 0x30, t);
+       } else {
+               lgs8gxx_write_reg(priv, 0xC6, 0x01);
+               lgs8gxx_write_reg(priv, 0xC6, 0x41);
+               lgs8gxx_write_reg(priv, 0xC6, 0x01);
+       }
+}
+
+static void packet_counter_stop(struct lgs8gxx_state *priv)
+{
+       u8 t;
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               lgs8gxx_read_reg(priv, 0x30, &t);
+               t &= 0xE7;
+               lgs8gxx_write_reg(priv, 0x30, t);
+       } else {
+               lgs8gxx_write_reg(priv, 0xC6, 0x81);
+       }
+}
+
+static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+       u8 reg_err, reg_total, t;
+       u32 total_cnt = 0, err_cnt = 0;
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       packet_counter_start(priv);
+       msleep(200);
+       packet_counter_stop(priv);
+
+       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+               reg_total = 0x28; reg_err = 0x2C;
+       } else {
+               reg_total = 0xD0; reg_err = 0xD4;
+       }
+
+       for (i = 0; i < 4; i++) {
+               total_cnt <<= 8;
+               lgs8gxx_read_reg(priv, reg_total+3-i, &t);
+               total_cnt |= t;
+       }
+       for (i = 0; i < 4; i++) {
+               err_cnt <<= 8;
+               lgs8gxx_read_reg(priv, reg_err+3-i, &t);
+               err_cnt |= t;
+       }
+       dprintk("error=%d total=%d\n", err_cnt, total_cnt);
+
+       if (total_cnt == 0)
+               *ber = 0;
+       else
+               *ber = err_cnt * 100 / total_cnt;
+
+       dprintk("%s: ber=0x%x\n", __func__, *ber);
+       return 0;
+}
+
+static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+       if (priv->config->tuner_address == 0)
+               return 0;
+       if (enable) {
+               u8 v = 0x80 | priv->config->tuner_address;
+               return lgs8gxx_write_reg(priv, 0x01, v);
+       }
+       return lgs8gxx_write_reg(priv, 0x01, 0);
+}
+
+static struct dvb_frontend_ops lgs8gxx_ops = {
+       .delsys = { SYS_DTMB },
+       .info = {
+               .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
+               .frequency_min = 474000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 10000,
+               .caps =
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO
+       },
+
+       .release = lgs8gxx_release,
+
+       .init = lgs8gxx_init,
+       .write = lgs8gxx_write,
+       .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
+
+       .set_frontend = lgs8gxx_set_fe,
+       .get_frontend = lgs8gxx_get_fe,
+       .get_tune_settings = lgs8gxx_get_tune_settings,
+
+       .read_status = lgs8gxx_read_status,
+       .read_ber = lgs8gxx_read_ber,
+       .read_signal_strength = lgs8gxx_read_signal_strength,
+       .read_snr = lgs8gxx_read_snr,
+       .read_ucblocks = lgs8gxx_read_ucblocks,
+};
+
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+       struct i2c_adapter *i2c)
+{
+       struct lgs8gxx_state *priv = NULL;
+       u8 data = 0;
+
+       dprintk("%s()\n", __func__);
+
+       if (config == NULL || i2c == NULL)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
+       if (priv == NULL)
+               goto error_out;
+
+       priv->config = config;
+       priv->i2c = i2c;
+
+       /* check if the demod is there */
+       if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
+               dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
+                       __func__, priv->config->demod_address);
+               goto error_out;
+       }
+
+       lgs8gxx_read_reg(priv, 1, &data);
+
+       memcpy(&priv->frontend.ops, &lgs8gxx_ops,
+              sizeof(struct dvb_frontend_ops));
+       priv->frontend.demodulator_priv = priv;
+
+       if (config->prod == LGS8GXX_PROD_LGS8G75)
+               lgs8g75_init_data(priv);
+
+       return &priv->frontend;
+
+error_out:
+       dprintk("%s() error_out\n", __func__);
+       kfree(priv);
+       return NULL;
+
+}
+EXPORT_SYMBOL(lgs8gxx_attach);
+
+MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(LGS8GXX_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/lgs8gxx.h b/drivers/media/dvb-frontends/lgs8gxx.h
new file mode 100644 (file)
index 0000000..33c3c5e
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LGS8GXX_H__
+#define __LGS8GXX_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define LGS8GXX_PROD_LGS8913 0
+#define LGS8GXX_PROD_LGS8GL5 1
+#define LGS8GXX_PROD_LGS8G42 3
+#define LGS8GXX_PROD_LGS8G52 4
+#define LGS8GXX_PROD_LGS8G54 5
+#define LGS8GXX_PROD_LGS8G75 6
+
+struct lgs8gxx_config {
+
+       /* product type */
+       u8 prod;
+
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* parallel or serial transport stream */
+       u8 serial_ts;
+
+       /* transport stream polarity*/
+       u8 ts_clk_pol;
+
+       /* transport stream clock gated by ts_valid */
+       u8 ts_clk_gated;
+
+       /* A/D Clock frequency */
+       u32 if_clk_freq; /* in kHz */
+
+       /* IF frequency */
+       u32 if_freq; /* in kHz */
+
+       /*Use External ADC*/
+       u8 ext_adc;
+
+       /*External ADC output two's complement*/
+       u8 adc_signed;
+
+       /*Sample IF data at falling edge of IF_CLK*/
+       u8 if_neg_edge;
+
+       /*IF use Negative center frequency*/
+       u8 if_neg_center;
+
+       /*8G75 internal ADC input range selection*/
+       /*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
+       u8 adc_vpp;
+
+       /* slave address and configuration of the tuner */
+       u8 tuner_address;
+};
+
+#if defined(CONFIG_DVB_LGS8GXX) || \
+       (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+                                   struct i2c_adapter *i2c) {
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_LGS8GXX */
+
+#endif /* __LGS8GXX_H__ */
diff --git a/drivers/media/dvb-frontends/lgs8gxx_priv.h b/drivers/media/dvb-frontends/lgs8gxx_priv.h
new file mode 100644 (file)
index 0000000..8ef376f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef LGS8913_PRIV_H
+#define LGS8913_PRIV_H
+
+struct lgs8gxx_state {
+       struct i2c_adapter *i2c;
+       /* configuration settings */
+       const struct lgs8gxx_config *config;
+       struct dvb_frontend frontend;
+       u16 curr_gi; /* current guard interval */
+};
+
+#define SC_MASK                0x1C    /* Sub-Carrier Modulation Mask */
+#define SC_QAM64       0x10    /* 64QAM modulation */
+#define SC_QAM32       0x0C    /* 32QAM modulation */
+#define SC_QAM16       0x08    /* 16QAM modulation */
+#define SC_QAM4NR      0x04    /* 4QAM-NR modulation */
+#define SC_QAM4                0x00    /* 4QAM modulation */
+
+#define LGS_FEC_MASK   0x03    /* FEC Rate Mask */
+#define LGS_FEC_0_4    0x00    /* FEC Rate 0.4 */
+#define LGS_FEC_0_6    0x01    /* FEC Rate 0.6 */
+#define LGS_FEC_0_8    0x02    /* FEC Rate 0.8 */
+
+#define TIM_MASK         0x20  /* Time Interleave Length Mask */
+#define TIM_LONG         0x20  /* Time Interleave Length = 720 */
+#define TIM_MIDDLE     0x00   /* Time Interleave Length = 240 */
+
+#define CF_MASK        0x80    /* Control Frame Mask */
+#define CF_EN  0x80    /* Control Frame On */
+
+#define GI_MASK        0x03    /* Guard Interval Mask */
+#define GI_420 0x00    /* 1/9 Guard Interval */
+#define GI_595 0x01    /* */
+#define GI_945 0x02    /* 1/4 Guard Interval */
+
+
+#define TS_PARALLEL    0x00    /* Parallel TS Output a.k.a. SPI */
+#define TS_SERIAL      0x01    /* Serial TS Output a.k.a. SSI */
+#define TS_CLK_NORMAL          0x00    /* MPEG Clock Normal */
+#define TS_CLK_INVERTED                0x02    /* MPEG Clock Inverted */
+#define TS_CLK_GATED           0x00    /* MPEG clock gated */
+#define TS_CLK_FREERUN         0x04    /* MPEG clock free running*/
+
+
+#endif
diff --git a/drivers/media/dvb-frontends/lnbh24.h b/drivers/media/dvb-frontends/lnbh24.h
new file mode 100644 (file)
index 0000000..c059b16
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * lnbh24.h - driver for lnb supply and control ic lnbh24
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LNBH24_H
+#define _LNBH24_H
+
+/* system register bits */
+#define LNBH24_OLF     0x01
+#define LNBH24_OTF     0x02
+#define LNBH24_EN      0x04
+#define LNBH24_VSEL    0x08
+#define LNBH24_LLC     0x10
+#define LNBH24_TEN     0x20
+#define LNBH24_TTX     0x40
+#define LNBH24_PCL     0x80
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+                                                       && defined(MODULE))
+/* override_set and override_clear control which
+   system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear, u8 i2c_addr);
+#else
+static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear, u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c
new file mode 100644 (file)
index 0000000..1343725
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * lnbp21.c - driver for lnb supply and control ic lnbp21
+ *
+ * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "lnbp21.h"
+#include "lnbh24.h"
+
+struct lnbp21 {
+       u8                      config;
+       u8                      override_or;
+       u8                      override_and;
+       struct i2c_adapter      *i2c;
+       u8                      i2c_addr;
+};
+
+static int lnbp21_set_voltage(struct dvb_frontend *fe,
+                                       fe_sec_voltage_t voltage)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
+
+       switch(voltage) {
+       case SEC_VOLTAGE_OFF:
+               break;
+       case SEC_VOLTAGE_13:
+               lnbp21->config |= LNBP21_EN;
+               break;
+       case SEC_VOLTAGE_18:
+               lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       if (arg)
+               lnbp21->config |= LNBP21_LLC;
+       else
+               lnbp21->config &= ~LNBP21_LLC;
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp21_set_tone(struct dvb_frontend *fe,
+                               fe_sec_tone_mode_t tone)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
+       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       switch (tone) {
+       case SEC_TONE_OFF:
+               lnbp21->config &= ~LNBP21_TEN;
+               break;
+       case SEC_TONE_ON:
+               lnbp21->config |= LNBP21_TEN;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void lnbp21_release(struct dvb_frontend *fe)
+{
+       /* LNBP power off */
+       lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free data */
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear, u8 i2c_addr, u8 config)
+{
+       struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
+       if (!lnbp21)
+               return NULL;
+
+       /* default configuration */
+       lnbp21->config = config;
+       lnbp21->i2c = i2c;
+       lnbp21->i2c_addr = i2c_addr;
+       fe->sec_priv = lnbp21;
+
+       /* bits which should be forced to '1' */
+       lnbp21->override_or = override_set;
+
+       /* bits which should be forced to '0' */
+       lnbp21->override_and = ~override_clear;
+
+       /* detect if it is present or not */
+       if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+               kfree(lnbp21);
+               return NULL;
+       }
+
+       /* install release callback */
+       fe->ops.release_sec = lnbp21_release;
+
+       /* override frontend ops */
+       fe->ops.set_voltage = lnbp21_set_voltage;
+       fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+       if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
+               fe->ops.set_tone = lnbp21_set_tone;
+       printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
+
+       return fe;
+}
+
+struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear, u8 i2c_addr)
+{
+       return lnbx2x_attach(fe, i2c, override_set, override_clear,
+                                                       i2c_addr, LNBH24_TTX);
+}
+EXPORT_SYMBOL(lnbh24_attach);
+
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear)
+{
+       return lnbx2x_attach(fe, i2c, override_set, override_clear,
+                                                       0x08, LNBP21_ISEL);
+}
+EXPORT_SYMBOL(lnbp21_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
+MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/lnbp21.h b/drivers/media/dvb-frontends/lnbp21.h
new file mode 100644 (file)
index 0000000..fcdf1c6
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * lnbp21.h - driver for lnb supply and control ic lnbp21
+ *
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _LNBP21_H
+#define _LNBP21_H
+
+/* system register bits */
+/* [RO] 0=OK; 1=over current limit flag */
+#define LNBP21_OLF     0x01
+/* [RO] 0=OK; 1=over temperature flag (150 C) */
+#define LNBP21_OTF     0x02
+/* [RW] 0=disable LNB power, enable loopthrough
+       1=enable LNB power, disable loopthrough */
+#define LNBP21_EN      0x04
+/* [RW] 0=low voltage (13/14V, vert pol)
+       1=high voltage (18/19V,horiz pol) */
+#define LNBP21_VSEL    0x08
+/* [RW] increase LNB voltage by 1V:
+       0=13/18V; 1=14/19V */
+#define LNBP21_LLC     0x10
+/* [RW] 0=tone controlled by DSQIN pin
+       1=tone enable, disable DSQIN */
+#define LNBP21_TEN     0x20
+/* [RW] current limit select:
+       0:Iout=500-650mA Isc=300mA
+       1:Iout=400-550mA Isc=200mA */
+#define LNBP21_ISEL    0x40
+/* [RW] short-circuit protect:
+       0=pulsed (dynamic) curr limiting
+       1=static curr limiting */
+#define LNBP21_PCL     0x80
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+                                                       && defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear);
+#else
+static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+                               struct i2c_adapter *i2c, u8 override_set,
+                               u8 override_clear)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c
new file mode 100644 (file)
index 0000000..84ad039
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * lnbp22.h - driver for lnb supply and control ic lnbp22
+ *
+ * Copyright (C) 2006 Dominik Kuhlen
+ * Based on lnbp21 driver
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "lnbp22.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+
+#define dprintk(lvl, arg...) if (debug >= (lvl)) printk(arg)
+
+struct lnbp22 {
+       u8                  config[4];
+       struct i2c_adapter *i2c;
+};
+
+static int lnbp22_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct lnbp22 *lnbp22 = (struct lnbp22 *)fe->sec_priv;
+       struct i2c_msg msg = {
+               .addr = 0x08,
+               .flags = 0,
+               .buf = (char *)&lnbp22->config,
+               .len = sizeof(lnbp22->config),
+       };
+
+       dprintk(1, "%s: %d (18V=%d 13V=%d)\n", __func__, voltage,
+              SEC_VOLTAGE_18, SEC_VOLTAGE_13);
+
+       lnbp22->config[3] = 0x60; /* Power down */
+       switch (voltage) {
+       case SEC_VOLTAGE_OFF:
+               break;
+       case SEC_VOLTAGE_13:
+               lnbp22->config[3] |= LNBP22_EN;
+               break;
+       case SEC_VOLTAGE_18:
+               lnbp22->config[3] |= (LNBP22_EN | LNBP22_VSEL);
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       dprintk(1, "%s: 0x%02x)\n", __func__, lnbp22->config[3]);
+       return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp22_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct lnbp22 *lnbp22 = (struct lnbp22 *) fe->sec_priv;
+       struct i2c_msg msg = {
+               .addr = 0x08,
+               .flags = 0,
+               .buf = (char *)&lnbp22->config,
+               .len = sizeof(lnbp22->config),
+       };
+
+       dprintk(1, "%s: %d\n", __func__, (int)arg);
+       if (arg)
+               lnbp22->config[3] |= LNBP22_LLC;
+       else
+               lnbp22->config[3] &= ~LNBP22_LLC;
+
+       return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void lnbp22_release(struct dvb_frontend *fe)
+{
+       dprintk(1, "%s\n", __func__);
+       /* LNBP power off */
+       lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free data */
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
+                                       struct i2c_adapter *i2c)
+{
+       struct lnbp22 *lnbp22 = kmalloc(sizeof(struct lnbp22), GFP_KERNEL);
+       if (!lnbp22)
+               return NULL;
+
+       /* default configuration */
+       lnbp22->config[0] = 0x00; /* ? */
+       lnbp22->config[1] = 0x28; /* ? */
+       lnbp22->config[2] = 0x48; /* ? */
+       lnbp22->config[3] = 0x60; /* Power down */
+       lnbp22->i2c = i2c;
+       fe->sec_priv = lnbp22;
+
+       /* detect if it is present or not */
+       if (lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+               dprintk(0, "%s LNBP22 not found\n", __func__);
+               kfree(lnbp22);
+               fe->sec_priv = NULL;
+               return NULL;
+       }
+
+       /* install release callback */
+       fe->ops.release_sec = lnbp22_release;
+
+       /* override frontend ops */
+       fe->ops.set_voltage = lnbp22_set_voltage;
+       fe->ops.enable_high_lnb_voltage = lnbp22_enable_high_lnb_voltage;
+
+       return fe;
+}
+EXPORT_SYMBOL(lnbp22_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22");
+MODULE_AUTHOR("Dominik Kuhlen");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/lnbp22.h b/drivers/media/dvb-frontends/lnbp22.h
new file mode 100644 (file)
index 0000000..63e2dec
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * lnbp22.h - driver for lnb supply and control ic lnbp22
+ *
+ * Copyright (C) 2006 Dominik Kuhlen
+ * Based on lnbp21.h
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _LNBP22_H
+#define _LNBP22_H
+
+/* Enable */
+#define LNBP22_EN        0x10
+/* Voltage selection */
+#define LNBP22_VSEL    0x02
+/* Plus 1 Volt Bit */
+#define LNBP22_LLC     0x01
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP22) || \
+               (defined(CONFIG_DVB_LNBP22_MODULE) && defined(MODULE))
+/*
+ * override_set and override_clear control which system register bits (above)
+ * to always set & clear
+ */
+extern struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
+                                               struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
+                                               struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_LNBP22 */
+
+#endif /* _LNBP22_H */
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
new file mode 100644 (file)
index 0000000..633815e
--- /dev/null
@@ -0,0 +1,919 @@
+/*
+       Driver for M88RS2000 demodulator and tuner
+
+       Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
+       Beta Driver
+
+       Include various calculation code from DS3000 driver.
+       Copyright (C) 2009 Konstantin Dimitrov.
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+
+#include "dvb_frontend.h"
+#include "m88rs2000.h"
+
+struct m88rs2000_state {
+       struct i2c_adapter *i2c;
+       const struct m88rs2000_config *config;
+       struct dvb_frontend frontend;
+       u8 no_lock_count;
+       u32 tuner_frequency;
+       u32 symbol_rate;
+       fe_code_rate_t fec_inner;
+       u8 tuner_level;
+       int errmode;
+};
+
+static int m88rs2000_debug;
+
+module_param_named(debug, m88rs2000_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define dprintk(level, args...) do { \
+       if (level & m88rs2000_debug) \
+               printk(KERN_DEBUG "m88rs2000-fe: " args); \
+} while (0)
+
+#define deb_info(args...)  dprintk(0x01, args)
+#define info(format, arg...) \
+       printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)
+
+static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
+       u8 reg, u8 data)
+{
+       int ret;
+       u8 addr = (tuner == 0) ? state->config->tuner_addr :
+               state->config->demod_addr;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = addr,
+               .flags = 0,
+               .buf = buf,
+               .len = 2
+       };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
+                       "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data)
+{
+       return m88rs2000_writereg(state, 1, reg, data);
+}
+
+static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data)
+{
+       m88rs2000_demod_write(state, 0x81, 0x84);
+       udelay(10);
+       return m88rs2000_writereg(state, 0, reg, data);
+
+}
+
+static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return m88rs2000_writereg(state, 1, buf[0], buf[1]);
+}
+
+static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       u8 addr = (tuner == 0) ? state->config->tuner_addr :
+               state->config->demod_addr;
+       struct i2c_msg msg[] = {
+               {
+                       .addr = addr,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = addr,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n",
+                               __func__, reg, ret);
+
+       return b1[0];
+}
+
+static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
+{
+       return m88rs2000_readreg(state, 1, reg);
+}
+
+static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
+{
+       m88rs2000_demod_write(state, 0x81, 0x85);
+       udelay(10);
+       return m88rs2000_readreg(state, 0, reg);
+}
+
+static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       int ret;
+       u32 temp;
+       u8 b[3];
+
+       if ((srate < 1000000) || (srate > 45000000))
+               return -EINVAL;
+
+       temp = srate / 1000;
+       temp *= 11831;
+       temp /= 68;
+       temp -= 3;
+
+       b[0] = (u8) (temp >> 16) & 0xff;
+       b[1] = (u8) (temp >> 8) & 0xff;
+       b[2] = (u8) temp & 0xff;
+       ret = m88rs2000_demod_write(state, 0x93, b[2]);
+       ret |= m88rs2000_demod_write(state, 0x94, b[1]);
+       ret |= m88rs2000_demod_write(state, 0x95, b[0]);
+
+       deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
+       return ret;
+}
+
+static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+
+       int i;
+       u8 reg;
+       deb_info("%s\n", __func__);
+       m88rs2000_demod_write(state, 0x9a, 0x30);
+       reg = m88rs2000_demod_read(state, 0xb2);
+       reg &= 0x3f;
+       m88rs2000_demod_write(state, 0xb2, reg);
+       for (i = 0; i <  m->msg_len; i++)
+               m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]);
+
+       reg = m88rs2000_demod_read(state, 0xb1);
+       reg &= 0x87;
+       reg |= ((m->msg_len - 1) << 3) | 0x07;
+       reg &= 0x7f;
+       m88rs2000_demod_write(state, 0xb1, reg);
+
+       for (i = 0; i < 15; i++) {
+               if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0)
+                       break;
+               msleep(20);
+       }
+
+       reg = m88rs2000_demod_read(state, 0xb1);
+       if ((reg & 0x40) > 0x0) {
+               reg &= 0x7f;
+               reg |= 0x40;
+               m88rs2000_demod_write(state, 0xb1, reg);
+       }
+
+       reg = m88rs2000_demod_read(state, 0xb2);
+       reg &= 0x3f;
+       reg |= 0x80;
+       m88rs2000_demod_write(state, 0xb2, reg);
+       m88rs2000_demod_write(state, 0x9a, 0xb0);
+
+
+       return 0;
+}
+
+static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
+                                               fe_sec_mini_cmd_t burst)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       u8 reg0, reg1;
+       deb_info("%s\n", __func__);
+       m88rs2000_demod_write(state, 0x9a, 0x30);
+       msleep(50);
+       reg0 = m88rs2000_demod_read(state, 0xb1);
+       reg1 = m88rs2000_demod_read(state, 0xb2);
+       /* TODO complete this section */
+       m88rs2000_demod_write(state, 0xb2, reg1);
+       m88rs2000_demod_write(state, 0xb1, reg0);
+       m88rs2000_demod_write(state, 0x9a, 0xb0);
+
+       return 0;
+}
+
+static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       u8 reg0, reg1;
+       m88rs2000_demod_write(state, 0x9a, 0x30);
+       reg0 = m88rs2000_demod_read(state, 0xb1);
+       reg1 = m88rs2000_demod_read(state, 0xb2);
+
+       reg1 &= 0x3f;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               reg0 |= 0x4;
+               reg0 &= 0xbc;
+               break;
+       case SEC_TONE_OFF:
+               reg1 |= 0x80;
+               break;
+       default:
+               break;
+       }
+       m88rs2000_demod_write(state, 0xb2, reg1);
+       m88rs2000_demod_write(state, 0xb1, reg0);
+       m88rs2000_demod_write(state, 0x9a, 0xb0);
+       return 0;
+}
+
+struct inittab {
+       u8 cmd;
+       u8 reg;
+       u8 val;
+};
+
+struct inittab m88rs2000_setup[] = {
+       {DEMOD_WRITE, 0x9a, 0x30},
+       {DEMOD_WRITE, 0x00, 0x01},
+       {WRITE_DELAY, 0x19, 0x00},
+       {DEMOD_WRITE, 0x00, 0x00},
+       {DEMOD_WRITE, 0x9a, 0xb0},
+       {DEMOD_WRITE, 0x81, 0xc1},
+       {TUNER_WRITE, 0x42, 0x73},
+       {TUNER_WRITE, 0x05, 0x07},
+       {TUNER_WRITE, 0x20, 0x27},
+       {TUNER_WRITE, 0x07, 0x02},
+       {TUNER_WRITE, 0x11, 0xff},
+       {TUNER_WRITE, 0x60, 0xf9},
+       {TUNER_WRITE, 0x08, 0x01},
+       {TUNER_WRITE, 0x00, 0x41},
+       {DEMOD_WRITE, 0x81, 0x81},
+       {DEMOD_WRITE, 0x86, 0xc6},
+       {DEMOD_WRITE, 0x9a, 0x30},
+       {DEMOD_WRITE, 0xf0, 0x22},
+       {DEMOD_WRITE, 0xf1, 0xbf},
+       {DEMOD_WRITE, 0xb0, 0x45},
+       {DEMOD_WRITE, 0xb2, 0x01}, /* set voltage pin always set 1*/
+       {DEMOD_WRITE, 0x9a, 0xb0},
+       {0xff, 0xaa, 0xff}
+};
+
+struct inittab m88rs2000_shutdown[] = {
+       {DEMOD_WRITE, 0x9a, 0x30},
+       {DEMOD_WRITE, 0xb0, 0x00},
+       {DEMOD_WRITE, 0xf1, 0x89},
+       {DEMOD_WRITE, 0x00, 0x01},
+       {DEMOD_WRITE, 0x9a, 0xb0},
+       {TUNER_WRITE, 0x00, 0x40},
+       {DEMOD_WRITE, 0x81, 0x81},
+       {0xff, 0xaa, 0xff}
+};
+
+struct inittab tuner_reset[] = {
+       {TUNER_WRITE, 0x42, 0x73},
+       {TUNER_WRITE, 0x05, 0x07},
+       {TUNER_WRITE, 0x20, 0x27},
+       {TUNER_WRITE, 0x07, 0x02},
+       {TUNER_WRITE, 0x11, 0xff},
+       {TUNER_WRITE, 0x60, 0xf9},
+       {TUNER_WRITE, 0x08, 0x01},
+       {TUNER_WRITE, 0x00, 0x41},
+       {0xff, 0xaa, 0xff}
+};
+
+struct inittab fe_reset[] = {
+       {DEMOD_WRITE, 0x00, 0x01},
+       {DEMOD_WRITE, 0xf1, 0xbf},
+       {DEMOD_WRITE, 0x00, 0x01},
+       {DEMOD_WRITE, 0x20, 0x81},
+       {DEMOD_WRITE, 0x21, 0x80},
+       {DEMOD_WRITE, 0x10, 0x33},
+       {DEMOD_WRITE, 0x11, 0x44},
+       {DEMOD_WRITE, 0x12, 0x07},
+       {DEMOD_WRITE, 0x18, 0x20},
+       {DEMOD_WRITE, 0x28, 0x04},
+       {DEMOD_WRITE, 0x29, 0x8e},
+       {DEMOD_WRITE, 0x3b, 0xff},
+       {DEMOD_WRITE, 0x32, 0x10},
+       {DEMOD_WRITE, 0x33, 0x02},
+       {DEMOD_WRITE, 0x34, 0x30},
+       {DEMOD_WRITE, 0x35, 0xff},
+       {DEMOD_WRITE, 0x38, 0x50},
+       {DEMOD_WRITE, 0x39, 0x68},
+       {DEMOD_WRITE, 0x3c, 0x7f},
+       {DEMOD_WRITE, 0x3d, 0x0f},
+       {DEMOD_WRITE, 0x45, 0x20},
+       {DEMOD_WRITE, 0x46, 0x24},
+       {DEMOD_WRITE, 0x47, 0x7c},
+       {DEMOD_WRITE, 0x48, 0x16},
+       {DEMOD_WRITE, 0x49, 0x04},
+       {DEMOD_WRITE, 0x4a, 0x01},
+       {DEMOD_WRITE, 0x4b, 0x78},
+       {DEMOD_WRITE, 0X4d, 0xd2},
+       {DEMOD_WRITE, 0x4e, 0x6d},
+       {DEMOD_WRITE, 0x50, 0x30},
+       {DEMOD_WRITE, 0x51, 0x30},
+       {DEMOD_WRITE, 0x54, 0x7b},
+       {DEMOD_WRITE, 0x56, 0x09},
+       {DEMOD_WRITE, 0x58, 0x59},
+       {DEMOD_WRITE, 0x59, 0x37},
+       {DEMOD_WRITE, 0x63, 0xfa},
+       {0xff, 0xaa, 0xff}
+};
+
+struct inittab fe_trigger[] = {
+       {DEMOD_WRITE, 0x97, 0x04},
+       {DEMOD_WRITE, 0x99, 0x77},
+       {DEMOD_WRITE, 0x9b, 0x64},
+       {DEMOD_WRITE, 0x9e, 0x00},
+       {DEMOD_WRITE, 0x9f, 0xf8},
+       {DEMOD_WRITE, 0xa0, 0x20},
+       {DEMOD_WRITE, 0xa1, 0xe0},
+       {DEMOD_WRITE, 0xa3, 0x38},
+       {DEMOD_WRITE, 0x98, 0xff},
+       {DEMOD_WRITE, 0xc0, 0x0f},
+       {DEMOD_WRITE, 0x89, 0x01},
+       {DEMOD_WRITE, 0x00, 0x00},
+       {WRITE_DELAY, 0x0a, 0x00},
+       {DEMOD_WRITE, 0x00, 0x01},
+       {DEMOD_WRITE, 0x00, 0x00},
+       {DEMOD_WRITE, 0x9a, 0xb0},
+       {0xff, 0xaa, 0xff}
+};
+
+static int m88rs2000_tab_set(struct m88rs2000_state *state,
+               struct inittab *tab)
+{
+       int ret = 0;
+       u8 i;
+       if (tab == NULL)
+               return -EINVAL;
+
+       for (i = 0; i < 255; i++) {
+               switch (tab[i].cmd) {
+               case 0x01:
+                       ret = m88rs2000_demod_write(state, tab[i].reg,
+                               tab[i].val);
+                       break;
+               case 0x02:
+                       ret = m88rs2000_tuner_write(state, tab[i].reg,
+                               tab[i].val);
+                       break;
+               case 0x10:
+                       if (tab[i].reg > 0)
+                               mdelay(tab[i].reg);
+                       break;
+               case 0xff:
+                       if (tab[i].reg == 0xaa && tab[i].val == 0xff)
+                               return 0;
+               case 0x00:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               if (ret < 0)
+                       return -ENODEV;
+       }
+       return 0;
+}
+
+static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       u8 data;
+
+       data = m88rs2000_demod_read(state, 0xb2);
+       data |= 0x03; /* bit0 V/H, bit1 off/on */
+
+       switch (volt) {
+       case SEC_VOLTAGE_18:
+               data &= ~0x03;
+               break;
+       case SEC_VOLTAGE_13:
+               data &= ~0x03;
+               data |= 0x01;
+               break;
+       case SEC_VOLTAGE_OFF:
+               break;
+       }
+
+       m88rs2000_demod_write(state, 0xb2, data);
+
+       return 0;
+}
+
+static int m88rs2000_startup(struct m88rs2000_state *state)
+{
+       int ret = 0;
+       u8 reg;
+
+       reg = m88rs2000_tuner_read(state, 0x00);
+       if ((reg & 0x40) == 0)
+               ret = -ENODEV;
+
+       return ret;
+}
+
+static int m88rs2000_init(struct dvb_frontend *fe)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       int ret;
+
+       deb_info("m88rs2000: init chip\n");
+       /* Setup frontend from shutdown/cold */
+       ret = m88rs2000_tab_set(state, m88rs2000_setup);
+
+       return ret;
+}
+
+static int m88rs2000_sleep(struct dvb_frontend *fe)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       int ret;
+       /* Shutdown the frondend */
+       ret = m88rs2000_tab_set(state, m88rs2000_shutdown);
+       return ret;
+}
+
+static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       u8 reg = m88rs2000_demod_read(state, 0x8c);
+
+       *status = 0;
+
+       if ((reg & 0x7) == 0x7) {
+               *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
+                       | FE_HAS_SYNC | FE_HAS_LOCK;
+               if (state->config->set_ts_params)
+                       state->config->set_ts_params(fe, CALL_IS_READ);
+       }
+       return 0;
+}
+
+/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
+
+static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       deb_info("m88rs2000_read_ber %d\n", *ber);
+       *ber = 0;
+       return 0;
+}
+
+static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
+       u16 *strength)
+{
+       *strength = 0;
+       return 0;
+}
+
+static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       deb_info("m88rs2000_read_snr %d\n", *snr);
+       *snr = 0;
+       return 0;
+}
+
+static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       deb_info("m88rs2000_read_ber %d\n", *ucblocks);
+       *ucblocks = 0;
+       return 0;
+}
+
+static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset)
+{
+       int ret;
+       ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset);
+       ret |= m88rs2000_tuner_write(state, 0x51, 0x1f);
+       ret |= m88rs2000_tuner_write(state, 0x50, offset);
+       ret |= m88rs2000_tuner_write(state, 0x50, 0x00);
+       msleep(20);
+       return ret;
+}
+
+static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       int reg;
+       reg = m88rs2000_tuner_read(state, 0x3d);
+       reg &= 0x7f;
+       if (reg < 0x16)
+               reg = 0xa1;
+       else if (reg == 0x16)
+               reg = 0x99;
+       else
+               reg = 0xf9;
+
+       m88rs2000_tuner_write(state, 0x60, reg);
+       reg = m88rs2000_tuner_gate_ctrl(state, 0x08);
+
+       if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       return reg;
+}
+
+static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       int ret;
+       u32 frequency = c->frequency;
+       s32 offset_khz;
+       s32 tmp;
+       u32 symbol_rate = (c->symbol_rate / 1000);
+       u32 f3db, gdiv28;
+       u16 value, ndiv, lpf_coeff;
+       u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
+       u8 lo = 0x01, div4 = 0x0;
+
+       /* Reset Tuner */
+       ret = m88rs2000_tab_set(state, tuner_reset);
+
+       /* Calculate frequency divider */
+       if (frequency < 1060000) {
+               lo |= 0x10;
+               div4 = 0x1;
+               ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ;
+       } else
+               ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ;
+       ndiv = ndiv + ndiv % 2;
+       ndiv = ndiv - 1024;
+
+       ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo);
+
+       /* Set frequency divider */
+       ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf);
+       ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff);
+
+       ret |= m88rs2000_tuner_write(state, 0x03, 0x06);
+       ret |= m88rs2000_tuner_gate_ctrl(state, 0x10);
+       if (ret < 0)
+               return -ENODEV;
+
+       /* Tuner Frequency Range */
+       ret = m88rs2000_tuner_write(state, 0x10, lo);
+
+       ret |= m88rs2000_tuner_gate_ctrl(state, 0x08);
+
+       /* Tuner RF */
+       ret |= m88rs2000_set_tuner_rf(fe);
+
+       gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
+       ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff);
+       ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
+       if (ret < 0)
+               return -ENODEV;
+
+       value = m88rs2000_tuner_read(state, 0x26);
+
+       f3db = (symbol_rate * 135) / 200 + 2000;
+       f3db += FREQ_OFFSET_LOW_SYM_RATE;
+       if (f3db < 7000)
+               f3db = 7000;
+       if (f3db > 40000)
+               f3db = 40000;
+
+       gdiv28 = gdiv28 * 207 / (value * 2 + 151);
+       mlpf_max = gdiv28 * 135 / 100;
+       mlpf_min = gdiv28 * 78 / 100;
+       if (mlpf_max > 63)
+               mlpf_max = 63;
+
+       lpf_coeff = 2766;
+
+       nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
+               (FE_CRYSTAL_KHZ / 1000)  + 1) / 2;
+       if (nlpf > 23)
+               nlpf = 23;
+       if (nlpf < 1)
+               nlpf = 1;
+
+       lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
+               * lpf_coeff * 2  / f3db + 1) / 2;
+
+       if (lpf_mxdiv < mlpf_min) {
+               nlpf++;
+               lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
+                       * lpf_coeff * 2  / f3db + 1) / 2;
+       }
+
+       if (lpf_mxdiv > mlpf_max)
+               lpf_mxdiv = mlpf_max;
+
+       ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv);
+       ret |= m88rs2000_tuner_write(state, 0x06, nlpf);
+
+       ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
+
+       ret |= m88rs2000_tuner_gate_ctrl(state, 0x01);
+
+       msleep(80);
+       /* calculate offset assuming 96000kHz*/
+       offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ
+               / 14 / (div4 + 1) / 2;
+
+       offset_khz -= frequency;
+
+       tmp = offset_khz;
+       tmp *= 65536;
+
+       tmp = (2 * tmp + 96000) / (2 * 96000);
+       if (tmp < 0)
+               tmp += 65536;
+
+       *offset = tmp & 0xffff;
+
+       if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return (ret < 0) ? -EINVAL : 0;
+}
+
+static int m88rs2000_set_fec(struct m88rs2000_state *state,
+               fe_code_rate_t fec)
+{
+       u16 fec_set;
+       switch (fec) {
+       /* This is not confirmed kept for reference */
+/*     case FEC_1_2:
+               fec_set = 0x88;
+               break;
+       case FEC_2_3:
+               fec_set = 0x68;
+               break;
+       case FEC_3_4:
+               fec_set = 0x48;
+               break;
+       case FEC_5_6:
+               fec_set = 0x28;
+               break;
+       case FEC_7_8:
+               fec_set = 0x18;
+               break; */
+       case FEC_AUTO:
+       default:
+               fec_set = 0x08;
+       }
+       m88rs2000_demod_write(state, 0x76, fec_set);
+
+       return 0;
+}
+
+
+static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
+{
+       u8 reg;
+       m88rs2000_demod_write(state, 0x9a, 0x30);
+       reg = m88rs2000_demod_read(state, 0x76);
+       m88rs2000_demod_write(state, 0x9a, 0xb0);
+
+       switch (reg) {
+       case 0x88:
+               return FEC_1_2;
+       case 0x68:
+               return FEC_2_3;
+       case 0x48:
+               return FEC_3_4;
+       case 0x28:
+               return FEC_5_6;
+       case 0x18:
+               return FEC_7_8;
+       case 0x08:
+       default:
+               break;
+       }
+
+       return FEC_AUTO;
+}
+
+static int m88rs2000_set_frontend(struct dvb_frontend *fe)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       fe_status_t status;
+       int i, ret;
+       u16 offset = 0;
+       u8 reg;
+
+       state->no_lock_count = 0;
+
+       if (c->delivery_system != SYS_DVBS) {
+                       deb_info("%s: unsupported delivery "
+                               "system selected (%d)\n",
+                               __func__, c->delivery_system);
+                       return -EOPNOTSUPP;
+       }
+
+       /* Set Tuner */
+       ret = m88rs2000_set_tuner(fe, &offset);
+       if (ret < 0)
+               return -ENODEV;
+
+       ret = m88rs2000_demod_write(state, 0x9a, 0x30);
+       /* Unknown usually 0xc6 sometimes 0xc1 */
+       reg = m88rs2000_demod_read(state, 0x86);
+       ret |= m88rs2000_demod_write(state, 0x86, reg);
+       /* Offset lower nibble always 0 */
+       ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8));
+       ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0);
+
+
+       /* Reset Demod */
+       ret = m88rs2000_tab_set(state, fe_reset);
+       if (ret < 0)
+               return -ENODEV;
+
+       /* Unknown */
+       reg = m88rs2000_demod_read(state, 0x70);
+       ret = m88rs2000_demod_write(state, 0x70, reg);
+
+       /* Set FEC */
+       ret |= m88rs2000_set_fec(state, c->fec_inner);
+       ret |= m88rs2000_demod_write(state, 0x85, 0x1);
+       ret |= m88rs2000_demod_write(state, 0x8a, 0xbf);
+       ret |= m88rs2000_demod_write(state, 0x8d, 0x1e);
+       ret |= m88rs2000_demod_write(state, 0x90, 0xf1);
+       ret |= m88rs2000_demod_write(state, 0x91, 0x08);
+
+       if (ret < 0)
+               return -ENODEV;
+
+       /* Set Symbol Rate */
+       ret = m88rs2000_set_symbolrate(fe, c->symbol_rate);
+       if (ret < 0)
+               return -ENODEV;
+
+       /* Set up Demod */
+       ret = m88rs2000_tab_set(state, fe_trigger);
+       if (ret < 0)
+               return -ENODEV;
+
+       for (i = 0; i < 25; i++) {
+               reg = m88rs2000_demod_read(state, 0x8c);
+               if ((reg & 0x7) == 0x7) {
+                       status = FE_HAS_LOCK;
+                       break;
+               }
+               state->no_lock_count++;
+               if (state->no_lock_count == 15) {
+                       reg = m88rs2000_demod_read(state, 0x70);
+                       reg ^= 0x4;
+                       m88rs2000_demod_write(state, 0x70, reg);
+                       state->no_lock_count = 0;
+               }
+               if (state->no_lock_count == 20)
+                       m88rs2000_set_tuner_rf(fe);
+               msleep(20);
+       }
+
+       if (status & FE_HAS_LOCK) {
+               state->fec_inner = m88rs2000_get_fec(state);
+               /* Uknown suspect SNR level */
+               reg = m88rs2000_demod_read(state, 0x65);
+       }
+
+       state->tuner_frequency = c->frequency;
+       state->symbol_rate = c->symbol_rate;
+       return 0;
+}
+
+static int m88rs2000_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       c->fec_inner = state->fec_inner;
+       c->frequency = state->tuner_frequency;
+       c->symbol_rate = state->symbol_rate;
+       return 0;
+}
+
+static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+
+       if (enable)
+               m88rs2000_demod_write(state, 0x81, 0x84);
+       else
+               m88rs2000_demod_write(state, 0x81, 0x81);
+       udelay(10);
+       return 0;
+}
+
+static void m88rs2000_release(struct dvb_frontend *fe)
+{
+       struct m88rs2000_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops m88rs2000_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "M88RS2000 DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
+               .frequency_tolerance    = 5000,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                     FE_CAN_QPSK |
+                     FE_CAN_FEC_AUTO
+       },
+
+       .release = m88rs2000_release,
+       .init = m88rs2000_init,
+       .sleep = m88rs2000_sleep,
+       .write = m88rs2000_write,
+       .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
+       .read_status = m88rs2000_read_status,
+       .read_ber = m88rs2000_read_ber,
+       .read_signal_strength = m88rs2000_read_signal_strength,
+       .read_snr = m88rs2000_read_snr,
+       .read_ucblocks = m88rs2000_read_ucblocks,
+       .diseqc_send_master_cmd = m88rs2000_send_diseqc_msg,
+       .diseqc_send_burst = m88rs2000_send_diseqc_burst,
+       .set_tone = m88rs2000_set_tone,
+       .set_voltage = m88rs2000_set_voltage,
+
+       .set_frontend = m88rs2000_set_frontend,
+       .get_frontend = m88rs2000_get_frontend,
+};
+
+struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct m88rs2000_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->tuner_frequency = 0;
+       state->symbol_rate = 0;
+       state->fec_inner = 0;
+
+       if (m88rs2000_startup(state) < 0)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &m88rs2000_ops,
+                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(m88rs2000_attach);
+
+MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver");
+MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.13");
+
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
new file mode 100644 (file)
index 0000000..59acdb6
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+       Driver for M88RS2000 demodulator
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef M88RS2000_H
+#define M88RS2000_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct m88rs2000_config {
+       /* Demodulator i2c address */
+       u8 demod_addr;
+       /* Tuner address */
+       u8 tuner_addr;
+
+       u8 *inittab;
+
+       /* minimum delay before retuning */
+       int min_delay_ms;
+
+       int (*set_ts_params)(struct dvb_frontend *, int);
+};
+
+enum {
+       CALL_IS_SET_FRONTEND = 0x0,
+       CALL_IS_READ,
+};
+
+#if defined(CONFIG_DVB_M88RS2000) || (defined(CONFIG_DVB_M88RS2000_MODULE) && \
+                                                       defined(MODULE))
+extern struct dvb_frontend *m88rs2000_attach(
+       const struct m88rs2000_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *m88rs2000_attach(
+       const struct m88rs2000_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_M88RS2000 */
+
+#define FE_CRYSTAL_KHZ 27000
+#define FREQ_OFFSET_LOW_SYM_RATE 3000
+
+enum {
+       DEMOD_WRITE = 0x1,
+       TUNER_WRITE,
+       WRITE_DELAY = 0x10,
+};
+#endif /* M88RS2000_H */
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
new file mode 100644 (file)
index 0000000..9ae40ab
--- /dev/null
@@ -0,0 +1,1878 @@
+/*
+       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "mb86a16.h"
+#include "mb86a16_priv.h"
+
+unsigned int verbose = 5;
+module_param(verbose, int, 0644);
+
+#define ABS(x)         ((x) < 0 ? (-x) : (x))
+
+struct mb86a16_state {
+       struct i2c_adapter              *i2c_adap;
+       const struct mb86a16_config     *config;
+       struct dvb_frontend             frontend;
+
+       /* tuning parameters */
+       int                             frequency;
+       int                             srate;
+
+       /* Internal stuff */
+       int                             master_clk;
+       int                             deci;
+       int                             csel;
+       int                             rsel;
+};
+
+#define MB86A16_ERROR          0
+#define MB86A16_NOTICE         1
+#define MB86A16_INFO           2
+#define MB86A16_DEBUG          3
+
+#define dprintk(x, y, z, format, arg...) do {                                          \
+       if (z) {                                                                        \
+               if      ((x > MB86A16_ERROR) && (x > y))                                \
+                       printk(KERN_ERR "%s: " format "\n", __func__, ##arg);           \
+               else if ((x > MB86A16_NOTICE) && (x > y))                               \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg);        \
+               else if ((x > MB86A16_INFO) && (x > y))                                 \
+                       printk(KERN_INFO "%s: " format "\n", __func__, ##arg);          \
+               else if ((x > MB86A16_DEBUG) && (x > y))                                \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg);         \
+       } else {                                                                        \
+               if (x > y)                                                              \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while (0)
+
+#define TRACE_IN       dprintk(verbose, MB86A16_DEBUG, 1, "-->()")
+#define TRACE_OUT      dprintk(verbose, MB86A16_DEBUG, 1, "()-->")
+
+static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val)
+{
+       int ret;
+       u8 buf[] = { reg, val };
+
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 2
+       };
+
+       dprintk(verbose, MB86A16_DEBUG, 1,
+               "writing to [0x%02x],Reg[0x%02x],Data[0x%02x]",
+               state->config->demod_address, buf[0], buf[1]);
+
+       ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+       ret = i2c_transfer(state->i2c_adap, msg, 2);
+       if (ret != 2) {
+               dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
+                       reg, ret);
+
+               return -EREMOTEIO;
+       }
+       *val = b1[0];
+
+       return ret;
+}
+
+static int CNTM_set(struct mb86a16_state *state,
+                   unsigned char timint1,
+                   unsigned char timint2,
+                   unsigned char cnext)
+{
+       unsigned char val;
+
+       val = (timint1 << 4) | (timint2 << 2) | cnext;
+       if (mb86a16_write(state, MB86A16_CNTMR, val) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int smrt_set(struct mb86a16_state *state, int rate)
+{
+       int tmp ;
+       int m ;
+       unsigned char STOFS0, STOFS1;
+
+       m = 1 << state->deci;
+       tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk;
+
+       STOFS0 = tmp & 0x0ff;
+       STOFS1 = (tmp & 0xf00) >> 8;
+
+       if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) |
+                                      (state->csel << 1) |
+                                       state->rsel) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -1;
+}
+
+static int srst(struct mb86a16_state *state)
+{
+       if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+
+}
+
+static int afcex_data_set(struct mb86a16_state *state,
+                         unsigned char AFCEX_L,
+                         unsigned char AFCEX_H)
+{
+       if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+
+       return -1;
+}
+
+static int afcofs_data_set(struct mb86a16_state *state,
+                          unsigned char AFCEX_L,
+                          unsigned char AFCEX_H)
+{
+       if (mb86a16_write(state, 0x58, AFCEX_L) < 0)
+               goto err;
+       if (mb86a16_write(state, 0x59, AFCEX_H) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int stlp_set(struct mb86a16_state *state,
+                   unsigned char STRAS,
+                   unsigned char STRBS)
+{
+       if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA)
+{
+       if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int initial_set(struct mb86a16_state *state)
+{
+       if (stlp_set(state, 5, 7))
+               goto err;
+
+       udelay(100);
+       if (afcex_data_set(state, 0, 0))
+               goto err;
+
+       udelay(100);
+       if (afcofs_data_set(state, 0, 0))
+               goto err;
+
+       udelay(100);
+       if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0)
+               goto err;
+       if (mb86a16_write(state, 0x2f, 0x21) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0)
+               goto err;
+       if (mb86a16_write(state, 0x54, 0xff) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int S01T_set(struct mb86a16_state *state,
+                   unsigned char s1t,
+                   unsigned s0t)
+{
+       if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+
+static int EN_set(struct mb86a16_state *state,
+                 int cren,
+                 int afcen)
+{
+       unsigned char val;
+
+       val = 0x7a | (cren << 7) | (afcen << 2);
+       if (mb86a16_write(state, 0x49, val) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int AFCEXEN_set(struct mb86a16_state *state,
+                      int afcexen,
+                      int smrt)
+{
+       unsigned char AFCA ;
+
+       if (smrt > 18875)
+               AFCA = 4;
+       else if (smrt > 9375)
+               AFCA = 3;
+       else if (smrt > 2250)
+               AFCA = 2;
+       else
+               AFCA = 1;
+
+       if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int DAGC_data_set(struct mb86a16_state *state,
+                        unsigned char DAGCA,
+                        unsigned char DAGCW)
+{
+       if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static void smrt_info_get(struct mb86a16_state *state, int rate)
+{
+       if (rate >= 37501) {
+               state->deci = 0; state->csel = 0; state->rsel = 0;
+       } else if (rate >= 30001) {
+               state->deci = 0; state->csel = 0; state->rsel = 1;
+       } else if (rate >= 26251) {
+               state->deci = 0; state->csel = 1; state->rsel = 0;
+       } else if (rate >= 22501) {
+               state->deci = 0; state->csel = 1; state->rsel = 1;
+       } else if (rate >= 18751) {
+               state->deci = 1; state->csel = 0; state->rsel = 0;
+       } else if (rate >= 15001) {
+               state->deci = 1; state->csel = 0; state->rsel = 1;
+       } else if (rate >= 13126) {
+               state->deci = 1; state->csel = 1; state->rsel = 0;
+       } else if (rate >= 11251) {
+               state->deci = 1; state->csel = 1; state->rsel = 1;
+       } else if (rate >= 9376) {
+               state->deci = 2; state->csel = 0; state->rsel = 0;
+       } else if (rate >= 7501) {
+               state->deci = 2; state->csel = 0; state->rsel = 1;
+       } else if (rate >= 6563) {
+               state->deci = 2; state->csel = 1; state->rsel = 0;
+       } else if (rate >= 5626) {
+               state->deci = 2; state->csel = 1; state->rsel = 1;
+       } else if (rate >= 4688) {
+               state->deci = 3; state->csel = 0; state->rsel = 0;
+       } else if (rate >= 3751) {
+               state->deci = 3; state->csel = 0; state->rsel = 1;
+       } else if (rate >= 3282) {
+               state->deci = 3; state->csel = 1; state->rsel = 0;
+       } else if (rate >= 2814) {
+               state->deci = 3; state->csel = 1; state->rsel = 1;
+       } else if (rate >= 2344) {
+               state->deci = 4; state->csel = 0; state->rsel = 0;
+       } else if (rate >= 1876) {
+               state->deci = 4; state->csel = 0; state->rsel = 1;
+       } else if (rate >= 1641) {
+               state->deci = 4; state->csel = 1; state->rsel = 0;
+       } else if (rate >= 1407) {
+               state->deci = 4; state->csel = 1; state->rsel = 1;
+       } else if (rate >= 1172) {
+               state->deci = 5; state->csel = 0; state->rsel = 0;
+       } else if (rate >=  939) {
+               state->deci = 5; state->csel = 0; state->rsel = 1;
+       } else if (rate >=  821) {
+               state->deci = 5; state->csel = 1; state->rsel = 0;
+       } else {
+               state->deci = 5; state->csel = 1; state->rsel = 1;
+       }
+
+       if (state->csel == 0)
+               state->master_clk = 92000;
+       else
+               state->master_clk = 61333;
+
+}
+
+static int signal_det(struct mb86a16_state *state,
+                     int smrt,
+                     unsigned char *SIG)
+{
+
+       int ret ;
+       int smrtd ;
+       int wait_sym ;
+
+       u32 wait_t;
+       unsigned char S[3] ;
+       int i ;
+
+       if (*SIG > 45) {
+               if (CNTM_set(state, 2, 1, 2) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+                       return -1;
+               }
+               wait_sym = 40000;
+       } else {
+               if (CNTM_set(state, 3, 1, 2) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+                       return -1;
+               }
+               wait_sym = 80000;
+       }
+       for (i = 0; i < 3; i++) {
+               if (i == 0)
+                       smrtd = smrt * 98 / 100;
+               else if (i == 1)
+                       smrtd = smrt;
+               else
+                       smrtd = smrt * 102 / 100;
+               smrt_info_get(state, smrtd);
+               smrt_set(state, smrtd);
+               srst(state);
+               wait_t = (wait_sym + 99 * smrtd / 100) / smrtd;
+               if (wait_t == 0)
+                       wait_t = 1;
+               msleep_interruptible(10);
+               if (mb86a16_read(state, 0x37, &(S[i])) != 2) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+                       return -EREMOTEIO;
+               }
+       }
+       if ((S[1] > S[0] * 112 / 100) &&
+           (S[1] > S[2] * 112 / 100)) {
+
+               ret = 1;
+       } else {
+               ret = 0;
+       }
+       *SIG = S[1];
+
+       if (CNTM_set(state, 0, 1, 2) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
+               return -1;
+       }
+
+       return ret;
+}
+
+static int rf_val_set(struct mb86a16_state *state,
+                     int f,
+                     int smrt,
+                     unsigned char R)
+{
+       unsigned char C, F, B;
+       int M;
+       unsigned char rf_val[5];
+       int ack = -1;
+
+       if (smrt > 37750)
+               C = 1;
+       else if (smrt > 18875)
+               C = 2;
+       else if (smrt > 5500)
+               C = 3;
+       else
+               C = 4;
+
+       if (smrt > 30500)
+               F = 3;
+       else if (smrt > 9375)
+               F = 1;
+       else if (smrt > 4625)
+               F = 0;
+       else
+               F = 2;
+
+       if (f < 1060)
+               B = 0;
+       else if (f < 1175)
+               B = 1;
+       else if (f < 1305)
+               B = 2;
+       else if (f < 1435)
+               B = 3;
+       else if (f < 1570)
+               B = 4;
+       else if (f < 1715)
+               B = 5;
+       else if (f < 1845)
+               B = 6;
+       else if (f < 1980)
+               B = 7;
+       else if (f < 2080)
+               B = 8;
+       else
+               B = 9;
+
+       M = f * (1 << R) / 2;
+
+       rf_val[0] = 0x01 | (C << 3) | (F << 1);
+       rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12);
+       rf_val[2] = (M & 0x00ff0) >> 4;
+       rf_val[3] = ((M & 0x0000f) << 4) | B;
+
+       /* Frequency Set */
+       if (mb86a16_write(state, 0x21, rf_val[0]) < 0)
+               ack = 0;
+       if (mb86a16_write(state, 0x22, rf_val[1]) < 0)
+               ack = 0;
+       if (mb86a16_write(state, 0x23, rf_val[2]) < 0)
+               ack = 0;
+       if (mb86a16_write(state, 0x24, rf_val[3]) < 0)
+               ack = 0;
+       if (mb86a16_write(state, 0x25, 0x01) < 0)
+               ack = 0;
+       if (ack == 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int afcerr_chk(struct mb86a16_state *state)
+{
+       unsigned char AFCM_L, AFCM_H ;
+       int AFCM ;
+       int afcm, afcerr ;
+
+       if (mb86a16_read(state, 0x0e, &AFCM_L) != 2)
+               goto err;
+       if (mb86a16_read(state, 0x0f, &AFCM_H) != 2)
+               goto err;
+
+       AFCM = (AFCM_H << 8) + AFCM_L;
+
+       if (AFCM > 2048)
+               afcm = AFCM - 4096;
+       else
+               afcm = AFCM;
+       afcerr = afcm * state->master_clk / 8192;
+
+       return afcerr;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int dagcm_val_get(struct mb86a16_state *state)
+{
+       int DAGCM;
+       unsigned char DAGCM_H, DAGCM_L;
+
+       if (mb86a16_read(state, 0x45, &DAGCM_L) != 2)
+               goto err;
+       if (mb86a16_read(state, 0x46, &DAGCM_H) != 2)
+               goto err;
+
+       DAGCM = (DAGCM_H << 8) + DAGCM_L;
+
+       return DAGCM;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       u8 stat, stat2;
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       *status = 0;
+
+       if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2)
+               goto err;
+       if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2)
+               goto err;
+       if ((stat > 25) && (stat2 > 25))
+               *status |= FE_HAS_SIGNAL;
+       if ((stat > 45) && (stat2 > 45))
+               *status |= FE_HAS_CARRIER;
+
+       if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2)
+               goto err;
+
+       if (stat & 0x01)
+               *status |= FE_HAS_SYNC;
+       if (stat & 0x01)
+               *status |= FE_HAS_VITERBI;
+
+       if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2)
+               goto err;
+
+       if ((stat & 0x0f) && (*status & FE_HAS_VITERBI))
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int sync_chk(struct mb86a16_state *state,
+                   unsigned char *VIRM)
+{
+       unsigned char val;
+       int sync;
+
+       if (mb86a16_read(state, 0x0d, &val) != 2)
+               goto err;
+
+       dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val);
+       sync = val & 0x01;
+       *VIRM = (val & 0x1c) >> 2;
+
+       return sync;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+
+}
+
+static int freqerr_chk(struct mb86a16_state *state,
+                      int fTP,
+                      int smrt,
+                      int unit)
+{
+       unsigned char CRM, AFCML, AFCMH;
+       unsigned char temp1, temp2, temp3;
+       int crm, afcm, AFCM;
+       int crrerr, afcerr;             /* kHz */
+       int frqerr;                     /* MHz */
+       int afcen, afcexen = 0;
+       int R, M, fOSC, fOSC_OFS;
+
+       if (mb86a16_read(state, 0x43, &CRM) != 2)
+               goto err;
+
+       if (CRM > 127)
+               crm = CRM - 256;
+       else
+               crm = CRM;
+
+       crrerr = smrt * crm / 256;
+       if (mb86a16_read(state, 0x49, &temp1) != 2)
+               goto err;
+
+       afcen = (temp1 & 0x04) >> 2;
+       if (afcen == 0) {
+               if (mb86a16_read(state, 0x2a, &temp1) != 2)
+                       goto err;
+               afcexen = (temp1 & 0x20) >> 5;
+       }
+
+       if (afcen == 1) {
+               if (mb86a16_read(state, 0x0e, &AFCML) != 2)
+                       goto err;
+               if (mb86a16_read(state, 0x0f, &AFCMH) != 2)
+                       goto err;
+       } else if (afcexen == 1) {
+               if (mb86a16_read(state, 0x2b, &AFCML) != 2)
+                       goto err;
+               if (mb86a16_read(state, 0x2c, &AFCMH) != 2)
+                       goto err;
+       }
+       if ((afcen == 1) || (afcexen == 1)) {
+               smrt_info_get(state, smrt);
+               AFCM = ((AFCMH & 0x01) << 8) + AFCML;
+               if (AFCM > 255)
+                       afcm = AFCM - 512;
+               else
+                       afcm = AFCM;
+
+               afcerr = afcm * state->master_clk / 8192;
+       } else
+               afcerr = 0;
+
+       if (mb86a16_read(state, 0x22, &temp1) != 2)
+               goto err;
+       if (mb86a16_read(state, 0x23, &temp2) != 2)
+               goto err;
+       if (mb86a16_read(state, 0x24, &temp3) != 2)
+               goto err;
+
+       R = (temp1 & 0xe0) >> 5;
+       M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4);
+       if (R == 0)
+               fOSC = 2 * M;
+       else
+               fOSC = M;
+
+       fOSC_OFS = fOSC - fTP;
+
+       if (unit == 0) {        /* MHz */
+               if (crrerr + afcerr + fOSC_OFS * 1000 >= 0)
+                       frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000;
+               else
+                       frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000;
+       } else {        /* kHz */
+               frqerr = crrerr + afcerr + fOSC_OFS * 1000;
+       }
+
+       return frqerr;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt)
+{
+       unsigned char R;
+
+       if (smrt > 9375)
+               R = 0;
+       else
+               R = 1;
+
+       return R;
+}
+
+static void swp_info_get(struct mb86a16_state *state,
+                        int fOSC_start,
+                        int smrt,
+                        int v, int R,
+                        int swp_ofs,
+                        int *fOSC,
+                        int *afcex_freq,
+                        unsigned char *AFCEX_L,
+                        unsigned char *AFCEX_H)
+{
+       int AFCEX ;
+       int crnt_swp_freq ;
+
+       crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs;
+
+       if (R == 0)
+               *fOSC = (crnt_swp_freq + 1000) / 2000 * 2;
+       else
+               *fOSC = (crnt_swp_freq + 500) / 1000;
+
+       if (*fOSC >= crnt_swp_freq)
+               *afcex_freq = *fOSC * 1000 - crnt_swp_freq;
+       else
+               *afcex_freq = crnt_swp_freq - *fOSC * 1000;
+
+       AFCEX = *afcex_freq * 8192 / state->master_clk;
+       *AFCEX_L =  AFCEX & 0x00ff;
+       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+
+static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V,  int vmax, int vmin,
+                              int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1)
+{
+       int swp_freq ;
+
+       if ((i % 2 == 1) && (v <= vmax)) {
+               /* positive v (case 1) */
+               if ((v - 1 == vmin)                             &&
+                   (*(V + 30 + v) >= 0)                        &&
+                   (*(V + 30 + v - 1) >= 0)                    &&
+                   (*(V + 30 + v - 1) > *(V + 30 + v))         &&
+                   (*(V + 30 + v - 1) > SIGMIN)) {
+
+                       swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+                       *SIG1 = *(V + 30 + v - 1);
+               } else if ((v == vmax)                          &&
+                          (*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v - 1) >= 0)             &&
+                          (*(V + 30 + v) > *(V + 30 + v - 1))  &&
+                          (*(V + 30 + v) > SIGMIN)) {
+                       /* (case 2) */
+                       swp_freq = fOSC * 1000 + afcex_freq;
+                       *SIG1 = *(V + 30 + v);
+               } else if ((*(V + 30 + v) > 0)                  &&
+                          (*(V + 30 + v - 1) > 0)              &&
+                          (*(V + 30 + v - 2) > 0)              &&
+                          (*(V + 30 + v - 3) > 0)              &&
+                          (*(V + 30 + v - 1) > *(V + 30 + v))  &&
+                          (*(V + 30 + v - 2) > *(V + 30 + v - 3)) &&
+                          ((*(V + 30 + v - 1) > SIGMIN)        ||
+                          (*(V + 30 + v - 2) > SIGMIN))) {
+                       /* (case 3) */
+                       if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) {
+                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+                               *SIG1 = *(V + 30 + v - 1);
+                       } else {
+                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2;
+                               *SIG1 = *(V + 30 + v - 2);
+                       }
+               } else if ((v == vmax)                          &&
+                          (*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v - 1) >= 0)             &&
+                          (*(V + 30 + v - 2) >= 0)             &&
+                          (*(V + 30 + v) > *(V + 30 + v - 2))  &&
+                          (*(V + 30 + v - 1) > *(V + 30 + v - 2)) &&
+                          ((*(V + 30 + v) > SIGMIN)            ||
+                          (*(V + 30 + v - 1) > SIGMIN))) {
+                       /* (case 4) */
+                       if (*(V + 30 + v) >= *(V + 30 + v - 1)) {
+                               swp_freq = fOSC * 1000 + afcex_freq;
+                               *SIG1 = *(V + 30 + v);
+                       } else {
+                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
+                               *SIG1 = *(V + 30 + v - 1);
+                       }
+               } else  {
+                       swp_freq = -1 ;
+               }
+       } else if ((i % 2 == 0) && (v >= vmin)) {
+               /* Negative v (case 1) */
+               if ((*(V + 30 + v) > 0)                         &&
+                   (*(V + 30 + v + 1) > 0)                     &&
+                   (*(V + 30 + v + 2) > 0)                     &&
+                   (*(V + 30 + v + 1) > *(V + 30 + v))         &&
+                   (*(V + 30 + v + 1) > *(V + 30 + v + 2))     &&
+                   (*(V + 30 + v + 1) > SIGMIN)) {
+
+                       swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+                       *SIG1 = *(V + 30 + v + 1);
+               } else if ((v + 1 == vmax)                      &&
+                          (*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v + 1) >= 0)             &&
+                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
+                          (*(V + 30 + v + 1) > SIGMIN)) {
+                       /* (case 2) */
+                       swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+                       *SIG1 = *(V + 30 + v);
+               } else if ((v == vmin)                          &&
+                          (*(V + 30 + v) > 0)                  &&
+                          (*(V + 30 + v + 1) > 0)              &&
+                          (*(V + 30 + v + 2) > 0)              &&
+                          (*(V + 30 + v) > *(V + 30 + v + 1))  &&
+                          (*(V + 30 + v) > *(V + 30 + v + 2))  &&
+                          (*(V + 30 + v) > SIGMIN)) {
+                       /* (case 3) */
+                       swp_freq = fOSC * 1000 + afcex_freq;
+                       *SIG1 = *(V + 30 + v);
+               } else if ((*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v + 1) >= 0)             &&
+                          (*(V + 30 + v + 2) >= 0)             &&
+                          (*(V + 30 + v + 3) >= 0)             &&
+                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
+                          (*(V + 30 + v + 2) > *(V + 30 + v + 3)) &&
+                          ((*(V + 30 + v + 1) > SIGMIN)        ||
+                           (*(V + 30 + v + 2) > SIGMIN))) {
+                       /* (case 4) */
+                       if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
+                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+                               *SIG1 = *(V + 30 + v + 1);
+                       } else {
+                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
+                               *SIG1 = *(V + 30 + v + 2);
+                       }
+               } else if ((*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v + 1) >= 0)             &&
+                          (*(V + 30 + v + 2) >= 0)             &&
+                          (*(V + 30 + v + 3) >= 0)             &&
+                          (*(V + 30 + v) > *(V + 30 + v + 2))  &&
+                          (*(V + 30 + v + 1) > *(V + 30 + v + 2)) &&
+                          (*(V + 30 + v) > *(V + 30 + v + 3))  &&
+                          (*(V + 30 + v + 1) > *(V + 30 + v + 3)) &&
+                          ((*(V + 30 + v) > SIGMIN)            ||
+                           (*(V + 30 + v + 1) > SIGMIN))) {
+                       /* (case 5) */
+                       if (*(V + 30 + v) >= *(V + 30 + v + 1)) {
+                               swp_freq = fOSC * 1000 + afcex_freq;
+                               *SIG1 = *(V + 30 + v);
+                       } else {
+                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+                               *SIG1 = *(V + 30 + v + 1);
+                       }
+               } else if ((v + 2 == vmin)                      &&
+                          (*(V + 30 + v) >= 0)                 &&
+                          (*(V + 30 + v + 1) >= 0)             &&
+                          (*(V + 30 + v + 2) >= 0)             &&
+                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
+                          (*(V + 30 + v + 2) > *(V + 30 + v))  &&
+                          ((*(V + 30 + v + 1) > SIGMIN)        ||
+                           (*(V + 30 + v + 2) > SIGMIN))) {
+                       /* (case 6) */
+                       if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
+                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
+                               *SIG1 = *(V + 30 + v + 1);
+                       } else {
+                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
+                               *SIG1 = *(V + 30 + v + 2);
+                       }
+               } else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) {
+                       swp_freq = fOSC * 1000;
+                       *SIG1 = *(V + 30 + v);
+               } else
+                       swp_freq = -1;
+       } else
+               swp_freq = -1;
+
+       return swp_freq;
+}
+
+static void swp_info_get2(struct mb86a16_state *state,
+                         int smrt,
+                         int R,
+                         int swp_freq,
+                         int *afcex_freq,
+                         int *fOSC,
+                         unsigned char *AFCEX_L,
+                         unsigned char *AFCEX_H)
+{
+       int AFCEX ;
+
+       if (R == 0)
+               *fOSC = (swp_freq + 1000) / 2000 * 2;
+       else
+               *fOSC = (swp_freq + 500) / 1000;
+
+       if (*fOSC >= swp_freq)
+               *afcex_freq = *fOSC * 1000 - swp_freq;
+       else
+               *afcex_freq = swp_freq - *fOSC * 1000;
+
+       AFCEX = *afcex_freq * 8192 / state->master_clk;
+       *AFCEX_L =  AFCEX & 0x00ff;
+       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+static void afcex_info_get(struct mb86a16_state *state,
+                          int afcex_freq,
+                          unsigned char *AFCEX_L,
+                          unsigned char *AFCEX_H)
+{
+       int AFCEX ;
+
+       AFCEX = afcex_freq * 8192 / state->master_clk;
+       *AFCEX_L =  AFCEX & 0x00ff;
+       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
+}
+
+static int SEQ_set(struct mb86a16_state *state, unsigned char loop)
+{
+       /* SLOCK0 = 0 */
+       if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV)
+{
+       /* Viterbi Rate, IQ Settings */
+       if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int FEC_srst(struct mb86a16_state *state)
+{
+       if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int S2T_set(struct mb86a16_state *state, unsigned char S2T)
+{
+       if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T)
+{
+       if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+
+static int mb86a16_set_fe(struct mb86a16_state *state)
+{
+       u8 agcval, cnmval;
+
+       int i, j;
+       int fOSC = 0;
+       int fOSC_start = 0;
+       int wait_t;
+       int fcp;
+       int swp_ofs;
+       int V[60];
+       u8 SIG1MIN;
+
+       unsigned char CREN, AFCEN, AFCEXEN;
+       unsigned char SIG1;
+       unsigned char TIMINT1, TIMINT2, TIMEXT;
+       unsigned char S0T, S1T;
+       unsigned char S2T;
+/*     unsigned char S2T, S3T; */
+       unsigned char S4T, S5T;
+       unsigned char AFCEX_L, AFCEX_H;
+       unsigned char R;
+       unsigned char VIRM;
+       unsigned char ETH, VIA;
+       unsigned char junk;
+
+       int loop;
+       int ftemp;
+       int v, vmax, vmin;
+       int vmax_his, vmin_his;
+       int swp_freq, prev_swp_freq[20];
+       int prev_freq_num;
+       int signal_dupl;
+       int afcex_freq;
+       int signal;
+       int afcerr;
+       int temp_freq, delta_freq;
+       int dagcm[4];
+       int smrt_d;
+/*     int freq_err; */
+       int n;
+       int ret = -1;
+       int sync;
+
+       dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate);
+
+       fcp = 3000;
+       swp_ofs = state->srate / 4;
+
+       for (i = 0; i < 60; i++)
+               V[i] = -1;
+
+       for (i = 0; i < 20; i++)
+               prev_swp_freq[i] = 0;
+
+       SIG1MIN = 25;
+
+       for (n = 0; ((n < 3) && (ret == -1)); n++) {
+               SEQ_set(state, 0);
+               iq_vt_set(state, 0);
+
+               CREN = 0;
+               AFCEN = 0;
+               AFCEXEN = 1;
+               TIMINT1 = 0;
+               TIMINT2 = 1;
+               TIMEXT = 2;
+               S1T = 0;
+               S0T = 0;
+
+               if (initial_set(state) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "initial set failed");
+                       return -1;
+               }
+               if (DAGC_data_set(state, 3, 2) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+                       return -1;
+               }
+               if (EN_set(state, CREN, AFCEN) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+                       return -1; /* (0, 0) */
+               }
+               if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+                       return -1; /* (1, smrt) = (1, symbolrate) */
+               }
+               if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error");
+                       return -1; /* (0, 1, 2) */
+               }
+               if (S01T_set(state, S1T, S0T) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+                       return -1; /* (0, 0) */
+               }
+               smrt_info_get(state, state->srate);
+               if (smrt_set(state, state->srate) < 0) {
+                       dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error");
+                       return -1;
+               }
+
+               R = vco_dev_get(state, state->srate);
+               if (R == 1)
+                       fOSC_start = state->frequency;
+
+               else if (R == 0) {
+                       if (state->frequency % 2 == 0) {
+                               fOSC_start = state->frequency;
+                       } else {
+                               fOSC_start = state->frequency + 1;
+                               if (fOSC_start > 2150)
+                                       fOSC_start = state->frequency - 1;
+                       }
+               }
+               loop = 1;
+               ftemp = fOSC_start * 1000;
+               vmax = 0 ;
+               while (loop == 1) {
+                       ftemp = ftemp + swp_ofs;
+                       vmax++;
+
+                       /* Upper bound */
+                       if (ftemp > 2150000) {
+                               loop = 0;
+                               vmax--;
+                       } else {
+                               if ((ftemp == 2150000) ||
+                                   (ftemp - state->frequency * 1000 >= fcp + state->srate / 4))
+                                       loop = 0;
+                       }
+               }
+
+               loop = 1;
+               ftemp = fOSC_start * 1000;
+               vmin = 0 ;
+               while (loop == 1) {
+                       ftemp = ftemp - swp_ofs;
+                       vmin--;
+
+                       /* Lower bound */
+                       if (ftemp < 950000) {
+                               loop = 0;
+                               vmin++;
+                       } else {
+                               if ((ftemp == 950000) ||
+                                   (state->frequency * 1000 - ftemp >= fcp + state->srate / 4))
+                                       loop = 0;
+                       }
+               }
+
+               wait_t = (8000 + state->srate / 2) / state->srate;
+               if (wait_t == 0)
+                       wait_t = 1;
+
+               i = 0;
+               j = 0;
+               prev_freq_num = 0;
+               loop = 1;
+               signal = 0;
+               vmax_his = 0;
+               vmin_his = 0;
+               v = 0;
+
+               while (loop == 1) {
+                       swp_info_get(state, fOSC_start, state->srate,
+                                    v, R, swp_ofs, &fOSC,
+                                    &afcex_freq, &AFCEX_L, &AFCEX_H);
+
+                       udelay(100);
+                       if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+                               return -1;
+                       }
+                       udelay(100);
+                       if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+                               return -1;
+                       }
+                       if (srst(state) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+                               return -1;
+                       }
+                       msleep_interruptible(wait_t);
+
+                       if (mb86a16_read(state, 0x37, &SIG1) != 2) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+                               return -1;
+                       }
+                       V[30 + v] = SIG1 ;
+                       swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin,
+                                                     SIG1MIN, fOSC, afcex_freq,
+                                                     swp_ofs, &SIG1);  /* changed */
+
+                       signal_dupl = 0;
+                       for (j = 0; j < prev_freq_num; j++) {
+                               if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) {
+                                       signal_dupl = 1;
+                                       dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j);
+                               }
+                       }
+                       if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) {
+                               dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate);
+                               prev_swp_freq[prev_freq_num] = swp_freq;
+                               prev_freq_num++;
+                               swp_info_get2(state, state->srate, R, swp_freq,
+                                             &afcex_freq, &fOSC,
+                                             &AFCEX_L, &AFCEX_H);
+
+                               if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+                                       return -1;
+                               }
+                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+                                       return -1;
+                               }
+                               signal = signal_det(state, state->srate, &SIG1);
+                               if (signal == 1) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****");
+                                       loop = 0;
+                               } else {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again...");
+                                       smrt_info_get(state, state->srate);
+                                       if (smrt_set(state, state->srate) < 0) {
+                                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+                                               return -1;
+                                       }
+                               }
+                       }
+                       if (v > vmax)
+                               vmax_his = 1 ;
+                       if (v < vmin)
+                               vmin_his = 1 ;
+                       i++;
+
+                       if ((i % 2 == 1) && (vmax_his == 1))
+                               i++;
+                       if ((i % 2 == 0) && (vmin_his == 1))
+                               i++;
+
+                       if (i % 2 == 1)
+                               v = (i + 1) / 2;
+                       else
+                               v = -i / 2;
+
+                       if ((vmax_his == 1) && (vmin_his == 1))
+                               loop = 0 ;
+               }
+
+               if (signal == 1) {
+                       dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check");
+                       S1T = 7 ;
+                       S0T = 1 ;
+                       CREN = 0 ;
+                       AFCEN = 1 ;
+                       AFCEXEN = 0 ;
+
+                       if (S01T_set(state, S1T, S0T) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+                               return -1;
+                       }
+                       smrt_info_get(state, state->srate);
+                       if (smrt_set(state, state->srate) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+                               return -1;
+                       }
+                       if (EN_set(state, CREN, AFCEN) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+                               return -1;
+                       }
+                       if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+                               return -1;
+                       }
+                       afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H);
+                       if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error");
+                               return -1;
+                       }
+                       if (srst(state) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+                               return -1;
+                       }
+                       /* delay 4~200 */
+                       wait_t = 200000 / state->master_clk + 200000 / state->srate;
+                       msleep(wait_t);
+                       afcerr = afcerr_chk(state);
+                       if (afcerr == -1)
+                               return -1;
+
+                       swp_freq = fOSC * 1000 + afcerr ;
+                       AFCEXEN = 1 ;
+                       if (state->srate >= 1500)
+                               smrt_d = state->srate / 3;
+                       else
+                               smrt_d = state->srate / 2;
+                       smrt_info_get(state, smrt_d);
+                       if (smrt_set(state, smrt_d) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+                               return -1;
+                       }
+                       if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+                               return -1;
+                       }
+                       R = vco_dev_get(state, smrt_d);
+                       if (DAGC_data_set(state, 2, 0) < 0) {
+                               dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+                               return -1;
+                       }
+                       for (i = 0; i < 3; i++) {
+                               temp_freq = swp_freq + (i - 1) * state->srate / 8;
+                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+                                       return -1;
+                               }
+                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+                                       return -1;
+                               }
+                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+                               msleep(wait_t);
+                               dagcm[i] = dagcm_val_get(state);
+                       }
+                       if ((dagcm[0] > dagcm[1]) &&
+                           (dagcm[0] > dagcm[2]) &&
+                           (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) {
+
+                               temp_freq = swp_freq - 2 * state->srate / 8;
+                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+                                       return -1;
+                               }
+                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
+                                       return -1;
+                               }
+                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+                               msleep(wait_t);
+                               dagcm[3] = dagcm_val_get(state);
+                               if (dagcm[3] > dagcm[1])
+                                       delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300;
+                               else
+                                       delta_freq = 0;
+                       } else if ((dagcm[2] > dagcm[1]) &&
+                                  (dagcm[2] > dagcm[0]) &&
+                                  (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) {
+
+                               temp_freq = swp_freq + 2 * state->srate / 8;
+                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set");
+                                       return -1;
+                               }
+                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
+                                       return -1;
+                               }
+                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
+                               msleep(wait_t);
+                               dagcm[3] = dagcm_val_get(state);
+                               if (dagcm[3] > dagcm[1])
+                                       delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300;
+                               else
+                                       delta_freq = 0 ;
+
+                       } else {
+                               delta_freq = 0 ;
+                       }
+                       dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq);
+                       swp_freq += delta_freq;
+                       dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq);
+                       if (ABS(state->frequency * 1000 - swp_freq) > 3800) {
+                               dprintk(verbose, MB86A16_INFO, 1, "NO  --  SIGNAL !");
+                       } else {
+
+                               S1T = 0;
+                               S0T = 3;
+                               CREN = 1;
+                               AFCEN = 0;
+                               AFCEXEN = 1;
+
+                               if (S01T_set(state, S1T, S0T) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
+                                       return -1;
+                               }
+                               if (DAGC_data_set(state, 0, 0) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
+                                       return -1;
+                               }
+                               R = vco_dev_get(state, state->srate);
+                               smrt_info_get(state, state->srate);
+                               if (smrt_set(state, state->srate) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
+                                       return -1;
+                               }
+                               if (EN_set(state, CREN, AFCEN) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
+                                       return -1;
+                               }
+                               if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
+                                       return -1;
+                               }
+                               swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
+                               if (rf_val_set(state, fOSC, state->srate, R) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
+                                       return -1;
+                               }
+                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
+                                       return -1;
+                               }
+                               if (srst(state) < 0) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "srst error");
+                                       return -1;
+                               }
+                               wait_t = 7 + (10000 + state->srate / 2) / state->srate;
+                               if (wait_t == 0)
+                                       wait_t = 1;
+                               msleep_interruptible(wait_t);
+                               if (mb86a16_read(state, 0x37, &SIG1) != 2) {
+                                       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+                                       return -EREMOTEIO;
+                               }
+
+                               if (SIG1 > 110) {
+                                       S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6;
+                                       wait_t = 7 + (917504 + state->srate / 2) / state->srate;
+                               } else if (SIG1 > 105) {
+                                       S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+                                       wait_t = 7 + (1048576 + state->srate / 2) / state->srate;
+                               } else if (SIG1 > 85) {
+                                       S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+                                       wait_t = 7 + (1310720 + state->srate / 2) / state->srate;
+                               } else if (SIG1 > 65) {
+                                       S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+                                       wait_t = 7 + (1572864 + state->srate / 2) / state->srate;
+                               } else {
+                                       S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
+                                       wait_t = 7 + (2097152 + state->srate / 2) / state->srate;
+                               }
+                               wait_t *= 2; /* FOS */
+                               S2T_set(state, S2T);
+                               S45T_set(state, S4T, S5T);
+                               Vi_set(state, ETH, VIA);
+                               srst(state);
+                               msleep_interruptible(wait_t);
+                               sync = sync_chk(state, &VIRM);
+                               dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync);
+                               if (VIRM) {
+                                       if (VIRM == 4) {
+                                               /* 5/6 */
+                                               if (SIG1 > 110)
+                                                       wait_t = (786432 + state->srate / 2) / state->srate;
+                                               else
+                                                       wait_t = (1572864 + state->srate / 2) / state->srate;
+                                               if (state->srate < 5000)
+                                                       /* FIXME ! , should be a long wait ! */
+                                                       msleep_interruptible(wait_t);
+                                               else
+                                                       msleep_interruptible(wait_t);
+
+                                               if (sync_chk(state, &junk) == 0) {
+                                                       iq_vt_set(state, 1);
+                                                       FEC_srst(state);
+                                               }
+                                       }
+                                       /* 1/2, 2/3, 3/4, 7/8 */
+                                       if (SIG1 > 110)
+                                               wait_t = (786432 + state->srate / 2) / state->srate;
+                                       else
+                                               wait_t = (1572864 + state->srate / 2) / state->srate;
+                                       msleep_interruptible(wait_t);
+                                       SEQ_set(state, 1);
+                               } else {
+                                       dprintk(verbose, MB86A16_INFO, 1, "NO  -- SYNC");
+                                       SEQ_set(state, 1);
+                                       ret = -1;
+                               }
+                       }
+               } else {
+                       dprintk(verbose, MB86A16_INFO, 1, "NO  -- SIGNAL");
+                       ret = -1;
+               }
+
+               sync = sync_chk(state, &junk);
+               if (sync) {
+                       dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******");
+                       freqerr_chk(state, state->frequency, state->srate, 1);
+                       ret = 0;
+                       break;
+               }
+       }
+
+       mb86a16_read(state, 0x15, &agcval);
+       mb86a16_read(state, 0x26, &cnmval);
+       dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval);
+
+       return ret;
+}
+
+static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
+                                  struct dvb_diseqc_master_cmd *cmd)
+{
+       struct mb86a16_state *state = fe->demodulator_priv;
+       int i;
+       u8 regs;
+
+       if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
+               goto err;
+
+       regs = 0x18;
+
+       if (cmd->msg_len > 5 || cmd->msg_len < 4)
+               return -EINVAL;
+
+       for (i = 0; i < cmd->msg_len; i++) {
+               if (mb86a16_write(state, regs, cmd->msg[i]) < 0)
+                       goto err;
+
+               regs++;
+       }
+       i += 0x90;
+
+       msleep_interruptible(10);
+
+       if (mb86a16_write(state, MB86A16_DCC1, i) < 0)
+               goto err;
+       if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       switch (burst) {
+       case SEC_MINI_A:
+               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+                                                      MB86A16_DCC1_TBEN  |
+                                                      MB86A16_DCC1_TBO) < 0)
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+                       goto err;
+               break;
+       case SEC_MINI_B:
+               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+                                                      MB86A16_DCC1_TBEN) < 0)
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+                       goto err;
+               break;
+       }
+
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0)
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
+                                                      MB86A16_DCC1_CTOE) < 0)
+
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
+                       goto err;
+               break;
+       case SEC_TONE_OFF:
+               if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
+                       goto err;
+               if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
+                       goto err;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       state->frequency = p->frequency / 1000;
+       state->srate = p->symbol_rate / 1000;
+
+       if (!mb86a16_set_fe(state)) {
+               dprintk(verbose, MB86A16_ERROR, 1, "Successfully acquired LOCK");
+               return DVBFE_ALGO_SEARCH_SUCCESS;
+       }
+
+       dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!");
+       return DVBFE_ALGO_SEARCH_FAILED;
+}
+
+static void mb86a16_release(struct dvb_frontend *fe)
+{
+       struct mb86a16_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static int mb86a16_init(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int mb86a16_sleep(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst;
+       u32 timer;
+
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       *ber = 0;
+       if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2)
+               goto err;
+       if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2)
+               goto err;
+       if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2)
+               goto err;
+       if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2)
+               goto err;
+       if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2)
+               goto err;
+       /* BER monitor invalid when BER_EN = 0  */
+       if (ber_mon & 0x04) {
+               /* coarse, fast calculation     */
+               *ber = ber_tab & 0x1f;
+               dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber);
+               if (ber_mon & 0x01) {
+                       /*
+                        * BER_SEL = 1, The monitored BER is the estimated
+                        * value with a Reed-Solomon decoder error amount at
+                        * the deinterleaver output.
+                        * monitored BER is expressed as a 20 bit output in total
+                        */
+                       ber_rst = ber_mon >> 3;
+                       *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
+                       if (ber_rst == 0)
+                               timer =  12500000;
+                       if (ber_rst == 1)
+                               timer =  25000000;
+                       if (ber_rst == 2)
+                               timer =  50000000;
+                       if (ber_rst == 3)
+                               timer = 100000000;
+
+                       *ber /= timer;
+                       dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
+               } else {
+                       /*
+                        * BER_SEL = 0, The monitored BER is the estimated
+                        * value with a Viterbi decoder error amount at the
+                        * QPSK demodulator output.
+                        * monitored BER is expressed as a 24 bit output in total
+                        */
+                       ber_tim = ber_mon >> 1;
+                       *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
+                       if (ber_tim == 0)
+                               timer = 16;
+                       if (ber_tim == 1)
+                               timer = 24;
+
+                       *ber /= 2 ^ timer;
+                       dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
+               }
+       }
+       return 0;
+err:
+       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+       return -EREMOTEIO;
+}
+
+static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       u8 agcm = 0;
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       *strength = 0;
+       if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       *strength = ((0xff - agcm) * 100) / 256;
+       dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength);
+       *strength = (0xffff - 0xff) + agcm;
+
+       return 0;
+}
+
+struct cnr {
+       u8 cn_reg;
+       u8 cn_val;
+};
+
+static const struct cnr cnr_tab[] = {
+       {  35,  2 },
+       {  40,  3 },
+       {  50,  4 },
+       {  60,  5 },
+       {  70,  6 },
+       {  80,  7 },
+       {  92,  8 },
+       { 103,  9 },
+       { 115, 10 },
+       { 138, 12 },
+       { 162, 15 },
+       { 180, 18 },
+       { 185, 19 },
+       { 189, 20 },
+       { 195, 22 },
+       { 199, 24 },
+       { 201, 25 },
+       { 202, 26 },
+       { 203, 27 },
+       { 205, 28 },
+       { 208, 30 }
+};
+
+static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct mb86a16_state *state = fe->demodulator_priv;
+       int i = 0;
+       int low_tide = 2, high_tide = 30, q_level;
+       u8  cn;
+
+       *snr = 0;
+       if (mb86a16_read(state, 0x26, &cn) != 2) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) {
+               if (cn < cnr_tab[i].cn_reg) {
+                       *snr = cnr_tab[i].cn_val;
+                       break;
+               }
+       }
+       q_level = (*snr * 100) / (high_tide - low_tide);
+       dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level);
+       *snr = (0xffff - 0xff) + *snr;
+
+       return 0;
+}
+
+static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       u8 dist;
+       struct mb86a16_state *state = fe->demodulator_priv;
+
+       if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) {
+               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+               return -EREMOTEIO;
+       }
+       *ucblocks = dist;
+
+       return 0;
+}
+
+static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+static struct dvb_frontend_ops mb86a16_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "Fujitsu MB86A16 DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 3000,
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,
+               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+                                         FE_CAN_FEC_7_8 | FE_CAN_QPSK    |
+                                         FE_CAN_FEC_AUTO
+       },
+       .release                        = mb86a16_release,
+
+       .get_frontend_algo              = mb86a16_frontend_algo,
+       .search                         = mb86a16_search,
+       .init                           = mb86a16_init,
+       .sleep                          = mb86a16_sleep,
+       .read_status                    = mb86a16_read_status,
+
+       .read_ber                       = mb86a16_read_ber,
+       .read_signal_strength           = mb86a16_read_signal_strength,
+       .read_snr                       = mb86a16_read_snr,
+       .read_ucblocks                  = mb86a16_read_ucblocks,
+
+       .diseqc_send_master_cmd         = mb86a16_send_diseqc_msg,
+       .diseqc_send_burst              = mb86a16_send_diseqc_burst,
+       .set_tone                       = mb86a16_set_tone,
+};
+
+struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+                                   struct i2c_adapter *i2c_adap)
+{
+       u8 dev_id = 0;
+       struct mb86a16_state *state = NULL;
+
+       state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->config = config;
+       state->i2c_adap = i2c_adap;
+
+       mb86a16_read(state, 0x7f, &dev_id);
+       if (dev_id != 0xfe)
+               goto error;
+
+       memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       state->frontend.ops.set_voltage = state->config->set_voltage;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(mb86a16_attach);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/dvb-frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h
new file mode 100644 (file)
index 0000000..6ea8c37
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __MB86A16_H
+#define __MB86A16_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+
+struct mb86a16_config {
+       u8 demod_address;
+
+       int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
+};
+
+
+
+#if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+                                          struct i2c_adapter *i2c_adap);
+
+#else
+
+static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
+                                          struct i2c_adapter *i2c_adap)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif /* CONFIG_DVB_MB86A16 */
+
+#endif /* __MB86A16_H */
diff --git a/drivers/media/dvb-frontends/mb86a16_priv.h b/drivers/media/dvb-frontends/mb86a16_priv.h
new file mode 100644 (file)
index 0000000..360a35a
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
+
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __MB86A16_PRIV_H
+#define __MB86A16_PRIV_H
+
+#define MB86A16_TSOUT          0x00
+#define MB86A16_TSOUT_HIZSEL   (0x01 << 5)
+#define MB86A16_TSOUT_HIZCNTI  (0x01 << 4)
+#define MB86A16_TSOUT_MODE     (0x01 << 3)
+#define MB86A16_TSOUT_ORDER    (0x01 << 2)
+#define MB86A16_TSOUT_ERROR    (0x01 << 1)
+#define Mb86A16_TSOUT_EDGE     (0x01 << 0)
+
+#define MB86A16_FEC            0x01
+#define MB86A16_FEC_FSYNC      (0x01 << 5)
+#define MB86A16_FEC_PCKB8      (0x01 << 4)
+#define MB86A16_FEC_DVDS       (0x01 << 3)
+#define MB86A16_FEC_EREN       (0x01 << 2)
+#define Mb86A16_FEC_RSEN       (0x01 << 1)
+#define MB86A16_FEC_DIEN       (0x01 << 0)
+
+#define MB86A16_AGC            0x02
+#define MB86A16_AGC_AGMD       (0x01 << 6)
+#define MB86A16_AGC_AGCW       (0x0f << 2)
+#define MB86A16_AGC_AGCP       (0x01 << 1)
+#define MB86A16_AGC_AGCR       (0x01 << 0)
+
+#define MB86A16_SRATE1         0x03
+#define MB86A16_SRATE1_DECI    (0x07 << 2)
+#define MB86A16_SRATE1_CSEL    (0x01 << 1)
+#define MB86A16_SRATE1_RSEL    (0x01 << 0)
+
+#define MB86A16_SRATE2         0x04
+#define MB86A16_SRATE2_STOFSL  (0xff << 0)
+
+#define MB86A16_SRATE3         0x05
+#define MB86A16_SRATE2_STOFSH  (0xff << 0)
+
+#define MB86A16_VITERBI                0x06
+#define MB86A16_FRAMESYNC      0x07
+#define MB86A16_CRLFILTCOEF1   0x08
+#define MB86A16_CRLFILTCOEF2   0x09
+#define MB86A16_STRFILTCOEF1   0x0a
+#define MB86A16_STRFILTCOEF2   0x0b
+#define MB86A16_RESET          0x0c
+#define MB86A16_STATUS         0x0d
+#define MB86A16_AFCML          0x0e
+#define MB86A16_AFCMH          0x0f
+#define MB86A16_BERMON         0x10
+#define MB86A16_BERTAB         0x11
+#define MB86A16_BERLSB         0x12
+#define MB86A16_BERMID         0x13
+#define MB86A16_BERMSB         0x14
+#define MB86A16_AGCM           0x15
+
+#define MB86A16_DCC1           0x16
+#define MB86A16_DCC1_DISTA     (0x01 << 7)
+#define MB86A16_DCC1_PRTY      (0x01 << 6)
+#define MB86A16_DCC1_CTOE      (0x01 << 5)
+#define MB86A16_DCC1_TBEN      (0x01 << 4)
+#define MB86A16_DCC1_TBO       (0x01 << 3)
+#define MB86A16_DCC1_NUM       (0x07 << 0)
+
+#define MB86A16_DCC2           0x17
+#define MB86A16_DCC2_DCBST     (0x01 << 0)
+
+#define MB86A16_DCC3           0x18
+#define MB86A16_DCC3_CODE0     (0xff << 0)
+
+#define MB86A16_DCC4           0x19
+#define MB86A16_DCC4_CODE1     (0xff << 0)
+
+#define MB86A16_DCC5           0x1a
+#define MB86A16_DCC5_CODE2     (0xff << 0)
+
+#define MB86A16_DCC6           0x1b
+#define MB86A16_DCC6_CODE3     (0xff << 0)
+
+#define MB86A16_DCC7           0x1c
+#define MB86A16_DCC7_CODE4     (0xff << 0)
+
+#define MB86A16_DCC8           0x1d
+#define MB86A16_DCC8_CODE5     (0xff << 0)
+
+#define MB86A16_DCCOUT         0x1e
+#define MB86A16_DCCOUT_DISEN   (0x01 << 0)
+
+#define MB86A16_TONEOUT1       0x1f
+#define MB86A16_TONE_TDIVL     (0xff << 0)
+
+#define MB86A16_TONEOUT2       0x20
+#define MB86A16_TONE_TMD       (0x03 << 2)
+#define MB86A16_TONE_TDIVH     (0x03 << 0)
+
+#define MB86A16_FREQ1          0x21
+#define MB86A16_FREQ2          0x22
+#define MB86A16_FREQ3          0x23
+#define MB86A16_FREQ4          0x24
+#define MB86A16_FREQSET                0x25
+#define MB86A16_CNM            0x26
+#define MB86A16_PORT0          0x27
+#define MB86A16_PORT1          0x28
+#define MB86A16_DRCFILT                0x29
+#define MB86A16_AFC            0x2a
+#define MB86A16_AFCEXL         0x2b
+#define MB86A16_AFCEXH         0x2c
+#define MB86A16_DAGC           0x2d
+#define MB86A16_SEQMODE                0x32
+#define MB86A16_S0S1T          0x33
+#define MB86A16_S2S3T          0x34
+#define MB86A16_S4S5T          0x35
+#define MB86A16_CNTMR          0x36
+#define MB86A16_SIG1           0x37
+#define MB86A16_SIG2           0x38
+#define MB86A16_VIMAG          0x39
+#define MB86A16_VISET1         0x3a
+#define MB86A16_VISET2         0x3b
+#define MB86A16_VISET3         0x3c
+#define MB86A16_FAGCS1         0x3d
+#define MB86A16_FAGCS2         0x3e
+#define MB86A16_FAGCS3         0x3f
+#define MB86A16_FAGCS4         0x40
+#define MB86A16_FAGCS5         0x41
+#define MB86A16_FAGCS6         0x42
+#define MB86A16_CRM            0x43
+#define MB86A16_STRM           0x44
+#define MB86A16_DAGCML         0x45
+#define MB86A16_DAGCMH         0x46
+#define MB86A16_QPSKTST                0x49
+#define MB86A16_DISTMON                0x52
+#define MB86A16_VERSION                0x7f
+
+#endif /* __MB86A16_PRIV_H */
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
new file mode 100644 (file)
index 0000000..fade566
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ *   Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
+ *
+ *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ *   FIXME: Need to port to DVB v5.2 API
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation version 2.
+ *
+ *   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.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "mb86a20s.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...)  do {                                              \
+       printk(KERN_ERR  "mb86a20s: " args);                            \
+} while (0)
+
+#define dprintk(args...)                                               \
+       do {                                                            \
+               if (debug) {                                            \
+                       printk(KERN_DEBUG "mb86a20s: %s: ", __func__);  \
+                       printk(args);                                   \
+               }                                                       \
+       } while (0)
+
+struct mb86a20s_state {
+       struct i2c_adapter *i2c;
+       const struct mb86a20s_config *config;
+
+       struct dvb_frontend frontend;
+
+       bool need_init;
+};
+
+struct regdata {
+       u8 reg;
+       u8 data;
+};
+
+/*
+ * Initialization sequence: Use whatevere default values that PV SBTVD
+ * does on its initialisation, obtained via USB snoop
+ */
+static struct regdata mb86a20s_init[] = {
+       { 0x70, 0x0f },
+       { 0x70, 0xff },
+       { 0x08, 0x01 },
+       { 0x09, 0x3e },
+       { 0x50, 0xd1 }, { 0x51, 0x22 },
+       { 0x39, 0x01 },
+       { 0x71, 0x00 },
+       { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
+       { 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 },
+       { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
+       { 0x3b, 0x21 },
+       { 0x3c, 0x3a },
+       { 0x01, 0x0d },
+       { 0x04, 0x08 }, { 0x05, 0x05 },
+       { 0x04, 0x0e }, { 0x05, 0x00 },
+       { 0x04, 0x0f }, { 0x05, 0x14 },
+       { 0x04, 0x0b }, { 0x05, 0x8c },
+       { 0x04, 0x00 }, { 0x05, 0x00 },
+       { 0x04, 0x01 }, { 0x05, 0x07 },
+       { 0x04, 0x02 }, { 0x05, 0x0f },
+       { 0x04, 0x03 }, { 0x05, 0xa0 },
+       { 0x04, 0x09 }, { 0x05, 0x00 },
+       { 0x04, 0x0a }, { 0x05, 0xff },
+       { 0x04, 0x27 }, { 0x05, 0x64 },
+       { 0x04, 0x28 }, { 0x05, 0x00 },
+       { 0x04, 0x1e }, { 0x05, 0xff },
+       { 0x04, 0x29 }, { 0x05, 0x0a },
+       { 0x04, 0x32 }, { 0x05, 0x0a },
+       { 0x04, 0x14 }, { 0x05, 0x02 },
+       { 0x04, 0x04 }, { 0x05, 0x00 },
+       { 0x04, 0x05 }, { 0x05, 0x22 },
+       { 0x04, 0x06 }, { 0x05, 0x0e },
+       { 0x04, 0x07 }, { 0x05, 0xd8 },
+       { 0x04, 0x12 }, { 0x05, 0x00 },
+       { 0x04, 0x13 }, { 0x05, 0xff },
+       { 0x04, 0x15 }, { 0x05, 0x4e },
+       { 0x04, 0x16 }, { 0x05, 0x20 },
+       { 0x52, 0x01 },
+       { 0x50, 0xa7 }, { 0x51, 0xff },
+       { 0x50, 0xa8 }, { 0x51, 0xff },
+       { 0x50, 0xa9 }, { 0x51, 0xff },
+       { 0x50, 0xaa }, { 0x51, 0xff },
+       { 0x50, 0xab }, { 0x51, 0xff },
+       { 0x50, 0xac }, { 0x51, 0xff },
+       { 0x50, 0xad }, { 0x51, 0xff },
+       { 0x50, 0xae }, { 0x51, 0xff },
+       { 0x50, 0xaf }, { 0x51, 0xff },
+       { 0x5e, 0x07 },
+       { 0x50, 0xdc }, { 0x51, 0x01 },
+       { 0x50, 0xdd }, { 0x51, 0xf4 },
+       { 0x50, 0xde }, { 0x51, 0x01 },
+       { 0x50, 0xdf }, { 0x51, 0xf4 },
+       { 0x50, 0xe0 }, { 0x51, 0x01 },
+       { 0x50, 0xe1 }, { 0x51, 0xf4 },
+       { 0x50, 0xb0 }, { 0x51, 0x07 },
+       { 0x50, 0xb2 }, { 0x51, 0xff },
+       { 0x50, 0xb3 }, { 0x51, 0xff },
+       { 0x50, 0xb4 }, { 0x51, 0xff },
+       { 0x50, 0xb5 }, { 0x51, 0xff },
+       { 0x50, 0xb6 }, { 0x51, 0xff },
+       { 0x50, 0xb7 }, { 0x51, 0xff },
+       { 0x50, 0x50 }, { 0x51, 0x02 },
+       { 0x50, 0x51 }, { 0x51, 0x04 },
+       { 0x45, 0x04 },
+       { 0x48, 0x04 },
+       { 0x50, 0xd5 }, { 0x51, 0x01 },         /* Serial */
+       { 0x50, 0xd6 }, { 0x51, 0x1f },
+       { 0x50, 0xd2 }, { 0x51, 0x03 },
+       { 0x50, 0xd7 }, { 0x51, 0x3f },
+       { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x28, 0x74 }, { 0x29, 0x40 },
+       { 0x28, 0x46 }, { 0x29, 0x2c }, { 0x28, 0x46 }, { 0x29, 0x0c },
+       { 0x04, 0x40 }, { 0x05, 0x01 },
+       { 0x28, 0x00 }, { 0x29, 0x10 },
+       { 0x28, 0x05 }, { 0x29, 0x02 },
+       { 0x1c, 0x01 },
+       { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
+       { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
+       { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
+       { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
+       { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
+       { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
+       { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
+       { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
+       { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
+       { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
+       { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
+       { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
+       { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
+       { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
+       { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
+       { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
+       { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
+       { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
+       { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
+       { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
+       { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
+       { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
+       { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
+       { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
+       { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
+       { 0x50, 0x1e }, { 0x51, 0x5d },
+       { 0x50, 0x22 }, { 0x51, 0x00 },
+       { 0x50, 0x23 }, { 0x51, 0xc8 },
+       { 0x50, 0x24 }, { 0x51, 0x00 },
+       { 0x50, 0x25 }, { 0x51, 0xf0 },
+       { 0x50, 0x26 }, { 0x51, 0x00 },
+       { 0x50, 0x27 }, { 0x51, 0xc3 },
+       { 0x50, 0x39 }, { 0x51, 0x02 },
+       { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
+       { 0xd0, 0x00 },
+};
+
+static struct regdata mb86a20s_reset_reception[] = {
+       { 0x70, 0xf0 },
+       { 0x70, 0xff },
+       { 0x08, 0x01 },
+       { 0x08, 0x00 },
+};
+
+static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
+                            u8 i2c_addr, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+       };
+       int rc;
+
+       rc = i2c_transfer(state->i2c, &msg, 1);
+       if (rc != 1) {
+               printk("%s: writereg error (rc == %i, reg == 0x%02x,"
+                        " data == 0x%02x)\n", __func__, rc, reg, data);
+               return rc;
+       }
+
+       return 0;
+}
+
+static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
+                                    u8 i2c_addr, struct regdata *rd, int size)
+{
+       int i, rc;
+
+       for (i = 0; i < size; i++) {
+               rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
+                                          rd[i].data);
+               if (rc < 0)
+                       return rc;
+       }
+       return 0;
+}
+
+static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
+                               u8 i2c_addr, u8 reg)
+{
+       u8 val;
+       int rc;
+       struct i2c_msg msg[] = {
+               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+       };
+
+       rc = i2c_transfer(state->i2c, msg, 2);
+
+       if (rc != 2) {
+               rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc);
+               return rc;
+       }
+
+       return val;
+}
+
+#define mb86a20s_readreg(state, reg) \
+       mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
+#define mb86a20s_writereg(state, reg, val) \
+       mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
+#define mb86a20s_writeregdata(state, regdata) \
+       mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
+       regdata, ARRAY_SIZE(regdata))
+
+static int mb86a20s_initfe(struct dvb_frontend *fe)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+       int rc;
+       u8  regD5 = 1;
+
+       dprintk("\n");
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       /* Initialize the frontend */
+       rc = mb86a20s_writeregdata(state, mb86a20s_init);
+       if (rc < 0)
+               goto err;
+
+       if (!state->config->is_serial) {
+               regD5 &= ~1;
+
+               rc = mb86a20s_writereg(state, 0x50, 0xd5);
+               if (rc < 0)
+                       goto err;
+               rc = mb86a20s_writereg(state, 0x51, regD5);
+               if (rc < 0)
+                       goto err;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+err:
+       if (rc < 0) {
+               state->need_init = true;
+               printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
+       } else {
+               state->need_init = false;
+               dprintk("Initialization succeeded.\n");
+       }
+       return rc;
+}
+
+static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+       unsigned rf_max, rf_min, rf;
+       u8       val;
+
+       dprintk("\n");
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       /* Does a binary search to get RF strength */
+       rf_max = 0xfff;
+       rf_min = 0;
+       do {
+               rf = (rf_max + rf_min) / 2;
+               mb86a20s_writereg(state, 0x04, 0x1f);
+               mb86a20s_writereg(state, 0x05, rf >> 8);
+               mb86a20s_writereg(state, 0x04, 0x20);
+               mb86a20s_writereg(state, 0x04, rf);
+
+               val = mb86a20s_readreg(state, 0x02);
+               if (val & 0x08)
+                       rf_min = (rf_max + rf_min) / 2;
+               else
+                       rf_max = (rf_max + rf_min) / 2;
+               if (rf_max - rf_min < 4) {
+                       *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
+                       break;
+               }
+       } while (1);
+
+       dprintk("signal strength = %d\n", *strength);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       return 0;
+}
+
+static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("\n");
+       *status = 0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+       val = mb86a20s_readreg(state, 0x0a) & 0xf;
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       if (val >= 2)
+               *status |= FE_HAS_SIGNAL;
+
+       if (val >= 4)
+               *status |= FE_HAS_CARRIER;
+
+       if (val >= 5)
+               *status |= FE_HAS_VITERBI;
+
+       if (val >= 7)
+               *status |= FE_HAS_SYNC;
+
+       if (val >= 8)                           /* Maybe 9? */
+               *status |= FE_HAS_LOCK;
+
+       dprintk("val = %d, status = 0x%02x\n", val, *status);
+
+       return 0;
+}
+
+static int mb86a20s_set_frontend(struct dvb_frontend *fe)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+       int rc;
+#if 0
+       /*
+        * FIXME: Properly implement the set frontend properties
+        */
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+#endif
+
+       dprintk("\n");
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       dprintk("Calling tuner set parameters\n");
+       fe->ops.tuner_ops.set_params(fe);
+
+       /*
+        * Make it more reliable: if, for some reason, the initial
+        * device initialization doesn't happen, initialize it when
+        * a SBTVD parameters are adjusted.
+        *
+        * Unfortunately, due to a hard to track bug at tda829x/tda18271,
+        * the agc callback logic is not called during DVB attach time,
+        * causing mb86a20s to not be initialized with Kworld SBTVD.
+        * So, this hack is needed, in order to make Kworld SBTVD to work.
+        */
+       if (state->need_init)
+               mb86a20s_initfe(fe);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+       rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       return rc;
+}
+
+static int mb86a20s_get_modulation(struct mb86a20s_state *state,
+                                  unsigned layer)
+{
+       int rc;
+       static unsigned char reg[] = {
+               [0] = 0x86,     /* Layer A */
+               [1] = 0x8a,     /* Layer B */
+               [2] = 0x8e,     /* Layer C */
+       };
+
+       if (layer >= ARRAY_SIZE(reg))
+               return -EINVAL;
+       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
+       if (rc < 0)
+               return rc;
+       rc = mb86a20s_readreg(state, 0x6e);
+       if (rc < 0)
+               return rc;
+       switch ((rc & 0x70) >> 4) {
+       case 0:
+               return DQPSK;
+       case 1:
+               return QPSK;
+       case 2:
+               return QAM_16;
+       case 3:
+               return QAM_64;
+       default:
+               return QAM_AUTO;
+       }
+}
+
+static int mb86a20s_get_fec(struct mb86a20s_state *state,
+                           unsigned layer)
+{
+       int rc;
+
+       static unsigned char reg[] = {
+               [0] = 0x87,     /* Layer A */
+               [1] = 0x8b,     /* Layer B */
+               [2] = 0x8f,     /* Layer C */
+       };
+
+       if (layer >= ARRAY_SIZE(reg))
+               return -EINVAL;
+       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
+       if (rc < 0)
+               return rc;
+       rc = mb86a20s_readreg(state, 0x6e);
+       if (rc < 0)
+               return rc;
+       switch (rc) {
+       case 0:
+               return FEC_1_2;
+       case 1:
+               return FEC_2_3;
+       case 2:
+               return FEC_3_4;
+       case 3:
+               return FEC_5_6;
+       case 4:
+               return FEC_7_8;
+       default:
+               return FEC_AUTO;
+       }
+}
+
+static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
+                                    unsigned layer)
+{
+       int rc;
+
+       static unsigned char reg[] = {
+               [0] = 0x88,     /* Layer A */
+               [1] = 0x8c,     /* Layer B */
+               [2] = 0x90,     /* Layer C */
+       };
+
+       if (layer >= ARRAY_SIZE(reg))
+               return -EINVAL;
+       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
+       if (rc < 0)
+               return rc;
+       rc = mb86a20s_readreg(state, 0x6e);
+       if (rc < 0)
+               return rc;
+       if (rc > 3)
+               return -EINVAL; /* Not used */
+       return rc;
+}
+
+static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
+                                     unsigned layer)
+{
+       int rc, count;
+
+       static unsigned char reg[] = {
+               [0] = 0x89,     /* Layer A */
+               [1] = 0x8d,     /* Layer B */
+               [2] = 0x91,     /* Layer C */
+       };
+
+       if (layer >= ARRAY_SIZE(reg))
+               return -EINVAL;
+       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
+       if (rc < 0)
+               return rc;
+       rc = mb86a20s_readreg(state, 0x6e);
+       if (rc < 0)
+               return rc;
+       count = (rc >> 4) & 0x0f;
+
+       return count;
+}
+
+static int mb86a20s_get_frontend(struct dvb_frontend *fe)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       int i, rc;
+
+       /* Fixed parameters */
+       p->delivery_system = SYS_ISDBT;
+       p->bandwidth_hz = 6000000;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       /* Check for partial reception */
+       rc = mb86a20s_writereg(state, 0x6d, 0x85);
+       if (rc >= 0)
+               rc = mb86a20s_readreg(state, 0x6e);
+       if (rc >= 0)
+               p->isdbt_partial_reception = (rc & 0x10) ? 1 : 0;
+
+       /* Get per-layer data */
+       p->isdbt_layer_enabled = 0;
+       for (i = 0; i < 3; i++) {
+               rc = mb86a20s_get_segment_count(state, i);
+                       if (rc >= 0 && rc < 14)
+                               p->layer[i].segment_count = rc;
+               if (rc == 0x0f)
+                       continue;
+               p->isdbt_layer_enabled |= 1 << i;
+               rc = mb86a20s_get_modulation(state, i);
+                       if (rc >= 0)
+                               p->layer[i].modulation = rc;
+               rc = mb86a20s_get_fec(state, i);
+                       if (rc >= 0)
+                               p->layer[i].fec = rc;
+               rc = mb86a20s_get_interleaving(state, i);
+                       if (rc >= 0)
+                               p->layer[i].interleaving = rc;
+       }
+
+       p->isdbt_sb_mode = 0;
+       rc = mb86a20s_writereg(state, 0x6d, 0x84);
+       if ((rc >= 0) && ((rc & 0x60) == 0x20)) {
+               p->isdbt_sb_mode = 1;
+               /* At least, one segment should exist */
+               if (!p->isdbt_sb_segment_count)
+                       p->isdbt_sb_segment_count = 1;
+       } else
+               p->isdbt_sb_segment_count = 0;
+
+       /* Get transmission mode and guard interval */
+       p->transmission_mode = TRANSMISSION_MODE_AUTO;
+       p->guard_interval = GUARD_INTERVAL_AUTO;
+       rc = mb86a20s_readreg(state, 0x07);
+       if (rc >= 0) {
+               if ((rc & 0x60) == 0x20) {
+                       switch (rc & 0x0c >> 2) {
+                       case 0:
+                               p->transmission_mode = TRANSMISSION_MODE_2K;
+                               break;
+                       case 1:
+                               p->transmission_mode = TRANSMISSION_MODE_4K;
+                               break;
+                       case 2:
+                               p->transmission_mode = TRANSMISSION_MODE_8K;
+                               break;
+                       }
+               }
+               if (!(rc & 0x10)) {
+                       switch (rc & 0x3) {
+                       case 0:
+                               p->guard_interval = GUARD_INTERVAL_1_4;
+                               break;
+                       case 1:
+                               p->guard_interval = GUARD_INTERVAL_1_8;
+                               break;
+                       case 2:
+                               p->guard_interval = GUARD_INTERVAL_1_16;
+                               break;
+                       }
+               }
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       return 0;
+}
+
+static int mb86a20s_tune(struct dvb_frontend *fe,
+                       bool re_tune,
+                       unsigned int mode_flags,
+                       unsigned int *delay,
+                       fe_status_t *status)
+{
+       int rc = 0;
+
+       dprintk("\n");
+
+       if (re_tune)
+               rc = mb86a20s_set_frontend(fe);
+
+       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+               mb86a20s_read_status(fe, status);
+
+       return rc;
+}
+
+static void mb86a20s_release(struct dvb_frontend *fe)
+{
+       struct mb86a20s_state *state = fe->demodulator_priv;
+
+       dprintk("\n");
+
+       kfree(state);
+}
+
+static struct dvb_frontend_ops mb86a20s_ops;
+
+struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       u8      rev;
+
+       /* allocate memory for the internal state */
+       struct mb86a20s_state *state =
+               kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
+
+       dprintk("\n");
+       if (state == NULL) {
+               rc("Unable to kzalloc\n");
+               goto error;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &mb86a20s_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* Check if it is a mb86a20s frontend */
+       rev = mb86a20s_readreg(state, 0);
+
+       if (rev == 0x13) {
+               printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
+       } else {
+               printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
+                      rev);
+               goto error;
+       }
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(mb86a20s_attach);
+
+static struct dvb_frontend_ops mb86a20s_ops = {
+       .delsys = { SYS_ISDBT },
+       /* Use dib8000 values per default */
+       .info = {
+               .name = "Fujitsu mb86A20s",
+               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK     | FE_CAN_QAM_16  | FE_CAN_QAM_64 |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO    | FE_CAN_HIERARCHY_AUTO,
+               /* Actually, those values depend on the used tuner */
+               .frequency_min = 45000000,
+               .frequency_max = 864000000,
+               .frequency_stepsize = 62500,
+       },
+
+       .release = mb86a20s_release,
+
+       .init = mb86a20s_initfe,
+       .set_frontend = mb86a20s_set_frontend,
+       .get_frontend = mb86a20s_get_frontend,
+       .read_status = mb86a20s_read_status,
+       .read_signal_strength = mb86a20s_read_signal_strength,
+       .tune = mb86a20s_tune,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h
new file mode 100644 (file)
index 0000000..bf22e77
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *   Fujitsu mb86a20s driver
+ *
+ *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation version 2.
+ *
+ *   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.
+ */
+
+#ifndef MB86A20S_H
+#define MB86A20S_H
+
+#include <linux/dvb/frontend.h>
+
+/**
+ * struct mb86a20s_config - Define the per-device attributes of the frontend
+ *
+ * @demod_address:     the demodulator's i2c address
+ */
+
+struct mb86a20s_config {
+       u8 demod_address;
+       bool is_serial;
+};
+
+#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
+       && defined(MODULE))
+extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+                                          struct i2c_adapter *i2c);
+extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *mb86a20s_attach(
+       const struct mb86a20s_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static struct i2c_adapter *
+       mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* MB86A20S */
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
new file mode 100644 (file)
index 0000000..e20bf13
--- /dev/null
@@ -0,0 +1,839 @@
+/*
+    Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder
+
+    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
+    Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    References:
+    http://products.zarlink.com/product_profiles/MT312.htm
+    http://products.zarlink.com/product_profiles/SL1935.htm
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "mt312_priv.h"
+#include "mt312.h"
+
+
+struct mt312_state {
+       struct i2c_adapter *i2c;
+       /* configuration settings */
+       const struct mt312_config *config;
+       struct dvb_frontend frontend;
+
+       u8 id;
+       unsigned long xtal;
+       u8 freq_mult;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "mt312: " args); \
+       } while (0)
+
+#define MT312_PLL_CLK          10000000UL      /* 10 MHz */
+#define MT312_PLL_CLK_10_111   10111000UL      /* 10.111 MHz */
+
+static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
+                     u8 *buf, const size_t count)
+{
+       int ret;
+       struct i2c_msg msg[2];
+       u8 regbuf[1] = { reg };
+
+       msg[0].addr = state->config->demod_address;
+       msg[0].flags = 0;
+       msg[0].buf = regbuf;
+       msg[0].len = 1;
+       msg[1].addr = state->config->demod_address;
+       msg[1].flags = I2C_M_RD;
+       msg[1].buf = buf;
+       msg[1].len = count;
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+
+       if (debug) {
+               int i;
+               dprintk("R(%d):", reg & 0x7f);
+               for (i = 0; i < count; i++)
+                       printk(KERN_CONT " %02x", buf[i]);
+               printk("\n");
+       }
+
+       return 0;
+}
+
+static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
+                      const u8 *src, const size_t count)
+{
+       int ret;
+       u8 buf[count + 1];
+       struct i2c_msg msg;
+
+       if (debug) {
+               int i;
+               dprintk("W(%d):", reg & 0x7f);
+               for (i = 0; i < count; i++)
+                       printk(KERN_CONT " %02x", src[i]);
+               printk("\n");
+       }
+
+       buf[0] = reg;
+       memcpy(&buf[1], src, count);
+
+       msg.addr = state->config->demod_address;
+       msg.flags = 0;
+       msg.buf = buf;
+       msg.len = count + 1;
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1) {
+               dprintk("%s: ret == %d\n", __func__, ret);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static inline int mt312_readreg(struct mt312_state *state,
+                               const enum mt312_reg_addr reg, u8 *val)
+{
+       return mt312_read(state, reg, val, 1);
+}
+
+static inline int mt312_writereg(struct mt312_state *state,
+                                const enum mt312_reg_addr reg, const u8 val)
+{
+       return mt312_write(state, reg, &val, 1);
+}
+
+static inline u32 mt312_div(u32 a, u32 b)
+{
+       return (a + (b / 2)) / b;
+}
+
+static int mt312_reset(struct mt312_state *state, const u8 full)
+{
+       return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
+}
+
+static int mt312_get_inversion(struct mt312_state *state,
+                              fe_spectral_inversion_t *i)
+{
+       int ret;
+       u8 vit_mode;
+
+       ret = mt312_readreg(state, VIT_MODE, &vit_mode);
+       if (ret < 0)
+               return ret;
+
+       if (vit_mode & 0x80)    /* auto inversion was used */
+               *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
+
+       return 0;
+}
+
+static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr)
+{
+       int ret;
+       u8 sym_rate_h;
+       u8 dec_ratio;
+       u16 sym_rat_op;
+       u16 monitor;
+       u8 buf[2];
+
+       ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h);
+       if (ret < 0)
+               return ret;
+
+       if (sym_rate_h & 0x80) {
+               /* symbol rate search was used */
+               ret = mt312_writereg(state, MON_CTRL, 0x03);
+               if (ret < 0)
+                       return ret;
+
+               ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
+               if (ret < 0)
+                       return ret;
+
+               monitor = (buf[0] << 8) | buf[1];
+
+               dprintk("sr(auto) = %u\n",
+                      mt312_div(monitor * 15625, 4));
+       } else {
+               ret = mt312_writereg(state, MON_CTRL, 0x05);
+               if (ret < 0)
+                       return ret;
+
+               ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
+               if (ret < 0)
+                       return ret;
+
+               dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
+
+               ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf));
+               if (ret < 0)
+                       return ret;
+
+               sym_rat_op = (buf[0] << 8) | buf[1];
+
+               dprintk("sym_rat_op=%d dec_ratio=%d\n",
+                      sym_rat_op, dec_ratio);
+               dprintk("*sr(manual) = %lu\n",
+                      (((state->xtal * 8192) / (sym_rat_op + 8192)) *
+                       2) - dec_ratio);
+       }
+
+       return 0;
+}
+
+static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr)
+{
+       const fe_code_rate_t fec_tab[8] =
+           { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
+               FEC_AUTO, FEC_AUTO };
+
+       int ret;
+       u8 fec_status;
+
+       ret = mt312_readreg(state, FEC_STATUS, &fec_status);
+       if (ret < 0)
+               return ret;
+
+       *cr = fec_tab[(fec_status >> 4) & 0x07];
+
+       return 0;
+}
+
+static int mt312_initfe(struct dvb_frontend *fe)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+
+       /* wake up */
+       ret = mt312_writereg(state, CONFIG,
+                       (state->freq_mult == 6 ? 0x88 : 0x8c));
+       if (ret < 0)
+               return ret;
+
+       /* wait at least 150 usec */
+       udelay(150);
+
+       /* full reset */
+       ret = mt312_reset(state, 1);
+       if (ret < 0)
+               return ret;
+
+/* Per datasheet, write correct values. 09/28/03 ACCJr.
+ * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */
+       {
+               u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02,
+                                 0x01, 0x00, 0x00, 0x00 };
+
+               ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def));
+               if (ret < 0)
+                       return ret;
+       }
+
+       switch (state->id) {
+       case ID_ZL10313:
+               /* enable ADC */
+               ret = mt312_writereg(state, GPP_CTRL, 0x80);
+               if (ret < 0)
+                       return ret;
+
+               /* configure ZL10313 for optimal ADC performance */
+               buf[0] = 0x80;
+               buf[1] = 0xB0;
+               ret = mt312_write(state, HW_CTRL, buf, 2);
+               if (ret < 0)
+                       return ret;
+
+               /* enable MPEG output and ADCs */
+               ret = mt312_writereg(state, HW_CTRL, 0x00);
+               if (ret < 0)
+                       return ret;
+
+               ret = mt312_writereg(state, MPEG_CTRL, 0x00);
+               if (ret < 0)
+                       return ret;
+
+               break;
+       }
+
+       /* SYS_CLK */
+       buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
+
+       /* DISEQC_RATIO */
+       buf[1] = mt312_div(state->xtal, 22000 * 4);
+
+       ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_writereg(state, SNR_THS_HIGH, 0x32);
+       if (ret < 0)
+               return ret;
+
+       /* different MOCLK polarity */
+       switch (state->id) {
+       case ID_ZL10313:
+               buf[0] = 0x33;
+               break;
+       default:
+               buf[0] = 0x53;
+               break;
+       }
+
+       ret = mt312_writereg(state, OP_CTRL, buf[0]);
+       if (ret < 0)
+               return ret;
+
+       /* TS_SW_LIM */
+       buf[0] = 0x8c;
+       buf[1] = 0x98;
+
+       ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_writereg(state, CS_SW_LIM, 0x69);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int mt312_send_master_cmd(struct dvb_frontend *fe,
+                                struct dvb_diseqc_master_cmd *c)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 diseqc_mode;
+
+       if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
+               return -EINVAL;
+
+       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_writereg(state, DISEQC_MODE,
+                            (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
+                            | 0x04);
+       if (ret < 0)
+               return ret;
+
+       /* is there a better way to wait for message to be transmitted */
+       msleep(100);
+
+       /* set DISEQC_MODE[2:0] to zero if a return message is expected */
+       if (c->msg[0] & 0x02) {
+               ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       const u8 mini_tab[2] = { 0x02, 0x03 };
+
+       int ret;
+       u8 diseqc_mode;
+
+       if (c > SEC_MINI_B)
+               return -EINVAL;
+
+       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_writereg(state, DISEQC_MODE,
+                            (diseqc_mode & 0x40) | mini_tab[c]);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       const u8 tone_tab[2] = { 0x01, 0x00 };
+
+       int ret;
+       u8 diseqc_mode;
+
+       if (t > SEC_TONE_OFF)
+               return -EINVAL;
+
+       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_writereg(state, DISEQC_MODE,
+                            (diseqc_mode & 0x40) | tone_tab[t]);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
+       u8 val;
+
+       if (v > SEC_VOLTAGE_OFF)
+               return -EINVAL;
+
+       val = volt_tab[v];
+       if (state->config->voltage_inverted)
+               val ^= 0x40;
+
+       return mt312_writereg(state, DISEQC_MODE, val);
+}
+
+static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 status[3];
+
+       *s = 0;
+
+       ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status));
+       if (ret < 0)
+               return ret;
+
+       dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x,"
+               " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
+
+       if (status[0] & 0xc0)
+               *s |= FE_HAS_SIGNAL;    /* signal noise ratio */
+       if (status[0] & 0x04)
+               *s |= FE_HAS_CARRIER;   /* qpsk carrier lock */
+       if (status[2] & 0x02)
+               *s |= FE_HAS_VITERBI;   /* viterbi lock */
+       if (status[2] & 0x04)
+               *s |= FE_HAS_SYNC;      /* byte align lock */
+       if (status[0] & 0x01)
+               *s |= FE_HAS_LOCK;      /* qpsk lock */
+
+       return 0;
+}
+
+static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[3];
+
+       ret = mt312_read(state, RS_BERCNT_H, buf, 3);
+       if (ret < 0)
+               return ret;
+
+       *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
+
+       return 0;
+}
+
+static int mt312_read_signal_strength(struct dvb_frontend *fe,
+                                     u16 *signal_strength)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[3];
+       u16 agc;
+       s16 err_db;
+
+       ret = mt312_read(state, AGC_H, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       agc = (buf[0] << 6) | (buf[1] >> 2);
+       err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
+
+       *signal_strength = agc;
+
+       dprintk("agc=%08x err_db=%hd\n", agc, err_db);
+
+       return 0;
+}
+
+static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+
+       ret = mt312_read(state, M_SNR_H, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
+
+       return 0;
+}
+
+static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+
+       ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       *ubc = (buf[0] << 8) | buf[1];
+
+       return 0;
+}
+
+static int mt312_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 buf[5], config_val;
+       u16 sr;
+
+       const u8 fec_tab[10] =
+           { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
+       const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
+
+       dprintk("%s: Freq %d\n", __func__, p->frequency);
+
+       if ((p->frequency < fe->ops.info.frequency_min)
+           || (p->frequency > fe->ops.info.frequency_max))
+               return -EINVAL;
+
+       if ((p->inversion < INVERSION_OFF)
+           || (p->inversion > INVERSION_ON))
+               return -EINVAL;
+
+       if ((p->symbol_rate < fe->ops.info.symbol_rate_min)
+           || (p->symbol_rate > fe->ops.info.symbol_rate_max))
+               return -EINVAL;
+
+       if ((p->fec_inner < FEC_NONE)
+           || (p->fec_inner > FEC_AUTO))
+               return -EINVAL;
+
+       if ((p->fec_inner == FEC_4_5)
+           || (p->fec_inner == FEC_8_9))
+               return -EINVAL;
+
+       switch (state->id) {
+       case ID_VP310:
+       /* For now we will do this only for the VP310.
+        * It should be better for the mt312 as well,
+        * but tuning will be slower. ACCJr 09/29/03
+        */
+               ret = mt312_readreg(state, CONFIG, &config_val);
+               if (ret < 0)
+                       return ret;
+               if (p->symbol_rate >= 30000000) {
+                       /* Note that 30MS/s should use 90MHz */
+                       if (state->freq_mult == 6) {
+                               /* We are running 60MHz */
+                               state->freq_mult = 9;
+                               ret = mt312_initfe(fe);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               } else {
+                       if (state->freq_mult == 9) {
+                               /* We are running 90MHz */
+                               state->freq_mult = 6;
+                               ret = mt312_initfe(fe);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               }
+               break;
+
+       case ID_MT312:
+       case ID_ZL10313:
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* sr = (u16)(sr * 256.0 / 1000000.0) */
+       sr = mt312_div(p->symbol_rate * 4, 15625);
+
+       /* SYM_RATE */
+       buf[0] = (sr >> 8) & 0x3f;
+       buf[1] = (sr >> 0) & 0xff;
+
+       /* VIT_MODE */
+       buf[2] = inv_tab[p->inversion] | fec_tab[p->fec_inner];
+
+       /* QPSK_CTRL */
+       buf[3] = 0x40;          /* swap I and Q before QPSK demodulation */
+
+       if (p->symbol_rate < 10000000)
+               buf[3] |= 0x04; /* use afc mode */
+
+       /* GO */
+       buf[4] = 0x01;
+
+       ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       mt312_reset(state, 0);
+
+       return 0;
+}
+
+static int mt312_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+
+       ret = mt312_get_inversion(state, &p->inversion);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_get_symbol_rate(state, &p->symbol_rate);
+       if (ret < 0)
+               return ret;
+
+       ret = mt312_get_code_rate(state, &p->fec_inner);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+
+       u8 val = 0x00;
+       int ret;
+
+       switch (state->id) {
+       case ID_ZL10313:
+               ret = mt312_readreg(state, GPP_CTRL, &val);
+               if (ret < 0)
+                       goto error;
+
+               /* preserve this bit to not accidentally shutdown ADC */
+               val &= 0x80;
+               break;
+       }
+
+       if (enable)
+               val |= 0x40;
+       else
+               val &= ~0x40;
+
+       ret = mt312_writereg(state, GPP_CTRL, val);
+
+error:
+       return ret;
+}
+
+static int mt312_sleep(struct dvb_frontend *fe)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       int ret;
+       u8 config;
+
+       /* reset all registers to defaults */
+       ret = mt312_reset(state, 1);
+       if (ret < 0)
+               return ret;
+
+       if (state->id == ID_ZL10313) {
+               /* reset ADC */
+               ret = mt312_writereg(state, GPP_CTRL, 0x00);
+               if (ret < 0)
+                       return ret;
+
+               /* full shutdown of ADCs, mpeg bus tristated */
+               ret = mt312_writereg(state, HW_CTRL, 0x0d);
+               if (ret < 0)
+                       return ret;
+       }
+
+       ret = mt312_readreg(state, CONFIG, &config);
+       if (ret < 0)
+               return ret;
+
+       /* enter standby */
+       ret = mt312_writereg(state, CONFIG, config & 0x7f);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int mt312_get_tune_settings(struct dvb_frontend *fe,
+               struct dvb_frontend_tune_settings *fesettings)
+{
+       fesettings->min_delay_ms = 50;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void mt312_release(struct dvb_frontend *fe)
+{
+       struct mt312_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+#define MT312_SYS_CLK          90000000UL      /* 90 MHz */
+static struct dvb_frontend_ops mt312_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name = "Zarlink ???? DVB-S",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               /* FIXME: adjust freq to real used xtal */
+               .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
+               .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
+               .symbol_rate_max = MT312_SYS_CLK / 2,
+               .caps =
+                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                   FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                   FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
+                   FE_CAN_RECOVER
+       },
+
+       .release = mt312_release,
+
+       .init = mt312_initfe,
+       .sleep = mt312_sleep,
+       .i2c_gate_ctrl = mt312_i2c_gate_ctrl,
+
+       .set_frontend = mt312_set_frontend,
+       .get_frontend = mt312_get_frontend,
+       .get_tune_settings = mt312_get_tune_settings,
+
+       .read_status = mt312_read_status,
+       .read_ber = mt312_read_ber,
+       .read_signal_strength = mt312_read_signal_strength,
+       .read_snr = mt312_read_snr,
+       .read_ucblocks = mt312_read_ucblocks,
+
+       .diseqc_send_master_cmd = mt312_send_master_cmd,
+       .diseqc_send_burst = mt312_send_burst,
+       .set_tone = mt312_set_tone,
+       .set_voltage = mt312_set_voltage,
+};
+
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       struct mt312_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if (mt312_readreg(state, ID, &state->id) < 0)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &mt312_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       switch (state->id) {
+       case ID_VP310:
+               strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
+               state->xtal = MT312_PLL_CLK;
+               state->freq_mult = 9;
+               break;
+       case ID_MT312:
+               strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
+               state->xtal = MT312_PLL_CLK;
+               state->freq_mult = 6;
+               break;
+       case ID_ZL10313:
+               strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
+               state->xtal = MT312_PLL_CLK_10_111;
+               state->freq_mult = 9;
+               break;
+       default:
+               printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313"
+                       " are supported chips.\n");
+               goto error;
+       }
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(mt312_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
+MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb-frontends/mt312.h b/drivers/media/dvb-frontends/mt312.h
new file mode 100644 (file)
index 0000000..29e3bb5
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    Driver for Zarlink MT312 Satellite Channel Decoder
+
+    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    References:
+    http://products.zarlink.com/product_profiles/MT312.htm
+    http://products.zarlink.com/product_profiles/SL1935.htm
+*/
+
+#ifndef MT312_H
+#define MT312_H
+
+#include <linux/dvb/frontend.h>
+
+struct mt312_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* inverted voltage setting */
+       unsigned int voltage_inverted:1;
+};
+
+#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
+                                       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *mt312_attach(
+       const struct mt312_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_MT312 */
+
+#endif /* MT312_H */
diff --git a/drivers/media/dvb-frontends/mt312_priv.h b/drivers/media/dvb-frontends/mt312_priv.h
new file mode 100644 (file)
index 0000000..a3959f9
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+    Driver for Zarlink MT312 QPSK Frontend
+
+    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _DVB_FRONTENDS_MT312_PRIV
+#define _DVB_FRONTENDS_MT312_PRIV
+
+enum mt312_reg_addr {
+       QPSK_INT_H = 0,
+       QPSK_INT_M = 1,
+       QPSK_INT_L = 2,
+       FEC_INT = 3,
+       QPSK_STAT_H = 4,
+       QPSK_STAT_L = 5,
+       FEC_STATUS = 6,
+       LNB_FREQ_H = 7,
+       LNB_FREQ_L = 8,
+       M_SNR_H = 9,
+       M_SNR_L = 10,
+       VIT_ERRCNT_H = 11,
+       VIT_ERRCNT_M = 12,
+       VIT_ERRCNT_L = 13,
+       RS_BERCNT_H = 14,
+       RS_BERCNT_M = 15,
+       RS_BERCNT_L = 16,
+       RS_UBC_H = 17,
+       RS_UBC_L = 18,
+       SIG_LEVEL = 19,
+       GPP_CTRL = 20,
+       RESET = 21,
+       DISEQC_MODE = 22,
+       SYM_RATE_H = 23,
+       SYM_RATE_L = 24,
+       VIT_MODE = 25,
+       QPSK_CTRL = 26,
+       GO = 27,
+       IE_QPSK_H = 28,
+       IE_QPSK_M = 29,
+       IE_QPSK_L = 30,
+       IE_FEC = 31,
+       QPSK_STAT_EN = 32,
+       FEC_STAT_EN = 33,
+       SYS_CLK = 34,
+       DISEQC_RATIO = 35,
+       DISEQC_INSTR = 36,
+       FR_LIM = 37,
+       FR_OFF = 38,
+       AGC_CTRL = 39,
+       AGC_INIT = 40,
+       AGC_REF = 41,
+       AGC_MAX = 42,
+       AGC_MIN = 43,
+       AGC_LK_TH = 44,
+       TS_AGC_LK_TH = 45,
+       AGC_PWR_SET = 46,
+       QPSK_MISC = 47,
+       SNR_THS_LOW = 48,
+       SNR_THS_HIGH = 49,
+       TS_SW_RATE = 50,
+       TS_SW_LIM_L = 51,
+       TS_SW_LIM_H = 52,
+       CS_SW_RATE_1 = 53,
+       CS_SW_RATE_2 = 54,
+       CS_SW_RATE_3 = 55,
+       CS_SW_RATE_4 = 56,
+       CS_SW_LIM = 57,
+       TS_LPK = 58,
+       TS_LPK_M = 59,
+       TS_LPK_L = 60,
+       CS_KPROP_H = 61,
+       CS_KPROP_L = 62,
+       CS_KINT_H = 63,
+       CS_KINT_L = 64,
+       QPSK_SCALE = 65,
+       TLD_OUTCLK_TH = 66,
+       TLD_INCLK_TH = 67,
+       FLD_TH = 68,
+       PLD_OUTLK3 = 69,
+       PLD_OUTLK2 = 70,
+       PLD_OUTLK1 = 71,
+       PLD_OUTLK0 = 72,
+       PLD_INLK3 = 73,
+       PLD_INLK2 = 74,
+       PLD_INLK1 = 75,
+       PLD_INLK0 = 76,
+       PLD_ACC_TIME = 77,
+       SWEEP_PAR = 78,
+       STARTUP_TIME = 79,
+       LOSSLOCK_TH = 80,
+       FEC_LOCK_TM = 81,
+       LOSSLOCK_TM = 82,
+       VIT_ERRPER_H = 83,
+       VIT_ERRPER_M = 84,
+       VIT_ERRPER_L = 85,
+       HW_CTRL = 84,   /* ZL10313 only */
+       MPEG_CTRL = 85, /* ZL10313 only */
+       VIT_SETUP = 86,
+       VIT_REF0 = 87,
+       VIT_REF1 = 88,
+       VIT_REF2 = 89,
+       VIT_REF3 = 90,
+       VIT_REF4 = 91,
+       VIT_REF5 = 92,
+       VIT_REF6 = 93,
+       VIT_MAXERR = 94,
+       BA_SETUPT = 95,
+       OP_CTRL = 96,
+       FEC_SETUP = 97,
+       PROG_SYNC = 98,
+       AFC_SEAR_TH = 99,
+       CSACC_DIF_TH = 100,
+       QPSK_LK_CT = 101,
+       QPSK_ST_CT = 102,
+       MON_CTRL = 103,
+       QPSK_RESET = 104,
+       QPSK_TST_CT = 105,
+       QPSK_TST_ST = 106,
+       TEST_R = 107,
+       AGC_H = 108,
+       AGC_M = 109,
+       AGC_L = 110,
+       FREQ_ERR1_H = 111,
+       FREQ_ERR1_M = 112,
+       FREQ_ERR1_L = 113,
+       FREQ_ERR2_H = 114,
+       FREQ_ERR2_L = 115,
+       SYM_RAT_OP_H = 116,
+       SYM_RAT_OP_L = 117,
+       DESEQC2_INT = 118,
+       DISEQC2_STAT = 119,
+       DISEQC2_FIFO = 120,
+       DISEQC2_CTRL1 = 121,
+       DISEQC2_CTRL2 = 122,
+       MONITOR_H = 123,
+       MONITOR_L = 124,
+       TEST_MODE = 125,
+       ID = 126,
+       CONFIG = 127
+};
+
+enum mt312_model_id {
+       ID_VP310 = 1,
+       ID_MT312 = 3,
+       ID_ZL10313 = 5,
+};
+
+#endif                         /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c
new file mode 100644 (file)
index 0000000..2c3b50e
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+ *  Driver for Zarlink DVB-T MT352 demodulator
+ *
+ *  Written by Holger Waechtler <holger@qanu.de>
+ *      and Daniel Mack <daniel@qanu.de>
+ *
+ *  AVerMedia AVerTV DVB-T 771 support by
+ *       Wolfram Joost <dbox2@frokaschwei.de>
+ *
+ *  Support for Samsung TDTC9251DH01C(M) tuner
+ *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
+ *                     Amauri  Celani  <acelani@essegi.net>
+ *
+ *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "mt352_priv.h"
+#include "mt352.h"
+
+struct mt352_state {
+       struct i2c_adapter* i2c;
+       struct dvb_frontend frontend;
+
+       /* configuration settings */
+       struct mt352_config config;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "mt352: " args); \
+       } while (0)
+
+static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+       int err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
+               return err;
+       }
+       return 0;
+}
+
+static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
+{
+       int err,i;
+       for (i=0; i < ilen-1; i++)
+               if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
+                       return err;
+
+       return 0;
+}
+
+static int mt352_read_register(struct mt352_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config.demod_address,
+                                   .flags = 0,
+                                   .buf = b0, .len = 1 },
+                                 { .addr = state->config.demod_address,
+                                   .flags = I2C_M_RD,
+                                   .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk("%s: readreg error (reg=%d, ret==%i)\n",
+                      __func__, reg, ret);
+               return ret;
+       }
+
+       return b1[0];
+}
+
+static int mt352_sleep(struct dvb_frontend* fe)
+{
+       static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
+
+       _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
+       return 0;
+}
+
+static void mt352_calc_nominal_rate(struct mt352_state* state,
+                                   u32 bandwidth,
+                                   unsigned char *buf)
+{
+       u32 adc_clock = 20480; /* 20.340 MHz */
+       u32 bw,value;
+
+       switch (bandwidth) {
+       case 6000000:
+               bw = 6;
+               break;
+       case 7000000:
+               bw = 7;
+               break;
+       case 8000000:
+       default:
+               bw = 8;
+               break;
+       }
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
+
+       value = 64 * bw * (1<<16) / (7 * 8);
+       value = value * 1000 / adc_clock;
+       dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
+               __func__, bw, adc_clock, value);
+       buf[0] = msb(value);
+       buf[1] = lsb(value);
+}
+
+static void mt352_calc_input_freq(struct mt352_state* state,
+                                 unsigned char *buf)
+{
+       int adc_clock = 20480; /* 20.480000 MHz */
+       int if2       = 36167; /* 36.166667 MHz */
+       int ife,value;
+
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
+       if (state->config.if2)
+               if2 = state->config.if2;
+
+       if (adc_clock >= if2 * 2)
+               ife = if2;
+       else {
+               ife = adc_clock - (if2 % adc_clock);
+               if (ife > adc_clock / 2)
+                       ife = adc_clock - ife;
+       }
+       value = -16374 * ife / adc_clock;
+       dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
+               __func__, if2, ife, adc_clock, value, value & 0x3fff);
+       buf[0] = msb(value);
+       buf[1] = lsb(value);
+}
+
+static int mt352_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *op = &fe->dtv_property_cache;
+       struct mt352_state* state = fe->demodulator_priv;
+       unsigned char buf[13];
+       static unsigned char tuner_go[] = { 0x5d, 0x01 };
+       static unsigned char fsm_go[]   = { 0x5e, 0x01 };
+       unsigned int tps = 0;
+
+       switch (op->code_rate_HP) {
+               case FEC_2_3:
+                       tps |= (1 << 7);
+                       break;
+               case FEC_3_4:
+                       tps |= (2 << 7);
+                       break;
+               case FEC_5_6:
+                       tps |= (3 << 7);
+                       break;
+               case FEC_7_8:
+                       tps |= (4 << 7);
+                       break;
+               case FEC_1_2:
+               case FEC_AUTO:
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       switch (op->code_rate_LP) {
+               case FEC_2_3:
+                       tps |= (1 << 4);
+                       break;
+               case FEC_3_4:
+                       tps |= (2 << 4);
+                       break;
+               case FEC_5_6:
+                       tps |= (3 << 4);
+                       break;
+               case FEC_7_8:
+                       tps |= (4 << 4);
+                       break;
+               case FEC_1_2:
+               case FEC_AUTO:
+                       break;
+               case FEC_NONE:
+                       if (op->hierarchy == HIERARCHY_AUTO ||
+                           op->hierarchy == HIERARCHY_NONE)
+                               break;
+               default:
+                       return -EINVAL;
+       }
+
+       switch (op->modulation) {
+               case QPSK:
+                       break;
+               case QAM_AUTO:
+               case QAM_16:
+                       tps |= (1 << 13);
+                       break;
+               case QAM_64:
+                       tps |= (2 << 13);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       switch (op->transmission_mode) {
+               case TRANSMISSION_MODE_2K:
+               case TRANSMISSION_MODE_AUTO:
+                       break;
+               case TRANSMISSION_MODE_8K:
+                       tps |= (1 << 0);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       switch (op->guard_interval) {
+               case GUARD_INTERVAL_1_32:
+               case GUARD_INTERVAL_AUTO:
+                       break;
+               case GUARD_INTERVAL_1_16:
+                       tps |= (1 << 2);
+                       break;
+               case GUARD_INTERVAL_1_8:
+                       tps |= (2 << 2);
+                       break;
+               case GUARD_INTERVAL_1_4:
+                       tps |= (3 << 2);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       switch (op->hierarchy) {
+               case HIERARCHY_AUTO:
+               case HIERARCHY_NONE:
+                       break;
+               case HIERARCHY_1:
+                       tps |= (1 << 10);
+                       break;
+               case HIERARCHY_2:
+                       tps |= (2 << 10);
+                       break;
+               case HIERARCHY_4:
+                       tps |= (3 << 10);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+
+       buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
+
+       buf[1] = msb(tps);      /* TPS_GIVEN_(1|0) */
+       buf[2] = lsb(tps);
+
+       buf[3] = 0x50;  // old
+//     buf[3] = 0xf4;  // pinnacle
+
+       mt352_calc_nominal_rate(state, op->bandwidth_hz, buf+4);
+       mt352_calc_input_freq(state, buf+6);
+
+       if (state->config.no_tuner) {
+               if (fe->ops.tuner_ops.set_params) {
+                       fe->ops.tuner_ops.set_params(fe);
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+
+               _mt352_write(fe, buf, 8);
+               _mt352_write(fe, fsm_go, 2);
+       } else {
+               if (fe->ops.tuner_ops.calc_regs) {
+                       fe->ops.tuner_ops.calc_regs(fe, buf+8, 5);
+                       buf[8] <<= 1;
+                       _mt352_write(fe, buf, sizeof(buf));
+                       _mt352_write(fe, tuner_go, 2);
+               }
+       }
+
+       return 0;
+}
+
+static int mt352_get_parameters(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *op = &fe->dtv_property_cache;
+       struct mt352_state* state = fe->demodulator_priv;
+       u16 tps;
+       u16 div;
+       u8 trl;
+       static const u8 tps_fec_to_api[8] =
+       {
+               FEC_1_2,
+               FEC_2_3,
+               FEC_3_4,
+               FEC_5_6,
+               FEC_7_8,
+               FEC_AUTO,
+               FEC_AUTO,
+               FEC_AUTO
+       };
+
+       if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
+               return -EINVAL;
+
+       /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
+        * the mt352 sometimes works with the wrong parameters
+        */
+       tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
+       div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
+       trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
+
+       op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
+       op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
+
+       switch ( (tps >> 13) & 3)
+       {
+               case 0:
+                       op->modulation = QPSK;
+                       break;
+               case 1:
+                       op->modulation = QAM_16;
+                       break;
+               case 2:
+                       op->modulation = QAM_64;
+                       break;
+               default:
+                       op->modulation = QAM_AUTO;
+                       break;
+       }
+
+       op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
+
+       switch ( (tps >> 2) & 3)
+       {
+               case 0:
+                       op->guard_interval = GUARD_INTERVAL_1_32;
+                       break;
+               case 1:
+                       op->guard_interval = GUARD_INTERVAL_1_16;
+                       break;
+               case 2:
+                       op->guard_interval = GUARD_INTERVAL_1_8;
+                       break;
+               case 3:
+                       op->guard_interval = GUARD_INTERVAL_1_4;
+                       break;
+               default:
+                       op->guard_interval = GUARD_INTERVAL_AUTO;
+                       break;
+       }
+
+       switch ( (tps >> 10) & 7)
+       {
+               case 0:
+                       op->hierarchy = HIERARCHY_NONE;
+                       break;
+               case 1:
+                       op->hierarchy = HIERARCHY_1;
+                       break;
+               case 2:
+                       op->hierarchy = HIERARCHY_2;
+                       break;
+               case 3:
+                       op->hierarchy = HIERARCHY_4;
+                       break;
+               default:
+                       op->hierarchy = HIERARCHY_AUTO;
+                       break;
+       }
+
+       op->frequency = (500 * (div - IF_FREQUENCYx6)) / 3 * 1000;
+
+       if (trl == 0x72)
+               op->bandwidth_hz = 8000000;
+       else if (trl == 0x64)
+               op->bandwidth_hz = 7000000;
+       else
+               op->bandwidth_hz = 6000000;
+
+
+       if (mt352_read_register(state, STATUS_2) & 0x02)
+               op->inversion = INVERSION_OFF;
+       else
+               op->inversion = INVERSION_ON;
+
+       return 0;
+}
+
+static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+       int s0, s1, s3;
+
+       /* FIXME:
+        *
+        * The MT352 design manual from Zarlink states (page 46-47):
+        *
+        * Notes about the TUNER_GO register:
+        *
+        * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
+        * byte is copied from the tuner to the STATUS_3 register and
+        * completion of the read operation is indicated by bit-5 of the
+        * INTERRUPT_3 register.
+        */
+
+       if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
+               return -EREMOTEIO;
+       if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
+               return -EREMOTEIO;
+       if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
+               return -EREMOTEIO;
+
+       *status = 0;
+       if (s0 & (1 << 4))
+               *status |= FE_HAS_CARRIER;
+       if (s0 & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if (s0 & (1 << 5))
+               *status |= FE_HAS_LOCK;
+       if (s1 & (1 << 1))
+               *status |= FE_HAS_SYNC;
+       if (s3 & (1 << 6))
+               *status |= FE_HAS_SIGNAL;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+                     (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+
+       *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
+              (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
+              (mt352_read_register (state, RS_ERR_CNT_0));
+
+       return 0;
+}
+
+static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+
+       /* align the 12 bit AGC gain with the most significant bits */
+       u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
+               (mt352_read_register(state, AGC_GAIN_0) << 4);
+
+       /* inverse of gain is signal strength */
+       *strength = ~signal;
+       return 0;
+}
+
+static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+
+       u8 _snr = mt352_read_register (state, SNR);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+
+       *ucblocks = (mt352_read_register (state,  RS_UBC_1) << 8) |
+                   (mt352_read_register (state,  RS_UBC_0));
+
+       return 0;
+}
+
+static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 800;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static int mt352_init(struct dvb_frontend* fe)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+
+       static u8 mt352_reset_attach [] = { RESET, 0xC0 };
+
+       dprintk("%s: hello\n",__func__);
+
+       if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
+           (mt352_read_register(state, CONFIG) & 0x20) == 0) {
+
+               /* Do a "hard" reset */
+               _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
+               return state->config.demod_init(fe);
+       }
+
+       return 0;
+}
+
+static void mt352_release(struct dvb_frontend* fe)
+{
+       struct mt352_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops mt352_ops;
+
+struct dvb_frontend* mt352_attach(const struct mt352_config* config,
+                                 struct i2c_adapter* i2c)
+{
+       struct mt352_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config,config,sizeof(struct mt352_config));
+
+       /* check if the demod is there */
+       if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops mt352_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Zarlink MT352 DVB-T",
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = mt352_release,
+
+       .init = mt352_init,
+       .sleep = mt352_sleep,
+       .write = _mt352_write,
+
+       .set_frontend = mt352_set_parameters,
+       .get_frontend = mt352_get_parameters,
+       .get_tune_settings = mt352_get_tune_settings,
+
+       .read_status = mt352_read_status,
+       .read_ber = mt352_read_ber,
+       .read_signal_strength = mt352_read_signal_strength,
+       .read_snr = mt352_read_snr,
+       .read_ucblocks = mt352_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
+MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(mt352_attach);
diff --git a/drivers/media/dvb-frontends/mt352.h b/drivers/media/dvb-frontends/mt352.h
new file mode 100644 (file)
index 0000000..ca2562d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Driver for Zarlink DVB-T MT352 demodulator
+ *
+ *  Written by Holger Waechtler <holger@qanu.de>
+ *      and Daniel Mack <daniel@qanu.de>
+ *
+ *  AVerMedia AVerTV DVB-T 771 support by
+ *       Wolfram Joost <dbox2@frokaschwei.de>
+ *
+ *  Support for Samsung TDTC9251DH01C(M) tuner
+ *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
+ *                     Amauri  Celani  <acelani@essegi.net>
+ *
+ *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MT352_H
+#define MT352_H
+
+#include <linux/dvb/frontend.h>
+
+struct mt352_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* frequencies in kHz */
+       int adc_clock;  // default: 20480
+       int if2;        // default: 36166
+
+       /* set if no pll is connected to the secondary i2c bus */
+       int no_tuner;
+
+       /* Initialise the demodulator and PLL. Cannot be NULL */
+       int (*demod_init)(struct dvb_frontend* fe);
+};
+
+#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE))
+extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
+                                        struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
+                                        struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_MT352
+
+static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) {
+       int r = 0;
+       if (fe->ops.write)
+               r = fe->ops.write(fe, buf, len);
+       return r;
+}
+
+#endif // MT352_H
diff --git a/drivers/media/dvb-frontends/mt352_priv.h b/drivers/media/dvb-frontends/mt352_priv.h
new file mode 100644 (file)
index 0000000..44ad0d4
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *  Driver for Zarlink DVB-T MT352 demodulator
+ *
+ *  Written by Holger Waechtler <holger@qanu.de>
+ *      and Daniel Mack <daniel@qanu.de>
+ *
+ *  AVerMedia AVerTV DVB-T 771 support by
+ *       Wolfram Joost <dbox2@frokaschwei.de>
+ *
+ *  Support for Samsung TDTC9251DH01C(M) tuner
+ *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
+ *                     Amauri  Celani  <acelani@essegi.net>
+ *
+ *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
+ *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef _MT352_PRIV_
+#define _MT352_PRIV_
+
+#define ID_MT352        0x13
+
+#define msb(x) (((x) >> 8) & 0xff)
+#define lsb(x) ((x) & 0xff)
+
+enum mt352_reg_addr {
+       STATUS_0           = 0x00,
+       STATUS_1           = 0x01,
+       STATUS_2           = 0x02,
+       STATUS_3           = 0x03,
+       STATUS_4           = 0x04,
+       INTERRUPT_0        = 0x05,
+       INTERRUPT_1        = 0x06,
+       INTERRUPT_2        = 0x07,
+       INTERRUPT_3        = 0x08,
+       SNR                = 0x09,
+       VIT_ERR_CNT_2      = 0x0A,
+       VIT_ERR_CNT_1      = 0x0B,
+       VIT_ERR_CNT_0      = 0x0C,
+       RS_ERR_CNT_2       = 0x0D,
+       RS_ERR_CNT_1       = 0x0E,
+       RS_ERR_CNT_0       = 0x0F,
+       RS_UBC_1           = 0x10,
+       RS_UBC_0           = 0x11,
+       AGC_GAIN_3         = 0x12,
+       AGC_GAIN_2         = 0x13,
+       AGC_GAIN_1         = 0x14,
+       AGC_GAIN_0         = 0x15,
+       FREQ_OFFSET_2      = 0x17,
+       FREQ_OFFSET_1      = 0x18,
+       FREQ_OFFSET_0      = 0x19,
+       TIMING_OFFSET_1    = 0x1A,
+       TIMING_OFFSET_0    = 0x1B,
+       CHAN_FREQ_1        = 0x1C,
+       CHAN_FREQ_0        = 0x1D,
+       TPS_RECEIVED_1     = 0x1E,
+       TPS_RECEIVED_0     = 0x1F,
+       TPS_CURRENT_1      = 0x20,
+       TPS_CURRENT_0      = 0x21,
+       TPS_CELL_ID_1      = 0x22,
+       TPS_CELL_ID_0      = 0x23,
+       TPS_MISC_DATA_2    = 0x24,
+       TPS_MISC_DATA_1    = 0x25,
+       TPS_MISC_DATA_0    = 0x26,
+       RESET              = 0x50,
+       TPS_GIVEN_1        = 0x51,
+       TPS_GIVEN_0        = 0x52,
+       ACQ_CTL            = 0x53,
+       TRL_NOMINAL_RATE_1 = 0x54,
+       TRL_NOMINAL_RATE_0 = 0x55,
+       INPUT_FREQ_1       = 0x56,
+       INPUT_FREQ_0       = 0x57,
+       TUNER_ADDR         = 0x58,
+       CHAN_START_1       = 0x59,
+       CHAN_START_0       = 0x5A,
+       CONT_1             = 0x5B,
+       CONT_0             = 0x5C,
+       TUNER_GO           = 0x5D,
+       STATUS_EN_0        = 0x5F,
+       STATUS_EN_1        = 0x60,
+       INTERRUPT_EN_0     = 0x61,
+       INTERRUPT_EN_1     = 0x62,
+       INTERRUPT_EN_2     = 0x63,
+       INTERRUPT_EN_3     = 0x64,
+       AGC_TARGET         = 0x67,
+       AGC_CTL            = 0x68,
+       CAPT_RANGE         = 0x75,
+       SNR_SELECT_1       = 0x79,
+       SNR_SELECT_0       = 0x7A,
+       RS_ERR_PER_1       = 0x7C,
+       RS_ERR_PER_0       = 0x7D,
+       CHIP_ID            = 0x7F,
+       CHAN_STOP_1        = 0x80,
+       CHAN_STOP_0        = 0x81,
+       CHAN_STEP_1        = 0x82,
+       CHAN_STEP_0        = 0x83,
+       FEC_LOCK_TIME      = 0x85,
+       OFDM_LOCK_TIME     = 0x86,
+       ACQ_DELAY          = 0x87,
+       SCAN_CTL           = 0x88,
+       CLOCK_CTL          = 0x89,
+       CONFIG             = 0x8A,
+       MCLK_RATIO         = 0x8B,
+       GPP_CTL            = 0x8C,
+       ADC_CTL_1          = 0x8E,
+       ADC_CTL_0          = 0x8F
+};
+
+/* here we assume 1/6MHz == 166.66kHz stepsize */
+#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
+
+#endif                          /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
new file mode 100644 (file)
index 0000000..8e28894
--- /dev/null
@@ -0,0 +1,1242 @@
+/*
+ *    Support for NXT2002 and NXT2004 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
+ *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
+ *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
+ *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+/*
+ *                      NOTES ABOUT THIS DRIVER
+ *
+ * This Linux driver supports:
+ *   B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
+ *   AverTVHD MCE A180 (NXT2004)
+ *   ATI HDTV Wonder (NXT2004)
+ *
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
+ * download/extract the appropriate firmware, and then copy it to
+ * /usr/lib/hotplug/firmware/ or /lib/firmware/
+ * (depending on configuration of firmware hotplug).
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
+#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
+#define CRC_CCIT_MASK 0x1021
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "dvb_frontend.h"
+#include "nxt200x.h"
+
+struct nxt200x_state {
+
+       struct i2c_adapter* i2c;
+       const struct nxt200x_config* config;
+       struct dvb_frontend frontend;
+
+       /* demodulator private data */
+       nxt_chip_type demod_chip;
+       u8 initialised:1;
+};
+
+static int debug;
+#define dprintk(args...)       do { if (debug) pr_debug(args); } while (0)
+
+static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
+{
+       int err;
+       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
+                       __func__, addr, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
+{
+       int err;
+       struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
+                       __func__, addr, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
+                              const u8 *buf, u8 len)
+{
+       u8 buf2 [len+1];
+       int err;
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
+
+       buf2[0] = reg;
+       memcpy(&buf2[1], buf, len);
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
+                       __func__, state->config->demod_address, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
+{
+       u8 reg2 [] = { reg };
+
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
+                       { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
+
+       int err;
+
+       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+               pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
+                       __func__, state->config->demod_address, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static u16 nxt200x_crc(u16 crc, u8 c)
+{
+       u8 i;
+       u16 input = (u16) c & 0xFF;
+
+       input<<=8;
+       for(i=0; i<8; i++) {
+               if((crc^input) & 0x8000)
+                       crc=(crc<<1)^CRC_CCIT_MASK;
+               else
+                       crc<<=1;
+               input<<=1;
+       }
+       return crc;
+}
+
+static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
+{
+       u8 attr, len2, buf;
+       dprintk("%s\n", __func__);
+
+       /* set mutli register register */
+       nxt200x_writebytes(state, 0x35, &reg, 1);
+
+       /* send the actual data */
+       nxt200x_writebytes(state, 0x36, data, len);
+
+       switch (state->demod_chip) {
+               case NXT2002:
+                       len2 = len;
+                       buf = 0x02;
+                       break;
+               case NXT2004:
+                       /* probably not right, but gives correct values */
+                       attr = 0x02;
+                       if (reg & 0x80) {
+                               attr = attr << 1;
+                               if (reg & 0x04)
+                                       attr = attr >> 1;
+                       }
+                       /* set write bit */
+                       len2 = ((attr << 4) | 0x10) | len;
+                       buf = 0x80;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       /* set multi register length */
+       nxt200x_writebytes(state, 0x34, &len2, 1);
+
+       /* toggle the multireg write bit */
+       nxt200x_writebytes(state, 0x21, &buf, 1);
+
+       nxt200x_readbytes(state, 0x21, &buf, 1);
+
+       switch (state->demod_chip) {
+               case NXT2002:
+                       if ((buf & 0x02) == 0)
+                               return 0;
+                       break;
+               case NXT2004:
+                       if (buf == 0)
+                               return 0;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       pr_warn("Error writing multireg register 0x%02X\n", reg);
+
+       return 0;
+}
+
+static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
+{
+       int i;
+       u8 buf, len2, attr;
+       dprintk("%s\n", __func__);
+
+       /* set mutli register register */
+       nxt200x_writebytes(state, 0x35, &reg, 1);
+
+       switch (state->demod_chip) {
+               case NXT2002:
+                       /* set multi register length */
+                       len2 = len & 0x80;
+                       nxt200x_writebytes(state, 0x34, &len2, 1);
+
+                       /* read the actual data */
+                       nxt200x_readbytes(state, reg, data, len);
+                       return 0;
+                       break;
+               case NXT2004:
+                       /* probably not right, but gives correct values */
+                       attr = 0x02;
+                       if (reg & 0x80) {
+                               attr = attr << 1;
+                               if (reg & 0x04)
+                                       attr = attr >> 1;
+                       }
+
+                       /* set multi register length */
+                       len2 = (attr << 4) | len;
+                       nxt200x_writebytes(state, 0x34, &len2, 1);
+
+                       /* toggle the multireg bit*/
+                       buf = 0x80;
+                       nxt200x_writebytes(state, 0x21, &buf, 1);
+
+                       /* read the actual data */
+                       for(i = 0; i < len; i++) {
+                               nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
+                       }
+                       return 0;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+}
+
+static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
+{
+       u8 buf, stopval, counter = 0;
+       dprintk("%s\n", __func__);
+
+       /* set correct stop value */
+       switch (state->demod_chip) {
+               case NXT2002:
+                       stopval = 0x40;
+                       break;
+               case NXT2004:
+                       stopval = 0x10;
+                       break;
+               default:
+                       stopval = 0;
+                       break;
+       }
+
+       buf = 0x80;
+       nxt200x_writebytes(state, 0x22, &buf, 1);
+
+       while (counter < 20) {
+               nxt200x_readbytes(state, 0x31, &buf, 1);
+               if (buf & stopval)
+                       return;
+               msleep(10);
+               counter++;
+       }
+
+       pr_warn("Timeout waiting for nxt200x to stop. This is ok after "
+               "firmware upload.\n");
+       return;
+}
+
+static void nxt200x_microcontroller_start (struct nxt200x_state* state)
+{
+       u8 buf;
+       dprintk("%s\n", __func__);
+
+       buf = 0x00;
+       nxt200x_writebytes(state, 0x22, &buf, 1);
+}
+
+static void nxt2004_microcontroller_init (struct nxt200x_state* state)
+{
+       u8 buf[9];
+       u8 counter = 0;
+       dprintk("%s\n", __func__);
+
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x2b, buf, 1);
+       buf[0] = 0x70;
+       nxt200x_writebytes(state, 0x34, buf, 1);
+       buf[0] = 0x04;
+       nxt200x_writebytes(state, 0x35, buf, 1);
+       buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
+       buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
+       nxt200x_writebytes(state, 0x36, buf, 9);
+       buf[0] = 0x80;
+       nxt200x_writebytes(state, 0x21, buf, 1);
+
+       while (counter < 20) {
+               nxt200x_readbytes(state, 0x21, buf, 1);
+               if (buf[0] == 0)
+                       return;
+               msleep(10);
+               counter++;
+       }
+
+       pr_warn("Timeout waiting for nxt2004 to init.\n");
+
+       return;
+}
+
+static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
+{
+       u8 buf, count = 0;
+
+       dprintk("%s\n", __func__);
+
+       dprintk("Tuner Bytes: %*ph\n", 4, data + 1);
+
+       /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
+        * direct write is required for Philips TUV1236D and ALPS TDHU2 */
+       switch (state->demod_chip) {
+               case NXT2004:
+                       if (i2c_writebytes(state, data[0], data+1, 4))
+                               pr_warn("error writing to tuner\n");
+                       /* wait until we have a lock */
+                       while (count < 20) {
+                               i2c_readbytes(state, data[0], &buf, 1);
+                               if (buf & 0x40)
+                                       return 0;
+                               msleep(100);
+                               count++;
+                       }
+                       pr_warn("timeout waiting for tuner lock\n");
+                       break;
+               case NXT2002:
+                       /* set the i2c transfer speed to the tuner */
+                       buf = 0x03;
+                       nxt200x_writebytes(state, 0x20, &buf, 1);
+
+                       /* setup to transfer 4 bytes via i2c */
+                       buf = 0x04;
+                       nxt200x_writebytes(state, 0x34, &buf, 1);
+
+                       /* write actual tuner bytes */
+                       nxt200x_writebytes(state, 0x36, data+1, 4);
+
+                       /* set tuner i2c address */
+                       buf = data[0] << 1;
+                       nxt200x_writebytes(state, 0x35, &buf, 1);
+
+                       /* write UC Opmode to begin transfer */
+                       buf = 0x80;
+                       nxt200x_writebytes(state, 0x21, &buf, 1);
+
+                       while (count < 20) {
+                               nxt200x_readbytes(state, 0x21, &buf, 1);
+                               if ((buf & 0x80)== 0x00)
+                                       return 0;
+                               msleep(100);
+                               count++;
+                       }
+                       pr_warn("timeout error writing to tuner\n");
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+       return 0;
+}
+
+static void nxt200x_agc_reset(struct nxt200x_state* state)
+{
+       u8 buf;
+       dprintk("%s\n", __func__);
+
+       switch (state->demod_chip) {
+               case NXT2002:
+                       buf = 0x08;
+                       nxt200x_writebytes(state, 0x08, &buf, 1);
+                       buf = 0x00;
+                       nxt200x_writebytes(state, 0x08, &buf, 1);
+                       break;
+               case NXT2004:
+                       nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
+                       buf = 0x08;
+                       nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
+                       buf = 0x00;
+                       nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
+                       break;
+               default:
+                       break;
+       }
+       return;
+}
+
+static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 buf[3], written = 0, chunkpos = 0;
+       u16 rambase, position, crc = 0;
+
+       dprintk("%s\n", __func__);
+       dprintk("Firmware is %zu bytes\n", fw->size);
+
+       /* Get the RAM base for this nxt2002 */
+       nxt200x_readbytes(state, 0x10, buf, 1);
+
+       if (buf[0] & 0x10)
+               rambase = 0x1000;
+       else
+               rambase = 0x0000;
+
+       dprintk("rambase on this nxt2002 is %04X\n", rambase);
+
+       /* Hold the micro in reset while loading firmware */
+       buf[0] = 0x80;
+       nxt200x_writebytes(state, 0x2B, buf, 1);
+
+       for (position = 0; position < fw->size; position++) {
+               if (written == 0) {
+                       crc = 0;
+                       chunkpos = 0x28;
+                       buf[0] = ((rambase + position) >> 8);
+                       buf[1] = (rambase + position) & 0xFF;
+                       buf[2] = 0x81;
+                       /* write starting address */
+                       nxt200x_writebytes(state, 0x29, buf, 3);
+               }
+               written++;
+               chunkpos++;
+
+               if ((written % 4) == 0)
+                       nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
+
+               crc = nxt200x_crc(crc, fw->data[position]);
+
+               if ((written == 255) || (position+1 == fw->size)) {
+                       /* write remaining bytes of firmware */
+                       nxt200x_writebytes(state, chunkpos+4-(written %4),
+                               &fw->data[position-(written %4) + 1],
+                               written %4);
+                       buf[0] = crc << 8;
+                       buf[1] = crc & 0xFF;
+
+                       /* write crc */
+                       nxt200x_writebytes(state, 0x2C, buf, 2);
+
+                       /* do a read to stop things */
+                       nxt200x_readbytes(state, 0x2A, buf, 1);
+
+                       /* set transfer mode to complete */
+                       buf[0] = 0x80;
+                       nxt200x_writebytes(state, 0x2B, buf, 1);
+
+                       written = 0;
+               }
+       }
+
+       return 0;
+};
+
+static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 buf[3];
+       u16 rambase, position, crc=0;
+
+       dprintk("%s\n", __func__);
+       dprintk("Firmware is %zu bytes\n", fw->size);
+
+       /* set rambase */
+       rambase = 0x1000;
+
+       /* hold the micro in reset while loading firmware */
+       buf[0] = 0x80;
+       nxt200x_writebytes(state, 0x2B, buf,1);
+
+       /* calculate firmware CRC */
+       for (position = 0; position < fw->size; position++) {
+               crc = nxt200x_crc(crc, fw->data[position]);
+       }
+
+       buf[0] = rambase >> 8;
+       buf[1] = rambase & 0xFF;
+       buf[2] = 0x81;
+       /* write starting address */
+       nxt200x_writebytes(state,0x29,buf,3);
+
+       for (position = 0; position < fw->size;) {
+               nxt200x_writebytes(state, 0x2C, &fw->data[position],
+                       fw->size-position > 255 ? 255 : fw->size-position);
+               position += (fw->size-position > 255 ? 255 : fw->size-position);
+       }
+       buf[0] = crc >> 8;
+       buf[1] = crc & 0xFF;
+
+       dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
+
+       /* write crc */
+       nxt200x_writebytes(state, 0x2C, buf,2);
+
+       /* do a read to stop things */
+       nxt200x_readbytes(state, 0x2C, buf, 1);
+
+       /* set transfer mode to complete */
+       buf[0] = 0x80;
+       nxt200x_writebytes(state, 0x2B, buf,1);
+
+       return 0;
+};
+
+static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 buf[5];
+
+       /* stop the micro first */
+       nxt200x_microcontroller_stop(state);
+
+       if (state->demod_chip == NXT2004) {
+               /* make sure demod is set to digital */
+               buf[0] = 0x04;
+               nxt200x_writebytes(state, 0x14, buf, 1);
+               buf[0] = 0x00;
+               nxt200x_writebytes(state, 0x17, buf, 1);
+       }
+
+       /* set additional params */
+       switch (p->modulation) {
+               case QAM_64:
+               case QAM_256:
+                       /* Set punctured clock for QAM */
+                       /* This is just a guess since I am unable to test it */
+                       if (state->config->set_ts_params)
+                               state->config->set_ts_params(fe, 1);
+                       break;
+               case VSB_8:
+                       /* Set non-punctured clock for VSB */
+                       if (state->config->set_ts_params)
+                               state->config->set_ts_params(fe, 0);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       if (fe->ops.tuner_ops.calc_regs) {
+               /* get tuning information */
+               fe->ops.tuner_ops.calc_regs(fe, buf, 5);
+
+               /* write frequency information */
+               nxt200x_writetuner(state, buf);
+       }
+
+       /* reset the agc now that tuning has been completed */
+       nxt200x_agc_reset(state);
+
+       /* set target power level */
+       switch (p->modulation) {
+               case QAM_64:
+               case QAM_256:
+                       buf[0] = 0x74;
+                       break;
+               case VSB_8:
+                       buf[0] = 0x70;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+       nxt200x_writebytes(state, 0x42, buf, 1);
+
+       /* configure sdm */
+       switch (state->demod_chip) {
+               case NXT2002:
+                       buf[0] = 0x87;
+                       break;
+               case NXT2004:
+                       buf[0] = 0x07;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+       nxt200x_writebytes(state, 0x57, buf, 1);
+
+       /* write sdm1 input */
+       buf[0] = 0x10;
+       buf[1] = 0x00;
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x58, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x58, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       /* write sdmx input */
+       switch (p->modulation) {
+               case QAM_64:
+                               buf[0] = 0x68;
+                               break;
+               case QAM_256:
+                               buf[0] = 0x64;
+                               break;
+               case VSB_8:
+                               buf[0] = 0x60;
+                               break;
+               default:
+                               return -EINVAL;
+                               break;
+       }
+       buf[1] = 0x00;
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x5C, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       /* write adc power lpf fc */
+       buf[0] = 0x05;
+       nxt200x_writebytes(state, 0x43, buf, 1);
+
+       if (state->demod_chip == NXT2004) {
+               /* write ??? */
+               buf[0] = 0x00;
+               buf[1] = 0x00;
+               nxt200x_writebytes(state, 0x46, buf, 2);
+       }
+
+       /* write accumulator2 input */
+       buf[0] = 0x80;
+       buf[1] = 0x00;
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       /* write kg1 */
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x4D, buf, 1);
+
+       /* write sdm12 lpf fc */
+       buf[0] = 0x44;
+       nxt200x_writebytes(state, 0x55, buf, 1);
+
+       /* write agc control reg */
+       buf[0] = 0x04;
+       nxt200x_writebytes(state, 0x41, buf, 1);
+
+       if (state->demod_chip == NXT2004) {
+               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+               buf[0] = 0x24;
+               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+               /* soft reset? */
+               nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+               buf[0] = 0x10;
+               nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+               nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+               buf[0] = 0x00;
+               nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+               buf[0] = 0x04;
+               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+               buf[0] = 0x00;
+               nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+               buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
+               nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+               nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+               buf[0] = 0x11;
+               nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+               buf[0] = 0x44;
+               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+       }
+
+       /* write agc ucgp0 */
+       switch (p->modulation) {
+               case QAM_64:
+                               buf[0] = 0x02;
+                               break;
+               case QAM_256:
+                               buf[0] = 0x03;
+                               break;
+               case VSB_8:
+                               buf[0] = 0x00;
+                               break;
+               default:
+                               return -EINVAL;
+                               break;
+       }
+       nxt200x_writebytes(state, 0x30, buf, 1);
+
+       /* write agc control reg */
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x41, buf, 1);
+
+       /* write accumulator2 input */
+       buf[0] = 0x80;
+       buf[1] = 0x00;
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x49, buf, 2);
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x49, buf, 2);
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
+
+       /* write agc control reg */
+       buf[0] = 0x04;
+       nxt200x_writebytes(state, 0x41, buf, 1);
+
+       nxt200x_microcontroller_start(state);
+
+       if (state->demod_chip == NXT2004) {
+               nxt2004_microcontroller_init(state);
+
+               /* ???? */
+               buf[0] = 0xF0;
+               buf[1] = 0x00;
+               nxt200x_writebytes(state, 0x5C, buf, 2);
+       }
+
+       /* adjacent channel detection should be done here, but I don't
+       have any stations with this need so I cannot test it */
+
+       return 0;
+}
+
+static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 lock;
+       nxt200x_readbytes(state, 0x31, &lock, 1);
+
+       *status = 0;
+       if (lock & 0x20) {
+               *status |= FE_HAS_SIGNAL;
+               *status |= FE_HAS_CARRIER;
+               *status |= FE_HAS_VITERBI;
+               *status |= FE_HAS_SYNC;
+               *status |= FE_HAS_LOCK;
+       }
+       return 0;
+}
+
+static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 b[3];
+
+       nxt200x_readreg_multibyte(state, 0xE6, b, 3);
+
+       *ber = ((b[0] << 8) + b[1]) * 8;
+
+       return 0;
+}
+
+static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 b[2];
+       u16 temp = 0;
+
+       /* setup to read cluster variance */
+       b[0] = 0x00;
+       nxt200x_writebytes(state, 0xA1, b, 1);
+
+       /* get multreg val */
+       nxt200x_readreg_multibyte(state, 0xA6, b, 2);
+
+       temp = (b[0] << 8) | b[1];
+       *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
+
+       return 0;
+}
+
+static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 b[2];
+       u16 temp = 0, temp2;
+       u32 snrdb = 0;
+
+       /* setup to read cluster variance */
+       b[0] = 0x00;
+       nxt200x_writebytes(state, 0xA1, b, 1);
+
+       /* get multreg val from 0xA6 */
+       nxt200x_readreg_multibyte(state, 0xA6, b, 2);
+
+       temp = (b[0] << 8) | b[1];
+       temp2 = 0x7FFF - temp;
+
+       /* snr will be in db */
+       if (temp2 > 0x7F00)
+               snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
+       else if (temp2 > 0x7EC0)
+               snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
+       else if (temp2 > 0x7C00)
+               snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
+       else
+               snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
+
+       /* the value reported back from the frontend will be FFFF=32db 0000=0db */
+       *snr = snrdb * (0xFFFF/32000);
+
+       return 0;
+}
+
+static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       u8 b[3];
+
+       nxt200x_readreg_multibyte(state, 0xE6, b, 3);
+       *ucblocks = b[2];
+
+       return 0;
+}
+
+static int nxt200x_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int nxt2002_init(struct dvb_frontend* fe)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       const struct firmware *fw;
+       int ret;
+       u8 buf[2];
+
+       /* request the firmware, this will block until someone uploads it */
+       pr_debug("%s: Waiting for firmware upload (%s)...\n",
+                __func__, NXT2002_DEFAULT_FIRMWARE);
+       ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
+                              state->i2c->dev.parent);
+       pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
+       if (ret) {
+               pr_err("%s: No firmware uploaded (timeout or file not found?)"
+                      "\n", __func__);
+               return ret;
+       }
+
+       ret = nxt2002_load_firmware(fe, fw);
+       release_firmware(fw);
+       if (ret) {
+               pr_err("%s: Writing firmware to device failed\n", __func__);
+               return ret;
+       }
+       pr_info("%s: Firmware upload complete\n", __func__);
+
+       /* Put the micro into reset */
+       nxt200x_microcontroller_stop(state);
+
+       /* ensure transfer is complete */
+       buf[0]=0x00;
+       nxt200x_writebytes(state, 0x2B, buf, 1);
+
+       /* Put the micro into reset for real this time */
+       nxt200x_microcontroller_stop(state);
+
+       /* soft reset everything (agc,frontend,eq,fec)*/
+       buf[0] = 0x0F;
+       nxt200x_writebytes(state, 0x08, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x08, buf, 1);
+
+       /* write agc sdm configure */
+       buf[0] = 0xF1;
+       nxt200x_writebytes(state, 0x57, buf, 1);
+
+       /* write mod output format */
+       buf[0] = 0x20;
+       nxt200x_writebytes(state, 0x09, buf, 1);
+
+       /* write fec mpeg mode */
+       buf[0] = 0x7E;
+       buf[1] = 0x00;
+       nxt200x_writebytes(state, 0xE9, buf, 2);
+
+       /* write mux selection */
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0xCC, buf, 1);
+
+       return 0;
+}
+
+static int nxt2004_init(struct dvb_frontend* fe)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       const struct firmware *fw;
+       int ret;
+       u8 buf[3];
+
+       /* ??? */
+       buf[0]=0x00;
+       nxt200x_writebytes(state, 0x1E, buf, 1);
+
+       /* request the firmware, this will block until someone uploads it */
+       pr_debug("%s: Waiting for firmware upload (%s)...\n",
+                __func__, NXT2004_DEFAULT_FIRMWARE);
+       ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
+                              state->i2c->dev.parent);
+       pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
+       if (ret) {
+               pr_err("%s: No firmware uploaded (timeout or file not found?)"
+                      "\n", __func__);
+               return ret;
+       }
+
+       ret = nxt2004_load_firmware(fe, fw);
+       release_firmware(fw);
+       if (ret) {
+               pr_err("%s: Writing firmware to device failed\n", __func__);
+               return ret;
+       }
+       pr_info("%s: Firmware upload complete\n", __func__);
+
+       /* ensure transfer is complete */
+       buf[0] = 0x01;
+       nxt200x_writebytes(state, 0x19, buf, 1);
+
+       nxt2004_microcontroller_init(state);
+       nxt200x_microcontroller_stop(state);
+       nxt200x_microcontroller_stop(state);
+       nxt2004_microcontroller_init(state);
+       nxt200x_microcontroller_stop(state);
+
+       /* soft reset everything (agc,frontend,eq,fec)*/
+       buf[0] = 0xFF;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+       /* write agc sdm configure */
+       buf[0] = 0xD7;
+       nxt200x_writebytes(state, 0x57, buf, 1);
+
+       /* ???*/
+       buf[0] = 0x07;
+       buf[1] = 0xfe;
+       nxt200x_writebytes(state, 0x35, buf, 2);
+       buf[0] = 0x12;
+       nxt200x_writebytes(state, 0x34, buf, 1);
+       buf[0] = 0x80;
+       nxt200x_writebytes(state, 0x21, buf, 1);
+
+       /* ???*/
+       buf[0] = 0x21;
+       nxt200x_writebytes(state, 0x0A, buf, 1);
+
+       /* ???*/
+       buf[0] = 0x01;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+       /* write fec mpeg mode */
+       buf[0] = 0x7E;
+       buf[1] = 0x00;
+       nxt200x_writebytes(state, 0xE9, buf, 2);
+
+       /* write mux selection */
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0xCC, buf, 1);
+
+       /* ???*/
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+       /* soft reset? */
+       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+       buf[0] = 0x10;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+       /* ???*/
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x01;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x70;
+       nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+       buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
+       nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+
+       nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+       buf[0] = 0x11;
+       nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x40;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+       nxt200x_readbytes(state, 0x10, buf, 1);
+       buf[0] = 0x10;
+       nxt200x_writebytes(state, 0x10, buf, 1);
+       nxt200x_readbytes(state, 0x0A, buf, 1);
+       buf[0] = 0x21;
+       nxt200x_writebytes(state, 0x0A, buf, 1);
+
+       nxt2004_microcontroller_init(state);
+
+       buf[0] = 0x21;
+       nxt200x_writebytes(state, 0x0A, buf, 1);
+       buf[0] = 0x7E;
+       nxt200x_writebytes(state, 0xE9, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0xEA, buf, 1);
+
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+       /* soft reset? */
+       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+       buf[0] = 0x10;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
+
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x04;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x81, buf, 1);
+       buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
+       nxt200x_writereg_multibyte(state, 0x82, buf, 3);
+
+       nxt200x_readreg_multibyte(state, 0x88, buf, 1);
+       buf[0] = 0x11;
+       nxt200x_writereg_multibyte(state, 0x88, buf, 1);
+
+       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
+       buf[0] = 0x44;
+       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
+
+       /* initialize tuner */
+       nxt200x_readbytes(state, 0x10, buf, 1);
+       buf[0] = 0x12;
+       nxt200x_writebytes(state, 0x10, buf, 1);
+       buf[0] = 0x04;
+       nxt200x_writebytes(state, 0x13, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x16, buf, 1);
+       buf[0] = 0x04;
+       nxt200x_writebytes(state, 0x14, buf, 1);
+       buf[0] = 0x00;
+       nxt200x_writebytes(state, 0x14, buf, 1);
+       nxt200x_writebytes(state, 0x17, buf, 1);
+       nxt200x_writebytes(state, 0x14, buf, 1);
+       nxt200x_writebytes(state, 0x17, buf, 1);
+
+       return 0;
+}
+
+static int nxt200x_init(struct dvb_frontend* fe)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       int ret = 0;
+
+       if (!state->initialised) {
+               switch (state->demod_chip) {
+                       case NXT2002:
+                               ret = nxt2002_init(fe);
+                               break;
+                       case NXT2004:
+                               ret = nxt2004_init(fe);
+                               break;
+                       default:
+                               return -EINVAL;
+                               break;
+               }
+               state->initialised = 1;
+       }
+       return ret;
+}
+
+static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 500;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void nxt200x_release(struct dvb_frontend* fe)
+{
+       struct nxt200x_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops nxt200x_ops;
+
+struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+                                  struct i2c_adapter* i2c)
+{
+       struct nxt200x_state* state = NULL;
+       u8 buf [] = {0,0,0,0,0};
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+
+       /* read card id */
+       nxt200x_readbytes(state, 0x00, buf, 5);
+       dprintk("NXT info: %*ph\n", 5, buf);
+
+       /* set demod chip */
+       switch (buf[0]) {
+               case 0x04:
+                       state->demod_chip = NXT2002;
+                       pr_info("NXT2002 Detected\n");
+                       break;
+               case 0x05:
+                       state->demod_chip = NXT2004;
+                       pr_info("NXT2004 Detected\n");
+                       break;
+               default:
+                       goto error;
+       }
+
+       /* make sure demod chip is supported */
+       switch (state->demod_chip) {
+               case NXT2002:
+                       if (buf[0] != 0x04) goto error;         /* device id */
+                       if (buf[1] != 0x02) goto error;         /* fab id */
+                       if (buf[2] != 0x11) goto error;         /* month */
+                       if (buf[3] != 0x20) goto error;         /* year msb */
+                       if (buf[4] != 0x00) goto error;         /* year lsb */
+                       break;
+               case NXT2004:
+                       if (buf[0] != 0x05) goto error;         /* device id */
+                       break;
+               default:
+                       goto error;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       pr_err("Unknown/Unsupported NXT chip: %*ph\n", 5, buf);
+       return NULL;
+}
+
+static struct dvb_frontend_ops nxt200x_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name = "Nextwave NXT200X VSB/QAM frontend",
+               .frequency_min =  54000000,
+               .frequency_max = 860000000,
+               .frequency_stepsize = 166666,   /* stepsize is just a guess */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
+       },
+
+       .release = nxt200x_release,
+
+       .init = nxt200x_init,
+       .sleep = nxt200x_sleep,
+
+       .set_frontend = nxt200x_setup_frontend_parameters,
+       .get_tune_settings = nxt200x_get_tune_settings,
+
+       .read_status = nxt200x_read_status,
+       .read_ber = nxt200x_read_ber,
+       .read_signal_strength = nxt200x_read_signal_strength,
+       .read_snr = nxt200x_read_snr,
+       .read_ucblocks = nxt200x_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(nxt200x_attach);
+
diff --git a/drivers/media/dvb-frontends/nxt200x.h b/drivers/media/dvb-frontends/nxt200x.h
new file mode 100644 (file)
index 0000000..f3c8458
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *    Support for NXT2002 and NXT2004 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
+ *    and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+#ifndef NXT200X_H
+#define NXT200X_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+typedef enum nxt_chip_t {
+               NXTUNDEFINED,
+               NXT2002,
+               NXT2004
+}nxt_chip_type;
+
+struct nxt200x_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* need to set device param for start_dma */
+       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+};
+
+#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_NXT200X
+
+#endif /* NXT200X_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c
new file mode 100644 (file)
index 0000000..90ae6c7
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+       NxtWave Communications - NXT6000 demodulator driver
+
+    Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
+    Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "nxt6000_priv.h"
+#include "nxt6000.h"
+
+
+
+struct nxt6000_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct nxt6000_config* config;
+       struct dvb_frontend frontend;
+};
+
+static int debug;
+#define dprintk if (debug) printk
+
+static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
+       int ret;
+
+       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
+               dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
+
+       return (ret != 1) ? -EIO : 0;
+}
+
+static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msgs[] = {
+               {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
+               {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
+       };
+
+       ret = i2c_transfer(state->i2c, msgs, 2);
+
+       if (ret != 2)
+               dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
+
+       return b1[0];
+}
+
+static void nxt6000_reset(struct nxt6000_state* state)
+{
+       u8 val;
+
+       val = nxt6000_readreg(state, OFDM_COR_CTL);
+
+       nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
+       nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
+}
+
+static int nxt6000_set_bandwidth(struct nxt6000_state *state, u32 bandwidth)
+{
+       u16 nominal_rate;
+       int result;
+
+       switch (bandwidth) {
+       case 6000000:
+               nominal_rate = 0x55B7;
+               break;
+
+       case 7000000:
+               nominal_rate = 0x6400;
+               break;
+
+       case 8000000:
+               nominal_rate = 0x7249;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
+               return result;
+
+       return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
+}
+
+static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
+{
+       switch (guard_interval) {
+
+       case GUARD_INTERVAL_1_32:
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
+
+       case GUARD_INTERVAL_1_16:
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
+
+       case GUARD_INTERVAL_AUTO:
+       case GUARD_INTERVAL_1_8:
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
+
+       case GUARD_INTERVAL_1_4:
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
+{
+       switch (inversion) {
+
+       case INVERSION_OFF:
+               return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
+
+       case INVERSION_ON:
+               return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
+
+       default:
+               return -EINVAL;
+
+       }
+}
+
+static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
+{
+       int result;
+
+       switch (transmission_mode) {
+
+       case TRANSMISSION_MODE_2K:
+               if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
+                       return result;
+
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
+
+       case TRANSMISSION_MODE_8K:
+       case TRANSMISSION_MODE_AUTO:
+               if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
+                       return result;
+
+               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
+
+       default:
+               return -EINVAL;
+
+       }
+}
+
+static void nxt6000_setup(struct dvb_frontend* fe)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
+       nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
+       nxt6000_writereg(state, VIT_BERTIME_2, 0x00);  // BER Timer = 0x000200 * 256 = 131072 bits
+       nxt6000_writereg(state, VIT_BERTIME_1, 0x02);  //
+       nxt6000_writereg(state, VIT_BERTIME_0, 0x00);  //
+       nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
+       nxt6000_writereg(state, VIT_COR_CTL, 0x82);   // Enable BER measurement
+       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
+       nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
+       nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
+       nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
+       nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
+       nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
+       nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
+       nxt6000_writereg(state, CAS_FREQ, 0xBB);        /* CHECKME */
+       nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
+       nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
+       nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
+       nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
+       nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
+       nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
+       nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
+
+       if (state->config->clock_inversion)
+               nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
+       else
+               nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
+
+       nxt6000_writereg(state, TS_FORMAT, 0);
+}
+
+static void nxt6000_dump_status(struct nxt6000_state *state)
+{
+       u8 val;
+
+/*
+       printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
+       printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
+       printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
+       printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
+       printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
+       printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
+       printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
+       printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
+       printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
+       printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
+*/
+       printk("NXT6000 status:");
+
+       val = nxt6000_readreg(state, RS_COR_STAT);
+
+       printk(" DATA DESCR LOCK: %d,", val & 0x01);
+       printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
+
+       val = nxt6000_readreg(state, VIT_SYNC_STATUS);
+
+       printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
+
+       switch ((val >> 4) & 0x07) {
+
+       case 0x00:
+               printk(" VITERBI CODERATE: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" VITERBI CODERATE: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" VITERBI CODERATE: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" VITERBI CODERATE: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" VITERBI CODERATE: 7/8,");
+               break;
+
+       default:
+               printk(" VITERBI CODERATE: Reserved,");
+
+       }
+
+       val = nxt6000_readreg(state, OFDM_COR_STAT);
+
+       printk(" CHCTrack: %d,", (val >> 7) & 0x01);
+       printk(" TPSLock: %d,", (val >> 6) & 0x01);
+       printk(" SYRLock: %d,", (val >> 5) & 0x01);
+       printk(" AGCLock: %d,", (val >> 4) & 0x01);
+
+       switch (val & 0x0F) {
+
+       case 0x00:
+               printk(" CoreState: IDLE,");
+               break;
+
+       case 0x02:
+               printk(" CoreState: WAIT_AGC,");
+               break;
+
+       case 0x03:
+               printk(" CoreState: WAIT_SYR,");
+               break;
+
+       case 0x04:
+               printk(" CoreState: WAIT_PPM,");
+               break;
+
+       case 0x01:
+               printk(" CoreState: WAIT_TRL,");
+               break;
+
+       case 0x05:
+               printk(" CoreState: WAIT_TPS,");
+               break;
+
+       case 0x06:
+               printk(" CoreState: MONITOR_TPS,");
+               break;
+
+       default:
+               printk(" CoreState: Reserved,");
+
+       }
+
+       val = nxt6000_readreg(state, OFDM_SYR_STAT);
+
+       printk(" SYRLock: %d,", (val >> 4) & 0x01);
+       printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
+
+       switch ((val >> 4) & 0x03) {
+
+       case 0x00:
+               printk(" SYRGuard: 1/32,");
+               break;
+
+       case 0x01:
+               printk(" SYRGuard: 1/16,");
+               break;
+
+       case 0x02:
+               printk(" SYRGuard: 1/8,");
+               break;
+
+       case 0x03:
+               printk(" SYRGuard: 1/4,");
+               break;
+       }
+
+       val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
+
+       switch ((val >> 4) & 0x07) {
+
+       case 0x00:
+               printk(" TPSLP: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" TPSLP: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" TPSLP: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" TPSLP: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" TPSLP: 7/8,");
+               break;
+
+       default:
+               printk(" TPSLP: Reserved,");
+
+       }
+
+       switch (val & 0x07) {
+
+       case 0x00:
+               printk(" TPSHP: 1/2,");
+               break;
+
+       case 0x01:
+               printk(" TPSHP: 2/3,");
+               break;
+
+       case 0x02:
+               printk(" TPSHP: 3/4,");
+               break;
+
+       case 0x03:
+               printk(" TPSHP: 5/6,");
+               break;
+
+       case 0x04:
+               printk(" TPSHP: 7/8,");
+               break;
+
+       default:
+               printk(" TPSHP: Reserved,");
+
+       }
+
+       val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
+
+       printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
+
+       switch ((val >> 4) & 0x03) {
+
+       case 0x00:
+               printk(" TPSGuard: 1/32,");
+               break;
+
+       case 0x01:
+               printk(" TPSGuard: 1/16,");
+               break;
+
+       case 0x02:
+               printk(" TPSGuard: 1/8,");
+               break;
+
+       case 0x03:
+               printk(" TPSGuard: 1/4,");
+               break;
+
+       }
+
+       /* Strange magic required to gain access to RF_AGC_STATUS */
+       nxt6000_readreg(state, RF_AGC_VAL_1);
+       val = nxt6000_readreg(state, RF_AGC_STATUS);
+       val = nxt6000_readreg(state, RF_AGC_STATUS);
+
+       printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
+       printk("\n");
+}
+
+static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       u8 core_status;
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *status = 0;
+
+       core_status = nxt6000_readreg(state, OFDM_COR_STAT);
+
+       if (core_status & AGCLOCKED)
+               *status |= FE_HAS_SIGNAL;
+
+       if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
+               *status |= FE_HAS_CARRIER;
+
+       if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
+               *status |= FE_HAS_VITERBI;
+
+       if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
+               *status |= FE_HAS_SYNC;
+
+       if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
+               *status |= FE_HAS_LOCK;
+
+       if (debug)
+               nxt6000_dump_status(state);
+
+       return 0;
+}
+
+static int nxt6000_init(struct dvb_frontend* fe)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       nxt6000_reset(state);
+       nxt6000_setup(fe);
+
+       return 0;
+}
+
+static int nxt6000_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct nxt6000_state* state = fe->demodulator_priv;
+       int result;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       result = nxt6000_set_bandwidth(state, p->bandwidth_hz);
+       if (result < 0)
+               return result;
+
+       result = nxt6000_set_guard_interval(state, p->guard_interval);
+       if (result < 0)
+               return result;
+
+       result = nxt6000_set_transmission_mode(state, p->transmission_mode);
+       if (result < 0)
+               return result;
+
+       result = nxt6000_set_inversion(state, p->inversion);
+       if (result < 0)
+               return result;
+
+       msleep(500);
+       return 0;
+}
+
+static void nxt6000_release(struct dvb_frontend* fe)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
+
+       return 0;
+}
+
+static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
+
+       *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
+               nxt6000_readreg( state, VIT_BER_0 );
+
+       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
+
+       return 0;
+}
+
+static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       *signal_strength = (short) (511 -
+               (nxt6000_readreg(state, AGC_GAIN_1) +
+               ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
+
+       return 0;
+}
+
+static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 500;
+       return 0;
+}
+
+static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct nxt6000_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);
+       } else {
+               return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);
+       }
+}
+
+static struct dvb_frontend_ops nxt6000_ops;
+
+struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct nxt6000_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops nxt6000_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "NxtWave NXT6000 DVB-T",
+               .frequency_min = 0,
+               .frequency_max = 863250000,
+               .frequency_stepsize = 62500,
+               /*.frequency_tolerance = *//* FIXME: 12% of SR */
+               .symbol_rate_min = 0,   /* FIXME */
+               .symbol_rate_max = 9360000,     /* FIXME */
+               .symbol_rate_tolerance = 4000,
+               .caps = 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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = nxt6000_release,
+
+       .init = nxt6000_init,
+       .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl,
+
+       .get_tune_settings = nxt6000_fe_get_tune_settings,
+
+       .set_frontend = nxt6000_set_frontend,
+
+       .read_status = nxt6000_read_status,
+       .read_ber = nxt6000_read_ber,
+       .read_signal_strength = nxt6000_read_signal_strength,
+       .read_snr = nxt6000_read_snr,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
+MODULE_AUTHOR("Florian Schirmer");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb-frontends/nxt6000.h b/drivers/media/dvb-frontends/nxt6000.h
new file mode 100644 (file)
index 0000000..878eb38
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+       NxtWave Communications - NXT6000 demodulator driver
+
+    Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
+    Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef NXT6000_H
+#define NXT6000_H
+
+#include <linux/dvb/frontend.h>
+
+struct nxt6000_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* should clock inversion be used? */
+       u8 clock_inversion:1;
+};
+
+#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE))
+extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_NXT6000
+
+#endif // NXT6000_H
diff --git a/drivers/media/dvb-frontends/nxt6000_priv.h b/drivers/media/dvb-frontends/nxt6000_priv.h
new file mode 100644 (file)
index 0000000..0422e58
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Public Include File for DRV6000 users
+ * (ie. NxtWave Communications - NXT6000 demodulator driver)
+ *
+ * Copyright (C) 2001 NxtWave Communications, Inc.
+ *
+ */
+
+/*  Nxt6000 Register Addresses and Bit Masks */
+
+/* Maximum Register Number */
+#define MAXNXT6000REG          (0x9A)
+
+/* 0x1B A_VIT_BER_0  aka 0x3A */
+#define A_VIT_BER_0            (0x1B)
+
+/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
+#define A_VIT_BER_TIMER_0      (0x1D)
+
+/* 0x21 RS_COR_STAT */
+#define RS_COR_STAT            (0x21)
+#define RSCORESTATUS           (0x03)
+
+/* 0x22 RS_COR_INTEN */
+#define RS_COR_INTEN           (0x22)
+
+/* 0x23 RS_COR_INSTAT */
+#define RS_COR_INSTAT          (0x23)
+#define INSTAT_ERROR           (0x04)
+#define LOCK_LOSS_BITS         (0x03)
+
+/* 0x24 RS_COR_SYNC_PARAM */
+#define RS_COR_SYNC_PARAM      (0x24)
+#define SYNC_PARAM             (0x03)
+
+/* 0x25 BER_CTRL */
+#define BER_CTRL               (0x25)
+#define BER_ENABLE             (0x02)
+#define BER_RESET              (0x01)
+
+/* 0x26 BER_PAY */
+#define BER_PAY                (0x26)
+
+/* 0x27 BER_PKT_L */
+#define BER_PKT_L              (0x27)
+#define BER_PKTOVERFLOW        (0x80)
+
+/* 0x30 VIT_COR_CTL */
+#define VIT_COR_CTL            (0x30)
+#define BER_CONTROL            (0x02)
+#define VIT_COR_MASK           (0x82)
+#define VIT_COR_RESYNC         (0x80)
+
+
+/* 0x32 VIT_SYNC_STATUS */
+#define VIT_SYNC_STATUS        (0x32)
+#define VITINSYNC              (0x80)
+
+/* 0x33 VIT_COR_INTEN */
+#define VIT_COR_INTEN          (0x33)
+#define GLOBAL_ENABLE          (0x80)
+
+/* 0x34 VIT_COR_INTSTAT */
+#define VIT_COR_INTSTAT        (0x34)
+#define BER_DONE               (0x08)
+#define BER_OVERFLOW           (0x10)
+
+/* 0x38 VIT_BERTIME_2 */
+#define VIT_BERTIME_2      (0x38)
+
+/* 0x39 VIT_BERTIME_1 */
+#define VIT_BERTIME_1      (0x39)
+
+/* 0x3A VIT_BERTIME_0 */
+#define VIT_BERTIME_0      (0x3a)
+
+                            /* 0x38 OFDM_BERTimer *//* Use the alias registers */
+#define A_VIT_BER_TIMER_0      (0x1D)
+
+                            /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
+#define A_VIT_BER_0            (0x1B)
+
+/* 0x3B VIT_BER_1 */
+#define VIT_BER_1              (0x3b)
+
+/* 0x3C VIT_BER_0 */
+#define VIT_BER_0              (0x3c)
+
+/* 0x40 OFDM_COR_CTL */
+#define OFDM_COR_CTL           (0x40)
+#define COREACT                (0x20)
+#define HOLDSM                 (0x10)
+#define WAIT_AGC               (0x02)
+#define WAIT_SYR               (0x03)
+
+/* 0x41 OFDM_COR_STAT */
+#define OFDM_COR_STAT          (0x41)
+#define COR_STATUS             (0x0F)
+#define MONITOR_TPS            (0x06)
+#define TPSLOCKED              (0x40)
+#define AGCLOCKED              (0x10)
+
+/* 0x42 OFDM_COR_INTEN */
+#define OFDM_COR_INTEN         (0x42)
+#define TPSRCVBAD              (0x04)
+#define TPSRCVCHANGED         (0x02)
+#define TPSRCVUPDATE           (0x01)
+
+/* 0x43 OFDM_COR_INSTAT */
+#define OFDM_COR_INSTAT        (0x43)
+
+/* 0x44 OFDM_COR_MODEGUARD */
+#define OFDM_COR_MODEGUARD     (0x44)
+#define FORCEMODE              (0x08)
+#define FORCEMODE8K                       (0x04)
+
+/* 0x45 OFDM_AGC_CTL */
+#define OFDM_AGC_CTL           (0x45)
+#define INITIAL_AGC_BW            (0x08)
+#define AGCNEG                 (0x02)
+#define AGCLAST                                   (0x10)
+
+/* 0x48 OFDM_AGC_TARGET */
+#define OFDM_AGC_TARGET                   (0x48)
+#define OFDM_AGC_TARGET_DEFAULT (0x28)
+#define OFDM_AGC_TARGET_IMPULSE (0x38)
+
+/* 0x49 OFDM_AGC_GAIN_1 */
+#define OFDM_AGC_GAIN_1        (0x49)
+
+/* 0x4B OFDM_ITB_CTL */
+#define OFDM_ITB_CTL           (0x4B)
+#define ITBINV                 (0x01)
+
+/* 0x49 AGC_GAIN_1 */
+#define AGC_GAIN_1             (0x49)
+
+/* 0x4A AGC_GAIN_2 */
+#define AGC_GAIN_2             (0x4A)
+
+/* 0x4C OFDM_ITB_FREQ_1 */
+#define OFDM_ITB_FREQ_1        (0x4C)
+
+/* 0x4D OFDM_ITB_FREQ_2 */
+#define OFDM_ITB_FREQ_2        (0x4D)
+
+/* 0x4E  OFDM_CAS_CTL */
+#define OFDM_CAS_CTL           (0x4E)
+#define ACSDIS                 (0x40)
+#define CCSEN                  (0x80)
+
+/* 0x4F CAS_FREQ */
+#define CAS_FREQ               (0x4F)
+
+/* 0x51 OFDM_SYR_CTL */
+#define OFDM_SYR_CTL           (0x51)
+#define SIXTH_ENABLE           (0x80)
+#define SYR_TRACKING_DISABLE   (0x01)
+
+/* 0x52 OFDM_SYR_STAT */
+#define OFDM_SYR_STAT             (0x52)
+#define GI14_2K_SYR_LOCK          (0x13)
+#define GI14_8K_SYR_LOCK          (0x17)
+#define GI14_SYR_LOCK             (0x10)
+
+/* 0x55 OFDM_SYR_OFFSET_1 */
+#define OFDM_SYR_OFFSET_1      (0x55)
+
+/* 0x56 OFDM_SYR_OFFSET_2 */
+#define OFDM_SYR_OFFSET_2      (0x56)
+
+/* 0x58 OFDM_SCR_CTL */
+#define OFDM_SCR_CTL           (0x58)
+#define SYR_ADJ_DECAY_MASK     (0x70)
+#define SYR_ADJ_DECAY          (0x30)
+
+/* 0x59 OFDM_PPM_CTL_1 */
+#define OFDM_PPM_CTL_1         (0x59)
+#define PPMMAX_MASK            (0x30)
+#define PPM256                            (0x30)
+
+/* 0x5B OFDM_TRL_NOMINALRATE_1 */
+#define OFDM_TRL_NOMINALRATE_1 (0x5B)
+
+/* 0x5C OFDM_TRL_NOMINALRATE_2 */
+#define OFDM_TRL_NOMINALRATE_2 (0x5C)
+
+/* 0x5D OFDM_TRL_TIME_1 */
+#define OFDM_TRL_TIME_1        (0x5D)
+
+/* 0x60 OFDM_CRL_FREQ_1 */
+#define OFDM_CRL_FREQ_1        (0x60)
+
+/* 0x63 OFDM_CHC_CTL_1 */
+#define OFDM_CHC_CTL_1         (0x63)
+#define MANMEAN1               (0xF0);
+#define CHCFIR                 (0x01)
+
+/* 0x64 OFDM_CHC_SNR */
+#define OFDM_CHC_SNR           (0x64)
+
+/* 0x65 OFDM_BDI_CTL */
+#define OFDM_BDI_CTL           (0x65)
+#define LP_SELECT              (0x02)
+
+/* 0x67 OFDM_TPS_RCVD_1 */
+#define OFDM_TPS_RCVD_1        (0x67)
+#define TPSFRAME               (0x03)
+
+/* 0x68 OFDM_TPS_RCVD_2 */
+#define OFDM_TPS_RCVD_2        (0x68)
+
+/* 0x69 OFDM_TPS_RCVD_3 */
+#define OFDM_TPS_RCVD_3        (0x69)
+
+/* 0x6A OFDM_TPS_RCVD_4 */
+#define OFDM_TPS_RCVD_4        (0x6A)
+
+/* 0x6B OFDM_TPS_RESERVED_1 */
+#define OFDM_TPS_RESERVED_1    (0x6B)
+
+/* 0x6C OFDM_TPS_RESERVED_2 */
+#define OFDM_TPS_RESERVED_2    (0x6C)
+
+/* 0x73 OFDM_MSC_REV */
+#define OFDM_MSC_REV           (0x73)
+
+/* 0x76 OFDM_SNR_CARRIER_2 */
+#define OFDM_SNR_CARRIER_2     (0x76)
+#define MEAN_MASK              (0x80)
+#define MEANBIT                (0x80)
+
+/* 0x80 ANALOG_CONTROL_0 */
+#define ANALOG_CONTROL_0       (0x80)
+#define POWER_DOWN_ADC         (0x40)
+
+/* 0x81 ENABLE_TUNER_IIC */
+#define ENABLE_TUNER_IIC       (0x81)
+#define ENABLE_TUNER_BIT       (0x01)
+
+/* 0x82 EN_DMD_RACQ */
+#define EN_DMD_RACQ            (0x82)
+#define EN_DMD_RACQ_REG_VAL    (0x81)
+#define EN_DMD_RACQ_REG_VAL_14 (0x01)
+
+/* 0x84 SNR_COMMAND */
+#define SNR_COMMAND            (0x84)
+#define SNRStat                (0x80)
+
+/* 0x85 SNRCARRIERNUMBER_LSB */
+#define SNRCARRIERNUMBER_LSB   (0x85)
+
+/* 0x87 SNRMINTHRESHOLD_LSB */
+#define SNRMINTHRESHOLD_LSB    (0x87)
+
+/* 0x89 SNR_PER_CARRIER_LSB */
+#define SNR_PER_CARRIER_LSB    (0x89)
+
+/* 0x8B SNRBELOWTHRESHOLD_LSB */
+#define SNRBELOWTHRESHOLD_LSB  (0x8B)
+
+/* 0x91 RF_AGC_VAL_1 */
+#define RF_AGC_VAL_1           (0x91)
+
+/* 0x92 RF_AGC_STATUS */
+#define RF_AGC_STATUS          (0x92)
+
+/* 0x98 DIAG_CONFIG */
+#define DIAG_CONFIG            (0x98)
+#define DIAG_MASK              (0x70)
+#define TB_SET                 (0x10)
+#define TRAN_SELECT            (0x07)
+#define SERIAL_SELECT          (0x01)
+
+/* 0x99 SUB_DIAG_MODE_SEL */
+#define SUB_DIAG_MODE_SEL      (0x99)
+#define CLKINVERSION           (0x01)
+
+/* 0x9A TS_FORMAT */
+#define TS_FORMAT              (0x9A)
+#define ERROR_SENSE            (0x08)
+#define VALID_SENSE            (0x04)
+#define SYNC_SENSE             (0x02)
+#define GATED_CLOCK            (0x01)
+
+#define NXT6000ASICDEVICE      (0x0b)
diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
new file mode 100644 (file)
index 0000000..5ef9218
--- /dev/null
@@ -0,0 +1,631 @@
+/*
+ *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
+ *
+ *
+ *    Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org>
+ *
+ *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ *    Based on code from Jack Kelliher (kelliher@xmission.com)
+ *                           Copyright (C) 2002 & pcHDTV, inc.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+/*
+ * This driver needs two external firmware files. Please copy
+ * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
+ * /usr/lib/hotplug/firmware/ or /lib/firmware/
+ * (depending on configuration of firmware hotplug).
+ */
+#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
+#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+
+#include "dvb_math.h"
+#include "dvb_frontend.h"
+#include "or51132.h"
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "or51132: " args); \
+       } while (0)
+
+
+struct or51132_state
+{
+       struct i2c_adapter* i2c;
+
+       /* Configuration settings */
+       const struct or51132_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* Demodulator private data */
+       fe_modulation_t current_modulation;
+       u32 snr; /* Result of last SNR calculation */
+
+       /* Tuner private data */
+       u32 current_frequency;
+};
+
+
+/* Write buffer to demod */
+static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
+{
+       int err;
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+                              .flags = 0, .buf = (u8*)buf, .len = len };
+
+       /* msleep(20); */ /* doesn't appear to be necessary */
+       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",
+                      msg.addr, msg.len, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);
+   Less code and more efficient that loading a buffer on the stack with
+   the bytes to send and then calling or51132_writebuf() on that. */
+#define or51132_writebytes(state, data...)  \
+       ({ static const u8 _data[] = {data}; \
+       or51132_writebuf(state, _data, sizeof(_data)); })
+
+/* Read data from demod into buffer.  Returns 0 on success. */
+static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len)
+{
+       int err;
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+                              .flags = I2C_M_RD, .buf = buf, .len = len };
+
+       /* msleep(20); */ /* doesn't appear to be necessary */
+       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",
+                      msg.addr, msg.len, err);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* Reads a 16-bit demod register.  Returns <0 on error. */
+static int or51132_readreg(struct or51132_state *state, u8 reg)
+{
+       u8 buf[2] = { 0x04, reg };
+       struct i2c_msg msg[2] = {
+               {.addr = state->config->demod_address, .flags = 0,
+                .buf = buf, .len = 2 },
+               {.addr = state->config->demod_address, .flags = I2C_M_RD,
+                .buf = buf, .len = 2 }};
+       int err;
+
+       if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {
+               printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",
+                      reg, err);
+               return -EREMOTEIO;
+       }
+       return buf[0] | (buf[1] << 8);
+}
+
+static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+{
+       struct or51132_state* state = fe->demodulator_priv;
+       static const u8 run_buf[] = {0x7F,0x01};
+       u8 rec_buf[8];
+       u32 firmwareAsize, firmwareBsize;
+       int i,ret;
+
+       dprintk("Firmware is %Zd bytes\n",fw->size);
+
+       /* Get size of firmware A and B */
+       firmwareAsize = le32_to_cpu(*((__le32*)fw->data));
+       dprintk("FirmwareA is %i bytes\n",firmwareAsize);
+       firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));
+       dprintk("FirmwareB is %i bytes\n",firmwareBsize);
+
+       /* Upload firmware */
+       if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
+               printk(KERN_WARNING "or51132: load_firmware error 1\n");
+               return ret;
+       }
+       if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
+                                   firmwareBsize))) {
+               printk(KERN_WARNING "or51132: load_firmware error 2\n");
+               return ret;
+       }
+
+       if ((ret = or51132_writebuf(state, run_buf, 2))) {
+               printk(KERN_WARNING "or51132: load_firmware error 3\n");
+               return ret;
+       }
+       if ((ret = or51132_writebuf(state, run_buf, 2))) {
+               printk(KERN_WARNING "or51132: load_firmware error 4\n");
+               return ret;
+       }
+
+       /* 50ms for operation to begin */
+       msleep(50);
+
+       /* Read back ucode version to besure we loaded correctly and are really up and running */
+       /* Get uCode version */
+       if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {
+               printk(KERN_WARNING "or51132: load_firmware error a\n");
+               return ret;
+       }
+       if ((ret = or51132_writebytes(state, 0x04, 0x17))) {
+               printk(KERN_WARNING "or51132: load_firmware error b\n");
+               return ret;
+       }
+       if ((ret = or51132_writebytes(state, 0x00, 0x00))) {
+               printk(KERN_WARNING "or51132: load_firmware error c\n");
+               return ret;
+       }
+       for (i=0;i<4;i++) {
+               /* Once upon a time, this command might have had something
+                  to do with getting the firmware version, but it's
+                  not used anymore:
+                  {0x04,0x00,0x30,0x00,i+1} */
+               /* Read 8 bytes, two bytes at a time */
+               if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {
+                       printk(KERN_WARNING
+                              "or51132: load_firmware error d - %d\n",i);
+                       return ret;
+               }
+       }
+
+       printk(KERN_WARNING
+              "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
+              rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
+              rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
+              rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
+              rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
+
+       if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {
+               printk(KERN_WARNING "or51132: load_firmware error e\n");
+               return ret;
+       }
+       return 0;
+};
+
+static int or51132_init(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       *ber = 0;
+       return 0;
+}
+
+static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+static int or51132_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int or51132_setmode(struct dvb_frontend* fe)
+{
+       struct or51132_state* state = fe->demodulator_priv;
+       u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};
+       u8 cmd_buf2[3] = {0x1c, 0x00, 0 };
+
+       dprintk("setmode %d\n",(int)state->current_modulation);
+
+       switch (state->current_modulation) {
+       case VSB_8:
+               /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */
+               cmd_buf1[2] = 0x50;
+               /* REC MODE inv IF spectrum, Normal */
+               cmd_buf2[1] = 0x03;
+               /* Channel MODE ATSC/VSB8 */
+               cmd_buf2[2] = 0x06;
+               break;
+       /* All QAM modes are:
+          Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high
+          REC MODE Normal Carrier Lock */
+       case QAM_AUTO:
+               /* Channel MODE Auto QAM64/256 */
+               cmd_buf2[2] = 0x4f;
+               break;
+       case QAM_256:
+               /* Channel MODE QAM256 */
+               cmd_buf2[2] = 0x45;
+               break;
+       case QAM_64:
+               /* Channel MODE QAM64 */
+               cmd_buf2[2] = 0x43;
+               break;
+       default:
+               printk(KERN_WARNING
+                      "or51132: setmode: Modulation set to unsupported value (%d)\n",
+                      state->current_modulation);
+               return -EINVAL;
+       }
+
+       /* Set Receiver 1 register */
+       if (or51132_writebuf(state, cmd_buf1, 3)) {
+               printk(KERN_WARNING "or51132: set_mode error 1\n");
+               return -EREMOTEIO;
+       }
+       dprintk("set #1 to %02x\n", cmd_buf1[2]);
+
+       /* Set operation mode in Receiver 6 register */
+       if (or51132_writebuf(state, cmd_buf2, 3)) {
+               printk(KERN_WARNING "or51132: set_mode error 2\n");
+               return -EREMOTEIO;
+       }
+       dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);
+
+       return 0;
+}
+
+/* Some modulations use the same firmware.  This classifies modulations
+   by the firmware they use. */
+#define MOD_FWCLASS_UNKNOWN    0
+#define MOD_FWCLASS_VSB                1
+#define MOD_FWCLASS_QAM                2
+static int modulation_fw_class(fe_modulation_t modulation)
+{
+       switch(modulation) {
+       case VSB_8:
+               return MOD_FWCLASS_VSB;
+       case QAM_AUTO:
+       case QAM_64:
+       case QAM_256:
+               return MOD_FWCLASS_QAM;
+       default:
+               return MOD_FWCLASS_UNKNOWN;
+       }
+}
+
+static int or51132_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       int ret;
+       struct or51132_state* state = fe->demodulator_priv;
+       const struct firmware *fw;
+       const char *fwname;
+       int clock_mode;
+
+       /* Upload new firmware only if we need a different one */
+       if (modulation_fw_class(state->current_modulation) !=
+           modulation_fw_class(p->modulation)) {
+               switch (modulation_fw_class(p->modulation)) {
+               case MOD_FWCLASS_VSB:
+                       dprintk("set_parameters VSB MODE\n");
+                       fwname = OR51132_VSB_FIRMWARE;
+
+                       /* Set non-punctured clock for VSB */
+                       clock_mode = 0;
+                       break;
+               case MOD_FWCLASS_QAM:
+                       dprintk("set_parameters QAM MODE\n");
+                       fwname = OR51132_QAM_FIRMWARE;
+
+                       /* Set punctured clock for QAM */
+                       clock_mode = 1;
+                       break;
+               default:
+                       printk("or51132: Modulation type(%d) UNSUPPORTED\n",
+                              p->modulation);
+                       return -1;
+               }
+               printk("or51132: Waiting for firmware upload(%s)...\n",
+                      fwname);
+               ret = request_firmware(&fw, fwname, state->i2c->dev.parent);
+               if (ret) {
+                       printk(KERN_WARNING "or51132: No firmware up"
+                              "loaded(timeout or file not found?)\n");
+                       return ret;
+               }
+               ret = or51132_load_firmware(fe, fw);
+               release_firmware(fw);
+               if (ret) {
+                       printk(KERN_WARNING "or51132: Writing firmware to "
+                              "device failed!\n");
+                       return ret;
+               }
+               printk("or51132: Firmware upload complete.\n");
+               state->config->set_ts_params(fe, clock_mode);
+       }
+       /* Change only if we are actually changing the modulation */
+       if (state->current_modulation != p->modulation) {
+               state->current_modulation = p->modulation;
+               or51132_setmode(fe);
+       }
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* Set to current mode */
+       or51132_setmode(fe);
+
+       /* Update current frequency */
+       state->current_frequency = p->frequency;
+       return 0;
+}
+
+static int or51132_get_parameters(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct or51132_state* state = fe->demodulator_priv;
+       int status;
+       int retry = 1;
+
+start:
+       /* Receiver Status */
+       if ((status = or51132_readreg(state, 0x00)) < 0) {
+               printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n");
+               return -EREMOTEIO;
+       }
+       switch(status&0xff) {
+       case 0x06:
+               p->modulation = VSB_8;
+               break;
+       case 0x43:
+               p->modulation = QAM_64;
+               break;
+       case 0x45:
+               p->modulation = QAM_256;
+               break;
+       default:
+               if (retry--)
+                       goto start;
+               printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
+                      status&0xff);
+               return -EREMOTEIO;
+       }
+
+       /* FIXME: Read frequency from frontend, take AFC into account */
+       p->frequency = state->current_frequency;
+
+       /* FIXME: How to read inversion setting? Receiver 6 register? */
+       p->inversion = INVERSION_AUTO;
+
+       return 0;
+}
+
+static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct or51132_state* state = fe->demodulator_priv;
+       int reg;
+
+       /* Receiver Status */
+       if ((reg = or51132_readreg(state, 0x00)) < 0) {
+               printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg);
+               *status = 0;
+               return -EREMOTEIO;
+       }
+       dprintk("%s: read_status %04x\n", __func__, reg);
+
+       if (reg & 0x0100) /* Receiver Lock */
+               *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
+                         FE_HAS_SYNC|FE_HAS_LOCK;
+       else
+               *status = 0;
+       return 0;
+}
+
+/* Calculate SNR estimation (scaled by 2^24)
+
+   8-VSB SNR and QAM equations from Oren datasheets
+
+   For 8-VSB:
+     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K
+
+     Where K = 0 if NTSC rejection filter is OFF; and
+          K = 3 if NTSC rejection filter is ON
+
+   For QAM64:
+     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 )
+
+   For QAM256:
+     SNR[dB] = 10 * log10(907832426.314266  / MSE^2 )
+
+   We re-write the snr equation as:
+     SNR * 2^24 = 10*(c - 2*intlog10(MSE))
+   Where for QAM256, c = log10(907832426.314266) * 2^24
+   and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */
+
+static u32 calculate_snr(u32 mse, u32 c)
+{
+       if (mse == 0) /* No signal */
+               return 0;
+
+       mse = 2*intlog10(mse);
+       if (mse > c) {
+               /* Negative SNR, which is possible, but realisticly the
+               demod will lose lock before the signal gets this bad.  The
+               API only allows for unsigned values, so just return 0 */
+               return 0;
+       }
+       return 10*(c - mse);
+}
+
+static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct or51132_state* state = fe->demodulator_priv;
+       int noise, reg;
+       u32 c, usK = 0;
+       int retry = 1;
+
+start:
+       /* SNR after Equalizer */
+       noise = or51132_readreg(state, 0x02);
+       if (noise < 0) {
+               printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n");
+               return -EREMOTEIO;
+       }
+       dprintk("read_snr noise (%d)\n", noise);
+
+       /* Read status, contains modulation type for QAM_AUTO and
+          NTSC filter for VSB */
+       reg = or51132_readreg(state, 0x00);
+       if (reg < 0) {
+               printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n");
+               return -EREMOTEIO;
+       }
+
+       switch (reg&0xff) {
+       case 0x06:
+               if (reg & 0x1000) usK = 3 << 24;
+               /* Fall through to QAM64 case */
+       case 0x43:
+               c = 150204167;
+               break;
+       case 0x45:
+               c = 150290396;
+               break;
+       default:
+               printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff);
+               if (retry--) goto start;
+               return -EREMOTEIO;
+       }
+       dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__,
+               reg&0xff, reg&0x1000?"n":"ff");
+
+       /* Calculate SNR using noise, c, and NTSC rejection correction */
+       state->snr = calculate_snr(noise, c) - usK;
+       *snr = (state->snr) >> 16;
+
+       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
+               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
+
+       return 0;
+}
+
+static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       /* Calculate Strength from SNR up to 35dB */
+       /* Even though the SNR can go higher than 35dB, there is some comfort */
+       /* factor in having a range of strong signals that can show at 100%   */
+       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
+       u16 snr;
+       int ret;
+
+       ret = fe->ops.read_snr(fe, &snr);
+       if (ret != 0)
+               return ret;
+       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+       /* scale the range 0 - 35*2^24 into 0 - 65535 */
+       if (state->snr >= 8960 * 0x10000)
+               *strength = 0xffff;
+       else
+               *strength = state->snr / 8960;
+
+       return 0;
+}
+
+static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 500;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static void or51132_release(struct dvb_frontend* fe)
+{
+       struct or51132_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops or51132_ops;
+
+struct dvb_frontend* or51132_attach(const struct or51132_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct or51132_state* state = NULL;
+
+       /* Allocate memory for the internal state */
+       state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       /* Setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->current_frequency = -1;
+       state->current_modulation = -1;
+
+       /* Create dvb_frontend */
+       memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops or51132_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name                   = "Oren OR51132 VSB/QAM Frontend",
+               .frequency_min          = 44000000,
+               .frequency_max          = 958000000,
+               .frequency_stepsize     = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
+                       FE_CAN_8VSB
+       },
+
+       .release = or51132_release,
+
+       .init = or51132_init,
+       .sleep = or51132_sleep,
+
+       .set_frontend = or51132_set_parameters,
+       .get_frontend = or51132_get_parameters,
+       .get_tune_settings = or51132_get_tune_settings,
+
+       .read_status = or51132_read_status,
+       .read_ber = or51132_read_ber,
+       .read_signal_strength = or51132_read_signal_strength,
+       .read_snr = or51132_read_snr,
+       .read_ucblocks = or51132_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
+MODULE_AUTHOR("Kirk Lapray");
+MODULE_AUTHOR("Trent Piepho");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(or51132_attach);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/or51132.h b/drivers/media/dvb-frontends/or51132.h
new file mode 100644 (file)
index 0000000..1b8e04d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
+ *
+ *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+#ifndef OR51132_H
+#define OR51132_H
+
+#include <linux/firmware.h>
+#include <linux/dvb/frontend.h>
+
+struct or51132_config
+{
+       /* The demodulator's i2c address */
+       u8 demod_address;
+
+       /* Need to set device param for start_dma */
+       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+};
+
+#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE))
+extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_OR51132
+
+#endif // OR51132_H
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
new file mode 100644 (file)
index 0000000..c625b57
--- /dev/null
@@ -0,0 +1,581 @@
+/*
+ *    Support for OR51211 (pcHDTV HD-2000) - VSB
+ *
+ *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ *    Based on code from Jack Kelliher (kelliher@xmission.com)
+ *                           Copyright (C) 2002 & pcHDTV, inc.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+/*
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
+ */
+#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+
+#include "dvb_math.h"
+#include "dvb_frontend.h"
+#include "or51211.h"
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "or51211: " args); \
+       } while (0)
+
+static u8 run_buf[] = {0x7f,0x01};
+static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
+
+struct or51211_state {
+
+       struct i2c_adapter* i2c;
+
+       /* Configuration settings */
+       const struct or51211_config* config;
+
+       struct dvb_frontend frontend;
+       struct bt878* bt;
+
+       /* Demodulator private data */
+       u8 initialized:1;
+       u32 snr; /* Result of last SNR claculation */
+
+       /* Tuner private data */
+       u32 current_frequency;
+};
+
+static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
+                          int len)
+{
+       int err;
+       struct i2c_msg msg;
+       msg.addr        = reg;
+       msg.flags       = 0;
+       msg.len         = len;
+       msg.buf         = (u8 *)buf;
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "or51211: i2c_writebytes error "
+                      "(addr %02x, err == %i)\n", reg, err);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len)
+{
+       int err;
+       struct i2c_msg msg;
+       msg.addr        = reg;
+       msg.flags       = I2C_M_RD;
+       msg.len         = len;
+       msg.buf         = buf;
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "or51211: i2c_readbytes error "
+                      "(addr %02x, err == %i)\n", reg, err);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int or51211_load_firmware (struct dvb_frontend* fe,
+                                 const struct firmware *fw)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       u8 tudata[585];
+       int i;
+
+       dprintk("Firmware is %zd bytes\n",fw->size);
+
+       /* Get eprom data */
+       tudata[0] = 17;
+       if (i2c_writebytes(state,0x50,tudata,1)) {
+               printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
+               return -1;
+       }
+       if (i2c_readbytes(state,0x50,&tudata[145],192)) {
+               printk(KERN_WARNING "or51211: load_firmware error eprom\n");
+               return -1;
+       }
+
+       /* Create firmware buffer */
+       for (i = 0; i < 145; i++)
+               tudata[i] = fw->data[i];
+
+       for (i = 0; i < 248; i++)
+               tudata[i+337] = fw->data[145+i];
+
+       state->config->reset(fe);
+
+       if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
+               printk(KERN_WARNING "or51211: load_firmware error 1\n");
+               return -1;
+       }
+       msleep(1);
+
+       if (i2c_writebytes(state,state->config->demod_address,
+                          &fw->data[393],8125)) {
+               printk(KERN_WARNING "or51211: load_firmware error 2\n");
+               return -1;
+       }
+       msleep(1);
+
+       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+               printk(KERN_WARNING "or51211: load_firmware error 3\n");
+               return -1;
+       }
+
+       /* Wait at least 5 msec */
+       msleep(10);
+       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+               printk(KERN_WARNING "or51211: load_firmware error 4\n");
+               return -1;
+       }
+       msleep(10);
+
+       printk("or51211: Done.\n");
+       return 0;
+};
+
+static int or51211_setmode(struct dvb_frontend* fe, int mode)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       u8 rec_buf[14];
+
+       state->config->setmode(fe, mode);
+
+       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+               printk(KERN_WARNING "or51211: setmode error 1\n");
+               return -1;
+       }
+
+       /* Wait at least 5 msec */
+       msleep(10);
+       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+               printk(KERN_WARNING "or51211: setmode error 2\n");
+               return -1;
+       }
+
+       msleep(10);
+
+       /* Set operation mode in Receiver 1 register;
+        * type 1:
+        * data 0x50h  Automatic sets receiver channel conditions
+        *             Automatic NTSC rejection filter
+        *             Enable  MPEG serial data output
+        *             MPEG2tr
+        *             High tuner phase noise
+        *             normal +/-150kHz Carrier acquisition range
+        */
+       if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
+               printk(KERN_WARNING "or51211: setmode error 3\n");
+               return -1;
+       }
+
+       rec_buf[0] = 0x04;
+       rec_buf[1] = 0x00;
+       rec_buf[2] = 0x03;
+       rec_buf[3] = 0x00;
+       msleep(20);
+       if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
+               printk(KERN_WARNING "or51211: setmode error 5\n");
+       }
+       msleep(3);
+       if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
+               printk(KERN_WARNING "or51211: setmode error 6");
+               return -1;
+       }
+       dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
+
+       return 0;
+}
+
+static int or51211_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct or51211_state* state = fe->demodulator_priv;
+
+       /* Change only if we are actually changing the channel */
+       if (state->current_frequency != p->frequency) {
+               if (fe->ops.tuner_ops.set_params) {
+                       fe->ops.tuner_ops.set_params(fe);
+                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+
+               /* Set to ATSC mode */
+               or51211_setmode(fe,0);
+
+               /* Update current frequency */
+               state->current_frequency = p->frequency;
+       }
+       return 0;
+}
+
+static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       unsigned char rec_buf[2];
+       unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
+       *status = 0;
+
+       /* Receiver Status */
+       if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
+               printk(KERN_WARNING "or51132: read_status write error\n");
+               return -1;
+       }
+       msleep(3);
+       if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
+               printk(KERN_WARNING "or51132: read_status read error\n");
+               return -1;
+       }
+       dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
+
+       if (rec_buf[0] &  0x01) { /* Receiver Lock */
+               *status |= FE_HAS_SIGNAL;
+               *status |= FE_HAS_CARRIER;
+               *status |= FE_HAS_VITERBI;
+               *status |= FE_HAS_SYNC;
+               *status |= FE_HAS_LOCK;
+       }
+       return 0;
+}
+
+/* Calculate SNR estimation (scaled by 2^24)
+
+   8-VSB SNR equation from Oren datasheets
+
+   For 8-VSB:
+     SNR[dB] = 10 * log10(219037.9454 / MSE^2 )
+
+   We re-write the snr equation as:
+     SNR * 2^24 = 10*(c - 2*intlog10(MSE))
+   Where for 8-VSB, c = log10(219037.9454) * 2^24 */
+
+static u32 calculate_snr(u32 mse, u32 c)
+{
+       if (mse == 0) /* No signal */
+               return 0;
+
+       mse = 2*intlog10(mse);
+       if (mse > c) {
+               /* Negative SNR, which is possible, but realisticly the
+               demod will lose lock before the signal gets this bad.  The
+               API only allows for unsigned values, so just return 0 */
+               return 0;
+       }
+       return 10*(c - mse);
+}
+
+static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       u8 rec_buf[2];
+       u8 snd_buf[3];
+
+       /* SNR after Equalizer */
+       snd_buf[0] = 0x04;
+       snd_buf[1] = 0x00;
+       snd_buf[2] = 0x04;
+
+       if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
+               printk(KERN_WARNING "%s: error writing snr reg\n",
+                      __func__);
+               return -1;
+       }
+       if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
+               printk(KERN_WARNING "%s: read_status read error\n",
+                      __func__);
+               return -1;
+       }
+
+       state->snr = calculate_snr(rec_buf[0], 89599047);
+       *snr = (state->snr) >> 16;
+
+       dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0],
+               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
+
+       return 0;
+}
+
+static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       /* Calculate Strength from SNR up to 35dB */
+       /* Even though the SNR can go higher than 35dB, there is some comfort */
+       /* factor in having a range of strong signals that can show at 100%   */
+       struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv;
+       u16 snr;
+       int ret;
+
+       ret = fe->ops.read_snr(fe, &snr);
+       if (ret != 0)
+               return ret;
+       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+       /* scale the range 0 - 35*2^24 into 0 - 65535 */
+       if (state->snr >= 8960 * 0x10000)
+               *strength = 0xffff;
+       else
+               *strength = state->snr / 8960;
+
+       return 0;
+}
+
+static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       *ber = -ENOSYS;
+       return 0;
+}
+
+static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       *ucblocks = -ENOSYS;
+       return 0;
+}
+
+static int or51211_sleep(struct dvb_frontend* fe)
+{
+       return 0;
+}
+
+static int or51211_init(struct dvb_frontend* fe)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       const struct or51211_config* config = state->config;
+       const struct firmware* fw;
+       unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
+       unsigned char rec_buf[14];
+       int ret,i;
+
+       if (!state->initialized) {
+               /* Request the firmware, this will block until it uploads */
+               printk(KERN_INFO "or51211: Waiting for firmware upload "
+                      "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
+               ret = config->request_firmware(fe, &fw,
+                                              OR51211_DEFAULT_FIRMWARE);
+               printk(KERN_INFO "or51211:Got Hotplug firmware\n");
+               if (ret) {
+                       printk(KERN_WARNING "or51211: No firmware uploaded "
+                              "(timeout or file not found?)\n");
+                       return ret;
+               }
+
+               ret = or51211_load_firmware(fe, fw);
+               release_firmware(fw);
+               if (ret) {
+                       printk(KERN_WARNING "or51211: Writing firmware to "
+                              "device failed!\n");
+                       return ret;
+               }
+               printk(KERN_INFO "or51211: Firmware upload complete.\n");
+
+               /* Set operation mode in Receiver 1 register;
+                * type 1:
+                * data 0x50h  Automatic sets receiver channel conditions
+                *             Automatic NTSC rejection filter
+                *             Enable  MPEG serial data output
+                *             MPEG2tr
+                *             High tuner phase noise
+                *             normal +/-150kHz Carrier acquisition range
+                */
+               if (i2c_writebytes(state,state->config->demod_address,
+                                  cmd_buf,3)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error 5\n");
+                       return -1;
+               }
+
+               /* Read back ucode version to besure we loaded correctly */
+               /* and are really up and running */
+               rec_buf[0] = 0x04;
+               rec_buf[1] = 0x00;
+               rec_buf[2] = 0x03;
+               rec_buf[3] = 0x00;
+               msleep(30);
+               if (i2c_writebytes(state,state->config->demod_address,
+                                  rec_buf,3)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error A\n");
+                       return -1;
+               }
+               msleep(3);
+               if (i2c_readbytes(state,state->config->demod_address,
+                                 &rec_buf[10],2)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error B\n");
+                       return -1;
+               }
+
+               rec_buf[0] = 0x04;
+               rec_buf[1] = 0x00;
+               rec_buf[2] = 0x01;
+               rec_buf[3] = 0x00;
+               msleep(20);
+               if (i2c_writebytes(state,state->config->demod_address,
+                                  rec_buf,3)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error C\n");
+                       return -1;
+               }
+               msleep(3);
+               if (i2c_readbytes(state,state->config->demod_address,
+                                 &rec_buf[12],2)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error D\n");
+                       return -1;
+               }
+
+               for (i = 0; i < 8; i++)
+                       rec_buf[i]=0xed;
+
+               for (i = 0; i < 5; i++) {
+                       msleep(30);
+                       get_ver_buf[4] = i+1;
+                       if (i2c_writebytes(state,state->config->demod_address,
+                                          get_ver_buf,5)) {
+                               printk(KERN_WARNING "or51211:Load DVR Error 6"
+                                      " - %d\n",i);
+                               return -1;
+                       }
+                       msleep(3);
+
+                       if (i2c_readbytes(state,state->config->demod_address,
+                                         &rec_buf[i*2],2)) {
+                               printk(KERN_WARNING "or51211:Load DVR Error 7"
+                                      " - %d\n",i);
+                               return -1;
+                       }
+                       /* If we didn't receive the right index, try again */
+                       if ((int)rec_buf[i*2+1]!=i+1){
+                         i--;
+                       }
+               }
+               dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
+                       rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
+                       rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
+                       rec_buf[8], rec_buf[9]);
+
+               printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
+                      " Status %02x\n",
+                      rec_buf[2], rec_buf[4],rec_buf[6],
+                      rec_buf[12],rec_buf[10]);
+
+               rec_buf[0] = 0x04;
+               rec_buf[1] = 0x00;
+               rec_buf[2] = 0x03;
+               rec_buf[3] = 0x00;
+               msleep(20);
+               if (i2c_writebytes(state,state->config->demod_address,
+                                  rec_buf,3)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error 8\n");
+                       return -1;
+               }
+               msleep(20);
+               if (i2c_readbytes(state,state->config->demod_address,
+                                 &rec_buf[8],2)) {
+                       printk(KERN_WARNING "or51211: Load DVR Error 9\n");
+                       return -1;
+               }
+               state->initialized = 1;
+       }
+
+       return 0;
+}
+
+static int or51211_get_tune_settings(struct dvb_frontend* fe,
+                                    struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 500;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void or51211_release(struct dvb_frontend* fe)
+{
+       struct or51211_state* state = fe->demodulator_priv;
+       state->config->sleep(fe);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops or51211_ops;
+
+struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct or51211_state* state = NULL;
+
+       /* Allocate memory for the internal state */
+       state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       /* Setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialized = 0;
+       state->current_frequency = 0;
+
+       /* Create dvb_frontend */
+       memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops or51211_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name               = "Oren OR51211 VSB Frontend",
+               .frequency_min      = 44000000,
+               .frequency_max      = 958000000,
+               .frequency_stepsize = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_8VSB
+       },
+
+       .release = or51211_release,
+
+       .init = or51211_init,
+       .sleep = or51211_sleep,
+
+       .set_frontend = or51211_set_parameters,
+       .get_tune_settings = or51211_get_tune_settings,
+
+       .read_status = or51211_read_status,
+       .read_ber = or51211_read_ber,
+       .read_signal_strength = or51211_read_signal_strength,
+       .read_snr = or51211_read_snr,
+       .read_ucblocks = or51211_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
+MODULE_AUTHOR("Kirk Lapray");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(or51211_attach);
+
diff --git a/drivers/media/dvb-frontends/or51211.h b/drivers/media/dvb-frontends/or51211.h
new file mode 100644 (file)
index 0000000..3ce0508
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *    Support for OR51211 (pcHDTV HD-2000) - VSB
+ *
+ *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+#ifndef OR51211_H
+#define OR51211_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct or51211_config
+{
+       /* The demodulator's i2c address */
+       u8 demod_address;
+
+       /* Request firmware for device */
+       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+       void (*setmode)(struct dvb_frontend * fe, int mode);
+       void (*reset)(struct dvb_frontend * fe);
+       void (*sleep)(struct dvb_frontend * fe);
+};
+
+#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE))
+extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_OR51211
+
+#endif // OR51211_H
+
diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c
new file mode 100644 (file)
index 0000000..8fa8b08
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * Realtek RTL2830 DVB-T demodulator driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+
+/*
+ * Driver implements own I2C-adapter for tuner I2C access. That's since chip
+ * have unusual I2C-gate control which closes gate automatically after each
+ * I2C transfer. Using own I2C adapter we can workaround that.
+ */
+
+#include "rtl2830_priv.h"
+
+int rtl2830_debug;
+module_param_named(debug, rtl2830_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+/* write multiple hardware registers */
+static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       u8 buf[1+len];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 1+len,
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple hardware registers */
+static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* write multiple registers */
+static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
+{
+       int ret;
+       u8 reg2 = (reg >> 0) & 0xff;
+       u8 page = (reg >> 8) & 0xff;
+
+       /* switch bank if needed */
+       if (page != priv->page) {
+               ret = rtl2830_wr(priv, 0x00, &page, 1);
+               if (ret)
+                       return ret;
+
+               priv->page = page;
+       }
+
+       return rtl2830_wr(priv, reg2, val, len);
+}
+
+/* read multiple registers */
+static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
+{
+       int ret;
+       u8 reg2 = (reg >> 0) & 0xff;
+       u8 page = (reg >> 8) & 0xff;
+
+       /* switch bank if needed */
+       if (page != priv->page) {
+               ret = rtl2830_wr(priv, 0x00, &page, 1);
+               if (ret)
+                       return ret;
+
+               priv->page = page;
+       }
+
+       return rtl2830_rd(priv, reg2, val, len);
+}
+
+#if 0 /* currently not used */
+/* write single register */
+static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
+{
+       return rtl2830_wr_regs(priv, reg, &val, 1);
+}
+#endif
+
+/* read single register */
+static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
+{
+       return rtl2830_rd_regs(priv, reg, val, 1);
+}
+
+/* write single register with mask */
+int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return rtl2830_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register with mask */
+int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+static int rtl2830_init(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       int ret, i;
+       u64 num;
+       u8 buf[3], tmp;
+       u32 if_ctl;
+       struct rtl2830_reg_val_mask tab[] = {
+               { 0x00d, 0x01, 0x03 },
+               { 0x00d, 0x10, 0x10 },
+               { 0x104, 0x00, 0x1e },
+               { 0x105, 0x80, 0x80 },
+               { 0x110, 0x02, 0x03 },
+               { 0x110, 0x08, 0x0c },
+               { 0x17b, 0x00, 0x40 },
+               { 0x17d, 0x05, 0x0f },
+               { 0x17d, 0x50, 0xf0 },
+               { 0x18c, 0x08, 0x0f },
+               { 0x18d, 0x00, 0xc0 },
+               { 0x188, 0x05, 0x0f },
+               { 0x189, 0x00, 0xfc },
+               { 0x2d5, 0x02, 0x02 },
+               { 0x2f1, 0x02, 0x06 },
+               { 0x2f1, 0x20, 0xf8 },
+               { 0x16d, 0x00, 0x01 },
+               { 0x1a6, 0x00, 0x80 },
+               { 0x106, priv->cfg.vtop, 0x3f },
+               { 0x107, priv->cfg.krf, 0x3f },
+               { 0x112, 0x28, 0xff },
+               { 0x103, priv->cfg.agc_targ_val, 0xff },
+               { 0x00a, 0x02, 0x07 },
+               { 0x140, 0x0c, 0x3c },
+               { 0x140, 0x40, 0xc0 },
+               { 0x15b, 0x05, 0x07 },
+               { 0x15b, 0x28, 0x38 },
+               { 0x15c, 0x05, 0x07 },
+               { 0x15c, 0x28, 0x38 },
+               { 0x115, priv->cfg.spec_inv, 0x01 },
+               { 0x16f, 0x01, 0x07 },
+               { 0x170, 0x18, 0x38 },
+               { 0x172, 0x0f, 0x0f },
+               { 0x173, 0x08, 0x38 },
+               { 0x175, 0x01, 0x07 },
+               { 0x176, 0x00, 0xc0 },
+       };
+
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+                       tab[i].mask);
+               if (ret)
+                       goto err;
+       }
+
+       ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2);
+       if (ret)
+               goto err;
+
+       ret = rtl2830_wr_regs(priv, 0x195,
+               "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
+       if (ret)
+               goto err;
+
+       num = priv->cfg.if_dvbt % priv->cfg.xtal;
+       num *= 0x400000;
+       num = div_u64(num, priv->cfg.xtal);
+       num = -num;
+       if_ctl = num & 0x3fffff;
+       dbg("%s: if_ctl=%08x", __func__, if_ctl);
+
+       ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
+       if (ret)
+               goto err;
+
+       buf[0] = tmp << 6;
+       buf[0] = (if_ctl >> 16) & 0x3f;
+       buf[1] = (if_ctl >>  8) & 0xff;
+       buf[2] = (if_ctl >>  0) & 0xff;
+
+       ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
+       if (ret)
+               goto err;
+
+       /* TODO: spec init */
+
+       /* soft reset */
+       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04);
+       if (ret)
+               goto err;
+
+       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04);
+       if (ret)
+               goto err;
+
+       priv->sleeping = false;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_sleep(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       priv->sleeping = true;
+       return 0;
+}
+
+int rtl2830_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 500;
+       s->step_size = fe->ops.info.frequency_stepsize * 2;
+       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+
+       return 0;
+}
+
+static int rtl2830_set_frontend(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       static u8 bw_params1[3][34] = {
+               {
+               0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
+               0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
+               0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
+               0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
+               }, {
+               0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
+               0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
+               0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
+               0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
+               }, {
+               0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
+               0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
+               0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
+               0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
+               },
+       };
+       static u8 bw_params2[3][6] = {
+               {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
+               {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
+               {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
+       };
+
+
+       dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
+               c->frequency, c->bandwidth_hz, c->inversion);
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               i = 0;
+               break;
+       case 7000000:
+               i = 1;
+               break;
+       case 8000000:
+               i = 2;
+               break;
+       default:
+               dbg("invalid bandwidth");
+               return -EINVAL;
+       }
+
+       ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06);
+       if (ret)
+               goto err;
+
+       /* 1/2 split I2C write */
+       ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
+       if (ret)
+               goto err;
+
+       /* 2/2 split I2C write */
+       ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17);
+       if (ret)
+               goto err;
+
+       ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_get_frontend(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u8 buf[3];
+
+       if (priv->sleeping)
+               return 0;
+
+       ret = rtl2830_rd_regs(priv, 0x33c, buf, 2);
+       if (ret)
+               goto err;
+
+       ret = rtl2830_rd_reg(priv, 0x351, &buf[2]);
+       if (ret)
+               goto err;
+
+       dbg("%s: TPS=%*ph", __func__, 3, buf);
+
+       switch ((buf[0] >> 2) & 3) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       }
+
+       switch ((buf[2] >> 2) & 1) {
+       case 0:
+               c->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               c->transmission_mode = TRANSMISSION_MODE_8K;
+       }
+
+       switch ((buf[2] >> 0) & 3) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       switch ((buf[0] >> 4) & 7) {
+       case 0:
+               c->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               c->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               c->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               c->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+       switch ((buf[1] >> 3) & 7) {
+       case 0:
+               c->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_HP = FEC_7_8;
+               break;
+       }
+
+       switch ((buf[1] >> 0) & 7) {
+       case 0:
+               c->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               c->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               c->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               c->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               c->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+       *status = 0;
+
+       if (priv->sleeping)
+               return 0;
+
+       ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */
+       if (ret)
+               goto err;
+
+       if (tmp == 11) {
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                       FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       } else if (tmp == 10) {
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                       FE_HAS_VITERBI;
+       }
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       int ret, hierarchy, constellation;
+       u8 buf[2], tmp;
+       u16 tmp16;
+#define CONSTELLATION_NUM 3
+#define HIERARCHY_NUM 4
+       static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
+               { 70705899, 70705899, 70705899, 70705899 },
+               { 82433173, 82433173, 87483115, 94445660 },
+               { 92888734, 92888734, 95487525, 99770748 },
+       };
+
+       if (priv->sleeping)
+               return 0;
+
+       /* reports SNR in resolution of 0.1 dB */
+
+       ret = rtl2830_rd_reg(priv, 0x33c, &tmp);
+       if (ret)
+               goto err;
+
+       constellation = (tmp >> 2) & 0x03; /* [3:2] */
+       if (constellation > CONSTELLATION_NUM - 1)
+               goto err;
+
+       hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
+       if (hierarchy > HIERARCHY_NUM - 1)
+               goto err;
+
+       ret = rtl2830_rd_regs(priv, 0x40c, buf, 2);
+       if (ret)
+               goto err;
+
+       tmp16 = buf[0] << 8 | buf[1];
+
+       if (tmp16)
+               *snr = (snr_constant[constellation][hierarchy] -
+                               intlog10(tmp16)) / ((1 << 24) / 100);
+       else
+               *snr = 0;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+
+       if (priv->sleeping)
+               return 0;
+
+       ret = rtl2830_rd_regs(priv, 0x34e, buf, 2);
+       if (ret)
+               goto err;
+
+       *ber = buf[0] << 8 | buf[1];
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+       u16 if_agc_raw, if_agc;
+
+       if (priv->sleeping)
+               return 0;
+
+       ret = rtl2830_rd_regs(priv, 0x359, buf, 2);
+       if (ret)
+               goto err;
+
+       if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff;
+
+       if (if_agc_raw & (1 << 9))
+               if_agc = -(~(if_agc_raw - 1) & 0x1ff);
+       else
+               if_agc = if_agc_raw;
+
+       *strength = (u8) (55 - if_agc / 182);
+       *strength |= *strength << 8;
+
+       return 0;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static struct dvb_frontend_ops rtl2830_ops;
+
+static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
+       struct i2c_msg msg[], int num)
+{
+       struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap);
+       int ret;
+
+       /* open i2c-gate */
+       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08);
+       if (ret)
+               goto err;
+
+       ret = i2c_transfer(priv->i2c, msg, num);
+       if (ret < 0)
+               warn("tuner i2c failed=%d", ret);
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static struct i2c_algorithm rtl2830_tuner_i2c_algo = {
+       .master_xfer   = rtl2830_tuner_i2c_xfer,
+       .functionality = rtl2830_tuner_i2c_func,
+};
+
+struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+       return &priv->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter);
+
+static void rtl2830_release(struct dvb_frontend *fe)
+{
+       struct rtl2830_priv *priv = fe->demodulator_priv;
+
+       i2c_del_adapter(&priv->tuner_i2c_adapter);
+       kfree(priv);
+}
+
+struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
+       struct i2c_adapter *i2c)
+{
+       struct rtl2830_priv *priv = NULL;
+       int ret = 0;
+       u8 tmp;
+
+       /* allocate memory for the internal state */
+       priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL);
+       if (priv == NULL)
+               goto err;
+
+       /* setup the priv */
+       priv->i2c = i2c;
+       memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config));
+
+       /* check if the demod is there */
+       ret = rtl2830_rd_reg(priv, 0x000, &tmp);
+       if (ret)
+               goto err;
+
+       /* create dvb_frontend */
+       memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops));
+       priv->fe.demodulator_priv = priv;
+
+       /* create tuner i2c adapter */
+       strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter",
+               sizeof(priv->tuner_i2c_adapter.name));
+       priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
+       priv->tuner_i2c_adapter.algo_data = NULL;
+       i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
+       if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
+               err("tuner I2C bus could not be initialized");
+               goto err;
+       }
+
+       priv->sleeping = true;
+
+       return &priv->fe;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(rtl2830_attach);
+
+static struct dvb_frontend_ops rtl2830_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Realtek RTL2830 (DVB-T)",
+               .caps = FE_CAN_FEC_1_2 |
+                       FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = rtl2830_release,
+
+       .init = rtl2830_init,
+       .sleep = rtl2830_sleep,
+
+       .get_tune_settings = rtl2830_get_tune_settings,
+
+       .set_frontend = rtl2830_set_frontend,
+       .get_frontend = rtl2830_get_frontend,
+
+       .read_status = rtl2830_read_status,
+       .read_snr = rtl2830_read_snr,
+       .read_ber = rtl2830_read_ber,
+       .read_ucblocks = rtl2830_read_ucblocks,
+       .read_signal_strength = rtl2830_read_signal_strength,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/rtl2830.h b/drivers/media/dvb-frontends/rtl2830.h
new file mode 100644 (file)
index 0000000..1c6ee91
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Realtek RTL2830 DVB-T demodulator driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef RTL2830_H
+#define RTL2830_H
+
+#include <linux/dvb/frontend.h>
+
+struct rtl2830_config {
+       /*
+        * Demodulator I2C address.
+        */
+       u8 i2c_addr;
+
+       /*
+        * Xtal frequency.
+        * Hz
+        * 4000000, 16000000, 25000000, 28800000
+        */
+       u32 xtal;
+
+       /*
+        * TS output mode.
+        */
+       u8 ts_mode;
+
+       /*
+        * Spectrum inversion.
+        */
+       bool spec_inv;
+
+       /*
+        * IFs for all used modes.
+        * Hz
+        * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
+        */
+       u32 if_dvbt;
+
+       /*
+        */
+       u8 vtop;
+
+       /*
+        */
+       u8 krf;
+
+       /*
+        */
+       u8 agc_targ_val;
+};
+
+#if defined(CONFIG_DVB_RTL2830) || \
+       (defined(CONFIG_DVB_RTL2830_MODULE) && defined(MODULE))
+extern struct dvb_frontend *rtl2830_attach(
+       const struct rtl2830_config *config,
+       struct i2c_adapter *i2c
+);
+
+extern struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
+       struct dvb_frontend *fe
+);
+#else
+static inline struct dvb_frontend *rtl2830_attach(
+       const struct rtl2830_config *config,
+       struct i2c_adapter *i2c
+)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
+       struct dvb_frontend *fe
+)
+{
+       return NULL;
+}
+#endif
+
+#endif /* RTL2830_H */
diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h
new file mode 100644 (file)
index 0000000..9b20557
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Realtek RTL2830 DVB-T demodulator driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef RTL2830_PRIV_H
+#define RTL2830_PRIV_H
+
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "rtl2830.h"
+
+#define LOG_PREFIX "rtl2830"
+
+#undef dbg
+#define dbg(f, arg...) \
+       if (rtl2830_debug) \
+               printk(KERN_INFO            LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct rtl2830_priv {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct rtl2830_config cfg;
+       struct i2c_adapter tuner_i2c_adapter;
+
+       bool sleeping;
+
+       u8 page; /* active register page */
+};
+
+struct rtl2830_reg_val_mask {
+       u16 reg;
+       u8  val;
+       u8  mask;
+};
+
+#endif /* RTL2830_PRIV_H */
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
new file mode 100644 (file)
index 0000000..28269cc
--- /dev/null
@@ -0,0 +1,789 @@
+/*
+ * Realtek RTL2832 DVB-T demodulator driver
+ *
+ * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
+ *
+ *     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.
+ */
+
+#include "rtl2832_priv.h"
+#include <linux/bitops.h>
+
+int rtl2832_debug;
+module_param_named(debug, rtl2832_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+#define REG_MASK(b) (BIT(b + 1) - 1)
+
+static const struct rtl2832_reg_entry registers[] = {
+       [DVBT_SOFT_RST]         = {0x1, 0x1,   2, 2},
+       [DVBT_IIC_REPEAT]       = {0x1, 0x1,   3, 3},
+       [DVBT_TR_WAIT_MIN_8K]   = {0x1, 0x88, 11, 2},
+       [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
+       [DVBT_EN_BK_TRK]        = {0x1, 0xa6,  7, 7},
+       [DVBT_AD_EN_REG]        = {0x0, 0x8,   7, 7},
+       [DVBT_AD_EN_REG1]       = {0x0, 0x8,   6, 6},
+       [DVBT_EN_BBIN]          = {0x1, 0xb1,  0, 0},
+       [DVBT_MGD_THD0]         = {0x1, 0x95,  7, 0},
+       [DVBT_MGD_THD1]         = {0x1, 0x96,  7, 0},
+       [DVBT_MGD_THD2]         = {0x1, 0x97,  7, 0},
+       [DVBT_MGD_THD3]         = {0x1, 0x98,  7, 0},
+       [DVBT_MGD_THD4]         = {0x1, 0x99,  7, 0},
+       [DVBT_MGD_THD5]         = {0x1, 0x9a,  7, 0},
+       [DVBT_MGD_THD6]         = {0x1, 0x9b,  7, 0},
+       [DVBT_MGD_THD7]         = {0x1, 0x9c,  7, 0},
+       [DVBT_EN_CACQ_NOTCH]    = {0x1, 0x61,  4, 4},
+       [DVBT_AD_AV_REF]        = {0x0, 0x9,   6, 0},
+       [DVBT_REG_PI]           = {0x0, 0xa,   2, 0},
+       [DVBT_PIP_ON]           = {0x0, 0x21,  3, 3},
+       [DVBT_SCALE1_B92]       = {0x2, 0x92,  7, 0},
+       [DVBT_SCALE1_B93]       = {0x2, 0x93,  7, 0},
+       [DVBT_SCALE1_BA7]       = {0x2, 0xa7,  7, 0},
+       [DVBT_SCALE1_BA9]       = {0x2, 0xa9,  7, 0},
+       [DVBT_SCALE1_BAA]       = {0x2, 0xaa,  7, 0},
+       [DVBT_SCALE1_BAB]       = {0x2, 0xab,  7, 0},
+       [DVBT_SCALE1_BAC]       = {0x2, 0xac,  7, 0},
+       [DVBT_SCALE1_BB0]       = {0x2, 0xb0,  7, 0},
+       [DVBT_SCALE1_BB1]       = {0x2, 0xb1,  7, 0},
+       [DVBT_KB_P1]            = {0x1, 0x64,  3, 1},
+       [DVBT_KB_P2]            = {0x1, 0x64,  6, 4},
+       [DVBT_KB_P3]            = {0x1, 0x65,  2, 0},
+       [DVBT_OPT_ADC_IQ]       = {0x0, 0x6,   5, 4},
+       [DVBT_AD_AVI]           = {0x0, 0x9,   1, 0},
+       [DVBT_AD_AVQ]           = {0x0, 0x9,   3, 2},
+       [DVBT_K1_CR_STEP12]     = {0x2, 0xad,  9, 4},
+       [DVBT_TRK_KS_P2]        = {0x1, 0x6f,  2, 0},
+       [DVBT_TRK_KS_I2]        = {0x1, 0x70,  5, 3},
+       [DVBT_TR_THD_SET2]      = {0x1, 0x72,  3, 0},
+       [DVBT_TRK_KC_P2]        = {0x1, 0x73,  5, 3},
+       [DVBT_TRK_KC_I2]        = {0x1, 0x75,  2, 0},
+       [DVBT_CR_THD_SET2]      = {0x1, 0x76,  7, 6},
+       [DVBT_PSET_IFFREQ]      = {0x1, 0x19, 21, 0},
+       [DVBT_SPEC_INV]         = {0x1, 0x15,  0, 0},
+       [DVBT_RSAMP_RATIO]      = {0x1, 0x9f, 27, 2},
+       [DVBT_CFREQ_OFF_RATIO]  = {0x1, 0x9d, 23, 4},
+       [DVBT_FSM_STAGE]        = {0x3, 0x51,  6, 3},
+       [DVBT_RX_CONSTEL]       = {0x3, 0x3c,  3, 2},
+       [DVBT_RX_HIER]          = {0x3, 0x3c,  6, 4},
+       [DVBT_RX_C_RATE_LP]     = {0x3, 0x3d,  2, 0},
+       [DVBT_RX_C_RATE_HP]     = {0x3, 0x3d,  5, 3},
+       [DVBT_GI_IDX]           = {0x3, 0x51,  1, 0},
+       [DVBT_FFT_MODE_IDX]     = {0x3, 0x51,  2, 2},
+       [DVBT_RSD_BER_EST]      = {0x3, 0x4e, 15, 0},
+       [DVBT_CE_EST_EVM]       = {0x4, 0xc,  15, 0},
+       [DVBT_RF_AGC_VAL]       = {0x3, 0x5b, 13, 0},
+       [DVBT_IF_AGC_VAL]       = {0x3, 0x59, 13, 0},
+       [DVBT_DAGC_VAL]         = {0x3, 0x5,   7, 0},
+       [DVBT_SFREQ_OFF]        = {0x3, 0x18, 13, 0},
+       [DVBT_CFREQ_OFF]        = {0x3, 0x5f, 17, 0},
+       [DVBT_POLAR_RF_AGC]     = {0x0, 0xe,   1, 1},
+       [DVBT_POLAR_IF_AGC]     = {0x0, 0xe,   0, 0},
+       [DVBT_AAGC_HOLD]        = {0x1, 0x4,   5, 5},
+       [DVBT_EN_RF_AGC]        = {0x1, 0x4,   6, 6},
+       [DVBT_EN_IF_AGC]        = {0x1, 0x4,   7, 7},
+       [DVBT_IF_AGC_MIN]       = {0x1, 0x8,   7, 0},
+       [DVBT_IF_AGC_MAX]       = {0x1, 0x9,   7, 0},
+       [DVBT_RF_AGC_MIN]       = {0x1, 0xa,   7, 0},
+       [DVBT_RF_AGC_MAX]       = {0x1, 0xb,   7, 0},
+       [DVBT_IF_AGC_MAN]       = {0x1, 0xc,   6, 6},
+       [DVBT_IF_AGC_MAN_VAL]   = {0x1, 0xc,  13, 0},
+       [DVBT_RF_AGC_MAN]       = {0x1, 0xe,   6, 6},
+       [DVBT_RF_AGC_MAN_VAL]   = {0x1, 0xe,  13, 0},
+       [DVBT_DAGC_TRG_VAL]     = {0x1, 0x12,  7, 0},
+       [DVBT_AGC_TARG_VAL_0]   = {0x1, 0x2,   0, 0},
+       [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3,   7, 0},
+       [DVBT_AAGC_LOOP_GAIN]   = {0x1, 0xc7,  5, 1},
+       [DVBT_LOOP_GAIN2_3_0]   = {0x1, 0x4,   4, 1},
+       [DVBT_LOOP_GAIN2_4]     = {0x1, 0x5,   7, 7},
+       [DVBT_LOOP_GAIN3]       = {0x1, 0xc8,  4, 0},
+       [DVBT_VTOP1]            = {0x1, 0x6,   5, 0},
+       [DVBT_VTOP2]            = {0x1, 0xc9,  5, 0},
+       [DVBT_VTOP3]            = {0x1, 0xca,  5, 0},
+       [DVBT_KRF1]             = {0x1, 0xcb,  7, 0},
+       [DVBT_KRF2]             = {0x1, 0x7,   7, 0},
+       [DVBT_KRF3]             = {0x1, 0xcd,  7, 0},
+       [DVBT_KRF4]             = {0x1, 0xce,  7, 0},
+       [DVBT_EN_GI_PGA]        = {0x1, 0xe5,  0, 0},
+       [DVBT_THD_LOCK_UP]      = {0x1, 0xd9,  8, 0},
+       [DVBT_THD_LOCK_DW]      = {0x1, 0xdb,  8, 0},
+       [DVBT_THD_UP1]          = {0x1, 0xdd,  7, 0},
+       [DVBT_THD_DW1]          = {0x1, 0xde,  7, 0},
+       [DVBT_INTER_CNT_LEN]    = {0x1, 0xd8,  3, 0},
+       [DVBT_GI_PGA_STATE]     = {0x1, 0xe6,  3, 3},
+       [DVBT_EN_AGC_PGA]       = {0x1, 0xd7,  0, 0},
+       [DVBT_CKOUTPAR]         = {0x1, 0x7b,  5, 5},
+       [DVBT_CKOUT_PWR]        = {0x1, 0x7b,  6, 6},
+       [DVBT_SYNC_DUR]         = {0x1, 0x7b,  7, 7},
+       [DVBT_ERR_DUR]          = {0x1, 0x7c,  0, 0},
+       [DVBT_SYNC_LVL]         = {0x1, 0x7c,  1, 1},
+       [DVBT_ERR_LVL]          = {0x1, 0x7c,  2, 2},
+       [DVBT_VAL_LVL]          = {0x1, 0x7c,  3, 3},
+       [DVBT_SERIAL]           = {0x1, 0x7c,  4, 4},
+       [DVBT_SER_LSB]          = {0x1, 0x7c,  5, 5},
+       [DVBT_CDIV_PH0]         = {0x1, 0x7d,  3, 0},
+       [DVBT_CDIV_PH1]         = {0x1, 0x7d,  7, 4},
+       [DVBT_MPEG_IO_OPT_2_2]  = {0x0, 0x6,   7, 7},
+       [DVBT_MPEG_IO_OPT_1_0]  = {0x0, 0x7,   7, 6},
+       [DVBT_CKOUTPAR_PIP]     = {0x0, 0xb7,  4, 4},
+       [DVBT_CKOUT_PWR_PIP]    = {0x0, 0xb7,  3, 3},
+       [DVBT_SYNC_LVL_PIP]     = {0x0, 0xb7,  2, 2},
+       [DVBT_ERR_LVL_PIP]      = {0x0, 0xb7,  1, 1},
+       [DVBT_VAL_LVL_PIP]      = {0x0, 0xb7,  0, 0},
+       [DVBT_CKOUTPAR_PID]     = {0x0, 0xb9,  4, 4},
+       [DVBT_CKOUT_PWR_PID]    = {0x0, 0xb9,  3, 3},
+       [DVBT_SYNC_LVL_PID]     = {0x0, 0xb9,  2, 2},
+       [DVBT_ERR_LVL_PID]      = {0x0, 0xb9,  1, 1},
+       [DVBT_VAL_LVL_PID]      = {0x0, 0xb9,  0, 0},
+       [DVBT_SM_PASS]          = {0x1, 0x93, 11, 0},
+       [DVBT_AD7_SETTING]      = {0x0, 0x11, 15, 0},
+       [DVBT_RSSI_R]           = {0x3, 0x1,   6, 0},
+       [DVBT_ACI_DET_IND]      = {0x3, 0x12,  0, 0},
+       [DVBT_REG_MON]          = {0x0, 0xd,   1, 0},
+       [DVBT_REG_MONSEL]       = {0x0, 0xd,   2, 2},
+       [DVBT_REG_GPE]          = {0x0, 0xd,   7, 7},
+       [DVBT_REG_GPO]          = {0x0, 0x10,  0, 0},
+       [DVBT_REG_4MSEL]        = {0x0, 0x13,  0, 0},
+};
+
+/* write multiple hardware registers */
+static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       u8 buf[1+len];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 1+len,
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple hardware registers */
+static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
+{
+       int ret;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = priv->cfg.i2c_addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = val,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               ret = 0;
+       } else {
+               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+               ret = -EREMOTEIO;
+}
+return ret;
+}
+
+/* write multiple registers */
+static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
+       int len)
+{
+       int ret;
+
+
+       /* switch bank if needed */
+       if (page != priv->page) {
+               ret = rtl2832_wr(priv, 0x00, &page, 1);
+               if (ret)
+                       return ret;
+
+               priv->page = page;
+}
+
+return rtl2832_wr(priv, reg, val, len);
+}
+
+/* read multiple registers */
+static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
+       int len)
+{
+       int ret;
+
+       /* switch bank if needed */
+       if (page != priv->page) {
+               ret = rtl2832_wr(priv, 0x00, &page, 1);
+               if (ret)
+                       return ret;
+
+               priv->page = page;
+       }
+
+       return rtl2832_rd(priv, reg, val, len);
+}
+
+#if 0 /* currently not used */
+/* write single register */
+static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
+{
+       return rtl2832_wr_regs(priv, reg, page, &val, 1);
+}
+#endif
+
+/* read single register */
+static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
+{
+       return rtl2832_rd_regs(priv, reg, page, val, 1);
+}
+
+int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
+{
+       int ret;
+
+       u8 reg_start_addr;
+       u8 msb, lsb;
+       u8 page;
+       u8 reading[4];
+       u32 reading_tmp;
+       int i;
+
+       u8 len;
+       u32 mask;
+
+       reg_start_addr = registers[reg].start_address;
+       msb = registers[reg].msb;
+       lsb = registers[reg].lsb;
+       page = registers[reg].page;
+
+       len = (msb >> 3) + 1;
+       mask = REG_MASK(msb - lsb);
+
+       ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
+       if (ret)
+               goto err;
+
+       reading_tmp = 0;
+       for (i = 0; i < len; i++)
+               reading_tmp |= reading[i] << ((len - 1 - i) * 8);
+
+       *val = (reading_tmp >> lsb) & mask;
+
+       return ret;
+
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+
+}
+
+int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
+{
+       int ret, i;
+       u8 len;
+       u8 reg_start_addr;
+       u8 msb, lsb;
+       u8 page;
+       u32 mask;
+
+
+       u8 reading[4];
+       u8 writing[4];
+       u32 reading_tmp;
+       u32 writing_tmp;
+
+
+       reg_start_addr = registers[reg].start_address;
+       msb = registers[reg].msb;
+       lsb = registers[reg].lsb;
+       page = registers[reg].page;
+
+       len = (msb >> 3) + 1;
+       mask = REG_MASK(msb - lsb);
+
+
+       ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
+       if (ret)
+               goto err;
+
+       reading_tmp = 0;
+       for (i = 0; i < len; i++)
+               reading_tmp |= reading[i] << ((len - 1 - i) * 8);
+
+       writing_tmp = reading_tmp & ~(mask << lsb);
+       writing_tmp |= ((val & mask) << lsb);
+
+
+       for (i = 0; i < len; i++)
+               writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
+
+       ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
+       if (ret)
+               goto err;
+
+       return ret;
+
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+
+}
+
+
+static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       int ret;
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+
+       dbg("%s: enable=%d", __func__, enable);
+
+       /* gate already open or close */
+       if (priv->i2c_gate_state == enable)
+               return 0;
+
+       ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
+       if (ret)
+               goto err;
+
+       priv->i2c_gate_state = enable;
+
+       return ret;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+
+
+static int rtl2832_init(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+       int i, ret;
+
+       u8 en_bbin;
+       u64 pset_iffreq;
+
+       /* initialization values for the demodulator registers */
+       struct rtl2832_reg_value rtl2832_initial_regs[] = {
+               {DVBT_AD_EN_REG,                0x1},
+               {DVBT_AD_EN_REG1,               0x1},
+               {DVBT_RSD_BER_FAIL_VAL,         0x2800},
+               {DVBT_MGD_THD0,                 0x10},
+               {DVBT_MGD_THD1,                 0x20},
+               {DVBT_MGD_THD2,                 0x20},
+               {DVBT_MGD_THD3,                 0x40},
+               {DVBT_MGD_THD4,                 0x22},
+               {DVBT_MGD_THD5,                 0x32},
+               {DVBT_MGD_THD6,                 0x37},
+               {DVBT_MGD_THD7,                 0x39},
+               {DVBT_EN_BK_TRK,                0x0},
+               {DVBT_EN_CACQ_NOTCH,            0x0},
+               {DVBT_AD_AV_REF,                0x2a},
+               {DVBT_REG_PI,                   0x6},
+               {DVBT_PIP_ON,                   0x0},
+               {DVBT_CDIV_PH0,                 0x8},
+               {DVBT_CDIV_PH1,                 0x8},
+               {DVBT_SCALE1_B92,               0x4},
+               {DVBT_SCALE1_B93,               0xb0},
+               {DVBT_SCALE1_BA7,               0x78},
+               {DVBT_SCALE1_BA9,               0x28},
+               {DVBT_SCALE1_BAA,               0x59},
+               {DVBT_SCALE1_BAB,               0x83},
+               {DVBT_SCALE1_BAC,               0xd4},
+               {DVBT_SCALE1_BB0,               0x65},
+               {DVBT_SCALE1_BB1,               0x43},
+               {DVBT_KB_P1,                    0x1},
+               {DVBT_KB_P2,                    0x4},
+               {DVBT_KB_P3,                    0x7},
+               {DVBT_K1_CR_STEP12,             0xa},
+               {DVBT_REG_GPE,                  0x1},
+               {DVBT_SERIAL,                   0x0},
+               {DVBT_CDIV_PH0,                 0x9},
+               {DVBT_CDIV_PH1,                 0x9},
+               {DVBT_MPEG_IO_OPT_2_2,          0x0},
+               {DVBT_MPEG_IO_OPT_1_0,          0x0},
+               {DVBT_TRK_KS_P2,                0x4},
+               {DVBT_TRK_KS_I2,                0x7},
+               {DVBT_TR_THD_SET2,              0x6},
+               {DVBT_TRK_KC_I2,                0x5},
+               {DVBT_CR_THD_SET2,              0x1},
+               {DVBT_SPEC_INV,                 0x0},
+               {DVBT_DAGC_TRG_VAL,             0x5a},
+               {DVBT_AGC_TARG_VAL_0,           0x0},
+               {DVBT_AGC_TARG_VAL_8_1,         0x5a},
+               {DVBT_AAGC_LOOP_GAIN,           0x16},
+               {DVBT_LOOP_GAIN2_3_0,           0x6},
+               {DVBT_LOOP_GAIN2_4,             0x1},
+               {DVBT_LOOP_GAIN3,               0x16},
+               {DVBT_VTOP1,                    0x35},
+               {DVBT_VTOP2,                    0x21},
+               {DVBT_VTOP3,                    0x21},
+               {DVBT_KRF1,                     0x0},
+               {DVBT_KRF2,                     0x40},
+               {DVBT_KRF3,                     0x10},
+               {DVBT_KRF4,                     0x10},
+               {DVBT_IF_AGC_MIN,               0x80},
+               {DVBT_IF_AGC_MAX,               0x7f},
+               {DVBT_RF_AGC_MIN,               0x80},
+               {DVBT_RF_AGC_MAX,               0x7f},
+               {DVBT_POLAR_RF_AGC,             0x0},
+               {DVBT_POLAR_IF_AGC,             0x0},
+               {DVBT_AD7_SETTING,              0xe9bf},
+               {DVBT_EN_GI_PGA,                0x0},
+               {DVBT_THD_LOCK_UP,              0x0},
+               {DVBT_THD_LOCK_DW,              0x0},
+               {DVBT_THD_UP1,                  0x11},
+               {DVBT_THD_DW1,                  0xef},
+               {DVBT_INTER_CNT_LEN,            0xc},
+               {DVBT_GI_PGA_STATE,             0x0},
+               {DVBT_EN_AGC_PGA,               0x1},
+               {DVBT_IF_AGC_MAN,               0x0},
+       };
+
+
+       dbg("%s", __func__);
+
+       en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
+
+       /*
+       * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
+       *               / CrystalFreqHz)
+       */
+       pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
+       pset_iffreq *= 0x400000;
+       pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
+       pset_iffreq = pset_iffreq & 0x3fffff;
+
+
+
+       for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
+               ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
+                       rtl2832_initial_regs[i].value);
+               if (ret)
+                       goto err;
+       }
+
+       /* if frequency settings */
+       ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
+               if (ret)
+                       goto err;
+
+       ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
+               if (ret)
+                       goto err;
+
+       priv->sleeping = false;
+
+       return ret;
+
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2832_sleep(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+
+       dbg("%s", __func__);
+       priv->sleeping = true;
+       return 0;
+}
+
+int rtl2832_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       dbg("%s", __func__);
+       s->min_delay_ms = 1000;
+       s->step_size = fe->ops.info.frequency_stepsize * 2;
+       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+       return 0;
+}
+
+static int rtl2832_set_frontend(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i, j;
+       u64 bw_mode, num, num2;
+       u32 resamp_ratio, cfreq_off_ratio;
+
+
+       static u8 bw_params[3][32] = {
+       /* 6 MHz bandwidth */
+               {
+               0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
+               0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
+               0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
+               0x19, 0xe0,
+               },
+
+       /*  7 MHz bandwidth */
+               {
+               0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
+               0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
+               0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
+               0x19, 0x10,
+               },
+
+       /*  8 MHz bandwidth */
+               {
+               0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
+               0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
+               0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
+               0x19, 0xe0,
+               },
+       };
+
+
+       dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
+               c->frequency, c->bandwidth_hz, c->inversion);
+
+
+       /* program tuner */
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               i = 0;
+               bw_mode = 48000000;
+               break;
+       case 7000000:
+               i = 1;
+               bw_mode = 56000000;
+               break;
+       case 8000000:
+               i = 2;
+               bw_mode = 64000000;
+               break;
+       default:
+               dbg("invalid bandwidth");
+               return -EINVAL;
+       }
+
+       for (j = 0; j < sizeof(bw_params[0]); j++) {
+               ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
+               if (ret)
+                       goto err;
+       }
+
+       /* calculate and set resample ratio
+       * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
+       *       / ConstWithBandwidthMode)
+       */
+       num = priv->cfg.xtal * 7;
+       num *= 0x400000;
+       num = div_u64(num, bw_mode);
+       resamp_ratio =  num & 0x3ffffff;
+       ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
+       if (ret)
+               goto err;
+
+       /* calculate and set cfreq off ratio
+       * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
+       *       / (CrystalFreqHz * 7))
+       */
+       num = bw_mode << 20;
+       num2 = priv->cfg.xtal * 7;
+       num = div_u64(num, num2);
+       num = -num;
+       cfreq_off_ratio = num & 0xfffff;
+       ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
+       if (ret)
+               goto err;
+
+
+       /* soft reset */
+       ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
+       if (ret)
+               goto err;
+
+       ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
+       if (ret)
+               goto err;
+
+       return ret;
+err:
+       info("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+       int ret;
+       u32 tmp;
+       *status = 0;
+
+
+       dbg("%s", __func__);
+       if (priv->sleeping)
+               return 0;
+
+       ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
+       if (ret)
+               goto err;
+
+       if (tmp == 11) {
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+       }
+       /* TODO find out if this is also true for rtl2832? */
+       /*else if (tmp == 10) {
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+                               FE_HAS_VITERBI;
+       }*/
+
+       return ret;
+err:
+       info("%s: failed=%d", __func__, ret);
+       return ret;
+}
+
+static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       *snr = 0;
+       return 0;
+}
+
+static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       *ber = 0;
+       return 0;
+}
+
+static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       *ucblocks = 0;
+       return 0;
+}
+
+
+static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       *strength = 0;
+       return 0;
+}
+
+static struct dvb_frontend_ops rtl2832_ops;
+
+static void rtl2832_release(struct dvb_frontend *fe)
+{
+       struct rtl2832_priv *priv = fe->demodulator_priv;
+
+       dbg("%s", __func__);
+       kfree(priv);
+}
+
+struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
+       struct i2c_adapter *i2c)
+{
+       struct rtl2832_priv *priv = NULL;
+       int ret = 0;
+       u8 tmp;
+
+       dbg("%s", __func__);
+
+       /* allocate memory for the internal state */
+       priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
+       if (priv == NULL)
+               goto err;
+
+       /* setup the priv */
+       priv->i2c = i2c;
+       priv->tuner = cfg->tuner;
+       memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
+
+       /* check if the demod is there */
+       ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
+       if (ret)
+               goto err;
+
+       /* create dvb_frontend */
+       memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
+       priv->fe.demodulator_priv = priv;
+
+       /* TODO implement sleep mode */
+       priv->sleeping = true;
+
+       return &priv->fe;
+err:
+       dbg("%s: failed=%d", __func__, ret);
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(rtl2832_attach);
+
+static struct dvb_frontend_ops rtl2832_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Realtek RTL2832 (DVB-T)",
+               .frequency_min    = 174000000,
+               .frequency_max    = 862000000,
+               .frequency_stepsize = 166667,
+               .caps = FE_CAN_FEC_1_2 |
+                       FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+        },
+
+       .release = rtl2832_release,
+
+       .init = rtl2832_init,
+       .sleep = rtl2832_sleep,
+
+       .get_tune_settings = rtl2832_get_tune_settings,
+
+       .set_frontend = rtl2832_set_frontend,
+
+       .read_status = rtl2832_read_status,
+       .read_snr = rtl2832_read_snr,
+       .read_ber = rtl2832_read_ber,
+       .read_ucblocks = rtl2832_read_ucblocks,
+       .read_signal_strength = rtl2832_read_signal_strength,
+       .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
+};
+
+MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
+MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.5");
diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h
new file mode 100644 (file)
index 0000000..d94dc9a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Realtek RTL2832 DVB-T demodulator driver
+ *
+ * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
+ *
+ *     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.
+ */
+
+#ifndef RTL2832_H
+#define RTL2832_H
+
+#include <linux/dvb/frontend.h>
+
+struct rtl2832_config {
+       /*
+        * Demodulator I2C address.
+        */
+       u8 i2c_addr;
+
+       /*
+        * Xtal frequency.
+        * Hz
+        * 4000000, 16000000, 25000000, 28800000
+        */
+       u32 xtal;
+
+       /*
+        * IFs for all used modes.
+        * Hz
+        * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
+        */
+       u32 if_dvbt;
+
+       /*
+        */
+       u8 tuner;
+};
+
+
+#if defined(CONFIG_DVB_RTL2832) || \
+       (defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE))
+extern struct dvb_frontend *rtl2832_attach(
+       const struct rtl2832_config *cfg,
+       struct i2c_adapter *i2c
+);
+
+extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
+       struct dvb_frontend *fe
+);
+#else
+static inline struct dvb_frontend *rtl2832_attach(
+       const struct rtl2832_config *config,
+       struct i2c_adapter *i2c
+)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+
+#endif /* RTL2832_H */
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
new file mode 100644 (file)
index 0000000..0ce9502
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Realtek RTL2832 DVB-T demodulator driver
+ *
+ * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
+ *
+ *     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.
+ */
+
+#ifndef RTL2832_PRIV_H
+#define RTL2832_PRIV_H
+
+#include "dvb_frontend.h"
+#include "rtl2832.h"
+
+#define LOG_PREFIX "rtl2832"
+
+#undef dbg
+#define dbg(f, arg...) \
+do { \
+       if (rtl2832_debug)  \
+               printk(KERN_INFO     LOG_PREFIX": " f "\n" , ## arg); \
+} while (0)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct rtl2832_priv {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct rtl2832_config cfg;
+
+       bool i2c_gate_state;
+       bool sleeping;
+
+       u8 tuner;
+       u8 page; /* active register page */
+};
+
+struct rtl2832_reg_entry {
+       u8 page;
+       u8 start_address;
+       u8 msb;
+       u8 lsb;
+};
+
+struct rtl2832_reg_value {
+       int reg;
+       u32 value;
+};
+
+
+/* Demod register bit names */
+enum DVBT_REG_BIT_NAME {
+       DVBT_SOFT_RST,
+       DVBT_IIC_REPEAT,
+       DVBT_TR_WAIT_MIN_8K,
+       DVBT_RSD_BER_FAIL_VAL,
+       DVBT_EN_BK_TRK,
+       DVBT_REG_PI,
+       DVBT_REG_PFREQ_1_0,
+       DVBT_PD_DA8,
+       DVBT_LOCK_TH,
+       DVBT_BER_PASS_SCAL,
+       DVBT_CE_FFSM_BYPASS,
+       DVBT_ALPHAIIR_N,
+       DVBT_ALPHAIIR_DIF,
+       DVBT_EN_TRK_SPAN,
+       DVBT_LOCK_TH_LEN,
+       DVBT_CCI_THRE,
+       DVBT_CCI_MON_SCAL,
+       DVBT_CCI_M0,
+       DVBT_CCI_M1,
+       DVBT_CCI_M2,
+       DVBT_CCI_M3,
+       DVBT_SPEC_INIT_0,
+       DVBT_SPEC_INIT_1,
+       DVBT_SPEC_INIT_2,
+       DVBT_AD_EN_REG,
+       DVBT_AD_EN_REG1,
+       DVBT_EN_BBIN,
+       DVBT_MGD_THD0,
+       DVBT_MGD_THD1,
+       DVBT_MGD_THD2,
+       DVBT_MGD_THD3,
+       DVBT_MGD_THD4,
+       DVBT_MGD_THD5,
+       DVBT_MGD_THD6,
+       DVBT_MGD_THD7,
+       DVBT_EN_CACQ_NOTCH,
+       DVBT_AD_AV_REF,
+       DVBT_PIP_ON,
+       DVBT_SCALE1_B92,
+       DVBT_SCALE1_B93,
+       DVBT_SCALE1_BA7,
+       DVBT_SCALE1_BA9,
+       DVBT_SCALE1_BAA,
+       DVBT_SCALE1_BAB,
+       DVBT_SCALE1_BAC,
+       DVBT_SCALE1_BB0,
+       DVBT_SCALE1_BB1,
+       DVBT_KB_P1,
+       DVBT_KB_P2,
+       DVBT_KB_P3,
+       DVBT_OPT_ADC_IQ,
+       DVBT_AD_AVI,
+       DVBT_AD_AVQ,
+       DVBT_K1_CR_STEP12,
+       DVBT_TRK_KS_P2,
+       DVBT_TRK_KS_I2,
+       DVBT_TR_THD_SET2,
+       DVBT_TRK_KC_P2,
+       DVBT_TRK_KC_I2,
+       DVBT_CR_THD_SET2,
+       DVBT_PSET_IFFREQ,
+       DVBT_SPEC_INV,
+       DVBT_BW_INDEX,
+       DVBT_RSAMP_RATIO,
+       DVBT_CFREQ_OFF_RATIO,
+       DVBT_FSM_STAGE,
+       DVBT_RX_CONSTEL,
+       DVBT_RX_HIER,
+       DVBT_RX_C_RATE_LP,
+       DVBT_RX_C_RATE_HP,
+       DVBT_GI_IDX,
+       DVBT_FFT_MODE_IDX,
+       DVBT_RSD_BER_EST,
+       DVBT_CE_EST_EVM,
+       DVBT_RF_AGC_VAL,
+       DVBT_IF_AGC_VAL,
+       DVBT_DAGC_VAL,
+       DVBT_SFREQ_OFF,
+       DVBT_CFREQ_OFF,
+       DVBT_POLAR_RF_AGC,
+       DVBT_POLAR_IF_AGC,
+       DVBT_AAGC_HOLD,
+       DVBT_EN_RF_AGC,
+       DVBT_EN_IF_AGC,
+       DVBT_IF_AGC_MIN,
+       DVBT_IF_AGC_MAX,
+       DVBT_RF_AGC_MIN,
+       DVBT_RF_AGC_MAX,
+       DVBT_IF_AGC_MAN,
+       DVBT_IF_AGC_MAN_VAL,
+       DVBT_RF_AGC_MAN,
+       DVBT_RF_AGC_MAN_VAL,
+       DVBT_DAGC_TRG_VAL,
+       DVBT_AGC_TARG_VAL,
+       DVBT_LOOP_GAIN_3_0,
+       DVBT_LOOP_GAIN_4,
+       DVBT_VTOP,
+       DVBT_KRF,
+       DVBT_AGC_TARG_VAL_0,
+       DVBT_AGC_TARG_VAL_8_1,
+       DVBT_AAGC_LOOP_GAIN,
+       DVBT_LOOP_GAIN2_3_0,
+       DVBT_LOOP_GAIN2_4,
+       DVBT_LOOP_GAIN3,
+       DVBT_VTOP1,
+       DVBT_VTOP2,
+       DVBT_VTOP3,
+       DVBT_KRF1,
+       DVBT_KRF2,
+       DVBT_KRF3,
+       DVBT_KRF4,
+       DVBT_EN_GI_PGA,
+       DVBT_THD_LOCK_UP,
+       DVBT_THD_LOCK_DW,
+       DVBT_THD_UP1,
+       DVBT_THD_DW1,
+       DVBT_INTER_CNT_LEN,
+       DVBT_GI_PGA_STATE,
+       DVBT_EN_AGC_PGA,
+       DVBT_CKOUTPAR,
+       DVBT_CKOUT_PWR,
+       DVBT_SYNC_DUR,
+       DVBT_ERR_DUR,
+       DVBT_SYNC_LVL,
+       DVBT_ERR_LVL,
+       DVBT_VAL_LVL,
+       DVBT_SERIAL,
+       DVBT_SER_LSB,
+       DVBT_CDIV_PH0,
+       DVBT_CDIV_PH1,
+       DVBT_MPEG_IO_OPT_2_2,
+       DVBT_MPEG_IO_OPT_1_0,
+       DVBT_CKOUTPAR_PIP,
+       DVBT_CKOUT_PWR_PIP,
+       DVBT_SYNC_LVL_PIP,
+       DVBT_ERR_LVL_PIP,
+       DVBT_VAL_LVL_PIP,
+       DVBT_CKOUTPAR_PID,
+       DVBT_CKOUT_PWR_PID,
+       DVBT_SYNC_LVL_PID,
+       DVBT_ERR_LVL_PID,
+       DVBT_VAL_LVL_PID,
+       DVBT_SM_PASS,
+       DVBT_UPDATE_REG_2,
+       DVBT_BTHD_P3,
+       DVBT_BTHD_D3,
+       DVBT_FUNC4_REG0,
+       DVBT_FUNC4_REG1,
+       DVBT_FUNC4_REG2,
+       DVBT_FUNC4_REG3,
+       DVBT_FUNC4_REG4,
+       DVBT_FUNC4_REG5,
+       DVBT_FUNC4_REG6,
+       DVBT_FUNC4_REG7,
+       DVBT_FUNC4_REG8,
+       DVBT_FUNC4_REG9,
+       DVBT_FUNC4_REG10,
+       DVBT_FUNC5_REG0,
+       DVBT_FUNC5_REG1,
+       DVBT_FUNC5_REG2,
+       DVBT_FUNC5_REG3,
+       DVBT_FUNC5_REG4,
+       DVBT_FUNC5_REG5,
+       DVBT_FUNC5_REG6,
+       DVBT_FUNC5_REG7,
+       DVBT_FUNC5_REG8,
+       DVBT_FUNC5_REG9,
+       DVBT_FUNC5_REG10,
+       DVBT_FUNC5_REG11,
+       DVBT_FUNC5_REG12,
+       DVBT_FUNC5_REG13,
+       DVBT_FUNC5_REG14,
+       DVBT_FUNC5_REG15,
+       DVBT_FUNC5_REG16,
+       DVBT_FUNC5_REG17,
+       DVBT_FUNC5_REG18,
+       DVBT_AD7_SETTING,
+       DVBT_RSSI_R,
+       DVBT_ACI_DET_IND,
+       DVBT_REG_MON,
+       DVBT_REG_MONSEL,
+       DVBT_REG_GPE,
+       DVBT_REG_GPO,
+       DVBT_REG_4MSEL,
+       DVBT_TEST_REG_1,
+       DVBT_TEST_REG_2,
+       DVBT_TEST_REG_3,
+       DVBT_TEST_REG_4,
+       DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
+};
+
+#endif /* RTL2832_PRIV_H */
diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c
new file mode 100644 (file)
index 0000000..f71b062
--- /dev/null
@@ -0,0 +1,1029 @@
+/*
+    Samsung S5H1409 VSB/QAM demodulator driver
+
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s5h1409.h"
+
+struct s5h1409_state {
+
+       struct i2c_adapter *i2c;
+
+       /* configuration settings */
+       const struct s5h1409_config *config;
+
+       struct dvb_frontend frontend;
+
+       /* previous uncorrected block counter */
+       fe_modulation_t current_modulation;
+
+       u32 current_frequency;
+       int if_freq;
+
+       u32 is_qam_locked;
+
+       /* QAM tuning state goes through the following state transitions */
+#define QAM_STATE_UNTUNED 0
+#define QAM_STATE_TUNING_STARTED 1
+#define QAM_STATE_INTERLEAVE_SET 2
+#define QAM_STATE_QAM_OPTIMIZED_L1 3
+#define QAM_STATE_QAM_OPTIMIZED_L2 4
+#define QAM_STATE_QAM_OPTIMIZED_L3 5
+       u8  qam_state;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+#define dprintk        if (debug) printk
+
+/* Register values to initialise the demod, this will set VSB by default */
+static struct init_tab {
+       u8      reg;
+       u16     data;
+} init_tab[] = {
+       { 0x00, 0x0071, },
+       { 0x01, 0x3213, },
+       { 0x09, 0x0025, },
+       { 0x1c, 0x001d, },
+       { 0x1f, 0x002d, },
+       { 0x20, 0x001d, },
+       { 0x22, 0x0022, },
+       { 0x23, 0x0020, },
+       { 0x29, 0x110f, },
+       { 0x2a, 0x10b4, },
+       { 0x2b, 0x10ae, },
+       { 0x2c, 0x0031, },
+       { 0x31, 0x010d, },
+       { 0x32, 0x0100, },
+       { 0x44, 0x0510, },
+       { 0x54, 0x0104, },
+       { 0x58, 0x2222, },
+       { 0x59, 0x1162, },
+       { 0x5a, 0x3211, },
+       { 0x5d, 0x0370, },
+       { 0x5e, 0x0296, },
+       { 0x61, 0x0010, },
+       { 0x63, 0x4a00, },
+       { 0x65, 0x0800, },
+       { 0x71, 0x0003, },
+       { 0x72, 0x0470, },
+       { 0x81, 0x0002, },
+       { 0x82, 0x0600, },
+       { 0x86, 0x0002, },
+       { 0x8a, 0x2c38, },
+       { 0x8b, 0x2a37, },
+       { 0x92, 0x302f, },
+       { 0x93, 0x3332, },
+       { 0x96, 0x000c, },
+       { 0x99, 0x0101, },
+       { 0x9c, 0x2e37, },
+       { 0x9d, 0x2c37, },
+       { 0x9e, 0x2c37, },
+       { 0xab, 0x0100, },
+       { 0xac, 0x1003, },
+       { 0xad, 0x103f, },
+       { 0xe2, 0x0100, },
+       { 0xe3, 0x1000, },
+       { 0x28, 0x1010, },
+       { 0xb1, 0x000e, },
+};
+
+/* VSB SNR lookup table */
+static struct vsb_snr_tab {
+       u16     val;
+       u16     data;
+} vsb_snr_tab[] = {
+       {  924, 300, },
+       {  923, 300, },
+       {  918, 295, },
+       {  915, 290, },
+       {  911, 285, },
+       {  906, 280, },
+       {  901, 275, },
+       {  896, 270, },
+       {  891, 265, },
+       {  885, 260, },
+       {  879, 255, },
+       {  873, 250, },
+       {  864, 245, },
+       {  858, 240, },
+       {  850, 235, },
+       {  841, 230, },
+       {  832, 225, },
+       {  823, 220, },
+       {  812, 215, },
+       {  802, 210, },
+       {  788, 205, },
+       {  778, 200, },
+       {  767, 195, },
+       {  753, 190, },
+       {  740, 185, },
+       {  725, 180, },
+       {  707, 175, },
+       {  689, 170, },
+       {  671, 165, },
+       {  656, 160, },
+       {  637, 155, },
+       {  616, 150, },
+       {  542, 145, },
+       {  519, 140, },
+       {  507, 135, },
+       {  497, 130, },
+       {  492, 125, },
+       {  474, 120, },
+       {  300, 111, },
+       {    0,   0, },
+};
+
+/* QAM64 SNR lookup table */
+static struct qam64_snr_tab {
+       u16     val;
+       u16     data;
+} qam64_snr_tab[] = {
+       {    1,   0, },
+       {   12, 300, },
+       {   15, 290, },
+       {   18, 280, },
+       {   22, 270, },
+       {   23, 268, },
+       {   24, 266, },
+       {   25, 264, },
+       {   27, 262, },
+       {   28, 260, },
+       {   29, 258, },
+       {   30, 256, },
+       {   32, 254, },
+       {   33, 252, },
+       {   34, 250, },
+       {   35, 249, },
+       {   36, 248, },
+       {   37, 247, },
+       {   38, 246, },
+       {   39, 245, },
+       {   40, 244, },
+       {   41, 243, },
+       {   42, 241, },
+       {   43, 240, },
+       {   44, 239, },
+       {   45, 238, },
+       {   46, 237, },
+       {   47, 236, },
+       {   48, 235, },
+       {   49, 234, },
+       {   50, 233, },
+       {   51, 232, },
+       {   52, 231, },
+       {   53, 230, },
+       {   55, 229, },
+       {   56, 228, },
+       {   57, 227, },
+       {   58, 226, },
+       {   59, 225, },
+       {   60, 224, },
+       {   62, 223, },
+       {   63, 222, },
+       {   65, 221, },
+       {   66, 220, },
+       {   68, 219, },
+       {   69, 218, },
+       {   70, 217, },
+       {   72, 216, },
+       {   73, 215, },
+       {   75, 214, },
+       {   76, 213, },
+       {   78, 212, },
+       {   80, 211, },
+       {   81, 210, },
+       {   83, 209, },
+       {   84, 208, },
+       {   85, 207, },
+       {   87, 206, },
+       {   89, 205, },
+       {   91, 204, },
+       {   93, 203, },
+       {   95, 202, },
+       {   96, 201, },
+       {  104, 200, },
+       {  255,   0, },
+};
+
+/* QAM256 SNR lookup table */
+static struct qam256_snr_tab {
+       u16     val;
+       u16     data;
+} qam256_snr_tab[] = {
+       {    1,   0, },
+       {   12, 400, },
+       {   13, 390, },
+       {   15, 380, },
+       {   17, 360, },
+       {   19, 350, },
+       {   22, 348, },
+       {   23, 346, },
+       {   24, 344, },
+       {   25, 342, },
+       {   26, 340, },
+       {   27, 336, },
+       {   28, 334, },
+       {   29, 332, },
+       {   30, 330, },
+       {   31, 328, },
+       {   32, 326, },
+       {   33, 325, },
+       {   34, 322, },
+       {   35, 320, },
+       {   37, 318, },
+       {   39, 316, },
+       {   40, 314, },
+       {   41, 312, },
+       {   42, 310, },
+       {   43, 308, },
+       {   46, 306, },
+       {   47, 304, },
+       {   49, 302, },
+       {   51, 300, },
+       {   53, 298, },
+       {   54, 297, },
+       {   55, 296, },
+       {   56, 295, },
+       {   57, 294, },
+       {   59, 293, },
+       {   60, 292, },
+       {   61, 291, },
+       {   63, 290, },
+       {   64, 289, },
+       {   65, 288, },
+       {   66, 287, },
+       {   68, 286, },
+       {   69, 285, },
+       {   71, 284, },
+       {   72, 283, },
+       {   74, 282, },
+       {   75, 281, },
+       {   76, 280, },
+       {   77, 279, },
+       {   78, 278, },
+       {   81, 277, },
+       {   83, 276, },
+       {   84, 275, },
+       {   86, 274, },
+       {   87, 273, },
+       {   89, 272, },
+       {   90, 271, },
+       {   92, 270, },
+       {   93, 269, },
+       {   95, 268, },
+       {   96, 267, },
+       {   98, 266, },
+       {  100, 265, },
+       {  102, 264, },
+       {  104, 263, },
+       {  105, 262, },
+       {  106, 261, },
+       {  110, 260, },
+       {  255,   0, },
+};
+
+/* 8 bit registers, 16 bit values */
+static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data)
+{
+       int ret;
+       u8 buf[] = { reg, data >> 8,  data & 0xff };
+
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+                              .flags = 0, .buf = buf, .len = 3 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "
+                      "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0, 0 };
+
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0,
+                 .buf = b0, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD,
+                 .buf = b1, .len = 2 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk("%s: readreg error (ret == %i)\n", __func__, ret);
+       return (b1[0] << 8) | b1[1];
+}
+
+static int s5h1409_softreset(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       s5h1409_writereg(state, 0xf5, 0);
+       s5h1409_writereg(state, 0xf5, 1);
+       state->is_qam_locked = 0;
+       state->qam_state = QAM_STATE_UNTUNED;
+       return 0;
+}
+
+#define S5H1409_VSB_IF_FREQ 5380
+#define S5H1409_QAM_IF_FREQ (state->config->qam_if)
+
+static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d KHz)\n", __func__, KHz);
+
+       switch (KHz) {
+       case 4000:
+               s5h1409_writereg(state, 0x87, 0x014b);
+               s5h1409_writereg(state, 0x88, 0x0cb5);
+               s5h1409_writereg(state, 0x89, 0x03e2);
+               break;
+       case 5380:
+       case 44000:
+       default:
+               s5h1409_writereg(state, 0x87, 0x01be);
+               s5h1409_writereg(state, 0x88, 0x0436);
+               s5h1409_writereg(state, 0x89, 0x054d);
+               break;
+       }
+       state->if_freq = KHz;
+
+       return 0;
+}
+
+static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, inverted);
+
+       if (inverted == 1)
+               return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
+       else
+               return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
+}
+
+static int s5h1409_enable_modulation(struct dvb_frontend *fe,
+                                    fe_modulation_t m)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(0x%08x)\n", __func__, m);
+
+       switch (m) {
+       case VSB_8:
+               dprintk("%s() VSB_8\n", __func__);
+               if (state->if_freq != S5H1409_VSB_IF_FREQ)
+                       s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);
+               s5h1409_writereg(state, 0xf4, 0);
+               break;
+       case QAM_64:
+       case QAM_256:
+       case QAM_AUTO:
+               dprintk("%s() QAM_AUTO (64/256)\n", __func__);
+               if (state->if_freq != S5H1409_QAM_IF_FREQ)
+                       s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
+               s5h1409_writereg(state, 0xf4, 1);
+               s5h1409_writereg(state, 0x85, 0x110);
+               break;
+       default:
+               dprintk("%s() Invalid modulation\n", __func__);
+               return -EINVAL;
+       }
+
+       state->current_modulation = m;
+       s5h1409_softreset(fe);
+
+       return 0;
+}
+
+static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (enable)
+               return s5h1409_writereg(state, 0xf3, 1);
+       else
+               return s5h1409_writereg(state, 0xf3, 0);
+}
+
+static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (enable)
+               return s5h1409_writereg(state, 0xe3,
+                       s5h1409_readreg(state, 0xe3) | 0x1100);
+       else
+               return s5h1409_writereg(state, 0xe3,
+                       s5h1409_readreg(state, 0xe3) & 0xfeff);
+}
+
+static int s5h1409_sleep(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       return s5h1409_writereg(state, 0xf2, enable);
+}
+
+static int s5h1409_register_reset(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       return s5h1409_writereg(state, 0xfa, 0);
+}
+
+static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg;
+
+       if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
+               /* We should not perform amhum optimization until
+                  the interleave mode has been configured */
+               return;
+       }
+
+       if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
+               /* We've already reached the maximum optimization level, so
+                  dont bother banging on the status registers */
+               return;
+       }
+
+       /* QAM EQ lock check */
+       reg = s5h1409_readreg(state, 0xf0);
+
+       if ((reg >> 13) & 0x1) {
+               reg &= 0xff;
+
+               s5h1409_writereg(state, 0x96, 0x000c);
+               if (reg < 0x68) {
+                       if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
+                               dprintk("%s() setting QAM state to OPT_L3\n",
+                                       __func__);
+                               s5h1409_writereg(state, 0x93, 0x3130);
+                               s5h1409_writereg(state, 0x9e, 0x2836);
+                               state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
+                       }
+               } else {
+                       if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
+                               dprintk("%s() setting QAM state to OPT_L2\n",
+                                       __func__);
+                               s5h1409_writereg(state, 0x93, 0x3332);
+                               s5h1409_writereg(state, 0x9e, 0x2c37);
+                               state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
+                       }
+               }
+
+       } else {
+               if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
+                       dprintk("%s() setting QAM state to OPT_L1\n", __func__);
+                       s5h1409_writereg(state, 0x96, 0x0008);
+                       s5h1409_writereg(state, 0x93, 0x3332);
+                       s5h1409_writereg(state, 0x9e, 0x2c37);
+                       state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
+               }
+       }
+}
+
+static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg;
+
+       if (state->is_qam_locked)
+               return;
+
+       /* QAM EQ lock check */
+       reg = s5h1409_readreg(state, 0xf0);
+
+       if ((reg >> 13) & 0x1) {
+
+               state->is_qam_locked = 1;
+               reg &= 0xff;
+
+               s5h1409_writereg(state, 0x96, 0x00c);
+               if ((reg < 0x38) || (reg > 0x68)) {
+                       s5h1409_writereg(state, 0x93, 0x3332);
+                       s5h1409_writereg(state, 0x9e, 0x2c37);
+               } else {
+                       s5h1409_writereg(state, 0x93, 0x3130);
+                       s5h1409_writereg(state, 0x9e, 0x2836);
+               }
+
+       } else {
+               s5h1409_writereg(state, 0x96, 0x0008);
+               s5h1409_writereg(state, 0x93, 0x3332);
+               s5h1409_writereg(state, 0x9e, 0x2c37);
+       }
+}
+
+static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg, reg1, reg2;
+
+       if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
+               /* We've done the optimization already */
+               return;
+       }
+
+       reg = s5h1409_readreg(state, 0xf1);
+
+       /* Master lock */
+       if ((reg >> 15) & 0x1) {
+               if (state->qam_state == QAM_STATE_UNTUNED ||
+                   state->qam_state == QAM_STATE_TUNING_STARTED) {
+                       dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
+                               __func__);
+                       reg1 = s5h1409_readreg(state, 0xb2);
+                       reg2 = s5h1409_readreg(state, 0xad);
+
+                       s5h1409_writereg(state, 0x96, 0x0020);
+                       s5h1409_writereg(state, 0xad,
+                               (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
+                       state->qam_state = QAM_STATE_INTERLEAVE_SET;
+               }
+       } else {
+               if (state->qam_state == QAM_STATE_UNTUNED) {
+                       dprintk("%s() setting QAM state to TUNING_STARTED\n",
+                               __func__);
+                       s5h1409_writereg(state, 0x96, 0x08);
+                       s5h1409_writereg(state, 0xab,
+                               s5h1409_readreg(state, 0xab) | 0x1001);
+                       state->qam_state = QAM_STATE_TUNING_STARTED;
+               }
+       }
+}
+
+static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg, reg1, reg2;
+
+       reg = s5h1409_readreg(state, 0xf1);
+
+       /* Master lock */
+       if ((reg >> 15) & 0x1) {
+               if (state->qam_state != 2) {
+                       state->qam_state = 2;
+                       reg1 = s5h1409_readreg(state, 0xb2);
+                       reg2 = s5h1409_readreg(state, 0xad);
+
+                       s5h1409_writereg(state, 0x96, 0x20);
+                       s5h1409_writereg(state, 0xad,
+                               (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
+                       s5h1409_writereg(state, 0xab,
+                               s5h1409_readreg(state, 0xab) & 0xeffe);
+               }
+       } else {
+               if (state->qam_state != 1) {
+                       state->qam_state = 1;
+                       s5h1409_writereg(state, 0x96, 0x08);
+                       s5h1409_writereg(state, 0xab,
+                               s5h1409_readreg(state, 0xab) | 0x1001);
+               }
+       }
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int s5h1409_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+       s5h1409_softreset(fe);
+
+       state->current_frequency = p->frequency;
+
+       s5h1409_enable_modulation(fe, p->modulation);
+
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* Issue a reset to the demod so it knows to resync against the
+          newly tuned frequency */
+       s5h1409_softreset(fe);
+
+       /* Optimize the demod for QAM */
+       if (state->current_modulation != VSB_8) {
+               /* This almost certainly applies to all boards, but for now
+                  only do it for the HVR-1600.  Once the other boards are
+                  tested, the "legacy" versions can just go away */
+               if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+                       s5h1409_set_qam_interleave_mode(fe);
+                       s5h1409_set_qam_amhum_mode(fe);
+               } else {
+                       s5h1409_set_qam_amhum_mode_legacy(fe);
+                       s5h1409_set_qam_interleave_mode_legacy(fe);
+               }
+       }
+
+       return 0;
+}
+
+static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, mode);
+
+       val = s5h1409_readreg(state, 0xac) & 0xcfff;
+       switch (mode) {
+       case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
+               val |= 0x0000;
+               break;
+       case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
+               dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
+               val |= 0x1000;
+               break;
+       case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
+               val |= 0x2000;
+               break;
+       case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
+               val |= 0x3000;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Configure MPEG Signal Timing charactistics */
+       return s5h1409_writereg(state, 0xac, val);
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+static int s5h1409_init(struct dvb_frontend *fe)
+{
+       int i;
+
+       struct s5h1409_state *state = fe->demodulator_priv;
+       dprintk("%s()\n", __func__);
+
+       s5h1409_sleep(fe, 0);
+       s5h1409_register_reset(fe);
+
+       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+               s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
+
+       /* The datasheet says that after initialisation, VSB is default */
+       state->current_modulation = VSB_8;
+
+       /* Optimize for the HVR-1600 if appropriate.  Note that some of these
+          may get folded into the generic case after testing with other
+          devices */
+       if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+               /* VSB AGC REF */
+               s5h1409_writereg(state, 0x09, 0x0050);
+
+               /* Unknown but Windows driver does it... */
+               s5h1409_writereg(state, 0x21, 0x0001);
+               s5h1409_writereg(state, 0x50, 0x030e);
+
+               /* QAM AGC REF */
+               s5h1409_writereg(state, 0x82, 0x0800);
+       }
+
+       if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
+               s5h1409_writereg(state, 0xab,
+                       s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
+       else
+               s5h1409_writereg(state, 0xab,
+                       s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */
+
+       s5h1409_set_spectralinversion(fe, state->config->inversion);
+       s5h1409_set_if_freq(fe, state->if_freq);
+       s5h1409_set_gpio(fe, state->config->gpio);
+       s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing);
+       s5h1409_softreset(fe);
+
+       /* Note: Leaving the I2C gate closed. */
+       s5h1409_i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg;
+       u32 tuner_status = 0;
+
+       *status = 0;
+
+       /* Optimize the demod for QAM */
+       if (state->current_modulation != VSB_8) {
+               /* This almost certainly applies to all boards, but for now
+                  only do it for the HVR-1600.  Once the other boards are
+                  tested, the "legacy" versions can just go away */
+               if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
+                       s5h1409_set_qam_interleave_mode(fe);
+                       s5h1409_set_qam_amhum_mode(fe);
+               }
+       }
+
+       /* Get the demodulator status */
+       reg = s5h1409_readreg(state, 0xf1);
+       if (reg & 0x1000)
+               *status |= FE_HAS_VITERBI;
+       if (reg & 0x8000)
+               *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+       switch (state->config->status_mode) {
+       case S5H1409_DEMODLOCKING:
+               if (*status & FE_HAS_VITERBI)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       case S5H1409_TUNERLOCKING:
+               /* Get the tuner status */
+               if (fe->ops.tuner_ops.get_status) {
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 1);
+
+                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               if (tuner_status)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       }
+
+       dprintk("%s() status 0x%08x\n", __func__, *status);
+
+       return 0;
+}
+
+static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+               if (v < qam256_snr_tab[i].val) {
+                       *snr = qam256_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+               if (v < qam64_snr_tab[i].val) {
+                       *snr = qam64_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+               if (v > vsb_snr_tab[i].val) {
+                       *snr = vsb_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       dprintk("%s() snr=%d\n", __func__, *snr);
+       return ret;
+}
+
+static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       u16 reg;
+       dprintk("%s()\n", __func__);
+
+       switch (state->current_modulation) {
+       case QAM_64:
+               reg = s5h1409_readreg(state, 0xf0) & 0xff;
+               return s5h1409_qam64_lookup_snr(fe, snr, reg);
+       case QAM_256:
+               reg = s5h1409_readreg(state, 0xf0) & 0xff;
+               return s5h1409_qam256_lookup_snr(fe, snr, reg);
+       case VSB_8:
+               reg = s5h1409_readreg(state, 0xf1) & 0x3ff;
+               return s5h1409_vsb_lookup_snr(fe, snr, reg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
+                                       u16 *signal_strength)
+{
+       /* borrowed from lgdt330x.c
+        *
+        * Calculate strength from SNR up to 35dB
+        * Even though the SNR can go higher than 35dB,
+        * there is some comfort factor in having a range of
+        * strong signals that can show at 100%
+        */
+       u16 snr;
+       u32 tmp;
+       int ret = s5h1409_read_snr(fe, &snr);
+
+       *signal_strength = 0;
+
+       if (0 == ret) {
+               /* The following calculation method was chosen
+                * purely for the sake of code re-use from the
+                * other demod drivers that use this method */
+
+               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
+               tmp = (snr * ((1 << 24) / 10));
+
+               /* Convert from 8.24 fixed-point to
+                * scale the range 0 - 35*2^24 into 0 - 65535*/
+               if (tmp >= 8960 * 0x10000)
+                       *signal_strength = 0xffff;
+               else
+                       *signal_strength = tmp / 8960;
+       }
+
+       return ret;
+}
+
+static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       *ucblocks = s5h1409_readreg(state, 0xb5);
+
+       return 0;
+}
+
+static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       return s5h1409_read_ucblocks(fe, ber);
+}
+
+static int s5h1409_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1409_state *state = fe->demodulator_priv;
+
+       p->frequency = state->current_frequency;
+       p->modulation = state->current_modulation;
+
+       return 0;
+}
+
+static int s5h1409_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void s5h1409_release(struct dvb_frontend *fe)
+{
+       struct s5h1409_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1409_ops;
+
+struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct s5h1409_state *state = NULL;
+       u16 reg;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->current_modulation = 0;
+       state->if_freq = S5H1409_VSB_IF_FREQ;
+
+       /* check if the demod exists */
+       reg = s5h1409_readreg(state, 0x04);
+       if ((reg != 0x0066) && (reg != 0x007f))
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s5h1409_ops,
+              sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       if (s5h1409_init(&state->frontend) != 0) {
+               printk(KERN_ERR "%s: Failed to initialize correctly\n",
+                       __func__);
+               goto error;
+       }
+
+       /* Note: Leaving the I2C gate open here. */
+       s5h1409_i2c_gate_ctrl(&state->frontend, 1);
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(s5h1409_attach);
+
+static struct dvb_frontend_ops s5h1409_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name                   = "Samsung S5H1409 QAM/8VSB Frontend",
+               .frequency_min          = 54000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .init                 = s5h1409_init,
+       .i2c_gate_ctrl        = s5h1409_i2c_gate_ctrl,
+       .set_frontend         = s5h1409_set_frontend,
+       .get_frontend         = s5h1409_get_frontend,
+       .get_tune_settings    = s5h1409_get_tune_settings,
+       .read_status          = s5h1409_read_status,
+       .read_ber             = s5h1409_read_ber,
+       .read_signal_strength = s5h1409_read_signal_strength,
+       .read_snr             = s5h1409_read_snr,
+       .read_ucblocks        = s5h1409_read_ucblocks,
+       .release              = s5h1409_release,
+};
+
+MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb-frontends/s5h1409.h b/drivers/media/dvb-frontends/s5h1409.h
new file mode 100644 (file)
index 0000000..91f2ebd
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+    Samsung S5H1409 VSB/QAM demodulator driver
+
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __S5H1409_H__
+#define __S5H1409_H__
+
+#include <linux/dvb/frontend.h>
+
+struct s5h1409_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* serial/parallel output */
+#define S5H1409_PARALLEL_OUTPUT 0
+#define S5H1409_SERIAL_OUTPUT   1
+       u8 output_mode;
+
+       /* GPIO Setting */
+#define S5H1409_GPIO_OFF 0
+#define S5H1409_GPIO_ON  1
+       u8 gpio;
+
+       /* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */
+       u16 qam_if;
+
+       /* Spectral Inversion */
+#define S5H1409_INVERSION_OFF 0
+#define S5H1409_INVERSION_ON  1
+       u8 inversion;
+
+       /* Return lock status based on tuner lock, or demod lock */
+#define S5H1409_TUNERLOCKING 0
+#define S5H1409_DEMODLOCKING 1
+       u8 status_mode;
+
+       /* MPEG signal timing */
+#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
+#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
+#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
+#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
+       u16 mpeg_timing;
+
+       /* HVR-1600 optimizations (to better work with MXL5005s)
+          Note: some of these are likely to be folded into the generic driver
+          after being regression tested with other boards */
+#define S5H1409_HVR1600_NOOPTIMIZE 0
+#define S5H1409_HVR1600_OPTIMIZE   1
+       u8 hvr1600_opt;
+};
+
+#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
+       && defined(MODULE))
+extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *s5h1409_attach(
+       const struct s5h1409_config *config,
+       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_S5H1409 */
+
+#endif /* __S5H1409_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
new file mode 100644 (file)
index 0000000..6cc4b7a
--- /dev/null
@@ -0,0 +1,951 @@
+/*
+    Samsung S5H1411 VSB/QAM demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s5h1411.h"
+
+struct s5h1411_state {
+
+       struct i2c_adapter *i2c;
+
+       /* configuration settings */
+       const struct s5h1411_config *config;
+
+       struct dvb_frontend frontend;
+
+       fe_modulation_t current_modulation;
+       unsigned int first_tune:1;
+
+       u32 current_frequency;
+       int if_freq;
+
+       u8 inversion;
+};
+
+static int debug;
+
+#define dprintk(arg...) do {   \
+       if (debug)              \
+               printk(arg);    \
+       } while (0)
+
+/* Register values to initialise the demod, defaults to VSB */
+static struct init_tab {
+       u8      addr;
+       u8      reg;
+       u16     data;
+} init_tab[] = {
+       { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, },
+       { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
+       { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
+       { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
+       { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, },
+       { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
+       { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
+       { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
+       { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, },
+       { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, },
+       { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, },
+       { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, },
+       { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, },
+       { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, },
+       { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, },
+       { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, },
+       { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, },
+       { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, },
+       { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, },
+       { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, },
+       { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, },
+       { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, },
+       { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, },
+       { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, },
+       { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, },
+       { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, },
+       { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, },
+       { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, },
+       { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, },
+       { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, },
+       { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, },
+       { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, },
+       { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, },
+       { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, },
+       { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, },
+       { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, },
+       { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, },
+       { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, },
+       { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, },
+       { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
+       { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
+       { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
+       { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
+       { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
+       { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
+       { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, },
+       { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, },
+       { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, },
+       { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, },
+       { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, },
+       { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, },
+       { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, },
+       { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, },
+       { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, },
+       { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, },
+       { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, },
+       { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, },
+       { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, },
+       { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, },
+       { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, },
+       { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, },
+       { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, },
+       { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, },
+       { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, },
+       { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, },
+       { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, },
+       { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, },
+       { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, },
+       { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, },
+       { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, },
+       { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, },
+       { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, },
+       { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, },
+       { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, },
+       { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, },
+       { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, },
+       { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, },
+       { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, },
+       { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, },
+       { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, },
+};
+
+/* VSB SNR lookup table */
+static struct vsb_snr_tab {
+       u16     val;
+       u16     data;
+} vsb_snr_tab[] = {
+       {  0x39f, 300, },
+       {  0x39b, 295, },
+       {  0x397, 290, },
+       {  0x394, 285, },
+       {  0x38f, 280, },
+       {  0x38b, 275, },
+       {  0x387, 270, },
+       {  0x382, 265, },
+       {  0x37d, 260, },
+       {  0x377, 255, },
+       {  0x370, 250, },
+       {  0x36a, 245, },
+       {  0x364, 240, },
+       {  0x35b, 235, },
+       {  0x353, 230, },
+       {  0x349, 225, },
+       {  0x340, 320, },
+       {  0x337, 215, },
+       {  0x327, 210, },
+       {  0x31b, 205, },
+       {  0x310, 200, },
+       {  0x302, 195, },
+       {  0x2f3, 190, },
+       {  0x2e4, 185, },
+       {  0x2d7, 180, },
+       {  0x2cd, 175, },
+       {  0x2bb, 170, },
+       {  0x2a9, 165, },
+       {  0x29e, 160, },
+       {  0x284, 155, },
+       {  0x27a, 150, },
+       {  0x260, 145, },
+       {  0x23a, 140, },
+       {  0x224, 135, },
+       {  0x213, 130, },
+       {  0x204, 125, },
+       {  0x1fe, 120, },
+       {      0,   0, },
+};
+
+/* QAM64 SNR lookup table */
+static struct qam64_snr_tab {
+       u16     val;
+       u16     data;
+} qam64_snr_tab[] = {
+       {  0x0001,   0, },
+       {  0x0af0, 300, },
+       {  0x0d80, 290, },
+       {  0x10a0, 280, },
+       {  0x14b5, 270, },
+       {  0x1590, 268, },
+       {  0x1680, 266, },
+       {  0x17b0, 264, },
+       {  0x18c0, 262, },
+       {  0x19b0, 260, },
+       {  0x1ad0, 258, },
+       {  0x1d00, 256, },
+       {  0x1da0, 254, },
+       {  0x1ef0, 252, },
+       {  0x2050, 250, },
+       {  0x20f0, 249, },
+       {  0x21d0, 248, },
+       {  0x22b0, 247, },
+       {  0x23a0, 246, },
+       {  0x2470, 245, },
+       {  0x24f0, 244, },
+       {  0x25a0, 243, },
+       {  0x26c0, 242, },
+       {  0x27b0, 241, },
+       {  0x28d0, 240, },
+       {  0x29b0, 239, },
+       {  0x2ad0, 238, },
+       {  0x2ba0, 237, },
+       {  0x2c80, 236, },
+       {  0x2d20, 235, },
+       {  0x2e00, 234, },
+       {  0x2f10, 233, },
+       {  0x3050, 232, },
+       {  0x3190, 231, },
+       {  0x3300, 230, },
+       {  0x3340, 229, },
+       {  0x3200, 228, },
+       {  0x3550, 227, },
+       {  0x3610, 226, },
+       {  0x3600, 225, },
+       {  0x3700, 224, },
+       {  0x3800, 223, },
+       {  0x3920, 222, },
+       {  0x3a20, 221, },
+       {  0x3b30, 220, },
+       {  0x3d00, 219, },
+       {  0x3e00, 218, },
+       {  0x4000, 217, },
+       {  0x4100, 216, },
+       {  0x4300, 215, },
+       {  0x4400, 214, },
+       {  0x4600, 213, },
+       {  0x4700, 212, },
+       {  0x4800, 211, },
+       {  0x4a00, 210, },
+       {  0x4b00, 209, },
+       {  0x4d00, 208, },
+       {  0x4f00, 207, },
+       {  0x5050, 206, },
+       {  0x5200, 205, },
+       {  0x53c0, 204, },
+       {  0x5450, 203, },
+       {  0x5650, 202, },
+       {  0x5820, 201, },
+       {  0x6000, 200, },
+       {  0xffff,   0, },
+};
+
+/* QAM256 SNR lookup table */
+static struct qam256_snr_tab {
+       u16     val;
+       u16     data;
+} qam256_snr_tab[] = {
+       {  0x0001,   0, },
+       {  0x0970, 400, },
+       {  0x0a90, 390, },
+       {  0x0b90, 380, },
+       {  0x0d90, 370, },
+       {  0x0ff0, 360, },
+       {  0x1240, 350, },
+       {  0x1345, 348, },
+       {  0x13c0, 346, },
+       {  0x14c0, 344, },
+       {  0x1500, 342, },
+       {  0x1610, 340, },
+       {  0x1700, 338, },
+       {  0x1800, 336, },
+       {  0x18b0, 334, },
+       {  0x1900, 332, },
+       {  0x1ab0, 330, },
+       {  0x1bc0, 328, },
+       {  0x1cb0, 326, },
+       {  0x1db0, 324, },
+       {  0x1eb0, 322, },
+       {  0x2030, 320, },
+       {  0x2200, 318, },
+       {  0x2280, 316, },
+       {  0x2410, 314, },
+       {  0x25b0, 312, },
+       {  0x27a0, 310, },
+       {  0x2840, 308, },
+       {  0x29d0, 306, },
+       {  0x2b10, 304, },
+       {  0x2d30, 302, },
+       {  0x2f20, 300, },
+       {  0x30c0, 298, },
+       {  0x3260, 297, },
+       {  0x32c0, 296, },
+       {  0x3300, 295, },
+       {  0x33b0, 294, },
+       {  0x34b0, 293, },
+       {  0x35a0, 292, },
+       {  0x3650, 291, },
+       {  0x3800, 290, },
+       {  0x3900, 289, },
+       {  0x3a50, 288, },
+       {  0x3b30, 287, },
+       {  0x3cb0, 286, },
+       {  0x3e20, 285, },
+       {  0x3fa0, 284, },
+       {  0x40a0, 283, },
+       {  0x41c0, 282, },
+       {  0x42f0, 281, },
+       {  0x44a0, 280, },
+       {  0x4600, 279, },
+       {  0x47b0, 278, },
+       {  0x4900, 277, },
+       {  0x4a00, 276, },
+       {  0x4ba0, 275, },
+       {  0x4d00, 274, },
+       {  0x4f00, 273, },
+       {  0x5000, 272, },
+       {  0x51f0, 272, },
+       {  0x53a0, 270, },
+       {  0x5520, 269, },
+       {  0x5700, 268, },
+       {  0x5800, 267, },
+       {  0x5a00, 266, },
+       {  0x5c00, 265, },
+       {  0x5d00, 264, },
+       {  0x5f00, 263, },
+       {  0x6000, 262, },
+       {  0x6200, 261, },
+       {  0x6400, 260, },
+       {  0xffff,   0, },
+};
+
+/* 8 bit registers, 16 bit values */
+static int s5h1411_writereg(struct s5h1411_state *state,
+       u8 addr, u8 reg, u16 data)
+{
+       int ret;
+       u8 buf[] = { reg, data >> 8,  data & 0xff };
+
+       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
+                      "ret == %i)\n", __func__, addr, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0, 0 };
+
+       struct i2c_msg msg[] = {
+               { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
+               { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+                       __func__, ret);
+       return (b1[0] << 8) | b1[1];
+}
+
+static int s5h1411_softreset(struct dvb_frontend *fe)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0);
+       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1);
+       return 0;
+}
+
+static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d KHz)\n", __func__, KHz);
+
+       switch (KHz) {
+       case 3250:
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
+               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
+               break;
+       case 3500:
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96);
+               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225);
+               break;
+       case 4000:
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e);
+               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd);
+               break;
+       default:
+               dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
+                       __func__, KHz);
+               /* no break, need to continue */
+       case 5380:
+       case 44000:
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655);
+               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4);
+               break;
+       }
+
+       state->if_freq = KHz;
+
+       return 0;
+}
+
+static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, mode);
+
+       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff;
+       switch (mode) {
+       case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
+               val |= 0x0000;
+               break;
+       case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
+               dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
+               val |= 0x1000;
+               break;
+       case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
+               val |= 0x2000;
+               break;
+       case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
+               val |= 0x3000;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Configure MPEG Signal Timing charactistics */
+       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val);
+}
+
+static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, inversion);
+       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000;
+
+       if (inversion == 1)
+               val |= 0x1000; /* Inverted */
+
+       state->inversion = inversion;
+       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
+}
+
+static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, serial);
+       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
+
+       if (serial == 1)
+               val |= 0x100;
+
+       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
+}
+
+static int s5h1411_enable_modulation(struct dvb_frontend *fe,
+                                    fe_modulation_t m)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s(0x%08x)\n", __func__, m);
+
+       if ((state->first_tune == 0) && (m == state->current_modulation)) {
+               dprintk("%s() Already at desired modulation.  Skipping...\n",
+                       __func__);
+               return 0;
+       }
+
+       switch (m) {
+       case VSB_8:
+               dprintk("%s() VSB_8\n", __func__);
+               s5h1411_set_if_freq(fe, state->config->vsb_if);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1);
+               break;
+       case QAM_64:
+       case QAM_256:
+       case QAM_AUTO:
+               dprintk("%s() QAM_AUTO (64/256)\n", __func__);
+               s5h1411_set_if_freq(fe, state->config->qam_if);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001);
+               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101);
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0);
+               break;
+       default:
+               dprintk("%s() Invalid modulation\n", __func__);
+               return -EINVAL;
+       }
+
+       state->current_modulation = m;
+       state->first_tune = 0;
+       s5h1411_softreset(fe);
+
+       return 0;
+}
+
+static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (enable)
+               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
+       else
+               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0);
+}
+
+static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 val;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02;
+
+       if (enable)
+               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0,
+                               val | 0x02);
+       else
+               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
+}
+
+static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __func__, enable);
+
+       if (enable)
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1);
+       else {
+               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0);
+               s5h1411_softreset(fe);
+       }
+
+       return 0;
+}
+
+static int s5h1411_sleep(struct dvb_frontend *fe)
+{
+       return s5h1411_set_powerstate(fe, 1);
+}
+
+static int s5h1411_register_reset(struct dvb_frontend *fe)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __func__);
+
+       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0);
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int s5h1411_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+       s5h1411_softreset(fe);
+
+       state->current_frequency = p->frequency;
+
+       s5h1411_enable_modulation(fe, p->modulation);
+
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               fe->ops.tuner_ops.set_params(fe);
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* Issue a reset to the demod so it knows to resync against the
+          newly tuned frequency */
+       s5h1411_softreset(fe);
+
+       return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+static int s5h1411_init(struct dvb_frontend *fe)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       int i;
+
+       dprintk("%s()\n", __func__);
+
+       s5h1411_set_powerstate(fe, 0);
+       s5h1411_register_reset(fe);
+
+       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+               s5h1411_writereg(state, init_tab[i].addr,
+                       init_tab[i].reg,
+                       init_tab[i].data);
+
+       /* The datasheet says that after initialisation, VSB is default */
+       state->current_modulation = VSB_8;
+
+       /* Although the datasheet says it's in VSB, empirical evidence
+          shows problems getting lock on the first tuning request.  Make
+          sure we call enable_modulation the first time around */
+       state->first_tune = 1;
+
+       if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
+               /* Serial */
+               s5h1411_set_serialmode(fe, 1);
+       else
+               /* Parallel */
+               s5h1411_set_serialmode(fe, 0);
+
+       s5h1411_set_spectralinversion(fe, state->config->inversion);
+       s5h1411_set_if_freq(fe, state->config->vsb_if);
+       s5h1411_set_gpio(fe, state->config->gpio);
+       s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing);
+       s5h1411_softreset(fe);
+
+       /* Note: Leaving the I2C gate closed. */
+       s5h1411_i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 reg;
+       u32 tuner_status = 0;
+
+       *status = 0;
+
+       /* Register F2 bit 15 = Master Lock, removed */
+
+       switch (state->current_modulation) {
+       case QAM_64:
+       case QAM_256:
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
+               if (reg & 0x10) /* QAM FEC Lock */
+                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+               if (reg & 0x100) /* QAM EQ Lock */
+                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+               break;
+       case VSB_8:
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
+               if (reg & 0x1000) /* FEC Lock */
+                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+               if (reg & 0x2000) /* EQ Lock */
+                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53);
+               if (reg & 0x1) /* AFC Lock */
+                       *status |= FE_HAS_SIGNAL;
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (state->config->status_mode) {
+       case S5H1411_DEMODLOCKING:
+               if (*status & FE_HAS_VITERBI)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       case S5H1411_TUNERLOCKING:
+               /* Get the tuner status */
+               if (fe->ops.tuner_ops.get_status) {
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 1);
+
+                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               if (tuner_status)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       }
+
+       dprintk("%s() status 0x%08x\n", __func__, *status);
+
+       return 0;
+}
+
+static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+               if (v < qam256_snr_tab[i].val) {
+                       *snr = qam256_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+               if (v < qam64_snr_tab[i].val) {
+                       *snr = qam64_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+               if (v > vsb_snr_tab[i].val) {
+                       *snr = vsb_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       dprintk("%s() snr=%d\n", __func__, *snr);
+       return ret;
+}
+
+static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       u16 reg;
+       dprintk("%s()\n", __func__);
+
+       switch (state->current_modulation) {
+       case QAM_64:
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
+               return s5h1411_qam64_lookup_snr(fe, snr, reg);
+       case QAM_256:
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
+               return s5h1411_qam256_lookup_snr(fe, snr, reg);
+       case VSB_8:
+               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR,
+                       0xf2) & 0x3ff;
+               return s5h1411_vsb_lookup_snr(fe, snr, reg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
+       u16 *signal_strength)
+{
+       /* borrowed from lgdt330x.c
+        *
+        * Calculate strength from SNR up to 35dB
+        * Even though the SNR can go higher than 35dB,
+        * there is some comfort factor in having a range of
+        * strong signals that can show at 100%
+        */
+       u16 snr;
+       u32 tmp;
+       int ret = s5h1411_read_snr(fe, &snr);
+
+       *signal_strength = 0;
+
+       if (0 == ret) {
+               /* The following calculation method was chosen
+                * purely for the sake of code re-use from the
+                * other demod drivers that use this method */
+
+               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
+               tmp = (snr * ((1 << 24) / 10));
+
+               /* Convert from 8.24 fixed-point to
+                * scale the range 0 - 35*2^24 into 0 - 65535*/
+               if (tmp >= 8960 * 0x10000)
+                       *signal_strength = 0xffff;
+               else
+                       *signal_strength = tmp / 8960;
+       }
+
+       return ret;
+}
+
+static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9);
+
+       return 0;
+}
+
+static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       return s5h1411_read_ucblocks(fe, ber);
+}
+
+static int s5h1411_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1411_state *state = fe->demodulator_priv;
+
+       p->frequency = state->current_frequency;
+       p->modulation = state->current_modulation;
+
+       return 0;
+}
+
+static int s5h1411_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void s5h1411_release(struct dvb_frontend *fe)
+{
+       struct s5h1411_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1411_ops;
+
+struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct s5h1411_state *state = NULL;
+       u16 reg;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->current_modulation = VSB_8;
+       state->inversion = state->config->inversion;
+
+       /* check if the demod exists */
+       reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05);
+       if (reg != 0x0066)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s5h1411_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->frontend.demodulator_priv = state;
+
+       if (s5h1411_init(&state->frontend) != 0) {
+               printk(KERN_ERR "%s: Failed to initialize correctly\n",
+                       __func__);
+               goto error;
+       }
+
+       /* Note: Leaving the I2C gate open here. */
+       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
+
+       /* Put the device into low-power mode until first use */
+       s5h1411_set_powerstate(&state->frontend, 1);
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(s5h1411_attach);
+
+static struct dvb_frontend_ops s5h1411_ops = {
+       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+       .info = {
+               .name                   = "Samsung S5H1411 QAM/8VSB Frontend",
+               .frequency_min          = 54000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .init                 = s5h1411_init,
+       .sleep                = s5h1411_sleep,
+       .i2c_gate_ctrl        = s5h1411_i2c_gate_ctrl,
+       .set_frontend         = s5h1411_set_frontend,
+       .get_frontend         = s5h1411_get_frontend,
+       .get_tune_settings    = s5h1411_get_tune_settings,
+       .read_status          = s5h1411_read_status,
+       .read_ber             = s5h1411_read_ber,
+       .read_signal_strength = s5h1411_read_signal_strength,
+       .read_snr             = s5h1411_read_snr,
+       .read_ucblocks        = s5h1411_read_ucblocks,
+       .release              = s5h1411_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb-frontends/s5h1411.h b/drivers/media/dvb-frontends/s5h1411.h
new file mode 100644 (file)
index 0000000..45ec0f8
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+    Samsung S5H1411 VSB/QAM demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __S5H1411_H__
+#define __S5H1411_H__
+
+#include <linux/dvb/frontend.h>
+
+#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
+#define S5H1411_I2C_QAM_ADDR (0x34 >> 1)
+
+struct s5h1411_config {
+
+       /* serial/parallel output */
+#define S5H1411_PARALLEL_OUTPUT 0
+#define S5H1411_SERIAL_OUTPUT   1
+       u8 output_mode;
+
+       /* GPIO Setting */
+#define S5H1411_GPIO_OFF 0
+#define S5H1411_GPIO_ON  1
+       u8 gpio;
+
+       /* MPEG signal timing */
+#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
+#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
+#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
+#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
+       u16 mpeg_timing;
+
+       /* IF Freq for QAM and VSB in KHz */
+#define S5H1411_IF_3250  3250
+#define S5H1411_IF_3500  3500
+#define S5H1411_IF_4000  4000
+#define S5H1411_IF_5380  5380
+#define S5H1411_IF_44000 44000
+#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000
+#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000
+       u16 qam_if;
+       u16 vsb_if;
+
+       /* Spectral Inversion */
+#define S5H1411_INVERSION_OFF 0
+#define S5H1411_INVERSION_ON  1
+       u8 inversion;
+
+       /* Return lock status based on tuner lock, or demod lock */
+#define S5H1411_TUNERLOCKING 0
+#define S5H1411_DEMODLOCKING 1
+       u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_S5H1411) || \
+       (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
+extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *s5h1411_attach(
+       const struct s5h1411_config *config,
+       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_S5H1411 */
+
+#endif /* __S5H1411_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
new file mode 100644 (file)
index 0000000..e2fec9e
--- /dev/null
@@ -0,0 +1,960 @@
+/*
+ * Driver for
+ *    Samsung S5H1420 and
+ *    PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
+
+#include <linux/i2c.h>
+
+
+#include "dvb_frontend.h"
+#include "s5h1420.h"
+#include "s5h1420_priv.h"
+
+#define TONE_FREQ 22000
+
+struct s5h1420_state {
+       struct i2c_adapter* i2c;
+       const struct s5h1420_config* config;
+
+       struct dvb_frontend frontend;
+       struct i2c_adapter tuner_i2c_adapter;
+
+       u8 CON_1_val;
+
+       u8 postlocked:1;
+       u32 fclk;
+       u32 tunedfreq;
+       fe_code_rate_t fec_inner;
+       u32 symbol_rate;
+
+       /* FIXME: ugly workaround for flexcop's incapable i2c-controller
+        * it does not support repeated-start, workaround: write addr-1
+        * and then read
+        */
+       u8 shadow[256];
+};
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+                                    struct dvb_frontend_tune_settings* fesettings);
+
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debugging");
+
+#define dprintk(x...) do { \
+       if (debug) \
+               printk(KERN_DEBUG "S5H1420: " x); \
+} while (0)
+
+static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
+{
+       int ret;
+       u8 b[2];
+       struct i2c_msg msg[] = {
+               { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 },
+               { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 },
+       };
+
+       b[0] = (reg - 1) & 0xff;
+       b[1] = state->shadow[(reg - 1) & 0xff];
+
+       if (state->config->repeated_start_workaround) {
+               ret = i2c_transfer(state->i2c, msg, 3);
+               if (ret != 3)
+                       return ret;
+       } else {
+               ret = i2c_transfer(state->i2c, &msg[1], 1);
+               if (ret != 1)
+                       return ret;
+               ret = i2c_transfer(state->i2c, &msg[2], 1);
+               if (ret != 1)
+                       return ret;
+       }
+
+       /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */
+
+       return b[0];
+}
+
+static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+       int err;
+
+       /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+       state->shadow[reg] = data;
+
+       return 0;
+}
+
+static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       dprintk("enter %s\n", __func__);
+
+       switch(voltage) {
+       case SEC_VOLTAGE_13:
+               s5h1420_writereg(state, 0x3c,
+                                (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
+               break;
+
+       case SEC_VOLTAGE_18:
+               s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
+               break;
+
+       case SEC_VOLTAGE_OFF:
+               s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
+               break;
+       }
+
+       dprintk("leave %s\n", __func__);
+       return 0;
+}
+
+static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       dprintk("enter %s\n", __func__);
+       switch(tone) {
+       case SEC_TONE_ON:
+               s5h1420_writereg(state, 0x3b,
+                                (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
+               break;
+
+       case SEC_TONE_OFF:
+               s5h1420_writereg(state, 0x3b,
+                                (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
+               break;
+       }
+       dprintk("leave %s\n", __func__);
+
+       return 0;
+}
+
+static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd* cmd)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       u8 val;
+       int i;
+       unsigned long timeout;
+       int result = 0;
+
+       dprintk("enter %s\n", __func__);
+       if (cmd->msg_len > 8)
+               return -EINVAL;
+
+       /* setup for DISEQC */
+       val = s5h1420_readreg(state, 0x3b);
+       s5h1420_writereg(state, 0x3b, 0x02);
+       msleep(15);
+
+       /* write the DISEQC command bytes */
+       for(i=0; i< cmd->msg_len; i++) {
+               s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
+       }
+
+       /* kick off transmission */
+       s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
+                                     ((cmd->msg_len-1) << 4) | 0x08);
+
+       /* wait for transmission to complete */
+       timeout = jiffies + ((100*HZ) / 1000);
+       while(time_before(jiffies, timeout)) {
+               if (!(s5h1420_readreg(state, 0x3b) & 0x08))
+                       break;
+
+               msleep(5);
+       }
+       if (time_after(jiffies, timeout))
+               result = -ETIMEDOUT;
+
+       /* restore original settings */
+       s5h1420_writereg(state, 0x3b, val);
+       msleep(15);
+       dprintk("leave %s\n", __func__);
+       return result;
+}
+
+static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
+                                    struct dvb_diseqc_slave_reply* reply)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       u8 val;
+       int i;
+       int length;
+       unsigned long timeout;
+       int result = 0;
+
+       /* setup for DISEQC receive */
+       val = s5h1420_readreg(state, 0x3b);
+       s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
+       msleep(15);
+
+       /* wait for reception to complete */
+       timeout = jiffies + ((reply->timeout*HZ) / 1000);
+       while(time_before(jiffies, timeout)) {
+               if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
+                       break;
+
+               msleep(5);
+       }
+       if (time_after(jiffies, timeout)) {
+               result = -ETIMEDOUT;
+               goto exit;
+       }
+
+       /* check error flag - FIXME: not sure what this does - docs do not describe
+        * beyond "error flag for diseqc receive data :( */
+       if (s5h1420_readreg(state, 0x49)) {
+               result = -EIO;
+               goto exit;
+       }
+
+       /* check length */
+       length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
+       if (length > sizeof(reply->msg)) {
+               result = -EOVERFLOW;
+               goto exit;
+       }
+       reply->msg_len = length;
+
+       /* extract data */
+       for(i=0; i< length; i++) {
+               reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
+       }
+
+exit:
+       /* restore original settings */
+       s5h1420_writereg(state, 0x3b, val);
+       msleep(15);
+       return result;
+}
+
+static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       u8 val;
+       int result = 0;
+       unsigned long timeout;
+
+       /* setup for tone burst */
+       val = s5h1420_readreg(state, 0x3b);
+       s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
+
+       /* set value for B position if requested */
+       if (minicmd == SEC_MINI_B) {
+               s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
+       }
+       msleep(15);
+
+       /* start transmission */
+       s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
+
+       /* wait for transmission to complete */
+       timeout = jiffies + ((100*HZ) / 1000);
+       while(time_before(jiffies, timeout)) {
+               if (!(s5h1420_readreg(state, 0x3b) & 0x08))
+                       break;
+
+               msleep(5);
+       }
+       if (time_after(jiffies, timeout))
+               result = -ETIMEDOUT;
+
+       /* restore original settings */
+       s5h1420_writereg(state, 0x3b, val);
+       msleep(15);
+       return result;
+}
+
+static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
+{
+       u8 val;
+       fe_status_t status = 0;
+
+       val = s5h1420_readreg(state, 0x14);
+       if (val & 0x02)
+               status |=  FE_HAS_SIGNAL;
+       if (val & 0x01)
+               status |=  FE_HAS_CARRIER;
+       val = s5h1420_readreg(state, 0x36);
+       if (val & 0x01)
+               status |=  FE_HAS_VITERBI;
+       if (val & 0x20)
+               status |=  FE_HAS_SYNC;
+       if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
+               status |=  FE_HAS_LOCK;
+
+       return status;
+}
+
+static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("enter %s\n", __func__);
+
+       if (status == NULL)
+               return -EINVAL;
+
+       /* determine lock state */
+       *status = s5h1420_get_status_bits(state);
+
+       /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
+       the inversion, wait a bit and check again */
+       if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) {
+               val = s5h1420_readreg(state, Vit10);
+               if ((val & 0x07) == 0x03) {
+                       if (val & 0x08)
+                               s5h1420_writereg(state, Vit09, 0x13);
+                       else
+                               s5h1420_writereg(state, Vit09, 0x1b);
+
+                       /* wait a bit then update lock status */
+                       mdelay(200);
+                       *status = s5h1420_get_status_bits(state);
+               }
+       }
+
+       /* perform post lock setup */
+       if ((*status & FE_HAS_LOCK) && !state->postlocked) {
+
+               /* calculate the data rate */
+               u32 tmp = s5h1420_getsymbolrate(state);
+               switch (s5h1420_readreg(state, Vit10) & 0x07) {
+               case 0: tmp = (tmp * 2 * 1) / 2; break;
+               case 1: tmp = (tmp * 2 * 2) / 3; break;
+               case 2: tmp = (tmp * 2 * 3) / 4; break;
+               case 3: tmp = (tmp * 2 * 5) / 6; break;
+               case 4: tmp = (tmp * 2 * 6) / 7; break;
+               case 5: tmp = (tmp * 2 * 7) / 8; break;
+               }
+
+               if (tmp == 0) {
+                       printk(KERN_ERR "s5h1420: avoided division by 0\n");
+                       tmp = 1;
+               }
+               tmp = state->fclk / tmp;
+
+
+               /* set the MPEG_CLK_INTL for the calculated data rate */
+               if (tmp < 2)
+                       val = 0x00;
+               else if (tmp < 5)
+                       val = 0x01;
+               else if (tmp < 9)
+                       val = 0x02;
+               else if (tmp < 13)
+                       val = 0x03;
+               else if (tmp < 17)
+                       val = 0x04;
+               else if (tmp < 25)
+                       val = 0x05;
+               else if (tmp < 33)
+                       val = 0x06;
+               else
+                       val = 0x07;
+               dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val);
+
+               s5h1420_writereg(state, FEC01, 0x18);
+               s5h1420_writereg(state, FEC01, 0x10);
+               s5h1420_writereg(state, FEC01, val);
+
+               /* Enable "MPEG_Out" */
+               val = s5h1420_readreg(state, Mpeg02);
+               s5h1420_writereg(state, Mpeg02, val | (1 << 6));
+
+               /* kicker disable */
+               val = s5h1420_readreg(state, QPSK01) & 0x7f;
+               s5h1420_writereg(state, QPSK01, val);
+
+               /* DC freeze TODO it was never activated by default or it can stay activated */
+
+               if (s5h1420_getsymbolrate(state) >= 20000000) {
+                       s5h1420_writereg(state, Loop04, 0x8a);
+                       s5h1420_writereg(state, Loop05, 0x6a);
+               } else {
+                       s5h1420_writereg(state, Loop04, 0x58);
+                       s5h1420_writereg(state, Loop05, 0x27);
+               }
+
+               /* post-lock processing has been done! */
+               state->postlocked = 1;
+       }
+
+       dprintk("leave %s\n", __func__);
+
+       return 0;
+}
+
+static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       s5h1420_writereg(state, 0x46, 0x1d);
+       mdelay(25);
+
+       *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+       return 0;
+}
+
+static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       u8 val = s5h1420_readreg(state, 0x15);
+
+       *strength =  (u16) ((val << 8) | val);
+
+       return 0;
+}
+
+static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       s5h1420_writereg(state, 0x46, 0x1f);
+       mdelay(25);
+
+       *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+       return 0;
+}
+
+static void s5h1420_reset(struct s5h1420_state* state)
+{
+       dprintk("%s\n", __func__);
+       s5h1420_writereg (state, 0x01, 0x08);
+       s5h1420_writereg (state, 0x01, 0x00);
+       udelay(10);
+}
+
+static void s5h1420_setsymbolrate(struct s5h1420_state* state,
+                                 struct dtv_frontend_properties *p)
+{
+       u8 v;
+       u64 val;
+
+       dprintk("enter %s\n", __func__);
+
+       val = ((u64) p->symbol_rate / 1000ULL) * (1ULL<<24);
+       if (p->symbol_rate < 29000000)
+               val *= 2;
+       do_div(val, (state->fclk / 1000));
+
+       dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
+
+       v = s5h1420_readreg(state, Loop01);
+       s5h1420_writereg(state, Loop01, v & 0x7f);
+       s5h1420_writereg(state, Tnco01, val >> 16);
+       s5h1420_writereg(state, Tnco02, val >> 8);
+       s5h1420_writereg(state, Tnco03, val & 0xff);
+       s5h1420_writereg(state, Loop01,  v | 0x80);
+       dprintk("leave %s\n", __func__);
+}
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
+{
+       return state->symbol_rate;
+}
+
+static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
+{
+       int val;
+       u8 v;
+
+       dprintk("enter %s\n", __func__);
+
+       /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+        * divide fclk by 1000000 to get the correct value. */
+       val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
+
+       dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val);
+
+       v = s5h1420_readreg(state, Loop01);
+       s5h1420_writereg(state, Loop01, v & 0xbf);
+       s5h1420_writereg(state, Pnco01, val >> 16);
+       s5h1420_writereg(state, Pnco02, val >> 8);
+       s5h1420_writereg(state, Pnco03, val & 0xff);
+       s5h1420_writereg(state, Loop01, v | 0x40);
+       dprintk("leave %s\n", __func__);
+}
+
+static int s5h1420_getfreqoffset(struct s5h1420_state* state)
+{
+       int val;
+
+       s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
+       val  = s5h1420_readreg(state, 0x0e) << 16;
+       val |= s5h1420_readreg(state, 0x0f) << 8;
+       val |= s5h1420_readreg(state, 0x10);
+       s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+
+       if (val & 0x800000)
+               val |= 0xff000000;
+
+       /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+        * divide fclk by 1000000 to get the correct value. */
+       val = (((-val) * (state->fclk/1000000)) / (1<<24));
+
+       return val;
+}
+
+static void s5h1420_setfec_inversion(struct s5h1420_state* state,
+                                    struct dtv_frontend_properties *p)
+{
+       u8 inversion = 0;
+       u8 vit08, vit09;
+
+       dprintk("enter %s\n", __func__);
+
+       if (p->inversion == INVERSION_OFF)
+               inversion = state->config->invert ? 0x08 : 0;
+       else if (p->inversion == INVERSION_ON)
+               inversion = state->config->invert ? 0 : 0x08;
+
+       if ((p->fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
+               vit08 = 0x3f;
+               vit09 = 0;
+       } else {
+               switch (p->fec_inner) {
+               case FEC_1_2:
+                       vit08 = 0x01; vit09 = 0x10;
+                       break;
+
+               case FEC_2_3:
+                       vit08 = 0x02; vit09 = 0x11;
+                       break;
+
+               case FEC_3_4:
+                       vit08 = 0x04; vit09 = 0x12;
+                       break;
+
+               case FEC_5_6:
+                       vit08 = 0x08; vit09 = 0x13;
+                       break;
+
+               case FEC_6_7:
+                       vit08 = 0x10; vit09 = 0x14;
+                       break;
+
+               case FEC_7_8:
+                       vit08 = 0x20; vit09 = 0x15;
+                       break;
+
+               default:
+                       return;
+               }
+       }
+       vit09 |= inversion;
+       dprintk("fec: %02x %02x\n", vit08, vit09);
+       s5h1420_writereg(state, Vit08, vit08);
+       s5h1420_writereg(state, Vit09, vit09);
+       dprintk("leave %s\n", __func__);
+}
+
+static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
+{
+       switch(s5h1420_readreg(state, 0x32) & 0x07) {
+       case 0:
+               return FEC_1_2;
+
+       case 1:
+               return FEC_2_3;
+
+       case 2:
+               return FEC_3_4;
+
+       case 3:
+               return FEC_5_6;
+
+       case 4:
+               return FEC_6_7;
+
+       case 5:
+               return FEC_7_8;
+       }
+
+       return FEC_NONE;
+}
+
+static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
+{
+       if (s5h1420_readreg(state, 0x32) & 0x08)
+               return INVERSION_ON;
+
+       return INVERSION_OFF;
+}
+
+static int s5h1420_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1420_state* state = fe->demodulator_priv;
+       int frequency_delta;
+       struct dvb_frontend_tune_settings fesettings;
+
+       dprintk("enter %s\n", __func__);
+
+       /* check if we should do a fast-tune */
+       s5h1420_get_tune_settings(fe, &fesettings);
+       frequency_delta = p->frequency - state->tunedfreq;
+       if ((frequency_delta > -fesettings.max_drift) &&
+                       (frequency_delta < fesettings.max_drift) &&
+                       (frequency_delta != 0) &&
+                       (state->fec_inner == p->fec_inner) &&
+                       (state->symbol_rate == p->symbol_rate)) {
+
+               if (fe->ops.tuner_ops.set_params) {
+                       fe->ops.tuner_ops.set_params(fe);
+                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               if (fe->ops.tuner_ops.get_frequency) {
+                       u32 tmp;
+                       fe->ops.tuner_ops.get_frequency(fe, &tmp);
+                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+                       s5h1420_setfreqoffset(state, p->frequency - tmp);
+               } else {
+                       s5h1420_setfreqoffset(state, 0);
+               }
+               dprintk("simple tune\n");
+               return 0;
+       }
+       dprintk("tuning demod\n");
+
+       /* first of all, software reset */
+       s5h1420_reset(state);
+
+       /* set s5h1420 fclk PLL according to desired symbol rate */
+       if (p->symbol_rate > 33000000)
+               state->fclk = 80000000;
+       else if (p->symbol_rate > 28500000)
+               state->fclk = 59000000;
+       else if (p->symbol_rate > 25000000)
+               state->fclk = 86000000;
+       else if (p->symbol_rate > 1900000)
+               state->fclk = 88000000;
+       else
+               state->fclk = 44000000;
+
+       dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
+       s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8);
+       s5h1420_writereg(state, PLL02, 0x40);
+       s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
+
+       /* TODO DC offset removal, config parameter ? */
+       if (p->symbol_rate > 29000000)
+               s5h1420_writereg(state, QPSK01, 0xae | 0x10);
+       else
+               s5h1420_writereg(state, QPSK01, 0xac | 0x10);
+
+       /* set misc registers */
+       s5h1420_writereg(state, CON_1, 0x00);
+       s5h1420_writereg(state, QPSK02, 0x00);
+       s5h1420_writereg(state, Pre01, 0xb0);
+
+       s5h1420_writereg(state, Loop01, 0xF0);
+       s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */
+       s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */
+       if (p->symbol_rate > 20000000)
+               s5h1420_writereg(state, Loop04, 0x79);
+       else
+               s5h1420_writereg(state, Loop04, 0x58);
+       s5h1420_writereg(state, Loop05, 0x6b);
+
+       if (p->symbol_rate >= 8000000)
+               s5h1420_writereg(state, Post01, (0 << 6) | 0x10);
+       else if (p->symbol_rate >= 4000000)
+               s5h1420_writereg(state, Post01, (1 << 6) | 0x10);
+       else
+               s5h1420_writereg(state, Post01, (3 << 6) | 0x10);
+
+       s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */
+
+       s5h1420_writereg(state, Sync01, 0x33);
+       s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity);
+       s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */
+       s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */
+
+       s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */
+       s5h1420_writereg(state, DiS03, 0x00);
+       s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */
+
+       /* set tuner PLL */
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+               s5h1420_setfreqoffset(state, 0);
+       }
+
+       /* set the reset of the parameters */
+       s5h1420_setsymbolrate(state, p);
+       s5h1420_setfec_inversion(state, p);
+
+       /* start QPSK */
+       s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1);
+
+       state->fec_inner = p->fec_inner;
+       state->symbol_rate = p->symbol_rate;
+       state->postlocked = 0;
+       state->tunedfreq = p->frequency;
+
+       dprintk("leave %s\n", __func__);
+       return 0;
+}
+
+static int s5h1420_get_frontend(struct dvb_frontend* fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
+       p->inversion = s5h1420_getinversion(state);
+       p->symbol_rate = s5h1420_getsymbolrate(state);
+       p->fec_inner = s5h1420_getfec(state);
+
+       return 0;
+}
+
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+                                    struct dvb_frontend_tune_settings* fesettings)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       if (p->symbol_rate > 20000000) {
+               fesettings->min_delay_ms = 50;
+               fesettings->step_size = 2000;
+               fesettings->max_drift = 8000;
+       } else if (p->symbol_rate > 12000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 1500;
+               fesettings->max_drift = 9000;
+       } else if (p->symbol_rate > 8000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 1000;
+               fesettings->max_drift = 8000;
+       } else if (p->symbol_rate > 4000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 500;
+               fesettings->max_drift = 7000;
+       } else if (p->symbol_rate > 2000000) {
+               fesettings->min_delay_ms = 200;
+               fesettings->step_size = (p->symbol_rate / 8000);
+               fesettings->max_drift = 14 * fesettings->step_size;
+       } else {
+               fesettings->min_delay_ms = 200;
+               fesettings->step_size = (p->symbol_rate / 8000);
+               fesettings->max_drift = 18 * fesettings->step_size;
+       }
+
+       return 0;
+}
+
+static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       if (enable)
+               return s5h1420_writereg(state, 0x02, state->CON_1_val | 1);
+       else
+               return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe);
+}
+
+static int s5h1420_init (struct dvb_frontend* fe)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+
+       /* disable power down and do reset */
+       state->CON_1_val = state->config->serial_mpeg << 4;
+       s5h1420_writereg(state, 0x02, state->CON_1_val);
+       msleep(10);
+       s5h1420_reset(state);
+
+       return 0;
+}
+
+static int s5h1420_sleep(struct dvb_frontend* fe)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       state->CON_1_val = 0x12;
+       return s5h1420_writereg(state, 0x02, state->CON_1_val);
+}
+
+static void s5h1420_release(struct dvb_frontend* fe)
+{
+       struct s5h1420_state* state = fe->demodulator_priv;
+       i2c_del_adapter(&state->tuner_i2c_adapter);
+       kfree(state);
+}
+
+static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+       struct s5h1420_state *state = i2c_get_adapdata(i2c_adap);
+       struct i2c_msg m[1 + num];
+       u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */
+
+       memset(m, 0, sizeof(struct i2c_msg) * (1 + num));
+
+       m[0].addr = state->config->demod_address;
+       m[0].buf  = tx_open;
+       m[0].len  = 2;
+
+       memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
+
+       return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO;
+}
+
+static struct i2c_algorithm s5h1420_tuner_i2c_algo = {
+       .master_xfer   = s5h1420_tuner_i2c_tuner_xfer,
+       .functionality = s5h1420_tuner_i2c_func,
+};
+
+struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       struct s5h1420_state *state = fe->demodulator_priv;
+       return &state->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter);
+
+static struct dvb_frontend_ops s5h1420_ops;
+
+struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       /* allocate memory for the internal state */
+       struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
+       u8 i;
+
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->postlocked = 0;
+       state->fclk = 88000000;
+       state->tunedfreq = 0;
+       state->fec_inner = FEC_NONE;
+       state->symbol_rate = 0;
+
+       /* check if the demod is there + identify it */
+       i = s5h1420_readreg(state, ID01);
+       if (i != 0x03)
+               goto error;
+
+       memset(state->shadow, 0xff, sizeof(state->shadow));
+
+       for (i = 0; i < 0x50; i++)
+               state->shadow[i] = s5h1420_readreg(state, i);
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* create tuner i2c adapter */
+       strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
+               sizeof(state->tuner_i2c_adapter.name));
+       state->tuner_i2c_adapter.algo      = &s5h1420_tuner_i2c_algo;
+       state->tuner_i2c_adapter.algo_data = NULL;
+       i2c_set_adapdata(&state->tuner_i2c_adapter, state);
+       if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
+               printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n");
+               goto error;
+       }
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(s5h1420_attach);
+
+static struct dvb_frontend_ops s5h1420_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name     = "Samsung S5H1420/PnpNetwork PN1010 DVB-S",
+               .frequency_min    = 950000,
+               .frequency_max    = 2150000,
+               .frequency_stepsize = 125,     /* kHz for QPSK frontends */
+               .frequency_tolerance  = 29500,
+               .symbol_rate_min  = 1000000,
+               .symbol_rate_max  = 45000000,
+               /*  .symbol_rate_tolerance  = ???,*/
+               .caps = FE_CAN_INVERSION_AUTO |
+               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+               FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+               FE_CAN_QPSK
+       },
+
+       .release = s5h1420_release,
+
+       .init = s5h1420_init,
+       .sleep = s5h1420_sleep,
+       .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl,
+
+       .set_frontend = s5h1420_set_frontend,
+       .get_frontend = s5h1420_get_frontend,
+       .get_tune_settings = s5h1420_get_tune_settings,
+
+       .read_status = s5h1420_read_status,
+       .read_ber = s5h1420_read_ber,
+       .read_signal_strength = s5h1420_read_signal_strength,
+       .read_ucblocks = s5h1420_read_ucblocks,
+
+       .diseqc_send_master_cmd = s5h1420_send_master_cmd,
+       .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
+       .diseqc_send_burst = s5h1420_send_burst,
+       .set_tone = s5h1420_set_tone,
+       .set_voltage = s5h1420_set_voltage,
+};
+
+MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver");
+MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/s5h1420.h b/drivers/media/dvb-frontends/s5h1420.h
new file mode 100644 (file)
index 0000000..ff30813
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Driver for
+ *    Samsung S5H1420 and
+ *    PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef S5H1420_H
+#define S5H1420_H
+
+#include <linux/dvb/frontend.h>
+
+struct s5h1420_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* does the inversion require inversion? */
+       u8 invert:1;
+
+       u8 repeated_start_workaround:1;
+       u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */
+
+       u8 serial_mpeg:1;
+};
+
+#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
+extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+            struct i2c_adapter *i2c);
+extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe);
+#else
+static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+                                          struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       return NULL;
+}
+#endif // CONFIG_DVB_S5H1420
+
+#endif // S5H1420_H
diff --git a/drivers/media/dvb-frontends/s5h1420_priv.h b/drivers/media/dvb-frontends/s5h1420_priv.h
new file mode 100644 (file)
index 0000000..d9c58d2
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Driver for
+ *    Samsung S5H1420 and
+ *    PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef S5H1420_PRIV
+#define S5H1420_PRIV
+
+#include <asm/types.h>
+
+enum s5h1420_register {
+       ID01      = 0x00,
+       CON_0     = 0x01,
+       CON_1     = 0x02,
+       PLL01     = 0x03,
+       PLL02     = 0x04,
+       QPSK01    = 0x05,
+       QPSK02    = 0x06,
+       Pre01     = 0x07,
+       Post01    = 0x08,
+       Loop01    = 0x09,
+       Loop02    = 0x0a,
+       Loop03    = 0x0b,
+       Loop04    = 0x0c,
+       Loop05    = 0x0d,
+       Pnco01    = 0x0e,
+       Pnco02    = 0x0f,
+       Pnco03    = 0x10,
+       Tnco01    = 0x11,
+       Tnco02    = 0x12,
+       Tnco03    = 0x13,
+       Monitor01 = 0x14,
+       Monitor02 = 0x15,
+       Monitor03 = 0x16,
+       Monitor04 = 0x17,
+       Monitor05 = 0x18,
+       Monitor06 = 0x19,
+       Monitor07 = 0x1a,
+       Monitor12 = 0x1f,
+
+       FEC01     = 0x22,
+       Soft01    = 0x23,
+       Soft02    = 0x24,
+       Soft03    = 0x25,
+       Soft04    = 0x26,
+       Soft05    = 0x27,
+       Soft06    = 0x28,
+       Vit01     = 0x29,
+       Vit02     = 0x2a,
+       Vit03     = 0x2b,
+       Vit04     = 0x2c,
+       Vit05     = 0x2d,
+       Vit06     = 0x2e,
+       Vit07     = 0x2f,
+       Vit08     = 0x30,
+       Vit09     = 0x31,
+       Vit10     = 0x32,
+       Vit11     = 0x33,
+       Vit12     = 0x34,
+       Sync01    = 0x35,
+       Sync02    = 0x36,
+       Rs01      = 0x37,
+       Mpeg01    = 0x38,
+       Mpeg02    = 0x39,
+       DiS01     = 0x3a,
+       DiS02     = 0x3b,
+       DiS03     = 0x3c,
+       DiS04     = 0x3d,
+       DiS05     = 0x3e,
+       DiS06     = 0x3f,
+       DiS07     = 0x40,
+       DiS08     = 0x41,
+       DiS09     = 0x42,
+       DiS10     = 0x43,
+       DiS11     = 0x44,
+       Rf01      = 0x45,
+       Err01     = 0x46,
+       Err02     = 0x47,
+       Err03     = 0x48,
+       Err04     = 0x49,
+};
+
+
+#endif
diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c
new file mode 100644 (file)
index 0000000..8352ce1
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ *  Samsung s5h1432 DVB-T demodulator driver
+ *
+ *  Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s5h1432.h"
+
+struct s5h1432_state {
+
+       struct i2c_adapter *i2c;
+
+       /* configuration settings */
+       const struct s5h1432_config *config;
+
+       struct dvb_frontend frontend;
+
+       fe_modulation_t current_modulation;
+       unsigned int first_tune:1;
+
+       u32 current_frequency;
+       int if_freq;
+
+       u8 inversion;
+};
+
+static int debug;
+
+#define dprintk(arg...) do {   \
+       if (debug)              \
+               printk(arg);    \
+       } while (0)
+
+static int s5h1432_writereg(struct s5h1432_state *state,
+                           u8 addr, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+
+       struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
+                      "ret == %i)\n", __func__, addr, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+
+       struct i2c_msg msg[] = {
+               {.addr = addr, .flags = 0, .buf = b0, .len = 1},
+               {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1}
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+                      __func__, ret);
+       return b1[0];
+}
+
+static int s5h1432_sleep(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe,
+                                        u32 bandwidth)
+{
+       struct s5h1432_state *state = fe->demodulator_priv;
+
+       u8 reg = 0;
+
+       /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */
+       reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E);
+       reg &= ~(0x0C);
+       switch (bandwidth) {
+       case 6:
+               reg |= 0x08;
+               break;
+       case 7:
+               reg |= 0x04;
+               break;
+       case 8:
+               reg |= 0x00;
+               break;
+       default:
+               return 0;
+       }
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg);
+       return 1;
+}
+
+static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz)
+{
+       struct s5h1432_state *state = fe->demodulator_priv;
+
+       switch (ifFreqHz) {
+       case TAIWAN_HI_IF_FREQ_44_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15);
+               break;
+       case EUROPE_HI_IF_FREQ_36_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40);
+               break;
+       case IF_FREQ_6_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0);
+               break;
+       case IF_FREQ_3point3_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
+               break;
+       case IF_FREQ_3point5_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED);
+               break;
+       case IF_FREQ_4_MHZ:
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA);
+               break;
+       default:
+               {
+                       u32 value = 0;
+                       value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 *
+                                       (u32) 32768) / (48 * 1000));
+                       printk(KERN_INFO
+                              "Default IFFreq %d :reg value = 0x%x\n",
+                              ifFreqHz, value);
+                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4,
+                                        (u8) value & 0xFF);
+                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5,
+                                        (u8) (value >> 8) & 0xFF);
+                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7,
+                                        (u8) (value >> 16) & 0xFF);
+                       break;
+               }
+
+       }
+
+       return 1;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int s5h1432_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u32 dvb_bandwidth = 8;
+       struct s5h1432_state *state = fe->demodulator_priv;
+
+       if (p->frequency == state->current_frequency) {
+               /*current_frequency = p->frequency; */
+               /*state->current_frequency = p->frequency; */
+       } else {
+               fe->ops.tuner_ops.set_params(fe);
+               msleep(300);
+               s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
+               switch (p->bandwidth_hz) {
+               case 6000000:
+                       dvb_bandwidth = 6;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               case 7000000:
+                       dvb_bandwidth = 7;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               case 8000000:
+                       dvb_bandwidth = 8;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               default:
+                       return 0;
+               }
+               /*fe->ops.tuner_ops.set_params(fe); */
+/*Soft Reset chip*/
+               msleep(30);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
+               msleep(30);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
+
+               s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
+               switch (p->bandwidth_hz) {
+               case 6000000:
+                       dvb_bandwidth = 6;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               case 7000000:
+                       dvb_bandwidth = 7;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               case 8000000:
+                       dvb_bandwidth = 8;
+                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
+                       break;
+               default:
+                       return 0;
+               }
+               /*fe->ops.tuner_ops.set_params(fe); */
+               /*Soft Reset chip*/
+               msleep(30);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
+               msleep(30);
+               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
+
+       }
+
+       state->current_frequency = p->frequency;
+
+       return 0;
+}
+
+static int s5h1432_init(struct dvb_frontend *fe)
+{
+       struct s5h1432_state *state = fe->demodulator_priv;
+
+       u8 reg = 0;
+       state->current_frequency = 0;
+       printk(KERN_INFO " s5h1432_init().\n");
+
+       /*Set VSB mode as default, this also does a soft reset */
+       /*Initialize registers */
+
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94);
+       /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00);
+
+       /*For NXP tuner*/
+
+       /*Set 3.3MHz as default IF frequency */
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
+       /* Set reg 0x1E to get the full dynamic range */
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31);
+
+       /* Mode setting in demod */
+       reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42);
+       reg |= 0x80;
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg);
+       /* Serial mode */
+
+       /* Soft Reset chip */
+
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
+       msleep(30);
+       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
+
+
+       return 0;
+}
+
+static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       return 0;
+}
+
+static int s5h1432_read_signal_strength(struct dvb_frontend *fe,
+                                       u16 *signal_strength)
+{
+       return 0;
+}
+
+static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       return 0;
+}
+
+static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+
+       return 0;
+}
+
+static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       return 0;
+}
+
+static int s5h1432_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       return 0;
+}
+
+static void s5h1432_release(struct dvb_frontend *fe)
+{
+       struct s5h1432_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1432_ops;
+
+struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct s5h1432_state *state = NULL;
+
+       printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->current_modulation = QAM_16;
+       state->inversion = state->config->inversion;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s5h1432_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(s5h1432_attach);
+
+static struct dvb_frontend_ops s5h1432_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+                .name = "Samsung s5h1432 DVB-T Frontend",
+                .frequency_min = 177000000,
+                .frequency_max = 858000000,
+                .frequency_stepsize = 166666,
+                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER},
+
+       .init = s5h1432_init,
+       .sleep = s5h1432_sleep,
+       .set_frontend = s5h1432_set_frontend,
+       .get_tune_settings = s5h1432_get_tune_settings,
+       .read_status = s5h1432_read_status,
+       .read_ber = s5h1432_read_ber,
+       .read_signal_strength = s5h1432_read_signal_strength,
+       .read_snr = s5h1432_read_snr,
+       .read_ucblocks = s5h1432_read_ucblocks,
+       .release = s5h1432_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver");
+MODULE_AUTHOR("Bill Liu");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/s5h1432.h b/drivers/media/dvb-frontends/s5h1432.h
new file mode 100644 (file)
index 0000000..b57438c
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  Samsung s5h1432 VSB/QAM demodulator driver
+ *
+ *  Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __S5H1432_H__
+#define __S5H1432_H__
+
+#include <linux/dvb/frontend.h>
+
+#define S5H1432_I2C_TOP_ADDR (0x02 >> 1)
+
+#define TAIWAN_HI_IF_FREQ_44_MHZ 44000000
+#define EUROPE_HI_IF_FREQ_36_MHZ 36000000
+#define IF_FREQ_6_MHZ             6000000
+#define IF_FREQ_3point3_MHZ       3300000
+#define IF_FREQ_3point5_MHZ       3500000
+#define IF_FREQ_4_MHZ             4000000
+
+struct s5h1432_config {
+
+       /* serial/parallel output */
+#define S5H1432_PARALLEL_OUTPUT 0
+#define S5H1432_SERIAL_OUTPUT   1
+       u8 output_mode;
+
+       /* GPIO Setting */
+#define S5H1432_GPIO_OFF 0
+#define S5H1432_GPIO_ON  1
+       u8 gpio;
+
+       /* MPEG signal timing */
+#define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
+#define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
+#define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
+#define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
+       u16 mpeg_timing;
+
+       /* IF Freq for QAM and VSB in KHz */
+#define S5H1432_IF_3250  3250
+#define S5H1432_IF_3500  3500
+#define S5H1432_IF_4000  4000
+#define S5H1432_IF_5380  5380
+#define S5H1432_IF_44000 44000
+#define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000
+#define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000
+       u16 qam_if;
+       u16 vsb_if;
+
+       /* Spectral Inversion */
+#define S5H1432_INVERSION_OFF 0
+#define S5H1432_INVERSION_ON  1
+       u8 inversion;
+
+       /* Return lock status based on tuner lock, or demod lock */
+#define S5H1432_TUNERLOCKING 0
+#define S5H1432_DEMODLOCKING 1
+       u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_S5H1432) || \
+       (defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE))
+extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config
+                                                 *config,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_s5h1432 */
+
+#endif /* __s5h1432_H__ */
diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c
new file mode 100644 (file)
index 0000000..cd2288c
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ *   Sharp VA3A5JZ921 One Seg Broadcast Module driver
+ *   This device is labeled as just S. 921 at the top of the frontend can
+ *
+ *   Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ *   Developed for Leadership SBTVD 1seg device sold in Brazil
+ *
+ *   Frontend module based on cx24123 driver, getting some info from
+ *     the old s921 driver.
+ *
+ *   FIXME: Need to port to DVB v5.2 API
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation version 2.
+ *
+ *   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.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "s921.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...)  do {                                              \
+       printk(KERN_ERR  "s921: " args);                                \
+} while (0)
+
+#define dprintk(args...)                                               \
+       do {                                                            \
+               if (debug) {                                            \
+                       printk(KERN_DEBUG "s921: %s: ", __func__);      \
+                       printk(args);                                   \
+               }                                                       \
+       } while (0)
+
+struct s921_state {
+       struct i2c_adapter *i2c;
+       const struct s921_config *config;
+
+       struct dvb_frontend frontend;
+
+       /* The Demod can't easily provide these, we cache them */
+       u32 currentfreq;
+};
+
+/*
+ * Various tuner defaults need to be established for a given frequency kHz.
+ * fixme: The bounds on the bands do not match the doc in real life.
+ * fixme: Some of them have been moved, other might need adjustment.
+ */
+static struct s921_bandselect_val {
+       u32 freq_low;
+       u8  band_reg;
+} s921_bandselect[] = {
+       {         0, 0x7b },
+       { 485140000, 0x5b },
+       { 515140000, 0x3b },
+       { 545140000, 0x1b },
+       { 599140000, 0xfb },
+       { 623140000, 0xdb },
+       { 659140000, 0xbb },
+       { 713140000, 0x9b },
+};
+
+struct regdata {
+       u8 reg;
+       u8 data;
+};
+
+static struct regdata s921_init[] = {
+       { 0x01, 0x80 },         /* Probably, a reset sequence */
+       { 0x01, 0x40 },
+       { 0x01, 0x80 },
+       { 0x01, 0x40 },
+
+       { 0x02, 0x00 },
+       { 0x03, 0x40 },
+       { 0x04, 0x01 },
+       { 0x05, 0x00 },
+       { 0x06, 0x00 },
+       { 0x07, 0x00 },
+       { 0x08, 0x00 },
+       { 0x09, 0x00 },
+       { 0x0a, 0x00 },
+       { 0x0b, 0x5a },
+       { 0x0c, 0x00 },
+       { 0x0d, 0x00 },
+       { 0x0f, 0x00 },
+       { 0x13, 0x1b },
+       { 0x14, 0x80 },
+       { 0x15, 0x40 },
+       { 0x17, 0x70 },
+       { 0x18, 0x01 },
+       { 0x19, 0x12 },
+       { 0x1a, 0x01 },
+       { 0x1b, 0x12 },
+       { 0x1c, 0xa0 },
+       { 0x1d, 0x00 },
+       { 0x1e, 0x0a },
+       { 0x1f, 0x08 },
+       { 0x20, 0x40 },
+       { 0x21, 0xff },
+       { 0x22, 0x4c },
+       { 0x23, 0x4e },
+       { 0x24, 0x4c },
+       { 0x25, 0x00 },
+       { 0x26, 0x00 },
+       { 0x27, 0xf4 },
+       { 0x28, 0x60 },
+       { 0x29, 0x88 },
+       { 0x2a, 0x40 },
+       { 0x2b, 0x40 },
+       { 0x2c, 0xff },
+       { 0x2d, 0x00 },
+       { 0x2e, 0xff },
+       { 0x2f, 0x00 },
+       { 0x30, 0x20 },
+       { 0x31, 0x06 },
+       { 0x32, 0x0c },
+       { 0x34, 0x0f },
+       { 0x37, 0xfe },
+       { 0x38, 0x00 },
+       { 0x39, 0x63 },
+       { 0x3a, 0x10 },
+       { 0x3b, 0x10 },
+       { 0x47, 0x00 },
+       { 0x49, 0xe5 },
+       { 0x4b, 0x00 },
+       { 0x50, 0xc0 },
+       { 0x52, 0x20 },
+       { 0x54, 0x5a },
+       { 0x55, 0x5b },
+       { 0x56, 0x40 },
+       { 0x57, 0x70 },
+       { 0x5c, 0x50 },
+       { 0x5d, 0x00 },
+       { 0x62, 0x17 },
+       { 0x63, 0x2f },
+       { 0x64, 0x6f },
+       { 0x68, 0x00 },
+       { 0x69, 0x89 },
+       { 0x6a, 0x00 },
+       { 0x6b, 0x00 },
+       { 0x6c, 0x00 },
+       { 0x6d, 0x00 },
+       { 0x6e, 0x00 },
+       { 0x70, 0x10 },
+       { 0x71, 0x00 },
+       { 0x75, 0x00 },
+       { 0x76, 0x30 },
+       { 0x77, 0x01 },
+       { 0xaf, 0x00 },
+       { 0xb0, 0xa0 },
+       { 0xb2, 0x3d },
+       { 0xb3, 0x25 },
+       { 0xb4, 0x8b },
+       { 0xb5, 0x4b },
+       { 0xb6, 0x3f },
+       { 0xb7, 0xff },
+       { 0xb8, 0xff },
+       { 0xb9, 0xfc },
+       { 0xba, 0x00 },
+       { 0xbb, 0x00 },
+       { 0xbc, 0x00 },
+       { 0xd0, 0x30 },
+       { 0xe4, 0x84 },
+       { 0xf0, 0x48 },
+       { 0xf1, 0x19 },
+       { 0xf2, 0x5a },
+       { 0xf3, 0x8e },
+       { 0xf4, 0x2d },
+       { 0xf5, 0x07 },
+       { 0xf6, 0x5a },
+       { 0xf7, 0xba },
+       { 0xf8, 0xd7 },
+};
+
+static struct regdata s921_prefreq[] = {
+       { 0x47, 0x60 },
+       { 0x68, 0x00 },
+       { 0x69, 0x89 },
+       { 0xf0, 0x48 },
+       { 0xf1, 0x19 },
+};
+
+static struct regdata s921_postfreq[] = {
+       { 0xf5, 0xae },
+       { 0xf6, 0xb7 },
+       { 0xf7, 0xba },
+       { 0xf8, 0xd7 },
+       { 0x68, 0x0a },
+       { 0x69, 0x09 },
+};
+
+static int s921_i2c_writereg(struct s921_state *state,
+                            u8 i2c_addr, int reg, int data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+       };
+       int rc;
+
+       rc = i2c_transfer(state->i2c, &msg, 1);
+       if (rc != 1) {
+               printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+                        " data == 0x%02x)\n", __func__, rc, reg, data);
+               return rc;
+       }
+
+       return 0;
+}
+
+static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
+                                struct regdata *rd, int size)
+{
+       int i, rc;
+
+       for (i = 0; i < size; i++) {
+               rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
+               if (rc < 0)
+                       return rc;
+       }
+       return 0;
+}
+
+static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
+{
+       u8 val;
+       int rc;
+       struct i2c_msg msg[] = {
+               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+       };
+
+       rc = i2c_transfer(state->i2c, msg, 2);
+
+       if (rc != 2) {
+               rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+               return rc;
+       }
+
+       return val;
+}
+
+#define s921_readreg(state, reg) \
+       s921_i2c_readreg(state, state->config->demod_address, reg)
+#define s921_writereg(state, reg, val) \
+       s921_i2c_writereg(state, state->config->demod_address, reg, val)
+#define s921_writeregdata(state, regdata) \
+       s921_i2c_writeregdata(state, state->config->demod_address, \
+       regdata, ARRAY_SIZE(regdata))
+
+static int s921_pll_tune(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s921_state *state = fe->demodulator_priv;
+       int band, rc, i;
+       unsigned long f_offset;
+       u8 f_switch;
+       u64 offset;
+
+       dprintk("frequency=%i\n", p->frequency);
+
+       for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
+               if (p->frequency < s921_bandselect[band].freq_low)
+                       break;
+       band--;
+
+       if (band < 0) {
+               rc("%s: frequency out of range\n", __func__);
+               return -EINVAL;
+       }
+
+       f_switch = s921_bandselect[band].band_reg;
+
+       offset = ((u64)p->frequency) * 258;
+       do_div(offset, 6000000);
+       f_offset = ((unsigned long)offset) + 2321;
+
+       rc = s921_writeregdata(state, s921_prefreq);
+       if (rc < 0)
+               return rc;
+
+       rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
+       if (rc < 0)
+               return rc;
+
+       rc = s921_writereg(state, 0xf3, f_offset & 0xff);
+       if (rc < 0)
+               return rc;
+
+       rc = s921_writereg(state, 0xf4, f_switch);
+       if (rc < 0)
+               return rc;
+
+       rc = s921_writeregdata(state, s921_postfreq);
+       if (rc < 0)
+               return rc;
+
+       for (i = 0 ; i < 6; i++) {
+               rc = s921_readreg(state, 0x80);
+               dprintk("status 0x80: %02x\n", rc);
+       }
+       rc = s921_writereg(state, 0x01, 0x40);
+       if (rc < 0)
+               return rc;
+
+       rc = s921_readreg(state, 0x01);
+       dprintk("status 0x01: %02x\n", rc);
+
+       rc = s921_readreg(state, 0x80);
+       dprintk("status 0x80: %02x\n", rc);
+
+       rc = s921_readreg(state, 0x80);
+       dprintk("status 0x80: %02x\n", rc);
+
+       rc = s921_readreg(state, 0x32);
+       dprintk("status 0x32: %02x\n", rc);
+
+       dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
+
+       return 0;
+}
+
+static int s921_initfe(struct dvb_frontend *fe)
+{
+       struct s921_state *state = fe->demodulator_priv;
+       int rc;
+
+       dprintk("\n");
+
+       rc = s921_writeregdata(state, s921_init);
+       if (rc < 0)
+               return rc;
+
+       return 0;
+}
+
+static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct s921_state *state = fe->demodulator_priv;
+       int regstatus, rc;
+
+       *status = 0;
+
+       rc = s921_readreg(state, 0x81);
+       if (rc < 0)
+               return rc;
+
+       regstatus = rc << 8;
+
+       rc = s921_readreg(state, 0x82);
+       if (rc < 0)
+               return rc;
+
+       regstatus |= rc;
+
+       dprintk("status = %04x\n", regstatus);
+
+       /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
+       if ((regstatus & 0xff) == 0x40) {
+               *status = FE_HAS_SIGNAL  |
+                         FE_HAS_CARRIER |
+                         FE_HAS_VITERBI |
+                         FE_HAS_SYNC    |
+                         FE_HAS_LOCK;
+       } else if (regstatus & 0x40) {
+               /* This is close to Full Sync, but not enough to get useful info */
+               *status = FE_HAS_SIGNAL  |
+                         FE_HAS_CARRIER |
+                         FE_HAS_VITERBI |
+                         FE_HAS_SYNC;
+       }
+
+       return 0;
+}
+
+static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       fe_status_t     status;
+       struct s921_state *state = fe->demodulator_priv;
+       int rc;
+
+       /* FIXME: Use the proper register for it... 0x80? */
+       rc = s921_read_status(fe, &status);
+       if (rc < 0)
+               return rc;
+
+       *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
+
+       dprintk("strength = 0x%04x\n", *strength);
+
+       rc = s921_readreg(state, 0x01);
+       dprintk("status 0x01: %02x\n", rc);
+
+       rc = s921_readreg(state, 0x80);
+       dprintk("status 0x80: %02x\n", rc);
+
+       rc = s921_readreg(state, 0x32);
+       dprintk("status 0x32: %02x\n", rc);
+
+       return 0;
+}
+
+static int s921_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s921_state *state = fe->demodulator_priv;
+       int rc;
+
+       dprintk("\n");
+
+       /* FIXME: We don't know how to use non-auto mode */
+
+       rc = s921_pll_tune(fe);
+       if (rc < 0)
+               return rc;
+
+       state->currentfreq = p->frequency;
+
+       return 0;
+}
+
+static int s921_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct s921_state *state = fe->demodulator_priv;
+
+       /* FIXME: Probably it is possible to get it from regs f1 and f2 */
+       p->frequency = state->currentfreq;
+       p->delivery_system = SYS_ISDBT;
+
+       return 0;
+}
+
+static int s921_tune(struct dvb_frontend *fe,
+                       bool re_tune,
+                       unsigned int mode_flags,
+                       unsigned int *delay,
+                       fe_status_t *status)
+{
+       int rc = 0;
+
+       dprintk("\n");
+
+       if (re_tune)
+               rc = s921_set_frontend(fe);
+
+       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+               s921_read_status(fe, status);
+
+       return rc;
+}
+
+static int s921_get_algo(struct dvb_frontend *fe)
+{
+       return 1; /* FE_ALGO_HW */
+}
+
+static void s921_release(struct dvb_frontend *fe)
+{
+       struct s921_state *state = fe->demodulator_priv;
+
+       dprintk("\n");
+       kfree(state);
+}
+
+static struct dvb_frontend_ops s921_ops;
+
+struct dvb_frontend *s921_attach(const struct s921_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       /* allocate memory for the internal state */
+       struct s921_state *state =
+               kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+
+       dprintk("\n");
+       if (state == NULL) {
+               rc("Unable to kzalloc\n");
+               goto rcor;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s921_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+
+rcor:
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(s921_attach);
+
+static struct dvb_frontend_ops s921_ops = {
+       .delsys = { SYS_ISDBT },
+       /* Use dib8000 values per default */
+       .info = {
+               .name = "Sharp S921",
+               .frequency_min = 470000000,
+               /*
+                * Max should be 770MHz instead, according with Sharp docs,
+                * but Leadership doc says it works up to 806 MHz. This is
+                * required to get channel 69, used in Brazil
+                */
+               .frequency_max = 806000000,
+               .frequency_tolerance = 0,
+                .caps = FE_CAN_INVERSION_AUTO |
+                        FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                        FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                        FE_CAN_QPSK     | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                        FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                        FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
+                        FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = s921_release,
+
+       .init = s921_initfe,
+       .set_frontend = s921_set_frontend,
+       .get_frontend = s921_get_frontend,
+       .read_status = s921_read_status,
+       .read_signal_strength = s921_read_signal_strength,
+       .tune = s921_tune,
+       .get_frontend_algo = s921_get_algo,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/s921.h b/drivers/media/dvb-frontends/s921.h
new file mode 100644 (file)
index 0000000..f220d82
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *   Sharp s921 driver
+ *
+ *   Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *   Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation version 2.
+ *
+ *   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.
+ */
+
+#ifndef S921_H
+#define S921_H
+
+#include <linux/dvb/frontend.h>
+
+struct s921_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
+       && defined(MODULE))
+extern struct dvb_frontend *s921_attach(const struct s921_config *config,
+                                          struct i2c_adapter *i2c);
+extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *s921_attach(
+       const struct s921_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static struct i2c_adapter *
+       s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* S921_H */
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
new file mode 100644 (file)
index 0000000..a68a648
--- /dev/null
@@ -0,0 +1,951 @@
+/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+*      This program is free software; you can redistribute it and/or modify
+*      it under the terms of the GNU General Public License as published by
+*      the Free Software Foundation; either version 2 of the License, or
+*      (at your option) any later version.
+*
+*/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "si21xx.h"
+
+#define        REVISION_REG                    0x00
+#define        SYSTEM_MODE_REG                 0x01
+#define        TS_CTRL_REG_1                   0x02
+#define        TS_CTRL_REG_2                   0x03
+#define        PIN_CTRL_REG_1                  0x04
+#define        PIN_CTRL_REG_2                  0x05
+#define        LOCK_STATUS_REG_1               0x0f
+#define        LOCK_STATUS_REG_2               0x10
+#define        ACQ_STATUS_REG                  0x11
+#define        ACQ_CTRL_REG_1                  0x13
+#define        ACQ_CTRL_REG_2                  0x14
+#define        PLL_DIVISOR_REG                 0x15
+#define        COARSE_TUNE_REG                 0x16
+#define        FINE_TUNE_REG_L                 0x17
+#define        FINE_TUNE_REG_H                 0x18
+
+#define        ANALOG_AGC_POWER_LEVEL_REG      0x28
+#define        CFO_ESTIMATOR_CTRL_REG_1        0x29
+#define        CFO_ESTIMATOR_CTRL_REG_2        0x2a
+#define        CFO_ESTIMATOR_CTRL_REG_3        0x2b
+
+#define        SYM_RATE_ESTIMATE_REG_L         0x31
+#define        SYM_RATE_ESTIMATE_REG_M         0x32
+#define        SYM_RATE_ESTIMATE_REG_H         0x33
+
+#define        CFO_ESTIMATOR_OFFSET_REG_L      0x36
+#define        CFO_ESTIMATOR_OFFSET_REG_H      0x37
+#define        CFO_ERROR_REG_L                 0x38
+#define        CFO_ERROR_REG_H                 0x39
+#define        SYM_RATE_ESTIMATOR_CTRL_REG     0x3a
+
+#define        SYM_RATE_REG_L                  0x3f
+#define        SYM_RATE_REG_M                  0x40
+#define        SYM_RATE_REG_H                  0x41
+#define        SYM_RATE_ESTIMATOR_MAXIMUM_REG  0x42
+#define        SYM_RATE_ESTIMATOR_MINIMUM_REG  0x43
+
+#define        C_N_ESTIMATOR_CTRL_REG          0x7c
+#define        C_N_ESTIMATOR_THRSHLD_REG       0x7d
+#define        C_N_ESTIMATOR_LEVEL_REG_L       0x7e
+#define        C_N_ESTIMATOR_LEVEL_REG_H       0x7f
+
+#define        BLIND_SCAN_CTRL_REG             0x80
+
+#define        LSA_CTRL_REG_1                  0x8D
+#define        SPCTRM_TILT_CORR_THRSHLD_REG    0x8f
+#define        ONE_DB_BNDWDTH_THRSHLD_REG      0x90
+#define        TWO_DB_BNDWDTH_THRSHLD_REG      0x91
+#define        THREE_DB_BNDWDTH_THRSHLD_REG    0x92
+#define        INBAND_POWER_THRSHLD_REG        0x93
+#define        REF_NOISE_LVL_MRGN_THRSHLD_REG  0x94
+
+#define        VIT_SRCH_CTRL_REG_1             0xa0
+#define        VIT_SRCH_CTRL_REG_2             0xa1
+#define        VIT_SRCH_CTRL_REG_3             0xa2
+#define        VIT_SRCH_STATUS_REG             0xa3
+#define        VITERBI_BER_COUNT_REG_L         0xab
+#define        REED_SOLOMON_CTRL_REG           0xb0
+#define        REED_SOLOMON_ERROR_COUNT_REG_L  0xb1
+#define        PRBS_CTRL_REG                   0xb5
+
+#define        LNB_CTRL_REG_1                  0xc0
+#define        LNB_CTRL_REG_2                  0xc1
+#define        LNB_CTRL_REG_3                  0xc2
+#define        LNB_CTRL_REG_4                  0xc3
+#define        LNB_CTRL_STATUS_REG             0xc4
+#define        LNB_FIFO_REGS_0                 0xc5
+#define        LNB_FIFO_REGS_1                 0xc6
+#define        LNB_FIFO_REGS_2                 0xc7
+#define        LNB_FIFO_REGS_3                 0xc8
+#define        LNB_FIFO_REGS_4                 0xc9
+#define        LNB_FIFO_REGS_5                 0xca
+#define        LNB_SUPPLY_CTRL_REG_1           0xcb
+#define        LNB_SUPPLY_CTRL_REG_2           0xcc
+#define        LNB_SUPPLY_CTRL_REG_3           0xcd
+#define        LNB_SUPPLY_CTRL_REG_4           0xce
+#define        LNB_SUPPLY_STATUS_REG           0xcf
+
+#define FAIL   -1
+#define PASS   0
+
+#define ALLOWABLE_FS_COUNT     10
+#define STATUS_BER             0
+#define STATUS_UCBLOCKS                1
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "si21xx: " args); \
+       } while (0)
+
+enum {
+       ACTIVE_HIGH,
+       ACTIVE_LOW
+};
+enum {
+       BYTE_WIDE,
+       BIT_WIDE
+};
+enum {
+       CLK_GAPPED_MODE,
+       CLK_CONTINUOUS_MODE
+};
+enum {
+       RISING_EDGE,
+       FALLING_EDGE
+};
+enum {
+       MSB_FIRST,
+       LSB_FIRST
+};
+enum {
+       SERIAL,
+       PARALLEL
+};
+
+struct si21xx_state {
+       struct i2c_adapter *i2c;
+       const struct si21xx_config *config;
+       struct dvb_frontend frontend;
+       u8 initialised:1;
+       int errmode;
+       int fs;                 /*Sampling rate of the ADC in MHz*/
+};
+
+/*     register default initialization */
+static u8 serit_sp1511lhb_inittab[] = {
+       0x01, 0x28,     /* set i2c_inc_disable */
+       0x20, 0x03,
+       0x27, 0x20,
+       0xe0, 0x45,
+       0xe1, 0x08,
+       0xfe, 0x01,
+       0x01, 0x28,
+       0x89, 0x09,
+       0x04, 0x80,
+       0x05, 0x01,
+       0x06, 0x00,
+       0x20, 0x03,
+       0x24, 0x88,
+       0x29, 0x09,
+       0x2a, 0x0f,
+       0x2c, 0x10,
+       0x2d, 0x19,
+       0x2e, 0x08,
+       0x2f, 0x10,
+       0x30, 0x19,
+       0x34, 0x20,
+       0x35, 0x03,
+       0x45, 0x02,
+       0x46, 0x45,
+       0x47, 0xd0,
+       0x48, 0x00,
+       0x49, 0x40,
+       0x4a, 0x03,
+       0x4c, 0xfd,
+       0x4f, 0x2e,
+       0x50, 0x2e,
+       0x51, 0x10,
+       0x52, 0x10,
+       0x56, 0x92,
+       0x59, 0x00,
+       0x5a, 0x2d,
+       0x5b, 0x33,
+       0x5c, 0x1f,
+       0x5f, 0x76,
+       0x62, 0xc0,
+       0x63, 0xc0,
+       0x64, 0xf3,
+       0x65, 0xf3,
+       0x79, 0x40,
+       0x6a, 0x40,
+       0x6b, 0x0a,
+       0x6c, 0x80,
+       0x6d, 0x27,
+       0x71, 0x06,
+       0x75, 0x60,
+       0x78, 0x00,
+       0x79, 0xb5,
+       0x7c, 0x05,
+       0x7d, 0x1a,
+       0x87, 0x55,
+       0x88, 0x72,
+       0x8f, 0x08,
+       0x90, 0xe0,
+       0x94, 0x40,
+       0xa0, 0x3f,
+       0xa1, 0xc0,
+       0xa4, 0xcc,
+       0xa5, 0x66,
+       0xa6, 0x66,
+       0xa7, 0x7b,
+       0xa8, 0x7b,
+       0xa9, 0x7b,
+       0xaa, 0x9a,
+       0xed, 0x04,
+       0xad, 0x00,
+       0xae, 0x03,
+       0xcc, 0xab,
+       0x01, 0x08,
+       0xff, 0xff
+};
+
+/*     low level read/writes */
+static int si21_writeregs(struct si21xx_state *state, u8 reg1,
+                                                       u8 *data, int len)
+{
+       int ret;
+       u8 buf[60];/* = { reg1, data };*/
+       struct i2c_msg msg = {
+                               .addr = state->config->demod_address,
+                               .flags = 0,
+                               .buf = buf,
+                               .len = len + 1
+       };
+
+       msg.buf[0] =  reg1;
+       memcpy(msg.buf + 1, data, len);
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
+                       "ret == %i)\n", __func__, reg1, data[0], ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+                               .addr = state->config->demod_address,
+                               .flags = 0,
+                               .buf = buf,
+                               .len = 2
+       };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
+                       "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return si21_writereg(state, buf[0], buf[1]);
+}
+
+static u8 si21_readreg(struct si21xx_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
+                       __func__, reg, ret);
+
+       return b1[0];
+}
+
+static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
+{
+       int ret;
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = &reg1,
+                       .len = 1
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b,
+                       .len = len
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
+
+       return ret == 2 ? 0 : -1;
+}
+
+static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
+{
+       unsigned long start = jiffies;
+
+       dprintk("%s\n", __func__);
+
+       while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
+               if (jiffies - start > timeout) {
+                       dprintk("%s: timeout!!\n", __func__);
+                       return -ETIMEDOUT;
+               }
+               msleep(10);
+       };
+
+       return 0;
+}
+
+static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u32 sym_rate, data_rate;
+       int i;
+       u8 sym_rate_bytes[3];
+
+       dprintk("%s : srate = %i\n", __func__ , srate);
+
+       if ((srate < 1000000) || (srate > 45000000))
+               return -EINVAL;
+
+       data_rate = srate;
+       sym_rate = 0;
+
+       for (i = 0; i < 4; ++i) {
+               sym_rate /= 100;
+               sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
+                                                               state->fs;
+               data_rate /= 100;
+       }
+       for (i = 0; i < 3; ++i)
+               sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
+
+       si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
+
+       return 0;
+}
+
+static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
+                                       struct dvb_diseqc_master_cmd *m)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 lnb_status;
+       u8 LNB_CTRL_1;
+       int status;
+
+       dprintk("%s\n", __func__);
+
+       status = PASS;
+       LNB_CTRL_1 = 0;
+
+       status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
+       status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
+
+       /*fill the FIFO*/
+       status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
+
+       LNB_CTRL_1 = (lnb_status & 0x70);
+       LNB_CTRL_1 |= m->msg_len;
+
+       LNB_CTRL_1 |= 0x80;     /* begin LNB signaling */
+
+       status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
+
+       return status;
+}
+
+static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
+                                               fe_sec_mini_cmd_t burst)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("%s\n", __func__);
+
+       if (si21xx_wait_diseqc_idle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       val = (0x80 | si21_readreg(state, 0xc1));
+       if (si21_writereg(state, LNB_CTRL_REG_1,
+                       burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
+               return -EREMOTEIO;
+
+       if (si21xx_wait_diseqc_idle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       if (si21_writereg(state, LNB_CTRL_REG_1, val))
+               return -EREMOTEIO;
+
+       return 0;
+}
+/*     30.06.2008 */
+static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("%s\n", __func__);
+       val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
+
+       case SEC_TONE_OFF:
+               return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       u8 val;
+       dprintk("%s: %s\n", __func__,
+               volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+               volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+
+       val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
+
+       switch (volt) {
+       case SEC_VOLTAGE_18:
+               return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
+               break;
+       case SEC_VOLTAGE_13:
+               return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
+               break;
+       default:
+               return -EINVAL;
+       };
+}
+
+static int si21xx_init(struct dvb_frontend *fe)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       int i;
+       int status = 0;
+       u8 reg1;
+       u8 val;
+       u8 reg2[2];
+
+       dprintk("%s\n", __func__);
+
+       for (i = 0; ; i += 2) {
+               reg1 = serit_sp1511lhb_inittab[i];
+               val = serit_sp1511lhb_inittab[i+1];
+               if (reg1 == 0xff && val == 0xff)
+                       break;
+               si21_writeregs(state, reg1, &val, 1);
+       }
+
+       /*DVB QPSK SYSTEM MODE REG*/
+       reg1 = 0x08;
+       si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
+
+       /*transport stream config*/
+       /*
+       mode = PARALLEL;
+       sdata_form = LSB_FIRST;
+       clk_edge = FALLING_EDGE;
+       clk_mode = CLK_GAPPED_MODE;
+       strt_len = BYTE_WIDE;
+       sync_pol = ACTIVE_HIGH;
+       val_pol = ACTIVE_HIGH;
+       err_pol = ACTIVE_HIGH;
+       sclk_rate = 0x00;
+       parity = 0x00 ;
+       data_delay = 0x00;
+       clk_delay = 0x00;
+       pclk_smooth = 0x00;
+       */
+       reg2[0] =
+               PARALLEL + (LSB_FIRST << 1)
+               + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
+               + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
+               + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
+
+       reg2[1] = 0;
+       /*      sclk_rate + (parity << 2)
+               + (data_delay << 3) + (clk_delay << 4)
+               + (pclk_smooth << 5);
+       */
+       status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
+       if (status != 0)
+               dprintk(" %s : TS Set Error\n", __func__);
+
+       return 0;
+
+}
+
+static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 regs_read[2];
+       u8 reg_read;
+       u8 i;
+       u8 lock;
+       u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
+
+       si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
+       reg_read = 0;
+
+       for (i = 0; i < 7; ++i)
+               reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
+
+       lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
+
+       dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
+       *status = 0;
+
+       if (signal > 10)
+               *status |= FE_HAS_SIGNAL;
+
+       if (lock & 0x2)
+               *status |= FE_HAS_CARRIER;
+
+       if (lock & 0x20)
+               *status |= FE_HAS_VITERBI;
+
+       if (lock & 0x40)
+               *status |= FE_HAS_SYNC;
+
+       if ((lock & 0x7b) == 0x7b)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
+                                               (u8*)agclevel, 0x01);*/
+
+       u16 signal = (3 * si21_readreg(state, 0x27) *
+                                       si21_readreg(state, 0x28));
+
+       dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
+               si21_readreg(state, 0x27),
+               si21_readreg(state, 0x28), (int) signal);
+
+       signal  <<= 4;
+       *strength = signal;
+
+       return 0;
+}
+
+static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (state->errmode != STATUS_BER)
+               return 0;
+
+       *ber = (si21_readreg(state, 0x1d) << 8) |
+                               si21_readreg(state, 0x1e);
+
+       return 0;
+}
+
+static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
+                                       si21_readreg(state, 0x25));
+       xsnr = 3 * (xsnr - 0xa100);
+       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
+
+       dprintk("%s\n", __func__);
+
+       return 0;
+}
+
+static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (state->errmode != STATUS_UCBLOCKS)
+               *ucblocks = 0;
+       else
+               *ucblocks = (si21_readreg(state, 0x1d) << 8) |
+                                       si21_readreg(state, 0x1e);
+
+       return 0;
+}
+
+/*     initiates a channel acquisition sequence
+       using the specified symbol rate and code rate */
+static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
+                                               fe_code_rate_t crate)
+{
+
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 coderates[] = {
+                               0x0, 0x01, 0x02, 0x04, 0x00,
+                               0x8, 0x10, 0x20, 0x00, 0x3f
+       };
+
+       u8 coderate_ptr;
+       int status;
+       u8 start_acq = 0x80;
+       u8 reg, regs[3];
+
+       dprintk("%s\n", __func__);
+
+       status = PASS;
+       coderate_ptr = coderates[crate];
+
+       si21xx_set_symbolrate(fe, symbrate);
+
+       /* write code rates to use in the Viterbi search */
+       status |= si21_writeregs(state,
+                               VIT_SRCH_CTRL_REG_1,
+                               &coderate_ptr, 0x01);
+
+       /* clear acq_start bit */
+       status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
+       reg &= ~start_acq;
+       status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
+
+       /* use new Carrier Frequency Offset Estimator (QuickLock) */
+       regs[0] = 0xCB;
+       regs[1] = 0x40;
+       regs[2] = 0xCB;
+
+       status |= si21_writeregs(state,
+                               TWO_DB_BNDWDTH_THRSHLD_REG,
+                               &regs[0], 0x03);
+       reg = 0x56;
+       status |= si21_writeregs(state,
+                               LSA_CTRL_REG_1, &reg, 1);
+       reg = 0x05;
+       status |= si21_writeregs(state,
+                               BLIND_SCAN_CTRL_REG, &reg, 1);
+       /* start automatic acq */
+       status |= si21_writeregs(state,
+                               ACQ_CTRL_REG_2, &start_acq, 0x01);
+
+       return status;
+}
+
+static int si21xx_set_frontend(struct dvb_frontend *fe)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       /* freq         Channel carrier frequency in KHz (i.e. 1550000 KHz)
+        datarate       Channel symbol rate in Sps (i.e. 22500000 Sps)*/
+
+       /* in MHz */
+       unsigned char coarse_tune_freq;
+       int fine_tune_freq;
+       unsigned char sample_rate = 0;
+       /* boolean */
+       bool inband_interferer_ind;
+
+       /* INTERMEDIATE VALUES */
+       int icoarse_tune_freq; /* MHz */
+       int ifine_tune_freq; /* MHz */
+       unsigned int band_high;
+       unsigned int band_low;
+       unsigned int x1;
+       unsigned int x2;
+       int i;
+       bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
+       bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
+       int status;
+
+       /* allowable sample rates for ADC in MHz */
+       int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
+                                       196, 204, 205, 206, 207
+       };
+       /* in MHz */
+       int if_limit_high;
+       int if_limit_low;
+       int lnb_lo;
+       int lnb_uncertanity;
+
+       int rf_freq;
+       int data_rate;
+       unsigned char regs[4];
+
+       dprintk("%s : FE_SET_FRONTEND\n", __func__);
+
+       if (c->delivery_system != SYS_DVBS) {
+                       dprintk("%s: unsupported delivery system selected (%d)\n",
+                               __func__, c->delivery_system);
+                       return -EOPNOTSUPP;
+       }
+
+       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
+               inband_interferer_div2[i] = inband_interferer_div4[i] = false;
+
+       if_limit_high = -700000;
+       if_limit_low = -100000;
+       /* in MHz */
+       lnb_lo = 0;
+       lnb_uncertanity = 0;
+
+       rf_freq = 10 * c->frequency ;
+       data_rate = c->symbol_rate / 100;
+
+       status = PASS;
+
+       band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
+                                       + (data_rate * 135)) / 200;
+
+       band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
+                                       + (data_rate * 135)) / 200;
+
+
+       icoarse_tune_freq = 100000 *
+                               (((rf_freq - lnb_lo) -
+                                       (if_limit_low + if_limit_high) / 2)
+                                                               / 100000);
+
+       ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
+
+       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+               x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
+                                       (afs[i] * 2500) + afs[i] * 2500;
+
+               x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
+                                                       (afs[i] * 2500);
+
+               if (((band_low < x1) && (x1 < band_high)) ||
+                                       ((band_low < x2) && (x2 < band_high)))
+                                       inband_interferer_div4[i] = true;
+
+       }
+
+       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+               x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
+                                       (afs[i] * 5000) + afs[i] * 5000;
+
+               x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
+                                       (afs[i] * 5000);
+
+               if (((band_low < x1) && (x1 < band_high)) ||
+                                       ((band_low < x2) && (x2 < band_high)))
+                                       inband_interferer_div2[i] = true;
+       }
+
+       inband_interferer_ind = true;
+       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+               if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
+                       inband_interferer_ind = false;
+                       break;
+               }
+       }
+
+       if (inband_interferer_ind) {
+               for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+                       if (!inband_interferer_div2[i]) {
+                               sample_rate = (u8) afs[i];
+                               break;
+                       }
+               }
+       } else {
+               for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
+                       if ((inband_interferer_div2[i] ||
+                            !inband_interferer_div4[i])) {
+                               sample_rate = (u8) afs[i];
+                               break;
+                       }
+               }
+
+       }
+
+       if (sample_rate > 207 || sample_rate < 192)
+               sample_rate = 200;
+
+       fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
+                                       ((sample_rate) * 1000));
+
+       coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
+
+       regs[0] = sample_rate;
+       regs[1] = coarse_tune_freq;
+       regs[2] = fine_tune_freq & 0xFF;
+       regs[3] = fine_tune_freq >> 8 & 0xFF;
+
+       status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
+
+       state->fs = sample_rate;/*ADC MHz*/
+       si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
+
+       return 0;
+}
+
+static int si21xx_sleep(struct dvb_frontend *fe)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+       u8 regdata;
+
+       dprintk("%s\n", __func__);
+
+       si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
+       regdata |= 1 << 6;
+       si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
+       state->initialised = 0;
+
+       return 0;
+}
+
+static void si21xx_release(struct dvb_frontend *fe)
+{
+       struct si21xx_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       kfree(state);
+}
+
+static struct dvb_frontend_ops si21xx_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "SL SI21XX DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+               FE_CAN_QPSK |
+               FE_CAN_FEC_AUTO
+       },
+
+       .release = si21xx_release,
+       .init = si21xx_init,
+       .sleep = si21xx_sleep,
+       .write = si21_write,
+       .read_status = si21_read_status,
+       .read_ber = si21_read_ber,
+       .read_signal_strength = si21_read_signal_strength,
+       .read_snr = si21_read_snr,
+       .read_ucblocks = si21_read_ucblocks,
+       .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
+       .diseqc_send_burst = si21xx_send_diseqc_burst,
+       .set_tone = si21xx_set_tone,
+       .set_voltage = si21xx_set_voltage,
+
+       .set_frontend = si21xx_set_frontend,
+};
+
+struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
+                                               struct i2c_adapter *i2c)
+{
+       struct si21xx_state *state = NULL;
+       int id;
+
+       dprintk("%s\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+       state->errmode = STATUS_BER;
+
+       /* check if the demod is there */
+       id = si21_readreg(state, SYSTEM_MODE_REG);
+       si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
+       msleep(200);
+       id = si21_readreg(state, 0x00);
+
+       /* register 0x00 contains:
+               0x34 for SI2107
+               0x24 for SI2108
+               0x14 for SI2109
+               0x04 for SI2110
+       */
+       if (id != 0x04 && id != 0x14)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &si21xx_ops,
+                                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(si21xx_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h
new file mode 100644 (file)
index 0000000..141b5b8
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef SI21XX_H
+#define SI21XX_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct si21xx_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* minimum delay before retuning */
+       int min_delay_ms;
+};
+
+#if defined(CONFIG_DVB_SI21XX) || \
+               (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
+                                               struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *si21xx_attach(
+               const struct si21xx_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       int r = 0;
+       u8 buf[] = {reg, val};
+       if (fe->ops.write)
+               r = fe->ops.write(fe, buf, 2);
+       return r;
+}
+
+#endif
diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
new file mode 100644 (file)
index 0000000..e37274c
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+    Driver for Spase SP8870 demodulator
+
+    Copyright (C) 1999 Juergen Peitz
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
+ */
+#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "sp8870.h"
+
+
+struct sp8870_state {
+
+       struct i2c_adapter* i2c;
+
+       const struct sp8870_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* demodulator private data */
+       u8 initialised:1;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "sp8870: " args); \
+       } while (0)
+
+/* firmware size for sp8870 */
+#define SP8870_FIRMWARE_SIZE 16382
+
+/* starting point for firmware in file 'Sc_main.mc' */
+#define SP8870_FIRMWARE_OFFSET 0x0A
+
+static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
+{
+       u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
+       int err;
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int sp8870_readreg (struct sp8870_state* state, u16 reg)
+{
+       int ret;
+       u8 b0 [] = { reg >> 8 , reg & 0xff };
+       u8 b1 [] = { 0, 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+
+       if (ret != 2) {
+               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
+               return -1;
+       }
+
+       return (b1[0] << 8 | b1[1]);
+}
+
+static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
+{
+       struct i2c_msg msg;
+       const char *fw_buf = fw->data;
+       int fw_pos;
+       u8 tx_buf[255];
+       int tx_len;
+       int err = 0;
+
+       dprintk ("%s: ...\n", __func__);
+
+       if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
+               return -EINVAL;
+
+       // system controller stop
+       sp8870_writereg(state, 0x0F00, 0x0000);
+
+       // instruction RAM register hiword
+       sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
+
+       // instruction RAM MWR
+       sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
+
+       // do firmware upload
+       fw_pos = SP8870_FIRMWARE_OFFSET;
+       while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
+               tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
+               // write register 0xCF0A
+               tx_buf[0] = 0xCF;
+               tx_buf[1] = 0x0A;
+               memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
+               msg.addr = state->config->demod_address;
+               msg.flags = 0;
+               msg.buf = tx_buf;
+               msg.len = tx_len + 2;
+               if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+                       printk("%s: firmware upload failed!\n", __func__);
+                       printk ("%s: i2c error (err == %i)\n", __func__, err);
+                       return err;
+               }
+               fw_pos += tx_len;
+       }
+
+       dprintk ("%s: done!\n", __func__);
+       return 0;
+};
+
+static void sp8870_microcontroller_stop (struct sp8870_state* state)
+{
+       sp8870_writereg(state, 0x0F08, 0x000);
+       sp8870_writereg(state, 0x0F09, 0x000);
+
+       // microcontroller STOP
+       sp8870_writereg(state, 0x0F00, 0x000);
+}
+
+static void sp8870_microcontroller_start (struct sp8870_state* state)
+{
+       sp8870_writereg(state, 0x0F08, 0x000);
+       sp8870_writereg(state, 0x0F09, 0x000);
+
+       // microcontroller START
+       sp8870_writereg(state, 0x0F00, 0x001);
+       // not documented but if we don't read 0x0D01 out here
+       // we don't get a correct data valid signal
+       sp8870_readreg(state, 0x0D01);
+}
+
+static int sp8870_read_data_valid_signal(struct sp8870_state* state)
+{
+       return (sp8870_readreg(state, 0x0D02) > 0);
+}
+
+static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
+{
+       int known_parameters = 1;
+
+       *reg0xc05 = 0x000;
+
+       switch (p->modulation) {
+       case QPSK:
+               break;
+       case QAM_16:
+               *reg0xc05 |= (1 << 10);
+               break;
+       case QAM_64:
+               *reg0xc05 |= (2 << 10);
+               break;
+       case QAM_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       switch (p->hierarchy) {
+       case HIERARCHY_NONE:
+               break;
+       case HIERARCHY_1:
+               *reg0xc05 |= (1 << 7);
+               break;
+       case HIERARCHY_2:
+               *reg0xc05 |= (2 << 7);
+               break;
+       case HIERARCHY_4:
+               *reg0xc05 |= (3 << 7);
+               break;
+       case HIERARCHY_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       switch (p->code_rate_HP) {
+       case FEC_1_2:
+               break;
+       case FEC_2_3:
+               *reg0xc05 |= (1 << 3);
+               break;
+       case FEC_3_4:
+               *reg0xc05 |= (2 << 3);
+               break;
+       case FEC_5_6:
+               *reg0xc05 |= (3 << 3);
+               break;
+       case FEC_7_8:
+               *reg0xc05 |= (4 << 3);
+               break;
+       case FEC_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       if (known_parameters)
+               *reg0xc05 |= (2 << 1);  /* use specified parameters */
+       else
+               *reg0xc05 |= (1 << 1);  /* enable autoprobing */
+
+       return 0;
+}
+
+static int sp8870_wake_up(struct sp8870_state* state)
+{
+       // enable TS output and interface pins
+       return sp8870_writereg(state, 0xC18, 0x00D);
+}
+
+static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct sp8870_state* state = fe->demodulator_priv;
+       int  err;
+       u16 reg0xc05;
+
+       if ((err = configure_reg0xc05(p, &reg0xc05)))
+               return err;
+
+       // system controller stop
+       sp8870_microcontroller_stop(state);
+
+       // set tuner parameters
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       // sample rate correction bit [23..17]
+       sp8870_writereg(state, 0x0319, 0x000A);
+
+       // sample rate correction bit [16..0]
+       sp8870_writereg(state, 0x031A, 0x0AAB);
+
+       // integer carrier offset
+       sp8870_writereg(state, 0x0309, 0x0400);
+
+       // fractional carrier offset
+       sp8870_writereg(state, 0x030A, 0x0000);
+
+       // filter for 6/7/8 Mhz channel
+       if (p->bandwidth_hz == 6000000)
+               sp8870_writereg(state, 0x0311, 0x0002);
+       else if (p->bandwidth_hz == 7000000)
+               sp8870_writereg(state, 0x0311, 0x0001);
+       else
+               sp8870_writereg(state, 0x0311, 0x0000);
+
+       // scan order: 2k first = 0x0000, 8k first = 0x0001
+       if (p->transmission_mode == TRANSMISSION_MODE_2K)
+               sp8870_writereg(state, 0x0338, 0x0000);
+       else
+               sp8870_writereg(state, 0x0338, 0x0001);
+
+       sp8870_writereg(state, 0xc05, reg0xc05);
+
+       // read status reg in order to clear pending irqs
+       sp8870_readreg(state, 0x200);
+
+       // system controller start
+       sp8870_microcontroller_start(state);
+
+       return 0;
+}
+
+static int sp8870_init (struct dvb_frontend* fe)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       const struct firmware *fw = NULL;
+
+       sp8870_wake_up(state);
+       if (state->initialised) return 0;
+       state->initialised = 1;
+
+       dprintk ("%s\n", __func__);
+
+
+       /* request the firmware, this will block until someone uploads it */
+       printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
+       if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
+               printk("sp8870: no firmware upload (timeout or file not found?)\n");
+               return -EIO;
+       }
+
+       if (sp8870_firmware_upload(state, fw)) {
+               printk("sp8870: writing firmware to device failed\n");
+               release_firmware(fw);
+               return -EIO;
+       }
+       release_firmware(fw);
+       printk("sp8870: firmware upload complete\n");
+
+       /* enable TS output and interface pins */
+       sp8870_writereg(state, 0xc18, 0x00d);
+
+       // system controller stop
+       sp8870_microcontroller_stop(state);
+
+       // ADC mode
+       sp8870_writereg(state, 0x0301, 0x0003);
+
+       // Reed Solomon parity bytes passed to output
+       sp8870_writereg(state, 0x0C13, 0x0001);
+
+       // MPEG clock is suppressed if no valid data
+       sp8870_writereg(state, 0x0C14, 0x0001);
+
+       /* bit 0x010: enable data valid signal */
+       sp8870_writereg(state, 0x0D00, 0x010);
+       sp8870_writereg(state, 0x0D01, 0x000);
+
+       return 0;
+}
+
+static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       int status;
+       int signal;
+
+       *fe_status = 0;
+
+       status = sp8870_readreg (state, 0x0200);
+       if (status < 0)
+               return -EIO;
+
+       signal = sp8870_readreg (state, 0x0303);
+       if (signal < 0)
+               return -EIO;
+
+       if (signal > 0x0F)
+               *fe_status |= FE_HAS_SIGNAL;
+       if (status & 0x08)
+               *fe_status |= FE_HAS_SYNC;
+       if (status & 0x04)
+               *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
+
+       return 0;
+}
+
+static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       int ret;
+       u32 tmp;
+
+       *ber = 0;
+
+       ret = sp8870_readreg(state, 0xC08);
+       if (ret < 0)
+               return -EIO;
+
+       tmp = ret & 0x3F;
+
+       ret = sp8870_readreg(state, 0xC07);
+       if (ret < 0)
+               return -EIO;
+
+        tmp = ret << 6;
+
+       if (tmp >= 0x3FFF0)
+               tmp = ~0;
+
+       *ber = tmp;
+
+       return 0;
+}
+
+static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       int ret;
+       u16 tmp;
+
+       *signal = 0;
+
+       ret = sp8870_readreg (state, 0x306);
+       if (ret < 0)
+               return -EIO;
+
+       tmp = ret << 8;
+
+       ret = sp8870_readreg (state, 0x303);
+       if (ret < 0)
+               return -EIO;
+
+       tmp |= ret;
+
+       if (tmp)
+               *signal = 0xFFFF - tmp;
+
+       return 0;
+}
+
+static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       int ret;
+
+       *ublocks = 0;
+
+       ret = sp8870_readreg(state, 0xC0C);
+       if (ret < 0)
+               return -EIO;
+
+       if (ret == 0xFFFF)
+               ret = ~0;
+
+       *ublocks = ret;
+
+       return 0;
+}
+
+/* number of trials to recover from lockup */
+#define MAXTRIALS 5
+/* maximum checks for data valid signal */
+#define MAXCHECKS 100
+
+/* only for debugging: counter for detected lockups */
+static int lockups;
+/* only for debugging: counter for channel switches */
+static int switches;
+
+static int sp8870_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct sp8870_state* state = fe->demodulator_priv;
+
+       /*
+           The firmware of the sp8870 sometimes locks up after setting frontend parameters.
+           We try to detect this by checking the data valid signal.
+           If it is not set after MAXCHECKS we try to recover the lockup by setting
+           the frontend parameters again.
+       */
+
+       int err = 0;
+       int valid = 0;
+       int trials = 0;
+       int check_count = 0;
+
+       dprintk("%s: frequency = %i\n", __func__, p->frequency);
+
+       for (trials = 1; trials <= MAXTRIALS; trials++) {
+
+               err = sp8870_set_frontend_parameters(fe);
+               if (err)
+                       return err;
+
+               for (check_count = 0; check_count < MAXCHECKS; check_count++) {
+//                     valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
+                       valid = sp8870_read_data_valid_signal(state);
+                       if (valid) {
+                               dprintk("%s: delay = %i usec\n",
+                                       __func__, check_count * 10);
+                               break;
+                       }
+                       udelay(10);
+               }
+               if (valid)
+                       break;
+       }
+
+       if (!valid) {
+               printk("%s: firmware crash!!!!!!\n", __func__);
+               return -EIO;
+       }
+
+       if (debug) {
+               if (valid) {
+                       if (trials > 1) {
+                               printk("%s: firmware lockup!!!\n", __func__);
+                               printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
+                               lockups++;
+                       }
+               }
+               switches++;
+               printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
+       }
+
+       return 0;
+}
+
+static int sp8870_sleep(struct dvb_frontend* fe)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+
+       // tristate TS output and disable interface pins
+       return sp8870_writereg(state, 0xC18, 0x000);
+}
+
+static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 350;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return sp8870_writereg(state, 0x206, 0x001);
+       } else {
+               return sp8870_writereg(state, 0x206, 0x000);
+       }
+}
+
+static void sp8870_release(struct dvb_frontend* fe)
+{
+       struct sp8870_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops sp8870_ops;
+
+struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
+                                  struct i2c_adapter* i2c)
+{
+       struct sp8870_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+
+       /* check if the demod is there */
+       if (sp8870_readreg(state, 0x0200) < 0) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops sp8870_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Spase SP8870 DVB-T",
+               .frequency_min          = 470000000,
+               .frequency_max          = 860000000,
+               .frequency_stepsize     = 166666,
+               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+                                         FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                                         FE_CAN_QPSK | FE_CAN_QAM_16 |
+                                         FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                                         FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
+       },
+
+       .release = sp8870_release,
+
+       .init = sp8870_init,
+       .sleep = sp8870_sleep,
+       .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
+
+       .set_frontend = sp8870_set_frontend,
+       .get_tune_settings = sp8870_get_tune_settings,
+
+       .read_status = sp8870_read_status,
+       .read_ber = sp8870_read_ber,
+       .read_signal_strength = sp8870_read_signal_strength,
+       .read_ucblocks = sp8870_read_uncorrected_blocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
+MODULE_AUTHOR("Juergen Peitz");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb-frontends/sp8870.h b/drivers/media/dvb-frontends/sp8870.h
new file mode 100644 (file)
index 0000000..a764a79
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    Driver for Spase SP8870 demodulator
+
+    Copyright (C) 1999 Juergen Peitz
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef SP8870_H
+#define SP8870_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct sp8870_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* request firmware for device */
+       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE))
+extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
+                                         struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
+                                         struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_SP8870
+
+#endif // SP8870_H
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
new file mode 100644 (file)
index 0000000..f4096cc
--- /dev/null
@@ -0,0 +1,629 @@
+/*
+   Driver for the Spase sp887x demodulator
+*/
+
+/*
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
+ */
+#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "sp887x.h"
+
+
+struct sp887x_state {
+       struct i2c_adapter* i2c;
+       const struct sp887x_config* config;
+       struct dvb_frontend frontend;
+
+       /* demodulator private data */
+       u8 initialised:1;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "sp887x: " args); \
+       } while (0)
+
+static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
+{
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
+       int err;
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               printk ("%s: i2c write error (addr %02x, err == %i)\n",
+                       __func__, state->config->demod_address, err);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
+{
+       u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
+       int ret;
+
+       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+               /**
+                *  in case of soft reset we ignore ACK errors...
+                */
+               if (!(reg == 0xf1a && data == 0x000 &&
+                       (ret == -EREMOTEIO || ret == -EFAULT)))
+               {
+                       printk("%s: writereg error "
+                              "(reg %03x, data %03x, ret == %i)\n",
+                              __func__, reg & 0xffff, data & 0xffff, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int sp887x_readreg (struct sp887x_state* state, u16 reg)
+{
+       u8 b0 [] = { reg >> 8 , reg & 0xff };
+       u8 b1 [2];
+       int ret;
+       struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
+                        { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
+
+       if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
+               printk("%s: readreg error (ret == %i)\n", __func__, ret);
+               return -1;
+       }
+
+       return (((b1[0] << 8) | b1[1]) & 0xfff);
+}
+
+static void sp887x_microcontroller_stop (struct sp887x_state* state)
+{
+       dprintk("%s\n", __func__);
+       sp887x_writereg(state, 0xf08, 0x000);
+       sp887x_writereg(state, 0xf09, 0x000);
+
+       /* microcontroller STOP */
+       sp887x_writereg(state, 0xf00, 0x000);
+}
+
+static void sp887x_microcontroller_start (struct sp887x_state* state)
+{
+       dprintk("%s\n", __func__);
+       sp887x_writereg(state, 0xf08, 0x000);
+       sp887x_writereg(state, 0xf09, 0x000);
+
+       /* microcontroller START */
+       sp887x_writereg(state, 0xf00, 0x001);
+}
+
+static void sp887x_setup_agc (struct sp887x_state* state)
+{
+       /* setup AGC parameters */
+       dprintk("%s\n", __func__);
+       sp887x_writereg(state, 0x33c, 0x054);
+       sp887x_writereg(state, 0x33b, 0x04c);
+       sp887x_writereg(state, 0x328, 0x000);
+       sp887x_writereg(state, 0x327, 0x005);
+       sp887x_writereg(state, 0x326, 0x001);
+       sp887x_writereg(state, 0x325, 0x001);
+       sp887x_writereg(state, 0x324, 0x001);
+       sp887x_writereg(state, 0x318, 0x050);
+       sp887x_writereg(state, 0x317, 0x3fe);
+       sp887x_writereg(state, 0x316, 0x001);
+       sp887x_writereg(state, 0x313, 0x005);
+       sp887x_writereg(state, 0x312, 0x002);
+       sp887x_writereg(state, 0x306, 0x000);
+       sp887x_writereg(state, 0x303, 0x000);
+}
+
+#define BLOCKSIZE 30
+#define FW_SIZE 0x4000
+/**
+ *  load firmware and setup MPEG interface...
+ */
+static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+       u8 buf [BLOCKSIZE+2];
+       int i;
+       int fw_size = fw->size;
+       const unsigned char *mem = fw->data;
+
+       dprintk("%s\n", __func__);
+
+       /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
+       if (fw_size < FW_SIZE+10)
+               return -ENODEV;
+
+       mem = fw->data + 10;
+
+       /* soft reset */
+       sp887x_writereg(state, 0xf1a, 0x000);
+
+       sp887x_microcontroller_stop (state);
+
+       printk ("%s: firmware upload... ", __func__);
+
+       /* setup write pointer to -1 (end of memory) */
+       /* bit 0x8000 in address is set to enable 13bit mode */
+       sp887x_writereg(state, 0x8f08, 0x1fff);
+
+       /* dummy write (wrap around to start of memory) */
+       sp887x_writereg(state, 0x8f0a, 0x0000);
+
+       for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
+               int c = BLOCKSIZE;
+               int err;
+
+               if (i+c > FW_SIZE)
+                       c = FW_SIZE - i;
+
+               /* bit 0x8000 in address is set to enable 13bit mode */
+               /* bit 0x4000 enables multibyte read/write transfers */
+               /* write register is 0xf0a */
+               buf[0] = 0xcf;
+               buf[1] = 0x0a;
+
+               memcpy(&buf[2], mem + i, c);
+
+               if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
+                       printk ("failed.\n");
+                       printk ("%s: i2c error (err == %i)\n", __func__, err);
+                       return err;
+               }
+       }
+
+       /* don't write RS bytes between packets */
+       sp887x_writereg(state, 0xc13, 0x001);
+
+       /* suppress clock if (!data_valid) */
+       sp887x_writereg(state, 0xc14, 0x000);
+
+       /* setup MPEG interface... */
+       sp887x_writereg(state, 0xc1a, 0x872);
+       sp887x_writereg(state, 0xc1b, 0x001);
+       sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
+       sp887x_writereg(state, 0xc1a, 0x871);
+
+       /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
+       sp887x_writereg(state, 0x301, 0x002);
+
+       sp887x_setup_agc(state);
+
+       /* bit 0x010: enable data valid signal */
+       sp887x_writereg(state, 0xd00, 0x010);
+       sp887x_writereg(state, 0x0d1, 0x000);
+       return 0;
+};
+
+static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
+{
+       int known_parameters = 1;
+
+       *reg0xc05 = 0x000;
+
+       switch (p->modulation) {
+       case QPSK:
+               break;
+       case QAM_16:
+               *reg0xc05 |= (1 << 10);
+               break;
+       case QAM_64:
+               *reg0xc05 |= (2 << 10);
+               break;
+       case QAM_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       switch (p->hierarchy) {
+       case HIERARCHY_NONE:
+               break;
+       case HIERARCHY_1:
+               *reg0xc05 |= (1 << 7);
+               break;
+       case HIERARCHY_2:
+               *reg0xc05 |= (2 << 7);
+               break;
+       case HIERARCHY_4:
+               *reg0xc05 |= (3 << 7);
+               break;
+       case HIERARCHY_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       switch (p->code_rate_HP) {
+       case FEC_1_2:
+               break;
+       case FEC_2_3:
+               *reg0xc05 |= (1 << 3);
+               break;
+       case FEC_3_4:
+               *reg0xc05 |= (2 << 3);
+               break;
+       case FEC_5_6:
+               *reg0xc05 |= (3 << 3);
+               break;
+       case FEC_7_8:
+               *reg0xc05 |= (4 << 3);
+               break;
+       case FEC_AUTO:
+               known_parameters = 0;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       if (known_parameters)
+               *reg0xc05 |= (2 << 1);  /* use specified parameters */
+       else
+               *reg0xc05 |= (1 << 1);  /* enable autoprobing */
+
+       return 0;
+}
+
+/**
+ *  estimates division of two 24bit numbers,
+ *  derived from the ves1820/stv0299 driver code
+ */
+static void divide (int n, int d, int *quotient_i, int *quotient_f)
+{
+       unsigned int q, r;
+
+       r = (n % d) << 8;
+       q = (r / d);
+
+       if (quotient_i)
+               *quotient_i = q;
+
+       if (quotient_f) {
+               r = (r % d) << 8;
+               q = (q << 8) | (r / d);
+               r = (r % d) << 8;
+               *quotient_f = (q << 8) | (r / d);
+       }
+}
+
+static void sp887x_correct_offsets (struct sp887x_state* state,
+                                   struct dtv_frontend_properties *p,
+                                   int actual_freq)
+{
+       static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
+       int bw_index;
+       int freq_offset = actual_freq - p->frequency;
+       int sysclock = 61003; //[kHz]
+       int ifreq = 36000000;
+       int freq;
+       int frequency_shift;
+
+       switch (p->bandwidth_hz) {
+       default:
+       case 8000000:
+               bw_index = 0;
+               break;
+       case 7000000:
+               bw_index = 1;
+               break;
+       case 6000000:
+               bw_index = 2;
+               break;
+       }
+
+       if (p->inversion == INVERSION_ON)
+               freq = ifreq - freq_offset;
+       else
+               freq = ifreq + freq_offset;
+
+       divide(freq / 333, sysclock, NULL, &frequency_shift);
+
+       if (p->inversion == INVERSION_ON)
+               frequency_shift = -frequency_shift;
+
+       /* sample rate correction */
+       sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
+       sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
+
+       /* carrier offset correction */
+       sp887x_writereg(state, 0x309, frequency_shift >> 12);
+       sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
+}
+
+static int sp887x_setup_frontend_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct sp887x_state* state = fe->demodulator_priv;
+       unsigned actual_freq;
+       int err;
+       u16 val, reg0xc05;
+
+       if (p->bandwidth_hz != 8000000 &&
+           p->bandwidth_hz != 7000000 &&
+           p->bandwidth_hz != 6000000)
+               return -EINVAL;
+
+       if ((err = configure_reg0xc05(p, &reg0xc05)))
+               return err;
+
+       sp887x_microcontroller_stop(state);
+
+       /* setup the PLL */
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+       if (fe->ops.tuner_ops.get_frequency) {
+               fe->ops.tuner_ops.get_frequency(fe, &actual_freq);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       } else {
+               actual_freq = p->frequency;
+       }
+
+       /* read status reg in order to clear <pending irqs */
+       sp887x_readreg(state, 0x200);
+
+       sp887x_correct_offsets(state, p, actual_freq);
+
+       /* filter for 6/7/8 Mhz channel */
+       if (p->bandwidth_hz == 6000000)
+               val = 2;
+       else if (p->bandwidth_hz == 7000000)
+               val = 1;
+       else
+               val = 0;
+
+       sp887x_writereg(state, 0x311, val);
+
+       /* scan order: 2k first = 0, 8k first = 1 */
+       if (p->transmission_mode == TRANSMISSION_MODE_2K)
+               sp887x_writereg(state, 0x338, 0x000);
+       else
+               sp887x_writereg(state, 0x338, 0x001);
+
+       sp887x_writereg(state, 0xc05, reg0xc05);
+
+       if (p->bandwidth_hz == 6000000)
+               val = 2 << 3;
+       else if (p->bandwidth_hz == 7000000)
+               val = 3 << 3;
+       else
+               val = 0 << 3;
+
+       /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
+        * optimize algorithm for given bandwidth...
+        */
+       sp887x_writereg(state, 0xf14, 0x160 | val);
+       sp887x_writereg(state, 0xf15, 0x000);
+
+       sp887x_microcontroller_start(state);
+       return 0;
+}
+
+static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+       u16 snr12 = sp887x_readreg(state, 0xf16);
+       u16 sync0x200 = sp887x_readreg(state, 0x200);
+       u16 sync0xf17 = sp887x_readreg(state, 0xf17);
+
+       *status = 0;
+
+       if (snr12 > 0x00f)
+               *status |= FE_HAS_SIGNAL;
+
+       //if (sync0x200 & 0x004)
+       //      *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
+
+       //if (sync0x200 & 0x008)
+       //      *status |= FE_HAS_VITERBI;
+
+       if ((sync0xf17 & 0x00f) == 0x002) {
+               *status |= FE_HAS_LOCK;
+               *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
+       }
+
+       if (sync0x200 & 0x001) {        /* tuner adjustment requested...*/
+               int steps = (sync0x200 >> 4) & 0x00f;
+               if (steps & 0x008)
+                       steps = -steps;
+               dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
+                      steps);
+       }
+
+       return 0;
+}
+
+static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
+              (sp887x_readreg(state, 0xc07) << 6);
+       sp887x_writereg(state, 0xc08, 0x000);
+       sp887x_writereg(state, 0xc07, 0x000);
+       if (*ber >= 0x3fff0)
+               *ber = ~0;
+
+       return 0;
+}
+
+static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       u16 snr12 = sp887x_readreg(state, 0xf16);
+       u32 signal = 3 * (snr12 << 4);
+       *strength = (signal < 0xffff) ? signal : 0xffff;
+
+       return 0;
+}
+
+static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       u16 snr12 = sp887x_readreg(state, 0xf16);
+       *snr = (snr12 << 4) | (snr12 >> 8);
+
+       return 0;
+}
+
+static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       *ucblocks = sp887x_readreg(state, 0xc0c);
+       if (*ucblocks == 0xfff)
+               *ucblocks = ~0;
+
+       return 0;
+}
+
+static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return sp887x_writereg(state, 0x206, 0x001);
+       } else {
+               return sp887x_writereg(state, 0x206, 0x000);
+       }
+}
+
+static int sp887x_sleep(struct dvb_frontend* fe)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+
+       /* tristate TS output and disable interface pins */
+       sp887x_writereg(state, 0xc18, 0x000);
+
+       return 0;
+}
+
+static int sp887x_init(struct dvb_frontend* fe)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+       const struct firmware *fw = NULL;
+       int ret;
+
+       if (!state->initialised) {
+               /* request the firmware, this will block until someone uploads it */
+               printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
+               ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
+               if (ret) {
+                       printk("sp887x: no firmware upload (timeout or file not found?)\n");
+                       return ret;
+               }
+
+               ret = sp887x_initial_setup(fe, fw);
+               release_firmware(fw);
+               if (ret) {
+                       printk("sp887x: writing firmware to device failed\n");
+                       return ret;
+               }
+               printk("sp887x: firmware upload complete\n");
+               state->initialised = 1;
+       }
+
+       /* enable TS output and interface pins */
+       sp887x_writereg(state, 0xc18, 0x00d);
+
+       return 0;
+}
+
+static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 350;
+       fesettings->step_size = 166666*2;
+       fesettings->max_drift = (166666*2)+1;
+       return 0;
+}
+
+static void sp887x_release(struct dvb_frontend* fe)
+{
+       struct sp887x_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops sp887x_ops;
+
+struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
+                                  struct i2c_adapter* i2c)
+{
+       struct sp887x_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+
+       /* check if the demod is there */
+       if (sp887x_readreg(state, 0x0200) < 0) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops sp887x_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Spase SP887x DVB-T",
+               .frequency_min =  50500000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_RECOVER
+       },
+
+       .release = sp887x_release,
+
+       .init = sp887x_init,
+       .sleep = sp887x_sleep,
+       .i2c_gate_ctrl = sp887x_i2c_gate_ctrl,
+
+       .set_frontend = sp887x_setup_frontend_parameters,
+       .get_tune_settings = sp887x_get_tune_settings,
+
+       .read_status = sp887x_read_status,
+       .read_ber = sp887x_read_ber,
+       .read_signal_strength = sp887x_read_signal_strength,
+       .read_snr = sp887x_read_snr,
+       .read_ucblocks = sp887x_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb-frontends/sp887x.h b/drivers/media/dvb-frontends/sp887x.h
new file mode 100644 (file)
index 0000000..04eff6e
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+   Driver for the Spase sp887x demodulator
+*/
+
+#ifndef SP887X_H
+#define SP887X_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct sp887x_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* request firmware for device */
+       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
+                                         struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
+                                         struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_SP887X
+
+#endif // SP887X_H
diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
new file mode 100644 (file)
index 0000000..117a569
--- /dev/null
@@ -0,0 +1,1525 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+static inline u32 stb0899_do_div(u64 n, u32 d)
+{
+       /* wrap do_div() for ease of use */
+
+       do_div(n, d);
+       return n;
+}
+
+#if 0
+/* These functions are currently unused */
+/*
+ * stb0899_calc_srate
+ * Compute symbol rate
+ */
+static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
+{
+       u64 tmp;
+
+       /* srate = (SFR * master_clk) >> 20 */
+
+       /* sfr is of size 20 bit, stored with an offset of 4 bit */
+       tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
+       tmp &= ~0xf;
+       tmp *= master_clk;
+       tmp >>= 24;
+
+       return tmp;
+}
+
+/*
+ * stb0899_get_srate
+ * Get the current symbol rate
+ */
+static u32 stb0899_get_srate(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       u8 sfr[3];
+
+       stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
+
+       return stb0899_calc_srate(internal->master_clk, sfr);
+}
+#endif
+
+/*
+ * stb0899_set_srate
+ * Set symbol frequency
+ * MasterClock: master clock frequency (hz)
+ * SymbolRate: symbol rate (bauds)
+ * return symbol frequency
+ */
+static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
+{
+       u32 tmp;
+       u8 sfr[3];
+
+       dprintk(state->verbose, FE_DEBUG, 1, "-->");
+       /*
+        * in order to have the maximum precision, the symbol rate entered into
+        * the chip is computed as the closest value of the "true value".
+        * In this purpose, the symbol rate value is rounded (1 is added on the bit
+        * below the LSB )
+        *
+        * srate = (SFR * master_clk) >> 20
+        *      <=>
+        *   SFR = srate << 20 / master_clk
+        *
+        * rounded:
+        *   SFR = (srate << 21 + master_clk) / (2 * master_clk)
+        *
+        * stored as 20 bit number with an offset of 4 bit:
+        *   sfr = SFR << 4;
+        */
+
+       tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
+       tmp <<= 4;
+
+       sfr[0] = tmp >> 16;
+       sfr[1] = tmp >>  8;
+       sfr[2] = tmp;
+
+       stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
+
+       return srate;
+}
+
+/*
+ * stb0899_calc_derot_time
+ * Compute the amount of time needed by the derotator to lock
+ * SymbolRate: Symbol rate
+ * return: derotator time constant (ms)
+ */
+static long stb0899_calc_derot_time(long srate)
+{
+       if (srate > 0)
+               return (100000 / (srate / 1000));
+       else
+               return 0;
+}
+
+/*
+ * stb0899_carr_width
+ * Compute the width of the carrier
+ * return: width of carrier (kHz or Mhz)
+ */
+long stb0899_carr_width(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+
+       return (internal->srate + (internal->srate * internal->rolloff) / 100);
+}
+
+/*
+ * stb0899_first_subrange
+ * Compute the first subrange of the search
+ */
+static void stb0899_first_subrange(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal       = &state->internal;
+       struct stb0899_params *params           = &state->params;
+       struct stb0899_config *config           =  state->config;
+
+       int range = 0;
+       u32 bandwidth = 0;
+
+       if (config->tuner_get_bandwidth) {
+               stb0899_i2c_gate_ctrl(&state->frontend, 1);
+               config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+               stb0899_i2c_gate_ctrl(&state->frontend, 0);
+               range = bandwidth - stb0899_carr_width(state) / 2;
+       }
+
+       if (range > 0)
+               internal->sub_range = min(internal->srch_range, range);
+       else
+               internal->sub_range = 0;
+
+       internal->freq = params->freq;
+       internal->tuner_offst = 0L;
+       internal->sub_dir = 1;
+}
+
+/*
+ * stb0899_check_tmg
+ * check for timing lock
+ * internal.Ttiming: time to wait for loop lock
+ */
+static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       int lock;
+       u8 reg;
+       s8 timing;
+
+       msleep(internal->t_derot);
+
+       stb0899_write_reg(state, STB0899_RTF, 0xf2);
+       reg = stb0899_read_reg(state, STB0899_TLIR);
+       lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
+       timing = stb0899_read_reg(state, STB0899_RTF);
+
+       if (lock >= 42) {
+               if ((lock > 48) && (abs(timing) >= 110)) {
+                       internal->status = ANALOGCARRIER;
+                       dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
+               } else {
+                       internal->status = TIMINGOK;
+                       dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
+               }
+       } else {
+               internal->status = NOTIMING;
+               dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
+       }
+       return internal->status;
+}
+
+/*
+ * stb0899_search_tmg
+ * perform a fs/2 zig-zag to find timing
+ */
+static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_params *params = &state->params;
+
+       short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
+       int index = 0;
+       u8 cfr[2];
+
+       internal->status = NOTIMING;
+
+       /* timing loop computation & symbol rate optimisation   */
+       derot_limit = (internal->sub_range / 2L) / internal->mclk;
+       derot_step = (params->srate / 2L) / internal->mclk;
+
+       while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
+               index++;
+               derot_freq += index * internal->direction * derot_step; /* next derot zig zag position  */
+
+               if (abs(derot_freq) > derot_limit)
+                       next_loop--;
+
+               if (next_loop) {
+                       STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+                       STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+                       stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency         */
+               }
+               internal->direction = -internal->direction;     /* Change zigzag direction              */
+       }
+
+       if (internal->status == TIMINGOK) {
+               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency              */
+               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+               dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_check_carrier
+ * Check for carrier found
+ */
+static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       u8 reg;
+
+       msleep(internal->t_derot); /* wait for derotator ok     */
+
+       reg = stb0899_read_reg(state, STB0899_CFD);
+       STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+       stb0899_write_reg(state, STB0899_CFD, reg);
+
+       reg = stb0899_read_reg(state, STB0899_DSTATUS);
+       dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
+       if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
+               internal->status = CARRIEROK;
+               dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
+       } else {
+               internal->status = NOCARRIER;
+               dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_search_carrier
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+
+       short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
+       int index = 0;
+       u8 cfr[2];
+       u8 reg;
+
+       internal->status = NOCARRIER;
+       derot_limit = (internal->sub_range / 2L) / internal->mclk;
+       derot_freq = internal->derot_freq;
+
+       reg = stb0899_read_reg(state, STB0899_CFD);
+       STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+       stb0899_write_reg(state, STB0899_CFD, reg);
+
+       do {
+               dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
+               if (stb0899_check_carrier(state) == NOCARRIER) {
+                       index++;
+                       last_derot_freq = derot_freq;
+                       derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
+
+                       if(abs(derot_freq) > derot_limit)
+                               next_loop--;
+
+                       if (next_loop) {
+                               reg = stb0899_read_reg(state, STB0899_CFD);
+                               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+                               stb0899_write_reg(state, STB0899_CFD, reg);
+
+                               STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+                               STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+                               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
+                       }
+               }
+
+               internal->direction = -internal->direction; /* Change zigzag direction */
+       } while ((internal->status != CARRIEROK) && next_loop);
+
+       if (internal->status == CARRIEROK) {
+               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
+               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+               dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
+       } else {
+               internal->derot_freq = last_derot_freq;
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_check_data
+ * Check for data found
+ */
+static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_params *params = &state->params;
+
+       int lock = 0, index = 0, dataTime = 500, loop;
+       u8 reg;
+
+       internal->status = NODATA;
+
+       /* RESET FEC    */
+       reg = stb0899_read_reg(state, STB0899_TSTRES);
+       STB0899_SETFIELD_VAL(FRESACS, reg, 1);
+       stb0899_write_reg(state, STB0899_TSTRES, reg);
+       msleep(1);
+       reg = stb0899_read_reg(state, STB0899_TSTRES);
+       STB0899_SETFIELD_VAL(FRESACS, reg, 0);
+       stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+       if (params->srate <= 2000000)
+               dataTime = 2000;
+       else if (params->srate <= 5000000)
+               dataTime = 1500;
+       else if (params->srate <= 15000000)
+               dataTime = 1000;
+       else
+               dataTime = 500;
+
+       /* clear previous failed END_LOOPVIT */
+       stb0899_read_reg(state, STB0899_VSTATUS);
+
+       stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop  */
+       while (1) {
+               /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP    */
+               reg = stb0899_read_reg(state, STB0899_VSTATUS);
+               lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
+               loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
+
+               if (lock || loop || (index > dataTime))
+                       break;
+               index++;
+       }
+
+       if (lock) {     /* DATA LOCK indicator  */
+               internal->status = DATAOK;
+               dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_search_data
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
+{
+       short int derot_freq, derot_step, derot_limit, next_loop = 3;
+       u8 cfr[2];
+       u8 reg;
+       int index = 1;
+
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_params *params = &state->params;
+
+       derot_step = (params->srate / 4L) / internal->mclk;
+       derot_limit = (internal->sub_range / 2L) / internal->mclk;
+       derot_freq = internal->derot_freq;
+
+       do {
+               if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
+
+                       derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
+                       if (abs(derot_freq) > derot_limit)
+                               next_loop--;
+
+                       if (next_loop) {
+                               dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
+                               reg = stb0899_read_reg(state, STB0899_CFD);
+                               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+                               stb0899_write_reg(state, STB0899_CFD, reg);
+
+                               STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+                               STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+                               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
+
+                               stb0899_check_carrier(state);
+                               index++;
+                       }
+               }
+               internal->direction = -internal->direction; /* change zig zag direction */
+       } while ((internal->status != DATAOK) && next_loop);
+
+       if (internal->status == DATAOK) {
+               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
+               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+               dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_check_range
+ * check if the found frequency is in the correct range
+ */
+static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_params *params = &state->params;
+
+       int range_offst, tp_freq;
+
+       range_offst = internal->srch_range / 2000;
+       tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+
+       if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
+               internal->status = RANGEOK;
+               dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
+       } else {
+               internal->status = OUTOFRANGE;
+               dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
+       }
+
+       return internal->status;
+}
+
+/*
+ * NextSubRange
+ * Compute the next subrange of the search
+ */
+static void next_sub_range(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_params *params = &state->params;
+
+       long old_sub_range;
+
+       if (internal->sub_dir > 0) {
+               old_sub_range = internal->sub_range;
+               internal->sub_range = min((internal->srch_range / 2) -
+                                         (internal->tuner_offst + internal->sub_range / 2),
+                                          internal->sub_range);
+
+               if (internal->sub_range < 0)
+                       internal->sub_range = 0;
+
+               internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
+       }
+
+       internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
+       internal->sub_dir = -internal->sub_dir;
+}
+
+/*
+ * stb0899_dvbs_algo
+ * Search for a signal, timing, carrier and data for a
+ * given frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
+{
+       struct stb0899_params *params           = &state->params;
+       struct stb0899_internal *internal       = &state->internal;
+       struct stb0899_config *config           = state->config;
+
+       u8 bclc, reg;
+       u8 cfr[2];
+       u8 eq_const[10];
+       s32 clnI = 3;
+       u32 bandwidth = 0;
+
+       /* BETA values rated @ 99MHz    */
+       s32 betaTab[5][4] = {
+              /*  5   10   20   30MBps */
+               { 37,  34,  32,  31 }, /* QPSK 1/2      */
+               { 37,  35,  33,  31 }, /* QPSK 2/3      */
+               { 37,  35,  33,  31 }, /* QPSK 3/4      */
+               { 37,  36,  33,  32 }, /* QPSK 5/6      */
+               { 37,  36,  33,  32 }  /* QPSK 7/8      */
+       };
+
+       internal->direction = 1;
+
+       stb0899_set_srate(state, internal->master_clk, params->srate);
+       /* Carrier loop optimization versus symbol rate for acquisition*/
+       if (params->srate <= 5000000) {
+               stb0899_write_reg(state, STB0899_ACLC, 0x89);
+               bclc = stb0899_read_reg(state, STB0899_BCLC);
+               STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
+               stb0899_write_reg(state, STB0899_BCLC, bclc);
+               clnI = 0;
+       } else if (params->srate <= 15000000) {
+               stb0899_write_reg(state, STB0899_ACLC, 0xc9);
+               bclc = stb0899_read_reg(state, STB0899_BCLC);
+               STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
+               stb0899_write_reg(state, STB0899_BCLC, bclc);
+               clnI = 1;
+       } else if(params->srate <= 25000000) {
+               stb0899_write_reg(state, STB0899_ACLC, 0x89);
+               bclc = stb0899_read_reg(state, STB0899_BCLC);
+               STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
+               stb0899_write_reg(state, STB0899_BCLC, bclc);
+               clnI = 2;
+       } else {
+               stb0899_write_reg(state, STB0899_ACLC, 0xc8);
+               bclc = stb0899_read_reg(state, STB0899_BCLC);
+               STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
+               stb0899_write_reg(state, STB0899_BCLC, bclc);
+               clnI = 3;
+       }
+
+       dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
+       /* Set the timing loop to acquisition   */
+       stb0899_write_reg(state, STB0899_RTC, 0x46);
+       stb0899_write_reg(state, STB0899_CFD, 0xee);
+
+       /* !! WARNING !!
+        * Do not read any status variables while acquisition,
+        * If any needed, read before the acquisition starts
+        * querying status while acquiring causes the
+        * acquisition to go bad and hence no locks.
+        */
+       dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
+               internal->derot_percent, params->srate, internal->mclk);
+
+       /* Initial calculations */
+       internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol  */
+       internal->t_derot = stb0899_calc_derot_time(params->srate);
+       internal->t_data = 500;
+
+       dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
+       /* RESET Stream merger  */
+       reg = stb0899_read_reg(state, STB0899_TSTRES);
+       STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+       stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+       /*
+        * Set KDIVIDER to an intermediate value between
+        * 1/2 and 7/8 for acquisition
+        */
+       reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
+       STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
+       stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+
+       stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
+       stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
+
+       stb0899_first_subrange(state);
+       do {
+               /* Initialisations */
+               cfr[0] = cfr[1] = 0;
+               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency   */
+
+               stb0899_write_reg(state, STB0899_RTF, 0);
+               reg = stb0899_read_reg(state, STB0899_CFD);
+               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+               stb0899_write_reg(state, STB0899_CFD, reg);
+
+               internal->derot_freq = 0;
+               internal->status = NOAGC1;
+
+               /* enable tuner I/O */
+               stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+               /* Move tuner to frequency */
+               dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
+               if (state->config->tuner_set_frequency)
+                       state->config->tuner_set_frequency(&state->frontend, internal->freq);
+
+               if (state->config->tuner_get_frequency)
+                       state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+               msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop  */
+               dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
+               internal->status = AGC1OK;
+
+               /* There is signal in the band  */
+               if (config->tuner_get_bandwidth)
+                       config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+
+               /* disable tuner I/O */
+               stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+               if (params->srate <= bandwidth / 2)
+                       stb0899_search_tmg(state); /* For low rates (SCPC)      */
+               else
+                       stb0899_check_tmg(state); /* For high rates (MCPC)      */
+
+               if (internal->status == TIMINGOK) {
+                       dprintk(state->verbose, FE_DEBUG, 1,
+                               "TIMING OK ! Derot freq=%d, mclk=%d",
+                               internal->derot_freq, internal->mclk);
+
+                       if (stb0899_search_carrier(state) == CARRIEROK) {       /* Search for carrier   */
+                               dprintk(state->verbose, FE_DEBUG, 1,
+                                       "CARRIER OK ! Derot freq=%d, mclk=%d",
+                                       internal->derot_freq, internal->mclk);
+
+                               if (stb0899_search_data(state) == DATAOK) {     /* Check for data       */
+                                       dprintk(state->verbose, FE_DEBUG, 1,
+                                               "DATA OK ! Derot freq=%d, mclk=%d",
+                                               internal->derot_freq, internal->mclk);
+
+                                       if (stb0899_check_range(state) == RANGEOK) {
+                                               dprintk(state->verbose, FE_DEBUG, 1,
+                                                       "RANGE OK ! derot freq=%d, mclk=%d",
+                                                       internal->derot_freq, internal->mclk);
+
+                                               internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+                                               reg = stb0899_read_reg(state, STB0899_PLPARM);
+                                               internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
+                                               dprintk(state->verbose, FE_DEBUG, 1,
+                                                       "freq=%d, internal resultant freq=%d",
+                                                       params->freq, internal->freq);
+
+                                               dprintk(state->verbose, FE_DEBUG, 1,
+                                                       "internal puncture rate=%d",
+                                                       internal->fecrate);
+                                       }
+                               }
+                       }
+               }
+               if (internal->status != RANGEOK)
+                       next_sub_range(state);
+
+       } while (internal->sub_range && internal->status != RANGEOK);
+
+       /* Set the timing loop to tracking      */
+       stb0899_write_reg(state, STB0899_RTC, 0x33);
+       stb0899_write_reg(state, STB0899_CFD, 0xf7);
+       /* if locked and range ok, set Kdiv     */
+       if (internal->status == RANGEOK) {
+               dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
+               stb0899_write_reg(state, STB0899_EQON, 0x41);           /* Equalizer OFF while acquiring        */
+               stb0899_write_reg(state, STB0899_VITSYNC, 0x39);        /* SN to b'11 for acquisition           */
+
+               /*
+                * Carrier loop optimization versus
+                * symbol Rate/Puncture Rate for Tracking
+                */
+               reg = stb0899_read_reg(state, STB0899_BCLC);
+               switch (internal->fecrate) {
+               case STB0899_FEC_1_2:           /* 13   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
+                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
+                       stb0899_write_reg(state, STB0899_BCLC, reg);
+                       break;
+               case STB0899_FEC_2_3:           /* 18   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
+                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
+                       stb0899_write_reg(state, STB0899_BCLC, reg);
+                       break;
+               case STB0899_FEC_3_4:           /* 21   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
+                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
+                       stb0899_write_reg(state, STB0899_BCLC, reg);
+                       break;
+               case STB0899_FEC_5_6:           /* 24   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
+                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
+                       stb0899_write_reg(state, STB0899_BCLC, reg);
+                       break;
+               case STB0899_FEC_6_7:           /* 25   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
+                       stb0899_write_reg(state, STB0899_ACLC, 0x88);
+                       stb0899_write_reg(state, STB0899_BCLC, 0x9a);
+                       break;
+               case STB0899_FEC_7_8:           /* 26   */
+                       stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
+                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
+                       stb0899_write_reg(state, STB0899_BCLC, reg);
+                       break;
+               default:
+                       dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
+                       break;
+               }
+               /* release stream merger RESET  */
+               reg = stb0899_read_reg(state, STB0899_TSTRES);
+               STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+               stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+               /* disable carrier detector     */
+               reg = stb0899_read_reg(state, STB0899_CFD);
+               STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
+               stb0899_write_reg(state, STB0899_CFD, reg);
+
+               stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
+       }
+
+       return internal->status;
+}
+
+/*
+ * stb0899_dvbs2_config_uwp
+ * Configure UWP state machine
+ */
+static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_config *config = state->config;
+       u32 uwp1, uwp2, uwp3, reg;
+
+       uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+       uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
+       uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
+
+       STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
+       STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
+       STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
+
+       STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
+       STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
+       STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
+
+       STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
+       STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
+
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
+       STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
+}
+
+/*
+ * stb0899_dvbs2_config_csm_auto
+ * Set CSM to AUTO mode
+ */
+static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
+{
+       u32 reg;
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+       STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
+}
+
+static long Log2Int(int number)
+{
+       int i;
+
+       i = 0;
+       while ((1 << i) <= abs(number))
+               i++;
+
+       if (number == 0)
+               i = 1;
+
+       return i - 1;
+}
+
+/*
+ * stb0899_dvbs2_calc_srate
+ * compute BTR_NOM_FREQ for the symbol rate
+ */
+static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal       = &state->internal;
+       struct stb0899_config *config           = state->config;
+
+       u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
+       u32 master_clk, srate;
+
+       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+       dec_rate = Log2Int(dec_ratio);
+       decim = 1 << dec_rate;
+       master_clk = internal->master_clk / 1000;
+       srate = internal->srate / 1000;
+
+       if (decim <= 4) {
+               intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
+               remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+       } else {
+               intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
+               remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+       }
+       btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
+
+       return btr_nom_freq;
+}
+
+/*
+ * stb0899_dvbs2_calc_dev
+ * compute the correction to be applied to symbol rate
+ */
+static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       u32 dec_ratio, correction, master_clk, srate;
+
+       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+
+       master_clk = internal->master_clk / 1000;       /* for integer Caculation*/
+       srate = internal->srate / 1000; /* for integer Caculation*/
+       correction = (512 * master_clk) / (2 * dec_ratio * srate);
+
+       return  correction;
+}
+
+/*
+ * stb0899_dvbs2_set_srate
+ * Set DVBS2 symbol rate
+ */
+static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+
+       u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
+       u32 correction, freq_adj, band_lim, decim_cntrl, reg;
+       u8 anti_alias;
+
+       /*set decimation to 1*/
+       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+       dec_rate = Log2Int(dec_ratio);
+
+       win_sel = 0;
+       if (dec_rate >= 5)
+               win_sel = dec_rate - 4;
+
+       decim = (1 << dec_rate);
+       /* (FSamp/Fsymbol *100) for integer Caculation */
+       f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
+
+       if (f_sym <= 2250)      /* don't band limit signal going into btr block*/
+               band_lim = 1;
+       else
+               band_lim = 0;   /* band limit signal going into btr block*/
+
+       decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
+
+       if (f_sym <= 3450)
+               anti_alias = 0;
+       else if (f_sym <= 4250)
+               anti_alias = 1;
+       else
+               anti_alias = 2;
+
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
+       btr_nom_freq = stb0899_dvbs2_calc_srate(state);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
+
+       correction = stb0899_dvbs2_calc_dev(state);
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+       STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+       /* scale UWP+CSM frequency to sample rate*/
+       freq_adj =  internal->srate / (internal->master_clk / 4096);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
+}
+
+/*
+ * stb0899_dvbs2_set_btr_loopbw
+ * set bit timing loop bandwidth as a percentage of the symbol rate
+ */
+static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal       = &state->internal;
+       struct stb0899_config *config           = state->config;
+
+       u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
+       s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
+       s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
+       u32 decim, K, wn, k_direct, k_indirect;
+       u32 reg;
+
+       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+       dec_rate = Log2Int(dec_ratio);
+       decim = (1 << dec_rate);
+
+       sym_peak *= 576000;
+       K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
+       K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
+
+       if (K != 0) {
+               K = sym_peak / K;
+               wn = (4 * zeta * zeta) + 1000000;
+               wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn;  /*wn =wn 10^-8*/
+
+               k_indirect = (wn * wn) / K;
+               k_indirect = k_indirect;          /*kindirect = kindirect 10^-6*/
+               k_direct   = (2 * wn * zeta) / K;       /*kDirect = kDirect 10^-2*/
+               k_direct  *= 100;
+
+               k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
+               k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
+               k_btr1 = k_direct / (1 << k_direct_shift);
+               k_btr1 /= 10000;
+
+               k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
+               k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
+               k_btr0 = k_indirect * (1 << (-k_indirect_shift));
+               k_btr0 /= 1000000;
+
+               k_btr2_rshft = 0;
+               if (k_btr0_rshft > 15) {
+                       k_btr2_rshft = k_btr0_rshft - 15;
+                       k_btr0_rshft = 15;
+               }
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
+               STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
+               STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
+               STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
+               STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
+               STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
+       } else
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
+}
+
+/*
+ * stb0899_dvbs2_set_carr_freq
+ * set nominal frequency for carrier search
+ */
+static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
+{
+       struct stb0899_config *config = state->config;
+       s32 crl_nom_freq;
+       u32 reg;
+
+       crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
+       crl_nom_freq *= carr_freq;
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+}
+
+/*
+ * stb0899_dvbs2_init_calc
+ * Initialize DVBS2 UWP, CSM, carrier and timing loops
+ */
+static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       s32 steps, step_size;
+       u32 range, reg;
+
+       /* config uwp and csm */
+       stb0899_dvbs2_config_uwp(state);
+       stb0899_dvbs2_config_csm_auto(state);
+
+       /* initialize BTR       */
+       stb0899_dvbs2_set_srate(state);
+       stb0899_dvbs2_set_btr_loopbw(state);
+
+       if (internal->srate / 1000000 >= 15)
+               step_size = (1 << 17) / 5;
+       else if (internal->srate / 1000000 >= 10)
+               step_size = (1 << 17) / 7;
+       else if (internal->srate / 1000000 >= 5)
+               step_size = (1 << 17) / 10;
+       else
+               step_size = (1 << 17) / 4;
+
+       range = internal->srch_range / 1000000;
+       steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
+       steps = (steps + 6) / 10;
+       steps = (steps == 0) ? 1 : steps;
+       if (steps % 2 == 0)
+               stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
+                                          (internal->step_size * (internal->srate / 20000000)),
+                                          (internal->master_clk) / 1000000);
+       else
+               stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
+
+       /*Set Carrier Search params (zigzag, num steps and freq step size*/
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
+       STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
+       STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
+       STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
+}
+
+/*
+ * stb0899_dvbs2_btr_init
+ * initialize the timing loop
+ */
+static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
+{
+       u32 reg;
+
+       /* set enable BTR loopback      */
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+       STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
+       STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+       /* fix btr freq accum at 0      */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
+
+       /* fix btr freq accum at 0      */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
+}
+
+/*
+ * stb0899_dvbs2_reacquire
+ * trigger a DVB-S2 acquisition
+ */
+static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
+{
+       u32 reg = 0;
+
+       /* demod soft reset     */
+       STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+       /*Reset Timing Loop     */
+       stb0899_dvbs2_btr_init(state);
+
+       /* reset Carrier loop   */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
+
+       /*release demod soft reset      */
+       reg = 0;
+       STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+       /* start acquisition process    */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
+
+       /* equalizer Init       */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
+
+       /*Start equilizer       */
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+       STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
+       STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
+       STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
+       STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+       /* RESET Packet delineator      */
+       stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
+}
+
+/*
+ * stb0899_dvbs2_get_dmd_status
+ * get DVB-S2 Demod LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
+{
+       int time = -10, lock = 0, uwp, csm;
+       u32 reg;
+
+       do {
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
+               dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
+               if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
+                       dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+               dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
+               uwp = STB0899_GETFIELD(UWP_LOCK, reg);
+               csm = STB0899_GETFIELD(CSM_LOCK, reg);
+               if (uwp && csm)
+                       lock = 1;
+
+               time += 10;
+               msleep(10);
+
+       } while ((!lock) && (time <= timeout));
+
+       if (lock) {
+               dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
+               return DVBS2_DEMOD_LOCK;
+       } else {
+               return DVBS2_DEMOD_NOLOCK;
+       }
+}
+
+/*
+ * stb0899_dvbs2_get_data_lock
+ * get FEC status
+ */
+static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
+{
+       int time = 0, lock = 0;
+       u8 reg;
+
+       while ((!lock) && (time < timeout)) {
+               reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+               dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
+               lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
+               time++;
+       }
+
+       return lock;
+}
+
+/*
+ * stb0899_dvbs2_get_fec_status
+ * get DVB-S2 FEC LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
+{
+       int time = 0, Locked;
+
+       do {
+               Locked = stb0899_dvbs2_get_data_lock(state, 1);
+               time++;
+               msleep(1);
+
+       } while ((!Locked) && (time < timeout));
+
+       if (Locked) {
+               dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
+               return DVBS2_FEC_LOCK;
+       } else {
+               return DVBS2_FEC_NOLOCK;
+       }
+}
+
+
+/*
+ * stb0899_dvbs2_init_csm
+ * set parameters for manual mode
+ */
+static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
+{
+       struct stb0899_internal *internal = &state->internal;
+
+       s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
+       s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
+       u32 csm1, csm2, csm3, csm4;
+
+       if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
+               switch (modcod) {
+               case STB0899_QPSK_12:
+                       gamma_acq               = 25;
+                       gamma_rho_acq           = 2700;
+                       gamma_trk               = 12;
+                       gamma_rho_trk           = 180;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_35:
+                       gamma_acq               = 38;
+                       gamma_rho_acq           = 7182;
+                       gamma_trk               = 14;
+                       gamma_rho_trk           = 308;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_23:
+                       gamma_acq               = 42;
+                       gamma_rho_acq           = 9408;
+                       gamma_trk               = 17;
+                       gamma_rho_trk           = 476;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_34:
+                       gamma_acq               = 53;
+                       gamma_rho_acq           = 16642;
+                       gamma_trk               = 19;
+                       gamma_rho_trk           = 646;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_45:
+                       gamma_acq               = 53;
+                       gamma_rho_acq           = 17119;
+                       gamma_trk               = 22;
+                       gamma_rho_trk           = 880;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_56:
+                       gamma_acq               = 55;
+                       gamma_rho_acq           = 19250;
+                       gamma_trk               = 23;
+                       gamma_rho_trk           = 989;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_89:
+                       gamma_acq               = 60;
+                       gamma_rho_acq           = 24240;
+                       gamma_trk               = 24;
+                       gamma_rho_trk           = 1176;
+                       lock_count_thr          = 8;
+                       break;
+               case STB0899_QPSK_910:
+                       gamma_acq               = 66;
+                       gamma_rho_acq           = 29634;
+                       gamma_trk               = 24;
+                       gamma_rho_trk           = 1176;
+                       lock_count_thr          = 8;
+                       break;
+               default:
+                       gamma_acq               = 66;
+                       gamma_rho_acq           = 29634;
+                       gamma_trk               = 24;
+                       gamma_rho_trk           = 1176;
+                       lock_count_thr          = 8;
+                       break;
+               }
+
+               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+               STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+               csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
+               csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
+               csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
+
+               STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
+               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
+               STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
+               STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
+               STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
+               STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
+               STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
+               STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
+               STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
+               STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
+               STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
+
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
+       }
+}
+
+/*
+ * stb0899_dvbs2_get_srate
+ * get DVB-S2 Symbol Rate
+ */
+static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_config *config = state->config;
+
+       u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
+       int div1, div2, rem1, rem2;
+
+       div1 = config->btr_nco_bits / 2;
+       div2 = config->btr_nco_bits - div1 - 1;
+
+       bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
+       decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
+       decimRate = (1 << decimRate);
+
+       intval1 = internal->master_clk / (1 << div1);
+       intval2 = bTrNomFreq / (1 << div2);
+
+       rem1 = internal->master_clk % (1 << div1);
+       rem2 = bTrNomFreq % (1 << div2);
+       /* only for integer calculation */
+       srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
+       srate /= decimRate;     /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
+
+       return  srate;
+}
+
+/*
+ * stb0899_dvbs2_algo
+ * Search for signal, timing, carrier and data for a given
+ * frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       enum stb0899_modcod modcod;
+
+       s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
+       int i = 0;
+       u32 reg, csm1;
+
+       if (internal->srate <= 2000000) {
+               searchTime      = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs           */
+               FecLockTime     = 350;  /* 350  ms max time to lock FEC, SYMB <= 2Mbs                   */
+       } else if (internal->srate <= 5000000) {
+               searchTime      = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs    */
+               FecLockTime     = 170;  /* 170  ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs             */
+       } else if (internal->srate <= 10000000) {
+               searchTime      = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs    */
+               FecLockTime     = 80;   /* 80  ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs             */
+       } else if (internal->srate <= 15000000) {
+               searchTime      = 500;  /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs    */
+               FecLockTime     = 50;   /* 50  ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs            */
+       } else if (internal->srate <= 20000000) {
+               searchTime      = 300;  /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs   */
+               FecLockTime     = 30;   /* 50  ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs            */
+       } else if (internal->srate <= 25000000) {
+               searchTime      = 250;  /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs  */
+               FecLockTime     = 25;   /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs             */
+       } else {
+               searchTime      = 150;  /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs            */
+               FecLockTime     = 20;   /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs             */
+       }
+
+       /* Maintain Stream Merger in reset during acquisition   */
+       reg = stb0899_read_reg(state, STB0899_TSTRES);
+       STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+       stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+       /* enable tuner I/O */
+       stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+       /* Move tuner to frequency      */
+       if (state->config->tuner_set_frequency)
+               state->config->tuner_set_frequency(&state->frontend, internal->freq);
+       if (state->config->tuner_get_frequency)
+               state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+       /* disable tuner I/O */
+       stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+       /* Set IF AGC to acquisition    */
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+       STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  4);
+       STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+       STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+
+       /* Initialisation       */
+       stb0899_dvbs2_init_calc(state);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+       switch (internal->inversion) {
+       case IQ_SWAP_OFF:
+               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
+               break;
+       case IQ_SWAP_ON:
+               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+               break;
+       case IQ_SWAP_AUTO:      /* use last successful search first     */
+               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+               break;
+       }
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+       stb0899_dvbs2_reacquire(state);
+
+       /* Wait for demod lock (UWP and CSM)    */
+       internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+
+       if (internal->status == DVBS2_DEMOD_LOCK) {
+               dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
+               i = 0;
+               /* Demod Locked, check FEC status       */
+               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+               /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
+               while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+                       /*      Read the frequency offset*/
+                       offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+                       /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+                       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+                       stb0899_dvbs2_reacquire(state);
+                       internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+                       i++;
+               }
+       }
+
+       if (internal->status != DVBS2_FEC_LOCK) {
+               if (internal->inversion == IQ_SWAP_AUTO) {
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+                       iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+                       /* IQ Spectrum Inversion        */
+                       STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+                       /* start acquistion process     */
+                       stb0899_dvbs2_reacquire(state);
+
+                       /* Wait for demod lock (UWP and CSM)    */
+                       internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+                       if (internal->status == DVBS2_DEMOD_LOCK) {
+                               i = 0;
+                               /* Demod Locked, check FEC      */
+                               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+                               /*try thrice for false locks, (UWP and CSM Locked but no FEC)   */
+                               while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+                                       /*      Read the frequency offset*/
+                                       offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+                                       /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+                                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+                                       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+                                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+
+                                       stb0899_dvbs2_reacquire(state);
+                                       internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+                                       i++;
+                               }
+                       }
+/*
+                       if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+                               pParams->IQLocked = !iqSpectrum;
+*/
+               }
+       }
+       if (internal->status == DVBS2_FEC_LOCK) {
+               dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+               modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+               pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+
+               if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+                     (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
+                     (pilots == 1)) {
+
+                       stb0899_dvbs2_init_csm(state, pilots, modcod);
+                       /* Wait for UWP,CSM and data LOCK 20ms max      */
+                       internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+                       i = 0;
+                       while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+                               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+                               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
+                               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+                               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+                               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
+                               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+                               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+                               i++;
+                       }
+               }
+
+               if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+                     (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
+                     (pilots == 1)) {
+
+                       /* Equalizer Disable update      */
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+                       STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
+                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+               }
+
+               /* slow down the Equalizer once locked  */
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+               STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+               /* Store signal parameters      */
+               offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+               offsetfreq = offsetfreq / ((1 << 30) / 1000);
+               offsetfreq *= (internal->master_clk / 1000000);
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+               if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
+                       offsetfreq *= -1;
+
+               internal->freq = internal->freq - offsetfreq;
+               internal->srate = stb0899_dvbs2_get_srate(state);
+
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+               internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+               internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+               internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
+
+                /* Set IF AGC to tracking      */
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+               STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  3);
+
+               /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
+               if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
+                       STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
+
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+               STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
+               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+       }
+
+       /* Release Stream Merger Reset          */
+       reg = stb0899_read_reg(state, STB0899_TSTRES);
+       STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+       stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+       return internal->status;
+}
diff --git a/drivers/media/dvb-frontends/stb0899_cfg.h b/drivers/media/dvb-frontends/stb0899_cfg.h
new file mode 100644 (file)
index 0000000..0867906
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_CFG_H
+#define __STB0899_CFG_H
+
+static const struct stb0899_s2_reg  stb0899_s2_init_2[] = {
+
+       { STB0899_OFF0_DMD_STATUS       , STB0899_BASE_DMD_STATUS       , 0x00000103 }, /* DMDSTATUS    */
+       { STB0899_OFF0_CRL_FREQ         , STB0899_BASE_CRL_FREQ         , 0x3ed1da56 }, /* CRLFREQ      */
+       { STB0899_OFF0_BTR_FREQ         , STB0899_BASE_BTR_FREQ         , 0x00004000 }, /* BTRFREQ      */
+       { STB0899_OFF0_IF_AGC_GAIN      , STB0899_BASE_IF_AGC_GAIN      , 0x00002ade }, /* IFAGCGAIN    */
+       { STB0899_OFF0_BB_AGC_GAIN      , STB0899_BASE_BB_AGC_GAIN      , 0x000001bc }, /* BBAGCGAIN    */
+       { STB0899_OFF0_DC_OFFSET        , STB0899_BASE_DC_OFFSET        , 0x00000200 }, /* DCOFFSET     */
+       { STB0899_OFF0_DMD_CNTRL        , STB0899_BASE_DMD_CNTRL        , 0x0000000f }, /* DMDCNTRL     */
+
+       { STB0899_OFF0_IF_AGC_CNTRL     , STB0899_BASE_IF_AGC_CNTRL     , 0x03fb4a20 }, /* IFAGCCNTRL   */
+       { STB0899_OFF0_BB_AGC_CNTRL     , STB0899_BASE_BB_AGC_CNTRL     , 0x00200c97 }, /* BBAGCCNTRL   */
+
+       { STB0899_OFF0_CRL_CNTRL        , STB0899_BASE_CRL_CNTRL        , 0x00000016 }, /* CRLCNTRL     */
+       { STB0899_OFF0_CRL_PHS_INIT     , STB0899_BASE_CRL_PHS_INIT     , 0x00000000 }, /* CRLPHSINIT   */
+       { STB0899_OFF0_CRL_FREQ_INIT    , STB0899_BASE_CRL_FREQ_INIT    , 0x00000000 }, /* CRLFREQINIT  */
+       { STB0899_OFF0_CRL_LOOP_GAIN    , STB0899_BASE_CRL_LOOP_GAIN    , 0x00000000 }, /* CRLLOOPGAIN  */
+       { STB0899_OFF0_CRL_NOM_FREQ     , STB0899_BASE_CRL_NOM_FREQ     , 0x3ed097b6 }, /* CRLNOMFREQ   */
+       { STB0899_OFF0_CRL_SWP_RATE     , STB0899_BASE_CRL_SWP_RATE     , 0x00000000 }, /* CRLSWPRATE   */
+       { STB0899_OFF0_CRL_MAX_SWP      , STB0899_BASE_CRL_MAX_SWP      , 0x00000000 }, /* CRLMAXSWP    */
+       { STB0899_OFF0_CRL_LK_CNTRL     , STB0899_BASE_CRL_LK_CNTRL     , 0x0f6cdc01 }, /* CRLLKCNTRL   */
+       { STB0899_OFF0_DECIM_CNTRL      , STB0899_BASE_DECIM_CNTRL      , 0x00000000 }, /* DECIMCNTRL   */
+       { STB0899_OFF0_BTR_CNTRL        , STB0899_BASE_BTR_CNTRL        , 0x00003993 }, /* BTRCNTRL     */
+       { STB0899_OFF0_BTR_LOOP_GAIN    , STB0899_BASE_BTR_LOOP_GAIN    , 0x000d3c6f }, /* BTRLOOPGAIN  */
+       { STB0899_OFF0_BTR_PHS_INIT     , STB0899_BASE_BTR_PHS_INIT     , 0x00000000 }, /* BTRPHSINIT   */
+       { STB0899_OFF0_BTR_FREQ_INIT    , STB0899_BASE_BTR_FREQ_INIT    , 0x00000000 }, /* BTRFREQINIT  */
+       { STB0899_OFF0_BTR_NOM_FREQ     , STB0899_BASE_BTR_NOM_FREQ     , 0x0238e38e }, /* BTRNOMFREQ   */
+       { STB0899_OFF0_BTR_LK_CNTRL     , STB0899_BASE_BTR_LK_CNTRL     , 0x00000000 }, /* BTRLKCNTRL   */
+       { STB0899_OFF0_DECN_CNTRL       , STB0899_BASE_DECN_CNTRL       , 0x00000000 }, /* DECNCNTRL    */
+       { STB0899_OFF0_TP_CNTRL         , STB0899_BASE_TP_CNTRL         , 0x00000000 }, /* TPCNTRL      */
+       { STB0899_OFF0_TP_BUF_STATUS    , STB0899_BASE_TP_BUF_STATUS    , 0x00000000 }, /* TPBUFSTATUS  */
+       { STB0899_OFF0_DC_ESTIM         , STB0899_BASE_DC_ESTIM         , 0x00000000 }, /* DCESTIM      */
+       { STB0899_OFF0_FLL_CNTRL        , STB0899_BASE_FLL_CNTRL        , 0x00000000 }, /* FLLCNTRL     */
+       { STB0899_OFF0_FLL_FREQ_WD      , STB0899_BASE_FLL_FREQ_WD      , 0x40070000 }, /* FLLFREQWD    */
+       { STB0899_OFF0_ANTI_ALIAS_SEL   , STB0899_BASE_ANTI_ALIAS_SEL   , 0x00000001 }, /* ANTIALIASSEL */
+       { STB0899_OFF0_RRC_ALPHA        , STB0899_BASE_RRC_ALPHA        , 0x00000002 }, /* RRCALPHA     */
+       { STB0899_OFF0_DC_ADAPT_LSHFT   , STB0899_BASE_DC_ADAPT_LSHFT   , 0x00000000 }, /* DCADAPTISHFT */
+       { STB0899_OFF0_IMB_OFFSET       , STB0899_BASE_IMB_OFFSET       , 0x0000fe01 }, /* IMBOFFSET    */
+       { STB0899_OFF0_IMB_ESTIMATE     , STB0899_BASE_IMB_ESTIMATE     , 0x00000000 }, /* IMBESTIMATE  */
+       { STB0899_OFF0_IMB_CNTRL        , STB0899_BASE_IMB_CNTRL        , 0x00000001 }, /* IMBCNTRL     */
+       { STB0899_OFF0_IF_AGC_CNTRL2    , STB0899_BASE_IF_AGC_CNTRL2    , 0x00005007 }, /* IFAGCCNTRL2  */
+       { STB0899_OFF0_DMD_CNTRL2       , STB0899_BASE_DMD_CNTRL2       , 0x00000002 }, /* DMDCNTRL2    */
+       { STB0899_OFF0_TP_BUFFER        , STB0899_BASE_TP_BUFFER        , 0x00000000 }, /* TPBUFFER     */
+       { STB0899_OFF0_TP_BUFFER1       , STB0899_BASE_TP_BUFFER1       , 0x00000000 }, /* TPBUFFER1    */
+       { STB0899_OFF0_TP_BUFFER2       , STB0899_BASE_TP_BUFFER2       , 0x00000000 }, /* TPBUFFER2    */
+       { STB0899_OFF0_TP_BUFFER3       , STB0899_BASE_TP_BUFFER3       , 0x00000000 }, /* TPBUFFER3    */
+       { STB0899_OFF0_TP_BUFFER4       , STB0899_BASE_TP_BUFFER4       , 0x00000000 }, /* TPBUFFER4    */
+       { STB0899_OFF0_TP_BUFFER5       , STB0899_BASE_TP_BUFFER5       , 0x00000000 }, /* TPBUFFER5    */
+       { STB0899_OFF0_TP_BUFFER6       , STB0899_BASE_TP_BUFFER6       , 0x00000000 }, /* TPBUFFER6    */
+       { STB0899_OFF0_TP_BUFFER7       , STB0899_BASE_TP_BUFFER7       , 0x00000000 }, /* TPBUFFER7    */
+       { STB0899_OFF0_TP_BUFFER8       , STB0899_BASE_TP_BUFFER8       , 0x00000000 }, /* TPBUFFER8    */
+       { STB0899_OFF0_TP_BUFFER9       , STB0899_BASE_TP_BUFFER9       , 0x00000000 }, /* TPBUFFER9    */
+       { STB0899_OFF0_TP_BUFFER10      , STB0899_BASE_TP_BUFFER10      , 0x00000000 }, /* TPBUFFER10   */
+       { STB0899_OFF0_TP_BUFFER11      , STB0899_BASE_TP_BUFFER11      , 0x00000000 }, /* TPBUFFER11   */
+       { STB0899_OFF0_TP_BUFFER12      , STB0899_BASE_TP_BUFFER12      , 0x00000000 }, /* TPBUFFER12   */
+       { STB0899_OFF0_TP_BUFFER13      , STB0899_BASE_TP_BUFFER13      , 0x00000000 }, /* TPBUFFER13   */
+       { STB0899_OFF0_TP_BUFFER14      , STB0899_BASE_TP_BUFFER14      , 0x00000000 }, /* TPBUFFER14   */
+       { STB0899_OFF0_TP_BUFFER15      , STB0899_BASE_TP_BUFFER15      , 0x00000000 }, /* TPBUFFER15   */
+       { STB0899_OFF0_TP_BUFFER16      , STB0899_BASE_TP_BUFFER16      , 0x0000ff00 }, /* TPBUFFER16   */
+       { STB0899_OFF0_TP_BUFFER17      , STB0899_BASE_TP_BUFFER17      , 0x00000100 }, /* TPBUFFER17   */
+       { STB0899_OFF0_TP_BUFFER18      , STB0899_BASE_TP_BUFFER18      , 0x0000fe01 }, /* TPBUFFER18   */
+       { STB0899_OFF0_TP_BUFFER19      , STB0899_BASE_TP_BUFFER19      , 0x000004fe }, /* TPBUFFER19   */
+       { STB0899_OFF0_TP_BUFFER20      , STB0899_BASE_TP_BUFFER20      , 0x0000cfe7 }, /* TPBUFFER20   */
+       { STB0899_OFF0_TP_BUFFER21      , STB0899_BASE_TP_BUFFER21      , 0x0000bec6 }, /* TPBUFFER21   */
+       { STB0899_OFF0_TP_BUFFER22      , STB0899_BASE_TP_BUFFER22      , 0x0000c2bf }, /* TPBUFFER22   */
+       { STB0899_OFF0_TP_BUFFER23      , STB0899_BASE_TP_BUFFER23      , 0x0000c1c1 }, /* TPBUFFER23   */
+       { STB0899_OFF0_TP_BUFFER24      , STB0899_BASE_TP_BUFFER24      , 0x0000c1c1 }, /* TPBUFFER24   */
+       { STB0899_OFF0_TP_BUFFER25      , STB0899_BASE_TP_BUFFER25      , 0x0000c1c1 }, /* TPBUFFER25   */
+       { STB0899_OFF0_TP_BUFFER26      , STB0899_BASE_TP_BUFFER26      , 0x0000c1c1 }, /* TPBUFFER26   */
+       { STB0899_OFF0_TP_BUFFER27      , STB0899_BASE_TP_BUFFER27      , 0x0000c1c0 }, /* TPBUFFER27   */
+       { STB0899_OFF0_TP_BUFFER28      , STB0899_BASE_TP_BUFFER28      , 0x0000c0c0 }, /* TPBUFFER28   */
+       { STB0899_OFF0_TP_BUFFER29      , STB0899_BASE_TP_BUFFER29      , 0x0000c1c1 }, /* TPBUFFER29   */
+       { STB0899_OFF0_TP_BUFFER30      , STB0899_BASE_TP_BUFFER30      , 0x0000c1c1 }, /* TPBUFFER30   */
+       { STB0899_OFF0_TP_BUFFER31      , STB0899_BASE_TP_BUFFER31      , 0x0000c0c1 }, /* TPBUFFER31   */
+       { STB0899_OFF0_TP_BUFFER32      , STB0899_BASE_TP_BUFFER32      , 0x0000c0c1 }, /* TPBUFFER32   */
+       { STB0899_OFF0_TP_BUFFER33      , STB0899_BASE_TP_BUFFER33      , 0x0000c1c1 }, /* TPBUFFER33   */
+       { STB0899_OFF0_TP_BUFFER34      , STB0899_BASE_TP_BUFFER34      , 0x0000c1c1 }, /* TPBUFFER34   */
+       { STB0899_OFF0_TP_BUFFER35      , STB0899_BASE_TP_BUFFER35      , 0x0000c0c1 }, /* TPBUFFER35   */
+       { STB0899_OFF0_TP_BUFFER36      , STB0899_BASE_TP_BUFFER36      , 0x0000c1c1 }, /* TPBUFFER36   */
+       { STB0899_OFF0_TP_BUFFER37      , STB0899_BASE_TP_BUFFER37      , 0x0000c0c1 }, /* TPBUFFER37   */
+       { STB0899_OFF0_TP_BUFFER38      , STB0899_BASE_TP_BUFFER38      , 0x0000c1c1 }, /* TPBUFFER38   */
+       { STB0899_OFF0_TP_BUFFER39      , STB0899_BASE_TP_BUFFER39      , 0x0000c0c0 }, /* TPBUFFER39   */
+       { STB0899_OFF0_TP_BUFFER40      , STB0899_BASE_TP_BUFFER40      , 0x0000c1c0 }, /* TPBUFFER40   */
+       { STB0899_OFF0_TP_BUFFER41      , STB0899_BASE_TP_BUFFER41      , 0x0000c1c1 }, /* TPBUFFER41   */
+       { STB0899_OFF0_TP_BUFFER42      , STB0899_BASE_TP_BUFFER42      , 0x0000c0c0 }, /* TPBUFFER42   */
+       { STB0899_OFF0_TP_BUFFER43      , STB0899_BASE_TP_BUFFER43      , 0x0000c1c0 }, /* TPBUFFER43   */
+       { STB0899_OFF0_TP_BUFFER44      , STB0899_BASE_TP_BUFFER44      , 0x0000c0c1 }, /* TPBUFFER44   */
+       { STB0899_OFF0_TP_BUFFER45      , STB0899_BASE_TP_BUFFER45      , 0x0000c1be }, /* TPBUFFER45   */
+       { STB0899_OFF0_TP_BUFFER46      , STB0899_BASE_TP_BUFFER46      , 0x0000c1c9 }, /* TPBUFFER46   */
+       { STB0899_OFF0_TP_BUFFER47      , STB0899_BASE_TP_BUFFER47      , 0x0000c0da }, /* TPBUFFER47   */
+       { STB0899_OFF0_TP_BUFFER48      , STB0899_BASE_TP_BUFFER48      , 0x0000c0ba }, /* TPBUFFER48   */
+       { STB0899_OFF0_TP_BUFFER49      , STB0899_BASE_TP_BUFFER49      , 0x0000c1c4 }, /* TPBUFFER49   */
+       { STB0899_OFF0_TP_BUFFER50      , STB0899_BASE_TP_BUFFER50      , 0x0000c1bf }, /* TPBUFFER50   */
+       { STB0899_OFF0_TP_BUFFER51      , STB0899_BASE_TP_BUFFER51      , 0x0000c0c1 }, /* TPBUFFER51   */
+       { STB0899_OFF0_TP_BUFFER52      , STB0899_BASE_TP_BUFFER52      , 0x0000c1c0 }, /* TPBUFFER52   */
+       { STB0899_OFF0_TP_BUFFER53      , STB0899_BASE_TP_BUFFER53      , 0x0000c0c1 }, /* TPBUFFER53   */
+       { STB0899_OFF0_TP_BUFFER54      , STB0899_BASE_TP_BUFFER54      , 0x0000c1c1 }, /* TPBUFFER54   */
+       { STB0899_OFF0_TP_BUFFER55      , STB0899_BASE_TP_BUFFER55      , 0x0000c1c1 }, /* TPBUFFER55   */
+       { STB0899_OFF0_TP_BUFFER56      , STB0899_BASE_TP_BUFFER56      , 0x0000c1c1 }, /* TPBUFFER56   */
+       { STB0899_OFF0_TP_BUFFER57      , STB0899_BASE_TP_BUFFER57      , 0x0000c1c1 }, /* TPBUFFER57   */
+       { STB0899_OFF0_TP_BUFFER58      , STB0899_BASE_TP_BUFFER58      , 0x0000c1c1 }, /* TPBUFFER58   */
+       { STB0899_OFF0_TP_BUFFER59      , STB0899_BASE_TP_BUFFER59      , 0x0000c1c1 }, /* TPBUFFER59   */
+       { STB0899_OFF0_TP_BUFFER60      , STB0899_BASE_TP_BUFFER60      , 0x0000c1c1 }, /* TPBUFFER60   */
+       { STB0899_OFF0_TP_BUFFER61      , STB0899_BASE_TP_BUFFER61      , 0x0000c1c1 }, /* TPBUFFER61   */
+       { STB0899_OFF0_TP_BUFFER62      , STB0899_BASE_TP_BUFFER62      , 0x0000c1c1 }, /* TPBUFFER62   */
+       { STB0899_OFF0_TP_BUFFER63      , STB0899_BASE_TP_BUFFER63      , 0x0000c1c0 }, /* TPBUFFER63   */
+       { STB0899_OFF0_RESET_CNTRL      , STB0899_BASE_RESET_CNTRL      , 0x00000001 }, /* RESETCNTRL   */
+       { STB0899_OFF0_ACM_ENABLE       , STB0899_BASE_ACM_ENABLE       , 0x00005654 }, /* ACMENABLE    */
+       { STB0899_OFF0_DESCR_CNTRL      , STB0899_BASE_DESCR_CNTRL      , 0x00000000 }, /* DESCRCNTRL   */
+       { STB0899_OFF0_CSM_CNTRL1       , STB0899_BASE_CSM_CNTRL1       , 0x00020019 }, /* CSMCNTRL1    */
+       { STB0899_OFF0_CSM_CNTRL2       , STB0899_BASE_CSM_CNTRL2       , 0x004b3237 }, /* CSMCNTRL2    */
+       { STB0899_OFF0_CSM_CNTRL3       , STB0899_BASE_CSM_CNTRL3       , 0x0003dd17 }, /* CSMCNTRL3    */
+       { STB0899_OFF0_CSM_CNTRL4       , STB0899_BASE_CSM_CNTRL4       , 0x00008008 }, /* CSMCNTRL4    */
+       { STB0899_OFF0_UWP_CNTRL1       , STB0899_BASE_UWP_CNTRL1       , 0x002a3106 }, /* UWPCNTRL1    */
+       { STB0899_OFF0_UWP_CNTRL2       , STB0899_BASE_UWP_CNTRL2       , 0x0006140a }, /* UWPCNTRL2    */
+       { STB0899_OFF0_UWP_STAT1        , STB0899_BASE_UWP_STAT1        , 0x00008000 }, /* UWPSTAT1     */
+       { STB0899_OFF0_UWP_STAT2        , STB0899_BASE_UWP_STAT2        , 0x00000000 }, /* UWPSTAT2     */
+       { STB0899_OFF0_DMD_STAT2        , STB0899_BASE_DMD_STAT2        , 0x00000000 }, /* DMDSTAT2     */
+       { STB0899_OFF0_FREQ_ADJ_SCALE   , STB0899_BASE_FREQ_ADJ_SCALE   , 0x00000471 }, /* FREQADJSCALE */
+       { STB0899_OFF0_UWP_CNTRL3       , STB0899_BASE_UWP_CNTRL3       , 0x017b0465 }, /* UWPCNTRL3    */
+       { STB0899_OFF0_SYM_CLK_SEL      , STB0899_BASE_SYM_CLK_SEL      , 0x00000002 }, /* SYMCLKSEL    */
+       { STB0899_OFF0_SOF_SRCH_TO      , STB0899_BASE_SOF_SRCH_TO      , 0x00196464 }, /* SOFSRCHTO    */
+       { STB0899_OFF0_ACQ_CNTRL1       , STB0899_BASE_ACQ_CNTRL1       , 0x00000603 }, /* ACQCNTRL1    */
+       { STB0899_OFF0_ACQ_CNTRL2       , STB0899_BASE_ACQ_CNTRL2       , 0x02046666 }, /* ACQCNTRL2    */
+       { STB0899_OFF0_ACQ_CNTRL3       , STB0899_BASE_ACQ_CNTRL3       , 0x10046583 }, /* ACQCNTRL3    */
+       { STB0899_OFF0_FE_SETTLE        , STB0899_BASE_FE_SETTLE        , 0x00010404 }, /* FESETTLE     */
+       { STB0899_OFF0_AC_DWELL         , STB0899_BASE_AC_DWELL         , 0x0002aa8a }, /* ACDWELL      */
+       { STB0899_OFF0_ACQUIRE_TRIG     , STB0899_BASE_ACQUIRE_TRIG     , 0x00000000 }, /* ACQUIRETRIG  */
+       { STB0899_OFF0_LOCK_LOST        , STB0899_BASE_LOCK_LOST        , 0x00000001 }, /* LOCKLOST     */
+       { STB0899_OFF0_ACQ_STAT1        , STB0899_BASE_ACQ_STAT1        , 0x00000500 }, /* ACQSTAT1     */
+       { STB0899_OFF0_ACQ_TIMEOUT      , STB0899_BASE_ACQ_TIMEOUT      , 0x0028a0a0 }, /* ACQTIMEOUT   */
+       { STB0899_OFF0_ACQ_TIME         , STB0899_BASE_ACQ_TIME         , 0x00000000 }, /* ACQTIME      */
+       { STB0899_OFF0_FINAL_AGC_CNTRL  , STB0899_BASE_FINAL_AGC_CNTRL  , 0x00800c17 }, /* FINALAGCCNTRL*/
+       { STB0899_OFF0_FINAL_AGC_GAIN   , STB0899_BASE_FINAL_AGC_GAIN   , 0x00000000 }, /* FINALAGCCGAIN*/
+       { STB0899_OFF0_EQUALIZER_INIT   , STB0899_BASE_EQUALIZER_INIT   , 0x00000000 }, /* EQUILIZERINIT*/
+       { STB0899_OFF0_EQ_CNTRL         , STB0899_BASE_EQ_CNTRL         , 0x00054802 }, /* EQCNTL       */
+       { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
+       { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
+       { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
+       { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
+       { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
+       { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
+       { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
+       { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
+       { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
+       { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
+       { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
+       { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
+       { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
+       { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
+       { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
+       { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
+       { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
+       { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
+       { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
+       { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
+       { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
+       { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
+       { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
+       { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
+       { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
+       { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
+       { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
+       { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
+       { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
+       { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
+       { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
+       { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
+       { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N  , 0x00000000 }, /* EQICOEFFSOUT10*/
+       { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
+       { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
+       { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
+       { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
+       { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
+       { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
+       { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
+       { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
+       { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
+       { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
+       { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
+       { 0xffff                        , 0xffffffff                    , 0xffffffff },
+};
+static const struct stb0899_s2_reg stb0899_s2_init_4[] = {
+       { STB0899_OFF0_BLOCK_LNGTH      , STB0899_BASE_BLOCK_LNGTH      , 0x00000008 }, /* BLOCKLNGTH   */
+       { STB0899_OFF0_ROW_STR          , STB0899_BASE_ROW_STR          , 0x000000b4 }, /* ROWSTR       */
+       { STB0899_OFF0_BN_END_ADDR      , STB0899_BASE_BN_END_ADDR      , 0x000004b5 }, /* BNANDADDR    */
+       { STB0899_OFF0_CN_END_ADDR      , STB0899_BASE_CN_END_ADDR      , 0x00000b4b }, /* CNANDADDR    */
+       { STB0899_OFF0_INFO_LENGTH      , STB0899_BASE_INFO_LENGTH      , 0x00000078 }, /* INFOLENGTH   */
+       { STB0899_OFF0_BOT_ADDR         , STB0899_BASE_BOT_ADDR         , 0x000001e0 }, /* BOT_ADDR     */
+       { STB0899_OFF0_BCH_BLK_LN       , STB0899_BASE_BCH_BLK_LN       , 0x0000a8c0 }, /* BCHBLKLN     */
+       { STB0899_OFF0_BCH_T            , STB0899_BASE_BCH_T            , 0x0000000c }, /* BCHT         */
+       { STB0899_OFF0_CNFG_MODE        , STB0899_BASE_CNFG_MODE        , 0x00000001 }, /* CNFGMODE     */
+       { STB0899_OFF0_LDPC_STAT        , STB0899_BASE_LDPC_STAT        , 0x0000000d }, /* LDPCSTAT     */
+       { STB0899_OFF0_ITER_SCALE       , STB0899_BASE_ITER_SCALE       , 0x00000040 }, /* ITERSCALE    */
+       { STB0899_OFF0_INPUT_MODE       , STB0899_BASE_INPUT_MODE       , 0x00000000 }, /* INPUTMODE    */
+       { STB0899_OFF0_LDPCDECRST       , STB0899_BASE_LDPCDECRST       , 0x00000000 }, /* LDPCDECRST   */
+       { STB0899_OFF0_CLK_PER_BYTE_RW  , STB0899_BASE_CLK_PER_BYTE_RW  , 0x00000008 }, /* CLKPERBYTE   */
+       { STB0899_OFF0_BCH_ERRORS       , STB0899_BASE_BCH_ERRORS       , 0x00000000 }, /* BCHERRORS    */
+       { STB0899_OFF0_LDPC_ERRORS      , STB0899_BASE_LDPC_ERRORS      , 0x00000000 }, /* LDPCERRORS   */
+       { STB0899_OFF0_BCH_MODE         , STB0899_BASE_BCH_MODE         , 0x00000000 }, /* BCHMODE      */
+       { STB0899_OFF0_ERR_ACC_PER      , STB0899_BASE_ERR_ACC_PER      , 0x00000008 }, /* ERRACCPER    */
+       { STB0899_OFF0_BCH_ERR_ACC      , STB0899_BASE_BCH_ERR_ACC      , 0x00000000 }, /* BCHERRACC    */
+       { STB0899_OFF0_FEC_TP_SEL       , STB0899_BASE_FEC_TP_SEL       , 0x00000000 }, /* FECTPSEL     */
+       { 0xffff                        , 0xffffffff                    , 0xffffffff },
+};
+
+static const struct stb0899_s1_reg stb0899_s1_init_5[] = {
+       { STB0899_TSTCK         , 0x00 },
+       { STB0899_TSTRES        , 0x00 },
+       { STB0899_TSTOUT        , 0x00 },
+       { STB0899_TSTIN         , 0x00 },
+       { STB0899_TSTSYS        , 0x00 },
+       { STB0899_TSTCHIP       , 0x00 },
+       { STB0899_TSTFREE       , 0x00 },
+       { STB0899_TSTI2C        , 0x00 },
+       { STB0899_BITSPEEDM     , 0x00 },
+       { STB0899_BITSPEEDL     , 0x00 },
+       { STB0899_TBUSBIT       , 0x00 },
+       { STB0899_TSTDIS        , 0x00 },
+       { STB0899_TSTDISRX      , 0x00 },
+       { STB0899_TSTJETON      , 0x00 },
+       { STB0899_TSTDCADJ      , 0x00 },
+       { STB0899_TSTAGC1       , 0x00 },
+       { STB0899_TSTAGC1N      , 0x00 },
+       { STB0899_TSTPOLYPH     , 0x00 },
+       { STB0899_TSTR          , 0x00 },
+       { STB0899_TSTAGC2       , 0x00 },
+       { STB0899_TSTCTL1       , 0x00 },
+       { STB0899_TSTCTL2       , 0x00 },
+       { STB0899_TSTCTL3       , 0x00 },
+       { STB0899_TSTDEMAP      , 0x00 },
+       { STB0899_TSTDEMAP2     , 0x00 },
+       { STB0899_TSTDEMMON     , 0x00 },
+       { STB0899_TSTRATE       , 0x00 },
+       { STB0899_TSTSELOUT     , 0x00 },
+       { STB0899_TSYNC         , 0x00 },
+       { STB0899_TSTERR        , 0x00 },
+       { STB0899_TSTRAM1       , 0x00 },
+       { STB0899_TSTVSELOUT    , 0x00 },
+       { STB0899_TSTFORCEIN    , 0x00 },
+       { STB0899_TSTRS1        , 0x00 },
+       { STB0899_TSTRS2        , 0x00 },
+       { STB0899_TSTRS3        , 0x00 },
+       { STB0899_GHOSTREG      , 0x81 },
+       { 0xffff                , 0xff },
+};
+
+#define STB0899_DVBS2_ESNO_AVE                 3
+#define STB0899_DVBS2_ESNO_QUANT               32
+#define STB0899_DVBS2_AVFRAMES_COARSE          10
+#define STB0899_DVBS2_AVFRAMES_FINE            20
+#define STB0899_DVBS2_MISS_THRESHOLD           6
+#define STB0899_DVBS2_UWP_THRESHOLD_ACQ                1125
+#define STB0899_DVBS2_UWP_THRESHOLD_TRACK      758
+#define STB0899_DVBS2_UWP_THRESHOLD_SOF                1350
+#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT       1664100
+
+#define STB0899_DVBS2_BTR_NCO_BITS             28
+#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET    15
+#define STB0899_DVBS2_CRL_NCO_BITS             30
+#define STB0899_DVBS2_LDPC_MAX_ITER            70
+
+#endif //__STB0899_CFG_H
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
new file mode 100644 (file)
index 0000000..5d7f8a9
--- /dev/null
@@ -0,0 +1,1651 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+static unsigned int verbose = 0;//1;
+module_param(verbose, int, 0644);
+
+/* C/N in dB/10, NIRM/NIRL */
+static const struct stb0899_tab stb0899_cn_tab[] = {
+       { 200,  2600 },
+       { 190,  2700 },
+       { 180,  2860 },
+       { 170,  3020 },
+       { 160,  3210 },
+       { 150,  3440 },
+       { 140,  3710 },
+       { 130,  4010 },
+       { 120,  4360 },
+       { 110,  4740 },
+       { 100,  5190 },
+       { 90,   5670 },
+       { 80,   6200 },
+       { 70,   6770 },
+       { 60,   7360 },
+       { 50,   7970 },
+       { 40,   8250 },
+       { 30,   9000 },
+       { 20,   9450 },
+       { 15,   9600 },
+};
+
+/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.0 dBm directly connected,
+ * -52.0 to -74.8 with extra attenuation.
+ * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
+ * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
+       { -750, -128 },
+       { -748,  -94 },
+       { -745,  -92 },
+       { -735,  -90 },
+       { -720,  -87 },
+       { -670,  -77 },
+       { -640,  -70 },
+       { -610,  -62 },
+       { -600,  -60 },
+       { -590,  -56 },
+       { -560,  -41 },
+       { -540,  -25 },
+       { -530,  -17 },
+       { -520,  -11 },
+       { -500,    1 },
+       { -490,    6 },
+       { -480,   10 },
+       { -440,   22 },
+       { -420,   27 },
+       { -400,   31 },
+       { -380,   34 },
+       { -340,   40 },
+       { -320,   43 },
+       { -280,   48 },
+       { -250,   52 },
+       { -230,   55 },
+       { -180,   61 },
+       { -140,   66 },
+       {  -90,   73 },
+       {  -80,   74 },
+       {  500,  127 }
+};
+
+/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.1 dBm directly connected,
+ * -53.0 to -76.6 with extra attenuation.
+ * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
+ * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
+       {  700,     0 },
+       {  -80,  3217 },
+       { -150,  3893 },
+       { -190,  4217 },
+       { -240,  4621 },
+       { -280,  4945 },
+       { -320,  5273 },
+       { -350,  5545 },
+       { -370,  5741 },
+       { -410,  6147 },
+       { -450,  6671 },
+       { -490,  7413 },
+       { -501,  7665 },
+       { -530,  8767 },
+       { -560, 10219 },
+       { -580, 10939 },
+       { -590, 11518 },
+       { -600, 11723 },
+       { -650, 12659 },
+       { -690, 13219 },
+       { -730, 13645 },
+       { -750, 13909 },
+       { -766, 14153 },
+       { -950, 16383 }
+};
+
+/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
+static struct stb0899_tab stb0899_quant_tab[] = {
+       {    0,     0 },
+       {    0,   100 },
+       {  600,   200 },
+       {  950,   299 },
+       { 1200,   398 },
+       { 1400,   501 },
+       { 1560,   603 },
+       { 1690,   700 },
+       { 1810,   804 },
+       { 1910,   902 },
+       { 2000,  1000 },
+       { 2080,  1096 },
+       { 2160,  1202 },
+       { 2230,  1303 },
+       { 2350,  1496 },
+       { 2410,  1603 },
+       { 2460,  1698 },
+       { 2510,  1799 },
+       { 2600,  1995 },
+       { 2650,  2113 },
+       { 2690,  2213 },
+       { 2720,  2291 },
+       { 2760,  2399 },
+       { 2800,  2512 },
+       { 2860,  2692 },
+       { 2930,  2917 },
+       { 2960,  3020 },
+       { 3010,  3199 },
+       { 3040,  3311 },
+       { 3060,  3388 },
+       { 3120,  3631 },
+       { 3190,  3936 },
+       { 3400,  5012 },
+       { 3610,  6383 },
+       { 3800,  7943 },
+       { 4210, 12735 },
+       { 4500, 17783 },
+       { 4690, 22131 },
+       { 4810, 25410 }
+};
+
+/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
+static struct stb0899_tab stb0899_est_tab[] = {
+       {    0,      0 },
+       {    0,      1 },
+       {  301,      2 },
+       { 1204,     16 },
+       { 1806,     64 },
+       { 2408,    256 },
+       { 2709,    512 },
+       { 3010,   1023 },
+       { 3311,   2046 },
+       { 3612,   4093 },
+       { 3823,   6653 },
+       { 3913,   8185 },
+       { 4010,  10233 },
+       { 4107,  12794 },
+       { 4214,  16368 },
+       { 4266,  18450 },
+       { 4311,  20464 },
+       { 4353,  22542 },
+       { 4391,  24604 },
+       { 4425,  26607 },
+       { 4457,  28642 },
+       { 4487,  30690 },
+       { 4515,  32734 },
+       { 4612,  40926 },
+       { 4692,  49204 },
+       { 4816,  65464 },
+       { 4913,  81846 },
+       { 4993,  98401 },
+       { 5060, 114815 },
+       { 5118, 131220 },
+       { 5200, 158489 },
+       { 5300, 199526 },
+       { 5400, 251189 },
+       { 5500, 316228 },
+       { 5600, 398107 },
+       { 5720, 524807 },
+       { 5721, 526017 },
+};
+
+static int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+       int ret;
+
+       u8 b0[] = { reg >> 8, reg & 0xff };
+       u8 buf;
+
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = state->config->demod_address,
+                       .flags  = 0,
+                       .buf    = b0,
+                       .len    = 2
+               },{
+                       .addr   = state->config->demod_address,
+                       .flags  = I2C_M_RD,
+                       .buf    = &buf,
+                       .len    = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2) {
+               if (ret != -ERESTARTSYS)
+                       dprintk(state->verbose, FE_ERROR, 1,
+                               "Read error, Reg=[0x%02x], Status=%d",
+                               reg, ret);
+
+               return ret < 0 ? ret : -EREMOTEIO;
+       }
+       if (unlikely(*state->verbose >= FE_DEBUGREG))
+               dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
+                       reg, buf);
+
+       return (unsigned int)buf;
+}
+
+int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+       int result;
+
+       result = _stb0899_read_reg(state, reg);
+       /*
+        * Bug ID 9:
+        * access to 0xf2xx/0xf6xx
+        * must be followed by read from 0xf2ff/0xf6ff.
+        */
+       if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+           (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+               _stb0899_read_reg(state, (reg | 0x00ff));
+
+       return result;
+}
+
+u32 _stb0899_read_s2reg(struct stb0899_state *state,
+                       u32 stb0899_i2cdev,
+                       u32 stb0899_base_addr,
+                       u16 stb0899_reg_offset)
+{
+       int status;
+       u32 data;
+       u8 buf[7] = { 0 };
+       u16 tmpaddr;
+
+       u8 buf_0[] = {
+               GETBYTE(stb0899_i2cdev, BYTE1),         /* 0xf3 S2 Base Address (MSB)   */
+               GETBYTE(stb0899_i2cdev, BYTE0),         /* 0xfc S2 Base Address (LSB)   */
+               GETBYTE(stb0899_base_addr, BYTE0),      /* 0x00 Base Address (LSB)      */
+               GETBYTE(stb0899_base_addr, BYTE1),      /* 0x04 Base Address (LSB)      */
+               GETBYTE(stb0899_base_addr, BYTE2),      /* 0x00 Base Address (MSB)      */
+               GETBYTE(stb0899_base_addr, BYTE3),      /* 0x00 Base Address (MSB)      */
+       };
+       u8 buf_1[] = {
+               0x00,   /* 0xf3 Reg Offset      */
+               0x00,   /* 0x44 Reg Offset      */
+       };
+
+       struct i2c_msg msg_0 = {
+               .addr   = state->config->demod_address,
+               .flags  = 0,
+               .buf    = buf_0,
+               .len    = 6
+       };
+
+       struct i2c_msg msg_1 = {
+               .addr   = state->config->demod_address,
+               .flags  = 0,
+               .buf    = buf_1,
+               .len    = 2
+       };
+
+       struct i2c_msg msg_r = {
+               .addr   = state->config->demod_address,
+               .flags  = I2C_M_RD,
+               .buf    = buf,
+               .len    = 4
+       };
+
+       tmpaddr = stb0899_reg_offset & 0xff00;
+       if (!(stb0899_reg_offset & 0x8))
+               tmpaddr = stb0899_reg_offset | 0x20;
+
+       buf_1[0] = GETBYTE(tmpaddr, BYTE1);
+       buf_1[1] = GETBYTE(tmpaddr, BYTE0);
+
+       status = i2c_transfer(state->i2c, &msg_0, 1);
+       if (status < 1) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+
+               goto err;
+       }
+
+       /* Dummy        */
+       status = i2c_transfer(state->i2c, &msg_1, 1);
+       if (status < 1)
+               goto err;
+
+       status = i2c_transfer(state->i2c, &msg_r, 1);
+       if (status < 1)
+               goto err;
+
+       buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+       buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+
+       /* Actual       */
+       status = i2c_transfer(state->i2c, &msg_1, 1);
+       if (status < 1) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+               goto err;
+       }
+
+       status = i2c_transfer(state->i2c, &msg_r, 1);
+       if (status < 1) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+               return status < 0 ? status : -EREMOTEIO;
+       }
+
+       data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
+       if (unlikely(*state->verbose >= FE_DEBUGREG))
+               printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+                      __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
+
+       return data;
+
+err:
+       return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_s2reg(struct stb0899_state *state,
+                       u32 stb0899_i2cdev,
+                       u32 stb0899_base_addr,
+                       u16 stb0899_reg_offset,
+                       u32 stb0899_data)
+{
+       int status;
+
+       /* Base Address Setup   */
+       u8 buf_0[] = {
+               GETBYTE(stb0899_i2cdev, BYTE1),         /* 0xf3 S2 Base Address (MSB)   */
+               GETBYTE(stb0899_i2cdev, BYTE0),         /* 0xfc S2 Base Address (LSB)   */
+               GETBYTE(stb0899_base_addr, BYTE0),      /* 0x00 Base Address (LSB)      */
+               GETBYTE(stb0899_base_addr, BYTE1),      /* 0x04 Base Address (LSB)      */
+               GETBYTE(stb0899_base_addr, BYTE2),      /* 0x00 Base Address (MSB)      */
+               GETBYTE(stb0899_base_addr, BYTE3),      /* 0x00 Base Address (MSB)      */
+       };
+       u8 buf_1[] = {
+               0x00,   /* 0xf3 Reg Offset      */
+               0x00,   /* 0x44 Reg Offset      */
+               0x00,   /* data                 */
+               0x00,   /* data                 */
+               0x00,   /* data                 */
+               0x00,   /* data                 */
+       };
+
+       struct i2c_msg msg_0 = {
+               .addr   = state->config->demod_address,
+               .flags  = 0,
+               .buf    = buf_0,
+               .len    = 6
+       };
+
+       struct i2c_msg msg_1 = {
+               .addr   = state->config->demod_address,
+               .flags  = 0,
+               .buf    = buf_1,
+               .len    = 6
+       };
+
+       buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+       buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+       buf_1[2] = GETBYTE(stb0899_data, BYTE0);
+       buf_1[3] = GETBYTE(stb0899_data, BYTE1);
+       buf_1[4] = GETBYTE(stb0899_data, BYTE2);
+       buf_1[5] = GETBYTE(stb0899_data, BYTE3);
+
+       if (unlikely(*state->verbose >= FE_DEBUGREG))
+               printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+                      __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
+
+       status = i2c_transfer(state->i2c, &msg_0, 1);
+       if (unlikely(status < 1)) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+               goto err;
+       }
+       status = i2c_transfer(state->i2c, &msg_1, 1);
+       if (unlikely(status < 1)) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+
+               return status < 0 ? status : -EREMOTEIO;
+       }
+
+       return 0;
+
+err:
+       return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count)
+{
+       int status;
+
+       u8 b0[] = { reg >> 8, reg & 0xff };
+
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = state->config->demod_address,
+                       .flags  = 0,
+                       .buf    = b0,
+                       .len    = 2
+               },{
+                       .addr   = state->config->demod_address,
+                       .flags  = I2C_M_RD,
+                       .buf    = buf,
+                       .len    = count
+               }
+       };
+
+       status = i2c_transfer(state->i2c, msg, 2);
+       if (status != 2) {
+               if (status != -ERESTARTSYS)
+                       printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
+                              __func__, reg, count, status);
+               goto err;
+       }
+       /*
+        * Bug ID 9:
+        * access to 0xf2xx/0xf6xx
+        * must be followed by read from 0xf2ff/0xf6ff.
+        */
+       if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+           (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+               _stb0899_read_reg(state, (reg | 0x00ff));
+
+       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+               int i;
+
+               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+               for (i = 0; i < count; i++) {
+                       printk(" %02x", buf[i]);
+               }
+               printk("\n");
+       }
+
+       return 0;
+err:
+       return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count)
+{
+       int ret;
+       u8 buf[2 + count];
+       struct i2c_msg i2c_msg = {
+               .addr   = state->config->demod_address,
+               .flags  = 0,
+               .buf    = buf,
+               .len    = 2 + count
+       };
+
+       buf[0] = reg >> 8;
+       buf[1] = reg & 0xff;
+       memcpy(&buf[2], data, count);
+
+       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+               int i;
+
+               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+               for (i = 0; i < count; i++)
+                       printk(" %02x", data[i]);
+               printk("\n");
+       }
+       ret = i2c_transfer(state->i2c, &i2c_msg, 1);
+
+       /*
+        * Bug ID 9:
+        * access to 0xf2xx/0xf6xx
+        * must be followed by read from 0xf2ff/0xf6ff.
+        */
+       if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+               stb0899_read_reg(state, (reg | 0x00ff));
+
+       if (ret != 1) {
+               if (ret != -ERESTARTSYS)
+                       dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
+                               reg, data[0], count, ret);
+               return ret < 0 ? ret : -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+{
+       return stb0899_write_regs(state, reg, &data, 1);
+}
+
+/*
+ * stb0899_get_mclk
+ * Get STB0899 master clock frequency
+ * ExtClk: external clock frequency (Hz)
+ */
+static u32 stb0899_get_mclk(struct stb0899_state *state)
+{
+       u32 mclk = 0, div = 0;
+
+       div = stb0899_read_reg(state, STB0899_NCOARSE);
+       mclk = (div + 1) * state->config->xtal_freq / 6;
+       dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
+
+       return mclk;
+}
+
+/*
+ * stb0899_set_mclk
+ * Set STB0899 master Clock frequency
+ * Mclk: demodulator master clock
+ * ExtClk: external clock frequency (Hz)
+ */
+static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
+{
+       struct stb0899_internal *internal = &state->internal;
+       u8 mdiv = 0;
+
+       dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config);
+       mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
+       dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
+
+       stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
+       internal->master_clk = stb0899_get_mclk(state);
+
+       dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
+}
+
+static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
+{
+       struct stb0899_config *config           = state->config;
+       const struct stb0899_postproc *postproc = config->postproc;
+
+       /* post process event */
+       if (postproc) {
+               if (enable) {
+                       if (postproc[ctl].level == STB0899_GPIOPULLUP)
+                               stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
+                       else
+                               stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
+               } else {
+                       if (postproc[ctl].level == STB0899_GPIOPULLUP)
+                               stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
+                       else
+                               stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
+               }
+       }
+       return 0;
+}
+
+static void stb0899_release(struct dvb_frontend *fe)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+
+       dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
+       /* post process event */
+       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
+       kfree(state);
+}
+
+/*
+ * stb0899_get_alpha
+ * return: rolloff
+ */
+static int stb0899_get_alpha(struct stb0899_state *state)
+{
+       u8 mode_coeff;
+
+       mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
+
+       if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
+               return 20;
+       else
+               return 35;
+}
+
+/*
+ * stb0899_init_calc
+ */
+static void stb0899_init_calc(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       int master_clk;
+       u8 agc[2];
+       u32 reg;
+
+       /* Read registers (in burst mode)       */
+       stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O   */
+
+       /* Initial calculations */
+       master_clk                      = stb0899_get_mclk(state);
+       internal->t_agc1                = 0;
+       internal->t_agc2                = 0;
+       internal->master_clk            = master_clk;
+       internal->mclk                  = master_clk / 65536L;
+       internal->rolloff               = stb0899_get_alpha(state);
+
+       /* DVBS2 Initial calculations   */
+       /* Set AGC value to the middle  */
+       internal->agc_gain              = 8154;
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+       STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
+       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
+       internal->rrc_alpha             = STB0899_GETFIELD(RRC_ALPHA, reg);
+
+       internal->center_freq           = 0;
+       internal->av_frame_coarse       = 10;
+       internal->av_frame_fine         = 20;
+       internal->step_size             = 2;
+/*
+       if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
+               pParams->IQLocked = 0;
+       else
+               pParams->IQLocked = 1;
+*/
+}
+
+static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
+{
+       u8 reg = 0;
+       unsigned long start = jiffies;
+
+       while (1) {
+               reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+               if (!STB0899_GETFIELD(FIFOFULL, reg))
+                       break;
+               if ((jiffies - start) > timeout) {
+                       dprintk(state->verbose, FE_ERROR, 1, "timed out !!");
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
+}
+
+static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+       u8 reg, i;
+
+       if (cmd->msg_len > 8)
+               return -EINVAL;
+
+       /* enable FIFO precharge        */
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+       for (i = 0; i < cmd->msg_len; i++) {
+               /* wait for FIFO empty  */
+               if (stb0899_wait_diseqc_fifo_empty(state, 100) < 0)
+                       return -ETIMEDOUT;
+
+               stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
+       }
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+       msleep(100);
+       return 0;
+}
+
+static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
+{
+       u8 reg = 0;
+       unsigned long start = jiffies;
+
+       while (!STB0899_GETFIELD(RXEND, reg)) {
+               reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+               if (jiffies - start > timeout) {
+                       dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
+                       return -ETIMEDOUT;
+               }
+               msleep(10);
+       }
+
+       return 0;
+}
+
+static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+       u8 reg, length = 0, i;
+       int result;
+
+       if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+       if (STB0899_GETFIELD(RXEND, reg)) {
+
+               reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
+               length = STB0899_GETFIELD(FIFOBYTENBR, reg);
+
+               if (length > sizeof (reply->msg)) {
+                       result = -EOVERFLOW;
+                       goto exit;
+               }
+               reply->msg_len = length;
+
+               /* extract data */
+               for (i = 0; i < length; i++)
+                       reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
+       }
+
+       return 0;
+exit:
+
+       return result;
+}
+
+static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
+{
+       u8 reg = 0;
+       unsigned long start = jiffies;
+
+       while (!STB0899_GETFIELD(TXIDLE, reg)) {
+               reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+               if (jiffies - start > timeout) {
+                       dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
+                       return -ETIMEDOUT;
+               }
+               msleep(10);
+       }
+       return 0;
+}
+
+static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+       u8 reg, old_state;
+
+       /* wait for diseqc idle */
+       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       old_state = reg;
+       /* set to burst mode    */
+       STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03);
+       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+       switch (burst) {
+       case SEC_MINI_A:
+               /* unmodulated  */
+               stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
+               break;
+       case SEC_MINI_B:
+               /* modulated    */
+               stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
+               break;
+       }
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+       /* wait for diseqc idle */
+       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       /* restore state        */
+       stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
+
+       return 0;
+}
+
+static int stb0899_diseqc_init(struct stb0899_state *state)
+{
+/*
+       struct dvb_diseqc_slave_reply rx_data;
+*/
+       u8 f22_tx, reg;
+
+       u32 mclk, tx_freq = 22000;/* count = 0, i; */
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
+       STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
+       stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
+
+       /* disable Tx spy       */
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
+       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+       mclk = stb0899_get_mclk(state);
+       f22_tx = mclk / (tx_freq * 32);
+       stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq     */
+       state->rx_freq = 20000;
+
+       return 0;
+}
+
+static int stb0899_sleep(struct dvb_frontend *fe)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+/*
+       u8 reg;
+*/
+       dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
+       /* post process event */
+       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
+
+       return 0;
+}
+
+static int stb0899_wakeup(struct dvb_frontend *fe)
+{
+       int rc;
+       struct stb0899_state *state = fe->demodulator_priv;
+
+       if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
+               return rc;
+       /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
+       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
+               return rc;
+       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
+               return rc;
+
+       /* post process event */
+       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1);
+
+       return 0;
+}
+
+static int stb0899_init(struct dvb_frontend *fe)
+{
+       int i;
+       struct stb0899_state *state = fe->demodulator_priv;
+       struct stb0899_config *config = state->config;
+
+       dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
+
+       /* init device          */
+       dprintk(state->verbose, FE_DEBUG, 1, "init device");
+       for (i = 0; config->init_dev[i].address != 0xffff; i++)
+               stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
+
+       dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod");
+       /* init S2 demod        */
+       for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
+               stb0899_write_s2reg(state, STB0899_S2DEMOD,
+                                   config->init_s2_demod[i].base_address,
+                                   config->init_s2_demod[i].offset,
+                                   config->init_s2_demod[i].data);
+
+       dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod");
+       /* init S1 demod        */
+       for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
+               stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
+
+       dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC");
+       /* init S2 fec          */
+       for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
+               stb0899_write_s2reg(state, STB0899_S2FEC,
+                                   config->init_s2_fec[i].base_address,
+                                   config->init_s2_fec[i].offset,
+                                   config->init_s2_fec[i].data);
+
+       dprintk(state->verbose, FE_DEBUG, 1, "init TST");
+       /* init test            */
+       for (i = 0; config->init_tst[i].address != 0xffff; i++)
+               stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
+
+       stb0899_init_calc(state);
+       stb0899_diseqc_init(state);
+
+       return 0;
+}
+
+static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
+{
+       int res = 0;
+       int min = 0, med;
+
+       if (val < tab[min].read)
+               res = tab[min].real;
+       else if (val >= tab[max].read)
+               res = tab[max].real;
+       else {
+               while ((max - min) > 1) {
+                       med = (max + min) / 2;
+                       if (val >= tab[min].read && val < tab[med].read)
+                               max = med;
+                       else
+                               min = med;
+               }
+               res = ((val - tab[min].read) *
+                      (tab[max].real - tab[min].real) /
+                      (tab[max].read - tab[min].read)) +
+                       tab[min].real;
+       }
+
+       return res;
+}
+
+static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct stb0899_state *state             = fe->demodulator_priv;
+       struct stb0899_internal *internal       = &state->internal;
+
+       int val;
+       u32 reg;
+       *strength = 0;
+       switch (state->delsys) {
+       case SYS_DVBS:
+       case SYS_DSS:
+               if (internal->lock) {
+                       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+                               reg = stb0899_read_reg(state, STB0899_AGCIQIN);
+                               val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
+
+                               *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
+                               *strength += 750;
+                               dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
+                                       val & 0xff, *strength);
+                       }
+               }
+               break;
+       case SYS_DVBS2:
+               if (internal->lock) {
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_GAIN);
+                       val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
+
+                       *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
+                       *strength += 950;
+                       dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
+                               val & 0x3fff, *strength);
+               }
+               break;
+       default:
+               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct stb0899_state *state             = fe->demodulator_priv;
+       struct stb0899_internal *internal       = &state->internal;
+
+       unsigned int val, quant, quantn = -1, est, estn = -1;
+       u8 buf[2];
+       u32 reg;
+
+       *snr = 0;
+       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+       switch (state->delsys) {
+       case SYS_DVBS:
+       case SYS_DSS:
+               if (internal->lock) {
+                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+                               stb0899_read_regs(state, STB0899_NIRM, buf, 2);
+                               val = MAKEWORD16(buf[0], buf[1]);
+
+                               *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
+                               dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
+                                       buf[0], buf[1], val, *snr);
+                       }
+               }
+               break;
+       case SYS_DVBS2:
+               if (internal->lock) {
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+                       quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+                       est = STB0899_GETFIELD(ESN0_EST, reg);
+                       if (est == 1)
+                               val = 301; /* C/N = 30.1 dB */
+                       else if (est == 2)
+                               val = 270; /* C/N = 27.0 dB */
+                       else {
+                               /* quantn = 100 * log(quant^2) */
+                               quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
+                               /* estn = 100 * log(est) */
+                               estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
+                               /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
+                               val = (quantn - estn) / 10;
+                       }
+                       *snr = val;
+                       dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
+                               quant, quantn, est, estn, val);
+               }
+               break;
+       default:
+               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+       struct stb0899_state *state             = fe->demodulator_priv;
+       struct stb0899_internal *internal       = &state->internal;
+       u8 reg;
+       *status = 0;
+
+       switch (state->delsys) {
+       case SYS_DVBS:
+       case SYS_DSS:
+               dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
+               if (internal->lock) {
+                       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
+                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+                               dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
+                               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+
+                               reg = stb0899_read_reg(state, STB0899_PLPARM);
+                               if (STB0899_GETFIELD(VITCURPUN, reg)) {
+                                       dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
+                                       *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
+                                       /* post process event */
+                                       stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
+                               }
+                       }
+               }
+               break;
+       case SYS_DVBS2:
+               dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
+               if (internal->lock) {
+                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+                       if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
+                               *status |= FE_HAS_CARRIER;
+                               dprintk(state->verbose, FE_DEBUG, 1,
+                                       "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
+
+                               reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+                               if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
+                                       *status |= FE_HAS_LOCK;
+                                       dprintk(state->verbose, FE_DEBUG, 1,
+                                               "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
+
+                               }
+                               if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
+                                       *status |= FE_HAS_VITERBI;
+                                       dprintk(state->verbose, FE_DEBUG, 1,
+                                               "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
+                               }
+                               if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
+                                       *status |= FE_HAS_SYNC;
+                                       dprintk(state->verbose, FE_DEBUG, 1,
+                                               "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
+                                       /* post process event */
+                                       stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
+                               }
+                       }
+               }
+               break;
+       default:
+               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * stb0899_get_error
+ * viterbi error for DVB-S/DSS
+ * packet error for DVB-S2
+ * Bit Error Rate or Packet Error Rate * 10 ^ 7
+ */
+static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct stb0899_state *state             = fe->demodulator_priv;
+       struct stb0899_internal *internal       = &state->internal;
+
+       u8  lsb, msb;
+
+       *ber = 0;
+
+       switch (state->delsys) {
+       case SYS_DVBS:
+       case SYS_DSS:
+               if (internal->lock) {
+                       lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+                       msb = stb0899_read_reg(state, STB0899_ECNT1M);
+                       *ber = MAKEWORD16(msb, lsb);
+                       /* Viterbi Check        */
+                       if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
+                               /* Error Rate           */
+                               *ber *= 9766;
+                               /* ber = ber * 10 ^ 7   */
+                               *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+                               *ber /= 8;
+                       }
+               }
+               break;
+       case SYS_DVBS2:
+               if (internal->lock) {
+                       lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+                       msb = stb0899_read_reg(state, STB0899_ECNT1M);
+                       *ber = MAKEWORD16(msb, lsb);
+                       /* ber = ber * 10 ^ 7   */
+                       *ber *= 10000000;
+                       *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+               }
+               break;
+       default:
+               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
+               break;
+       case SEC_VOLTAGE_18:
+               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
+               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+               break;
+       case SEC_VOLTAGE_OFF:
+               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
+               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+       struct stb0899_internal *internal = &state->internal;
+
+       u8 div, reg;
+
+       /* wait for diseqc idle */
+       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+               return -ETIMEDOUT;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               div = (internal->master_clk / 100) / 5632;
+               div = (div + 5) / 10;
+               stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
+               reg = stb0899_read_reg(state, STB0899_ACRPRESC);
+               STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
+               stb0899_write_reg(state, STB0899_ACRPRESC, reg);
+               stb0899_write_reg(state, STB0899_ACRDIV1, div);
+               break;
+       case SEC_TONE_OFF:
+               stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       int i2c_stat;
+       struct stb0899_state *state = fe->demodulator_priv;
+
+       i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
+       if (i2c_stat < 0)
+               goto err;
+
+       if (enable) {
+               dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
+               i2c_stat |=  STB0899_I2CTON;
+               if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+                       goto err;
+       } else {
+               dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
+               i2c_stat &= ~STB0899_I2CTON;
+               if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+                       goto err;
+       }
+       return 0;
+err:
+       dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
+       return -EREMOTEIO;
+}
+
+
+static inline void CONVERT32(u32 x, char *str)
+{
+       *str++  = (x >> 24) & 0xff;
+       *str++  = (x >> 16) & 0xff;
+       *str++  = (x >>  8) & 0xff;
+       *str++  = (x >>  0) & 0xff;
+       *str    = '\0';
+}
+
+int stb0899_get_dev_id(struct stb0899_state *state)
+{
+       u8 chip_id, release;
+       u16 id;
+       u32 demod_ver = 0, fec_ver = 0;
+       char demod_str[5] = { 0 };
+       char fec_str[5] = { 0 };
+
+       id = stb0899_read_reg(state, STB0899_DEV_ID);
+       dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
+       chip_id = STB0899_GETFIELD(CHIP_ID, id);
+       release = STB0899_GETFIELD(CHIP_REL, id);
+
+       dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
+               chip_id, release);
+
+       CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
+
+       demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
+       dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
+       CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
+       fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
+       if (! (chip_id > 0)) {
+               dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
+
+               return -ENODEV;
+       }
+       dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
+
+       return 0;
+}
+
+static void stb0899_set_delivery(struct stb0899_state *state)
+{
+       u8 reg;
+       u8 stop_clk[2];
+
+       stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
+       stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
+
+       switch (state->delsys) {
+       case SYS_DVBS:
+               dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
+               /* FECM/Viterbi ON      */
+               reg = stb0899_read_reg(state, STB0899_FECM);
+               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+               stb0899_write_reg(state, STB0899_FECM, reg);
+
+               stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+               stb0899_write_reg(state, STB0899_TSULC, 0x40);
+               stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+               stb0899_write_reg(state, STB0899_TSLPL, 0x12);
+
+               reg = stb0899_read_reg(state, STB0899_TSTRES);
+               STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+               stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+               STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+               break;
+       case SYS_DVBS2:
+               /* FECM/Viterbi OFF     */
+               reg = stb0899_read_reg(state, STB0899_FECM);
+               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
+               stb0899_write_reg(state, STB0899_FECM, reg);
+
+               stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+               stb0899_write_reg(state, STB0899_TSULC, 0x42);
+               stb0899_write_reg(state, STB0899_RSLLC, 0x40);
+               stb0899_write_reg(state, STB0899_TSLPL, 0x02);
+
+               reg = stb0899_read_reg(state, STB0899_TSTRES);
+               STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
+               stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
+               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
+
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
+
+               STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
+               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
+               break;
+       case SYS_DSS:
+               /* FECM/Viterbi ON      */
+               reg = stb0899_read_reg(state, STB0899_FECM);
+               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
+               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+               stb0899_write_reg(state, STB0899_FECM, reg);
+
+               stb0899_write_reg(state, STB0899_RSULC, 0xa1);
+               stb0899_write_reg(state, STB0899_TSULC, 0x61);
+               stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+
+               reg = stb0899_read_reg(state, STB0899_TSTRES);
+               STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+               stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+               break;
+       default:
+               dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
+               break;
+       }
+       STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
+       stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
+}
+
+/*
+ * stb0899_set_iterations
+ * set the LDPC iteration scale function
+ */
+static void stb0899_set_iterations(struct stb0899_state *state)
+{
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_config *config = state->config;
+
+       s32 iter_scale;
+       u32 reg;
+
+       iter_scale = 17 * (internal->master_clk / 1000);
+       iter_scale += 410000;
+       iter_scale /= (internal->srate / 1000000);
+       iter_scale /= 1000;
+
+       if (iter_scale > config->ldpc_max_iter)
+               iter_scale = config->ldpc_max_iter;
+
+       reg = STB0899_READ_S2REG(STB0899_S2FEC, MAX_ITER);
+       STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
+       stb0899_write_s2reg(state, STB0899_S2FEC, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
+}
+
+static enum dvbfe_search stb0899_search(struct dvb_frontend *fe)
+{
+       struct stb0899_state *state = fe->demodulator_priv;
+       struct stb0899_params *i_params = &state->params;
+       struct stb0899_internal *internal = &state->internal;
+       struct stb0899_config *config = state->config;
+       struct dtv_frontend_properties *props = &fe->dtv_property_cache;
+
+       u32 SearchRange, gain;
+
+       i_params->freq  = props->frequency;
+       i_params->srate = props->symbol_rate;
+       state->delsys = props->delivery_system;
+       dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
+
+       SearchRange = 10000000;
+       dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
+       /* checking Search Range is meaningless for a fixed 3 Mhz                       */
+       if (INRANGE(i_params->srate, 1000000, 45000000)) {
+               dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE");
+               stb0899_set_delivery(state);
+
+               if (state->config->tuner_set_rfsiggain) {
+                       if (internal->srate > 15000000)
+                               gain =  8; /* 15Mb < srate < 45Mb, gain = 8dB   */
+                       else if (internal->srate > 5000000)
+                               gain = 12; /*  5Mb < srate < 15Mb, gain = 12dB  */
+                       else
+                               gain = 14; /*  1Mb < srate <  5Mb, gain = 14db  */
+                       state->config->tuner_set_rfsiggain(fe, gain);
+               }
+
+               if (i_params->srate <= 5000000)
+                       stb0899_set_mclk(state, config->lo_clk);
+               else
+                       stb0899_set_mclk(state, config->hi_clk);
+
+               switch (state->delsys) {
+               case SYS_DVBS:
+               case SYS_DSS:
+                       dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system");
+                       internal->freq  = i_params->freq;
+                       internal->srate = i_params->srate;
+                       /*
+                        * search = user search range +
+                        *          500Khz +
+                        *          2 * Tuner_step_size +
+                        *          10% of the symbol rate
+                        */
+                       internal->srch_range    = SearchRange + 1500000 + (i_params->srate / 5);
+                       internal->derot_percent = 30;
+
+                       /* What to do for tuners having no bandwidth setup ?    */
+                       /* enable tuner I/O */
+                       stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+                       if (state->config->tuner_set_bandwidth)
+                               state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
+                       if (state->config->tuner_get_bandwidth)
+                               state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+                       /* disable tuner I/O */
+                       stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+                       /* Set DVB-S1 AGC               */
+                       stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
+
+                       /* Run the search algorithm     */
+                       dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
+                       if (stb0899_dvbs_algo(state)    == RANGEOK) {
+                               internal->lock          = 1;
+                               dprintk(state->verbose, FE_DEBUG, 1,
+                                       "-------------------------------------> DVB-S LOCK !");
+
+//                             stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors     */
+//                             internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+//                             internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+//                             dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
+//                             dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
+
+                               return DVBFE_ALGO_SEARCH_SUCCESS;
+                       } else {
+                               internal->lock          = 0;
+
+                               return DVBFE_ALGO_SEARCH_FAILED;
+                       }
+                       break;
+               case SYS_DVBS2:
+                       internal->freq                  = i_params->freq;
+                       internal->srate                 = i_params->srate;
+                       internal->srch_range            = SearchRange;
+
+                       /* enable tuner I/O */
+                       stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+                       if (state->config->tuner_set_bandwidth)
+                               state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
+                       if (state->config->tuner_get_bandwidth)
+                               state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+                       /* disable tuner I/O */
+                       stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+//                     pParams->SpectralInv            = pSearch->IQ_Inversion;
+
+                       /* Set DVB-S2 AGC               */
+                       stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
+
+                       /* Set IterScale =f(MCLK,SYMB)  */
+                       stb0899_set_iterations(state);
+
+                       /* Run the search algorithm     */
+                       dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
+                       if (stb0899_dvbs2_algo(state)   == DVBS2_FEC_LOCK) {
+                               internal->lock          = 1;
+                               dprintk(state->verbose, FE_DEBUG, 1,
+                                       "-------------------------------------> DVB-S2 LOCK !");
+
+//                             stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors      */
+//                             internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+//                             internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+
+                               return DVBFE_ALGO_SEARCH_SUCCESS;
+                       } else {
+                               internal->lock          = 0;
+
+                               return DVBFE_ALGO_SEARCH_FAILED;
+                       }
+                       break;
+               default:
+                       dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
+                       return DVBFE_ALGO_SEARCH_INVALID;
+               }
+       }
+
+       return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int stb0899_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stb0899_state *state             = fe->demodulator_priv;
+       struct stb0899_internal *internal       = &state->internal;
+
+       dprintk(state->verbose, FE_DEBUG, 1, "Get params");
+       p->symbol_rate = internal->srate;
+
+       return 0;
+}
+
+static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+static struct dvb_frontend_ops stb0899_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
+       .info = {
+               .name                   = "STB0899 Multistandard",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 0,
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        =  5000000,
+               .symbol_rate_max        = 45000000,
+
+               .caps                   = FE_CAN_INVERSION_AUTO |
+                                         FE_CAN_FEC_AUTO       |
+                                         FE_CAN_2G_MODULATION  |
+                                         FE_CAN_QPSK
+       },
+
+       .release                        = stb0899_release,
+       .init                           = stb0899_init,
+       .sleep                          = stb0899_sleep,
+//     .wakeup                         = stb0899_wakeup,
+
+       .i2c_gate_ctrl                  = stb0899_i2c_gate_ctrl,
+
+       .get_frontend_algo              = stb0899_frontend_algo,
+       .search                         = stb0899_search,
+       .get_frontend                   = stb0899_get_frontend,
+
+
+       .read_status                    = stb0899_read_status,
+       .read_snr                       = stb0899_read_snr,
+       .read_signal_strength           = stb0899_read_signal_strength,
+       .read_ber                       = stb0899_read_ber,
+
+       .set_voltage                    = stb0899_set_voltage,
+       .set_tone                       = stb0899_set_tone,
+
+       .diseqc_send_master_cmd         = stb0899_send_diseqc_msg,
+       .diseqc_recv_slave_reply        = stb0899_recv_slave_reply,
+       .diseqc_send_burst              = stb0899_send_diseqc_burst,
+};
+
+struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
+{
+       struct stb0899_state *state = NULL;
+       enum stb0899_inversion inversion;
+
+       state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       inversion                               = config->inversion;
+       state->verbose                          = &verbose;
+       state->config                           = config;
+       state->i2c                              = i2c;
+       state->frontend.ops                     = stb0899_ops;
+       state->frontend.demodulator_priv        = state;
+       state->internal.inversion               = inversion;
+
+       stb0899_wakeup(&state->frontend);
+       if (stb0899_get_dev_id(state) == -ENODEV) {
+               printk("%s: Exiting .. !\n", __func__);
+               goto error;
+       }
+
+       printk("%s: Attaching STB0899 \n", __func__);
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(stb0899_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
new file mode 100644 (file)
index 0000000..98b200c
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_DRV_H
+#define __STB0899_DRV_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "dvb_frontend.h"
+
+#define STB0899_TSMODE_SERIAL          1
+#define STB0899_CLKPOL_FALLING         2
+#define STB0899_CLKNULL_PARITY         3
+#define STB0899_SYNC_FORCED            4
+#define STB0899_FECMODE_DSS            5
+
+struct stb0899_s1_reg {
+       u16     address;
+       u8      data;
+};
+
+struct stb0899_s2_reg {
+       u16     offset;
+       u32     base_address;
+       u32     data;
+};
+
+enum stb0899_inversion {
+       IQ_SWAP_OFF     = 0,
+       IQ_SWAP_ON,
+       IQ_SWAP_AUTO
+};
+
+#define STB0899_GPIO00                         0xf140
+#define STB0899_GPIO01                         0xf141
+#define STB0899_GPIO02                         0xf142
+#define STB0899_GPIO03                         0xf143
+#define STB0899_GPIO04                         0xf144
+#define STB0899_GPIO05                         0xf145
+#define STB0899_GPIO06                         0xf146
+#define STB0899_GPIO07                         0xf147
+#define STB0899_GPIO08                         0xf148
+#define STB0899_GPIO09                         0xf149
+#define STB0899_GPIO10                         0xf14a
+#define STB0899_GPIO11                         0xf14b
+#define STB0899_GPIO12                         0xf14c
+#define STB0899_GPIO13                         0xf14d
+#define STB0899_GPIO14                         0xf14e
+#define STB0899_GPIO15                         0xf14f
+#define STB0899_GPIO16                         0xf150
+#define STB0899_GPIO17                         0xf151
+#define STB0899_GPIO18                         0xf152
+#define STB0899_GPIO19                         0xf153
+#define STB0899_GPIO20                         0xf154
+
+#define STB0899_GPIOPULLUP                     0x01 /* Output device is connected to Vdd */
+#define STB0899_GPIOPULLDN                     0x00 /* Output device is connected to Vss */
+
+#define STB0899_POSTPROC_GPIO_POWER            0x00
+#define STB0899_POSTPROC_GPIO_LOCK             0x01
+
+/*
+ * Post process output configuration control
+ * 1. POWER ON/OFF             (index 0)
+ * 2. FE_HAS_LOCK/LOCK_LOSS    (index 1)
+ *
+ * @gpio       = one of the above listed GPIO's
+ * @level      = output state: pulled up or low
+ */
+struct stb0899_postproc {
+       u16     gpio;
+       u8      level;
+};
+
+struct stb0899_config {
+       const struct stb0899_s1_reg     *init_dev;
+       const struct stb0899_s2_reg     *init_s2_demod;
+       const struct stb0899_s1_reg     *init_s1_demod;
+       const struct stb0899_s2_reg     *init_s2_fec;
+       const struct stb0899_s1_reg     *init_tst;
+
+       const struct stb0899_postproc   *postproc;
+
+       enum stb0899_inversion          inversion;
+
+       u32     xtal_freq;
+
+       u8      demod_address;
+       u8      ts_output_mode;
+       u8      block_sync_mode;
+       u8      ts_pfbit_toggle;
+
+       u8      clock_polarity;
+       u8      data_clk_parity;
+       u8      fec_mode;
+       u8      data_output_ctl;
+       u8      data_fifo_mode;
+       u8      out_rate_comp;
+       u8      i2c_repeater;
+//     int     inversion;
+       int     lo_clk;
+       int     hi_clk;
+
+       u32     esno_ave;
+       u32     esno_quant;
+       u32     avframes_coarse;
+       u32     avframes_fine;
+       u32     miss_threshold;
+       u32     uwp_threshold_acq;
+       u32     uwp_threshold_track;
+       u32     uwp_threshold_sof;
+       u32     sof_search_timeout;
+
+       u32     btr_nco_bits;
+       u32     btr_gain_shift_offset;
+       u32     crl_nco_bits;
+       u32     ldpc_max_iter;
+
+       int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
+       int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
+       int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+       int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+       int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
+};
+
+#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
+                                          struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif //CONFIG_DVB_STB0899
+
+
+#endif
diff --git a/drivers/media/dvb-frontends/stb0899_priv.h b/drivers/media/dvb-frontends/stb0899_priv.h
new file mode 100644 (file)
index 0000000..82395b9
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_PRIV_H
+#define __STB0899_PRIV_H
+
+#include "dvb_frontend.h"
+#include "stb0899_drv.h"
+
+#define FE_ERROR                               0
+#define FE_NOTICE                              1
+#define FE_INFO                                        2
+#define FE_DEBUG                               3
+#define FE_DEBUGREG                            4
+
+#define dprintk(x, y, z, format, arg...) do {                                          \
+       if (z) {                                                                        \
+               if      ((*x > FE_ERROR) && (*x > y))                                   \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
+               else if ((*x > FE_NOTICE) && (*x > y))                                  \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((*x > FE_INFO) && (*x > y))                                    \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
+               else if ((*x > FE_DEBUG) && (*x > y))                                   \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (*x > y)                                                             \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while(0)
+
+#define INRANGE(val, x, y)                     (((x <= val) && (val <= y)) ||          \
+                                                ((y <= val) && (val <= x)) ? 1 : 0)
+
+#define BYTE0                                  0
+#define BYTE1                                  8
+#define BYTE2                                  16
+#define BYTE3                                  24
+
+#define GETBYTE(x, y)                          (((x) >> (y)) & 0xff)
+#define MAKEWORD32(a, b, c, d)                 (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+#define MAKEWORD16(a, b)                       (((a) << 8) | (b))
+
+#define LSB(x)                                 ((x & 0xff))
+#define MSB(y)                                 ((y >> 8) & 0xff)
+
+
+#define STB0899_GETFIELD(bitf, val)            ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
+
+
+#define STB0899_SETFIELD(mask, val, width, offset)      (mask & (~(((1 << width) - 1) <<       \
+                                                        offset))) | ((val &                    \
+                                                        ((1 << width) - 1)) << offset)
+
+#define STB0899_SETFIELD_VAL(bitf, mask, val)  (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
+                                                        STB0899_OFFST_##bitf))) | \
+                                                        (val << STB0899_OFFST_##bitf))
+
+
+enum stb0899_status {
+       NOAGC1  = 0,
+       AGC1OK,
+       NOTIMING,
+       ANALOGCARRIER,
+       TIMINGOK,
+       NOAGC2,
+       AGC2OK,
+       NOCARRIER,
+       CARRIEROK,
+       NODATA,
+       FALSELOCK,
+       DATAOK,
+       OUTOFRANGE,
+       RANGEOK,
+       DVBS2_DEMOD_LOCK,
+       DVBS2_DEMOD_NOLOCK,
+       DVBS2_FEC_LOCK,
+       DVBS2_FEC_NOLOCK
+};
+
+enum stb0899_modcod {
+       STB0899_DUMMY_PLF,
+       STB0899_QPSK_14,
+       STB0899_QPSK_13,
+       STB0899_QPSK_25,
+       STB0899_QPSK_12,
+       STB0899_QPSK_35,
+       STB0899_QPSK_23,
+       STB0899_QPSK_34,
+       STB0899_QPSK_45,
+       STB0899_QPSK_56,
+       STB0899_QPSK_89,
+       STB0899_QPSK_910,
+       STB0899_8PSK_35,
+       STB0899_8PSK_23,
+       STB0899_8PSK_34,
+       STB0899_8PSK_56,
+       STB0899_8PSK_89,
+       STB0899_8PSK_910,
+       STB0899_16APSK_23,
+       STB0899_16APSK_34,
+       STB0899_16APSK_45,
+       STB0899_16APSK_56,
+       STB0899_16APSK_89,
+       STB0899_16APSK_910,
+       STB0899_32APSK_34,
+       STB0899_32APSK_45,
+       STB0899_32APSK_56,
+       STB0899_32APSK_89,
+       STB0899_32APSK_910
+};
+
+enum stb0899_frame {
+       STB0899_LONG_FRAME,
+       STB0899_SHORT_FRAME
+};
+
+enum stb0899_alpha {
+       RRC_20,
+       RRC_25,
+       RRC_35
+};
+
+struct stb0899_tab {
+       s32 real;
+       s32 read;
+};
+
+enum stb0899_fec {
+       STB0899_FEC_1_2                 = 13,
+       STB0899_FEC_2_3                 = 18,
+       STB0899_FEC_3_4                 = 21,
+       STB0899_FEC_5_6                 = 24,
+       STB0899_FEC_6_7                 = 25,
+       STB0899_FEC_7_8                 = 26
+};
+
+struct stb0899_params {
+       u32     freq;                                   /* Frequency    */
+       u32     srate;                                  /* Symbol rate  */
+       enum fe_code_rate fecrate;
+};
+
+struct stb0899_internal {
+       u32                     master_clk;
+       u32                     freq;                   /* Demod internal Frequency             */
+       u32                     srate;                  /* Demod internal Symbol rate           */
+       enum stb0899_fec        fecrate;                /* Demod internal FEC rate              */
+       s32                     srch_range;             /* Demod internal Search Range          */
+       s32                     sub_range;              /* Demod current sub range (Hz)         */
+       s32                     tuner_step;             /* Tuner step (Hz)                      */
+       s32                     tuner_offst;            /* Relative offset to carrier (Hz)      */
+       u32                     tuner_bw;               /* Current bandwidth of the tuner (Hz)  */
+
+       s32                     mclk;                   /* Masterclock Divider factor (binary)  */
+       s32                     rolloff;                /* Current RollOff of the filter (x100) */
+
+       s16                     derot_freq;             /* Current derotator frequency (Hz)     */
+       s16                     derot_percent;
+
+       s16                     direction;              /* Current derotator search direction   */
+       s16                     derot_step;             /* Derotator step (binary value)        */
+       s16                     t_derot;                /* Derotator time constant (ms)         */
+       s16                     t_data;                 /* Data recovery time constant (ms)     */
+       s16                     sub_dir;                /* Direction of the next sub range      */
+
+       s16                     t_agc1;                 /* Agc1 time constant (ms)              */
+       s16                     t_agc2;                 /* Agc2 time constant (ms)              */
+
+       u32                     lock;                   /* Demod internal lock state            */
+       enum stb0899_status     status;                 /* Demod internal status                */
+
+       /* DVB-S2 */
+       s32                     agc_gain;               /* RF AGC Gain                          */
+       s32                     center_freq;            /* Nominal carrier frequency            */
+       s32                     av_frame_coarse;        /* Coarse carrier freq search frames    */
+       s32                     av_frame_fine;          /* Fine carrier freq search frames      */
+
+       s16                     step_size;              /* Carrier frequency search step size   */
+
+       enum stb0899_alpha      rrc_alpha;
+       enum stb0899_inversion  inversion;
+       enum stb0899_modcod     modcod;
+       u8                      pilots;                 /* Pilots found                         */
+
+       enum stb0899_frame      frame_length;
+       u8                      v_status;               /* VSTATUS                              */
+       u8                      err_ctrl;               /* ERRCTRLn                             */
+};
+
+struct stb0899_state {
+       struct i2c_adapter              *i2c;
+       struct stb0899_config           *config;
+       struct dvb_frontend             frontend;
+
+       u32                             *verbose;       /* Cached module verbosity level        */
+
+       struct stb0899_internal         internal;       /* Device internal parameters           */
+
+       /*      cached params from API  */
+       enum fe_delivery_system         delsys;
+       struct stb0899_params           params;
+
+       u32                             rx_freq;        /* DiSEqC 2.0 receiver freq             */
+       struct mutex                    search_lock;
+};
+/* stb0899.c           */
+extern int stb0899_read_reg(struct stb0899_state *state,
+                           unsigned int reg);
+
+extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
+                              u32 stb0899_i2cdev,
+                              u32 stb0899_base_addr,
+                              u16 stb0899_reg_offset);
+
+extern int stb0899_read_regs(struct stb0899_state *state,
+                            unsigned int reg, u8 *buf,
+                            u32 count);
+
+extern int stb0899_write_regs(struct stb0899_state *state,
+                             unsigned int reg, u8 *data,
+                             u32 count);
+
+extern int stb0899_write_reg(struct stb0899_state *state,
+                            unsigned int reg,
+                            u8 data);
+
+extern int stb0899_write_s2reg(struct stb0899_state *state,
+                              u32 stb0899_i2cdev,
+                              u32 stb0899_base_addr,
+                              u16 stb0899_reg_offset,
+                              u32 stb0899_data);
+
+extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+
+
+#define STB0899_READ_S2REG(DEVICE, REG)        (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
+//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA)       (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
+
+/* stb0899_algo.c      */
+extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
+extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
+extern long stb0899_carr_width(struct stb0899_state *state);
+
+#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb-frontends/stb0899_reg.h b/drivers/media/dvb-frontends/stb0899_reg.h
new file mode 100644 (file)
index 0000000..ba1ed56
--- /dev/null
@@ -0,0 +1,2027 @@
+/*
+       STB0899 Multistandard Frontend driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_REG_H
+#define __STB0899_REG_H
+
+/*     S1      */
+#define STB0899_DEV_ID                         0xf000
+#define STB0899_CHIP_ID                                (0x0f << 4)
+#define STB0899_OFFST_CHIP_ID                  4
+#define STB0899_WIDTH_CHIP_ID                  4
+#define STB0899_CHIP_REL                       (0x0f << 0)
+#define STB0899_OFFST_CHIP_REL                 0
+#define STB0899_WIDTH_CHIP_REL                 4
+
+#define STB0899_DEMOD                          0xf40e
+#define STB0899_MODECOEFF                      (0x01 << 0)
+#define STB0899_OFFST_MODECOEFF                        0
+#define STB0899_WIDTH_MODECOEFF                        1
+
+#define STB0899_RCOMPC                         0xf410
+#define STB0899_AGC1CN                         0xf412
+#define STB0899_AGC1REF                                0xf413
+#define STB0899_RTC                            0xf417
+#define STB0899_TMGCFG                         0xf418
+#define STB0899_AGC2REF                                0xf419
+#define STB0899_TLSR                           0xf41a
+
+#define STB0899_CFD                            0xf41b
+#define STB0899_CFD_ON                         (0x01 << 7)
+#define STB0899_OFFST_CFD_ON                   7
+#define STB0899_WIDTH_CFD_ON                   1
+
+#define STB0899_ACLC                           0xf41c
+
+#define STB0899_BCLC                           0xf41d
+#define STB0899_OFFST_ALGO                     6
+#define STB0899_WIDTH_ALGO_QPSK2               2
+#define STB0899_ALGO_QPSK2                     (2 << 6)
+#define STB0899_ALGO_QPSK1                     (1 << 6)
+#define STB0899_ALGO_BPSK                      (0 << 6)
+#define STB0899_OFFST_BETA                     0
+#define STB0899_WIDTH_BETA                     6
+
+#define STB0899_EQON                           0xf41e
+#define STB0899_LDT                            0xf41f
+#define STB0899_LDT2                           0xf420
+#define STB0899_EQUALREF                       0xf425
+#define STB0899_TMGRAMP                                0xf426
+#define STB0899_TMGTHD                         0xf427
+#define STB0899_IDCCOMP                                0xf428
+#define STB0899_QDCCOMP                                0xf429
+#define STB0899_POWERI                         0xf42a
+#define STB0899_POWERQ                         0xf42b
+#define STB0899_RCOMP                          0xf42c
+
+#define STB0899_AGCIQIN                                0xf42e
+#define STB0899_AGCIQVALUE                     (0xff << 0)
+#define STB0899_OFFST_AGCIQVALUE               0
+#define STB0899_WIDTH_AGCIQVALUE               8
+
+#define STB0899_AGC2I1                         0xf436
+#define STB0899_AGC2I2                         0xf437
+
+#define STB0899_TLIR                           0xf438
+#define STB0899_TLIR_TMG_LOCK_IND              (0xff << 0)
+#define STB0899_OFFST_TLIR_TMG_LOCK_IND                0
+#define STB0899_WIDTH_TLIR_TMG_LOCK_IND                8
+
+#define STB0899_RTF                            0xf439
+#define STB0899_RTF_TIMING_LOOP_FREQ           (0xff << 0)
+#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ     0
+#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ     8
+
+#define STB0899_DSTATUS                                0xf43a
+#define STB0899_CARRIER_FOUND                  (0x01 << 7)
+#define STB0899_OFFST_CARRIER_FOUND            7
+#define STB0899_WIDTH_CARRIER_FOUND            1
+#define STB0899_TMG_LOCK                       (0x01 << 6)
+#define STB0899_OFFST_TMG_LOCK                 6
+#define STB0899_WIDTH_TMG_LOCK                 1
+#define STB0899_DEMOD_LOCK                     (0x01 << 5)
+#define STB0899_OFFST_DEMOD_LOCK               5
+#define STB0899_WIDTH_DEMOD_LOCK               1
+#define STB0899_TMG_AUTO                       (0x01 << 4)
+#define STB0899_OFFST_TMG_AUTO                 4
+#define STB0899_WIDTH_TMG_AUTO                 1
+#define STB0899_END_MAIN                       (0x01 << 3)
+#define STB0899_OFFST_END_MAIN                 3
+#define STB0899_WIDTH_END_MAIN                 1
+
+#define STB0899_LDI                            0xf43b
+#define STB0899_OFFST_LDI                      0
+#define STB0899_WIDTH_LDI                      8
+
+#define STB0899_CFRM                           0xf43e
+#define STB0899_OFFST_CFRM                     0
+#define STB0899_WIDTH_CFRM                     8
+
+#define STB0899_CFRL                           0xf43f
+#define STB0899_OFFST_CFRL                     0
+#define STB0899_WIDTH_CFRL                     8
+
+#define STB0899_NIRM                           0xf440
+#define STB0899_OFFST_NIRM                     0
+#define STB0899_WIDTH_NIRM                     8
+
+#define STB0899_NIRL                           0xf441
+#define STB0899_OFFST_NIRL                     0
+#define STB0899_WIDTH_NIRL                     8
+
+#define STB0899_ISYMB                          0xf444
+#define STB0899_QSYMB                          0xf445
+
+#define STB0899_SFRH                           0xf446
+#define STB0899_OFFST_SFRH                     0
+#define STB0899_WIDTH_SFRH                     8
+
+#define STB0899_SFRM                           0xf447
+#define STB0899_OFFST_SFRM                     0
+#define STB0899_WIDTH_SFRM                     8
+
+#define STB0899_SFRL                           0xf448
+#define STB0899_OFFST_SFRL                     4
+#define STB0899_WIDTH_SFRL                     4
+
+#define STB0899_SFRUPH                         0xf44c
+#define STB0899_SFRUPM                         0xf44d
+#define STB0899_SFRUPL                         0xf44e
+
+#define STB0899_EQUAI1                         0xf4e0
+#define STB0899_EQUAQ1                         0xf4e1
+#define STB0899_EQUAI2                         0xf4e2
+#define STB0899_EQUAQ2                         0xf4e3
+#define STB0899_EQUAI3                         0xf4e4
+#define STB0899_EQUAQ3                         0xf4e5
+#define STB0899_EQUAI4                         0xf4e6
+#define STB0899_EQUAQ4                         0xf4e7
+#define STB0899_EQUAI5                         0xf4e8
+#define STB0899_EQUAQ5                         0xf4e9
+
+#define STB0899_DSTATUS2                       0xf50c
+#define STB0899_DS2_TMG_AUTOSRCH               (0x01 << 7)
+#define STB8999_OFFST_DS2_TMG_AUTOSRCH         7
+#define STB0899_WIDTH_DS2_TMG_AUTOSRCH         1
+#define STB0899_DS2_END_MAINLOOP               (0x01 << 6)
+#define STB0899_OFFST_DS2_END_MAINLOOP         6
+#define STB0899_WIDTH_DS2_END_MAINLOOP         1
+#define STB0899_DS2_CFSYNC                     (0x01 << 5)
+#define STB0899_OFFST_DS2_CFSYNC               5
+#define STB0899_WIDTH_DS2_CFSYNC               1
+#define STB0899_DS2_TMGLOCK                    (0x01 << 4)
+#define STB0899_OFFST_DS2_TMGLOCK              4
+#define STB0899_WIDTH_DS2_TMGLOCK              1
+#define STB0899_DS2_DEMODWAIT                  (0x01 << 3)
+#define STB0899_OFFST_DS2_DEMODWAIT            3
+#define STB0899_WIDTH_DS2_DEMODWAIT            1
+#define STB0899_DS2_FECON                      (0x01 << 1)
+#define STB0899_OFFST_DS2_FECON                        1
+#define STB0899_WIDTH_DS2_FECON                        1
+
+/*     S1 FEC  */
+#define STB0899_VSTATUS                                0xf50d
+#define STB0899_VSTATUS_VITERBI_ON             (0x01 << 7)
+#define STB0899_OFFST_VSTATUS_VITERBI_ON       7
+#define STB0899_WIDTH_VSTATUS_VITERBI_ON       1
+#define STB0899_VSTATUS_END_LOOPVIT            (0x01 << 6)
+#define STB0899_OFFST_VSTATUS_END_LOOPVIT      6
+#define STB0899_WIDTH_VSTATUS_END_LOOPVIT      1
+#define STB0899_VSTATUS_PRFVIT                 (0x01 << 4)
+#define STB0899_OFFST_VSTATUS_PRFVIT           4
+#define STB0899_WIDTH_VSTATUS_PRFVIT           1
+#define STB0899_VSTATUS_LOCKEDVIT              (0x01 << 3)
+#define STB0899_OFFST_VSTATUS_LOCKEDVIT                3
+#define STB0899_WIDTH_VSTATUS_LOCKEDVIT                1
+
+#define STB0899_VERROR                         0xf50f
+
+#define STB0899_IQSWAP                         0xf523
+#define STB0899_SYM                            (0x01 << 3)
+#define STB0899_OFFST_SYM                      3
+#define STB0899_WIDTH_SYM                      1
+
+#define STB0899_FECAUTO1                       0xf530
+#define STB0899_DSSSRCH                                (0x01 << 3)
+#define STB0899_OFFST_DSSSRCH                  3
+#define STB0899_WIDTH_DSSSRCH                  1
+#define STB0899_SYMSRCH                                (0x01 << 2)
+#define STB0899_OFFST_SYMSRCH                  2
+#define STB0899_WIDTH_SYMSRCH                  1
+#define STB0899_QPSKSRCH                       (0x01 << 1)
+#define STB0899_OFFST_QPSKSRCH                 1
+#define STB0899_WIDTH_QPSKSRCH                 1
+#define STB0899_BPSKSRCH                       (0x01 << 0)
+#define STB0899_OFFST_BPSKSRCH                 0
+#define STB0899_WIDTH_BPSKSRCH                 1
+
+#define STB0899_FECM                           0xf533
+#define STB0899_FECM_NOT_DVB                   (0x01 << 7)
+#define STB0899_OFFST_FECM_NOT_DVB             7
+#define STB0899_WIDTH_FECM_NOT_DVB             1
+#define STB0899_FECM_RSVD1                     (0x07 << 4)
+#define STB0899_OFFST_FECM_RSVD1               4
+#define STB0899_WIDTH_FECM_RSVD1               3
+#define STB0899_FECM_VITERBI_ON                        (0x01 << 3)
+#define STB0899_OFFST_FECM_VITERBI_ON          3
+#define STB0899_WIDTH_FECM_VITERBI_ON          1
+#define STB0899_FECM_RSVD0                     (0x01 << 2)
+#define STB0899_OFFST_FECM_RSVD0               2
+#define STB0899_WIDTH_FECM_RSVD0               1
+#define STB0899_FECM_SYNCDIS                   (0x01 << 1)
+#define STB0899_OFFST_FECM_SYNCDIS             1
+#define STB0899_WIDTH_FECM_SYNCDIS             1
+#define STB0899_FECM_SYMI                      (0x01 << 0)
+#define STB0899_OFFST_FECM_SYMI                        0
+#define STB0899_WIDTH_FECM_SYMI                        1
+
+#define STB0899_VTH12                          0xf534
+#define STB0899_VTH23                          0xf535
+#define STB0899_VTH34                          0xf536
+#define STB0899_VTH56                          0xf537
+#define STB0899_VTH67                          0xf538
+#define STB0899_VTH78                          0xf539
+
+#define STB0899_PRVIT                          0xf53c
+#define STB0899_PR_7_8                         (0x01 << 5)
+#define STB0899_OFFST_PR_7_8                   5
+#define STB0899_WIDTH_PR_7_8                   1
+#define STB0899_PR_6_7                         (0x01 << 4)
+#define STB0899_OFFST_PR_6_7                   4
+#define STB0899_WIDTH_PR_6_7                   1
+#define STB0899_PR_5_6                         (0x01 << 3)
+#define STB0899_OFFST_PR_5_6                   3
+#define STB0899_WIDTH_PR_5_6                   1
+#define STB0899_PR_3_4                         (0x01 << 2)
+#define STB0899_OFFST_PR_3_4                   2
+#define STB0899_WIDTH_PR_3_4                   1
+#define STB0899_PR_2_3                         (0x01 << 1)
+#define STB0899_OFFST_PR_2_3                   1
+#define STB0899_WIDTH_PR_2_3                   1
+#define STB0899_PR_1_2                         (0x01 << 0)
+#define STB0899_OFFST_PR_1_2                   0
+#define STB0899_WIDTH_PR_1_2                   1
+
+#define STB0899_VITSYNC                                0xf53d
+#define STB0899_AM                             (0x01 << 7)
+#define STB0899_OFFST_AM                       7
+#define STB0899_WIDTH_AM                       1
+#define STB0899_FREEZE                         (0x01 << 6)
+#define STB0899_OFFST_FREEZE                   6
+#define STB0899_WIDTH_FREEZE                   1
+#define STB0899_SN_65536                       (0x03 << 4)
+#define STB0899_OFFST_SN_65536                 4
+#define STB0899_WIDTH_SN_65536                 2
+#define STB0899_SN_16384                       (0x01 << 5)
+#define STB0899_OFFST_SN_16384                 5
+#define STB0899_WIDTH_SN_16384                 1
+#define STB0899_SN_4096                                (0x01 << 4)
+#define STB0899_OFFST_SN_4096                  4
+#define STB0899_WIDTH_SN_4096                  1
+#define STB0899_SN_1024                                (0x00 << 4)
+#define STB0899_OFFST_SN_1024                  4
+#define STB0899_WIDTH_SN_1024                  0
+#define STB0899_TO_128                         (0x03 << 2)
+#define STB0899_OFFST_TO_128                   2
+#define STB0899_WIDTH_TO_128                   2
+#define STB0899_TO_64                          (0x01 << 3)
+#define STB0899_OFFST_TO_64                    3
+#define STB0899_WIDTH_TO_64                    1
+#define STB0899_TO_32                          (0x01 << 2)
+#define STB0899_OFFST_TO_32                    2
+#define STB0899_WIDTH_TO_32                    1
+#define STB0899_TO_16                          (0x00 << 2)
+#define STB0899_OFFST_TO_16                    2
+#define STB0899_WIDTH_TO_16                    0
+#define STB0899_HYST_128                       (0x03 << 1)
+#define STB0899_OFFST_HYST_128                 1
+#define STB0899_WIDTH_HYST_128                 2
+#define STB0899_HYST_64                                (0x01 << 1)
+#define STB0899_OFFST_HYST_64                  1
+#define STB0899_WIDTH_HYST_64                  1
+#define STB0899_HYST_32                                (0x01 << 0)
+#define STB0899_OFFST_HYST_32                  0
+#define STB0899_WIDTH_HYST_32                  1
+#define STB0899_HYST_16                                (0x00 << 0)
+#define STB0899_OFFST_HYST_16                  0
+#define STB0899_WIDTH_HYST_16                  0
+
+#define STB0899_RSULC                          0xf548
+#define STB0899_ULDIL_ON                       (0x01 << 7)
+#define STB0899_OFFST_ULDIL_ON                 7
+#define STB0899_WIDTH_ULDIL_ON                 1
+#define STB0899_ULAUTO_ON                      (0x01 << 6)
+#define STB0899_OFFST_ULAUTO_ON                        6
+#define STB0899_WIDTH_ULAUTO_ON                        1
+#define STB0899_ULRS_ON                                (0x01 << 5)
+#define STB0899_OFFST_ULRS_ON                  5
+#define STB0899_WIDTH_ULRS_ON                  1
+#define STB0899_ULDESCRAM_ON                   (0x01 << 4)
+#define STB0899_OFFST_ULDESCRAM_ON             4
+#define STB0899_WIDTH_ULDESCRAM_ON             1
+#define STB0899_UL_DISABLE                     (0x01 << 2)
+#define STB0899_OFFST_UL_DISABLE               2
+#define STB0899_WIDTH_UL_DISABLE               1
+#define STB0899_NOFTHRESHOLD                   (0x01 << 0)
+#define STB0899_OFFST_NOFTHRESHOLD             0
+#define STB0899_WIDTH_NOFTHRESHOLD             1
+
+#define STB0899_RSLLC                          0xf54a
+#define STB0899_DEMAPVIT                       0xf583
+#define STB0899_DEMAPVIT_RSVD                  (0x01 << 7)
+#define STB0899_OFFST_DEMAPVIT_RSVD            7
+#define STB0899_WIDTH_DEMAPVIT_RSVD            1
+#define STB0899_DEMAPVIT_KDIVIDER              (0x7f << 0)
+#define STB0899_OFFST_DEMAPVIT_KDIVIDER                0
+#define STB0899_WIDTH_DEMAPVIT_KDIVIDER                7
+
+#define STB0899_PLPARM                         0xf58c
+#define STB0899_VITMAPPING                     (0x07 << 5)
+#define STB0899_OFFST_VITMAPPING               5
+#define STB0899_WIDTH_VITMAPPING               3
+#define STB0899_VITMAPPING_BPSK                        (0x01 << 5)
+#define STB0899_OFFST_VITMAPPING_BPSK          5
+#define STB0899_WIDTH_VITMAPPING_BPSK          1
+#define STB0899_VITMAPPING_QPSK                        (0x00 << 5)
+#define STB0899_OFFST_VITMAPPING_QPSK          5
+#define STB0899_WIDTH_VITMAPPING_QPSK          0
+#define STB0899_VITCURPUN                      (0x1f << 0)
+#define STB0899_OFFST_VITCURPUN                        0
+#define STB0899_WIDTH_VITCURPUN                        5
+#define STB0899_VITCURPUN_1_2                  (0x0d << 0)
+#define STB0899_VITCURPUN_2_3                  (0x12 << 0)
+#define STB0899_VITCURPUN_3_4                  (0x15 << 0)
+#define STB0899_VITCURPUN_5_6                  (0x18 << 0)
+#define STB0899_VITCURPUN_6_7                  (0x19 << 0)
+#define STB0899_VITCURPUN_7_8                  (0x1a << 0)
+
+/*     S2 DEMOD        */
+#define STB0899_OFF0_DMD_STATUS                        0xf300
+#define STB0899_BASE_DMD_STATUS                        0x00000000
+#define STB0899_IF_AGC_LOCK                    (0x01 << 8)
+#define STB0899_OFFST_IF_AGC_LOCK              0
+#define STB0899_WIDTH_IF_AGC_LOCK              1
+
+#define STB0899_OFF0_CRL_FREQ                  0xf304
+#define STB0899_BASE_CRL_FREQ                  0x00000000
+#define STB0899_CARR_FREQ                      (0x3fffffff << 0)
+#define STB0899_OFFST_CARR_FREQ                        0
+#define STB0899_WIDTH_CARR_FREQ                        30
+
+#define STB0899_OFF0_BTR_FREQ                  0xf308
+#define STB0899_BASE_BTR_FREQ                  0x00000000
+#define STB0899_BTR_FREQ                       (0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ                 0
+#define STB0899_WIDTH_BTR_FREQ                 28
+
+#define STB0899_OFF0_IF_AGC_GAIN               0xf30c
+#define STB0899_BASE_IF_AGC_GAIN               0x00000000
+#define STB0899_IF_AGC_GAIN                    (0x3fff < 0)
+#define STB0899_OFFST_IF_AGC_GAIN              0
+#define STB0899_WIDTH_IF_AGC_GAIN              14
+
+#define STB0899_OFF0_BB_AGC_GAIN               0xf310
+#define STB0899_BASE_BB_AGC_GAIN               0x00000000
+#define STB0899_BB_AGC_GAIN                    (0x3fff < 0)
+#define STB0899_OFFST_BB_AGC_GAIN              0
+#define STB0899_WIDTH_BB_AGC_GAIN              14
+
+#define STB0899_OFF0_DC_OFFSET                 0xf314
+#define STB0899_BASE_DC_OFFSET                 0x00000000
+#define STB0899_I                              (0xff < 8)
+#define STB0899_OFFST_I                                8
+#define STB0899_WIDTH_I                                8
+#define STB0899_Q                              (0xff < 0)
+#define STB0899_OFFST_Q                                8
+#define STB0899_WIDTH_Q                                8
+
+#define STB0899_OFF0_DMD_CNTRL                 0xf31c
+#define STB0899_BASE_DMD_CNTRL                 0x00000000
+#define STB0899_ADC0_PINS1IN                   (0x01 << 6)
+#define STB0899_OFFST_ADC0_PINS1IN              6
+#define STB0899_WIDTH_ADC0_PINS1IN              1
+#define STB0899_IN2COMP1_OFFBIN0               (0x01 << 3)
+#define STB0899_OFFST_IN2COMP1_OFFBIN0          3
+#define STB0899_WIDTH_IN2COMP1_OFFBIN0          1
+#define STB0899_DC_COMP                                (0x01 << 2)
+#define STB0899_OFFST_DC_COMP                  2
+#define STB0899_WIDTH_DC_COMP                  1
+#define STB0899_MODMODE                                (0x03 << 0)
+#define STB0899_OFFST_MODMODE                  0
+#define STB0899_WIDTH_MODMODE                  2
+
+#define STB0899_OFF0_IF_AGC_CNTRL              0xf320
+#define STB0899_BASE_IF_AGC_CNTRL              0x00000000
+#define STB0899_IF_GAIN_INIT                   (0x3fff << 13)
+#define STB0899_OFFST_IF_GAIN_INIT             13
+#define STB0899_WIDTH_IF_GAIN_INIT             14
+#define STB0899_IF_GAIN_SENSE                  (0x01 << 12)
+#define STB0899_OFFST_IF_GAIN_SENSE            12
+#define STB0899_WIDTH_IF_GAIN_SENSE            1
+#define STB0899_IF_LOOP_GAIN                   (0x0f << 8)
+#define STB0899_OFFST_IF_LOOP_GAIN             8
+#define STB0899_WIDTH_IF_LOOP_GAIN             4
+#define STB0899_IF_LD_GAIN_INIT                        (0x01 << 7)
+#define STB0899_OFFST_IF_LD_GAIN_INIT          7
+#define STB0899_WIDTH_IF_LD_GAIN_INIT          1
+#define STB0899_IF_AGC_REF                     (0x7f << 0)
+#define STB0899_OFFST_IF_AGC_REF               0
+#define STB0899_WIDTH_IF_AGC_REF               7
+
+#define STB0899_OFF0_BB_AGC_CNTRL              0xf324
+#define STB0899_BASE_BB_AGC_CNTRL              0x00000000
+#define STB0899_BB_GAIN_INIT                   (0x3fff << 12)
+#define STB0899_OFFST_BB_GAIN_INIT             12
+#define STB0899_WIDTH_BB_GAIN_INIT             14
+#define STB0899_BB_LOOP_GAIN                   (0x0f << 8)
+#define STB0899_OFFST_BB_LOOP_GAIN             8
+#define STB0899_WIDTH_BB_LOOP_GAIN             4
+#define STB0899_BB_LD_GAIN_INIT                        (0x01 << 7)
+#define STB0899_OFFST_BB_LD_GAIN_INIT          7
+#define STB0899_WIDTH_BB_LD_GAIN_INIT          1
+#define STB0899_BB_AGC_REF                     (0x7f << 0)
+#define STB0899_OFFST_BB_AGC_REF               0
+#define STB0899_WIDTH_BB_AGC_REF               7
+
+#define STB0899_OFF0_CRL_CNTRL                 0xf328
+#define STB0899_BASE_CRL_CNTRL                 0x00000000
+#define STB0899_CRL_LOCK_CLEAR                 (0x01 << 5)
+#define STB0899_OFFST_CRL_LOCK_CLEAR           5
+#define STB0899_WIDTH_CRL_LOCK_CLEAR           1
+#define STB0899_CRL_SWPR_CLEAR                 (0x01 << 4)
+#define STB0899_OFFST_CRL_SWPR_CLEAR           4
+#define STB0899_WIDTH_CRL_SWPR_CLEAR           1
+#define STB0899_CRL_SWP_ENA                    (0x01 << 3)
+#define STB0899_OFFST_CRL_SWP_ENA              3
+#define STB0899_WIDTH_CRL_SWP_ENA              1
+#define STB0899_CRL_DET_SEL                    (0x01 << 2)
+#define STB0899_OFFST_CRL_DET_SEL              2
+#define STB0899_WIDTH_CRL_DET_SEL              1
+#define STB0899_CRL_SENSE                      (0x01 << 1)
+#define STB0899_OFFST_CRL_SENSE                        1
+#define STB0899_WIDTH_CRL_SENSE                        1
+#define STB0899_CRL_PHSERR_CLEAR               (0x01 << 0)
+#define STB0899_OFFST_CRL_PHSERR_CLEAR         0
+#define STB0899_WIDTH_CRL_PHSERR_CLEAR         1
+
+#define STB0899_OFF0_CRL_PHS_INIT              0xf32c
+#define STB0899_BASE_CRL_PHS_INIT              0x00000000
+#define STB0899_CRL_PHS_INIT_31                        (0x1 << 30)
+#define STB0899_OFFST_CRL_PHS_INIT_31          30
+#define STB0899_WIDTH_CRL_PHS_INIT_31          1
+#define STB0899_CRL_LD_INIT_PHASE              (0x1 << 24)
+#define STB0899_OFFST_CRL_LD_INIT_PHASE                24
+#define STB0899_WIDTH_CRL_LD_INIT_PHASE                1
+#define STB0899_CRL_INIT_PHASE                 (0xffffff << 0)
+#define STB0899_OFFST_CRL_INIT_PHASE           0
+#define STB0899_WIDTH_CRL_INIT_PHASE           24
+
+#define STB0899_OFF0_CRL_FREQ_INIT             0xf330
+#define STB0899_BASE_CRL_FREQ_INIT             0x00000000
+#define STB0899_CRL_FREQ_INIT_31               (0x1 << 30)
+#define STB0899_OFFST_CRL_FREQ_INIT_31         30
+#define STB0899_WIDTH_CRL_FREQ_INIT_31         1
+#define STB0899_CRL_LD_FREQ_INIT               (0x1 << 24)
+#define STB0899_OFFST_CRL_LD_FREQ_INIT         24
+#define STB0899_WIDTH_CRL_LD_FREQ_INIT         1
+#define STB0899_CRL_FREQ_INIT                  (0xffffff << 0)
+#define STB0899_OFFST_CRL_FREQ_INIT            0
+#define STB0899_WIDTH_CRL_FREQ_INIT            24
+
+#define STB0899_OFF0_CRL_LOOP_GAIN             0xf334
+#define STB0899_BASE_CRL_LOOP_GAIN             0x00000000
+#define STB0899_KCRL2_RSHFT                    (0xf << 16)
+#define STB0899_OFFST_KCRL2_RSHFT              16
+#define STB0899_WIDTH_KCRL2_RSHFT              4
+#define STB0899_KCRL1                          (0xf << 12)
+#define STB0899_OFFST_KCRL1                    12
+#define STB0899_WIDTH_KCRL1                    4
+#define STB0899_KCRL1_RSHFT                    (0xf << 8)
+#define STB0899_OFFST_KCRL1_RSHFT              8
+#define STB0899_WIDTH_KCRL1_RSHFT              4
+#define STB0899_KCRL0                          (0xf << 4)
+#define STB0899_OFFST_KCRL0                    4
+#define STB0899_WIDTH_KCRL0                    4
+#define STB0899_KCRL0_RSHFT                    (0xf << 0)
+#define STB0899_OFFST_KCRL0_RSHFT              0
+#define STB0899_WIDTH_KCRL0_RSHFT              4
+
+#define STB0899_OFF0_CRL_NOM_FREQ              0xf338
+#define STB0899_BASE_CRL_NOM_FREQ              0x00000000
+#define STB0899_CRL_NOM_FREQ                   (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_NOM_FREQ             0
+#define STB0899_WIDTH_CRL_NOM_FREQ             30
+
+#define STB0899_OFF0_CRL_SWP_RATE              0xf33c
+#define STB0899_BASE_CRL_SWP_RATE              0x00000000
+#define STB0899_CRL_SWP_RATE                   (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_SWP_RATE             0
+#define STB0899_WIDTH_CRL_SWP_RATE             30
+
+#define STB0899_OFF0_CRL_MAX_SWP               0xf340
+#define STB0899_BASE_CRL_MAX_SWP               0x00000000
+#define STB0899_CRL_MAX_SWP                    (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_MAX_SWP              0
+#define STB0899_WIDTH_CRL_MAX_SWP              30
+
+#define STB0899_OFF0_CRL_LK_CNTRL              0xf344
+#define STB0899_BASE_CRL_LK_CNTRL              0x00000000
+
+#define STB0899_OFF0_DECIM_CNTRL               0xf348
+#define STB0899_BASE_DECIM_CNTRL               0x00000000
+#define STB0899_BAND_LIMIT_B                   (0x01 << 5)
+#define STB0899_OFFST_BAND_LIMIT_B             5
+#define STB0899_WIDTH_BAND_LIMIT_B             1
+#define STB0899_WIN_SEL                                (0x03 << 3)
+#define STB0899_OFFST_WIN_SEL                  3
+#define STB0899_WIDTH_WIN_SEL                  2
+#define STB0899_DECIM_RATE                     (0x07 << 0)
+#define STB0899_OFFST_DECIM_RATE               0
+#define STB0899_WIDTH_DECIM_RATE               3
+
+#define STB0899_OFF0_BTR_CNTRL                 0xf34c
+#define STB0899_BASE_BTR_CNTRL                 0x00000000
+#define STB0899_BTR_FREQ_CORR                  (0x7ff << 4)
+#define STB0899_OFFST_BTR_FREQ_CORR            4
+#define STB0899_WIDTH_BTR_FREQ_CORR            11
+#define STB0899_BTR_CLR_LOCK                   (0x01 << 3)
+#define STB0899_OFFST_BTR_CLR_LOCK             3
+#define STB0899_WIDTH_BTR_CLR_LOCK             1
+#define STB0899_BTR_SENSE                      (0x01 << 2)
+#define STB0899_OFFST_BTR_SENSE                        2
+#define STB0899_WIDTH_BTR_SENSE                        1
+#define STB0899_BTR_ERR_ENA                    (0x01 << 1)
+#define STB0899_OFFST_BTR_ERR_ENA              1
+#define STB0899_WIDTH_BTR_ERR_ENA              1
+#define STB0899_INTRP_PHS_SENSE                        (0x01 << 0)
+#define STB0899_OFFST_INTRP_PHS_SENSE          0
+#define STB0899_WIDTH_INTRP_PHS_SENSE          1
+
+#define STB0899_OFF0_BTR_LOOP_GAIN             0xf350
+#define STB0899_BASE_BTR_LOOP_GAIN             0x00000000
+#define STB0899_KBTR2_RSHFT                    (0x0f << 16)
+#define STB0899_OFFST_KBTR2_RSHFT              16
+#define STB0899_WIDTH_KBTR2_RSHFT              4
+#define STB0899_KBTR1                          (0x0f << 12)
+#define STB0899_OFFST_KBTR1                    12
+#define STB0899_WIDTH_KBTR1                    4
+#define STB0899_KBTR1_RSHFT                    (0x0f << 8)
+#define STB0899_OFFST_KBTR1_RSHFT              8
+#define STB0899_WIDTH_KBTR1_RSHFT              4
+#define STB0899_KBTR0                          (0x0f << 4)
+#define STB0899_OFFST_KBTR0                    4
+#define STB0899_WIDTH_KBTR0                    4
+#define STB0899_KBTR0_RSHFT                    (0x0f << 0)
+#define STB0899_OFFST_KBTR0_RSHFT              0
+#define STB0899_WIDTH_KBTR0_RSHFT              4
+
+#define STB0899_OFF0_BTR_PHS_INIT              0xf354
+#define STB0899_BASE_BTR_PHS_INIT              0x00000000
+#define STB0899_BTR_LD_PHASE_INIT              (0x01 << 28)
+#define STB0899_OFFST_BTR_LD_PHASE_INIT                28
+#define STB0899_WIDTH_BTR_LD_PHASE_INIT                1
+#define STB0899_BTR_INIT_PHASE                 (0xfffffff << 0)
+#define STB0899_OFFST_BTR_INIT_PHASE           0
+#define STB0899_WIDTH_BTR_INIT_PHASE           28
+
+#define STB0899_OFF0_BTR_FREQ_INIT             0xf358
+#define STB0899_BASE_BTR_FREQ_INIT             0x00000000
+#define STB0899_BTR_LD_FREQ_INIT               (1 << 28)
+#define STB0899_OFFST_BTR_LD_FREQ_INIT         28
+#define STB0899_WIDTH_BTR_LD_FREQ_INIT         1
+#define STB0899_BTR_FREQ_INIT                  (0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ_INIT            0
+#define STB0899_WIDTH_BTR_FREQ_INIT            28
+
+#define STB0899_OFF0_BTR_NOM_FREQ              0xf35c
+#define STB0899_BASE_BTR_NOM_FREQ              0x00000000
+#define STB0899_BTR_NOM_FREQ                   (0xfffffff << 0)
+#define STB0899_OFFST_BTR_NOM_FREQ             0
+#define STB0899_WIDTH_BTR_NOM_FREQ             28
+
+#define STB0899_OFF0_BTR_LK_CNTRL              0xf360
+#define STB0899_BASE_BTR_LK_CNTRL              0x00000000
+#define STB0899_BTR_MIN_ENERGY                 (0x0f << 24)
+#define STB0899_OFFST_BTR_MIN_ENERGY           24
+#define STB0899_WIDTH_BTR_MIN_ENERGY           4
+#define STB0899_BTR_LOCK_TH_LO                 (0xff << 16)
+#define STB0899_OFFST_BTR_LOCK_TH_LO           16
+#define STB0899_WIDTH_BTR_LOCK_TH_LO           8
+#define STB0899_BTR_LOCK_TH_HI                 (0xff << 8)
+#define STB0899_OFFST_BTR_LOCK_TH_HI           8
+#define STB0899_WIDTH_BTR_LOCK_TH_HI           8
+#define STB0899_BTR_LOCK_GAIN                  (0x03 << 6)
+#define STB0899_OFFST_BTR_LOCK_GAIN            6
+#define STB0899_WIDTH_BTR_LOCK_GAIN            2
+#define STB0899_BTR_LOCK_LEAK                  (0x3f << 0)
+#define STB0899_OFFST_BTR_LOCK_LEAK            0
+#define STB0899_WIDTH_BTR_LOCK_LEAK            6
+
+#define STB0899_OFF0_DECN_CNTRL                        0xf364
+#define STB0899_BASE_DECN_CNTRL                        0x00000000
+
+#define STB0899_OFF0_TP_CNTRL                  0xf368
+#define STB0899_BASE_TP_CNTRL                  0x00000000
+
+#define STB0899_OFF0_TP_BUF_STATUS             0xf36c
+#define STB0899_BASE_TP_BUF_STATUS             0x00000000
+#define STB0899_TP_BUFFER_FULL                  (1 << 0)
+
+#define STB0899_OFF0_DC_ESTIM                  0xf37c
+#define STB0899_BASE_DC_ESTIM                  0x0000
+#define STB0899_I_DC_ESTIMATE                  (0xff << 8)
+#define STB0899_OFFST_I_DC_ESTIMATE            8
+#define STB0899_WIDTH_I_DC_ESTIMATE            8
+#define STB0899_Q_DC_ESTIMATE                  (0xff << 0)
+#define STB0899_OFFST_Q_DC_ESTIMATE            0
+#define STB0899_WIDTH_Q_DC_ESTIMATE            8
+
+#define STB0899_OFF0_FLL_CNTRL                 0xf310
+#define STB0899_BASE_FLL_CNTRL                 0x00000020
+#define STB0899_CRL_FLL_ACC                    (0x01 << 4)
+#define STB0899_OFFST_CRL_FLL_ACC              4
+#define STB0899_WIDTH_CRL_FLL_ACC              1
+#define STB0899_FLL_AVG_PERIOD                 (0x0f << 0)
+#define STB0899_OFFST_FLL_AVG_PERIOD           0
+#define STB0899_WIDTH_FLL_AVG_PERIOD           4
+
+#define STB0899_OFF0_FLL_FREQ_WD               0xf314
+#define STB0899_BASE_FLL_FREQ_WD               0x00000020
+#define STB0899_FLL_FREQ_WD                    (0xffffffff << 0)
+#define STB0899_OFFST_FLL_FREQ_WD              0
+#define STB0899_WIDTH_FLL_FREQ_WD              32
+
+#define STB0899_OFF0_ANTI_ALIAS_SEL            0xf358
+#define STB0899_BASE_ANTI_ALIAS_SEL            0x00000020
+#define STB0899_ANTI_ALIAS_SELB                        (0x03 << 0)
+#define STB0899_OFFST_ANTI_ALIAS_SELB          0
+#define STB0899_WIDTH_ANTI_ALIAS_SELB          2
+
+#define STB0899_OFF0_RRC_ALPHA                 0xf35c
+#define STB0899_BASE_RRC_ALPHA                 0x00000020
+#define STB0899_RRC_ALPHA                      (0x03 << 0)
+#define STB0899_OFFST_RRC_ALPHA                        0
+#define STB0899_WIDTH_RRC_ALPHA                        2
+
+#define STB0899_OFF0_DC_ADAPT_LSHFT            0xf360
+#define STB0899_BASE_DC_ADAPT_LSHFT            0x00000020
+#define STB0899_DC_ADAPT_LSHFT                 (0x077 << 0)
+#define STB0899_OFFST_DC_ADAPT_LSHFT           0
+#define STB0899_WIDTH_DC_ADAPT_LSHFT           3
+
+#define STB0899_OFF0_IMB_OFFSET                        0xf364
+#define STB0899_BASE_IMB_OFFSET                        0x00000020
+#define STB0899_PHS_IMB_COMP                   (0xff << 8)
+#define STB0899_OFFST_PHS_IMB_COMP             8
+#define STB0899_WIDTH_PHS_IMB_COMP             8
+#define STB0899_AMPL_IMB_COMP                  (0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_COMP            0
+#define STB0899_WIDTH_AMPL_IMB_COMP            8
+
+#define STB0899_OFF0_IMB_ESTIMATE              0xf368
+#define STB0899_BASE_IMB_ESTIMATE              0x00000020
+#define STB0899_PHS_IMB_ESTIMATE               (0xff << 8)
+#define STB0899_OFFST_PHS_IMB_ESTIMATE         8
+#define STB0899_WIDTH_PHS_IMB_ESTIMATE         8
+#define STB0899_AMPL_IMB_ESTIMATE              (0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_ESTIMATE                0
+#define STB0899_WIDTH_AMPL_IMB_ESTIMATE                8
+
+#define STB0899_OFF0_IMB_CNTRL                 0xf36c
+#define STB0899_BASE_IMB_CNTRL                 0x00000020
+#define STB0899_PHS_ADAPT_LSHFT                        (0x07 << 4)
+#define STB0899_OFFST_PHS_ADAPT_LSHFT          4
+#define STB0899_WIDTH_PHS_ADAPT_LSHFT          3
+#define STB0899_AMPL_ADAPT_LSHFT               (0x07 << 1)
+#define STB0899_OFFST_AMPL_ADAPT_LSHFT         1
+#define STB0899_WIDTH_AMPL_ADAPT_LSHFT         3
+#define STB0899_IMB_COMP                       (0x01 << 0)
+#define STB0899_OFFST_IMB_COMP                 0
+#define STB0899_WIDTH_IMB_COMP                 1
+
+#define STB0899_OFF0_IF_AGC_CNTRL2             0xf374
+#define STB0899_BASE_IF_AGC_CNTRL2             0x00000020
+#define STB0899_IF_AGC_LOCK_TH                 (0xff << 11)
+#define STB0899_OFFST_IF_AGC_LOCK_TH           11
+#define STB0899_WIDTH_IF_AGC_LOCK_TH           8
+#define STB0899_IF_AGC_SD_DIV                  (0xff << 3)
+#define STB0899_OFFST_IF_AGC_SD_DIV            3
+#define STB0899_WIDTH_IF_AGC_SD_DIV            8
+#define STB0899_IF_AGC_DUMP_PER                        (0x07 << 0)
+#define STB0899_OFFST_IF_AGC_DUMP_PER          0
+#define STB0899_WIDTH_IF_AGC_DUMP_PER          3
+
+#define STB0899_OFF0_DMD_CNTRL2                        0xf378
+#define STB0899_BASE_DMD_CNTRL2                        0x00000020
+#define STB0899_SPECTRUM_INVERT                        (0x01 << 2)
+#define STB0899_OFFST_SPECTRUM_INVERT          2
+#define STB0899_WIDTH_SPECTRUM_INVERT          1
+#define STB0899_AGC_MODE                       (0x01 << 1)
+#define STB0899_OFFST_AGC_MODE                 1
+#define STB0899_WIDTH_AGC_MODE                 1
+#define STB0899_CRL_FREQ_ADJ                   (0x01 << 0)
+#define STB0899_OFFST_CRL_FREQ_ADJ             0
+#define STB0899_WIDTH_CRL_FREQ_ADJ             1
+
+#define STB0899_OFF0_TP_BUFFER                 0xf300
+#define STB0899_BASE_TP_BUFFER                 0x00000040
+#define STB0899_TP_BUFFER_IN                   (0xffff << 0)
+#define STB0899_OFFST_TP_BUFFER_IN             0
+#define STB0899_WIDTH_TP_BUFFER_IN             16
+
+#define STB0899_OFF0_TP_BUFFER1                        0xf304
+#define STB0899_BASE_TP_BUFFER1                        0x00000040
+#define STB0899_OFF0_TP_BUFFER2                        0xf308
+#define STB0899_BASE_TP_BUFFER2                        0x00000040
+#define STB0899_OFF0_TP_BUFFER3                        0xf30c
+#define STB0899_BASE_TP_BUFFER3                        0x00000040
+#define STB0899_OFF0_TP_BUFFER4                        0xf310
+#define STB0899_BASE_TP_BUFFER4                        0x00000040
+#define STB0899_OFF0_TP_BUFFER5                        0xf314
+#define STB0899_BASE_TP_BUFFER5                        0x00000040
+#define STB0899_OFF0_TP_BUFFER6                        0xf318
+#define STB0899_BASE_TP_BUFFER6                        0x00000040
+#define STB0899_OFF0_TP_BUFFER7                        0xf31c
+#define STB0899_BASE_TP_BUFFER7                        0x00000040
+#define STB0899_OFF0_TP_BUFFER8                        0xf320
+#define STB0899_BASE_TP_BUFFER8                        0x00000040
+#define STB0899_OFF0_TP_BUFFER9                        0xf324
+#define STB0899_BASE_TP_BUFFER9                        0x00000040
+#define STB0899_OFF0_TP_BUFFER10               0xf328
+#define STB0899_BASE_TP_BUFFER10               0x00000040
+#define STB0899_OFF0_TP_BUFFER11               0xf32c
+#define STB0899_BASE_TP_BUFFER11               0x00000040
+#define STB0899_OFF0_TP_BUFFER12               0xf330
+#define STB0899_BASE_TP_BUFFER12               0x00000040
+#define STB0899_OFF0_TP_BUFFER13               0xf334
+#define STB0899_BASE_TP_BUFFER13               0x00000040
+#define STB0899_OFF0_TP_BUFFER14               0xf338
+#define STB0899_BASE_TP_BUFFER14               0x00000040
+#define STB0899_OFF0_TP_BUFFER15               0xf33c
+#define STB0899_BASE_TP_BUFFER15               0x00000040
+#define STB0899_OFF0_TP_BUFFER16               0xf340
+#define STB0899_BASE_TP_BUFFER16               0x00000040
+#define STB0899_OFF0_TP_BUFFER17               0xf344
+#define STB0899_BASE_TP_BUFFER17               0x00000040
+#define STB0899_OFF0_TP_BUFFER18               0xf348
+#define STB0899_BASE_TP_BUFFER18               0x00000040
+#define STB0899_OFF0_TP_BUFFER19               0xf34c
+#define STB0899_BASE_TP_BUFFER19               0x00000040
+#define STB0899_OFF0_TP_BUFFER20               0xf350
+#define STB0899_BASE_TP_BUFFER20               0x00000040
+#define STB0899_OFF0_TP_BUFFER21               0xf354
+#define STB0899_BASE_TP_BUFFER21               0x00000040
+#define STB0899_OFF0_TP_BUFFER22               0xf358
+#define STB0899_BASE_TP_BUFFER22               0x00000040
+#define STB0899_OFF0_TP_BUFFER23               0xf35c
+#define STB0899_BASE_TP_BUFFER23               0x00000040
+#define STB0899_OFF0_TP_BUFFER24               0xf360
+#define STB0899_BASE_TP_BUFFER24               0x00000040
+#define STB0899_OFF0_TP_BUFFER25               0xf364
+#define STB0899_BASE_TP_BUFFER25               0x00000040
+#define STB0899_OFF0_TP_BUFFER26               0xf368
+#define STB0899_BASE_TP_BUFFER26               0x00000040
+#define STB0899_OFF0_TP_BUFFER27               0xf36c
+#define STB0899_BASE_TP_BUFFER27               0x00000040
+#define STB0899_OFF0_TP_BUFFER28               0xf370
+#define STB0899_BASE_TP_BUFFER28               0x00000040
+#define STB0899_OFF0_TP_BUFFER29               0xf374
+#define STB0899_BASE_TP_BUFFER29               0x00000040
+#define STB0899_OFF0_TP_BUFFER30               0xf378
+#define STB0899_BASE_TP_BUFFER30               0x00000040
+#define STB0899_OFF0_TP_BUFFER31               0xf37c
+#define STB0899_BASE_TP_BUFFER31               0x00000040
+#define STB0899_OFF0_TP_BUFFER32               0xf300
+#define STB0899_BASE_TP_BUFFER32               0x00000060
+#define STB0899_OFF0_TP_BUFFER33               0xf304
+#define STB0899_BASE_TP_BUFFER33               0x00000060
+#define STB0899_OFF0_TP_BUFFER34               0xf308
+#define STB0899_BASE_TP_BUFFER34               0x00000060
+#define STB0899_OFF0_TP_BUFFER35               0xf30c
+#define STB0899_BASE_TP_BUFFER35               0x00000060
+#define STB0899_OFF0_TP_BUFFER36               0xf310
+#define STB0899_BASE_TP_BUFFER36               0x00000060
+#define STB0899_OFF0_TP_BUFFER37               0xf314
+#define STB0899_BASE_TP_BUFFER37               0x00000060
+#define STB0899_OFF0_TP_BUFFER38               0xf318
+#define STB0899_BASE_TP_BUFFER38               0x00000060
+#define STB0899_OFF0_TP_BUFFER39               0xf31c
+#define STB0899_BASE_TP_BUFFER39               0x00000060
+#define STB0899_OFF0_TP_BUFFER40               0xf320
+#define STB0899_BASE_TP_BUFFER40               0x00000060
+#define STB0899_OFF0_TP_BUFFER41               0xf324
+#define STB0899_BASE_TP_BUFFER41               0x00000060
+#define STB0899_OFF0_TP_BUFFER42               0xf328
+#define STB0899_BASE_TP_BUFFER42               0x00000060
+#define STB0899_OFF0_TP_BUFFER43               0xf32c
+#define STB0899_BASE_TP_BUFFER43               0x00000060
+#define STB0899_OFF0_TP_BUFFER44               0xf330
+#define STB0899_BASE_TP_BUFFER44               0x00000060
+#define STB0899_OFF0_TP_BUFFER45               0xf334
+#define STB0899_BASE_TP_BUFFER45               0x00000060
+#define STB0899_OFF0_TP_BUFFER46               0xf338
+#define STB0899_BASE_TP_BUFFER46               0x00000060
+#define STB0899_OFF0_TP_BUFFER47               0xf33c
+#define STB0899_BASE_TP_BUFFER47               0x00000060
+#define STB0899_OFF0_TP_BUFFER48               0xf340
+#define STB0899_BASE_TP_BUFFER48               0x00000060
+#define STB0899_OFF0_TP_BUFFER49               0xf344
+#define STB0899_BASE_TP_BUFFER49               0x00000060
+#define STB0899_OFF0_TP_BUFFER50               0xf348
+#define STB0899_BASE_TP_BUFFER50               0x00000060
+#define STB0899_OFF0_TP_BUFFER51               0xf34c
+#define STB0899_BASE_TP_BUFFER51               0x00000060
+#define STB0899_OFF0_TP_BUFFER52               0xf350
+#define STB0899_BASE_TP_BUFFER52               0x00000060
+#define STB0899_OFF0_TP_BUFFER53               0xf354
+#define STB0899_BASE_TP_BUFFER53               0x00000060
+#define STB0899_OFF0_TP_BUFFER54               0xf358
+#define STB0899_BASE_TP_BUFFER54               0x00000060
+#define STB0899_OFF0_TP_BUFFER55               0xf35c
+#define STB0899_BASE_TP_BUFFER55               0x00000060
+#define STB0899_OFF0_TP_BUFFER56               0xf360
+#define STB0899_BASE_TP_BUFFER56               0x00000060
+#define STB0899_OFF0_TP_BUFFER57               0xf364
+#define STB0899_BASE_TP_BUFFER57               0x00000060
+#define STB0899_OFF0_TP_BUFFER58               0xf368
+#define STB0899_BASE_TP_BUFFER58               0x00000060
+#define STB0899_OFF0_TP_BUFFER59               0xf36c
+#define STB0899_BASE_TP_BUFFER59               0x00000060
+#define STB0899_OFF0_TP_BUFFER60               0xf370
+#define STB0899_BASE_TP_BUFFER60               0x00000060
+#define STB0899_OFF0_TP_BUFFER61               0xf374
+#define STB0899_BASE_TP_BUFFER61               0x00000060
+#define STB0899_OFF0_TP_BUFFER62               0xf378
+#define STB0899_BASE_TP_BUFFER62               0x00000060
+#define STB0899_OFF0_TP_BUFFER63               0xf37c
+#define STB0899_BASE_TP_BUFFER63               0x00000060
+
+#define STB0899_OFF0_RESET_CNTRL               0xf300
+#define STB0899_BASE_RESET_CNTRL               0x00000400
+#define STB0899_DVBS2_RESET                    (0x01 << 0)
+#define STB0899_OFFST_DVBS2_RESET              0
+#define STB0899_WIDTH_DVBS2_RESET              1
+
+#define STB0899_OFF0_ACM_ENABLE                        0xf304
+#define STB0899_BASE_ACM_ENABLE                        0x00000400
+#define STB0899_ACM_ENABLE                     1
+
+#define STB0899_OFF0_DESCR_CNTRL               0xf30c
+#define STB0899_BASE_DESCR_CNTRL               0x00000400
+#define STB0899_OFFST_DESCR_CNTRL               0
+#define STB0899_WIDTH_DESCR_CNTRL               16
+
+#define STB0899_OFF0_UWP_CNTRL1                        0xf320
+#define STB0899_BASE_UWP_CNTRL1                        0x00000400
+#define STB0899_UWP_TH_SOF                     (0x7fff << 11)
+#define STB0899_OFFST_UWP_TH_SOF               11
+#define STB0899_WIDTH_UWP_TH_SOF               15
+#define STB0899_UWP_ESN0_QUANT                 (0xff << 3)
+#define STB0899_OFFST_UWP_ESN0_QUANT           3
+#define STB0899_WIDTH_UWP_ESN0_QUANT           8
+#define STB0899_UWP_ESN0_AVE                   (0x03 << 1)
+#define STB0899_OFFST_UWP_ESN0_AVE             1
+#define STB0899_WIDTH_UWP_ESN0_AVE             2
+#define STB0899_UWP_START                      (0x01 << 0)
+#define STB0899_OFFST_UWP_START                        0
+#define STB0899_WIDTH_UWP_START                        1
+
+#define STB0899_OFF0_UWP_CNTRL2                        0xf324
+#define STB0899_BASE_UWP_CNTRL2                        0x00000400
+#define STB0899_UWP_MISS_TH                    (0xff << 16)
+#define STB0899_OFFST_UWP_MISS_TH              16
+#define STB0899_WIDTH_UWP_MISS_TH              8
+#define STB0899_FE_FINE_TRK                    (0xff << 8)
+#define STB0899_OFFST_FE_FINE_TRK              8
+#define STB0899_WIDTH_FE_FINE_TRK              8
+#define STB0899_FE_COARSE_TRK                  (0xff << 0)
+#define STB0899_OFFST_FE_COARSE_TRK            0
+#define STB0899_WIDTH_FE_COARSE_TRK            8
+
+#define STB0899_OFF0_UWP_STAT1                 0xf328
+#define STB0899_BASE_UWP_STAT1                 0x00000400
+#define STB0899_UWP_STATE                      (0x03ff << 15)
+#define STB0899_OFFST_UWP_STATE                        15
+#define STB0899_WIDTH_UWP_STATE                        10
+#define STB0899_UW_MAX_PEAK                    (0x7fff << 0)
+#define STB0899_OFFST_UW_MAX_PEAK              0
+#define STB0899_WIDTH_UW_MAX_PEAK              15
+
+#define STB0899_OFF0_UWP_STAT2                 0xf32c
+#define STB0899_BASE_UWP_STAT2                 0x00000400
+#define STB0899_ESNO_EST                       (0x07ffff << 7)
+#define STB0899_OFFST_ESN0_EST                 7
+#define STB0899_WIDTH_ESN0_EST                 19
+#define STB0899_UWP_DECODE_MOD                 (0x7f << 0)
+#define STB0899_OFFST_UWP_DECODE_MOD           0
+#define STB0899_WIDTH_UWP_DECODE_MOD           7
+
+#define STB0899_OFF0_DMD_CORE_ID               0xf334
+#define STB0899_BASE_DMD_CORE_ID               0x00000400
+#define STB0899_CORE_ID                                (0xffffffff << 0)
+#define STB0899_OFFST_CORE_ID                  0
+#define STB0899_WIDTH_CORE_ID                  32
+
+#define STB0899_OFF0_DMD_VERSION_ID            0xf33c
+#define STB0899_BASE_DMD_VERSION_ID            0x00000400
+#define STB0899_VERSION_ID                     (0xff << 0)
+#define STB0899_OFFST_VERSION_ID               0
+#define STB0899_WIDTH_VERSION_ID               8
+
+#define STB0899_OFF0_DMD_STAT2                 0xf340
+#define STB0899_BASE_DMD_STAT2                 0x00000400
+#define STB0899_CSM_LOCK                       (0x01 << 1)
+#define STB0899_OFFST_CSM_LOCK                 1
+#define STB0899_WIDTH_CSM_LOCK                 1
+#define STB0899_UWP_LOCK                       (0x01 << 0)
+#define STB0899_OFFST_UWP_LOCK                 0
+#define STB0899_WIDTH_UWP_LOCK                 1
+
+#define STB0899_OFF0_FREQ_ADJ_SCALE            0xf344
+#define STB0899_BASE_FREQ_ADJ_SCALE            0x00000400
+#define STB0899_FREQ_ADJ_SCALE                 (0x0fff << 0)
+#define STB0899_OFFST_FREQ_ADJ_SCALE           0
+#define STB0899_WIDTH_FREQ_ADJ_SCALE           12
+
+#define STB0899_OFF0_UWP_CNTRL3                        0xf34c
+#define STB0899_BASE_UWP_CNTRL3                        0x00000400
+#define STB0899_UWP_TH_TRACK                   (0x7fff << 15)
+#define STB0899_OFFST_UWP_TH_TRACK             15
+#define STB0899_WIDTH_UWP_TH_TRACK             15
+#define STB0899_UWP_TH_ACQ                     (0x7fff << 0)
+#define STB0899_OFFST_UWP_TH_ACQ               0
+#define STB0899_WIDTH_UWP_TH_ACQ               15
+
+#define STB0899_OFF0_SYM_CLK_SEL               0xf350
+#define STB0899_BASE_SYM_CLK_SEL               0x00000400
+#define STB0899_SYM_CLK_SEL                    (0x03 << 0)
+#define STB0899_OFFST_SYM_CLK_SEL              0
+#define STB0899_WIDTH_SYM_CLK_SEL              2
+
+#define STB0899_OFF0_SOF_SRCH_TO               0xf354
+#define STB0899_BASE_SOF_SRCH_TO               0x00000400
+#define STB0899_SOF_SEARCH_TIMEOUT             (0x3fffff << 0)
+#define STB0899_OFFST_SOF_SEARCH_TIMEOUT       0
+#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT       22
+
+#define STB0899_OFF0_ACQ_CNTRL1                        0xf358
+#define STB0899_BASE_ACQ_CNTRL1                        0x00000400
+#define STB0899_FE_FINE_ACQ                    (0xff << 8)
+#define STB0899_OFFST_FE_FINE_ACQ              8
+#define STB0899_WIDTH_FE_FINE_ACQ              8
+#define STB0899_FE_COARSE_ACQ                  (0xff << 0)
+#define STB0899_OFFST_FE_COARSE_ACQ            0
+#define STB0899_WIDTH_FE_COARSE_ACQ            8
+
+#define STB0899_OFF0_ACQ_CNTRL2                        0xf35c
+#define STB0899_BASE_ACQ_CNTRL2                        0x00000400
+#define STB0899_ZIGZAG                         (0x01 << 25)
+#define STB0899_OFFST_ZIGZAG                   25
+#define STB0899_WIDTH_ZIGZAG                   1
+#define STB0899_NUM_STEPS                      (0xff << 17)
+#define STB0899_OFFST_NUM_STEPS                        17
+#define STB0899_WIDTH_NUM_STEPS                        8
+#define STB0899_FREQ_STEPSIZE                  (0x1ffff << 0)
+#define STB0899_OFFST_FREQ_STEPSIZE            0
+#define STB0899_WIDTH_FREQ_STEPSIZE            17
+
+#define STB0899_OFF0_ACQ_CNTRL3                        0xf360
+#define STB0899_BASE_ACQ_CNTRL3                        0x00000400
+#define STB0899_THRESHOLD_SCL                  (0x3f << 23)
+#define STB0899_OFFST_THRESHOLD_SCL            23
+#define STB0899_WIDTH_THRESHOLD_SCL            6
+#define STB0899_UWP_TH_SRCH                    (0x7fff << 8)
+#define STB0899_OFFST_UWP_TH_SRCH              8
+#define STB0899_WIDTH_UWP_TH_SRCH              15
+#define STB0899_AUTO_REACQUIRE                 (0x01 << 7)
+#define STB0899_OFFST_AUTO_REACQUIRE           7
+#define STB0899_WIDTH_AUTO_REACQUIRE           1
+#define STB0899_TRACK_LOCK_SEL                 (0x01 << 6)
+#define STB0899_OFFST_TRACK_LOCK_SEL           6
+#define STB0899_WIDTH_TRACK_LOCK_SEL           1
+#define STB0899_ACQ_SEARCH_MODE                        (0x03 << 4)
+#define STB0899_OFFST_ACQ_SEARCH_MODE          4
+#define STB0899_WIDTH_ACQ_SEARCH_MODE          2
+#define STB0899_CONFIRM_FRAMES                 (0x0f << 0)
+#define STB0899_OFFST_CONFIRM_FRAMES           0
+#define STB0899_WIDTH_CONFIRM_FRAMES           4
+
+#define STB0899_OFF0_FE_SETTLE                 0xf364
+#define STB0899_BASE_FE_SETTLE                 0x00000400
+#define STB0899_SETTLING_TIME                  (0x3fffff << 0)
+#define STB0899_OFFST_SETTLING_TIME            0
+#define STB0899_WIDTH_SETTLING_TIME            22
+
+#define STB0899_OFF0_AC_DWELL                  0xf368
+#define STB0899_BASE_AC_DWELL                  0x00000400
+#define STB0899_DWELL_TIME                     (0x3fffff << 0)
+#define STB0899_OFFST_DWELL_TIME               0
+#define STB0899_WIDTH_DWELL_TIME               22
+
+#define STB0899_OFF0_ACQUIRE_TRIG              0xf36c
+#define STB0899_BASE_ACQUIRE_TRIG              0x00000400
+#define STB0899_ACQUIRE                                (0x01 << 0)
+#define STB0899_OFFST_ACQUIRE                  0
+#define STB0899_WIDTH_ACQUIRE                  1
+
+#define STB0899_OFF0_LOCK_LOST                 0xf370
+#define STB0899_BASE_LOCK_LOST                 0x00000400
+#define STB0899_LOCK_LOST                      (0x01 << 0)
+#define STB0899_OFFST_LOCK_LOST                        0
+#define STB0899_WIDTH_LOCK_LOST                        1
+
+#define STB0899_OFF0_ACQ_STAT1                 0xf374
+#define STB0899_BASE_ACQ_STAT1                 0x00000400
+#define STB0899_STEP_FREQ                      (0x1fffff << 11)
+#define STB0899_OFFST_STEP_FREQ                        11
+#define STB0899_WIDTH_STEP_FREQ                        21
+#define STB0899_ACQ_STATE                      (0x07 << 8)
+#define STB0899_OFFST_ACQ_STATE                        8
+#define STB0899_WIDTH_ACQ_STATE                        3
+#define STB0899_UW_DETECT_COUNT                        (0xff << 0)
+#define STB0899_OFFST_UW_DETECT_COUNT          0
+#define STB0899_WIDTH_UW_DETECT_COUNT          8
+
+#define STB0899_OFF0_ACQ_TIMEOUT               0xf378
+#define STB0899_BASE_ACQ_TIMEOUT               0x00000400
+#define STB0899_ACQ_TIMEOUT                    (0x3fffff << 0)
+#define STB0899_OFFST_ACQ_TIMEOUT              0
+#define STB0899_WIDTH_ACQ_TIMEOUT              22
+
+#define STB0899_OFF0_ACQ_TIME                  0xf37c
+#define STB0899_BASE_ACQ_TIME                  0x00000400
+#define STB0899_ACQ_TIME_SYM                   (0xffffff << 0)
+#define STB0899_OFFST_ACQ_TIME_SYM             0
+#define STB0899_WIDTH_ACQ_TIME_SYM             24
+
+#define STB0899_OFF0_FINAL_AGC_CNTRL           0xf308
+#define STB0899_BASE_FINAL_AGC_CNTRL           0x00000440
+#define STB0899_FINAL_GAIN_INIT                        (0x3fff << 12)
+#define STB0899_OFFST_FINAL_GAIN_INIT          12
+#define STB0899_WIDTH_FINAL_GAIN_INIT          14
+#define STB0899_FINAL_LOOP_GAIN                        (0x0f << 8)
+#define STB0899_OFFST_FINAL_LOOP_GAIN          8
+#define STB0899_WIDTH_FINAL_LOOP_GAIN          4
+#define STB0899_FINAL_LD_GAIN_INIT             (0x01 << 7)
+#define STB0899_OFFST_FINAL_LD_GAIN_INIT       7
+#define STB0899_WIDTH_FINAL_LD_GAIN_INIT       1
+#define STB0899_FINAL_AGC_REF                  (0x7f << 0)
+#define STB0899_OFFST_FINAL_AGC_REF            0
+#define STB0899_WIDTH_FINAL_AGC_REF            7
+
+#define STB0899_OFF0_FINAL_AGC_GAIN            0xf30c
+#define STB0899_BASE_FINAL_AGC_GAIN            0x00000440
+#define STB0899_FINAL_AGC_GAIN                 (0x3fff << 0)
+#define STB0899_OFFST_FINAL_AGC_GAIN           0
+#define STB0899_WIDTH_FINAL_AGC_GAIN           14
+
+#define STB0899_OFF0_EQUALIZER_INIT            0xf310
+#define STB0899_BASE_EQUALIZER_INIT            0x00000440
+#define STB0899_EQ_SRST                                (0x01 << 1)
+#define STB0899_OFFST_EQ_SRST                  1
+#define STB0899_WIDTH_EQ_SRST                  1
+#define STB0899_EQ_INIT                                (0x01 << 0)
+#define STB0899_OFFST_EQ_INIT                  0
+#define STB0899_WIDTH_EQ_INIT                  1
+
+#define STB0899_OFF0_EQ_CNTRL                  0xf314
+#define STB0899_BASE_EQ_CNTRL                  0x00000440
+#define STB0899_EQ_ADAPT_MODE                  (0x01 << 18)
+#define STB0899_OFFST_EQ_ADAPT_MODE            18
+#define STB0899_WIDTH_EQ_ADAPT_MODE            1
+#define STB0899_EQ_DELAY                       (0x0f << 14)
+#define STB0899_OFFST_EQ_DELAY                 14
+#define STB0899_WIDTH_EQ_DELAY                 4
+#define STB0899_EQ_QUANT_LEVEL                 (0xff << 6)
+#define STB0899_OFFST_EQ_QUANT_LEVEL           6
+#define STB0899_WIDTH_EQ_QUANT_LEVEL           8
+#define STB0899_EQ_DISABLE_UPDATE              (0x01 << 5)
+#define STB0899_OFFST_EQ_DISABLE_UPDATE                5
+#define STB0899_WIDTH_EQ_DISABLE_UPDATE                1
+#define STB0899_EQ_BYPASS                      (0x01 << 4)
+#define STB0899_OFFST_EQ_BYPASS                        4
+#define STB0899_WIDTH_EQ_BYPASS                        1
+#define STB0899_EQ_SHIFT                       (0x0f << 0)
+#define STB0899_OFFST_EQ_SHIFT                 0
+#define STB0899_WIDTH_EQ_SHIFT                 4
+
+#define STB0899_OFF0_EQ_I_INIT_COEFF_0         0xf320
+#define STB0899_OFF1_EQ_I_INIT_COEFF_1         0xf324
+#define STB0899_OFF2_EQ_I_INIT_COEFF_2         0xf328
+#define STB0899_OFF3_EQ_I_INIT_COEFF_3         0xf32c
+#define STB0899_OFF4_EQ_I_INIT_COEFF_4         0xf330
+#define STB0899_OFF5_EQ_I_INIT_COEFF_5         0xf334
+#define STB0899_OFF6_EQ_I_INIT_COEFF_6         0xf338
+#define STB0899_OFF7_EQ_I_INIT_COEFF_7         0xf33c
+#define STB0899_OFF8_EQ_I_INIT_COEFF_8         0xf340
+#define STB0899_OFF9_EQ_I_INIT_COEFF_9         0xf344
+#define STB0899_OFFa_EQ_I_INIT_COEFF_10                0xf348
+#define STB0899_BASE_EQ_I_INIT_COEFF_N         0x00000440
+#define STB0899_EQ_I_INIT_COEFF_N              (0x0fff << 0)
+#define STB0899_OFFST_EQ_I_INIT_COEFF_N                0
+#define STB0899_WIDTH_EQ_I_INIT_COEFF_N                12
+
+#define STB0899_OFF0_EQ_Q_INIT_COEFF_0         0xf350
+#define STB0899_OFF1_EQ_Q_INIT_COEFF_1         0xf354
+#define STB0899_OFF2_EQ_Q_INIT_COEFF_2         0xf358
+#define STB0899_OFF3_EQ_Q_INIT_COEFF_3         0xf35c
+#define STB0899_OFF4_EQ_Q_INIT_COEFF_4         0xf360
+#define STB0899_OFF5_EQ_Q_INIT_COEFF_5         0xf364
+#define STB0899_OFF6_EQ_Q_INIT_COEFF_6         0xf368
+#define STB0899_OFF7_EQ_Q_INIT_COEFF_7         0xf36c
+#define STB0899_OFF8_EQ_Q_INIT_COEFF_8         0xf370
+#define STB0899_OFF9_EQ_Q_INIT_COEFF_9         0xf374
+#define STB0899_OFFa_EQ_Q_INIT_COEFF_10                0xf378
+#define STB0899_BASE_EQ_Q_INIT_COEFF_N         0x00000440
+#define STB0899_EQ_Q_INIT_COEFF_N              (0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_INIT_COEFF_N                0
+#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N                12
+
+#define STB0899_OFF0_EQ_I_OUT_COEFF_0          0xf300
+#define STB0899_OFF1_EQ_I_OUT_COEFF_1          0xf304
+#define STB0899_OFF2_EQ_I_OUT_COEFF_2          0xf308
+#define STB0899_OFF3_EQ_I_OUT_COEFF_3          0xf30c
+#define STB0899_OFF4_EQ_I_OUT_COEFF_4          0xf310
+#define STB0899_OFF5_EQ_I_OUT_COEFF_5          0xf314
+#define STB0899_OFF6_EQ_I_OUT_COEFF_6          0xf318
+#define STB0899_OFF7_EQ_I_OUT_COEFF_7          0xf31c
+#define STB0899_OFF8_EQ_I_OUT_COEFF_8          0xf320
+#define STB0899_OFF9_EQ_I_OUT_COEFF_9          0xf324
+#define STB0899_OFFa_EQ_I_OUT_COEFF_10         0xf328
+#define STB0899_BASE_EQ_I_OUT_COEFF_N          0x00000460
+#define STB0899_EQ_I_OUT_COEFF_N               (0x0fff << 0)
+#define STB0899_OFFST_EQ_I_OUT_COEFF_N         0
+#define STB0899_WIDTH_EQ_I_OUT_COEFF_N         12
+
+#define STB0899_OFF0_EQ_Q_OUT_COEFF_0          0xf330
+#define STB0899_OFF1_EQ_Q_OUT_COEFF_1          0xf334
+#define STB0899_OFF2_EQ_Q_OUT_COEFF_2          0xf338
+#define STB0899_OFF3_EQ_Q_OUT_COEFF_3          0xf33c
+#define STB0899_OFF4_EQ_Q_OUT_COEFF_4          0xf340
+#define STB0899_OFF5_EQ_Q_OUT_COEFF_5          0xf344
+#define STB0899_OFF6_EQ_Q_OUT_COEFF_6          0xf348
+#define STB0899_OFF7_EQ_Q_OUT_COEFF_7          0xf34c
+#define STB0899_OFF8_EQ_Q_OUT_COEFF_8          0xf350
+#define STB0899_OFF9_EQ_Q_OUT_COEFF_9          0xf354
+#define STB0899_OFFa_EQ_Q_OUT_COEFF_10         0xf358
+#define STB0899_BASE_EQ_Q_OUT_COEFF_N          0x00000460
+#define STB0899_EQ_Q_OUT_COEFF_N               (0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_OUT_COEFF_N         0
+#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N         12
+
+/*     S2 FEC  */
+#define STB0899_OFF0_BLOCK_LNGTH               0xfa04
+#define STB0899_BASE_BLOCK_LNGTH               0x00000000
+#define STB0899_BLOCK_LENGTH                   (0xff << 0)
+#define STB0899_OFFST_BLOCK_LENGTH             0
+#define STB0899_WIDTH_BLOCK_LENGTH             8
+
+#define STB0899_OFF0_ROW_STR                   0xfa08
+#define STB0899_BASE_ROW_STR                   0x00000000
+#define STB0899_ROW_STRIDE                     (0xff << 0)
+#define STB0899_OFFST_ROW_STRIDE               0
+#define STB0899_WIDTH_ROW_STRIDE               8
+
+#define STB0899_OFF0_MAX_ITER                  0xfa0c
+#define STB0899_BASE_MAX_ITER                  0x00000000
+#define STB0899_MAX_ITERATIONS                 (0xff << 0)
+#define STB0899_OFFST_MAX_ITERATIONS           0
+#define STB0899_WIDTH_MAX_ITERATIONS           8
+
+#define STB0899_OFF0_BN_END_ADDR               0xfa10
+#define STB0899_BASE_BN_END_ADDR               0x00000000
+#define STB0899_BN_END_ADDR                    (0x0fff << 0)
+#define STB0899_OFFST_BN_END_ADDR              0
+#define STB0899_WIDTH_BN_END_ADDR              12
+
+#define STB0899_OFF0_CN_END_ADDR               0xfa14
+#define STB0899_BASE_CN_END_ADDR               0x00000000
+#define STB0899_CN_END_ADDR                    (0x0fff << 0)
+#define STB0899_OFFST_CN_END_ADDR              0
+#define STB0899_WIDTH_CN_END_ADDR              12
+
+#define STB0899_OFF0_INFO_LENGTH               0xfa1c
+#define STB0899_BASE_INFO_LENGTH               0x00000000
+#define STB0899_INFO_LENGTH                    (0xff << 0)
+#define STB0899_OFFST_INFO_LENGTH              0
+#define STB0899_WIDTH_INFO_LENGTH              8
+
+#define STB0899_OFF0_BOT_ADDR                  0xfa20
+#define STB0899_BASE_BOT_ADDR                  0x00000000
+#define STB0899_BOTTOM_BASE_ADDR               (0x03ff << 0)
+#define STB0899_OFFST_BOTTOM_BASE_ADDR         0
+#define STB0899_WIDTH_BOTTOM_BASE_ADDR         10
+
+#define STB0899_OFF0_BCH_BLK_LN                        0xfa24
+#define STB0899_BASE_BCH_BLK_LN                        0x00000000
+#define STB0899_BCH_BLOCK_LENGTH               (0xffff << 0)
+#define STB0899_OFFST_BCH_BLOCK_LENGTH         0
+#define STB0899_WIDTH_BCH_BLOCK_LENGTH         16
+
+#define STB0899_OFF0_BCH_T                     0xfa28
+#define STB0899_BASE_BCH_T                     0x00000000
+#define STB0899_BCH_T                          (0x0f << 0)
+#define STB0899_OFFST_BCH_T                    0
+#define STB0899_WIDTH_BCH_T                    4
+
+#define STB0899_OFF0_CNFG_MODE                 0xfa00
+#define STB0899_BASE_CNFG_MODE                 0x00000800
+#define STB0899_MODCOD                         (0x1f << 2)
+#define STB0899_OFFST_MODCOD                   2
+#define STB0899_WIDTH_MODCOD                   5
+#define STB0899_MODCOD_SEL                     (0x01 << 1)
+#define STB0899_OFFST_MODCOD_SEL               1
+#define STB0899_WIDTH_MODCOD_SEL               1
+#define STB0899_CONFIG_MODE                    (0x01 << 0)
+#define STB0899_OFFST_CONFIG_MODE              0
+#define STB0899_WIDTH_CONFIG_MODE              1
+
+#define STB0899_OFF0_LDPC_STAT                 0xfa04
+#define STB0899_BASE_LDPC_STAT                 0x00000800
+#define STB0899_ITERATION                      (0xff << 3)
+#define STB0899_OFFST_ITERATION                        3
+#define STB0899_WIDTH_ITERATION                        8
+#define STB0899_LDPC_DEC_STATE                 (0x07 << 0)
+#define STB0899_OFFST_LDPC_DEC_STATE           0
+#define STB0899_WIDTH_LDPC_DEC_STATE           3
+
+#define STB0899_OFF0_ITER_SCALE                        0xfa08
+#define STB0899_BASE_ITER_SCALE                        0x00000800
+#define STB0899_ITERATION_SCALE                        (0xff << 0)
+#define STB0899_OFFST_ITERATION_SCALE          0
+#define STB0899_WIDTH_ITERATION_SCALE          8
+
+#define STB0899_OFF0_INPUT_MODE                        0xfa0c
+#define STB0899_BASE_INPUT_MODE                        0x00000800
+#define STB0899_SD_BLOCK1_STREAM0              (0x01 << 0)
+#define STB0899_OFFST_SD_BLOCK1_STREAM0                0
+#define STB0899_WIDTH_SD_BLOCK1_STREAM0                1
+
+#define STB0899_OFF0_LDPCDECRST                        0xfa10
+#define STB0899_BASE_LDPCDECRST                        0x00000800
+#define STB0899_LDPC_DEC_RST                   (0x01 << 0)
+#define STB0899_OFFST_LDPC_DEC_RST             0
+#define STB0899_WIDTH_LDPC_DEC_RST             1
+
+#define STB0899_OFF0_CLK_PER_BYTE_RW           0xfa14
+#define STB0899_BASE_CLK_PER_BYTE_RW           0x00000800
+#define STB0899_CLKS_PER_BYTE                  (0x0f << 0)
+#define STB0899_OFFST_CLKS_PER_BYTE            0
+#define STB0899_WIDTH_CLKS_PER_BYTE            5
+
+#define STB0899_OFF0_BCH_ERRORS                        0xfa18
+#define STB0899_BASE_BCH_ERRORS                        0x00000800
+#define STB0899_BCH_ERRORS                     (0x0f << 0)
+#define STB0899_OFFST_BCH_ERRORS               0
+#define STB0899_WIDTH_BCH_ERRORS               4
+
+#define STB0899_OFF0_LDPC_ERRORS               0xfa1c
+#define STB0899_BASE_LDPC_ERRORS               0x00000800
+#define STB0899_LDPC_ERRORS                    (0xffff << 0)
+#define STB0899_OFFST_LDPC_ERRORS              0
+#define STB0899_WIDTH_LDPC_ERRORS              16
+
+#define STB0899_OFF0_BCH_MODE                  0xfa20
+#define STB0899_BASE_BCH_MODE                  0x00000800
+#define STB0899_BCH_CORRECT_N                  (0x01 << 1)
+#define STB0899_OFFST_BCH_CORRECT_N            1
+#define STB0899_WIDTH_BCH_CORRECT_N            1
+#define STB0899_FULL_BYPASS                    (0x01 << 0)
+#define STB0899_OFFST_FULL_BYPASS              0
+#define STB0899_WIDTH_FULL_BYPASS              1
+
+#define STB0899_OFF0_ERR_ACC_PER               0xfa24
+#define STB0899_BASE_ERR_ACC_PER               0x00000800
+#define STB0899_BCH_ERR_ACC_PERIOD             (0x0f << 0)
+#define STB0899_OFFST_BCH_ERR_ACC_PERIOD       0
+#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD       4
+
+#define STB0899_OFF0_BCH_ERR_ACC               0xfa28
+#define STB0899_BASE_BCH_ERR_ACC               0x00000800
+#define STB0899_BCH_ERR_ACCUM                  (0xff << 0)
+#define STB0899_OFFST_BCH_ERR_ACCUM            0
+#define STB0899_WIDTH_BCH_ERR_ACCUM            8
+
+#define STB0899_OFF0_FEC_CORE_ID_REG           0xfa2c
+#define STB0899_BASE_FEC_CORE_ID_REG           0x00000800
+#define STB0899_FEC_CORE_ID                    (0xffffffff << 0)
+#define STB0899_OFFST_FEC_CORE_ID              0
+#define STB0899_WIDTH_FEC_CORE_ID              32
+
+#define STB0899_OFF0_FEC_VER_ID_REG            0xfa34
+#define STB0899_BASE_FEC_VER_ID_REG            0x00000800
+#define STB0899_FEC_VER_ID                     (0xff << 0)
+#define STB0899_OFFST_FEC_VER_ID               0
+#define STB0899_WIDTH_FEC_VER_ID               8
+
+#define STB0899_OFF0_FEC_TP_SEL                        0xfa38
+#define STB0899_BASE_FEC_TP_SEL                        0x00000800
+
+#define STB0899_OFF0_CSM_CNTRL1                        0xf310
+#define STB0899_BASE_CSM_CNTRL1                        0x00000400
+#define STB0899_CSM_FORCE_FREQLOCK             (0x01 << 19)
+#define STB0899_OFFST_CSM_FORCE_FREQLOCK       19
+#define STB0899_WIDTH_CSM_FORCE_FREQLOCK       1
+#define STB0899_CSM_FREQ_LOCKSTATE             (0x01 << 18)
+#define STB0899_OFFST_CSM_FREQ_LOCKSTATE       18
+#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE       1
+#define STB0899_CSM_AUTO_PARAM                 (0x01 << 17)
+#define STB0899_OFFST_CSM_AUTO_PARAM           17
+#define STB0899_WIDTH_CSM_AUTO_PARAM           1
+#define STB0899_FE_LOOP_SHIFT                  (0x07 << 14)
+#define STB0899_OFFST_FE_LOOP_SHIFT            14
+#define STB0899_WIDTH_FE_LOOP_SHIFT            3
+#define STB0899_CSM_AGC_SHIFT                  (0x07 << 11)
+#define STB0899_OFFST_CSM_AGC_SHIFT            11
+#define STB0899_WIDTH_CSM_AGC_SHIFT            3
+#define STB0899_CSM_AGC_GAIN                   (0x1ff << 2)
+#define STB0899_OFFST_CSM_AGC_GAIN             2
+#define STB0899_WIDTH_CSM_AGC_GAIN             9
+#define STB0899_CSM_TWO_PASS                   (0x01 << 1)
+#define STB0899_OFFST_CSM_TWO_PASS             1
+#define STB0899_WIDTH_CSM_TWO_PASS             1
+#define STB0899_CSM_DVT_TABLE                  (0x01 << 0)
+#define STB0899_OFFST_CSM_DVT_TABLE            0
+#define STB0899_WIDTH_CSM_DVT_TABLE            1
+
+#define STB0899_OFF0_CSM_CNTRL2                        0xf314
+#define STB0899_BASE_CSM_CNTRL2                        0x00000400
+#define STB0899_CSM_GAMMA_RHO_ACQ              (0x1ff << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOACQ         9
+#define STB0899_WIDTH_CSM_GAMMA_RHOACQ         9
+#define STB0899_CSM_GAMMA_ACQ                  (0x1ff << 0)
+#define STB0899_OFFST_CSM_GAMMA_ACQ            0
+#define STB0899_WIDTH_CSM_GAMMA_ACQ            9
+
+#define STB0899_OFF0_CSM_CNTRL3                        0xf318
+#define STB0899_BASE_CSM_CNTRL3                        0x00000400
+#define STB0899_CSM_GAMMA_RHO_TRACK            (0x1ff << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOTRACK       9
+#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK       9
+#define STB0899_CSM_GAMMA_TRACK                        (0x1ff << 0)
+#define STB0899_OFFST_CSM_GAMMA_TRACK          0
+#define STB0899_WIDTH_CSM_GAMMA_TRACK          9
+
+#define STB0899_OFF0_CSM_CNTRL4                        0xf31c
+#define STB0899_BASE_CSM_CNTRL4                        0x00000400
+#define STB0899_CSM_PHASEDIFF_THRESH           (0x0f << 8)
+#define STB0899_OFFST_CSM_PHASEDIFF_THRESH     8
+#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH     4
+#define STB0899_CSM_LOCKCOUNT_THRESH           (0xff << 0)
+#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH     0
+#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH     8
+
+/*     Check on chapter 8 page 42      */
+#define STB0899_ERRCTRL1                       0xf574
+#define STB0899_ERRCTRL2                       0xf575
+#define STB0899_ERRCTRL3                       0xf576
+#define STB0899_ERR_SRC_S1                     (0x1f << 3)
+#define STB0899_OFFST_ERR_SRC_S1               3
+#define STB0899_WIDTH_ERR_SRC_S1               5
+#define STB0899_ERR_SRC_S2                     (0x0f << 0)
+#define STB0899_OFFST_ERR_SRC_S2               0
+#define STB0899_WIDTH_ERR_SRC_S2               4
+#define STB0899_NOE                            (0x07 << 0)
+#define STB0899_OFFST_NOE                      0
+#define STB0899_WIDTH_NOE                      3
+
+#define STB0899_ECNT1M                         0xf524
+#define STB0899_ECNT1L                         0xf525
+#define STB0899_ECNT2M                         0xf526
+#define STB0899_ECNT2L                         0xf527
+#define STB0899_ECNT3M                         0xf528
+#define STB0899_ECNT3L                         0xf529
+
+#define STB0899_DMONMSK1                       0xf57b
+#define STB0899_DMONMSK1_WAIT_1STEP            (1 << 7)
+#define STB0899_DMONMSK1_FREE_14               (1 << 6)
+#define STB0899_DMONMSK1_AVRGVIT_CALC          (1 << 5)
+#define STB0899_DMONMSK1_FREE_12               (1 << 4)
+#define STB0899_DMONMSK1_FREE_11               (1 << 3)
+#define STB0899_DMONMSK1_B0DIV_CALC            (1 << 2)
+#define STB0899_DMONMSK1_KDIVB1_CALC           (1 << 1)
+#define STB0899_DMONMSK1_KDIVB2_CALC           (1 << 0)
+
+#define STB0899_DMONMSK0                       0xf57c
+#define STB0899_DMONMSK0_SMOTTH_CALC           (1 << 7)
+#define STB0899_DMONMSK0_FREE_6                        (1 << 6)
+#define STB0899_DMONMSK0_SIGPOWER_CALC         (1 << 5)
+#define STB0899_DMONMSK0_QSEUIL_CALC           (1 << 4)
+#define STB0899_DMONMSK0_FREE_3                        (1 << 3)
+#define STB0899_DMONMSK0_FREE_2                        (1 << 2)
+#define STB0899_DMONMSK0_KVDIVB1_CALC          (1 << 1)
+#define STB0899_DMONMSK0_KVDIVB2_CALC          (1 << 0)
+
+#define STB0899_TSULC                          0xf549
+#define STB0899_ULNOSYNCBYTES                  (0x01 << 7)
+#define STB0899_OFFST_ULNOSYNCBYTES            7
+#define STB0899_WIDTH_ULNOSYNCBYTES            1
+#define STB0899_ULPARITY_ON                    (0x01 << 6)
+#define STB0899_OFFST_ULPARITY_ON              6
+#define STB0899_WIDTH_ULPARITY_ON              1
+#define STB0899_ULSYNCOUTRS                    (0x01 << 5)
+#define STB0899_OFFST_ULSYNCOUTRS              5
+#define STB0899_WIDTH_ULSYNCOUTRS              1
+#define STB0899_ULDSS_PACKETS                  (0x01 << 0)
+#define STB0899_OFFST_ULDSS_PACKETS            0
+#define STB0899_WIDTH_ULDSS_PACKETS            1
+
+#define STB0899_TSLPL                          0xf54b
+#define STB0899_LLDVBS2_MODE                   (0x01 << 4)
+#define STB0899_OFFST_LLDVBS2_MODE             4
+#define STB0899_WIDTH_LLDVBS2_MODE             1
+#define STB0899_LLISSYI_ON                     (0x01 << 3)
+#define STB0899_OFFST_LLISSYI_ON               3
+#define STB0899_WIDTH_LLISSYI_ON               1
+#define STB0899_LLNPD_ON                       (0x01 << 2)
+#define STB0899_OFFST_LLNPD_ON                 2
+#define STB0899_WIDTH_LLNPD_ON                 1
+#define STB0899_LLCRC8_ON                      (0x01 << 1)
+#define STB0899_OFFST_LLCRC8_ON                        1
+#define STB0899_WIDTH_LLCRC8_ON                        1
+
+#define STB0899_TSCFGH                         0xf54c
+#define STB0899_OUTRS_PS                       (0x01 << 6)
+#define STB0899_OFFST_OUTRS_PS                 6
+#define STB0899_WIDTH_OUTRS_PS                 1
+#define STB0899_SYNCBYTE                       (0x01 << 5)
+#define STB0899_OFFST_SYNCBYTE                 5
+#define STB0899_WIDTH_SYNCBYTE                 1
+#define STB0899_PFBIT                          (0x01 << 4)
+#define STB0899_OFFST_PFBIT                    4
+#define STB0899_WIDTH_PFBIT                    1
+#define STB0899_ERR_BIT                                (0x01 << 3)
+#define STB0899_OFFST_ERR_BIT                  3
+#define STB0899_WIDTH_ERR_BIT                  1
+#define STB0899_MPEG                           (0x01 << 2)
+#define STB0899_OFFST_MPEG                     2
+#define STB0899_WIDTH_MPEG                     1
+#define STB0899_CLK_POL                                (0x01 << 1)
+#define STB0899_OFFST_CLK_POL                  1
+#define STB0899_WIDTH_CLK_POL                  1
+#define STB0899_FORCE0                         (0x01 << 0)
+#define STB0899_OFFST_FORCE0                   0
+#define STB0899_WIDTH_FORCE0                   1
+
+#define STB0899_TSCFGM                         0xf54d
+#define STB0899_LLPRIORITY                     (0x01 << 3)
+#define STB0899_OFFST_LLPRIORIY                        3
+#define STB0899_WIDTH_LLPRIORITY               1
+#define STB0899_EN188                          (0x01 << 2)
+#define STB0899_OFFST_EN188                    2
+#define STB0899_WIDTH_EN188                    1
+
+#define STB0899_TSCFGL                         0xf54e
+#define STB0899_DEL_ERRPCK                     (0x01 << 7)
+#define STB0899_OFFST_DEL_ERRPCK               7
+#define STB0899_WIDTH_DEL_ERRPCK               1
+#define STB0899_ERRFLAGSTD                     (0x01 << 5)
+#define STB0899_OFFST_ERRFLAGSTD               5
+#define STB0899_WIDTH_ERRFLAGSTD               1
+#define STB0899_MPEGERR                                (0x01 << 4)
+#define STB0899_OFFST_MPEGERR                  4
+#define STB0899_WIDTH_MPEGERR                  1
+#define STB0899_BCH_CHK                                (0x01 << 3)
+#define STB0899_OFFST_BCH_CHK                  5
+#define STB0899_WIDTH_BCH_CHK                  1
+#define STB0899_CRC8CHK                                (0x01 << 2)
+#define STB0899_OFFST_CRC8CHK                  2
+#define STB0899_WIDTH_CRC8CHK                  1
+#define STB0899_SPEC_INFO                      (0x01 << 1)
+#define STB0899_OFFST_SPEC_INFO                        1
+#define STB0899_WIDTH_SPEC_INFO                        1
+#define STB0899_LOW_PRIO_CLK                   (0x01 << 0)
+#define STB0899_OFFST_LOW_PRIO_CLK             0
+#define STB0899_WIDTH_LOW_PRIO_CLK             1
+#define STB0899_ERROR_NORM                     (0x00 << 0)
+#define STB0899_OFFST_ERROR_NORM               0
+#define STB0899_WIDTH_ERROR_NORM               0
+
+#define STB0899_TSOUT                          0xf54f
+#define STB0899_RSSYNCDEL                      0xf550
+#define STB0899_TSINHDELH                      0xf551
+#define STB0899_TSINHDELM                      0xf552
+#define STB0899_TSINHDELL                      0xf553
+#define STB0899_TSLLSTKM                       0xf55a
+#define STB0899_TSLLSTKL                       0xf55b
+#define STB0899_TSULSTKM                       0xf55c
+#define STB0899_TSULSTKL                       0xf55d
+#define STB0899_TSSTATUS                       0xf561
+
+#define STB0899_PDELCTRL                       0xf600
+#define STB0899_INVERT_RES                     (0x01 << 7)
+#define STB0899_OFFST_INVERT_RES               7
+#define STB0899_WIDTH_INVERT_RES               1
+#define STB0899_FORCE_ACCEPTED                 (0x01 << 6)
+#define STB0899_OFFST_FORCE_ACCEPTED           6
+#define STB0899_WIDTH_FORCE_ACCEPTED           1
+#define STB0899_FILTER_EN                      (0x01 << 5)
+#define STB0899_OFFST_FILTER_EN                        5
+#define STB0899_WIDTH_FILTER_EN                        1
+#define STB0899_LOCKFALL_THRESH                        (0x01 << 4)
+#define STB0899_OFFST_LOCKFALL_THRESH          4
+#define STB0899_WIDTH_LOCKFALL_THRESH          1
+#define STB0899_HYST_EN                                (0x01 << 3)
+#define STB0899_OFFST_HYST_EN                  3
+#define STB0899_WIDTH_HYST_EN                  1
+#define STB0899_HYST_SWRST                     (0x01 << 2)
+#define STB0899_OFFST_HYST_SWRST               2
+#define STB0899_WIDTH_HYST_SWRST               1
+#define STB0899_ALGO_EN                                (0x01 << 1)
+#define STB0899_OFFST_ALGO_EN                  1
+#define STB0899_WIDTH_ALGO_EN                  1
+#define STB0899_ALGO_SWRST                     (0x01 << 0)
+#define STB0899_OFFST_ALGO_SWRST               0
+#define STB0899_WIDTH_ALGO_SWRST               1
+
+#define STB0899_PDELCTRL2                      0xf601
+#define STB0899_BBHCTRL1                       0xf602
+#define STB0899_BBHCTRL2                       0xf603
+#define STB0899_HYSTTHRESH                     0xf604
+
+#define STB0899_MATCSTM                                0xf605
+#define STB0899_MATCSTL                                0xf606
+#define STB0899_UPLCSTM                                0xf607
+#define STB0899_UPLCSTL                                0xf608
+#define STB0899_DFLCSTM                                0xf609
+#define STB0899_DFLCSTL                                0xf60a
+#define STB0899_SYNCCST                                0xf60b
+#define STB0899_SYNCDCSTM                      0xf60c
+#define STB0899_SYNCDCSTL                      0xf60d
+#define STB0899_ISI_ENTRY                      0xf60e
+#define STB0899_ISI_BIT_EN                     0xf60f
+#define STB0899_MATSTRM                                0xf610
+#define STB0899_MATSTRL                                0xf611
+#define STB0899_UPLSTRM                                0xf612
+#define STB0899_UPLSTRL                                0xf613
+#define STB0899_DFLSTRM                                0xf614
+#define STB0899_DFLSTRL                                0xf615
+#define STB0899_SYNCSTR                                0xf616
+#define STB0899_SYNCDSTRM                      0xf617
+#define STB0899_SYNCDSTRL                      0xf618
+
+#define STB0899_CFGPDELSTATUS1                 0xf619
+#define STB0899_BADDFL                         (0x01 << 6)
+#define STB0899_OFFST_BADDFL                   6
+#define STB0899_WIDTH_BADDFL                   1
+#define STB0899_CONTINUOUS_STREAM              (0x01 << 5)
+#define STB0899_OFFST_CONTINUOUS_STREAM                5
+#define STB0899_WIDTH_CONTINUOUS_STREAM                1
+#define STB0899_ACCEPTED_STREAM                        (0x01 << 4)
+#define STB0899_OFFST_ACCEPTED_STREAM          4
+#define STB0899_WIDTH_ACCEPTED_STREAM          1
+#define STB0899_BCH_ERRFLAG                    (0x01 << 3)
+#define STB0899_OFFST_BCH_ERRFLAG              3
+#define STB0899_WIDTH_BCH_ERRFLAG              1
+#define STB0899_CRCRES                         (0x01 << 2)
+#define STB0899_OFFST_CRCRES                   2
+#define STB0899_WIDTH_CRCRES                   1
+#define STB0899_CFGPDELSTATUS_LOCK             (0x01 << 1)
+#define STB0899_OFFST_CFGPDELSTATUS_LOCK       1
+#define STB0899_WIDTH_CFGPDELSTATUS_LOCK       1
+#define STB0899_1STLOCK                                (0x01 << 0)
+#define STB0899_OFFST_1STLOCK                  0
+#define STB0899_WIDTH_1STLOCK                  1
+
+#define STB0899_CFGPDELSTATUS2                 0xf61a
+#define STB0899_BBFERRORM                      0xf61b
+#define STB0899_BBFERRORL                      0xf61c
+#define STB0899_UPKTERRORM                     0xf61d
+#define STB0899_UPKTERRORL                     0xf61e
+
+#define STB0899_TSTCK                          0xff10
+
+#define STB0899_TSTRES                         0xff11
+#define STB0899_FRESLDPC                       (0x01 << 7)
+#define STB0899_OFFST_FRESLDPC                 7
+#define STB0899_WIDTH_FRESLDPC                 1
+#define STB0899_FRESRS                         (0x01 << 6)
+#define STB0899_OFFST_FRESRS                   6
+#define STB0899_WIDTH_FRESRS                   1
+#define STB0899_FRESVIT                                (0x01 << 5)
+#define STB0899_OFFST_FRESVIT                  5
+#define STB0899_WIDTH_FRESVIT                  1
+#define STB0899_FRESMAS1_2                     (0x01 << 4)
+#define STB0899_OFFST_FRESMAS1_2               4
+#define STB0899_WIDTH_FRESMAS1_2               1
+#define STB0899_FRESACS                                (0x01 << 3)
+#define STB0899_OFFST_FRESACS                  3
+#define STB0899_WIDTH_FRESACS                  1
+#define STB0899_FRESSYM                                (0x01 << 2)
+#define STB0899_OFFST_FRESSYM                  2
+#define STB0899_WIDTH_FRESSYM                  1
+#define STB0899_FRESMAS                                (0x01 << 1)
+#define STB0899_OFFST_FRESMAS                  1
+#define STB0899_WIDTH_FRESMAS                  1
+#define STB0899_FRESINT                                (0x01 << 0)
+#define STB0899_OFFST_FRESINIT                 0
+#define STB0899_WIDTH_FRESINIT                 1
+
+#define STB0899_TSTOUT                         0xff12
+#define STB0899_EN_SIGNATURE                   (0x01 << 7)
+#define STB0899_OFFST_EN_SIGNATURE             7
+#define STB0899_WIDTH_EN_SIGNATURE             1
+#define STB0899_BCLK_CLK                       (0x01 << 6)
+#define STB0899_OFFST_BCLK_CLK                 6
+#define STB0899_WIDTH_BCLK_CLK                 1
+#define STB0899_SGNL_OUT                       (0x01 << 5)
+#define STB0899_OFFST_SGNL_OUT                 5
+#define STB0899_WIDTH_SGNL_OUT                 1
+#define STB0899_TS                             (0x01 << 4)
+#define STB0899_OFFST_TS                       4
+#define STB0899_WIDTH_TS                       1
+#define STB0899_CTEST                          (0x01 << 0)
+#define STB0899_OFFST_CTEST                    0
+#define STB0899_WIDTH_CTEST                    1
+
+#define STB0899_TSTIN                          0xff13
+#define STB0899_TEST_IN                                (0x01 << 7)
+#define STB0899_OFFST_TEST_IN                  7
+#define STB0899_WIDTH_TEST_IN                  1
+#define STB0899_EN_ADC                         (0x01 << 6)
+#define STB0899_OFFST_EN_ADC                   6
+#define STB0899_WIDTH_ENADC                    1
+#define STB0899_SGN_ADC                                (0x01 << 5)
+#define STB0899_OFFST_SGN_ADC                  5
+#define STB0899_WIDTH_SGN_ADC                  1
+#define STB0899_BCLK_IN                                (0x01 << 4)
+#define STB0899_OFFST_BCLK_IN                  4
+#define STB0899_WIDTH_BCLK_IN                  1
+#define STB0899_JETONIN_MODE                   (0x01 << 3)
+#define STB0899_OFFST_JETONIN_MODE             3
+#define STB0899_WIDTH_JETONIN_MODE             1
+#define STB0899_BCLK_VALUE                     (0x01 << 2)
+#define STB0899_OFFST_BCLK_VALUE               2
+#define STB0899_WIDTH_BCLK_VALUE               1
+#define STB0899_SGNRST_T12                     (0x01 << 1)
+#define STB0899_OFFST_SGNRST_T12               1
+#define STB0899_WIDTH_SGNRST_T12               1
+#define STB0899_LOWSP_ENAX                     (0x01 << 0)
+#define STB0899_OFFST_LOWSP_ENAX               0
+#define STB0899_WIDTH_LOWSP_ENAX               1
+
+#define STB0899_TSTSYS                         0xff14
+#define STB0899_TSTCHIP                                0xff15
+#define STB0899_TSTFREE                                0xff16
+#define STB0899_TSTI2C                         0xff17
+#define STB0899_BITSPEEDM                      0xff1c
+#define STB0899_BITSPEEDL                      0xff1d
+#define STB0899_TBUSBIT                                0xff1e
+#define STB0899_TSTDIS                         0xff24
+#define STB0899_TSTDISRX                       0xff25
+#define STB0899_TSTJETON                       0xff28
+#define STB0899_TSTDCADJ                       0xff40
+#define STB0899_TSTAGC1                                0xff41
+#define STB0899_TSTAGC1N                       0xff42
+#define STB0899_TSTPOLYPH                      0xff48
+#define STB0899_TSTR                           0xff49
+#define STB0899_TSTAGC2                                0xff4a
+#define STB0899_TSTCTL1                                0xff4b
+#define STB0899_TSTCTL2                                0xff4c
+#define STB0899_TSTCTL3                                0xff4d
+#define STB0899_TSTDEMAP                       0xff50
+#define STB0899_TSTDEMAP2                      0xff51
+#define STB0899_TSTDEMMON                      0xff52
+#define STB0899_TSTRATE                                0xff53
+#define STB0899_TSTSELOUT                      0xff54
+#define STB0899_TSYNC                          0xff55
+#define STB0899_TSTERR                         0xff56
+#define STB0899_TSTRAM1                                0xff58
+#define STB0899_TSTVSELOUT                     0xff59
+#define STB0899_TSTFORCEIN                     0xff5a
+#define STB0899_TSTRS1                         0xff5c
+#define STB0899_TSTRS2                         0xff5d
+#define STB0899_TSTRS3                         0xff53
+
+#define STB0899_INTBUFSTATUS                   0xf200
+#define STB0899_INTBUFCTRL                     0xf201
+#define STB0899_PCKLENUL                       0xf55e
+#define STB0899_PCKLENLL                       0xf55f
+#define STB0899_RSPCKLEN                       0xf560
+
+/*     2 registers     */
+#define STB0899_SYNCDCST                       0xf60c
+
+/*     DiSEqC  */
+#define STB0899_DISCNTRL1                      0xf0a0
+#define STB0899_TIMOFF                         (0x01 << 7)
+#define STB0899_OFFST_TIMOFF                   7
+#define STB0899_WIDTH_TIMOFF                   1
+#define STB0899_DISEQCRESET                    (0x01 << 6)
+#define STB0899_OFFST_DISEQCRESET              6
+#define STB0899_WIDTH_DISEQCRESET              1
+#define STB0899_TIMCMD                         (0x03 << 4)
+#define STB0899_OFFST_TIMCMD                   4
+#define STB0899_WIDTH_TIMCMD                   2
+#define STB0899_DISPRECHARGE                   (0x01 << 2)
+#define STB0899_OFFST_DISPRECHARGE             2
+#define STB0899_WIDTH_DISPRECHARGE             1
+#define STB0899_DISEQCMODE                     (0x03 << 0)
+#define STB0899_OFFST_DISEQCMODE               0
+#define STB0899_WIDTH_DISEQCMODE               2
+
+#define STB0899_DISCNTRL2                      0xf0a1
+#define STB0899_RECEIVER_ON                    (0x01 << 7)
+#define STB0899_OFFST_RECEIVER_ON              7
+#define STB0899_WIDTH_RECEIVER_ON              1
+#define STB0899_IGNO_SHORT_22K                 (0x01 << 6)
+#define STB0899_OFFST_IGNO_SHORT_22K           6
+#define STB0899_WIDTH_IGNO_SHORT_22K           1
+#define STB0899_ONECHIP_TRX                    (0x01 << 5)
+#define STB0899_OFFST_ONECHIP_TRX              5
+#define STB0899_WIDTH_ONECHIP_TRX              1
+#define STB0899_EXT_ENVELOP                    (0x01 << 4)
+#define STB0899_OFFST_EXT_ENVELOP              4
+#define STB0899_WIDTH_EXT_ENVELOP              1
+#define STB0899_PIN_SELECT                     (0x03 << 2)
+#define STB0899_OFFST_PIN_SELCT                        2
+#define STB0899_WIDTH_PIN_SELCT                        2
+#define STB0899_IRQ_RXEND                      (0x01 << 1)
+#define STB0899_OFFST_IRQ_RXEND                        1
+#define STB0899_WIDTH_IRQ_RXEND                        1
+#define STB0899_IRQ_4NBYTES                    (0x01 << 0)
+#define STB0899_OFFST_IRQ_4NBYTES              0
+#define STB0899_WIDTH_IRQ_4NBYTES              1
+
+#define STB0899_DISRX_ST0                      0xf0a4
+#define STB0899_RXEND                          (0x01 << 7)
+#define STB0899_OFFST_RXEND                    7
+#define STB0899_WIDTH_RXEND                    1
+#define STB0899_RXACTIVE                       (0x01 << 6)
+#define STB0899_OFFST_RXACTIVE                 6
+#define STB0899_WIDTH_RXACTIVE                 1
+#define STB0899_SHORT22K                       (0x01 << 5)
+#define STB0899_OFFST_SHORT22K                 5
+#define STB0899_WIDTH_SHORT22K                 1
+#define STB0899_CONTTONE                       (0x01 << 4)
+#define STB0899_OFFST_CONTTONE                 4
+#define STB0899_WIDTH_CONTONE                  1
+#define STB0899_4BFIFOREDY                     (0x01 << 3)
+#define STB0899_OFFST_4BFIFOREDY               3
+#define STB0899_WIDTH_4BFIFOREDY               1
+#define STB0899_FIFOEMPTY                      (0x01 << 2)
+#define STB0899_OFFST_FIFOEMPTY                        2
+#define STB0899_WIDTH_FIFOEMPTY                        1
+#define STB0899_ABORTTRX                       (0x01 << 0)
+#define STB0899_OFFST_ABORTTRX                 0
+#define STB0899_WIDTH_ABORTTRX                 1
+
+#define STB0899_DISRX_ST1                      0xf0a5
+#define STB0899_RXFAIL                         (0x01 << 7)
+#define STB0899_OFFST_RXFAIL                   7
+#define STB0899_WIDTH_RXFAIL                   1
+#define STB0899_FIFOPFAIL                      (0x01 << 6)
+#define STB0899_OFFST_FIFOPFAIL                        6
+#define STB0899_WIDTH_FIFOPFAIL                        1
+#define STB0899_RXNONBYTES                     (0x01 << 5)
+#define STB0899_OFFST_RXNONBYTES               5
+#define STB0899_WIDTH_RXNONBYTES               1
+#define STB0899_FIFOOVF                                (0x01 << 4)
+#define STB0899_OFFST_FIFOOVF                  4
+#define STB0899_WIDTH_FIFOOVF                  1
+#define STB0899_FIFOBYTENBR                    (0x0f << 0)
+#define STB0899_OFFST_FIFOBYTENBR              0
+#define STB0899_WIDTH_FIFOBYTENBR              4
+
+#define STB0899_DISPARITY                      0xf0a6
+
+#define STB0899_DISFIFO                                0xf0a7
+
+#define STB0899_DISSTATUS                      0xf0a8
+#define STB0899_FIFOFULL                       (0x01 << 6)
+#define STB0899_OFFST_FIFOFULL                 6
+#define STB0899_WIDTH_FIFOFULL                 1
+#define STB0899_TXIDLE                         (0x01 << 5)
+#define STB0899_OFFST_TXIDLE                   5
+#define STB0899_WIDTH_TXIDLE                   1
+#define STB0899_GAPBURST                       (0x01 << 4)
+#define STB0899_OFFST_GAPBURST                 4
+#define STB0899_WIDTH_GAPBURST                 1
+#define STB0899_TXFIFOBYTES                    (0x0f << 0)
+#define STB0899_OFFST_TXFIFOBYTES              0
+#define STB0899_WIDTH_TXFIFOBYTES              4
+#define STB0899_DISF22                         0xf0a9
+
+#define STB0899_DISF22RX                       0xf0aa
+
+/*     General Purpose */
+#define STB0899_SYSREG                         0xf101
+#define STB0899_ACRPRESC                       0xf110
+#define STB0899_OFFST_RSVD2                    7
+#define STB0899_WIDTH_RSVD2                    1
+#define STB0899_OFFST_ACRPRESC                 4
+#define STB0899_WIDTH_ACRPRESC                 3
+#define STB0899_OFFST_RSVD1                    3
+#define STB0899_WIDTH_RSVD1                    1
+#define STB0899_OFFST_ACRPRESC2                        0
+#define STB0899_WIDTH_ACRPRESC2                        3
+
+#define STB0899_ACRDIV1                                0xf111
+#define STB0899_ACRDIV2                                0xf112
+#define STB0899_DACR1                          0xf113
+#define STB0899_DACR2                          0xf114
+#define STB0899_OUTCFG                         0xf11c
+#define STB0899_MODECFG                                0xf11d
+#define STB0899_NCOARSE                                0xf1b3
+
+#define STB0899_SYNTCTRL                       0xf1b6
+#define STB0899_STANDBY                                (0x01 << 7)
+#define STB0899_OFFST_STANDBY                  7
+#define STB0899_WIDTH_STANDBY                  1
+#define STB0899_BYPASSPLL                      (0x01 << 6)
+#define STB0899_OFFST_BYPASSPLL                        6
+#define STB0899_WIDTH_BYPASSPLL                        1
+#define STB0899_SEL1XRATIO                     (0x01 << 5)
+#define STB0899_OFFST_SEL1XRATIO               5
+#define STB0899_WIDTH_SEL1XRATIO               1
+#define STB0899_SELOSCI                                (0x01 << 1)
+#define STB0899_OFFST_SELOSCI                  1
+#define STB0899_WIDTH_SELOSCI                  1
+
+#define STB0899_FILTCTRL                       0xf1b7
+#define STB0899_SYSCTRL                                0xf1b8
+
+#define STB0899_STOPCLK1                       0xf1c2
+#define STB0899_STOP_CKINTBUF108               (0x01 << 7)
+#define STB0899_OFFST_STOP_CKINTBUF108         7
+#define STB0899_WIDTH_STOP_CKINTBUF108         1
+#define STB0899_STOP_CKINTBUF216               (0x01 << 6)
+#define STB0899_OFFST_STOP_CKINTBUF216         6
+#define STB0899_WIDTH_STOP_CKINTBUF216         1
+#define STB0899_STOP_CHK8PSK                   (0x01 << 5)
+#define STB0899_OFFST_STOP_CHK8PSK             5
+#define STB0899_WIDTH_STOP_CHK8PSK             1
+#define STB0899_STOP_CKFEC108                  (0x01 << 4)
+#define STB0899_OFFST_STOP_CKFEC108            4
+#define STB0899_WIDTH_STOP_CKFEC108            1
+#define STB0899_STOP_CKFEC216                  (0x01 << 3)
+#define STB0899_OFFST_STOP_CKFEC216            3
+#define STB0899_WIDTH_STOP_CKFEC216            1
+#define STB0899_STOP_CKCORE216                 (0x01 << 2)
+#define STB0899_OFFST_STOP_CKCORE216           2
+#define STB0899_WIDTH_STOP_CKCORE216           1
+#define STB0899_STOP_CKADCI108                 (0x01 << 1)
+#define STB0899_OFFST_STOP_CKADCI108           1
+#define STB0899_WIDTH_STOP_CKADCI108           1
+#define STB0899_STOP_INVCKADCI108              (0x01 << 0)
+#define STB0899_OFFST_STOP_INVCKADCI108                0
+#define STB0899_WIDTH_STOP_INVCKADCI108                1
+
+#define STB0899_STOPCLK2                       0xf1c3
+#define STB0899_STOP_CKS2DMD108                        (0x01 << 2)
+#define STB0899_OFFST_STOP_CKS2DMD108          2
+#define STB0899_WIDTH_STOP_CKS2DMD108          1
+#define STB0899_STOP_CKPKDLIN108               (0x01 << 1)
+#define STB0899_OFFST_STOP_CKPKDLIN108         1
+#define STB0899_WIDTH_STOP_CKPKDLIN108         1
+#define STB0899_STOP_CKPKDLIN216               (0x01 << 0)
+#define STB0899_OFFST_STOP_CKPKDLIN216         0
+#define STB0899_WIDTH_STOP_CKPKDLIN216         1
+
+#define STB0899_TSTTNR1                                0xf1e0
+#define STB0899_BYPASS_ADC                     (0x01 << 7)
+#define STB0899_OFFST_BYPASS_ADC               7
+#define STB0899_WIDTH_BYPASS_ADC               1
+#define STB0899_INVADCICKOUT                   (0x01 << 6)
+#define STB0899_OFFST_INVADCICKOUT             6
+#define STB0899_WIDTH_INVADCICKOUT             1
+#define STB0899_ADCTEST_VOLTAGE                        (0x03 << 4)
+#define STB0899_OFFST_ADCTEST_VOLTAGE          4
+#define STB0899_WIDTH_ADCTEST_VOLTAGE          1
+#define STB0899_ADC_RESET                      (0x01 << 3)
+#define STB0899_OFFST_ADC_RESET                        3
+#define STB0899_WIDTH_ADC_RESET                        1
+#define STB0899_TSTTNR1_2                      (0x01 << 2)
+#define STB0899_OFFST_TSTTNR1_2                        2
+#define STB0899_WIDTH_TSTTNR1_2                        1
+#define STB0899_ADCPON                         (0x01 << 1)
+#define STB0899_OFFST_ADCPON                   1
+#define STB0899_WIDTH_ADCPON                   1
+#define STB0899_ADCIN_MODE                     (0x01 << 0)
+#define STB0899_OFFST_ADCIN_MODE               0
+#define STB0899_WIDTH_ADCIN_MODE               1
+
+#define STB0899_TSTTNR2                                0xf1e1
+#define STB0899_TSTTNR2_7                      (0x01 << 7)
+#define STB0899_OFFST_TSTTNR2_7                        7
+#define STB0899_WIDTH_TSTTNR2_7                        1
+#define STB0899_NOT_DISRX_WIRED                        (0x01 << 6)
+#define STB0899_OFFST_NOT_DISRX_WIRED          6
+#define STB0899_WIDTH_NOT_DISRX_WIRED          1
+#define STB0899_DISEQC_DCURRENT                        (0x01 << 5)
+#define STB0899_OFFST_DISEQC_DCURRENT          5
+#define STB0899_WIDTH_DISEQC_DCURRENT          1
+#define STB0899_DISEQC_ZCURRENT                        (0x01 << 4)
+#define STB0899_OFFST_DISEQC_ZCURRENT          4
+#define STB0899_WIDTH_DISEQC_ZCURRENT          1
+#define STB0899_DISEQC_SINC_SOURCE             (0x03 << 2)
+#define STB0899_OFFST_DISEQC_SINC_SOURCE       2
+#define STB0899_WIDTH_DISEQC_SINC_SOURCE       2
+#define STB0899_SELIQSRC                       (0x03 << 0)
+#define STB0899_OFFST_SELIQSRC                 0
+#define STB0899_WIDTH_SELIQSRC                 2
+
+#define STB0899_TSTTNR3                                0xf1e2
+
+#define STB0899_I2CCFG                         0xf129
+#define STB0899_I2CCFGRSVD                     (0x0f << 4)
+#define STB0899_OFFST_I2CCFGRSVD               4
+#define STB0899_WIDTH_I2CCFGRSVD               4
+#define STB0899_I2CFASTMODE                    (0x01 << 3)
+#define STB0899_OFFST_I2CFASTMODE              3
+#define STB0899_WIDTH_I2CFASTMODE              1
+#define STB0899_STATUSWR                       (0x01 << 2)
+#define STB0899_OFFST_STATUSWR                 2
+#define STB0899_WIDTH_STATUSWR                 1
+#define STB0899_I2CADDRINC                     (0x03 << 0)
+#define STB0899_OFFST_I2CADDRINC               0
+#define STB0899_WIDTH_I2CADDRINC               2
+
+#define STB0899_I2CRPT                         0xf12a
+#define STB0899_I2CTON                         (0x01 << 7)
+#define STB0899_OFFST_I2CTON                   7
+#define STB0899_WIDTH_I2CTON                   1
+#define STB0899_ENARPTLEVEL                    (0x01 << 6)
+#define STB0899_OFFST_ENARPTLEVEL              6
+#define STB0899_WIDTH_ENARPTLEVEL              2
+#define STB0899_SCLTDELAY                      (0x01 << 3)
+#define STB0899_OFFST_SCLTDELAY                        3
+#define STB0899_WIDTH_SCLTDELAY                        1
+#define STB0899_STOPENA                                (0x01 << 2)
+#define STB0899_OFFST_STOPENA                  2
+#define STB0899_WIDTH_STOPENA                  1
+#define STB0899_STOPSDAT2SDA                   (0x01 << 1)
+#define STB0899_OFFST_STOPSDAT2SDA             1
+#define STB0899_WIDTH_STOPSDAT2SDA             1
+
+#define STB0899_IOPVALUE8                      0xf136
+#define STB0899_IOPVALUE7                      0xf137
+#define STB0899_IOPVALUE6                      0xf138
+#define STB0899_IOPVALUE5                      0xf139
+#define STB0899_IOPVALUE4                      0xf13a
+#define STB0899_IOPVALUE3                      0xf13b
+#define STB0899_IOPVALUE2                      0xf13c
+#define STB0899_IOPVALUE1                      0xf13d
+#define STB0899_IOPVALUE0                      0xf13e
+
+#define STB0899_GPIO00CFG                      0xf140
+
+#define STB0899_GPIO01CFG                      0xf141
+#define STB0899_GPIO02CFG                      0xf142
+#define STB0899_GPIO03CFG                      0xf143
+#define STB0899_GPIO04CFG                      0xf144
+#define STB0899_GPIO05CFG                      0xf145
+#define STB0899_GPIO06CFG                      0xf146
+#define STB0899_GPIO07CFG                      0xf147
+#define STB0899_GPIO08CFG                      0xf148
+#define STB0899_GPIO09CFG                      0xf149
+#define STB0899_GPIO10CFG                      0xf14a
+#define STB0899_GPIO11CFG                      0xf14b
+#define STB0899_GPIO12CFG                      0xf14c
+#define STB0899_GPIO13CFG                      0xf14d
+#define STB0899_GPIO14CFG                      0xf14e
+#define STB0899_GPIO15CFG                      0xf14f
+#define STB0899_GPIO16CFG                      0xf150
+#define STB0899_GPIO17CFG                      0xf151
+#define STB0899_GPIO18CFG                      0xf152
+#define STB0899_GPIO19CFG                      0xf153
+#define STB0899_GPIO20CFG                      0xf154
+
+#define STB0899_SDATCFG                                0xf155
+#define STB0899_SCLTCFG                                0xf156
+#define STB0899_AGCRFCFG                       0xf157
+#define STB0899_GPIO22                         0xf158  /* AGCBB2CFG    */
+#define STB0899_GPIO21                         0xf159  /* AGCBB1CFG    */
+#define STB0899_DIRCLKCFG                      0xf15a
+#define STB0899_CLKOUT27CFG                    0xf15b
+#define STB0899_STDBYCFG                       0xf15c
+#define STB0899_CS0CFG                         0xf15d
+#define STB0899_CS1CFG                         0xf15e
+#define STB0899_DISEQCOCFG                     0xf15f
+
+#define STB0899_GPIO32CFG                      0xf160
+#define STB0899_GPIO33CFG                      0xf161
+#define STB0899_GPIO34CFG                      0xf162
+#define STB0899_GPIO35CFG                      0xf163
+#define STB0899_GPIO36CFG                      0xf164
+#define STB0899_GPIO37CFG                      0xf165
+#define STB0899_GPIO38CFG                      0xf166
+#define STB0899_GPIO39CFG                      0xf167
+
+#define STB0899_IRQSTATUS_3                    0xf120
+#define STB0899_IRQSTATUS_2                    0xf121
+#define STB0899_IRQSTATUS_1                    0xf122
+#define STB0899_IRQSTATUS_0                    0xf123
+
+#define STB0899_IRQMSK_3                       0xf124
+#define STB0899_IRQMSK_2                       0xf125
+#define STB0899_IRQMSK_1                       0xf126
+#define STB0899_IRQMSK_0                       0xf127
+
+#define STB0899_IRQCFG                         0xf128
+
+#define STB0899_GHOSTREG                       0xf000
+
+#define STB0899_S2DEMOD                                0xf3fc
+#define STB0899_S2FEC                          0xfafc
+
+
+#endif
diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c
new file mode 100644 (file)
index 0000000..a0c3c52
--- /dev/null
@@ -0,0 +1,256 @@
+  /*
+     Driver for ST STB6000 DVBS Silicon tuner
+
+     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+  */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "stb6000.h"
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "stb6000: " args); \
+       } while (0)
+
+struct stb6000_priv {
+       /* i2c details */
+       int i2c_address;
+       struct i2c_adapter *i2c;
+       u32 frequency;
+};
+
+static int stb6000_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int stb6000_sleep(struct dvb_frontend *fe)
+{
+       struct stb6000_priv *priv = fe->tuner_priv;
+       int ret;
+       u8 buf[] = { 10, 0 };
+       struct i2c_msg msg = {
+               .addr = priv->i2c_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 2
+       };
+
+       dprintk("%s:\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       ret = i2c_transfer(priv->i2c, &msg, 1);
+       if (ret != 1)
+               dprintk("%s: i2c error\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return (ret == 1) ? 0 : ret;
+}
+
+static int stb6000_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stb6000_priv *priv = fe->tuner_priv;
+       unsigned int n, m;
+       int ret;
+       u32 freq_mhz;
+       int bandwidth;
+       u8 buf[12];
+       struct i2c_msg msg = {
+               .addr = priv->i2c_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 12
+       };
+
+       dprintk("%s:\n", __func__);
+
+       freq_mhz = p->frequency / 1000;
+       bandwidth = p->symbol_rate / 1000000;
+
+       if (bandwidth > 31)
+               bandwidth = 31;
+
+       if ((freq_mhz > 949) && (freq_mhz < 2151)) {
+               buf[0] = 0x01;
+               buf[1] = 0xac;
+               if (freq_mhz < 1950)
+                       buf[1] = 0xaa;
+               if (freq_mhz < 1800)
+                       buf[1] = 0xa8;
+               if (freq_mhz < 1650)
+                       buf[1] = 0xa6;
+               if (freq_mhz < 1530)
+                       buf[1] = 0xa5;
+               if (freq_mhz < 1470)
+                       buf[1] = 0xa4;
+               if (freq_mhz < 1370)
+                       buf[1] = 0xa2;
+               if (freq_mhz < 1300)
+                       buf[1] = 0xa1;
+               if (freq_mhz < 1200)
+                       buf[1] = 0xa0;
+               if (freq_mhz < 1075)
+                       buf[1] = 0xbc;
+               if (freq_mhz < 1000)
+                       buf[1] = 0xba;
+               if (freq_mhz < 1075) {
+                       n = freq_mhz / 8; /* vco=lo*4 */
+                       m = 2;
+               } else {
+                       n = freq_mhz / 16; /* vco=lo*2 */
+                       m = 1;
+               }
+               buf[2] = n >> 1;
+               buf[3] = (unsigned char)(((n & 1) << 7) |
+                                       (m * freq_mhz - n * 16) | 0x60);
+               buf[4] = 0x04;
+               buf[5] = 0x0e;
+
+               buf[6] = (unsigned char)(bandwidth);
+
+               buf[7] = 0xd8;
+               buf[8] = 0xd0;
+               buf[9] = 0x50;
+               buf[10] = 0xeb;
+               buf[11] = 0x4f;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = i2c_transfer(priv->i2c, &msg, 1);
+               if (ret != 1)
+                       dprintk("%s: i2c error\n", __func__);
+
+               udelay(10);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+               buf[0] = 0x07;
+               buf[1] = 0xdf;
+               buf[2] = 0xd0;
+               buf[3] = 0x50;
+               buf[4] = 0xfb;
+               msg.len = 5;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = i2c_transfer(priv->i2c, &msg, 1);
+               if (ret != 1)
+                       dprintk("%s: i2c error\n", __func__);
+
+               udelay(10);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+               priv->frequency = freq_mhz * 1000;
+
+               return (ret == 1) ? 0 : ret;
+       }
+       return -1;
+}
+
+static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct stb6000_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops stb6000_tuner_ops = {
+       .info = {
+               .name = "ST STB6000",
+               .frequency_min = 950000,
+               .frequency_max = 2150000
+       },
+       .release = stb6000_release,
+       .sleep = stb6000_sleep,
+       .set_params = stb6000_set_params,
+       .get_frequency = stb6000_get_frequency,
+};
+
+struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
+                                               struct i2c_adapter *i2c)
+{
+       struct stb6000_priv *priv = NULL;
+       u8 b0[] = { 0 };
+       u8 b1[] = { 0, 0 };
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = addr,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 0
+               }, {
+                       .addr = addr,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 2
+               }
+       };
+       int ret;
+
+       dprintk("%s:\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       /* is some i2c device here ? */
+       ret = i2c_transfer(i2c, msg, 2);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret != 2)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c_address = addr;
+       priv->i2c = i2c;
+
+       memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
+                               sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       return fe;
+}
+EXPORT_SYMBOL(stb6000_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("DVB STB6000 driver");
+MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h
new file mode 100644 (file)
index 0000000..7be479c
--- /dev/null
@@ -0,0 +1,51 @@
+  /*
+     Driver for ST stb6000 DVBS Silicon tuner
+
+     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+  */
+
+#ifndef __DVB_STB6000_H__
+#define __DVB_STB6000_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a stb6000 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param addr i2c address of the tuner.
+ * @param i2c i2c adapter to use.
+ * @return FE pointer on success, NULL on failure.
+ */
+#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
+                                                       && defined(MODULE))
+extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe,
+                                                 int addr,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_STB6000 */
+
+#endif /* __DVB_STB6000_H__ */
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
new file mode 100644 (file)
index 0000000..2e93e65
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+       STB6100 Silicon Tuner
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "dvb_frontend.h"
+#include "stb6100.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+
+
+#define FE_ERROR               0
+#define FE_NOTICE              1
+#define FE_INFO                        2
+#define FE_DEBUG               3
+
+#define dprintk(x, y, z, format, arg...) do {                                          \
+       if (z) {                                                                        \
+               if      ((x > FE_ERROR) && (x > y))                                     \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
+               else if ((x > FE_NOTICE) && (x > y))                                    \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((x > FE_INFO) && (x > y))                                      \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
+               else if ((x > FE_DEBUG) && (x > y))                                     \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (x > y)                                                              \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while (0)
+
+struct stb6100_lkup {
+       u32 val_low;
+       u32 val_high;
+       u8   reg;
+};
+
+static int stb6100_release(struct dvb_frontend *fe);
+
+static const struct stb6100_lkup lkup[] = {
+       {       0,  950000, 0x0a },
+       {  950000, 1000000, 0x0a },
+       { 1000000, 1075000, 0x0c },
+       { 1075000, 1200000, 0x00 },
+       { 1200000, 1300000, 0x01 },
+       { 1300000, 1370000, 0x02 },
+       { 1370000, 1470000, 0x04 },
+       { 1470000, 1530000, 0x05 },
+       { 1530000, 1650000, 0x06 },
+       { 1650000, 1800000, 0x08 },
+       { 1800000, 1950000, 0x0a },
+       { 1950000, 2150000, 0x0c },
+       { 2150000, 9999999, 0x0c },
+       {       0,       0, 0x00 }
+};
+
+/* Register names for easy debugging.  */
+static const char *stb6100_regnames[] = {
+       [STB6100_LD]            = "LD",
+       [STB6100_VCO]           = "VCO",
+       [STB6100_NI]            = "NI",
+       [STB6100_NF_LSB]        = "NF",
+       [STB6100_K]             = "K",
+       [STB6100_G]             = "G",
+       [STB6100_F]             = "F",
+       [STB6100_DLB]           = "DLB",
+       [STB6100_TEST1]         = "TEST1",
+       [STB6100_FCCK]          = "FCCK",
+       [STB6100_LPEN]          = "LPEN",
+       [STB6100_TEST3]         = "TEST3",
+};
+
+/* Template for normalisation, i.e. setting unused or undocumented
+ * bits as required according to the documentation.
+ */
+struct stb6100_regmask {
+       u8 mask;
+       u8 set;
+};
+
+static const struct stb6100_regmask stb6100_template[] = {
+       [STB6100_LD]            = { 0xff, 0x00 },
+       [STB6100_VCO]           = { 0xff, 0x00 },
+       [STB6100_NI]            = { 0xff, 0x00 },
+       [STB6100_NF_LSB]        = { 0xff, 0x00 },
+       [STB6100_K]             = { 0xc7, 0x38 },
+       [STB6100_G]             = { 0xef, 0x10 },
+       [STB6100_F]             = { 0x1f, 0xc0 },
+       [STB6100_DLB]           = { 0x38, 0xc4 },
+       [STB6100_TEST1]         = { 0x00, 0x8f },
+       [STB6100_FCCK]          = { 0x40, 0x0d },
+       [STB6100_LPEN]          = { 0xf0, 0x0b },
+       [STB6100_TEST3]         = { 0x00, 0xde },
+};
+
+/*
+ * Currently unused. Some boards might need it in the future
+ */
+static inline void stb6100_normalise_regs(u8 regs[])
+{
+       int i;
+
+       for (i = 0; i < STB6100_NUMREGS; i++)
+               regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set;
+}
+
+static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
+{
+       int rc;
+       struct i2c_msg msg = {
+               .addr   = state->config->tuner_address,
+               .flags  = I2C_M_RD,
+               .buf    = regs,
+               .len    = STB6100_NUMREGS
+       };
+
+       rc = i2c_transfer(state->i2c, &msg, 1);
+       if (unlikely(rc != 1)) {
+               dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
+                       state->config->tuner_address, rc);
+
+               return -EREMOTEIO;
+       }
+       if (unlikely(verbose > FE_DEBUG)) {
+               int i;
+
+               dprintk(verbose, FE_DEBUG, 1, "    Read from 0x%02x", state->config->tuner_address);
+               for (i = 0; i < STB6100_NUMREGS; i++)
+                       dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[i], regs[i]);
+       }
+       return 0;
+}
+
+static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
+{
+       u8 regs[STB6100_NUMREGS];
+
+       struct i2c_msg msg = {
+               .addr   = state->config->tuner_address + reg,
+               .flags  = I2C_M_RD,
+               .buf    = regs,
+               .len    = 1
+       };
+
+       i2c_transfer(state->i2c, &msg, 1);
+
+       if (unlikely(reg >= STB6100_NUMREGS)) {
+               dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+               return -EINVAL;
+       }
+       if (unlikely(verbose > FE_DEBUG)) {
+               dprintk(verbose, FE_DEBUG, 1, "    Read from 0x%02x", state->config->tuner_address);
+               dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[reg], regs[0]);
+       }
+
+       return (unsigned int)regs[0];
+}
+
+static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
+{
+       int rc;
+       u8 cmdbuf[len + 1];
+       struct i2c_msg msg = {
+               .addr   = state->config->tuner_address,
+               .flags  = 0,
+               .buf    = cmdbuf,
+               .len    = len + 1
+       };
+
+       if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) {
+               dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d",
+                       start, len);
+               return -EINVAL;
+       }
+       memcpy(&cmdbuf[1], buf, len);
+       cmdbuf[0] = start;
+
+       if (unlikely(verbose > FE_DEBUG)) {
+               int i;
+
+               dprintk(verbose, FE_DEBUG, 1, "    Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len);
+               for (i = 0; i < len; i++)
+                       dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
+       }
+       rc = i2c_transfer(state->i2c, &msg, 1);
+       if (unlikely(rc != 1)) {
+               dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
+                       (unsigned int)state->config->tuner_address, start, len, rc);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
+{
+       if (unlikely(reg >= STB6100_NUMREGS)) {
+               dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+               return -EREMOTEIO;
+       }
+       data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
+       return stb6100_write_reg_range(state, &data, reg, 1);
+}
+
+
+static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       int rc;
+       struct stb6100_state *state = fe->tuner_priv;
+
+       rc = stb6100_read_reg(state, STB6100_LD);
+       if (rc < 0) {
+               dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
+               return rc;
+       }
+       return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
+}
+
+static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       int rc;
+       u8 f;
+       struct stb6100_state *state = fe->tuner_priv;
+
+       rc = stb6100_read_reg(state, STB6100_F);
+       if (rc < 0)
+               return rc;
+       f = rc & STB6100_F_F;
+
+       state->status.bandwidth = (f + 5) * 2000;       /* x2 for ZIF   */
+
+       *bandwidth = state->bandwidth = state->status.bandwidth * 1000;
+       dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
+       return 0;
+}
+
+static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+       u32 tmp;
+       int rc;
+       struct stb6100_state *state = fe->tuner_priv;
+
+       dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth);
+
+       bandwidth /= 2; /* ZIF */
+
+       if (bandwidth >= 36000000)      /* F[4:0] BW/2 max =31+5=36 mhz for F=31        */
+               tmp = 31;
+       else if (bandwidth <= 5000000)  /* bw/2 min = 5Mhz for F=0                      */
+               tmp = 0;
+       else                            /* if 5 < bw/2 < 36                             */
+               tmp = (bandwidth + 500000) / 1000000 - 5;
+
+       /* Turn on LPF bandwidth setting clock control,
+        * set bandwidth, wait 10ms, turn off.
+        */
+       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
+       if (rc < 0)
+               return rc;
+       rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
+       if (rc < 0)
+               return rc;
+
+       msleep(5);  /*  This is dangerous as another (related) thread may start */
+
+       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+       if (rc < 0)
+               return rc;
+
+       msleep(10);  /*  This is dangerous as another (related) thread may start */
+
+       return 0;
+}
+
+static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       int rc;
+       u32 nint, nfrac, fvco;
+       int psd2, odiv;
+       struct stb6100_state *state = fe->tuner_priv;
+       u8 regs[STB6100_NUMREGS];
+
+       rc = stb6100_read_regs(state, regs);
+       if (rc < 0)
+               return rc;
+
+       odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
+       psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT;
+       nint = regs[STB6100_NI];
+       nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB];
+       fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2);
+       *frequency = state->frequency = fvco >> (odiv + 1);
+
+       dprintk(verbose, FE_DEBUG, 1,
+               "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u",
+               state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac);
+       return 0;
+}
+
+
+static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+       int rc;
+       const struct stb6100_lkup *ptr;
+       struct stb6100_state *state = fe->tuner_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       u32 srate = 0, fvco, nint, nfrac;
+       u8 regs[STB6100_NUMREGS];
+       u8 g, psd2, odiv;
+
+       dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
+
+       if (fe->ops.get_frontend) {
+               dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
+               fe->ops.get_frontend(fe);
+       }
+       srate = p->symbol_rate;
+
+       /* Set up tuner cleanly, LPF calibration on */
+       rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
+       if (rc < 0)
+               return rc;  /* allow LPF calibration */
+
+       /* PLL Loop disabled, bias on, VCO on, synth on */
+       regs[STB6100_LPEN] = 0xeb;
+       rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+       if (rc < 0)
+               return rc;
+
+       /* Program the registers with their data values */
+
+       /* VCO divide ratio (LO divide ratio, VCO prescaler enable).    */
+       if (frequency <= 1075000)
+               odiv = 1;
+       else
+               odiv = 0;
+
+       /* VCO enabled, search clock off as per LL3.7, 3.4.1 */
+       regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
+
+       /* OSM  */
+       for (ptr = lkup;
+            (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
+            ptr++);
+
+       if (ptr->val_high == 0) {
+               printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
+               return -EINVAL;
+       }
+       regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
+       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+       if (rc < 0)
+               return rc;
+
+       if ((frequency > 1075000) && (frequency <= 1325000))
+               psd2 = 0;
+       else
+               psd2 = 1;
+       /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4)                 */
+       fvco = frequency << (1 + odiv);
+       /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1)))    */
+       nint = fvco / (state->reference << psd2);
+       /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9       */
+       nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
+                                        << (9 - psd2), state->reference);
+
+       /* NI */
+       regs[STB6100_NI] = nint;
+       rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
+       if (rc < 0)
+               return rc;
+
+       /* NF */
+       regs[STB6100_NF_LSB] = nfrac;
+       rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
+       if (rc < 0)
+               return rc;
+
+       /* K */
+       regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+       regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
+       rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
+       if (rc < 0)
+               return rc;
+
+       /* G Baseband gain. */
+       if (srate >= 15000000)
+               g = 9;  /*  +4 dB */
+       else if (srate >= 5000000)
+               g = 11; /*  +8 dB */
+       else
+               g = 14; /* +14 dB */
+
+       regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
+       regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
+       regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+       rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
+       if (rc < 0)
+               return rc;
+
+       /* F we don't write as it is set up in BW set */
+
+       /* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
+       regs[STB6100_DLB] = 0xcc;
+       rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
+       if (rc < 0)
+               return rc;
+
+       dprintk(verbose, FE_DEBUG, 1,
+               "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
+               frequency, srate, (unsigned int)g, (unsigned int)odiv,
+               (unsigned int)psd2, state->reference,
+               ptr->reg, fvco, nint, nfrac);
+
+       /* Set up the test registers */
+       regs[STB6100_TEST1] = 0x8f;
+       rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
+       if (rc < 0)
+               return rc;
+       regs[STB6100_TEST3] = 0xde;
+       rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
+       if (rc < 0)
+               return rc;
+
+       /* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
+       regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
+       rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+       if (rc < 0)
+               return rc;
+
+       msleep(2);
+
+       /* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
+       regs[STB6100_VCO] &= ~STB6100_VCO_OCK;          /* VCO fast search              */
+       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+       if (rc < 0)
+               return rc;
+
+       msleep(10);  /*  This is dangerous as another (related) thread may start */ /* wait for LO to lock */
+
+       regs[STB6100_VCO] &= ~STB6100_VCO_OSCH;         /* vco search disabled          */
+       regs[STB6100_VCO] |= STB6100_VCO_OCK;           /* search clock off             */
+       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+       if (rc < 0)
+               return rc;
+
+       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+       if (rc < 0)
+               return rc;  /* Stop LPF calibration */
+
+       msleep(10);  /*  This is dangerous as another (related) thread may start */
+                    /* wait for stabilisation, (should not be necessary)               */
+       return 0;
+}
+
+static int stb6100_sleep(struct dvb_frontend *fe)
+{
+       /* TODO: power down     */
+       return 0;
+}
+
+static int stb6100_init(struct dvb_frontend *fe)
+{
+       struct stb6100_state *state = fe->tuner_priv;
+       struct tuner_state *status = &state->status;
+
+       status->tunerstep       = 125000;
+       status->ifreq           = 0;
+       status->refclock        = 27000000;     /* Hz   */
+       status->iqsense         = 1;
+       status->bandwidth       = 36000;        /* kHz  */
+       state->bandwidth        = status->bandwidth * 1000;     /* Hz   */
+       state->reference        = status->refclock / 1000;      /* kHz  */
+
+       /* Set default bandwidth. Modified, PN 13-May-10        */
+       return 0;
+}
+
+static int stb6100_get_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *state)
+{
+       switch (param) {
+       case DVBFE_TUNER_FREQUENCY:
+               stb6100_get_frequency(fe, &state->frequency);
+               break;
+       case DVBFE_TUNER_TUNERSTEP:
+               break;
+       case DVBFE_TUNER_IFFREQ:
+               break;
+       case DVBFE_TUNER_BANDWIDTH:
+               stb6100_get_bandwidth(fe, &state->bandwidth);
+               break;
+       case DVBFE_TUNER_REFCLOCK:
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int stb6100_set_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *state)
+{
+       struct stb6100_state *tstate = fe->tuner_priv;
+
+       switch (param) {
+       case DVBFE_TUNER_FREQUENCY:
+               stb6100_set_frequency(fe, state->frequency);
+               tstate->frequency = state->frequency;
+               break;
+       case DVBFE_TUNER_TUNERSTEP:
+               break;
+       case DVBFE_TUNER_IFFREQ:
+               break;
+       case DVBFE_TUNER_BANDWIDTH:
+               stb6100_set_bandwidth(fe, state->bandwidth);
+               tstate->bandwidth = state->bandwidth;
+               break;
+       case DVBFE_TUNER_REFCLOCK:
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static struct dvb_tuner_ops stb6100_ops = {
+       .info = {
+               .name                   = "STB6100 Silicon Tuner",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_step         = 0,
+       },
+
+       .init           = stb6100_init,
+       .sleep          = stb6100_sleep,
+       .get_status     = stb6100_get_status,
+       .get_state      = stb6100_get_state,
+       .set_state      = stb6100_set_state,
+       .release        = stb6100_release
+};
+
+struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+                                   const struct stb6100_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct stb6100_state *state = NULL;
+
+       state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->config           = config;
+       state->i2c              = i2c;
+       state->frontend         = fe;
+       state->reference        = config->refclock / 1000; /* kHz */
+       fe->tuner_priv          = state;
+       fe->ops.tuner_ops       = stb6100_ops;
+
+       printk("%s: Attaching STB6100 \n", __func__);
+       return fe;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static int stb6100_release(struct dvb_frontend *fe)
+{
+       struct stb6100_state *state = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(stb6100_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STB6100 Silicon tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h
new file mode 100644 (file)
index 0000000..2ab0966
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+       STB6100 Silicon Tuner
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB_6100_REG_H
+#define __STB_6100_REG_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#define STB6100_LD                     0x00
+#define STB6100_LD_LOCK                        (1 << 0)
+
+#define STB6100_VCO                    0x01
+#define STB6100_VCO_OSCH               (0x01 << 7)
+#define STB6100_VCO_OSCH_SHIFT         7
+#define STB6100_VCO_OCK                        (0x03 << 5)
+#define STB6100_VCO_OCK_SHIFT          5
+#define STB6100_VCO_ODIV               (0x01 << 4)
+#define STB6100_VCO_ODIV_SHIFT         4
+#define STB6100_VCO_OSM                        (0x0f << 0)
+
+#define STB6100_NI                     0x02
+#define STB6100_NF_LSB                 0x03
+
+#define STB6100_K                      0x04
+#define STB6100_K_PSD2                 (0x01 << 2)
+#define STB6100_K_PSD2_SHIFT            2
+#define STB6100_K_NF_MSB               (0x03 << 0)
+
+#define STB6100_G                      0x05
+#define STB6100_G_G                    (0x0f << 0)
+#define STB6100_G_GCT                  (0x07 << 5)
+
+#define STB6100_F                      0x06
+#define STB6100_F_F                    (0x1f << 0)
+
+#define STB6100_DLB                    0x07
+
+#define STB6100_TEST1                  0x08
+
+#define STB6100_FCCK                   0x09
+#define STB6100_FCCK_FCCK              (0x01 << 6)
+
+#define STB6100_LPEN                   0x0a
+#define STB6100_LPEN_LPEN              (0x01 << 4)
+#define STB6100_LPEN_SYNP              (0x01 << 5)
+#define STB6100_LPEN_OSCP              (0x01 << 6)
+#define STB6100_LPEN_BEN               (0x01 << 7)
+
+#define STB6100_TEST3                  0x0b
+
+#define STB6100_NUMREGS                 0x0c
+
+
+#define INRANGE(val, x, y)             (((x <= val) && (val <= y)) ||          \
+                                        ((y <= val) && (val <= x)) ? 1 : 0)
+
+#define CHKRANGE(val, x, y)            (((val >= x) && (val < y)) ? 1 : 0)
+
+struct stb6100_config {
+       u8      tuner_address;
+       u32     refclock;
+};
+
+struct stb6100_state {
+       struct i2c_adapter *i2c;
+
+       const struct stb6100_config     *config;
+       struct dvb_tuner_ops            ops;
+       struct dvb_frontend             *frontend;
+       struct tuner_state              status;
+
+       u32 frequency;
+       u32 srate;
+       u32 bandwidth;
+       u32 reference;
+};
+
+#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+                                          const struct stb6100_config *config,
+                                          struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+                                                 const struct stb6100_config *config,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif //CONFIG_DVB_STB6100
+
+#endif
diff --git a/drivers/media/dvb-frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h
new file mode 100644 (file)
index 0000000..6314d18
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+       STB6100 Silicon Tuner
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+               *frequency = t_state.frequency;
+       }
+       return 0;
+}
+
+static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       t_state.frequency = frequency;
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->set_state) {
+               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+       }
+       return 0;
+}
+
+static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = &fe->ops;
+       struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+               *bandwidth = t_state.bandwidth;
+       }
+       return 0;
+}
+
+static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       t_state.bandwidth = bandwidth;
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->set_state) {
+               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+       }
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h
new file mode 100644 (file)
index 0000000..112163a
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+       STB6100 Silicon Tuner wrapper
+       Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 1);
+
+               err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+               if (err < 0) {
+                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 0);
+
+               *frequency = state.frequency;
+       }
+
+       return 0;
+}
+
+static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      state;
+       int err = 0;
+
+       state.frequency = frequency;
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->set_state) {
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 1);
+
+               err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
+               if (err < 0) {
+                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 0);
+
+       }
+
+       return 0;
+}
+
+static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 1);
+
+               err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+               if (err < 0) {
+                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 0);
+
+               *bandwidth = state.bandwidth;
+       }
+
+       return 0;
+}
+
+static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      state;
+       int err = 0;
+
+       state.bandwidth = bandwidth;
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->set_state) {
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 1);
+
+               err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
+               if (err < 0) {
+                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+
+               if (frontend_ops->i2c_gate_ctrl)
+                       frontend_ops->i2c_gate_ctrl(fe, 0);
+
+       }
+
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
new file mode 100644 (file)
index 0000000..632b251
--- /dev/null
@@ -0,0 +1,626 @@
+/*
+       Driver for ST STV0288 demodulator
+       Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
+               for Reel Multimedia
+       Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
+       Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
+               Removed stb6000 specific tuner code and revised some
+               procedures.
+       2010-09-01 Josef Pavlik <josef@pavlik.it>
+               Fixed diseqc_msg, diseqc_burst and set_tone problems
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "stv0288.h"
+
+struct stv0288_state {
+       struct i2c_adapter *i2c;
+       const struct stv0288_config *config;
+       struct dvb_frontend frontend;
+
+       u8 initialised:1;
+       u32 tuner_frequency;
+       u32 symbol_rate;
+       fe_code_rate_t fec_inner;
+       int errmode;
+};
+
+#define STATUS_BER 0
+#define STATUS_UCBLOCKS 1
+
+static int debug;
+static int debug_legacy_dish_switch;
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "stv0288: " args); \
+       } while (0)
+
+
+static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address,
+               .flags = 0,
+               .buf = buf,
+               .len = 2
+       };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
+                       "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return stv0288_writeregI(state, buf[0], buf[1]);
+}
+
+static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 1
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
+                               __func__, reg, ret);
+
+       return b1[0];
+}
+
+static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+       unsigned int temp;
+       unsigned char b[3];
+
+       if ((srate < 1000000) || (srate > 45000000))
+               return -EINVAL;
+
+       stv0288_writeregI(state, 0x22, 0);
+       stv0288_writeregI(state, 0x23, 0);
+       stv0288_writeregI(state, 0x2b, 0xff);
+       stv0288_writeregI(state, 0x2c, 0xf7);
+
+       temp = (unsigned int)srate / 1000;
+
+               temp = temp * 32768;
+               temp = temp / 25;
+               temp = temp / 125;
+               b[0] = (unsigned char)((temp >> 12) & 0xff);
+               b[1] = (unsigned char)((temp >> 4) & 0xff);
+               b[2] = (unsigned char)((temp << 4) & 0xf0);
+               stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
+               stv0288_writeregI(state, 0x29, 0); /* SFRM */
+               stv0288_writeregI(state, 0x2a, 0); /* SFRL */
+
+               stv0288_writeregI(state, 0x28, b[0]);
+               stv0288_writeregI(state, 0x29, b[1]);
+               stv0288_writeregI(state, 0x2a, b[2]);
+               dprintk("stv0288: stv0288_set_symbolrate\n");
+
+       return 0;
+}
+
+static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       int i;
+
+       dprintk("%s\n", __func__);
+
+       stv0288_writeregI(state, 0x09, 0);
+       msleep(30);
+       stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
+
+       for (i = 0; i < m->msg_len; i++) {
+               if (stv0288_writeregI(state, 0x06, m->msg[i]))
+                       return -EREMOTEIO;
+       }
+       msleep(m->msg_len*12);
+       return 0;
+}
+
+static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
+                                               fe_sec_mini_cmd_t burst)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
+               return -EREMOTEIO;
+
+       if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
+               return -EREMOTEIO;
+
+       msleep(15);
+       if (stv0288_writeregI(state, 0x05, 0x12))
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
+                       return -EREMOTEIO;
+       break;
+
+       case SEC_TONE_OFF:
+               if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
+                       return -EREMOTEIO;
+       break;
+
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static u8 stv0288_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x20,
+       0x09, 0x0,
+       0x0a, 0x4,
+       0x0b, 0x0,
+       0x0c, 0x0,
+       0x0d, 0x0,
+       0x0e, 0xd4,
+       0x0f, 0x30,
+       0x11, 0x80,
+       0x12, 0x03,
+       0x13, 0x48,
+       0x14, 0x84,
+       0x15, 0x45,
+       0x16, 0xb7,
+       0x17, 0x9c,
+       0x18, 0x0,
+       0x19, 0xa6,
+       0x1a, 0x88,
+       0x1b, 0x8f,
+       0x1c, 0xf0,
+       0x20, 0x0b,
+       0x21, 0x54,
+       0x22, 0x0,
+       0x23, 0x0,
+       0x2b, 0xff,
+       0x2c, 0xf7,
+       0x30, 0x0,
+       0x31, 0x1e,
+       0x32, 0x14,
+       0x33, 0x0f,
+       0x34, 0x09,
+       0x35, 0x0c,
+       0x36, 0x05,
+       0x37, 0x2f,
+       0x38, 0x16,
+       0x39, 0xbe,
+       0x3a, 0x0,
+       0x3b, 0x13,
+       0x3c, 0x11,
+       0x3d, 0x30,
+       0x40, 0x63,
+       0x41, 0x04,
+       0x42, 0x20,
+       0x43, 0x00,
+       0x44, 0x00,
+       0x45, 0x00,
+       0x46, 0x00,
+       0x47, 0x00,
+       0x4a, 0x00,
+       0x50, 0x10,
+       0x51, 0x38,
+       0x52, 0x21,
+       0x58, 0x54,
+       0x59, 0x86,
+       0x5a, 0x0,
+       0x5b, 0x9b,
+       0x5c, 0x08,
+       0x5d, 0x7f,
+       0x5e, 0x0,
+       0x5f, 0xff,
+       0x70, 0x0,
+       0x71, 0x0,
+       0x72, 0x0,
+       0x74, 0x0,
+       0x75, 0x0,
+       0x76, 0x0,
+       0x81, 0x0,
+       0x82, 0x3f,
+       0x83, 0x3f,
+       0x84, 0x0,
+       0x85, 0x0,
+       0x88, 0x0,
+       0x89, 0x0,
+       0x8a, 0x0,
+       0x8b, 0x0,
+       0x8c, 0x0,
+       0x90, 0x0,
+       0x91, 0x0,
+       0x92, 0x0,
+       0x93, 0x0,
+       0x94, 0x1c,
+       0x97, 0x0,
+       0xa0, 0x48,
+       0xa1, 0x0,
+       0xb0, 0xb8,
+       0xb1, 0x3a,
+       0xb2, 0x10,
+       0xb3, 0x82,
+       0xb4, 0x80,
+       0xb5, 0x82,
+       0xb6, 0x82,
+       0xb7, 0x82,
+       0xb8, 0x20,
+       0xb9, 0x0,
+       0xf0, 0x0,
+       0xf1, 0x0,
+       0xf2, 0xc0,
+       0x51, 0x36,
+       0x52, 0x09,
+       0x53, 0x94,
+       0x54, 0x62,
+       0x55, 0x29,
+       0x56, 0x64,
+       0x57, 0x2b,
+       0xff, 0xff,
+};
+
+static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
+{
+       dprintk("%s: %s\n", __func__,
+               volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+               volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+       return 0;
+}
+
+static int stv0288_init(struct dvb_frontend *fe)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+       int i;
+       u8 reg;
+       u8 val;
+
+       dprintk("stv0288: init chip\n");
+       stv0288_writeregI(state, 0x41, 0x04);
+       msleep(50);
+
+       /* we have default inittab */
+       if (state->config->inittab == NULL) {
+               for (i = 0; !(stv0288_inittab[i] == 0xff &&
+                               stv0288_inittab[i + 1] == 0xff); i += 2)
+                       stv0288_writeregI(state, stv0288_inittab[i],
+                                       stv0288_inittab[i + 1]);
+       } else {
+               for (i = 0; ; i += 2)  {
+                       reg = state->config->inittab[i];
+                       val = state->config->inittab[i+1];
+                       if (reg == 0xff && val == 0xff)
+                               break;
+                       stv0288_writeregI(state, reg, val);
+               }
+       }
+       return 0;
+}
+
+static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       u8 sync = stv0288_readreg(state, 0x24);
+       if (sync == 255)
+               sync = 0;
+
+       dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
+
+       *status = 0;
+       if (sync & 0x80)
+               *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+       if (sync & 0x10)
+               *status |= FE_HAS_VITERBI;
+       if (sync & 0x08) {
+               *status |= FE_HAS_LOCK;
+               dprintk("stv0288 has locked\n");
+       }
+
+       return 0;
+}
+
+static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       if (state->errmode != STATUS_BER)
+               return 0;
+       *ber = (stv0288_readreg(state, 0x26) << 8) |
+                                       stv0288_readreg(state, 0x27);
+       dprintk("stv0288_read_ber %d\n", *ber);
+
+       return 0;
+}
+
+
+static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
+
+
+       signal = signal * 5 / 4;
+       *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
+       dprintk("stv0288_read_signal_strength %d\n", *strength);
+
+       return 0;
+}
+static int stv0288_sleep(struct dvb_frontend *fe)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       stv0288_writeregI(state, 0x41, 0x84);
+       state->initialised = 0;
+
+       return 0;
+}
+static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
+                          | stv0288_readreg(state, 0x2e));
+       xsnr = 3 * (xsnr - 0xa100);
+       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
+       dprintk("stv0288_read_snr %d\n", *snr);
+
+       return 0;
+}
+
+static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       if (state->errmode != STATUS_BER)
+               return 0;
+       *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
+                                       stv0288_readreg(state, 0x27);
+       dprintk("stv0288_read_ber %d\n", *ucblocks);
+
+       return 0;
+}
+
+static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
+{
+       dprintk("%s(..)\n", __func__);
+       return 0;
+}
+
+static int stv0288_set_frontend(struct dvb_frontend *fe)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       char tm;
+       unsigned char tda[3];
+       u8 reg, time_out = 0;
+
+       dprintk("%s : FE_SET_FRONTEND\n", __func__);
+
+       if (c->delivery_system != SYS_DVBS) {
+                       dprintk("%s: unsupported delivery "
+                               "system selected (%d)\n",
+                               __func__, c->delivery_system);
+                       return -EOPNOTSUPP;
+       }
+
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+
+       /* only frequency & symbol_rate are used for tuner*/
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       udelay(10);
+       stv0288_set_symbolrate(fe, c->symbol_rate);
+       /* Carrier lock control register */
+       stv0288_writeregI(state, 0x15, 0xc5);
+
+       tda[2] = 0x0; /* CFRL */
+       for (tm = -9; tm < 7;) {
+               /* Viterbi status */
+               reg = stv0288_readreg(state, 0x24);
+               if (reg & 0x8)
+                               break;
+               if (reg & 0x80) {
+                       time_out++;
+                       if (time_out > 10)
+                               break;
+                       tda[2] += 40;
+                       if (tda[2] < 40)
+                               tm++;
+               } else {
+                       tm++;
+                       tda[2] = 0;
+                       time_out = 0;
+               }
+               tda[1] = (unsigned char)tm;
+               stv0288_writeregI(state, 0x2b, tda[1]);
+               stv0288_writeregI(state, 0x2c, tda[2]);
+               msleep(30);
+       }
+       state->tuner_frequency = c->frequency;
+       state->fec_inner = FEC_AUTO;
+       state->symbol_rate = c->symbol_rate;
+
+       return 0;
+}
+
+static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+
+       if (enable)
+               stv0288_writeregI(state, 0x01, 0xb5);
+       else
+               stv0288_writeregI(state, 0x01, 0x35);
+
+       udelay(1);
+
+       return 0;
+}
+
+static void stv0288_release(struct dvb_frontend *fe)
+{
+       struct stv0288_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops stv0288_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "ST STV0288 DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                     FE_CAN_QPSK |
+                     FE_CAN_FEC_AUTO
+       },
+
+       .release = stv0288_release,
+       .init = stv0288_init,
+       .sleep = stv0288_sleep,
+       .write = stv0288_write,
+       .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
+       .read_status = stv0288_read_status,
+       .read_ber = stv0288_read_ber,
+       .read_signal_strength = stv0288_read_signal_strength,
+       .read_snr = stv0288_read_snr,
+       .read_ucblocks = stv0288_read_ucblocks,
+       .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
+       .diseqc_send_burst = stv0288_send_diseqc_burst,
+       .set_tone = stv0288_set_tone,
+       .set_voltage = stv0288_set_voltage,
+
+       .set_property = stv0288_set_property,
+       .set_frontend = stv0288_set_frontend,
+};
+
+struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct stv0288_state *state = NULL;
+       int id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+       state->tuner_frequency = 0;
+       state->symbol_rate = 0;
+       state->fec_inner = 0;
+       state->errmode = STATUS_BER;
+
+       stv0288_writeregI(state, 0x41, 0x04);
+       msleep(200);
+       id = stv0288_readreg(state, 0x00);
+       dprintk("stv0288 id %x\n", id);
+
+       /* register 0x00 contains 0x11 for STV0288  */
+       if (id != 0x11)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &stv0288_ops,
+                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+
+       return NULL;
+}
+EXPORT_SYMBOL(stv0288_attach);
+
+module_param(debug_legacy_dish_switch, int, 0444);
+MODULE_PARM_DESC(debug_legacy_dish_switch,
+               "Enable timing analysis for Dish Network legacy switches");
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
+MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h
new file mode 100644 (file)
index 0000000..f2b53db
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+       Driver for ST STV0288 demodulator
+
+       Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
+               for Reel Multimedia
+       Copyright (C) 2008 TurboSight.com, <bob@turbosight.com>
+       Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
+               Removed stb6000 specific tuner code and revised some
+               procedures.
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef STV0288_H
+#define STV0288_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0288_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       u8* inittab;
+
+       /* minimum delay before retuning */
+       int min_delay_ms;
+
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+};
+
+#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
+                                                       defined(MODULE))
+extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
+                                          struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_STV0288 */
+
+static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       int r = 0;
+       u8 buf[] = { reg, val };
+       if (fe->ops.write)
+               r = fe->ops.write(fe, buf, 2);
+       return r;
+}
+
+#endif /* STV0288_H */
diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c
new file mode 100644 (file)
index 0000000..d40f226
--- /dev/null
@@ -0,0 +1,722 @@
+/*
+    Driver for STV0297 demodulator
+
+    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
+    Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "stv0297.h"
+
+struct stv0297_state {
+       struct i2c_adapter *i2c;
+       const struct stv0297_config *config;
+       struct dvb_frontend frontend;
+
+       unsigned long last_ber;
+       unsigned long base_freq;
+};
+
+#if 1
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+#define STV0297_CLOCK_KHZ   28900
+
+
+static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
+                       "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static int stv0297_readreg(struct stv0297_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
+                                {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
+                              };
+
+       // this device needs a STOP between the register and data
+       if (state->config->stop_during_read) {
+               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
+                       return -1;
+               }
+               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
+                       return -1;
+               }
+       } else {
+               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
+                       return -1;
+               }
+       }
+
+       return b1[0];
+}
+
+static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
+{
+       int val;
+
+       val = stv0297_readreg(state, reg);
+       val &= ~mask;
+       val |= (data & mask);
+       stv0297_writereg(state, reg, val);
+
+       return 0;
+}
+
+static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
+{
+       int ret;
+       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
+                                 &reg1,.len = 1},
+       {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
+       };
+
+       // this device needs a STOP between the register and data
+       if (state->config->stop_during_read) {
+               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
+                       return -1;
+               }
+               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
+                       return -1;
+               }
+       } else {
+               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
+                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+static u32 stv0297_get_symbolrate(struct stv0297_state *state)
+{
+       u64 tmp;
+
+       tmp = stv0297_readreg(state, 0x55);
+       tmp |= stv0297_readreg(state, 0x56) << 8;
+       tmp |= stv0297_readreg(state, 0x57) << 16;
+       tmp |= stv0297_readreg(state, 0x58) << 24;
+
+       tmp *= STV0297_CLOCK_KHZ;
+       tmp >>= 32;
+
+       return (u32) tmp;
+}
+
+static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
+{
+       long tmp;
+
+       tmp = 131072L * srate;  /* 131072 = 2^17  */
+       tmp = tmp / (STV0297_CLOCK_KHZ / 4);    /* 1/4 = 2^-2 */
+       tmp = tmp * 8192L;      /* 8192 = 2^13 */
+
+       stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
+       stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
+       stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
+       stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
+}
+
+static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
+{
+       long tmp;
+
+       tmp = (long) fshift *262144L;   /* 262144 = 2*18 */
+       tmp /= symrate;
+       tmp *= 1024;            /* 1024 = 2*10   */
+
+       // adjust
+       if (tmp >= 0) {
+               tmp += 500000;
+       } else {
+               tmp -= 500000;
+       }
+       tmp /= 1000000;
+
+       stv0297_writereg(state, 0x60, tmp & 0xFF);
+       stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
+}
+
+static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
+{
+       long tmp;
+
+       /* symrate is hardcoded to 10000 */
+       tmp = offset * 26844L;  /* (2**28)/10000 */
+       if (tmp < 0)
+               tmp += 0x10000000;
+       tmp &= 0x0FFFFFFF;
+
+       stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
+       stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
+       stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
+       stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
+}
+
+/*
+static long stv0297_get_carrieroffset(struct stv0297_state *state)
+{
+       s64 tmp;
+
+       stv0297_writereg(state, 0x6B, 0x00);
+
+       tmp = stv0297_readreg(state, 0x66);
+       tmp |= (stv0297_readreg(state, 0x67) << 8);
+       tmp |= (stv0297_readreg(state, 0x68) << 16);
+       tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
+
+       tmp *= stv0297_get_symbolrate(state);
+       tmp >>= 28;
+
+       return (s32) tmp;
+}
+*/
+
+static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
+{
+       s32 tmp;
+
+       if (freq > 10000)
+               freq -= STV0297_CLOCK_KHZ;
+
+       tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
+       tmp = (freq * 1000) / tmp;
+       if (tmp > 0xffff)
+               tmp = 0xffff;
+
+       stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
+       stv0297_writereg(state, 0x21, tmp >> 8);
+       stv0297_writereg(state, 0x20, tmp);
+}
+
+static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
+{
+       int val = 0;
+
+       switch (modulation) {
+       case QAM_16:
+               val = 0;
+               break;
+
+       case QAM_32:
+               val = 1;
+               break;
+
+       case QAM_64:
+               val = 4;
+               break;
+
+       case QAM_128:
+               val = 2;
+               break;
+
+       case QAM_256:
+               val = 3;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
+
+       return 0;
+}
+
+static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
+{
+       int val = 0;
+
+       switch (inversion) {
+       case INVERSION_OFF:
+               val = 0;
+               break;
+
+       case INVERSION_ON:
+               val = 1;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
+
+       return 0;
+}
+
+static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+
+       if (enable) {
+               stv0297_writereg(state, 0x87, 0x78);
+               stv0297_writereg(state, 0x86, 0xc8);
+       }
+
+       return 0;
+}
+
+static int stv0297_init(struct dvb_frontend *fe)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+       int i;
+
+       /* load init table */
+       for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
+               stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
+       msleep(200);
+
+       state->last_ber = 0;
+
+       return 0;
+}
+
+static int stv0297_sleep(struct dvb_frontend *fe)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+
+       stv0297_writereg_mask(state, 0x80, 1, 1);
+
+       return 0;
+}
+
+static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+
+       u8 sync = stv0297_readreg(state, 0xDF);
+
+       *status = 0;
+       if (sync & 0x80)
+               *status |=
+                       FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
+       return 0;
+}
+
+static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+       u8 BER[3];
+
+       stv0297_readregs(state, 0xA0, BER, 3);
+       if (!(BER[0] & 0x80)) {
+               state->last_ber = BER[2] << 8 | BER[1];
+               stv0297_writereg_mask(state, 0xA0, 0x80, 0x80);
+       }
+
+       *ber = state->last_ber;
+
+       return 0;
+}
+
+
+static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+       u8 STRENGTH[3];
+       u16 tmp;
+
+       stv0297_readregs(state, 0x41, STRENGTH, 3);
+       tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
+       if (STRENGTH[2] & 0x20) {
+               if (tmp < 0x200)
+                       tmp = 0;
+               else
+                       tmp = tmp - 0x200;
+       } else {
+               if (tmp > 0x1ff)
+                       tmp = 0;
+               else
+                       tmp = 0x1ff - tmp;
+       }
+       *strength = (tmp << 7) | (tmp >> 2);
+       return 0;
+}
+
+static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+       u8 SNR[2];
+
+       stv0297_readregs(state, 0x07, SNR, 2);
+       *snr = SNR[1] << 8 | SNR[0];
+
+       return 0;
+}
+
+static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+
+       stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */
+
+       *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
+               | stv0297_readreg(state, 0xD4);
+
+       stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */
+       stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */
+
+       return 0;
+}
+
+static int stv0297_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0297_state *state = fe->demodulator_priv;
+       int u_threshold;
+       int initial_u;
+       int blind_u;
+       int delay;
+       int sweeprate;
+       int carrieroffset;
+       unsigned long timeout;
+       fe_spectral_inversion_t inversion;
+
+       switch (p->modulation) {
+       case QAM_16:
+       case QAM_32:
+       case QAM_64:
+               delay = 100;
+               sweeprate = 1000;
+               break;
+
+       case QAM_128:
+       case QAM_256:
+               delay = 200;
+               sweeprate = 500;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // determine inversion dependent parameters
+       inversion = p->inversion;
+       if (state->config->invert)
+               inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
+       carrieroffset = -330;
+       switch (inversion) {
+       case INVERSION_OFF:
+               break;
+
+       case INVERSION_ON:
+               sweeprate = -sweeprate;
+               carrieroffset = -carrieroffset;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       stv0297_init(fe);
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* clear software interrupts */
+       stv0297_writereg(state, 0x82, 0x0);
+
+       /* set initial demodulation frequency */
+       stv0297_set_initialdemodfreq(state, 7250);
+
+       /* setup AGC */
+       stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
+       stv0297_writereg(state, 0x41, 0x00);
+       stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
+       stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
+       stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
+       stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
+       stv0297_writereg(state, 0x72, 0x00);
+       stv0297_writereg(state, 0x73, 0x00);
+       stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
+       stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
+       stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
+
+       /* setup STL */
+       stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
+       stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
+       stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
+       stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
+       stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
+
+       /* disable frequency sweep */
+       stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
+
+       /* reset deinterleaver */
+       stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
+       stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
+
+       /* ??? */
+       stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
+       stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
+
+       /* reset equaliser */
+       u_threshold = stv0297_readreg(state, 0x00) & 0xf;
+       initial_u = stv0297_readreg(state, 0x01) >> 4;
+       blind_u = stv0297_readreg(state, 0x01) & 0xf;
+       stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
+       stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
+       stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
+       stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
+       stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
+
+       /* data comes from internal A/D */
+       stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
+
+       /* clear phase registers */
+       stv0297_writereg(state, 0x63, 0x00);
+       stv0297_writereg(state, 0x64, 0x00);
+       stv0297_writereg(state, 0x65, 0x00);
+       stv0297_writereg(state, 0x66, 0x00);
+       stv0297_writereg(state, 0x67, 0x00);
+       stv0297_writereg(state, 0x68, 0x00);
+       stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
+
+       /* set parameters */
+       stv0297_set_qam(state, p->modulation);
+       stv0297_set_symbolrate(state, p->symbol_rate / 1000);
+       stv0297_set_sweeprate(state, sweeprate, p->symbol_rate / 1000);
+       stv0297_set_carrieroffset(state, carrieroffset);
+       stv0297_set_inversion(state, inversion);
+
+       /* kick off lock */
+       /* Disable corner detection for higher QAMs */
+       if (p->modulation == QAM_128 ||
+               p->modulation == QAM_256)
+               stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
+       else
+               stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+
+       stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
+       stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
+       stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
+       stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
+       stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
+       stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
+       stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
+
+       /* wait for WGAGC lock */
+       timeout = jiffies + msecs_to_jiffies(2000);
+       while (time_before(jiffies, timeout)) {
+               msleep(10);
+               if (stv0297_readreg(state, 0x43) & 0x08)
+                       break;
+       }
+       if (time_after(jiffies, timeout)) {
+               goto timeout;
+       }
+       msleep(20);
+
+       /* wait for equaliser partial convergence */
+       timeout = jiffies + msecs_to_jiffies(500);
+       while (time_before(jiffies, timeout)) {
+               msleep(10);
+
+               if (stv0297_readreg(state, 0x82) & 0x04) {
+                       break;
+               }
+       }
+       if (time_after(jiffies, timeout)) {
+               goto timeout;
+       }
+
+       /* wait for equaliser full convergence */
+       timeout = jiffies + msecs_to_jiffies(delay);
+       while (time_before(jiffies, timeout)) {
+               msleep(10);
+
+               if (stv0297_readreg(state, 0x82) & 0x08) {
+                       break;
+               }
+       }
+       if (time_after(jiffies, timeout)) {
+               goto timeout;
+       }
+
+       /* disable sweep */
+       stv0297_writereg_mask(state, 0x6a, 1, 0);
+       stv0297_writereg_mask(state, 0x88, 8, 0);
+
+       /* wait for main lock */
+       timeout = jiffies + msecs_to_jiffies(20);
+       while (time_before(jiffies, timeout)) {
+               msleep(10);
+
+               if (stv0297_readreg(state, 0xDF) & 0x80) {
+                       break;
+               }
+       }
+       if (time_after(jiffies, timeout)) {
+               goto timeout;
+       }
+       msleep(100);
+
+       /* is it still locked after that delay? */
+       if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
+               goto timeout;
+       }
+
+       /* success!! */
+       stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
+       state->base_freq = p->frequency;
+       return 0;
+
+timeout:
+       stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
+       return 0;
+}
+
+static int stv0297_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0297_state *state = fe->demodulator_priv;
+       int reg_00, reg_83;
+
+       reg_00 = stv0297_readreg(state, 0x00);
+       reg_83 = stv0297_readreg(state, 0x83);
+
+       p->frequency = state->base_freq;
+       p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
+       if (state->config->invert)
+               p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
+       p->symbol_rate = stv0297_get_symbolrate(state) * 1000;
+       p->fec_inner = FEC_NONE;
+
+       switch ((reg_00 >> 4) & 0x7) {
+       case 0:
+               p->modulation = QAM_16;
+               break;
+       case 1:
+               p->modulation = QAM_32;
+               break;
+       case 2:
+               p->modulation = QAM_128;
+               break;
+       case 3:
+               p->modulation = QAM_256;
+               break;
+       case 4:
+               p->modulation = QAM_64;
+               break;
+       }
+
+       return 0;
+}
+
+static void stv0297_release(struct dvb_frontend *fe)
+{
+       struct stv0297_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops stv0297_ops;
+
+struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct stv0297_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->last_ber = 0;
+       state->base_freq = 0;
+
+       /* check if the demod is there */
+       if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops stv0297_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A },
+       .info = {
+                .name = "ST STV0297 DVB-C",
+                .frequency_min = 47000000,
+                .frequency_max = 862000000,
+                .frequency_stepsize = 62500,
+                .symbol_rate_min = 870000,
+                .symbol_rate_max = 11700000,
+                .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+                FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
+
+       .release = stv0297_release,
+
+       .init = stv0297_init,
+       .sleep = stv0297_sleep,
+       .i2c_gate_ctrl = stv0297_i2c_gate_ctrl,
+
+       .set_frontend = stv0297_set_frontend,
+       .get_frontend = stv0297_get_frontend,
+
+       .read_status = stv0297_read_status,
+       .read_ber = stv0297_read_ber,
+       .read_signal_strength = stv0297_read_signal_strength,
+       .read_snr = stv0297_read_snr,
+       .read_ucblocks = stv0297_read_ucblocks,
+};
+
+MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
+MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(stv0297_attach);
diff --git a/drivers/media/dvb-frontends/stv0297.h b/drivers/media/dvb-frontends/stv0297.h
new file mode 100644 (file)
index 0000000..3f8f946
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+    Driver for STV0297 demodulator
+
+    Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef STV0297_H
+#define STV0297_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0297_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* inittab - array of pairs of values.
+       * First of each pair is the register, second is the value.
+       * List should be terminated with an 0xff, 0xff pair.
+       */
+       u8* inittab;
+
+       /* does the "inversion" need inverted? */
+       u8 invert:1;
+
+       /* set to 1 if the device requires an i2c STOP during reading */
+       u8 stop_during_read:1;
+};
+
+#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE))
+extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_STV0297
+
+#endif // STV0297_H
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
new file mode 100644 (file)
index 0000000..057b5f8
--- /dev/null
@@ -0,0 +1,762 @@
+/*
+    Driver for ST STV0299 demodulator
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+       <ralph@convergence.de>,
+       <holger@convergence.de>,
+       <js@convergence.de>
+
+
+    Philips SU1278/SH
+
+    Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
+
+
+    LG TDQF-S001F
+
+    Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
+                    & Andreas Oberritter <obi@linuxtv.org>
+
+
+    Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
+
+    Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
+
+    Support for Philips SU1278 on Technotrend hardware
+
+    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "stv0299.h"
+
+struct stv0299_state {
+       struct i2c_adapter* i2c;
+       const struct stv0299_config* config;
+       struct dvb_frontend frontend;
+
+       u8 initialised:1;
+       u32 tuner_frequency;
+       u32 symbol_rate;
+       fe_code_rate_t fec_inner;
+       int errmode;
+       u32 ucblocks;
+       u8 mcr_reg;
+};
+
+#define STATUS_BER 0
+#define STATUS_UCBLOCKS 1
+
+static int debug;
+static int debug_legacy_dish_switch;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "stv0299: " args); \
+       } while (0)
+
+
+static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf [] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+
+       ret = i2c_transfer (state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
+                       "ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return stv0299_writeregI(state, buf[0], buf[1]);
+}
+
+static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
+                               __func__, reg, ret);
+
+       return b1[0];
+}
+
+static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
+{
+       int ret;
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
+
+       return ret == 2 ? 0 : ret;
+}
+
+static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
+{
+       dprintk ("%s\n", __func__);
+
+       switch (fec) {
+       case FEC_AUTO:
+       {
+               return stv0299_writeregI (state, 0x31, 0x1f);
+       }
+       case FEC_1_2:
+       {
+               return stv0299_writeregI (state, 0x31, 0x01);
+       }
+       case FEC_2_3:
+       {
+               return stv0299_writeregI (state, 0x31, 0x02);
+       }
+       case FEC_3_4:
+       {
+               return stv0299_writeregI (state, 0x31, 0x04);
+       }
+       case FEC_5_6:
+       {
+               return stv0299_writeregI (state, 0x31, 0x08);
+       }
+       case FEC_7_8:
+       {
+               return stv0299_writeregI (state, 0x31, 0x10);
+       }
+       default:
+       {
+               return -EINVAL;
+       }
+    }
+}
+
+static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
+{
+       static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
+                                            FEC_7_8, FEC_1_2 };
+       u8 index;
+
+       dprintk ("%s\n", __func__);
+
+       index = stv0299_readreg (state, 0x1b);
+       index &= 0x7;
+
+       if (index > 4)
+               return FEC_AUTO;
+
+       return fec_tab [index];
+}
+
+static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
+{
+       unsigned long start = jiffies;
+
+       dprintk ("%s\n", __func__);
+
+       while (stv0299_readreg(state, 0x0a) & 1) {
+               if (jiffies - start > timeout) {
+                       dprintk ("%s: timeout!!\n", __func__);
+                       return -ETIMEDOUT;
+               }
+               msleep(10);
+       };
+
+       return 0;
+}
+
+static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
+{
+       unsigned long start = jiffies;
+
+       dprintk ("%s\n", __func__);
+
+       while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
+               if (jiffies - start > timeout) {
+                       dprintk ("%s: timeout!!\n", __func__);
+                       return -ETIMEDOUT;
+               }
+               msleep(10);
+       };
+
+       return 0;
+}
+
+static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u64 big = srate;
+       u32 ratio;
+
+       // check rate is within limits
+       if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
+
+       // calculate value to program
+       big = big << 20;
+       big += (state->config->mclk-1); // round correctly
+       do_div(big, state->config->mclk);
+       ratio = big << 4;
+
+       return state->config->set_symbol_rate(fe, srate, ratio);
+}
+
+static int stv0299_get_symbolrate (struct stv0299_state* state)
+{
+       u32 Mclk = state->config->mclk / 4096L;
+       u32 srate;
+       s32 offset;
+       u8 sfr[3];
+       s8 rtf;
+
+       dprintk ("%s\n", __func__);
+
+       stv0299_readregs (state, 0x1f, sfr, 3);
+       stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1);
+
+       srate = (sfr[0] << 8) | sfr[1];
+       srate *= Mclk;
+       srate /= 16;
+       srate += (sfr[2] >> 4) * Mclk / 256;
+       offset = (s32) rtf * (srate / 4096L);
+       offset /= 128;
+
+       dprintk ("%s : srate = %i\n", __func__, srate);
+       dprintk ("%s : ofset = %i\n", __func__, offset);
+
+       srate += offset;
+
+       srate += 1000;
+       srate /= 2000;
+       srate *= 2000;
+
+       return srate;
+}
+
+static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 val;
+       int i;
+
+       dprintk ("%s\n", __func__);
+
+       if (stv0299_wait_diseqc_idle (state, 100) < 0)
+               return -ETIMEDOUT;
+
+       val = stv0299_readreg (state, 0x08);
+
+       if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6))  /* DiSEqC mode */
+               return -EREMOTEIO;
+
+       for (i=0; i<m->msg_len; i++) {
+               if (stv0299_wait_diseqc_fifo (state, 100) < 0)
+                       return -ETIMEDOUT;
+
+               if (stv0299_writeregI (state, 0x09, m->msg[i]))
+                       return -EREMOTEIO;
+       }
+
+       if (stv0299_wait_diseqc_idle (state, 100) < 0)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk ("%s\n", __func__);
+
+       if (stv0299_wait_diseqc_idle (state, 100) < 0)
+               return -ETIMEDOUT;
+
+       val = stv0299_readreg (state, 0x08);
+
+       if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2))        /* burst mode */
+               return -EREMOTEIO;
+
+       if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
+               return -EREMOTEIO;
+
+       if (stv0299_wait_diseqc_idle (state, 100) < 0)
+               return -ETIMEDOUT;
+
+       if (stv0299_writeregI (state, 0x08, val))
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 val;
+
+       if (stv0299_wait_diseqc_idle (state, 100) < 0)
+               return -ETIMEDOUT;
+
+       val = stv0299_readreg (state, 0x08);
+
+       switch (tone) {
+       case SEC_TONE_ON:
+               return stv0299_writeregI (state, 0x08, val | 0x3);
+
+       case SEC_TONE_OFF:
+               return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 reg0x08;
+       u8 reg0x0c;
+
+       dprintk("%s: %s\n", __func__,
+               voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+               voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+       reg0x08 = stv0299_readreg (state, 0x08);
+       reg0x0c = stv0299_readreg (state, 0x0c);
+
+       /**
+        *  H/V switching over OP0, OP1 and OP2 are LNB power enable bits
+        */
+       reg0x0c &= 0x0f;
+       reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6);
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
+                       reg0x0c |= 0x10; /* OP1 off, OP0 on */
+               else
+                       reg0x0c |= 0x40; /* OP1 on, OP0 off */
+               break;
+       case SEC_VOLTAGE_18:
+               reg0x0c |= 0x50; /* OP1 on, OP0 on */
+               break;
+       case SEC_VOLTAGE_OFF:
+               /* LNB power off! */
+               reg0x08 = 0x00;
+               reg0x0c = 0x00;
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       if (state->config->op0_off)
+               reg0x0c &= ~0x10;
+
+       stv0299_writeregI(state, 0x08, reg0x08);
+       return stv0299_writeregI(state, 0x0c, reg0x0c);
+}
+
+static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       u8 reg0x08;
+       u8 reg0x0c;
+       u8 lv_mask = 0x40;
+       u8 last = 1;
+       int i;
+       struct timeval nexttime;
+       struct timeval tv[10];
+
+       reg0x08 = stv0299_readreg (state, 0x08);
+       reg0x0c = stv0299_readreg (state, 0x0c);
+       reg0x0c &= 0x0f;
+       stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
+       if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
+               lv_mask = 0x10;
+
+       cmd = cmd << 1;
+       if (debug_legacy_dish_switch)
+               printk ("%s switch command: 0x%04lx\n",__func__, cmd);
+
+       do_gettimeofday (&nexttime);
+       if (debug_legacy_dish_switch)
+               memcpy (&tv[0], &nexttime, sizeof (struct timeval));
+       stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
+
+       dvb_frontend_sleep_until(&nexttime, 32000);
+
+       for (i=0; i<9; i++) {
+               if (debug_legacy_dish_switch)
+                       do_gettimeofday (&tv[i+1]);
+               if((cmd & 0x01) != last) {
+                       /* set voltage to (last ? 13V : 18V) */
+                       stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
+                       last = (last) ? 0 : 1;
+               }
+
+               cmd = cmd >> 1;
+
+               if (i != 8)
+                       dvb_frontend_sleep_until(&nexttime, 8000);
+       }
+       if (debug_legacy_dish_switch) {
+               printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
+                       __func__, fe->dvb->num);
+               for (i = 1; i < 10; i++)
+                       printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
+       }
+
+       return 0;
+}
+
+static int stv0299_init (struct dvb_frontend* fe)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       int i;
+       u8 reg;
+       u8 val;
+
+       dprintk("stv0299: init chip\n");
+
+       stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
+       msleep(50);
+
+       for (i = 0; ; i += 2)  {
+               reg = state->config->inittab[i];
+               val = state->config->inittab[i+1];
+               if (reg == 0xff && val == 0xff)
+                       break;
+               if (reg == 0x0c && state->config->op0_off)
+                       val &= ~0x10;
+               if (reg == 0x2)
+                       state->mcr_reg = val & 0xf;
+               stv0299_writeregI(state, reg, val);
+       }
+
+       return 0;
+}
+
+static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       u8 signal = 0xff - stv0299_readreg (state, 0x18);
+       u8 sync = stv0299_readreg (state, 0x1b);
+
+       dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
+       *status = 0;
+
+       if (signal > 10)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 0x80)
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 0x10)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 0x08)
+               *status |= FE_HAS_SYNC;
+
+       if ((sync & 0x98) == 0x98)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       if (state->errmode != STATUS_BER)
+               return -ENOSYS;
+
+       *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
+
+       return 0;
+}
+
+static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       s32 signal =  0xffff - ((stv0299_readreg (state, 0x18) << 8)
+                              | stv0299_readreg (state, 0x19));
+
+       dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
+                stv0299_readreg (state, 0x18),
+                stv0299_readreg (state, 0x19), (int) signal);
+
+       signal = signal * 5 / 4;
+       *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
+
+       return 0;
+}
+
+static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
+                          | stv0299_readreg (state, 0x25));
+       xsnr = 3 * (xsnr - 0xa100);
+       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
+
+       return 0;
+}
+
+static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       if (state->errmode != STATUS_UCBLOCKS)
+               return -ENOSYS;
+
+       state->ucblocks += stv0299_readreg(state, 0x1e);
+       state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
+       *ucblocks = state->ucblocks;
+
+       return 0;
+}
+
+static int stv0299_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0299_state* state = fe->demodulator_priv;
+       int invval = 0;
+
+       dprintk ("%s : FE_SET_FRONTEND\n", __func__);
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+
+       // set the inversion
+       if (p->inversion == INVERSION_OFF) invval = 0;
+       else if (p->inversion == INVERSION_ON) invval = 1;
+       else {
+               printk("stv0299 does not support auto-inversion\n");
+               return -EINVAL;
+       }
+       if (state->config->invert) invval = (~invval) & 1;
+       stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       stv0299_set_FEC(state, p->fec_inner);
+       stv0299_set_symbolrate(fe, p->symbol_rate);
+       stv0299_writeregI(state, 0x22, 0x00);
+       stv0299_writeregI(state, 0x23, 0x00);
+
+       state->tuner_frequency = p->frequency;
+       state->fec_inner = p->fec_inner;
+       state->symbol_rate = p->symbol_rate;
+
+       return 0;
+}
+
+static int stv0299_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0299_state* state = fe->demodulator_priv;
+       s32 derot_freq;
+       int invval;
+
+       derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
+                               | stv0299_readreg (state, 0x23));
+
+       derot_freq *= (state->config->mclk >> 16);
+       derot_freq += 500;
+       derot_freq /= 1000;
+
+       p->frequency += derot_freq;
+
+       invval = stv0299_readreg (state, 0x0c) & 1;
+       if (state->config->invert) invval = (~invval) & 1;
+       p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
+
+       p->fec_inner = stv0299_get_fec(state);
+       p->symbol_rate = stv0299_get_symbolrate(state);
+
+       return 0;
+}
+
+static int stv0299_sleep(struct dvb_frontend* fe)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
+       state->initialised = 0;
+
+       return 0;
+}
+
+static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               stv0299_writeregI(state, 0x05, 0xb5);
+       } else {
+               stv0299_writeregI(state, 0x05, 0x35);
+       }
+       udelay(1);
+       return 0;
+}
+
+static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       fesettings->min_delay_ms = state->config->min_delay_ms;
+       if (p->symbol_rate < 10000000) {
+               fesettings->step_size = p->symbol_rate / 32000;
+               fesettings->max_drift = 5000;
+       } else {
+               fesettings->step_size = p->symbol_rate / 16000;
+               fesettings->max_drift = p->symbol_rate / 2000;
+       }
+       return 0;
+}
+
+static void stv0299_release(struct dvb_frontend* fe)
+{
+       struct stv0299_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops stv0299_ops;
+
+struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct stv0299_state* state = NULL;
+       int id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->initialised = 0;
+       state->tuner_frequency = 0;
+       state->symbol_rate = 0;
+       state->fec_inner = 0;
+       state->errmode = STATUS_BER;
+
+       /* check if the demod is there */
+       stv0299_writeregI(state, 0x02, 0x30); /* standby off */
+       msleep(200);
+       id = stv0299_readreg(state, 0x00);
+
+       /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
+       /* register 0x00 might contain 0x80 when returning from standby */
+       if (id != 0xa1 && id != 0x80) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops stv0299_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "ST STV0299 DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,  /* ppm */
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                     FE_CAN_QPSK |
+                     FE_CAN_FEC_AUTO
+       },
+
+       .release = stv0299_release,
+
+       .init = stv0299_init,
+       .sleep = stv0299_sleep,
+       .write = stv0299_write,
+       .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
+
+       .set_frontend = stv0299_set_frontend,
+       .get_frontend = stv0299_get_frontend,
+       .get_tune_settings = stv0299_get_tune_settings,
+
+       .read_status = stv0299_read_status,
+       .read_ber = stv0299_read_ber,
+       .read_signal_strength = stv0299_read_signal_strength,
+       .read_snr = stv0299_read_snr,
+       .read_ucblocks = stv0299_read_ucblocks,
+
+       .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
+       .diseqc_send_burst = stv0299_send_diseqc_burst,
+       .set_tone = stv0299_set_tone,
+       .set_voltage = stv0299_set_voltage,
+       .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
+};
+
+module_param(debug_legacy_dish_switch, int, 0444);
+MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
+MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
+             "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb-frontends/stv0299.h b/drivers/media/dvb-frontends/stv0299.h
new file mode 100644 (file)
index 0000000..ba219b7
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+    Driver for ST STV0299 demodulator
+
+    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+       <ralph@convergence.de>,
+       <holger@convergence.de>,
+       <js@convergence.de>
+
+
+    Philips SU1278/SH
+
+    Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
+
+
+    LG TDQF-S001F
+
+    Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
+                    & Andreas Oberritter <obi@linuxtv.org>
+
+
+    Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
+
+    Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
+
+    Support for Philips SU1278 on Technotrend hardware
+
+    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef STV0299_H
+#define STV0299_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#define STV0299_LOCKOUTPUT_0  0
+#define STV0299_LOCKOUTPUT_1  1
+#define STV0299_LOCKOUTPUT_CF 2
+#define STV0299_LOCKOUTPUT_LK 3
+
+#define STV0299_VOLT13_OP0 0
+#define STV0299_VOLT13_OP1 1
+
+struct stv0299_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* inittab - array of pairs of values.
+        * First of each pair is the register, second is the value.
+        * List should be terminated with an 0xff, 0xff pair.
+        */
+       const u8* inittab;
+
+       /* master clock to use */
+       u32 mclk;
+
+       /* does the inversion require inversion? */
+       u8 invert:1;
+
+       /* Skip reinitialisation? */
+       u8 skip_reinit:1;
+
+       /* LOCK OUTPUT setting */
+       u8 lock_output:2;
+
+       /* Is 13v controlled by OP0 or OP1? */
+       u8 volt13_op0_op1:1;
+
+       /* Turn-off OP0? */
+       u8 op0_off:1;
+
+       /* minimum delay before retuning */
+       int min_delay_ms;
+
+       /* Set the symbol rate */
+       int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio);
+
+       /* Set device param to start dma */
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+};
+
+#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
+extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
+                                          struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_STV0299
+
+static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
+       int r = 0;
+       u8 buf[] = {reg, val};
+       if (fe->ops.write)
+               r = fe->ops.write(fe, buf, 2);
+       return r;
+}
+
+#endif // STV0299_H
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
new file mode 100644 (file)
index 0000000..2a8aaeb
--- /dev/null
@@ -0,0 +1,3450 @@
+/*
+ * stv0367.c
+ *
+ * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2010,2011 NetUP Inc.
+ * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0367.h"
+#include "stv0367_regs.h"
+#include "stv0367_priv.h"
+
+static int stvdebug;
+module_param_named(debug, stvdebug, int, 0644);
+
+static int i2cdebug;
+module_param_named(i2c_debug, i2cdebug, int, 0644);
+
+#define dprintk(args...) \
+       do { \
+               if (stvdebug) \
+                       printk(KERN_DEBUG args); \
+       } while (0)
+       /* DVB-C */
+
+struct stv0367cab_state {
+       enum stv0367_cab_signal_type    state;
+       u32     mclk;
+       u32     adc_clk;
+       s32     search_range;
+       s32     derot_offset;
+       /* results */
+       int locked;                     /* channel found                */
+       u32 freq_khz;                   /* found frequency (in kHz)     */
+       u32 symbol_rate;                /* found symbol rate (in Bds)   */
+       enum stv0367cab_mod modulation; /* modulation                   */
+       fe_spectral_inversion_t spect_inv; /* Spectrum Inversion        */
+};
+
+struct stv0367ter_state {
+       /* DVB-T */
+       enum stv0367_ter_signal_type state;
+       enum stv0367_ter_if_iq_mode if_iq_mode;
+       enum stv0367_ter_mode mode;/* mode 2K or 8K */
+       fe_guard_interval_t guard;
+       enum stv0367_ter_hierarchy hierarchy;
+       u32 frequency;
+       fe_spectral_inversion_t  sense; /*  current search spectrum */
+       u8  force; /* force mode/guard */
+       u8  bw; /* channel width 6, 7 or 8 in MHz */
+       u8  pBW; /* channel width used during previous lock */
+       u32 pBER;
+       u32 pPER;
+       u32 ucblocks;
+       s8  echo_pos; /* echo position */
+       u8  first_lock;
+       u8  unlock_counter;
+       u32 agc_val;
+};
+
+struct stv0367_state {
+       struct dvb_frontend fe;
+       struct i2c_adapter *i2c;
+       /* config settings */
+       const struct stv0367_config *config;
+       u8 chip_id;
+       /* DVB-C */
+       struct stv0367cab_state *cab_state;
+       /* DVB-T */
+       struct stv0367ter_state *ter_state;
+};
+
+struct st_register {
+       u16     addr;
+       u8      value;
+};
+
+/* values for STV4100 XTAL=30M int clk=53.125M*/
+static struct st_register def0367ter[STV0367TER_NBREGS] = {
+       {R367TER_ID,            0x60},
+       {R367TER_I2CRPT,        0xa0},
+       /* {R367TER_I2CRPT,     0x22},*/
+       {R367TER_TOPCTRL,       0x00},/* for xc5000; was 0x02 */
+       {R367TER_IOCFG0,        0x40},
+       {R367TER_DAC0R,         0x00},
+       {R367TER_IOCFG1,        0x00},
+       {R367TER_DAC1R,         0x00},
+       {R367TER_IOCFG2,        0x62},
+       {R367TER_SDFR,          0x00},
+       {R367TER_STATUS,        0xf8},
+       {R367TER_AUX_CLK,       0x0a},
+       {R367TER_FREESYS1,      0x00},
+       {R367TER_FREESYS2,      0x00},
+       {R367TER_FREESYS3,      0x00},
+       {R367TER_GPIO_CFG,      0x55},
+       {R367TER_GPIO_CMD,      0x00},
+       {R367TER_AGC2MAX,       0xff},
+       {R367TER_AGC2MIN,       0x00},
+       {R367TER_AGC1MAX,       0xff},
+       {R367TER_AGC1MIN,       0x00},
+       {R367TER_AGCR,          0xbc},
+       {R367TER_AGC2TH,        0x00},
+       {R367TER_AGC12C,        0x00},
+       {R367TER_AGCCTRL1,      0x85},
+       {R367TER_AGCCTRL2,      0x1f},
+       {R367TER_AGC1VAL1,      0x00},
+       {R367TER_AGC1VAL2,      0x00},
+       {R367TER_AGC2VAL1,      0x6f},
+       {R367TER_AGC2VAL2,      0x05},
+       {R367TER_AGC2PGA,       0x00},
+       {R367TER_OVF_RATE1,     0x00},
+       {R367TER_OVF_RATE2,     0x00},
+       {R367TER_GAIN_SRC1,     0xaa},/* for xc5000; was 0x2b */
+       {R367TER_GAIN_SRC2,     0xd6},/* for xc5000; was 0x04 */
+       {R367TER_INC_DEROT1,    0x55},
+       {R367TER_INC_DEROT2,    0x55},
+       {R367TER_PPM_CPAMP_DIR, 0x2c},
+       {R367TER_PPM_CPAMP_INV, 0x00},
+       {R367TER_FREESTFE_1,    0x00},
+       {R367TER_FREESTFE_2,    0x1c},
+       {R367TER_DCOFFSET,      0x00},
+       {R367TER_EN_PROCESS,    0x05},
+       {R367TER_SDI_SMOOTHER,  0x80},
+       {R367TER_FE_LOOP_OPEN,  0x1c},
+       {R367TER_FREQOFF1,      0x00},
+       {R367TER_FREQOFF2,      0x00},
+       {R367TER_FREQOFF3,      0x00},
+       {R367TER_TIMOFF1,       0x00},
+       {R367TER_TIMOFF2,       0x00},
+       {R367TER_EPQ,           0x02},
+       {R367TER_EPQAUTO,       0x01},
+       {R367TER_SYR_UPDATE,    0xf5},
+       {R367TER_CHPFREE,       0x00},
+       {R367TER_PPM_STATE_MAC, 0x23},
+       {R367TER_INR_THRESHOLD, 0xff},
+       {R367TER_EPQ_TPS_ID_CELL, 0xf9},
+       {R367TER_EPQ_CFG,       0x00},
+       {R367TER_EPQ_STATUS,    0x01},
+       {R367TER_AUTORELOCK,    0x81},
+       {R367TER_BER_THR_VMSB,  0x00},
+       {R367TER_BER_THR_MSB,   0x00},
+       {R367TER_BER_THR_LSB,   0x00},
+       {R367TER_CCD,           0x83},
+       {R367TER_SPECTR_CFG,    0x00},
+       {R367TER_CHC_DUMMY,     0x18},
+       {R367TER_INC_CTL,       0x88},
+       {R367TER_INCTHRES_COR1, 0xb4},
+       {R367TER_INCTHRES_COR2, 0x96},
+       {R367TER_INCTHRES_DET1, 0x0e},
+       {R367TER_INCTHRES_DET2, 0x11},
+       {R367TER_IIR_CELLNB,    0x8d},
+       {R367TER_IIRCX_COEFF1_MSB, 0x00},
+       {R367TER_IIRCX_COEFF1_LSB, 0x00},
+       {R367TER_IIRCX_COEFF2_MSB, 0x09},
+       {R367TER_IIRCX_COEFF2_LSB, 0x18},
+       {R367TER_IIRCX_COEFF3_MSB, 0x14},
+       {R367TER_IIRCX_COEFF3_LSB, 0x9c},
+       {R367TER_IIRCX_COEFF4_MSB, 0x00},
+       {R367TER_IIRCX_COEFF4_LSB, 0x00},
+       {R367TER_IIRCX_COEFF5_MSB, 0x36},
+       {R367TER_IIRCX_COEFF5_LSB, 0x42},
+       {R367TER_FEPATH_CFG,    0x00},
+       {R367TER_PMC1_FUNC,     0x65},
+       {R367TER_PMC1_FOR,      0x00},
+       {R367TER_PMC2_FUNC,     0x00},
+       {R367TER_STATUS_ERR_DA, 0xe0},
+       {R367TER_DIG_AGC_R,     0xfe},
+       {R367TER_COMAGC_TARMSB, 0x0b},
+       {R367TER_COM_AGC_TAR_ENMODE, 0x41},
+       {R367TER_COM_AGC_CFG,   0x3e},
+       {R367TER_COM_AGC_GAIN1, 0x39},
+       {R367TER_AUT_AGC_TARGETMSB, 0x0b},
+       {R367TER_LOCK_DET_MSB,  0x01},
+       {R367TER_AGCTAR_LOCK_LSBS, 0x40},
+       {R367TER_AUT_GAIN_EN,   0xf4},
+       {R367TER_AUT_CFG,       0xf0},
+       {R367TER_LOCKN,         0x23},
+       {R367TER_INT_X_3,       0x00},
+       {R367TER_INT_X_2,       0x03},
+       {R367TER_INT_X_1,       0x8d},
+       {R367TER_INT_X_0,       0xa0},
+       {R367TER_MIN_ERRX_MSB,  0x00},
+       {R367TER_COR_CTL,       0x23},
+       {R367TER_COR_STAT,      0xf6},
+       {R367TER_COR_INTEN,     0x00},
+       {R367TER_COR_INTSTAT,   0x3f},
+       {R367TER_COR_MODEGUARD, 0x03},
+       {R367TER_AGC_CTL,       0x08},
+       {R367TER_AGC_MANUAL1,   0x00},
+       {R367TER_AGC_MANUAL2,   0x00},
+       {R367TER_AGC_TARG,      0x16},
+       {R367TER_AGC_GAIN1,     0x53},
+       {R367TER_AGC_GAIN2,     0x1d},
+       {R367TER_RESERVED_1,    0x00},
+       {R367TER_RESERVED_2,    0x00},
+       {R367TER_RESERVED_3,    0x00},
+       {R367TER_CAS_CTL,       0x44},
+       {R367TER_CAS_FREQ,      0xb3},
+       {R367TER_CAS_DAGCGAIN,  0x12},
+       {R367TER_SYR_CTL,       0x04},
+       {R367TER_SYR_STAT,      0x10},
+       {R367TER_SYR_NCO1,      0x00},
+       {R367TER_SYR_NCO2,      0x00},
+       {R367TER_SYR_OFFSET1,   0x00},
+       {R367TER_SYR_OFFSET2,   0x00},
+       {R367TER_FFT_CTL,       0x00},
+       {R367TER_SCR_CTL,       0x70},
+       {R367TER_PPM_CTL1,      0xf8},
+       {R367TER_TRL_CTL,       0x14},/* for xc5000; was 0xac */
+       {R367TER_TRL_NOMRATE1,  0xae},/* for xc5000; was 0x1e */
+       {R367TER_TRL_NOMRATE2,  0x56},/* for xc5000; was 0x58 */
+       {R367TER_TRL_TIME1,     0x1d},
+       {R367TER_TRL_TIME2,     0xfc},
+       {R367TER_CRL_CTL,       0x24},
+       {R367TER_CRL_FREQ1,     0xad},
+       {R367TER_CRL_FREQ2,     0x9d},
+       {R367TER_CRL_FREQ3,     0xff},
+       {R367TER_CHC_CTL,       0x01},
+       {R367TER_CHC_SNR,       0xf0},
+       {R367TER_BDI_CTL,       0x00},
+       {R367TER_DMP_CTL,       0x00},
+       {R367TER_TPS_RCVD1,     0x30},
+       {R367TER_TPS_RCVD2,     0x02},
+       {R367TER_TPS_RCVD3,     0x01},
+       {R367TER_TPS_RCVD4,     0x00},
+       {R367TER_TPS_ID_CELL1,  0x00},
+       {R367TER_TPS_ID_CELL2,  0x00},
+       {R367TER_TPS_RCVD5_SET1, 0x02},
+       {R367TER_TPS_SET2,      0x02},
+       {R367TER_TPS_SET3,      0x01},
+       {R367TER_TPS_CTL,       0x00},
+       {R367TER_CTL_FFTOSNUM,  0x34},
+       {R367TER_TESTSELECT,    0x09},
+       {R367TER_MSC_REV,       0x0a},
+       {R367TER_PIR_CTL,       0x00},
+       {R367TER_SNR_CARRIER1,  0xa1},
+       {R367TER_SNR_CARRIER2,  0x9a},
+       {R367TER_PPM_CPAMP,     0x2c},
+       {R367TER_TSM_AP0,       0x00},
+       {R367TER_TSM_AP1,       0x00},
+       {R367TER_TSM_AP2 ,      0x00},
+       {R367TER_TSM_AP3,       0x00},
+       {R367TER_TSM_AP4,       0x00},
+       {R367TER_TSM_AP5,       0x00},
+       {R367TER_TSM_AP6,       0x00},
+       {R367TER_TSM_AP7,       0x00},
+       {R367TER_TSTRES,        0x00},
+       {R367TER_ANACTRL,       0x0D},/* PLL stoped, restart at init!!! */
+       {R367TER_TSTBUS,        0x00},
+       {R367TER_TSTRATE,       0x00},
+       {R367TER_CONSTMODE,     0x01},
+       {R367TER_CONSTCARR1,    0x00},
+       {R367TER_CONSTCARR2,    0x00},
+       {R367TER_ICONSTEL,      0x0a},
+       {R367TER_QCONSTEL,      0x15},
+       {R367TER_TSTBISTRES0,   0x00},
+       {R367TER_TSTBISTRES1,   0x00},
+       {R367TER_TSTBISTRES2,   0x28},
+       {R367TER_TSTBISTRES3,   0x00},
+       {R367TER_RF_AGC1,       0xff},
+       {R367TER_RF_AGC2,       0x83},
+       {R367TER_ANADIGCTRL,    0x19},
+       {R367TER_PLLMDIV,       0x01},/* for xc5000; was 0x0c */
+       {R367TER_PLLNDIV,       0x06},/* for xc5000; was 0x55 */
+       {R367TER_PLLSETUP,      0x18},
+       {R367TER_DUAL_AD12,     0x0C},/* for xc5000 AGC voltage 1.6V */
+       {R367TER_TSTBIST,       0x00},
+       {R367TER_PAD_COMP_CTRL, 0x00},
+       {R367TER_PAD_COMP_WR,   0x00},
+       {R367TER_PAD_COMP_RD,   0xe0},
+       {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
+       {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
+       {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
+       {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
+       {R367TER_SYR_FLAG,      0x00},
+       {R367TER_CRL_TARGET1,   0x00},
+       {R367TER_CRL_TARGET2,   0x00},
+       {R367TER_CRL_TARGET3,   0x00},
+       {R367TER_CRL_TARGET4,   0x00},
+       {R367TER_CRL_FLAG,      0x00},
+       {R367TER_TRL_TARGET1,   0x00},
+       {R367TER_TRL_TARGET2,   0x00},
+       {R367TER_TRL_CHC,       0x00},
+       {R367TER_CHC_SNR_TARG,  0x00},
+       {R367TER_TOP_TRACK,     0x00},
+       {R367TER_TRACKER_FREE1, 0x00},
+       {R367TER_ERROR_CRL1,    0x00},
+       {R367TER_ERROR_CRL2,    0x00},
+       {R367TER_ERROR_CRL3,    0x00},
+       {R367TER_ERROR_CRL4,    0x00},
+       {R367TER_DEC_NCO1,      0x2c},
+       {R367TER_DEC_NCO2,      0x0f},
+       {R367TER_DEC_NCO3,      0x20},
+       {R367TER_SNR,           0xf1},
+       {R367TER_SYR_FFTADJ1,   0x00},
+       {R367TER_SYR_FFTADJ2,   0x00},
+       {R367TER_SYR_CHCADJ1,   0x00},
+       {R367TER_SYR_CHCADJ2,   0x00},
+       {R367TER_SYR_OFF,       0x00},
+       {R367TER_PPM_OFFSET1,   0x00},
+       {R367TER_PPM_OFFSET2,   0x03},
+       {R367TER_TRACKER_FREE2, 0x00},
+       {R367TER_DEBG_LT10,     0x00},
+       {R367TER_DEBG_LT11,     0x00},
+       {R367TER_DEBG_LT12,     0x00},
+       {R367TER_DEBG_LT13,     0x00},
+       {R367TER_DEBG_LT14,     0x00},
+       {R367TER_DEBG_LT15,     0x00},
+       {R367TER_DEBG_LT16,     0x00},
+       {R367TER_DEBG_LT17,     0x00},
+       {R367TER_DEBG_LT18,     0x00},
+       {R367TER_DEBG_LT19,     0x00},
+       {R367TER_DEBG_LT1A,     0x00},
+       {R367TER_DEBG_LT1B,     0x00},
+       {R367TER_DEBG_LT1C,     0x00},
+       {R367TER_DEBG_LT1D,     0x00},
+       {R367TER_DEBG_LT1E,     0x00},
+       {R367TER_DEBG_LT1F,     0x00},
+       {R367TER_RCCFGH,        0x00},
+       {R367TER_RCCFGM,        0x00},
+       {R367TER_RCCFGL,        0x00},
+       {R367TER_RCINSDELH,     0x00},
+       {R367TER_RCINSDELM,     0x00},
+       {R367TER_RCINSDELL,     0x00},
+       {R367TER_RCSTATUS,      0x00},
+       {R367TER_RCSPEED,       0x6f},
+       {R367TER_RCDEBUGM,      0xe7},
+       {R367TER_RCDEBUGL,      0x9b},
+       {R367TER_RCOBSCFG,      0x00},
+       {R367TER_RCOBSM,        0x00},
+       {R367TER_RCOBSL,        0x00},
+       {R367TER_RCFECSPY,      0x00},
+       {R367TER_RCFSPYCFG,     0x00},
+       {R367TER_RCFSPYDATA,    0x00},
+       {R367TER_RCFSPYOUT,     0x00},
+       {R367TER_RCFSTATUS,     0x00},
+       {R367TER_RCFGOODPACK,   0x00},
+       {R367TER_RCFPACKCNT,    0x00},
+       {R367TER_RCFSPYMISC,    0x00},
+       {R367TER_RCFBERCPT4,    0x00},
+       {R367TER_RCFBERCPT3,    0x00},
+       {R367TER_RCFBERCPT2,    0x00},
+       {R367TER_RCFBERCPT1,    0x00},
+       {R367TER_RCFBERCPT0,    0x00},
+       {R367TER_RCFBERERR2,    0x00},
+       {R367TER_RCFBERERR1,    0x00},
+       {R367TER_RCFBERERR0,    0x00},
+       {R367TER_RCFSTATESM,    0x00},
+       {R367TER_RCFSTATESL,    0x00},
+       {R367TER_RCFSPYBER,     0x00},
+       {R367TER_RCFSPYDISTM,   0x00},
+       {R367TER_RCFSPYDISTL,   0x00},
+       {R367TER_RCFSPYOBS7,    0x00},
+       {R367TER_RCFSPYOBS6,    0x00},
+       {R367TER_RCFSPYOBS5,    0x00},
+       {R367TER_RCFSPYOBS4,    0x00},
+       {R367TER_RCFSPYOBS3,    0x00},
+       {R367TER_RCFSPYOBS2,    0x00},
+       {R367TER_RCFSPYOBS1,    0x00},
+       {R367TER_RCFSPYOBS0,    0x00},
+       {R367TER_TSGENERAL,     0x00},
+       {R367TER_RC1SPEED,      0x6f},
+       {R367TER_TSGSTATUS,     0x18},
+       {R367TER_FECM,          0x01},
+       {R367TER_VTH12,         0xff},
+       {R367TER_VTH23,         0xa1},
+       {R367TER_VTH34,         0x64},
+       {R367TER_VTH56,         0x40},
+       {R367TER_VTH67,         0x00},
+       {R367TER_VTH78,         0x2c},
+       {R367TER_VITCURPUN,     0x12},
+       {R367TER_VERROR,        0x01},
+       {R367TER_PRVIT,         0x3f},
+       {R367TER_VAVSRVIT,      0x00},
+       {R367TER_VSTATUSVIT,    0xbd},
+       {R367TER_VTHINUSE,      0xa1},
+       {R367TER_KDIV12,        0x20},
+       {R367TER_KDIV23,        0x40},
+       {R367TER_KDIV34,        0x20},
+       {R367TER_KDIV56,        0x30},
+       {R367TER_KDIV67,        0x00},
+       {R367TER_KDIV78,        0x30},
+       {R367TER_SIGPOWER,      0x54},
+       {R367TER_DEMAPVIT,      0x40},
+       {R367TER_VITSCALE,      0x00},
+       {R367TER_FFEC1PRG,      0x00},
+       {R367TER_FVITCURPUN,    0x12},
+       {R367TER_FVERROR,       0x01},
+       {R367TER_FVSTATUSVIT,   0xbd},
+       {R367TER_DEBUG_LT1,     0x00},
+       {R367TER_DEBUG_LT2,     0x00},
+       {R367TER_DEBUG_LT3,     0x00},
+       {R367TER_TSTSFMET,      0x00},
+       {R367TER_SELOUT,        0x00},
+       {R367TER_TSYNC,         0x00},
+       {R367TER_TSTERR,        0x00},
+       {R367TER_TSFSYNC,       0x00},
+       {R367TER_TSTSFERR,      0x00},
+       {R367TER_TSTTSSF1,      0x01},
+       {R367TER_TSTTSSF2,      0x1f},
+       {R367TER_TSTTSSF3,      0x00},
+       {R367TER_TSTTS1,        0x00},
+       {R367TER_TSTTS2,        0x1f},
+       {R367TER_TSTTS3,        0x01},
+       {R367TER_TSTTS4,        0x00},
+       {R367TER_TSTTSRC,       0x00},
+       {R367TER_TSTTSRS,       0x00},
+       {R367TER_TSSTATEM,      0xb0},
+       {R367TER_TSSTATEL,      0x40},
+       {R367TER_TSCFGH,        0xC0},
+       {R367TER_TSCFGM,        0xc0},/* for xc5000; was 0x00 */
+       {R367TER_TSCFGL,        0x20},
+       {R367TER_TSSYNC,        0x00},
+       {R367TER_TSINSDELH,     0x00},
+       {R367TER_TSINSDELM,     0x00},
+       {R367TER_TSINSDELL,     0x00},
+       {R367TER_TSDIVN,        0x03},
+       {R367TER_TSDIVPM,       0x00},
+       {R367TER_TSDIVPL,       0x00},
+       {R367TER_TSDIVQM,       0x00},
+       {R367TER_TSDIVQL,       0x00},
+       {R367TER_TSDILSTKM,     0x00},
+       {R367TER_TSDILSTKL,     0x00},
+       {R367TER_TSSPEED,       0x40},/* for xc5000; was 0x6f */
+       {R367TER_TSSTATUS,      0x81},
+       {R367TER_TSSTATUS2,     0x6a},
+       {R367TER_TSBITRATEM,    0x0f},
+       {R367TER_TSBITRATEL,    0xc6},
+       {R367TER_TSPACKLENM,    0x00},
+       {R367TER_TSPACKLENL,    0xfc},
+       {R367TER_TSBLOCLENM,    0x0a},
+       {R367TER_TSBLOCLENL,    0x80},
+       {R367TER_TSDLYH,        0x90},
+       {R367TER_TSDLYM,        0x68},
+       {R367TER_TSDLYL,        0x01},
+       {R367TER_TSNPDAV,       0x00},
+       {R367TER_TSBUFSTATH,    0x00},
+       {R367TER_TSBUFSTATM,    0x00},
+       {R367TER_TSBUFSTATL,    0x00},
+       {R367TER_TSDEBUGM,      0xcf},
+       {R367TER_TSDEBUGL,      0x1e},
+       {R367TER_TSDLYSETH,     0x00},
+       {R367TER_TSDLYSETM,     0x68},
+       {R367TER_TSDLYSETL,     0x00},
+       {R367TER_TSOBSCFG,      0x00},
+       {R367TER_TSOBSM,        0x47},
+       {R367TER_TSOBSL,        0x1f},
+       {R367TER_ERRCTRL1,      0x95},
+       {R367TER_ERRCNT1H,      0x80},
+       {R367TER_ERRCNT1M,      0x00},
+       {R367TER_ERRCNT1L,      0x00},
+       {R367TER_ERRCTRL2,      0x95},
+       {R367TER_ERRCNT2H,      0x00},
+       {R367TER_ERRCNT2M,      0x00},
+       {R367TER_ERRCNT2L,      0x00},
+       {R367TER_FECSPY,        0x88},
+       {R367TER_FSPYCFG,       0x2c},
+       {R367TER_FSPYDATA,      0x3a},
+       {R367TER_FSPYOUT,       0x06},
+       {R367TER_FSTATUS,       0x61},
+       {R367TER_FGOODPACK,     0xff},
+       {R367TER_FPACKCNT,      0xff},
+       {R367TER_FSPYMISC,      0x66},
+       {R367TER_FBERCPT4,      0x00},
+       {R367TER_FBERCPT3,      0x00},
+       {R367TER_FBERCPT2,      0x36},
+       {R367TER_FBERCPT1,      0x36},
+       {R367TER_FBERCPT0,      0x14},
+       {R367TER_FBERERR2,      0x00},
+       {R367TER_FBERERR1,      0x03},
+       {R367TER_FBERERR0,      0x28},
+       {R367TER_FSTATESM,      0x00},
+       {R367TER_FSTATESL,      0x02},
+       {R367TER_FSPYBER,       0x00},
+       {R367TER_FSPYDISTM,     0x01},
+       {R367TER_FSPYDISTL,     0x9f},
+       {R367TER_FSPYOBS7,      0xc9},
+       {R367TER_FSPYOBS6,      0x99},
+       {R367TER_FSPYOBS5,      0x08},
+       {R367TER_FSPYOBS4,      0xec},
+       {R367TER_FSPYOBS3,      0x01},
+       {R367TER_FSPYOBS2,      0x0f},
+       {R367TER_FSPYOBS1,      0xf5},
+       {R367TER_FSPYOBS0,      0x08},
+       {R367TER_SFDEMAP,       0x40},
+       {R367TER_SFERROR,       0x00},
+       {R367TER_SFAVSR,        0x30},
+       {R367TER_SFECSTATUS,    0xcc},
+       {R367TER_SFKDIV12,      0x20},
+       {R367TER_SFKDIV23,      0x40},
+       {R367TER_SFKDIV34,      0x20},
+       {R367TER_SFKDIV56,      0x20},
+       {R367TER_SFKDIV67,      0x00},
+       {R367TER_SFKDIV78,      0x20},
+       {R367TER_SFDILSTKM,     0x00},
+       {R367TER_SFDILSTKL,     0x00},
+       {R367TER_SFSTATUS,      0xb5},
+       {R367TER_SFDLYH,        0x90},
+       {R367TER_SFDLYM,        0x60},
+       {R367TER_SFDLYL,        0x01},
+       {R367TER_SFDLYSETH,     0xc0},
+       {R367TER_SFDLYSETM,     0x60},
+       {R367TER_SFDLYSETL,     0x00},
+       {R367TER_SFOBSCFG,      0x00},
+       {R367TER_SFOBSM,        0x47},
+       {R367TER_SFOBSL,        0x05},
+       {R367TER_SFECINFO,      0x40},
+       {R367TER_SFERRCTRL,     0x74},
+       {R367TER_SFERRCNTH,     0x80},
+       {R367TER_SFERRCNTM ,    0x00},
+       {R367TER_SFERRCNTL,     0x00},
+       {R367TER_SYMBRATEM,     0x2f},
+       {R367TER_SYMBRATEL,     0x50},
+       {R367TER_SYMBSTATUS,    0x7f},
+       {R367TER_SYMBCFG,       0x00},
+       {R367TER_SYMBFIFOM,     0xf4},
+       {R367TER_SYMBFIFOL,     0x0d},
+       {R367TER_SYMBOFFSM,     0xf0},
+       {R367TER_SYMBOFFSL,     0x2d},
+       {R367TER_DEBUG_LT4,     0x00},
+       {R367TER_DEBUG_LT5,     0x00},
+       {R367TER_DEBUG_LT6,     0x00},
+       {R367TER_DEBUG_LT7,     0x00},
+       {R367TER_DEBUG_LT8,     0x00},
+       {R367TER_DEBUG_LT9,     0x00},
+};
+
+#define RF_LOOKUP_TABLE_SIZE  31
+#define RF_LOOKUP_TABLE2_SIZE 16
+/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
+s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
+       {/*AGC1*/
+               48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
+               64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+               76, 77, 78, 80, 83, 85, 88,
+       }, {/*RF(dbm)*/
+               22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+               34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
+               49, 50, 52, 53, 54, 55, 56,
+       }
+};
+/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
+s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
+       {/*AGC2*/
+               28, 29, 31, 32, 34, 35, 36, 37,
+               38, 39, 40, 41, 42, 43, 44, 45,
+       }, {/*RF(dbm)*/
+               57, 58, 59, 60, 61, 62, 63, 64,
+               65, 66, 67, 68, 69, 70, 71, 72,
+       }
+};
+
+static struct st_register def0367cab[STV0367CAB_NBREGS] = {
+       {R367CAB_ID,            0x60},
+       {R367CAB_I2CRPT,        0xa0},
+       /*{R367CAB_I2CRPT,      0x22},*/
+       {R367CAB_TOPCTRL,       0x10},
+       {R367CAB_IOCFG0,        0x80},
+       {R367CAB_DAC0R,         0x00},
+       {R367CAB_IOCFG1,        0x00},
+       {R367CAB_DAC1R,         0x00},
+       {R367CAB_IOCFG2,        0x00},
+       {R367CAB_SDFR,          0x00},
+       {R367CAB_AUX_CLK,       0x00},
+       {R367CAB_FREESYS1,      0x00},
+       {R367CAB_FREESYS2,      0x00},
+       {R367CAB_FREESYS3,      0x00},
+       {R367CAB_GPIO_CFG,      0x55},
+       {R367CAB_GPIO_CMD,      0x01},
+       {R367CAB_TSTRES,        0x00},
+       {R367CAB_ANACTRL,       0x0d},/* was 0x00 need to check - I.M.L.*/
+       {R367CAB_TSTBUS,        0x00},
+       {R367CAB_RF_AGC1,       0xea},
+       {R367CAB_RF_AGC2,       0x82},
+       {R367CAB_ANADIGCTRL,    0x0b},
+       {R367CAB_PLLMDIV,       0x01},
+       {R367CAB_PLLNDIV,       0x08},
+       {R367CAB_PLLSETUP,      0x18},
+       {R367CAB_DUAL_AD12,     0x0C}, /* for xc5000 AGC voltage 1.6V */
+       {R367CAB_TSTBIST,       0x00},
+       {R367CAB_CTRL_1,        0x00},
+       {R367CAB_CTRL_2,        0x03},
+       {R367CAB_IT_STATUS1,    0x2b},
+       {R367CAB_IT_STATUS2,    0x08},
+       {R367CAB_IT_EN1,        0x00},
+       {R367CAB_IT_EN2,        0x00},
+       {R367CAB_CTRL_STATUS,   0x04},
+       {R367CAB_TEST_CTL,      0x00},
+       {R367CAB_AGC_CTL,       0x73},
+       {R367CAB_AGC_IF_CFG,    0x50},
+       {R367CAB_AGC_RF_CFG,    0x00},
+       {R367CAB_AGC_PWM_CFG,   0x03},
+       {R367CAB_AGC_PWR_REF_L, 0x5a},
+       {R367CAB_AGC_PWR_REF_H, 0x00},
+       {R367CAB_AGC_RF_TH_L,   0xff},
+       {R367CAB_AGC_RF_TH_H,   0x07},
+       {R367CAB_AGC_IF_LTH_L,  0x00},
+       {R367CAB_AGC_IF_LTH_H,  0x08},
+       {R367CAB_AGC_IF_HTH_L,  0xff},
+       {R367CAB_AGC_IF_HTH_H,  0x07},
+       {R367CAB_AGC_PWR_RD_L,  0xa0},
+       {R367CAB_AGC_PWR_RD_M,  0xe9},
+       {R367CAB_AGC_PWR_RD_H,  0x03},
+       {R367CAB_AGC_PWM_IFCMD_L,       0xe4},
+       {R367CAB_AGC_PWM_IFCMD_H,       0x00},
+       {R367CAB_AGC_PWM_RFCMD_L,       0xff},
+       {R367CAB_AGC_PWM_RFCMD_H,       0x07},
+       {R367CAB_IQDEM_CFG,     0x01},
+       {R367CAB_MIX_NCO_LL,    0x22},
+       {R367CAB_MIX_NCO_HL,    0x96},
+       {R367CAB_MIX_NCO_HH,    0x55},
+       {R367CAB_SRC_NCO_LL,    0xff},
+       {R367CAB_SRC_NCO_LH,    0x0c},
+       {R367CAB_SRC_NCO_HL,    0xf5},
+       {R367CAB_SRC_NCO_HH,    0x20},
+       {R367CAB_IQDEM_GAIN_SRC_L,      0x06},
+       {R367CAB_IQDEM_GAIN_SRC_H,      0x01},
+       {R367CAB_IQDEM_DCRM_CFG_LL,     0xfe},
+       {R367CAB_IQDEM_DCRM_CFG_LH,     0xff},
+       {R367CAB_IQDEM_DCRM_CFG_HL,     0x0f},
+       {R367CAB_IQDEM_DCRM_CFG_HH,     0x00},
+       {R367CAB_IQDEM_ADJ_COEFF0,      0x34},
+       {R367CAB_IQDEM_ADJ_COEFF1,      0xae},
+       {R367CAB_IQDEM_ADJ_COEFF2,      0x46},
+       {R367CAB_IQDEM_ADJ_COEFF3,      0x77},
+       {R367CAB_IQDEM_ADJ_COEFF4,      0x96},
+       {R367CAB_IQDEM_ADJ_COEFF5,      0x69},
+       {R367CAB_IQDEM_ADJ_COEFF6,      0xc7},
+       {R367CAB_IQDEM_ADJ_COEFF7,      0x01},
+       {R367CAB_IQDEM_ADJ_EN,  0x04},
+       {R367CAB_IQDEM_ADJ_AGC_REF,     0x94},
+       {R367CAB_ALLPASSFILT1,  0xc9},
+       {R367CAB_ALLPASSFILT2,  0x2d},
+       {R367CAB_ALLPASSFILT3,  0xa3},
+       {R367CAB_ALLPASSFILT4,  0xfb},
+       {R367CAB_ALLPASSFILT5,  0xf6},
+       {R367CAB_ALLPASSFILT6,  0x45},
+       {R367CAB_ALLPASSFILT7,  0x6f},
+       {R367CAB_ALLPASSFILT8,  0x7e},
+       {R367CAB_ALLPASSFILT9,  0x05},
+       {R367CAB_ALLPASSFILT10, 0x0a},
+       {R367CAB_ALLPASSFILT11, 0x51},
+       {R367CAB_TRL_AGC_CFG,   0x20},
+       {R367CAB_TRL_LPF_CFG,   0x28},
+       {R367CAB_TRL_LPF_ACQ_GAIN,      0x44},
+       {R367CAB_TRL_LPF_TRK_GAIN,      0x22},
+       {R367CAB_TRL_LPF_OUT_GAIN,      0x03},
+       {R367CAB_TRL_LOCKDET_LTH,       0x04},
+       {R367CAB_TRL_LOCKDET_HTH,       0x11},
+       {R367CAB_TRL_LOCKDET_TRGVAL,    0x20},
+       {R367CAB_IQ_QAM,        0x01},
+       {R367CAB_FSM_STATE,     0xa0},
+       {R367CAB_FSM_CTL,       0x08},
+       {R367CAB_FSM_STS,       0x0c},
+       {R367CAB_FSM_SNR0_HTH,  0x00},
+       {R367CAB_FSM_SNR1_HTH,  0x00},
+       {R367CAB_FSM_SNR2_HTH,  0x23},/* 0x00 */
+       {R367CAB_FSM_SNR0_LTH,  0x00},
+       {R367CAB_FSM_SNR1_LTH,  0x00},
+       {R367CAB_FSM_EQA1_HTH,  0x00},
+       {R367CAB_FSM_TEMPO,     0x32},
+       {R367CAB_FSM_CONFIG,    0x03},
+       {R367CAB_EQU_I_TESTTAP_L,       0x11},
+       {R367CAB_EQU_I_TESTTAP_M,       0x00},
+       {R367CAB_EQU_I_TESTTAP_H,       0x00},
+       {R367CAB_EQU_TESTAP_CFG,        0x00},
+       {R367CAB_EQU_Q_TESTTAP_L,       0xff},
+       {R367CAB_EQU_Q_TESTTAP_M,       0x00},
+       {R367CAB_EQU_Q_TESTTAP_H,       0x00},
+       {R367CAB_EQU_TAP_CTRL,  0x00},
+       {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
+       {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
+       {R367CAB_EQU_CTR_HIPOW_L,       0x00},
+       {R367CAB_EQU_CTR_HIPOW_H,       0x00},
+       {R367CAB_EQU_I_EQU_LO,  0xef},
+       {R367CAB_EQU_I_EQU_HI,  0x00},
+       {R367CAB_EQU_Q_EQU_LO,  0xee},
+       {R367CAB_EQU_Q_EQU_HI,  0x00},
+       {R367CAB_EQU_MAPPER,    0xc5},
+       {R367CAB_EQU_SWEEP_RATE,        0x80},
+       {R367CAB_EQU_SNR_LO,    0x64},
+       {R367CAB_EQU_SNR_HI,    0x03},
+       {R367CAB_EQU_GAMMA_LO,  0x00},
+       {R367CAB_EQU_GAMMA_HI,  0x00},
+       {R367CAB_EQU_ERR_GAIN,  0x36},
+       {R367CAB_EQU_RADIUS,    0xaa},
+       {R367CAB_EQU_FFE_MAINTAP,       0x00},
+       {R367CAB_EQU_FFE_LEAKAGE,       0x63},
+       {R367CAB_EQU_FFE_MAINTAP_POS,   0xdf},
+       {R367CAB_EQU_GAIN_WIDE, 0x88},
+       {R367CAB_EQU_GAIN_NARROW,       0x41},
+       {R367CAB_EQU_CTR_LPF_GAIN,      0xd1},
+       {R367CAB_EQU_CRL_LPF_GAIN,      0xa7},
+       {R367CAB_EQU_GLOBAL_GAIN,       0x06},
+       {R367CAB_EQU_CRL_LD_SEN,        0x85},
+       {R367CAB_EQU_CRL_LD_VAL,        0xe2},
+       {R367CAB_EQU_CRL_TFR,   0x20},
+       {R367CAB_EQU_CRL_BISTH_LO,      0x00},
+       {R367CAB_EQU_CRL_BISTH_HI,      0x00},
+       {R367CAB_EQU_SWEEP_RANGE_LO,    0x00},
+       {R367CAB_EQU_SWEEP_RANGE_HI,    0x00},
+       {R367CAB_EQU_CRL_LIMITER,       0x40},
+       {R367CAB_EQU_MODULUS_MAP,       0x90},
+       {R367CAB_EQU_PNT_GAIN,  0xa7},
+       {R367CAB_FEC_AC_CTR_0,  0x16},
+       {R367CAB_FEC_AC_CTR_1,  0x0b},
+       {R367CAB_FEC_AC_CTR_2,  0x88},
+       {R367CAB_FEC_AC_CTR_3,  0x02},
+       {R367CAB_FEC_STATUS,    0x12},
+       {R367CAB_RS_COUNTER_0,  0x7d},
+       {R367CAB_RS_COUNTER_1,  0xd0},
+       {R367CAB_RS_COUNTER_2,  0x19},
+       {R367CAB_RS_COUNTER_3,  0x0b},
+       {R367CAB_RS_COUNTER_4,  0xa3},
+       {R367CAB_RS_COUNTER_5,  0x00},
+       {R367CAB_BERT_0,        0x01},
+       {R367CAB_BERT_1,        0x25},
+       {R367CAB_BERT_2,        0x41},
+       {R367CAB_BERT_3,        0x39},
+       {R367CAB_OUTFORMAT_0,   0xc2},
+       {R367CAB_OUTFORMAT_1,   0x22},
+       {R367CAB_SMOOTHER_2,    0x28},
+       {R367CAB_TSMF_CTRL_0,   0x01},
+       {R367CAB_TSMF_CTRL_1,   0xc6},
+       {R367CAB_TSMF_CTRL_3,   0x43},
+       {R367CAB_TS_ON_ID_0,    0x00},
+       {R367CAB_TS_ON_ID_1,    0x00},
+       {R367CAB_TS_ON_ID_2,    0x00},
+       {R367CAB_TS_ON_ID_3,    0x00},
+       {R367CAB_RE_STATUS_0,   0x00},
+       {R367CAB_RE_STATUS_1,   0x00},
+       {R367CAB_RE_STATUS_2,   0x00},
+       {R367CAB_RE_STATUS_3,   0x00},
+       {R367CAB_TS_STATUS_0,   0x00},
+       {R367CAB_TS_STATUS_1,   0x00},
+       {R367CAB_TS_STATUS_2,   0xa0},
+       {R367CAB_TS_STATUS_3,   0x00},
+       {R367CAB_T_O_ID_0,      0x00},
+       {R367CAB_T_O_ID_1,      0x00},
+       {R367CAB_T_O_ID_2,      0x00},
+       {R367CAB_T_O_ID_3,      0x00},
+};
+
+static
+int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
+{
+       u8 buf[len + 2];
+       struct i2c_msg msg = {
+               .addr = state->config->demod_address,
+               .flags = 0,
+               .buf = buf,
+               .len = len + 2
+       };
+       int ret;
+
+       buf[0] = MSB(reg);
+       buf[1] = LSB(reg);
+       memcpy(buf + 2, data, len);
+
+       if (i2cdebug)
+               printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+       if (ret != 1)
+               printk(KERN_ERR "%s: i2c write error!\n", __func__);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+{
+       return stv0367_writeregs(state, reg, &data, 1);
+}
+
+static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+{
+       u8 b0[] = { 0, 0 };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {
+                       .addr = state->config->demod_address,
+                       .flags = 0,
+                       .buf = b0,
+                       .len = 2
+               }, {
+                       .addr = state->config->demod_address,
+                       .flags = I2C_M_RD,
+                       .buf = b1,
+                       .len = 1
+               }
+       };
+       int ret;
+
+       b0[0] = MSB(reg);
+       b0[1] = LSB(reg);
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2)
+               printk(KERN_ERR "%s: i2c read error\n", __func__);
+
+       if (i2cdebug)
+               printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
+
+       return b1[0];
+}
+
+static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+       u8 position = 0, i = 0;
+
+       (*mask) = label & 0xff;
+
+       while ((position == 0) && (i < 8)) {
+               position = ((*mask) >> i) & 0x01;
+               i++;
+       }
+
+       (*pos) = (i - 1);
+}
+
+static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
+{
+       u8 reg, mask, pos;
+
+       reg = stv0367_readreg(state, (label >> 16) & 0xffff);
+       extract_mask_pos(label, &mask, &pos);
+
+       val = mask & (val << pos);
+
+       reg = (reg & (~mask)) | val;
+       stv0367_writereg(state, (label >> 16) & 0xffff, reg);
+
+}
+
+static void stv0367_setbits(u8 *reg, u32 label, u8 val)
+{
+       u8 mask, pos;
+
+       extract_mask_pos(label, &mask, &pos);
+
+       val = mask & (val << pos);
+
+       (*reg) = ((*reg) & (~mask)) | val;
+}
+
+static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
+{
+       u8 val = 0xff;
+       u8 mask, pos;
+
+       extract_mask_pos(label, &mask, &pos);
+
+       val = stv0367_readreg(state, label >> 16);
+       val = (val & mask) >> pos;
+
+       return val;
+}
+
+u8 stv0367_getbits(u8 reg, u32 label)
+{
+       u8 mask, pos;
+
+       extract_mask_pos(label, &mask, &pos);
+
+       return (reg & mask) >> pos;
+}
+
+static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
+
+       dprintk("%s:\n", __func__);
+
+       if (enable) {
+               stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
+               stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
+       } else {
+               stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
+               stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
+       }
+
+       stv0367_writereg(state, R367TER_I2CRPT, tmp);
+
+       return 0;
+}
+
+static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       u32 freq = 0;
+       int err = 0;
+
+       dprintk("%s:\n", __func__);
+
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_frequency) {
+               err = tuner_ops->get_frequency(fe, &freq);
+               if (err < 0) {
+                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+
+               dprintk("%s: frequency=%d\n", __func__, freq);
+
+       } else
+               return -1;
+
+       return freq;
+}
+
+static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
+       {
+               {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
+               {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
+               {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
+               {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
+               {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
+               {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
+       }, {
+               {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
+               {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
+               {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
+               {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
+               {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
+               {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
+       }, {
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
+       }
+};
+
+static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
+       {
+               {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
+               {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
+               {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
+               {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
+               {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
+               {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
+       }, {
+               {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
+               {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
+               {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
+               {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
+               {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
+               {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
+       }, {
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
+       }
+};
+
+static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
+       {
+               {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
+               {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
+               {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
+               {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
+               {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
+               {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
+       }, {
+               {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
+               {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
+               {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
+               {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
+               {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
+               {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
+
+       }, {
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
+               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
+       }
+};
+
+static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
+{
+       u32 mclk_Hz = 0; /* master clock frequency (Hz) */
+       u32 m, n, p;
+
+       dprintk("%s:\n", __func__);
+
+       if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
+               n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
+               if (n == 0)
+                       n = n + 1;
+
+               m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
+               if (m == 0)
+                       m = m + 1;
+
+               p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
+               if (p > 5)
+                       p = 5;
+
+               mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
+
+               dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
+                               n, m, p, mclk_Hz, ExtClk_Hz);
+       } else
+               mclk_Hz = ExtClk_Hz;
+
+       dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
+
+       return mclk_Hz;
+}
+
+static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
+                               u16 CellsCoeffs[3][6][5], u32 DemodXtal)
+{
+       int i, j, k, freq;
+
+       dprintk("%s:\n", __func__);
+
+       freq = stv0367ter_get_mclk(state, DemodXtal);
+
+       if (freq == 53125000)
+               k = 1; /* equivalent to Xtal 25M on 362*/
+       else if (freq == 54000000)
+               k = 0; /* equivalent to Xtal 27M on 362*/
+       else if (freq == 52500000)
+               k = 2; /* equivalent to Xtal 30M on 362*/
+       else
+               return 0;
+
+       for (i = 1; i <= 6; i++) {
+               stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
+
+               for (j = 1; j <= 5; j++) {
+                       stv0367_writereg(state,
+                               (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
+                               MSB(CellsCoeffs[k][i-1][j-1]));
+                       stv0367_writereg(state,
+                               (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
+                               LSB(CellsCoeffs[k][i-1][j-1]));
+               }
+       }
+
+       return 1;
+
+}
+
+static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
+{
+       dprintk("%s:\n", __func__);
+
+       stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
+
+       /* Lock detect 1 */
+       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
+       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
+       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
+
+       /* Lock detect 2 */
+       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
+       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
+       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
+
+       /* Lock detect 3 */
+       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
+       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
+       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
+
+       /* Lock detect 4 */
+       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
+       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
+       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
+
+}
+
+static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
+                                                       u32 DemodXtalValue)
+{
+       dprintk("%s:\n", __func__);
+
+       stv0367_writebits(state, F367TER_NRST_IIR, 0);
+
+       switch (Bandwidth) {
+       case 6:
+               if (!stv0367ter_filt_coeff_init(state,
+                               CellsCoeffs_6MHz_367cofdm,
+                               DemodXtalValue))
+                       return 0;
+               break;
+       case 7:
+               if (!stv0367ter_filt_coeff_init(state,
+                               CellsCoeffs_7MHz_367cofdm,
+                               DemodXtalValue))
+                       return 0;
+               break;
+       case 8:
+               if (!stv0367ter_filt_coeff_init(state,
+                               CellsCoeffs_8MHz_367cofdm,
+                               DemodXtalValue))
+                       return 0;
+               break;
+       default:
+               return 0;
+       }
+
+       stv0367_writebits(state, F367TER_NRST_IIR, 1);
+
+       return 1;
+}
+
+static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
+{
+
+       u8 com_n;
+
+       dprintk("%s:\n", __func__);
+
+       com_n = stv0367_readbits(state, F367TER_COM_N);
+
+       stv0367_writebits(state, F367TER_COM_N, 0x07);
+
+       stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
+       stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
+
+       stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
+       stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
+
+       stv0367_writebits(state, F367TER_COM_N, com_n);
+
+}
+
+static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
+{
+       int local_tempo = 0;
+       switch (mode) {
+       case 0:
+               local_tempo = tempo1;
+               break;
+       case 1:
+               local_tempo = tempo2;
+               break ;
+
+       case 2:
+               local_tempo = tempo3;
+               break;
+
+       default:
+               break;
+       }
+       /*      msleep(local_tempo);  */
+       return local_tempo;
+}
+
+static enum
+stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
+{
+       int wd = 100;
+       unsigned short int SYR_var;
+       s32 SYRStatus;
+
+       dprintk("%s:\n", __func__);
+
+       SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
+
+       while ((!SYR_var) && (wd > 0)) {
+               usleep_range(2000, 3000);
+               wd -= 2;
+               SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
+       }
+
+       if (!SYR_var)
+               SYRStatus = FE_TER_NOSYMBOL;
+       else
+               SYRStatus =  FE_TER_SYMBOLOK;
+
+       dprintk("stv0367ter_check_syr SYRStatus %s\n",
+                               SYR_var == 0 ? "No Symbol" : "OK");
+
+       return SYRStatus;
+}
+
+static enum
+stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
+                                                               s32 FFTmode)
+{
+
+       s32  CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
+       int wd = 0;
+
+       dprintk("%s:\n", __func__);
+
+       switch (FFTmode) {
+       case 0: /*2k mode*/
+               CPAMPMin = 20;
+               wd = 10;
+               break;
+       case 1: /*8k mode*/
+               CPAMPMin = 80;
+               wd = 55;
+               break;
+       case 2: /*4k mode*/
+               CPAMPMin = 40;
+               wd = 30;
+               break;
+       default:
+               CPAMPMin = 0xffff;  /*drives to NOCPAMP */
+               break;
+       }
+
+       dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
+
+       CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
+       while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
+               usleep_range(1000, 2000);
+               wd -= 1;
+               CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
+               /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
+       }
+       dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
+       if (CPAMPvalue < CPAMPMin) {
+               CPAMPStatus = FE_TER_NOCPAMP;
+               printk(KERN_ERR "CPAMP failed\n");
+       } else {
+               printk(KERN_ERR "CPAMP OK !\n");
+               CPAMPStatus = FE_TER_CPAMPOK;
+       }
+
+       return CPAMPStatus;
+}
+
+enum
+stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
+{
+       enum stv0367_ter_signal_type ret_flag;
+       short int wd, tempo;
+       u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
+       u8 tmp, tmp2;
+
+       dprintk("%s:\n", __func__);
+
+       if (state == NULL)
+               return FE_TER_SWNOK;
+
+       try = 0;
+       do {
+               ret_flag = FE_TER_LOCKOK;
+
+               stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
+
+               if (state->config->if_iq_mode != 0)
+                       stv0367_writebits(state, F367TER_COM_N, 0x07);
+
+               stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
+               stv0367_writebits(state, F367TER_MODE, 0);
+               stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
+               usleep_range(5000, 10000);
+
+               stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
+
+
+               if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
+                       return FE_TER_NOSYMBOL;
+               else { /*
+                       if chip locked on wrong mode first try,
+                       it must lock correctly second try */
+                       mode = stv0367_readbits(state, F367TER_SYR_MODE);
+                       if (stv0367ter_check_cpamp(state, mode) ==
+                                                       FE_TER_NOCPAMP) {
+                               if (try == 0)
+                                       ret_flag = FE_TER_NOCPAMP;
+
+                       }
+               }
+
+               try++;
+       } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
+
+       tmp  = stv0367_readreg(state, R367TER_SYR_STAT);
+       tmp2 = stv0367_readreg(state, R367TER_STATUS);
+       dprintk("state=%p\n", state);
+       dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
+                                                       mode, tmp, tmp2);
+
+       tmp  = stv0367_readreg(state, R367TER_PRVIT);
+       tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
+       dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
+
+       tmp  = stv0367_readreg(state, R367TER_GAIN_SRC1);
+       dprintk("GAIN_SRC1=0x%x\n", tmp);
+
+       if ((mode != 0) && (mode != 1) && (mode != 2))
+               return FE_TER_SWNOK;
+
+       /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
+
+       /*suppress EPQ auto for SYR_GARD 1/16 or 1/32
+       and set channel predictor in automatic */
+#if 0
+       switch (guard) {
+
+       case 0:
+       case 1:
+               stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
+               stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
+               break;
+       case 2:
+       case 3:
+               stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
+               stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
+               break;
+
+       default:
+               return FE_TER_SWNOK;
+       }
+#endif
+
+       /*reset fec an reedsolo FOR 367 only*/
+       stv0367_writebits(state, F367TER_RST_SFEC, 1);
+       stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
+       usleep_range(1000, 2000);
+       stv0367_writebits(state, F367TER_RST_SFEC, 0);
+       stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
+
+       u_var1 = stv0367_readbits(state, F367TER_LK);
+       u_var2 = stv0367_readbits(state, F367TER_PRF);
+       u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
+       /*      u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
+
+       wd = stv0367ter_duration(mode, 125, 500, 250);
+       tempo = stv0367ter_duration(mode, 4, 16, 8);
+
+       /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4))  && (wd>=0)) */
+       while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
+               usleep_range(1000 * tempo, 1000 * (tempo + 1));
+               wd -= tempo;
+               u_var1 = stv0367_readbits(state, F367TER_LK);
+               u_var2 = stv0367_readbits(state, F367TER_PRF);
+               u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
+               /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
+       }
+
+       if (!u_var1)
+               return FE_TER_NOLOCK;
+
+
+       if (!u_var2)
+               return FE_TER_NOPRFOUND;
+
+       if (!u_var3)
+               return FE_TER_NOTPS;
+
+       guard = stv0367_readbits(state, F367TER_SYR_GUARD);
+       stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
+       switch (guard) {
+       case 0:
+       case 1:
+               stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
+               /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
+               stv0367_writebits(state, F367TER_SYR_FILTER, 0);
+               break;
+       case 2:
+       case 3:
+               stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
+               /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
+               stv0367_writebits(state, F367TER_SYR_FILTER, 1);
+               break;
+
+       default:
+               return FE_TER_SWNOK;
+       }
+
+       /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
+       if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
+                       (mode == 1) &&
+                       (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
+               stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
+               stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
+               stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
+       } else
+               stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
+
+       wd = stv0367ter_duration(mode, 125, 500, 250);
+       u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
+
+       while ((!u_var4) && (wd >= 0)) {
+               usleep_range(1000 * tempo, 1000 * (tempo + 1));
+               wd -= tempo;
+               u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
+       }
+
+       if (!u_var4)
+               return FE_TER_NOLOCK;
+
+       /* for 367 leave COM_N at 0x7 for IQ_mode*/
+       /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
+               tempo=0;
+               while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
+               (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
+                       ChipWaitOrAbort(state,1);
+                       tempo+=1;
+               }
+
+               stv0367_writebits(state,F367TER_COM_N,0x17);
+       } */
+
+       stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
+
+       dprintk("FE_TER_LOCKOK !!!\n");
+
+       return  FE_TER_LOCKOK;
+
+}
+
+static void stv0367ter_set_ts_mode(struct stv0367_state *state,
+                                       enum stv0367_ts_mode PathTS)
+{
+
+       dprintk("%s:\n", __func__);
+
+       if (state == NULL)
+               return;
+
+       stv0367_writebits(state, F367TER_TS_DIS, 0);
+       switch (PathTS) {
+       default:
+               /*for removing warning :default we can assume in parallel mode*/
+       case STV0367_PARALLEL_PUNCT_CLOCK:
+               stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
+               stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
+               break;
+       case STV0367_SERIAL_PUNCT_CLOCK:
+               stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
+               stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
+               break;
+       }
+}
+
+static void stv0367ter_set_clk_pol(struct stv0367_state *state,
+                                       enum stv0367_clk_pol clock)
+{
+
+       dprintk("%s:\n", __func__);
+
+       if (state == NULL)
+               return;
+
+       switch (clock) {
+       case STV0367_RISINGEDGE_CLOCK:
+               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
+               break;
+       case STV0367_FALLINGEDGE_CLOCK:
+               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
+               break;
+               /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
+       default:
+               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
+               break;
+       }
+}
+
+#if 0
+static void stv0367ter_core_sw(struct stv0367_state *state)
+{
+
+       dprintk("%s:\n", __func__);
+
+       stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
+       stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
+       msleep(350);
+}
+#endif
+static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       dprintk("%s:\n", __func__);
+
+       if (standby_on) {
+               stv0367_writebits(state, F367TER_STDBY, 1);
+               stv0367_writebits(state, F367TER_STDBY_FEC, 1);
+               stv0367_writebits(state, F367TER_STDBY_CORE, 1);
+       } else {
+               stv0367_writebits(state, F367TER_STDBY, 0);
+               stv0367_writebits(state, F367TER_STDBY_FEC, 0);
+               stv0367_writebits(state, F367TER_STDBY_CORE, 0);
+       }
+
+       return 0;
+}
+
+static int stv0367ter_sleep(struct dvb_frontend *fe)
+{
+       return stv0367ter_standby(fe, 1);
+}
+
+int stv0367ter_init(struct dvb_frontend *fe)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+       int i;
+
+       dprintk("%s:\n", __func__);
+
+       ter_state->pBER = 0;
+
+       for (i = 0; i < STV0367TER_NBREGS; i++)
+               stv0367_writereg(state, def0367ter[i].addr,
+                                       def0367ter[i].value);
+
+       switch (state->config->xtal) {
+               /*set internal freq to 53.125MHz */
+       case 25000000:
+               stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
+               stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
+               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
+               break;
+       default:
+       case 27000000:
+               dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
+               stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
+               stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
+               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
+               break;
+       case 30000000:
+               stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
+               stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
+               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
+               break;
+       }
+
+       stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
+       stv0367_writereg(state, R367TER_ANACTRL, 0x00);
+
+       /*Set TS1 and TS2 to serial or parallel mode */
+       stv0367ter_set_ts_mode(state, state->config->ts_mode);
+       stv0367ter_set_clk_pol(state, state->config->clk_pol);
+
+       state->chip_id = stv0367_readreg(state, R367TER_ID);
+       ter_state->first_lock = 0;
+       ter_state->unlock_counter = 2;
+
+       return 0;
+}
+
+static int stv0367ter_algo(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+       int offset = 0, tempo = 0;
+       u8 u_var;
+       u8 /*constell,*/ counter;
+       s8 step;
+       s32 timing_offset = 0;
+       u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
+
+       dprintk("%s:\n", __func__);
+
+       ter_state->frequency = p->frequency;
+       ter_state->force = FE_TER_FORCENONE
+                       + stv0367_readbits(state, F367TER_FORCE) * 2;
+       ter_state->if_iq_mode = state->config->if_iq_mode;
+       switch (state->config->if_iq_mode) {
+       case FE_TER_NORMAL_IF_TUNER:  /* Normal IF mode */
+               dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
+               stv0367_writebits(state, F367TER_TUNER_BB, 0);
+               stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
+               stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
+               break;
+       case FE_TER_LONGPATH_IF_TUNER:  /* Long IF mode */
+               dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
+               stv0367_writebits(state, F367TER_TUNER_BB, 0);
+               stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
+               stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
+               break;
+       case FE_TER_IQ_TUNER:  /* IQ mode */
+               dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
+               stv0367_writebits(state, F367TER_TUNER_BB, 1);
+               stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
+               break;
+       default:
+               printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
+               return -EINVAL;
+       }
+
+       usleep_range(5000, 7000);
+
+       switch (p->inversion) {
+       case INVERSION_AUTO:
+       default:
+               dprintk("%s: inversion AUTO\n", __func__);
+               if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
+                       stv0367_writebits(state, F367TER_IQ_INVERT,
+                                               ter_state->sense);
+               else
+                       stv0367_writebits(state, F367TER_INV_SPECTR,
+                                               ter_state->sense);
+
+               break;
+       case INVERSION_ON:
+       case INVERSION_OFF:
+               if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
+                       stv0367_writebits(state, F367TER_IQ_INVERT,
+                                               p->inversion);
+               else
+                       stv0367_writebits(state, F367TER_INV_SPECTR,
+                                               p->inversion);
+
+               break;
+       }
+
+       if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
+                               (ter_state->pBW != ter_state->bw)) {
+               stv0367ter_agc_iir_lock_detect_set(state);
+
+               /*set fine agc target to 180 for LPIF or IQ mode*/
+               /* set Q_AGCTarget */
+               stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
+               stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
+               /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
+
+               /* set Q_AGCTarget */
+               stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
+               stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
+               /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
+
+               if (!stv0367_iir_filt_init(state, ter_state->bw,
+                                               state->config->xtal))
+                       return -EINVAL;
+               /*set IIR filter once for 6,7 or 8MHz BW*/
+               ter_state->pBW = ter_state->bw;
+
+               stv0367ter_agc_iir_rst(state);
+       }
+
+       if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
+               stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
+       else
+               stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
+
+       InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
+       temp = (int)
+               ((((ter_state->bw * 64 * (1 << 15) * 100)
+                                               / (InternalFreq)) * 10) / 7);
+
+       stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
+       temp = temp / 2;
+       stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
+       stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
+
+       temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
+                       stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
+                       stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
+       temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
+       stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
+       stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
+       temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
+                       stv0367_readbits(state, F367TER_GAIN_SRC_LO);
+
+       temp = (int)
+               ((InternalFreq - state->config->if_khz) * (1 << 16)
+                                                       / (InternalFreq));
+
+       dprintk("DEROT temp=0x%x\n", temp);
+       stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
+       stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
+
+       ter_state->echo_pos = 0;
+       ter_state->ucblocks = 0; /* liplianin */
+       ter_state->pBER = 0; /* liplianin */
+       stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
+
+       if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
+               return 0;
+
+       ter_state->state = FE_TER_LOCKOK;
+
+       ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
+       ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
+
+       ter_state->first_lock = 1; /* we know sense now :) */
+
+       ter_state->agc_val =
+                       (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
+                       (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
+                       stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
+                       (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
+
+       /* Carrier offset calculation */
+       stv0367_writebits(state, F367TER_FREEZE, 1);
+       offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
+       offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
+       offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
+       stv0367_writebits(state, F367TER_FREEZE, 0);
+       if (offset > 8388607)
+               offset -= 16777216;
+
+       offset = offset * 2 / 16384;
+
+       if (ter_state->mode == FE_TER_MODE_2K)
+               offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
+       else if (ter_state->mode == FE_TER_MODE_4K)
+               offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
+       else  if (ter_state->mode == FE_TER_MODE_8K)
+               offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
+
+       if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
+               if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
+                               (stv0367_readbits(state,
+                                       F367TER_STATUS_INV_SPECRUM) == 1)))
+                       offset = offset * -1;
+       }
+
+       if (ter_state->bw == 6)
+               offset = (offset * 6) / 8;
+       else if (ter_state->bw == 7)
+               offset = (offset * 7) / 8;
+
+       ter_state->frequency += offset;
+
+       tempo = 10;  /* exit even if timing_offset stays null */
+       while ((timing_offset == 0) && (tempo > 0)) {
+               usleep_range(10000, 20000);     /*was 20ms  */
+               /* fine tuning of timing offset if required */
+               timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
+                               + 256 * stv0367_readbits(state,
+                                                       F367TER_TRL_TOFFSET_HI);
+               if (timing_offset >= 32768)
+                       timing_offset -= 65536;
+               trl_nomrate = (512 * stv0367_readbits(state,
+                                                       F367TER_TRL_NOMRATE_HI)
+                       + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
+                       + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
+
+               timing_offset = ((signed)(1000000 / trl_nomrate) *
+                                                       timing_offset) / 2048;
+               tempo--;
+       }
+
+       if (timing_offset <= 0) {
+               timing_offset = (timing_offset - 11) / 22;
+               step = -1;
+       } else {
+               timing_offset = (timing_offset + 11) / 22;
+               step = 1;
+       }
+
+       for (counter = 0; counter < abs(timing_offset); counter++) {
+               trl_nomrate += step;
+               stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
+                                               trl_nomrate % 2);
+               stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
+                                               trl_nomrate / 2);
+               usleep_range(1000, 2000);
+       }
+
+       usleep_range(5000, 6000);
+       /* unlocks could happen in case of trl centring big step,
+       then a core off/on restarts demod */
+       u_var = stv0367_readbits(state, F367TER_LK);
+
+       if (!u_var) {
+               stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
+               msleep(20);
+               stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
+       }
+
+       return 0;
+}
+
+static int stv0367ter_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+
+       /*u8 trials[2]; */
+       s8 num_trials, index;
+       u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
+
+       stv0367ter_init(fe);
+
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       switch (p->transmission_mode) {
+       default:
+       case TRANSMISSION_MODE_AUTO:
+       case TRANSMISSION_MODE_2K:
+               ter_state->mode = FE_TER_MODE_2K;
+               break;
+/*     case TRANSMISSION_MODE_4K:
+               pLook.mode = FE_TER_MODE_4K;
+               break;*/
+       case TRANSMISSION_MODE_8K:
+               ter_state->mode = FE_TER_MODE_8K;
+               break;
+       }
+
+       switch (p->guard_interval) {
+       default:
+       case GUARD_INTERVAL_1_32:
+       case GUARD_INTERVAL_1_16:
+       case GUARD_INTERVAL_1_8:
+       case GUARD_INTERVAL_1_4:
+               ter_state->guard = p->guard_interval;
+               break;
+       case GUARD_INTERVAL_AUTO:
+               ter_state->guard = GUARD_INTERVAL_1_32;
+               break;
+       }
+
+       switch (p->bandwidth_hz) {
+       case 6000000:
+               ter_state->bw = FE_TER_CHAN_BW_6M;
+               break;
+       case 7000000:
+               ter_state->bw = FE_TER_CHAN_BW_7M;
+               break;
+       case 8000000:
+       default:
+               ter_state->bw = FE_TER_CHAN_BW_8M;
+       }
+
+       ter_state->hierarchy = FE_TER_HIER_NONE;
+
+       switch (p->inversion) {
+       case INVERSION_OFF:
+       case INVERSION_ON:
+               num_trials = 1;
+               break;
+       default:
+               num_trials = 2;
+               if (ter_state->first_lock)
+                       num_trials = 1;
+               break;
+       }
+
+       ter_state->state = FE_TER_NOLOCK;
+       index = 0;
+
+       while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
+               if (!ter_state->first_lock) {
+                       if (p->inversion == INVERSION_AUTO)
+                               ter_state->sense = SenseTrials[index];
+
+               }
+               stv0367ter_algo(fe);
+
+               if ((ter_state->state == FE_TER_LOCKOK) &&
+                               (p->inversion == INVERSION_AUTO) &&
+                                                               (index == 1)) {
+                       /* invert spectrum sense */
+                       SenseTrials[index] = SenseTrials[0];
+                       SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
+               }
+
+               index++;
+       }
+
+       return 0;
+}
+
+static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+       u32 errs = 0;
+
+       /*wait for counting completion*/
+       if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
+               errs =
+                       ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
+                       * (1 << 16))
+                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
+                       * (1 << 8))
+                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
+               ter_state->ucblocks = errs;
+       }
+
+       (*ucblocks) = ter_state->ucblocks;
+
+       return 0;
+}
+
+static int stv0367ter_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+
+       int error = 0;
+       enum stv0367_ter_mode mode;
+       int constell = 0,/* snr = 0,*/ Data = 0;
+
+       p->frequency = stv0367_get_tuner_freq(fe);
+       if ((int)p->frequency < 0)
+               p->frequency = -p->frequency;
+
+       constell = stv0367_readbits(state, F367TER_TPS_CONST);
+       if (constell == 0)
+               p->modulation = QPSK;
+       else if (constell == 1)
+               p->modulation = QAM_16;
+       else
+               p->modulation = QAM_64;
+
+       p->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
+
+       /* Get the Hierarchical mode */
+       Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
+
+       switch (Data) {
+       case 0:
+               p->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               p->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               p->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               p->hierarchy = HIERARCHY_4;
+               break;
+       default:
+               p->hierarchy = HIERARCHY_AUTO;
+               break; /* error */
+       }
+
+       /* Get the FEC Rate */
+       if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
+               Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
+       else
+               Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
+
+       switch (Data) {
+       case 0:
+               p->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_HP = FEC_7_8;
+               break;
+       default:
+               p->code_rate_HP = FEC_AUTO;
+               break; /* error */
+       }
+
+       mode = stv0367_readbits(state, F367TER_SYR_MODE);
+
+       switch (mode) {
+       case FE_TER_MODE_2K:
+               p->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+/*     case FE_TER_MODE_4K:
+               p->transmission_mode = TRANSMISSION_MODE_4K;
+               break;*/
+       case FE_TER_MODE_8K:
+               p->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       default:
+               p->transmission_mode = TRANSMISSION_MODE_AUTO;
+       }
+
+       p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
+
+       return error;
+}
+
+static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       u32 snru32 = 0;
+       int cpt = 0;
+       u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
+
+       while (cpt < 10) {
+               usleep_range(2000, 3000);
+               if (cut == 0x50) /*cut 1.0 cut 1.1*/
+                       snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
+               else /*cu2.0*/
+                       snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
+
+               cpt++;
+       }
+
+       snru32 /= 10;/*average on 10 values*/
+
+       *snr = snru32 / 1000;
+
+       return 0;
+}
+
+#if 0
+static int stv0367ter_status(struct dvb_frontend *fe)
+{
+
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+       int locked = FALSE;
+
+       locked = (stv0367_readbits(state, F367TER_LK));
+       if (!locked)
+               ter_state->unlock_counter += 1;
+       else
+               ter_state->unlock_counter = 0;
+
+       if (ter_state->unlock_counter > 2) {
+               if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
+                               (!stv0367_readbits(state, F367TER_LK))) {
+                       stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
+                       usleep_range(2000, 3000);
+                       stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
+                       msleep(350);
+                       locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
+                                       (stv0367_readbits(state, F367TER_LK));
+               }
+
+       }
+
+       return locked;
+}
+#endif
+static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       dprintk("%s:\n", __func__);
+
+       *status = 0;
+
+       if (stv0367_readbits(state, F367TER_LK)) {
+               *status |= FE_HAS_LOCK;
+               dprintk("%s: stv0367 has locked\n", __func__);
+       }
+
+       return 0;
+}
+
+static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367ter_state *ter_state = state->ter_state;
+       u32 Errors = 0, tber = 0, temporary = 0;
+       int abc = 0, def = 0;
+
+
+       /*wait for counting completion*/
+       if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
+               Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
+                       * (1 << 16))
+                       + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
+                       * (1 << 8))
+                       + ((u32)stv0367_readbits(state,
+                                               F367TER_SFEC_ERR_CNT_LO));
+       /*measurement not completed, load previous value*/
+       else {
+               tber = ter_state->pBER;
+               return 0;
+       }
+
+       abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
+       def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
+
+       if (Errors == 0) {
+               tber = 0;
+       } else if (abc == 0x7) {
+               if (Errors <= 4) {
+                       temporary = (Errors * 1000000000) / (8 * (1 << 14));
+                       temporary =  temporary;
+               } else if (Errors <= 42) {
+                       temporary = (Errors * 100000000) / (8 * (1 << 14));
+                       temporary = temporary * 10;
+               } else if (Errors <= 429) {
+                       temporary = (Errors * 10000000) / (8 * (1 << 14));
+                       temporary = temporary * 100;
+               } else if (Errors <= 4294) {
+                       temporary = (Errors * 1000000) / (8 * (1 << 14));
+                       temporary = temporary * 1000;
+               } else if (Errors <= 42949) {
+                       temporary = (Errors * 100000) / (8 * (1 << 14));
+                       temporary = temporary * 10000;
+               } else if (Errors <= 429496) {
+                       temporary = (Errors * 10000) / (8 * (1 << 14));
+                       temporary = temporary * 100000;
+               } else { /*if (Errors<4294967) 2^22 max error*/
+                       temporary = (Errors * 1000) / (8 * (1 << 14));
+                       temporary = temporary * 100000; /* still to *10 */
+               }
+
+               /* Byte error*/
+               if (def == 2)
+                       /*tber=Errors/(8*(1 <<14));*/
+                       tber = temporary;
+               else if (def == 3)
+                       /*tber=Errors/(8*(1 <<16));*/
+                       tber = temporary / 4;
+               else if (def == 4)
+                       /*tber=Errors/(8*(1 <<18));*/
+                       tber = temporary / 16;
+               else if (def == 5)
+                       /*tber=Errors/(8*(1 <<20));*/
+                       tber = temporary / 64;
+               else if (def == 6)
+                       /*tber=Errors/(8*(1 <<22));*/
+                       tber = temporary / 256;
+               else
+                       /* should not pass here*/
+                       tber = 0;
+
+               if ((Errors < 4294967) && (Errors > 429496))
+                       tber *= 10;
+
+       }
+
+       /* save actual value */
+       ter_state->pBER = tber;
+
+       (*ber) = tber;
+
+       return 0;
+}
+#if 0
+static u32 stv0367ter_get_per(struct stv0367_state *state)
+{
+       struct stv0367ter_state *ter_state = state->ter_state;
+       u32 Errors = 0, Per = 0, temporary = 0;
+       int abc = 0, def = 0, cpt = 0;
+
+       while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
+                       (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
+               usleep_range(1000, 2000);
+               Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
+                       * (1 << 16))
+                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
+                       * (1 << 8))
+                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
+               cpt++;
+       }
+       abc = stv0367_readbits(state, F367TER_ERR_SRC1);
+       def = stv0367_readbits(state, F367TER_NUM_EVT1);
+
+       if (Errors == 0)
+               Per = 0;
+       else if (abc == 0x9) {
+               if (Errors <= 4) {
+                       temporary = (Errors * 1000000000) / (8 * (1 << 8));
+                       temporary =  temporary;
+               } else if (Errors <= 42) {
+                       temporary = (Errors * 100000000) / (8 * (1 << 8));
+                       temporary = temporary * 10;
+               } else if (Errors <= 429) {
+                       temporary = (Errors * 10000000) / (8 * (1 << 8));
+                       temporary = temporary * 100;
+               } else if (Errors <= 4294) {
+                       temporary = (Errors * 1000000) / (8 * (1 << 8));
+                       temporary = temporary * 1000;
+               } else if (Errors <= 42949) {
+                       temporary = (Errors * 100000) / (8 * (1 << 8));
+                       temporary = temporary * 10000;
+               } else { /*if(Errors<=429496)  2^16 errors max*/
+                       temporary = (Errors * 10000) / (8 * (1 << 8));
+                       temporary = temporary * 100000;
+               }
+
+               /* pkt error*/
+               if (def == 2)
+                       /*Per=Errors/(1 << 8);*/
+                       Per = temporary;
+               else if (def == 3)
+                       /*Per=Errors/(1 << 10);*/
+                       Per = temporary / 4;
+               else if (def == 4)
+                       /*Per=Errors/(1 << 12);*/
+                       Per = temporary / 16;
+               else if (def == 5)
+                       /*Per=Errors/(1 << 14);*/
+                       Per = temporary / 64;
+               else if (def == 6)
+                       /*Per=Errors/(1 << 16);*/
+                       Per = temporary / 256;
+               else
+                       Per = 0;
+
+       }
+       /* save actual value */
+       ter_state->pPER = Per;
+
+       return Per;
+}
+#endif
+static int stv0367_get_tune_settings(struct dvb_frontend *fe,
+                                       struct dvb_frontend_tune_settings
+                                       *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 1000;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static void stv0367_release(struct dvb_frontend *fe)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       kfree(state->ter_state);
+       kfree(state->cab_state);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops stv0367ter_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "ST STV0367 DVB-T",
+               .frequency_min          = 47000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 15625,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_INVERSION_AUTO |
+                       FE_CAN_MUTE_TS
+       },
+       .release = stv0367_release,
+       .init = stv0367ter_init,
+       .sleep = stv0367ter_sleep,
+       .i2c_gate_ctrl = stv0367ter_gate_ctrl,
+       .set_frontend = stv0367ter_set_frontend,
+       .get_frontend = stv0367ter_get_frontend,
+       .get_tune_settings = stv0367_get_tune_settings,
+       .read_status = stv0367ter_read_status,
+       .read_ber = stv0367ter_read_ber,/* too slow */
+/*     .read_signal_strength = stv0367_read_signal_strength,*/
+       .read_snr = stv0367ter_read_snr,
+       .read_ucblocks = stv0367ter_read_ucblocks,
+};
+
+struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       struct stv0367_state *state = NULL;
+       struct stv0367ter_state *ter_state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+       ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
+       if (ter_state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       state->config = config;
+       state->ter_state = ter_state;
+       state->fe.ops = stv0367ter_ops;
+       state->fe.demodulator_priv = state;
+       state->chip_id = stv0367_readreg(state, 0xf000);
+
+       dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
+
+       /* check if the demod is there */
+       if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
+               goto error;
+
+       return &state->fe;
+
+error:
+       kfree(ter_state);
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(stv0367ter_attach);
+
+static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       dprintk("%s:\n", __func__);
+
+       stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
+
+       return 0;
+}
+
+static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       u32 mclk_Hz = 0;/* master clock frequency (Hz) */
+       u32 M, N, P;
+
+
+       if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
+               N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
+               if (N == 0)
+                       N = N + 1;
+
+               M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
+               if (M == 0)
+                       M = M + 1;
+
+               P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
+
+               if (P > 5)
+                       P = 5;
+
+               mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
+               dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
+                                                               mclk_Hz);
+       } else
+               mclk_Hz = ExtClk_Hz;
+
+       dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
+
+       return mclk_Hz;
+}
+
+static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
+{
+       u32 ADCClk_Hz = ExtClk_Hz;
+
+       ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
+
+       return ADCClk_Hz;
+}
+
+enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
+                                       u32 SymbolRate,
+                                       enum stv0367cab_mod QAMSize)
+{
+       /* Set QAM size */
+       stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
+
+       /* Set Registers settings specific to the QAM size */
+       switch (QAMSize) {
+       case FE_CAB_MOD_QAM4:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               break;
+       case FE_CAB_MOD_QAM16:
+               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
+               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
+               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
+               break;
+       case FE_CAB_MOD_QAM32:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
+               stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
+               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
+               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
+               break;
+       case FE_CAB_MOD_QAM64:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
+               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
+               if (SymbolRate > 45000000) {
+                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
+               } else if (SymbolRate > 25000000) {
+                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
+               } else {
+                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
+               }
+               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
+               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
+               break;
+       case FE_CAB_MOD_QAM128:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
+               stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
+               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
+               if (SymbolRate > 45000000)
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
+               else if (SymbolRate > 25000000)
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
+               else
+                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
+
+               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
+               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
+               break;
+       case FE_CAB_MOD_QAM256:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
+               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
+               stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
+               if (SymbolRate > 45000000)
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+               else if (SymbolRate > 25000000)
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
+               else
+                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
+
+               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
+               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
+               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
+               break;
+       case FE_CAB_MOD_QAM512:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               break;
+       case FE_CAB_MOD_QAM1024:
+               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
+               break;
+       default:
+               break;
+       }
+
+       return QAMSize;
+}
+
+static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
+                                       u32 adc_hz, s32 derot_hz)
+{
+       u32 sampled_if = 0;
+       u32 adc_khz;
+
+       adc_khz = adc_hz / 1000;
+
+       dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
+
+       if (adc_khz != 0) {
+               if (derot_hz < 1000000)
+                       derot_hz = adc_hz / 4; /* ZIF operation */
+               if (derot_hz > adc_hz)
+                       derot_hz = derot_hz - adc_hz;
+               sampled_if = (u32)derot_hz / 1000;
+               sampled_if *= 32768;
+               sampled_if /= adc_khz;
+               sampled_if *= 256;
+       }
+
+       if (sampled_if > 8388607)
+               sampled_if = 8388607;
+
+       dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
+
+       stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
+       stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
+       stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
+
+       return derot_hz;
+}
+
+static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
+{
+       u32 sampled_if;
+
+       sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
+                       (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
+                       (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
+
+       sampled_if /= 256;
+       sampled_if *= (adc_hz / 1000);
+       sampled_if += 1;
+       sampled_if /= 32768;
+
+       return sampled_if;
+}
+
+static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
+                       u32 mclk_hz, u32 SymbolRate,
+                       enum stv0367cab_mod QAMSize)
+{
+       u32 QamSizeCorr = 0;
+       u32 u32_tmp = 0, u32_tmp1 = 0;
+       u32 adp_khz;
+
+       dprintk("%s:\n", __func__);
+
+       /* Set Correction factor of SRC gain */
+       switch (QAMSize) {
+       case FE_CAB_MOD_QAM4:
+               QamSizeCorr = 1110;
+               break;
+       case FE_CAB_MOD_QAM16:
+               QamSizeCorr = 1032;
+               break;
+       case FE_CAB_MOD_QAM32:
+               QamSizeCorr =  954;
+               break;
+       case FE_CAB_MOD_QAM64:
+               QamSizeCorr =  983;
+               break;
+       case FE_CAB_MOD_QAM128:
+               QamSizeCorr =  957;
+               break;
+       case FE_CAB_MOD_QAM256:
+               QamSizeCorr =  948;
+               break;
+       case FE_CAB_MOD_QAM512:
+               QamSizeCorr =    0;
+               break;
+       case FE_CAB_MOD_QAM1024:
+               QamSizeCorr =  944;
+               break;
+       default:
+               break;
+       }
+
+       /* Transfer ratio calculation */
+       if (adc_hz != 0) {
+               u32_tmp = 256 * SymbolRate;
+               u32_tmp = u32_tmp / adc_hz;
+       }
+       stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
+
+       /* Symbol rate and SRC gain calculation */
+       adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
+       if (adp_khz != 0) {
+               u32_tmp = SymbolRate;
+               u32_tmp1 = SymbolRate;
+
+               if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
+                       /* Symbol rate calculation */
+                       u32_tmp *= 2048; /* 2048 = 2^11 */
+                       u32_tmp = u32_tmp / adp_khz;
+                       u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
+                       u32_tmp /= 125 ; /* 125 = 1000/2^3 */
+                       u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
+
+                       /* SRC Gain Calculation */
+                       u32_tmp1 *= 2048; /* *2*2^10 */
+                       u32_tmp1 /= 439; /* *2/878 */
+                       u32_tmp1 *= 256; /* *2^8 */
+                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
+                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
+                       u32_tmp1 = u32_tmp1 / 10000000;
+
+               } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
+                       /* Symbol rate calculation */
+                       u32_tmp *= 1024 ; /* 1024 = 2**10 */
+                       u32_tmp = u32_tmp / adp_khz;
+                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
+                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
+                       u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
+
+                       /* SRC Gain Calculation */
+                       u32_tmp1 *= 1024; /* *2*2^9 */
+                       u32_tmp1 /= 439; /* *2/878 */
+                       u32_tmp1 *= 256; /* *2^8 */
+                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
+                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
+                       u32_tmp1 = u32_tmp1 / 5000000;
+               } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
+                       /* Symbol rate calculation */
+                       u32_tmp *= 512 ; /* 512 = 2**9 */
+                       u32_tmp = u32_tmp / adp_khz;
+                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
+                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
+                       u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
+
+                       /* SRC Gain Calculation */
+                       u32_tmp1 *= 512; /* *2*2^8 */
+                       u32_tmp1 /= 439; /* *2/878 */
+                       u32_tmp1 *= 256; /* *2^8 */
+                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
+                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
+                       u32_tmp1 = u32_tmp1 / 2500000;
+               } else {
+                       /* Symbol rate calculation */
+                       u32_tmp *= 256 ; /* 256 = 2**8 */
+                       u32_tmp = u32_tmp / adp_khz;
+                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
+                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
+                       u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
+
+                       /* SRC Gain Calculation */
+                       u32_tmp1 *= 256; /* 2*2^7 */
+                       u32_tmp1 /= 439; /* *2/878 */
+                       u32_tmp1 *= 256; /* *2^8 */
+                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
+                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
+                       u32_tmp1 = u32_tmp1 / 1250000;
+               }
+       }
+#if 0
+       /* Filters' coefficients are calculated and written
+       into registers only if the filters are enabled */
+       if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
+               stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
+                                                               SymbolRate);
+               /* AllPass filter must be enabled
+               when the adjacents filter is used */
+               stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
+               stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
+       } else
+               /* AllPass filter must be disabled
+               when the adjacents filter is not used */
+#endif
+       stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
+
+       stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
+       stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
+       stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
+       stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
+
+       stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
+       stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
+
+       return SymbolRate ;
+}
+
+static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
+{
+       u32 regsym;
+       u32 adp_khz;
+
+       regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
+               (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
+               (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
+               (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
+
+       adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
+
+       if (regsym < 134217728) {               /* 134217728L = 2**27*/
+               regsym = regsym * 32;           /* 32 = 2**5 */
+               regsym = regsym / 32768;        /* 32768L = 2**15 */
+               regsym = adp_khz * regsym;      /* AdpClk in kHz */
+               regsym = regsym / 128;          /* 128 = 2**7 */
+               regsym *= 125 ;                 /* 125 = 1000/2**3 */
+               regsym /= 2048 ;                /* 2048 = 2**11 */
+       } else if (regsym < 268435456) {        /* 268435456L = 2**28 */
+               regsym = regsym * 16;           /* 16 = 2**4 */
+               regsym = regsym / 32768;        /* 32768L = 2**15 */
+               regsym = adp_khz * regsym;      /* AdpClk in kHz */
+               regsym = regsym / 128;          /* 128 = 2**7 */
+               regsym *= 125 ;                 /* 125 = 1000/2**3*/
+               regsym /= 1024 ;                /* 256 = 2**10*/
+       } else if (regsym < 536870912) {        /* 536870912L = 2**29*/
+               regsym = regsym * 8;            /* 8 = 2**3 */
+               regsym = regsym / 32768;        /* 32768L = 2**15 */
+               regsym = adp_khz * regsym;      /* AdpClk in kHz */
+               regsym = regsym / 128;          /* 128 = 2**7 */
+               regsym *= 125 ;                 /* 125 = 1000/2**3 */
+               regsym /= 512 ;                 /* 128 = 2**9 */
+       } else {
+               regsym = regsym * 4;            /* 4 = 2**2 */
+               regsym = regsym / 32768;        /* 32768L = 2**15 */
+               regsym = adp_khz * regsym;      /* AdpClk in kHz */
+               regsym = regsym / 128;          /* 128 = 2**7 */
+               regsym *= 125 ;                 /* 125 = 1000/2**3 */
+               regsym /= 256 ;                 /* 64 = 2**8 */
+       }
+
+       return regsym;
+}
+
+static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       dprintk("%s:\n", __func__);
+
+       *status = 0;
+
+       if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
+               *status |= FE_HAS_LOCK;
+               dprintk("%s: stv0367 has locked\n", __func__);
+       }
+
+       return 0;
+}
+
+static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       dprintk("%s:\n", __func__);
+
+       if (standby_on) {
+               stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
+               stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
+               stv0367_writebits(state, F367CAB_STDBY, 1);
+               stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
+               stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
+               stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
+               stv0367_writebits(state, F367CAB_POFFQ, 1);
+               stv0367_writebits(state, F367CAB_POFFI, 1);
+       } else {
+               stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
+               stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
+               stv0367_writebits(state, F367CAB_STDBY, 0);
+               stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
+               stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
+               stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
+               stv0367_writebits(state, F367CAB_POFFQ, 0);
+               stv0367_writebits(state, F367CAB_POFFI, 0);
+       }
+
+       return 0;
+}
+
+static int stv0367cab_sleep(struct dvb_frontend *fe)
+{
+       return stv0367cab_standby(fe, 1);
+}
+
+int stv0367cab_init(struct dvb_frontend *fe)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367cab_state *cab_state = state->cab_state;
+       int i;
+
+       dprintk("%s:\n", __func__);
+
+       for (i = 0; i < STV0367CAB_NBREGS; i++)
+               stv0367_writereg(state, def0367cab[i].addr,
+                                               def0367cab[i].value);
+
+       switch (state->config->ts_mode) {
+       case STV0367_DVBCI_CLOCK:
+               dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
+               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
+               break;
+       case STV0367_SERIAL_PUNCT_CLOCK:
+       case STV0367_SERIAL_CONT_CLOCK:
+               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
+               break;
+       case STV0367_PARALLEL_PUNCT_CLOCK:
+       case STV0367_OUTPUTMODE_DEFAULT:
+               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
+               break;
+       }
+
+       switch (state->config->clk_pol) {
+       case STV0367_RISINGEDGE_CLOCK:
+               stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
+               break;
+       case STV0367_FALLINGEDGE_CLOCK:
+       case STV0367_CLOCKPOLARITY_DEFAULT:
+               stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
+               break;
+       }
+
+       stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
+
+       stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
+
+       stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
+
+       stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
+
+       stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
+
+       cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
+       cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
+
+       return 0;
+}
+static
+enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
+                                            struct dtv_frontend_properties *p)
+{
+       struct stv0367cab_state *cab_state = state->cab_state;
+       enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
+       u32     QAMFEC_Lock, QAM_Lock, u32_tmp,
+               LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
+               CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
+       u8      TrackAGCAccum;
+       s32     tmp;
+
+       dprintk("%s:\n", __func__);
+
+       /* Timeouts calculation */
+       /* A max lock time of 25 ms is allowed for delayed AGC */
+       AGCTimeOut = 25;
+       /* 100000 symbols needed by the TRL as a maximum value */
+       TRLTimeOut = 100000000 / p->symbol_rate;
+       /* CRLSymbols is the needed number of symbols to achieve a lock
+          within [-4%, +4%] of the symbol rate.
+          CRL timeout is calculated
+          for a lock within [-search_range, +search_range].
+          EQL timeout can be changed depending on
+          the micro-reflections we want to handle.
+          A characterization must be performed
+          with these echoes to get new timeout values.
+       */
+       switch (p->modulation) {
+       case QAM_16:
+               CRLSymbols = 150000;
+               EQLTimeOut = 100;
+               break;
+       case QAM_32:
+               CRLSymbols = 250000;
+               EQLTimeOut = 100;
+               break;
+       case QAM_64:
+               CRLSymbols = 200000;
+               EQLTimeOut = 100;
+               break;
+       case QAM_128:
+               CRLSymbols = 250000;
+               EQLTimeOut = 100;
+               break;
+       case QAM_256:
+               CRLSymbols = 250000;
+               EQLTimeOut = 100;
+               break;
+       default:
+               CRLSymbols = 200000;
+               EQLTimeOut = 100;
+               break;
+       }
+#if 0
+       if (pIntParams->search_range < 0) {
+               CRLTimeOut = (25 * CRLSymbols *
+                               (-pIntParams->search_range / 1000)) /
+                                       (pIntParams->symbol_rate / 1000);
+       } else
+#endif
+       CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
+                                       (p->symbol_rate / 1000);
+
+       CRLTimeOut = (1000 * CRLTimeOut) / p->symbol_rate;
+       /* Timeouts below 50ms are coerced */
+       if (CRLTimeOut < 50)
+               CRLTimeOut = 50;
+       /* A maximum of 100 TS packets is needed to get FEC lock even in case
+       the spectrum inversion needs to be changed.
+          This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
+       */
+       FECTimeOut = 20;
+       DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
+
+       dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
+
+       /* Reset the TRL to ensure nothing starts until the
+          AGC is stable which ensures a better lock time
+       */
+       stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
+       /* Set AGC accumulation time to minimum and lock threshold to maximum
+       in order to speed up the AGC lock */
+       TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
+       stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
+       /* Modulus Mapper is disabled */
+       stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
+       /* Disable the sweep function */
+       stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
+       /* The sweep function is never used, Sweep rate must be set to 0 */
+       /* Set the derotator frequency in Hz */
+       stv0367cab_set_derot_freq(state, cab_state->adc_clk,
+               (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
+       /* Disable the Allpass Filter when the symbol rate is out of range */
+       if ((p->symbol_rate > 10800000) | (p->symbol_rate < 1800000)) {
+               stv0367_writebits(state, F367CAB_ADJ_EN, 0);
+               stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
+       }
+#if 0
+       /* Check if the tuner is locked */
+       tuner_lock = stv0367cab_tuner_get_status(fe);
+       if (tuner_lock == 0)
+               return FE_367CAB_NOTUNER;
+#endif
+       /* Relase the TRL to start demodulator acquisition */
+       /* Wait for QAM lock */
+       LockTime = 0;
+       stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
+       do {
+               QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
+               if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
+                                                       (QAM_Lock == 0x04))
+                       /*
+                        * We don't wait longer, the frequency/phase offset
+                        * must be too big
+                        */
+                       LockTime = DemodTimeOut;
+               else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
+                                                       (QAM_Lock == 0x02))
+                       /*
+                        * We don't wait longer, either there is no signal or
+                        * it is not the right symbol rate or it is an analog
+                        * carrier
+                        */
+               {
+                       LockTime = DemodTimeOut;
+                       u32_tmp = stv0367_readbits(state,
+                                               F367CAB_AGC_PWR_WORD_LO) +
+                                       (stv0367_readbits(state,
+                                               F367CAB_AGC_PWR_WORD_ME) << 8) +
+                                       (stv0367_readbits(state,
+                                               F367CAB_AGC_PWR_WORD_HI) << 16);
+                       if (u32_tmp >= 131072)
+                               u32_tmp = 262144 - u32_tmp;
+                       u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
+                                                       F367CAB_AGC_IF_BWSEL)));
+
+                       if (u32_tmp < stv0367_readbits(state,
+                                               F367CAB_AGC_PWRREF_LO) +
+                                       256 * stv0367_readbits(state,
+                                               F367CAB_AGC_PWRREF_HI) - 10)
+                               QAM_Lock = 0x0f;
+               } else {
+                       usleep_range(10000, 20000);
+                       LockTime += 10;
+               }
+               dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
+               tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
+
+               dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
+
+       } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
+                                               (LockTime < DemodTimeOut));
+
+       dprintk("QAM_Lock=0x%x\n", QAM_Lock);
+
+       tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
+       dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
+       tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
+       dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
+
+       tmp  = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
+       dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
+
+       if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
+               /* Wait for FEC lock */
+               LockTime = 0;
+               do {
+                       usleep_range(5000, 7000);
+                       LockTime += 5;
+                       QAMFEC_Lock = stv0367_readbits(state,
+                                                       F367CAB_QAMFEC_LOCK);
+               } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
+       } else
+               QAMFEC_Lock = 0;
+
+       if (QAMFEC_Lock) {
+               signalType = FE_CAB_DATAOK;
+               cab_state->modulation = p->modulation;
+               cab_state->spect_inv = stv0367_readbits(state,
+                                                       F367CAB_QUAD_INV);
+#if 0
+/* not clear for me */
+               if (state->config->if_khz != 0) {
+                       if (state->config->if_khz > cab_state->adc_clk / 1000) {
+                               cab_state->freq_khz =
+                                       FE_Cab_TunerGetFrequency(pIntParams->hTuner)
+                               - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
+                               - cab_state->adc_clk / 1000 + state->config->if_khz;
+                       } else {
+                               cab_state->freq_khz =
+                                               FE_Cab_TunerGetFrequency(pIntParams->hTuner)
+                                               - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
+                                                                               + state->config->if_khz;
+                       }
+               } else {
+                       cab_state->freq_khz =
+                               FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
+                               stv0367cab_get_derot_freq(state,
+                                                       cab_state->adc_clk) -
+                               cab_state->adc_clk / 4000;
+               }
+#endif
+               cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
+                                                       cab_state->mclk);
+               cab_state->locked = 1;
+
+               /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
+       } else {
+               switch (QAM_Lock) {
+               case 1:
+                       signalType = FE_CAB_NOAGC;
+                       break;
+               case 2:
+                       signalType = FE_CAB_NOTIMING;
+                       break;
+               case 3:
+                       signalType = FE_CAB_TIMINGOK;
+                       break;
+               case 4:
+                       signalType = FE_CAB_NOCARRIER;
+                       break;
+               case 5:
+                       signalType = FE_CAB_CARRIEROK;
+                       break;
+               case 7:
+                       signalType = FE_CAB_NOBLIND;
+                       break;
+               case 8:
+                       signalType = FE_CAB_BLINDOK;
+                       break;
+               case 10:
+                       signalType = FE_CAB_NODEMOD;
+                       break;
+               case 11:
+                       signalType = FE_CAB_DEMODOK;
+                       break;
+               case 12:
+                       signalType = FE_CAB_DEMODOK;
+                       break;
+               case 13:
+                       signalType = FE_CAB_NODEMOD;
+                       break;
+               case 14:
+                       signalType = FE_CAB_NOBLIND;
+                       break;
+               case 15:
+                       signalType = FE_CAB_NOSIGNAL;
+                       break;
+               default:
+                       break;
+               }
+
+       }
+
+       /* Set the AGC control values to tracking values */
+       stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
+       return signalType;
+}
+
+static int stv0367cab_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367cab_state *cab_state = state->cab_state;
+       enum stv0367cab_mod QAMSize = 0;
+
+       dprintk("%s: freq = %d, srate = %d\n", __func__,
+                                       p->frequency, p->symbol_rate);
+
+       cab_state->derot_offset = 0;
+
+       switch (p->modulation) {
+       case QAM_16:
+               QAMSize = FE_CAB_MOD_QAM16;
+               break;
+       case QAM_32:
+               QAMSize = FE_CAB_MOD_QAM32;
+               break;
+       case QAM_64:
+               QAMSize = FE_CAB_MOD_QAM64;
+               break;
+       case QAM_128:
+               QAMSize = FE_CAB_MOD_QAM128;
+               break;
+       case QAM_256:
+               QAMSize = FE_CAB_MOD_QAM256;
+               break;
+       default:
+               break;
+       }
+
+       stv0367cab_init(fe);
+
+       /* Tuner Frequency Setting */
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       stv0367cab_SetQamSize(
+                       state,
+                       p->symbol_rate,
+                       QAMSize);
+
+       stv0367cab_set_srate(state,
+                       cab_state->adc_clk,
+                       cab_state->mclk,
+                       p->symbol_rate,
+                       QAMSize);
+       /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
+       cab_state->state = stv0367cab_algo(state, p);
+       return 0;
+}
+
+static int stv0367cab_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0367_state *state = fe->demodulator_priv;
+       struct stv0367cab_state *cab_state = state->cab_state;
+
+       enum stv0367cab_mod QAMSize;
+
+       dprintk("%s:\n", __func__);
+
+       p->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
+
+       QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
+       switch (QAMSize) {
+       case FE_CAB_MOD_QAM16:
+               p->modulation = QAM_16;
+               break;
+       case FE_CAB_MOD_QAM32:
+               p->modulation = QAM_32;
+               break;
+       case FE_CAB_MOD_QAM64:
+               p->modulation = QAM_64;
+               break;
+       case FE_CAB_MOD_QAM128:
+               p->modulation = QAM_128;
+               break;
+       case QAM_256:
+               p->modulation = QAM_256;
+               break;
+       default:
+               break;
+       }
+
+       p->frequency = stv0367_get_tuner_freq(fe);
+
+       dprintk("%s: tuner frequency = %d\n", __func__, p->frequency);
+
+       if (state->config->if_khz == 0) {
+               p->frequency +=
+                       (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
+                       cab_state->adc_clk / 4000);
+               return 0;
+       }
+
+       if (state->config->if_khz > cab_state->adc_clk / 1000)
+               p->frequency += (state->config->if_khz
+                       - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
+                       - cab_state->adc_clk / 1000);
+       else
+               p->frequency += (state->config->if_khz
+                       - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
+
+       return 0;
+}
+
+#if 0
+void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
+                       u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
+{
+       stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
+       stv0367cab_GetPacketsCount(state, Monitor_results);
+
+       return;
+}
+
+static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       return 0;
+}
+#endif
+static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
+{
+       s32 rfLevel = 0;
+       s32 RfAgcPwm = 0, IfAgcPwm = 0;
+       u8 i;
+
+       stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
+
+       RfAgcPwm =
+               (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
+               (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
+       RfAgcPwm = 100 * RfAgcPwm / 1023;
+
+       IfAgcPwm =
+               stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
+               (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
+       if (IfAgcPwm >= 2048)
+               IfAgcPwm -= 2048;
+       else
+               IfAgcPwm += 2048;
+
+       IfAgcPwm = 100 * IfAgcPwm / 4095;
+
+       /* For DTT75467 on NIM */
+       if (RfAgcPwm < 90  && IfAgcPwm < 28) {
+               for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
+                       if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
+                               rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
+                               break;
+                       }
+               }
+               if (i == RF_LOOKUP_TABLE_SIZE)
+                       rfLevel = -56;
+       } else { /*if IF AGC>10*/
+               for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
+                       if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
+                               rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
+                               break;
+                       }
+               }
+               if (i == RF_LOOKUP_TABLE2_SIZE)
+                       rfLevel = -72;
+       }
+       return rfLevel;
+}
+
+static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+
+       s32 signal =  stv0367cab_get_rf_lvl(state);
+
+       dprintk("%s: signal=%d dBm\n", __func__, signal);
+
+       if (signal <= -72)
+               *strength = 65535;
+       else
+               *strength = (22 + signal) * (-1311);
+
+       dprintk("%s: strength=%d\n", __func__, (*strength));
+
+       return 0;
+}
+
+static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       u32 noisepercentage;
+       enum stv0367cab_mod QAMSize;
+       u32 regval = 0, temp = 0;
+       int power, i;
+
+       QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
+       switch (QAMSize) {
+       case FE_CAB_MOD_QAM4:
+               power = 21904;
+               break;
+       case FE_CAB_MOD_QAM16:
+               power = 20480;
+               break;
+       case FE_CAB_MOD_QAM32:
+               power = 23040;
+               break;
+       case FE_CAB_MOD_QAM64:
+               power = 21504;
+               break;
+       case FE_CAB_MOD_QAM128:
+               power = 23616;
+               break;
+       case FE_CAB_MOD_QAM256:
+               power = 21760;
+               break;
+       case FE_CAB_MOD_QAM512:
+               power = 1;
+               break;
+       case FE_CAB_MOD_QAM1024:
+               power = 21280;
+               break;
+       default:
+               power = 1;
+               break;
+       }
+
+       for (i = 0; i < 10; i++) {
+               regval += (stv0367_readbits(state, F367CAB_SNR_LO)
+                       + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
+       }
+
+       regval /= 10; /*for average over 10 times in for loop above*/
+       if (regval != 0) {
+               temp = power
+                       * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
+               temp /= regval;
+       }
+
+       /* table values, not needed to calculate logarithms */
+       if (temp >= 5012)
+               noisepercentage = 100;
+       else if (temp >= 3981)
+               noisepercentage = 93;
+       else if (temp >= 3162)
+               noisepercentage = 86;
+       else if (temp >= 2512)
+               noisepercentage = 79;
+       else if (temp >= 1995)
+               noisepercentage = 72;
+       else if (temp >= 1585)
+               noisepercentage = 65;
+       else if (temp >= 1259)
+               noisepercentage = 58;
+       else if (temp >= 1000)
+               noisepercentage = 50;
+       else if (temp >= 794)
+               noisepercentage = 43;
+       else if (temp >= 501)
+               noisepercentage = 36;
+       else if (temp >= 316)
+               noisepercentage = 29;
+       else if (temp >= 200)
+               noisepercentage = 22;
+       else if (temp >= 158)
+               noisepercentage = 14;
+       else if (temp >= 126)
+               noisepercentage = 7;
+       else
+               noisepercentage = 0;
+
+       dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
+
+       *snr = (noisepercentage * 65535) / 100;
+
+       return 0;
+}
+
+static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct stv0367_state *state = fe->demodulator_priv;
+       int corrected, tscount;
+
+       *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
+                       | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
+       corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
+                       | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
+       tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
+                       | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
+
+       dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
+                               __func__, *ucblocks, corrected, tscount);
+
+       return 0;
+};
+
+static struct dvb_frontend_ops stv0367cab_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A },
+       .info = {
+               .name = "ST STV0367 DVB-C",
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
+               .frequency_stepsize = 62500,
+               .symbol_rate_min = 870000,
+               .symbol_rate_max = 11700000,
+               .caps = 0x400 |/* FE_CAN_QAM_4 */
+                       FE_CAN_QAM_16 | FE_CAN_QAM_32  |
+                       FE_CAN_QAM_64 | FE_CAN_QAM_128 |
+                       FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
+       },
+       .release                                = stv0367_release,
+       .init                                   = stv0367cab_init,
+       .sleep                                  = stv0367cab_sleep,
+       .i2c_gate_ctrl                          = stv0367cab_gate_ctrl,
+       .set_frontend                           = stv0367cab_set_frontend,
+       .get_frontend                           = stv0367cab_get_frontend,
+       .read_status                            = stv0367cab_read_status,
+/*     .read_ber                               = stv0367cab_read_ber, */
+       .read_signal_strength                   = stv0367cab_read_strength,
+       .read_snr                               = stv0367cab_read_snr,
+       .read_ucblocks                          = stv0367cab_read_ucblcks,
+       .get_tune_settings                      = stv0367_get_tune_settings,
+};
+
+struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       struct stv0367_state *state = NULL;
+       struct stv0367cab_state *cab_state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+       cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
+       if (cab_state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       state->config = config;
+       cab_state->search_range = 280000;
+       state->cab_state = cab_state;
+       state->fe.ops = stv0367cab_ops;
+       state->fe.demodulator_priv = state;
+       state->chip_id = stv0367_readreg(state, 0xf000);
+
+       dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
+
+       /* check if the demod is there */
+       if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
+               goto error;
+
+       return &state->fe;
+
+error:
+       kfree(cab_state);
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(stv0367cab_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stv0367.h b/drivers/media/dvb-frontends/stv0367.h
new file mode 100644 (file)
index 0000000..93cc4a5
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * stv0367.h
+ *
+ * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2010,2011 NetUP Inc.
+ * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0367_H
+#define STV0367_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0367_config {
+       u8 demod_address;
+       u32 xtal;
+       u32 if_khz;/*4500*/
+       int if_iq_mode;
+       int ts_mode;
+       int clk_pol;
+};
+
+#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
+                                                       && defined(MODULE))
+extern struct
+dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
+                                       struct i2c_adapter *i2c);
+extern struct
+dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
+                                       struct i2c_adapter *i2c);
+#else
+static inline struct
+dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline struct
+dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv0367_priv.h b/drivers/media/dvb-frontends/stv0367_priv.h
new file mode 100644 (file)
index 0000000..995db06
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * stv0367_priv.h
+ *
+ * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2010,2011 NetUP Inc.
+ * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* Common driver error constants */
+
+#ifndef STV0367_PRIV_H
+#define STV0367_PRIV_H
+
+#ifndef TRUE
+    #define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+    #define FALSE (!TRUE)
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* MACRO definitions */
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
+#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
+#define INRANGE(X, Y, Z) \
+       ((((X) <= (Y)) && ((Y) <= (Z))) || \
+       (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xff))
+#define MSB(Y) (((Y) >> 8) & 0xff)
+#define MMSB(Y)(((Y) >> 16) & 0xff)
+
+enum stv0367_ter_signal_type {
+       FE_TER_NOAGC = 0,
+       FE_TER_AGCOK = 5,
+       FE_TER_NOTPS = 6,
+       FE_TER_TPSOK = 7,
+       FE_TER_NOSYMBOL = 8,
+       FE_TER_BAD_CPQ = 9,
+       FE_TER_PRFOUNDOK = 10,
+       FE_TER_NOPRFOUND = 11,
+       FE_TER_LOCKOK = 12,
+       FE_TER_NOLOCK = 13,
+       FE_TER_SYMBOLOK = 15,
+       FE_TER_CPAMPOK = 16,
+       FE_TER_NOCPAMP = 17,
+       FE_TER_SWNOK = 18
+};
+
+enum stv0367_ts_mode {
+       STV0367_OUTPUTMODE_DEFAULT,
+       STV0367_SERIAL_PUNCT_CLOCK,
+       STV0367_SERIAL_CONT_CLOCK,
+       STV0367_PARALLEL_PUNCT_CLOCK,
+       STV0367_DVBCI_CLOCK
+};
+
+enum stv0367_clk_pol {
+       STV0367_CLOCKPOLARITY_DEFAULT,
+       STV0367_RISINGEDGE_CLOCK,
+       STV0367_FALLINGEDGE_CLOCK
+};
+
+enum stv0367_ter_bw {
+       FE_TER_CHAN_BW_6M = 6,
+       FE_TER_CHAN_BW_7M = 7,
+       FE_TER_CHAN_BW_8M = 8
+};
+
+#if 0
+enum FE_TER_Rate_TPS {
+       FE_TER_TPS_1_2 = 0,
+       FE_TER_TPS_2_3 = 1,
+       FE_TER_TPS_3_4 = 2,
+       FE_TER_TPS_5_6 = 3,
+       FE_TER_TPS_7_8 = 4
+};
+#endif
+
+enum stv0367_ter_mode {
+       FE_TER_MODE_2K,
+       FE_TER_MODE_8K,
+       FE_TER_MODE_4K
+};
+#if 0
+enum FE_TER_Hierarchy_Alpha {
+       FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
+       FE_TER_HIER_ALPHA_1,    /* Hierarchical modulation a = 1*/
+       FE_TER_HIER_ALPHA_2,    /* Hierarchical modulation a = 2*/
+       FE_TER_HIER_ALPHA_4     /* Hierarchical modulation a = 4*/
+};
+#endif
+enum stv0367_ter_hierarchy {
+       FE_TER_HIER_NONE,       /*Hierarchy None*/
+       FE_TER_HIER_LOW_PRIO,   /*Hierarchy : Low Priority*/
+       FE_TER_HIER_HIGH_PRIO,  /*Hierarchy : High Priority*/
+       FE_TER_HIER_PRIO_ANY    /*Hierarchy  :Any*/
+};
+
+#if 0
+enum fe_stv0367_ter_spec {
+       FE_TER_INVERSION_NONE = 0,
+       FE_TER_INVERSION = 1,
+       FE_TER_INVERSION_AUTO = 2,
+       FE_TER_INVERSION_UNK  = 4
+};
+#endif
+
+enum stv0367_ter_if_iq_mode {
+       FE_TER_NORMAL_IF_TUNER = 0,
+       FE_TER_LONGPATH_IF_TUNER = 1,
+       FE_TER_IQ_TUNER = 2
+
+};
+
+#if 0
+enum FE_TER_FECRate {
+       FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
+       FE_TER_FEC_ALL = 0xFF,   /* Logical OR of all FECs */
+       FE_TER_FEC_1_2 = 1,
+       FE_TER_FEC_2_3 = (1 << 1),
+       FE_TER_FEC_3_4 = (1 << 2),
+       FE_TER_FEC_4_5 = (1 << 3),
+       FE_TER_FEC_5_6 = (1 << 4),
+       FE_TER_FEC_6_7 = (1 << 5),
+       FE_TER_FEC_7_8 = (1 << 6),
+       FE_TER_FEC_8_9 = (1 << 7)
+};
+
+enum FE_TER_Rate {
+       FE_TER_FE_1_2 = 0,
+       FE_TER_FE_2_3 = 1,
+       FE_TER_FE_3_4 = 2,
+       FE_TER_FE_5_6 = 3,
+       FE_TER_FE_6_7 = 4,
+       FE_TER_FE_7_8 = 5
+};
+#endif
+
+enum stv0367_ter_force {
+       FE_TER_FORCENONE = 0,
+       FE_TER_FORCE_M_G = 1
+};
+
+enum  stv0367cab_mod {
+       FE_CAB_MOD_QAM4,
+       FE_CAB_MOD_QAM16,
+       FE_CAB_MOD_QAM32,
+       FE_CAB_MOD_QAM64,
+       FE_CAB_MOD_QAM128,
+       FE_CAB_MOD_QAM256,
+       FE_CAB_MOD_QAM512,
+       FE_CAB_MOD_QAM1024
+};
+#if 0
+enum {
+       FE_CAB_FEC_A = 1,       /* J83 Annex A */
+       FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
+       FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
+} FE_CAB_FECType_t;
+#endif
+struct stv0367_cab_signal_info {
+       int locked;
+       u32 frequency; /* kHz */
+       u32 symbol_rate; /* Mbds */
+       enum stv0367cab_mod modulation;
+       fe_spectral_inversion_t spect_inv;
+       s32 Power_dBmx10;       /* Power of the RF signal (dBm x 10) */
+       u32     CN_dBx10;       /* Carrier to noise ratio (dB x 10) */
+       u32     BER;            /* Bit error rate (x 10000000)  */
+};
+
+enum stv0367_cab_signal_type {
+       FE_CAB_NOTUNER,
+       FE_CAB_NOAGC,
+       FE_CAB_NOSIGNAL,
+       FE_CAB_NOTIMING,
+       FE_CAB_TIMINGOK,
+       FE_CAB_NOCARRIER,
+       FE_CAB_CARRIEROK,
+       FE_CAB_NOBLIND,
+       FE_CAB_BLINDOK,
+       FE_CAB_NODEMOD,
+       FE_CAB_DEMODOK,
+       FE_CAB_DATAOK
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv0367_regs.h b/drivers/media/dvb-frontends/stv0367_regs.h
new file mode 100644 (file)
index 0000000..a96fbdc
--- /dev/null
@@ -0,0 +1,3614 @@
+/*
+ * stv0367_regs.h
+ *
+ * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2010,2011 NetUP Inc.
+ * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0367_REGS_H
+#define STV0367_REGS_H
+
+/* ID */
+#define        R367TER_ID      0xf000
+#define        F367TER_IDENTIFICATIONREG       0xf00000ff
+
+/* I2CRPT */
+#define        R367TER_I2CRPT  0xf001
+#define        F367TER_I2CT_ON 0xf0010080
+#define        F367TER_ENARPT_LEVEL    0xf0010070
+#define        F367TER_SCLT_DELAY      0xf0010008
+#define        F367TER_SCLT_NOD        0xf0010004
+#define        F367TER_STOP_ENABLE     0xf0010002
+#define        F367TER_SDAT_NOD        0xf0010001
+
+/* TOPCTRL */
+#define        R367TER_TOPCTRL 0xf002
+#define        F367TER_STDBY   0xf0020080
+#define        F367TER_STDBY_FEC       0xf0020040
+#define        F367TER_STDBY_CORE      0xf0020020
+#define        F367TER_QAM_COFDM       0xf0020010
+#define        F367TER_TS_DIS  0xf0020008
+#define        F367TER_DIR_CLK_216     0xf0020004
+#define        F367TER_TUNER_BB        0xf0020002
+#define        F367TER_DVBT_H  0xf0020001
+
+/* IOCFG0 */
+#define        R367TER_IOCFG0  0xf003
+#define        F367TER_OP0_SD  0xf0030080
+#define        F367TER_OP0_VAL 0xf0030040
+#define        F367TER_OP0_OD  0xf0030020
+#define        F367TER_OP0_INV 0xf0030010
+#define        F367TER_OP0_DACVALUE_HI 0xf003000f
+
+/* DAc0R */
+#define        R367TER_DAC0R   0xf004
+#define        F367TER_OP0_DACVALUE_LO 0xf00400ff
+
+/* IOCFG1 */
+#define        R367TER_IOCFG1  0xf005
+#define        F367TER_IP0     0xf0050040
+#define        F367TER_OP1_OD  0xf0050020
+#define        F367TER_OP1_INV 0xf0050010
+#define        F367TER_OP1_DACVALUE_HI 0xf005000f
+
+/* DAC1R */
+#define        R367TER_DAC1R   0xf006
+#define        F367TER_OP1_DACVALUE_LO 0xf00600ff
+
+/* IOCFG2 */
+#define        R367TER_IOCFG2  0xf007
+#define        F367TER_OP2_LOCK_CONF   0xf00700e0
+#define        F367TER_OP2_OD  0xf0070010
+#define        F367TER_OP2_VAL 0xf0070008
+#define        F367TER_OP1_LOCK_CONF   0xf0070007
+
+/* SDFR */
+#define        R367TER_SDFR    0xf008
+#define        F367TER_OP0_FREQ        0xf00800f0
+#define        F367TER_OP1_FREQ        0xf008000f
+
+/* STATUS */
+#define        R367TER_STATUS  0xf009
+#define        F367TER_TPS_LOCK        0xf0090080
+#define        F367TER_SYR_LOCK        0xf0090040
+#define        F367TER_AGC_LOCK        0xf0090020
+#define        F367TER_PRF     0xf0090010
+#define        F367TER_LK      0xf0090008
+#define        F367TER_PR      0xf0090007
+
+/* AUX_CLK */
+#define        R367TER_AUX_CLK 0xf00a
+#define        F367TER_AUXFEC_CTL      0xf00a00c0
+#define        F367TER_DIS_CKX4        0xf00a0020
+#define        F367TER_CKSEL   0xf00a0018
+#define        F367TER_CKDIV_PROG      0xf00a0006
+#define        F367TER_AUXCLK_ENA      0xf00a0001
+
+/* FREESYS1 */
+#define        R367TER_FREESYS1        0xf00b
+#define        F367TER_FREE_SYS1       0xf00b00ff
+
+/* FREESYS2 */
+#define        R367TER_FREESYS2        0xf00c
+#define        F367TER_FREE_SYS2       0xf00c00ff
+
+/* FREESYS3 */
+#define        R367TER_FREESYS3        0xf00d
+#define        F367TER_FREE_SYS3       0xf00d00ff
+
+/* GPIO_CFG */
+#define        R367TER_GPIO_CFG        0xf00e
+#define        F367TER_GPIO7_NOD       0xf00e0080
+#define        F367TER_GPIO7_CFG       0xf00e0040
+#define        F367TER_GPIO6_NOD       0xf00e0020
+#define        F367TER_GPIO6_CFG       0xf00e0010
+#define        F367TER_GPIO5_NOD       0xf00e0008
+#define        F367TER_GPIO5_CFG       0xf00e0004
+#define        F367TER_GPIO4_NOD       0xf00e0002
+#define        F367TER_GPIO4_CFG       0xf00e0001
+
+/* GPIO_CMD */
+#define        R367TER_GPIO_CMD        0xf00f
+#define        F367TER_GPIO7_VAL       0xf00f0008
+#define        F367TER_GPIO6_VAL       0xf00f0004
+#define        F367TER_GPIO5_VAL       0xf00f0002
+#define        F367TER_GPIO4_VAL       0xf00f0001
+
+/* AGC2MAX */
+#define        R367TER_AGC2MAX 0xf010
+#define        F367TER_AGC2_MAX        0xf01000ff
+
+/* AGC2MIN */
+#define        R367TER_AGC2MIN 0xf011
+#define        F367TER_AGC2_MIN        0xf01100ff
+
+/* AGC1MAX */
+#define        R367TER_AGC1MAX 0xf012
+#define        F367TER_AGC1_MAX        0xf01200ff
+
+/* AGC1MIN */
+#define        R367TER_AGC1MIN 0xf013
+#define        F367TER_AGC1_MIN        0xf01300ff
+
+/* AGCR */
+#define        R367TER_AGCR    0xf014
+#define        F367TER_RATIO_A 0xf01400e0
+#define        F367TER_RATIO_B 0xf0140018
+#define        F367TER_RATIO_C 0xf0140007
+
+/* AGC2TH */
+#define        R367TER_AGC2TH  0xf015
+#define        F367TER_AGC2_THRES      0xf01500ff
+
+/* AGC12c */
+#define        R367TER_AGC12C  0xf016
+#define        F367TER_AGC1_IV 0xf0160080
+#define        F367TER_AGC1_OD 0xf0160040
+#define        F367TER_AGC1_LOAD       0xf0160020
+#define        F367TER_AGC2_IV 0xf0160010
+#define        F367TER_AGC2_OD 0xf0160008
+#define        F367TER_AGC2_LOAD       0xf0160004
+#define        F367TER_AGC12_MODE      0xf0160003
+
+/* AGCCTRL1 */
+#define        R367TER_AGCCTRL1        0xf017
+#define        F367TER_DAGC_ON 0xf0170080
+#define        F367TER_INVERT_AGC12    0xf0170040
+#define        F367TER_AGC1_MODE       0xf0170008
+#define        F367TER_AGC2_MODE       0xf0170007
+
+/* AGCCTRL2 */
+#define        R367TER_AGCCTRL2        0xf018
+#define        F367TER_FRZ2_CTRL       0xf0180060
+#define        F367TER_FRZ1_CTRL       0xf0180018
+#define        F367TER_TIME_CST        0xf0180007
+
+/* AGC1VAL1 */
+#define        R367TER_AGC1VAL1        0xf019
+#define        F367TER_AGC1_VAL_LO     0xf01900ff
+
+/* AGC1VAL2 */
+#define        R367TER_AGC1VAL2        0xf01a
+#define        F367TER_AGC1_VAL_HI     0xf01a000f
+
+/* AGC2VAL1 */
+#define        R367TER_AGC2VAL1        0xf01b
+#define        F367TER_AGC2_VAL_LO     0xf01b00ff
+
+/* AGC2VAL2 */
+#define        R367TER_AGC2VAL2        0xf01c
+#define        F367TER_AGC2_VAL_HI     0xf01c000f
+
+/* AGC2PGA */
+#define        R367TER_AGC2PGA 0xf01d
+#define        F367TER_AGC2_PGA        0xf01d00ff
+
+/* OVF_RATE1 */
+#define        R367TER_OVF_RATE1       0xf01e
+#define        F367TER_OVF_RATE_HI     0xf01e000f
+
+/* OVF_RATE2 */
+#define        R367TER_OVF_RATE2       0xf01f
+#define        F367TER_OVF_RATE_LO     0xf01f00ff
+
+/* GAIN_SRC1 */
+#define        R367TER_GAIN_SRC1       0xf020
+#define        F367TER_INV_SPECTR      0xf0200080
+#define        F367TER_IQ_INVERT       0xf0200040
+#define        F367TER_INR_BYPASS      0xf0200020
+#define        F367TER_STATUS_INV_SPECRUM      0xf0200010
+#define        F367TER_GAIN_SRC_HI     0xf020000f
+
+/* GAIN_SRC2 */
+#define        R367TER_GAIN_SRC2       0xf021
+#define        F367TER_GAIN_SRC_LO     0xf02100ff
+
+/* INC_DEROT1 */
+#define        R367TER_INC_DEROT1      0xf022
+#define        F367TER_INC_DEROT_HI    0xf02200ff
+
+/* INC_DEROT2 */
+#define        R367TER_INC_DEROT2      0xf023
+#define        F367TER_INC_DEROT_LO    0xf02300ff
+
+/* PPM_CPAMP_DIR */
+#define        R367TER_PPM_CPAMP_DIR   0xf024
+#define        F367TER_PPM_CPAMP_DIRECT        0xf02400ff
+
+/* PPM_CPAMP_INV */
+#define        R367TER_PPM_CPAMP_INV   0xf025
+#define        F367TER_PPM_CPAMP_INVER 0xf02500ff
+
+/* FREESTFE_1 */
+#define        R367TER_FREESTFE_1      0xf026
+#define        F367TER_SYMBOL_NUMBER_INC       0xf02600c0
+#define        F367TER_SEL_LSB 0xf0260004
+#define        F367TER_AVERAGE_ON      0xf0260002
+#define        F367TER_DC_ADJ  0xf0260001
+
+/* FREESTFE_2 */
+#define        R367TER_FREESTFE_2      0xf027
+#define        F367TER_SEL_SRCOUT      0xf02700c0
+#define        F367TER_SEL_SYRTHR      0xf027001f
+
+/* DCOFFSET */
+#define        R367TER_DCOFFSET        0xf028
+#define        F367TER_SELECT_I_Q      0xf0280080
+#define        F367TER_DC_OFFSET       0xf028007f
+
+/* EN_PROCESS */
+#define        R367TER_EN_PROCESS      0xf029
+#define        F367TER_FREE    0xf02900f0
+#define        F367TER_ENAB_MANUAL     0xf0290001
+
+/* SDI_SMOOTHER */
+#define        R367TER_SDI_SMOOTHER    0xf02a
+#define        F367TER_DIS_SMOOTH      0xf02a0080
+#define        F367TER_SDI_INC_SMOOTHER        0xf02a007f
+
+/* FE_LOOP_OPEN */
+#define        R367TER_FE_LOOP_OPEN    0xf02b
+#define        F367TER_TRL_LOOP_OP     0xf02b0002
+#define        F367TER_CRL_LOOP_OP     0xf02b0001
+
+/* FREQOFF1 */
+#define        R367TER_FREQOFF1        0xf02c
+#define        F367TER_FREQ_OFFSET_LOOP_OPEN_VHI       0xf02c00ff
+
+/* FREQOFF2 */
+#define        R367TER_FREQOFF2        0xf02d
+#define        F367TER_FREQ_OFFSET_LOOP_OPEN_HI        0xf02d00ff
+
+/* FREQOFF3 */
+#define        R367TER_FREQOFF3        0xf02e
+#define        F367TER_FREQ_OFFSET_LOOP_OPEN_LO        0xf02e00ff
+
+/* TIMOFF1 */
+#define        R367TER_TIMOFF1 0xf02f
+#define        F367TER_TIM_OFFSET_LOOP_OPEN_HI 0xf02f00ff
+
+/* TIMOFF2 */
+#define        R367TER_TIMOFF2 0xf030
+#define        F367TER_TIM_OFFSET_LOOP_OPEN_LO 0xf03000ff
+
+/* EPQ */
+#define        R367TER_EPQ     0xf031
+#define        F367TER_EPQ1    0xf03100ff
+
+/* EPQAUTO */
+#define        R367TER_EPQAUTO 0xf032
+#define        F367TER_EPQ2    0xf03200ff
+
+/* SYR_UPDATE */
+#define        R367TER_SYR_UPDATE      0xf033
+#define        F367TER_SYR_PROTV       0xf0330080
+#define        F367TER_SYR_PROTV_GAIN  0xf0330060
+#define        F367TER_SYR_FILTER      0xf0330010
+#define        F367TER_SYR_TRACK_THRES 0xf033000c
+
+/* CHPFREE */
+#define        R367TER_CHPFREE 0xf034
+#define        F367TER_CHP_FREE        0xf03400ff
+
+/* PPM_STATE_MAC */
+#define        R367TER_PPM_STATE_MAC   0xf035
+#define        F367TER_PPM_STATE_MACHINE_DECODER       0xf035003f
+
+/* INR_THRESHOLD */
+#define        R367TER_INR_THRESHOLD   0xf036
+#define        F367TER_INR_THRESH      0xf03600ff
+
+/* EPQ_TPS_ID_CELL */
+#define        R367TER_EPQ_TPS_ID_CELL 0xf037
+#define        F367TER_ENABLE_LGTH_TO_CF       0xf0370080
+#define        F367TER_DIS_TPS_RSVD    0xf0370040
+#define        F367TER_DIS_BCH 0xf0370020
+#define        F367TER_DIS_ID_CEL      0xf0370010
+#define        F367TER_TPS_ADJUST_SYM  0xf037000f
+
+/* EPQ_CFG */
+#define        R367TER_EPQ_CFG 0xf038
+#define        F367TER_EPQ_RANGE       0xf0380002
+#define        F367TER_EPQ_SOFT        0xf0380001
+
+/* EPQ_STATUS */
+#define        R367TER_EPQ_STATUS      0xf039
+#define        F367TER_SLOPE_INC       0xf03900fc
+#define        F367TER_TPS_FIELD       0xf0390003
+
+/* AUTORELOCK */
+#define        R367TER_AUTORELOCK      0xf03a
+#define        F367TER_BYPASS_BER_TEMPO        0xf03a0080
+#define        F367TER_BER_TEMPO       0xf03a0070
+#define        F367TER_BYPASS_COFDM_TEMPO      0xf03a0008
+#define        F367TER_COFDM_TEMPO     0xf03a0007
+
+/* BER_THR_VMSB */
+#define        R367TER_BER_THR_VMSB    0xf03b
+#define        F367TER_BER_THRESHOLD_HI        0xf03b00ff
+
+/* BER_THR_MSB */
+#define        R367TER_BER_THR_MSB     0xf03c
+#define        F367TER_BER_THRESHOLD_MID       0xf03c00ff
+
+/* BER_THR_LSB */
+#define        R367TER_BER_THR_LSB     0xf03d
+#define        F367TER_BER_THRESHOLD_LO        0xf03d00ff
+
+/* CCD */
+#define        R367TER_CCD     0xf03e
+#define        F367TER_CCD_DETECTED    0xf03e0080
+#define        F367TER_CCD_RESET       0xf03e0040
+#define        F367TER_CCD_THRESHOLD   0xf03e000f
+
+/* SPECTR_CFG */
+#define        R367TER_SPECTR_CFG      0xf03f
+#define        F367TER_SPECT_CFG       0xf03f0003
+
+/* CONSTMU_MSB */
+#define        R367TER_CONSTMU_MSB     0xf040
+#define        F367TER_CONSTMU_FREEZE  0xf0400080
+#define        F367TER_CONSTNU_FORCE_EN        0xf0400040
+#define        F367TER_CONST_MU_MSB    0xf040003f
+
+/* CONSTMU_LSB */
+#define        R367TER_CONSTMU_LSB     0xf041
+#define        F367TER_CONST_MU_LSB    0xf04100ff
+
+/* CONSTMU_MAX_MSB */
+#define        R367TER_CONSTMU_MAX_MSB 0xf042
+#define        F367TER_CONST_MU_MAX_MSB        0xf042003f
+
+/* CONSTMU_MAX_LSB */
+#define        R367TER_CONSTMU_MAX_LSB 0xf043
+#define        F367TER_CONST_MU_MAX_LSB        0xf04300ff
+
+/* ALPHANOISE */
+#define        R367TER_ALPHANOISE      0xf044
+#define        F367TER_USE_ALLFILTER   0xf0440080
+#define        F367TER_INTER_ON        0xf0440040
+#define        F367TER_ALPHA_NOISE     0xf044001f
+
+/* MAXGP_MSB */
+#define        R367TER_MAXGP_MSB       0xf045
+#define        F367TER_MUFILTER_LENGTH 0xf04500f0
+#define        F367TER_MAX_GP_MSB      0xf045000f
+
+/* MAXGP_LSB */
+#define        R367TER_MAXGP_LSB       0xf046
+#define        F367TER_MAX_GP_LSB      0xf04600ff
+
+/* ALPHAMSB */
+#define        R367TER_ALPHAMSB        0xf047
+#define        F367TER_CHC_DATARATE    0xf04700c0
+#define        F367TER_ALPHA_MSB       0xf047003f
+
+/* ALPHALSB */
+#define        R367TER_ALPHALSB        0xf048
+#define        F367TER_ALPHA_LSB       0xf04800ff
+
+/* PILOT_ACCU */
+#define        R367TER_PILOT_ACCU      0xf049
+#define        F367TER_USE_SCAT4ADDAPT 0xf0490080
+#define        F367TER_PILOT_ACC       0xf049001f
+
+/* PILOTMU_ACCU */
+#define        R367TER_PILOTMU_ACCU    0xf04a
+#define        F367TER_DISCARD_BAD_SP  0xf04a0080
+#define        F367TER_DISCARD_BAD_CP  0xf04a0040
+#define        F367TER_PILOT_MU_ACCU   0xf04a001f
+
+/* FILT_CHANNEL_EST */
+#define        R367TER_FILT_CHANNEL_EST        0xf04b
+#define        F367TER_USE_FILT_PILOT  0xf04b0080
+#define        F367TER_FILT_CHANNEL    0xf04b007f
+
+/* ALPHA_NOPISE_FREQ */
+#define        R367TER_ALPHA_NOPISE_FREQ       0xf04c
+#define        F367TER_NOISE_FREQ_FILT 0xf04c0040
+#define        F367TER_ALPHA_NOISE_FREQ        0xf04c003f
+
+/* RATIO_PILOT */
+#define        R367TER_RATIO_PILOT     0xf04d
+#define        F367TER_RATIO_MEAN_SP   0xf04d00f0
+#define        F367TER_RATIO_MEAN_CP   0xf04d000f
+
+/* CHC_CTL */
+#define        R367TER_CHC_CTL 0xf04e
+#define        F367TER_TRACK_EN        0xf04e0080
+#define        F367TER_NOISE_NORM_EN   0xf04e0040
+#define        F367TER_FORCE_CHC_RESET 0xf04e0020
+#define        F367TER_SHORT_TIME      0xf04e0010
+#define        F367TER_FORCE_STATE_EN  0xf04e0008
+#define        F367TER_FORCE_STATE     0xf04e0007
+
+/* EPQ_ADJUST */
+#define        R367TER_EPQ_ADJUST      0xf04f
+#define        F367TER_ADJUST_SCAT_IND 0xf04f00c0
+#define        F367TER_ONE_SYMBOL      0xf04f0010
+#define        F367TER_EPQ_DECAY       0xf04f000e
+#define        F367TER_HOLD_SLOPE      0xf04f0001
+
+/* EPQ_THRES */
+#define        R367TER_EPQ_THRES       0xf050
+#define        F367TER_EPQ_THR 0xf05000ff
+
+/* OMEGA_CTL */
+#define        R367TER_OMEGA_CTL       0xf051
+#define        F367TER_OMEGA_RST       0xf0510080
+#define        F367TER_FREEZE_OMEGA    0xf0510040
+#define        F367TER_OMEGA_SEL       0xf051003f
+
+/* GP_CTL */
+#define        R367TER_GP_CTL  0xf052
+#define        F367TER_CHC_STATE       0xf05200e0
+#define        F367TER_FREEZE_GP       0xf0520010
+#define        F367TER_GP_SEL  0xf052000f
+
+/* MUMSB */
+#define        R367TER_MUMSB   0xf053
+#define        F367TER_MU_MSB  0xf053007f
+
+/* MULSB */
+#define        R367TER_MULSB   0xf054
+#define        F367TER_MU_LSB  0xf05400ff
+
+/* GPMSB */
+#define        R367TER_GPMSB   0xf055
+#define        F367TER_CSI_THRESHOLD   0xf05500e0
+#define        F367TER_GP_MSB  0xf055000f
+
+/* GPLSB */
+#define        R367TER_GPLSB   0xf056
+#define        F367TER_GP_LSB  0xf05600ff
+
+/* OMEGAMSB */
+#define        R367TER_OMEGAMSB        0xf057
+#define        F367TER_OMEGA_MSB       0xf057007f
+
+/* OMEGALSB */
+#define        R367TER_OMEGALSB        0xf058
+#define        F367TER_OMEGA_LSB       0xf05800ff
+
+/* SCAT_NB */
+#define        R367TER_SCAT_NB 0xf059
+#define        F367TER_CHC_TEST        0xf05900f8
+#define        F367TER_SCAT_NUMB       0xf0590003
+
+/* CHC_DUMMY */
+#define        R367TER_CHC_DUMMY       0xf05a
+#define        F367TER_CHC_DUM 0xf05a00ff
+
+/* INC_CTL */
+#define        R367TER_INC_CTL 0xf05b
+#define        F367TER_INC_BYPASS      0xf05b0080
+#define        F367TER_INC_NDEPTH      0xf05b000c
+#define        F367TER_INC_MADEPTH     0xf05b0003
+
+/* INCTHRES_COR1 */
+#define        R367TER_INCTHRES_COR1   0xf05c
+#define        F367TER_INC_THRES_COR1  0xf05c00ff
+
+/* INCTHRES_COR2 */
+#define        R367TER_INCTHRES_COR2   0xf05d
+#define        F367TER_INC_THRES_COR2  0xf05d00ff
+
+/* INCTHRES_DET1 */
+#define        R367TER_INCTHRES_DET1   0xf05e
+#define        F367TER_INC_THRES_DET1  0xf05e003f
+
+/* INCTHRES_DET2 */
+#define        R367TER_INCTHRES_DET2   0xf05f
+#define        F367TER_INC_THRES_DET2  0xf05f003f
+
+/* IIR_CELLNB */
+#define        R367TER_IIR_CELLNB      0xf060
+#define        F367TER_NRST_IIR        0xf0600080
+#define        F367TER_IIR_CELL_NB     0xf0600007
+
+/* IIRCX_COEFF1_MSB */
+#define        R367TER_IIRCX_COEFF1_MSB        0xf061
+#define        F367TER_IIR_CX_COEFF1_MSB       0xf06100ff
+
+/* IIRCX_COEFF1_LSB */
+#define        R367TER_IIRCX_COEFF1_LSB        0xf062
+#define        F367TER_IIR_CX_COEFF1_LSB       0xf06200ff
+
+/* IIRCX_COEFF2_MSB */
+#define        R367TER_IIRCX_COEFF2_MSB        0xf063
+#define        F367TER_IIR_CX_COEFF2_MSB       0xf06300ff
+
+/* IIRCX_COEFF2_LSB */
+#define        R367TER_IIRCX_COEFF2_LSB        0xf064
+#define        F367TER_IIR_CX_COEFF2_LSB       0xf06400ff
+
+/* IIRCX_COEFF3_MSB */
+#define        R367TER_IIRCX_COEFF3_MSB        0xf065
+#define        F367TER_IIR_CX_COEFF3_MSB       0xf06500ff
+
+/* IIRCX_COEFF3_LSB */
+#define        R367TER_IIRCX_COEFF3_LSB        0xf066
+#define        F367TER_IIR_CX_COEFF3_LSB       0xf06600ff
+
+/* IIRCX_COEFF4_MSB */
+#define        R367TER_IIRCX_COEFF4_MSB        0xf067
+#define        F367TER_IIR_CX_COEFF4_MSB       0xf06700ff
+
+/* IIRCX_COEFF4_LSB */
+#define        R367TER_IIRCX_COEFF4_LSB        0xf068
+#define        F367TER_IIR_CX_COEFF4_LSB       0xf06800ff
+
+/* IIRCX_COEFF5_MSB */
+#define        R367TER_IIRCX_COEFF5_MSB        0xf069
+#define        F367TER_IIR_CX_COEFF5_MSB       0xf06900ff
+
+/* IIRCX_COEFF5_LSB */
+#define        R367TER_IIRCX_COEFF5_LSB        0xf06a
+#define        F367TER_IIR_CX_COEFF5_LSB       0xf06a00ff
+
+/* FEPATH_CFG */
+#define        R367TER_FEPATH_CFG      0xf06b
+#define        F367TER_DEMUX_SWAP      0xf06b0004
+#define        F367TER_DIGAGC_SWAP     0xf06b0002
+#define        F367TER_LONGPATH_IF     0xf06b0001
+
+/* PMC1_FUNC */
+#define        R367TER_PMC1_FUNC       0xf06c
+#define        F367TER_SOFT_RSTN       0xf06c0080
+#define        F367TER_PMC1_AVERAGE_TIME       0xf06c0078
+#define        F367TER_PMC1_WAIT_TIME  0xf06c0006
+#define        F367TER_PMC1_2N_SEL     0xf06c0001
+
+/* PMC1_FOR */
+#define        R367TER_PMC1_FOR        0xf06d
+#define        F367TER_PMC1_FORCE      0xf06d0080
+#define        F367TER_PMC1_FORCE_VALUE        0xf06d007c
+
+/* PMC2_FUNC */
+#define        R367TER_PMC2_FUNC       0xf06e
+#define        F367TER_PMC2_SOFT_STN   0xf06e0080
+#define        F367TER_PMC2_ACCU_TIME  0xf06e0070
+#define        F367TER_PMC2_CMDP_MN    0xf06e0008
+#define        F367TER_PMC2_SWAP       0xf06e0004
+
+/* STATUS_ERR_DA */
+#define        R367TER_STATUS_ERR_DA   0xf06f
+#define        F367TER_COM_USEGAINTRK  0xf06f0080
+#define        F367TER_COM_AGCLOCK     0xf06f0040
+#define        F367TER_AUT_AGCLOCK     0xf06f0020
+#define        F367TER_MIN_ERR_X_LSB   0xf06f000f
+
+/* DIG_AGC_R */
+#define        R367TER_DIG_AGC_R       0xf070
+#define        F367TER_COM_SOFT_RSTN   0xf0700080
+#define        F367TER_COM_AGC_ON      0xf0700040
+#define        F367TER_COM_EARLY       0xf0700020
+#define        F367TER_AUT_SOFT_RESETN 0xf0700010
+#define        F367TER_AUT_AGC_ON      0xf0700008
+#define        F367TER_AUT_EARLY       0xf0700004
+#define        F367TER_AUT_ROT_EN      0xf0700002
+#define        F367TER_LOCK_SOFT_RESETN        0xf0700001
+
+/* COMAGC_TARMSB */
+#define        R367TER_COMAGC_TARMSB   0xf071
+#define        F367TER_COM_AGC_TARGET_MSB      0xf07100ff
+
+/* COM_AGC_TAR_ENMODE */
+#define        R367TER_COM_AGC_TAR_ENMODE      0xf072
+#define        F367TER_COM_AGC_TARGET_LSB      0xf07200f0
+#define        F367TER_COM_ENMODE      0xf072000f
+
+/* COM_AGC_CFG */
+#define        R367TER_COM_AGC_CFG     0xf073
+#define        F367TER_COM_N   0xf07300f8
+#define        F367TER_COM_STABMODE    0xf0730006
+#define        F367TER_ERR_SEL 0xf0730001
+
+/* COM_AGC_GAIN1 */
+#define        R367TER_COM_AGC_GAIN1   0xf074
+#define        F367TER_COM_GAIN1aCK    0xf07400f0
+#define        F367TER_COM_GAIN1TRK    0xf074000f
+
+/* AUT_AGC_TARGETMSB */
+#define        R367TER_AUT_AGC_TARGETMSB       0xf075
+#define        F367TER_AUT_AGC_TARGET_MSB      0xf07500ff
+
+/* LOCK_DET_MSB */
+#define        R367TER_LOCK_DET_MSB    0xf076
+#define        F367TER_LOCK_DETECT_MSB 0xf07600ff
+
+/* AGCTAR_LOCK_LSBS */
+#define        R367TER_AGCTAR_LOCK_LSBS        0xf077
+#define        F367TER_AUT_AGC_TARGET_LSB      0xf07700f0
+#define        F367TER_LOCK_DETECT_LSB 0xf077000f
+
+/* AUT_GAIN_EN */
+#define        R367TER_AUT_GAIN_EN     0xf078
+#define        F367TER_AUT_ENMODE      0xf07800f0
+#define        F367TER_AUT_GAIN2       0xf078000f
+
+/* AUT_CFG */
+#define        R367TER_AUT_CFG 0xf079
+#define        F367TER_AUT_N   0xf07900f8
+#define        F367TER_INT_CHOICE      0xf0790006
+#define        F367TER_INT_LOAD        0xf0790001
+
+/* LOCKN */
+#define        R367TER_LOCKN   0xf07a
+#define        F367TER_LOCK_N  0xf07a00f8
+#define        F367TER_SEL_IQNTAR      0xf07a0004
+#define        F367TER_LOCK_DETECT_CHOICE      0xf07a0003
+
+/* INT_X_3 */
+#define        R367TER_INT_X_3 0xf07b
+#define        F367TER_INT_X3  0xf07b00ff
+
+/* INT_X_2 */
+#define        R367TER_INT_X_2 0xf07c
+#define        F367TER_INT_X2  0xf07c00ff
+
+/* INT_X_1 */
+#define        R367TER_INT_X_1 0xf07d
+#define        F367TER_INT_X1  0xf07d00ff
+
+/* INT_X_0 */
+#define        R367TER_INT_X_0 0xf07e
+#define        F367TER_INT_X0  0xf07e00ff
+
+/* MIN_ERRX_MSB */
+#define        R367TER_MIN_ERRX_MSB    0xf07f
+#define        F367TER_MIN_ERR_X_MSB   0xf07f00ff
+
+/* COR_CTL */
+#define        R367TER_COR_CTL 0xf080
+#define        F367TER_CORE_ACTIVE     0xf0800020
+#define        F367TER_HOLD    0xf0800010
+#define        F367TER_CORE_STATE_CTL  0xf080000f
+
+/* COR_STAT */
+#define        R367TER_COR_STAT        0xf081
+#define        F367TER_SCATT_LOCKED    0xf0810080
+#define        F367TER_TPS_LOCKED      0xf0810040
+#define        F367TER_SYR_LOCKED_COR  0xf0810020
+#define        F367TER_AGC_LOCKED_STAT 0xf0810010
+#define        F367TER_CORE_STATE_STAT 0xf081000f
+
+/* COR_INTEN */
+#define        R367TER_COR_INTEN       0xf082
+#define        F367TER_INTEN   0xf0820080
+#define        F367TER_INTEN_SYR       0xf0820020
+#define        F367TER_INTEN_FFT       0xf0820010
+#define        F367TER_INTEN_AGC       0xf0820008
+#define        F367TER_INTEN_TPS1      0xf0820004
+#define        F367TER_INTEN_TPS2      0xf0820002
+#define        F367TER_INTEN_TPS3      0xf0820001
+
+/* COR_INTSTAT */
+#define        R367TER_COR_INTSTAT     0xf083
+#define        F367TER_INTSTAT_SYR     0xf0830020
+#define        F367TER_INTSTAT_FFT     0xf0830010
+#define        F367TER_INTSAT_AGC      0xf0830008
+#define        F367TER_INTSTAT_TPS1    0xf0830004
+#define        F367TER_INTSTAT_TPS2    0xf0830002
+#define        F367TER_INTSTAT_TPS3    0xf0830001
+
+/* COR_MODEGUARD */
+#define        R367TER_COR_MODEGUARD   0xf084
+#define        F367TER_FORCE   0xf0840010
+#define        F367TER_MODE    0xf084000c
+#define        F367TER_GUARD   0xf0840003
+
+/* AGC_CTL */
+#define        R367TER_AGC_CTL 0xf085
+#define        F367TER_AGC_TIMING_FACTOR       0xf08500e0
+#define        F367TER_AGC_LAST        0xf0850010
+#define        F367TER_AGC_GAIN        0xf085000c
+#define        F367TER_AGC_NEG 0xf0850002
+#define        F367TER_AGC_SET 0xf0850001
+
+/* AGC_MANUAL1 */
+#define        R367TER_AGC_MANUAL1     0xf086
+#define        F367TER_AGC_VAL_LO      0xf08600ff
+
+/* AGC_MANUAL2 */
+#define        R367TER_AGC_MANUAL2     0xf087
+#define        F367TER_AGC_VAL_HI      0xf087000f
+
+/* AGC_TARG */
+#define        R367TER_AGC_TARG        0xf088
+#define        F367TER_AGC_TARGET      0xf08800ff
+
+/* AGC_GAIN1 */
+#define        R367TER_AGC_GAIN1       0xf089
+#define        F367TER_AGC_GAIN_LO     0xf08900ff
+
+/* AGC_GAIN2 */
+#define        R367TER_AGC_GAIN2       0xf08a
+#define        F367TER_AGC_LOCKED_GAIN2        0xf08a0010
+#define        F367TER_AGC_GAIN_HI     0xf08a000f
+
+/* RESERVED_1 */
+#define        R367TER_RESERVED_1      0xf08b
+#define        F367TER_RESERVED1       0xf08b00ff
+
+/* RESERVED_2 */
+#define        R367TER_RESERVED_2      0xf08c
+#define        F367TER_RESERVED2       0xf08c00ff
+
+/* RESERVED_3 */
+#define        R367TER_RESERVED_3      0xf08d
+#define        F367TER_RESERVED3       0xf08d00ff
+
+/* CAS_CTL */
+#define        R367TER_CAS_CTL 0xf08e
+#define        F367TER_CCS_ENABLE      0xf08e0080
+#define        F367TER_ACS_DISABLE     0xf08e0040
+#define        F367TER_DAGC_DIS        0xf08e0020
+#define        F367TER_DAGC_GAIN       0xf08e0018
+#define        F367TER_CCSMU   0xf08e0007
+
+/* CAS_FREQ */
+#define        R367TER_CAS_FREQ        0xf08f
+#define        F367TER_CCS_FREQ        0xf08f00ff
+
+/* CAS_DAGCGAIN */
+#define        R367TER_CAS_DAGCGAIN    0xf090
+#define        F367TER_CAS_DAGC_GAIN   0xf09000ff
+
+/* SYR_CTL */
+#define        R367TER_SYR_CTL 0xf091
+#define        F367TER_SICTH_ENABLE    0xf0910080
+#define        F367TER_LONG_ECHO       0xf0910078
+#define        F367TER_AUTO_LE_EN      0xf0910004
+#define        F367TER_SYR_BYPASS      0xf0910002
+#define        F367TER_SYR_TR_DIS      0xf0910001
+
+/* SYR_STAT */
+#define        R367TER_SYR_STAT        0xf092
+#define        F367TER_SYR_LOCKED_STAT 0xf0920010
+#define        F367TER_SYR_MODE        0xf092000c
+#define        F367TER_SYR_GUARD       0xf0920003
+
+/* SYR_NCO1 */
+#define        R367TER_SYR_NCO1        0xf093
+#define        F367TER_SYR_NCO_LO      0xf09300ff
+
+/* SYR_NCO2 */
+#define        R367TER_SYR_NCO2        0xf094
+#define        F367TER_SYR_NCO_HI      0xf094003f
+
+/* SYR_OFFSET1 */
+#define        R367TER_SYR_OFFSET1     0xf095
+#define        F367TER_SYR_OFFSET_LO   0xf09500ff
+
+/* SYR_OFFSET2 */
+#define        R367TER_SYR_OFFSET2     0xf096
+#define        F367TER_SYR_OFFSET_HI   0xf096003f
+
+/* FFT_CTL */
+#define        R367TER_FFT_CTL 0xf097
+#define        F367TER_SHIFT_FFT_TRIG  0xf0970018
+#define        F367TER_FFT_TRIGGER     0xf0970004
+#define        F367TER_FFT_MANUAL      0xf0970002
+#define        F367TER_IFFT_MODE       0xf0970001
+
+/* SCR_CTL */
+#define        R367TER_SCR_CTL 0xf098
+#define        F367TER_SYRADJDECAY     0xf0980070
+#define        F367TER_SCR_CPEDIS      0xf0980002
+#define        F367TER_SCR_DIS 0xf0980001
+
+/* PPM_CTL1 */
+#define        R367TER_PPM_CTL1        0xf099
+#define        F367TER_PPM_MAXFREQ     0xf0990030
+#define        F367TER_PPM_MAXTIM      0xf0990008
+#define        F367TER_PPM_INVSEL      0xf0990004
+#define        F367TER_PPM_SCATDIS     0xf0990002
+#define        F367TER_PPM_BYP 0xf0990001
+
+/* TRL_CTL */
+#define        R367TER_TRL_CTL 0xf09a
+#define        F367TER_TRL_NOMRATE_LSB 0xf09a0080
+#define        F367TER_TRL_GAIN_FACTOR 0xf09a0078
+#define        F367TER_TRL_LOOPGAIN    0xf09a0007
+
+/* TRL_NOMRATE1 */
+#define        R367TER_TRL_NOMRATE1    0xf09b
+#define        F367TER_TRL_NOMRATE_LO  0xf09b00ff
+
+/* TRL_NOMRATE2 */
+#define        R367TER_TRL_NOMRATE2    0xf09c
+#define        F367TER_TRL_NOMRATE_HI  0xf09c00ff
+
+/* TRL_TIME1 */
+#define        R367TER_TRL_TIME1       0xf09d
+#define        F367TER_TRL_TOFFSET_LO  0xf09d00ff
+
+/* TRL_TIME2 */
+#define        R367TER_TRL_TIME2       0xf09e
+#define        F367TER_TRL_TOFFSET_HI  0xf09e00ff
+
+/* CRL_CTL */
+#define        R367TER_CRL_CTL 0xf09f
+#define        F367TER_CRL_DIS 0xf09f0080
+#define        F367TER_CRL_GAIN_FACTOR 0xf09f0078
+#define        F367TER_CRL_LOOPGAIN    0xf09f0007
+
+/* CRL_FREQ1 */
+#define        R367TER_CRL_FREQ1       0xf0a0
+#define        F367TER_CRL_FOFFSET_LO  0xf0a000ff
+
+/* CRL_FREQ2 */
+#define        R367TER_CRL_FREQ2       0xf0a1
+#define        F367TER_CRL_FOFFSET_HI  0xf0a100ff
+
+/* CRL_FREQ3 */
+#define        R367TER_CRL_FREQ3       0xf0a2
+#define        F367TER_CRL_FOFFSET_VHI 0xf0a200ff
+
+/* TPS_SFRAME_CTL */
+#define        R367TER_TPS_SFRAME_CTL  0xf0a3
+#define        F367TER_TPS_SFRAME_SYNC 0xf0a30001
+
+/* CHC_SNR */
+#define        R367TER_CHC_SNR 0xf0a4
+#define        F367TER_CHCSNR  0xf0a400ff
+
+/* BDI_CTL */
+#define        R367TER_BDI_CTL 0xf0a5
+#define        F367TER_BDI_LPSEL       0xf0a50002
+#define        F367TER_BDI_SERIAL      0xf0a50001
+
+/* DMP_CTL */
+#define        R367TER_DMP_CTL 0xf0a6
+#define        F367TER_DMP_SCALING_FACTOR      0xf0a6001e
+#define        F367TER_DMP_SDDIS       0xf0a60001
+
+/* TPS_RCVD1 */
+#define        R367TER_TPS_RCVD1       0xf0a7
+#define        F367TER_TPS_CHANGE      0xf0a70040
+#define        F367TER_BCH_OK  0xf0a70020
+#define        F367TER_TPS_SYNC        0xf0a70010
+#define        F367TER_TPS_FRAME       0xf0a70003
+
+/* TPS_RCVD2 */
+#define        R367TER_TPS_RCVD2       0xf0a8
+#define        F367TER_TPS_HIERMODE    0xf0a80070
+#define        F367TER_TPS_CONST       0xf0a80003
+
+/* TPS_RCVD3 */
+#define        R367TER_TPS_RCVD3       0xf0a9
+#define        F367TER_TPS_LPCODE      0xf0a90070
+#define        F367TER_TPS_HPCODE      0xf0a90007
+
+/* TPS_RCVD4 */
+#define        R367TER_TPS_RCVD4       0xf0aa
+#define        F367TER_TPS_GUARD       0xf0aa0030
+#define        F367TER_TPS_MODE        0xf0aa0003
+
+/* TPS_ID_CELL1 */
+#define        R367TER_TPS_ID_CELL1    0xf0ab
+#define        F367TER_TPS_ID_CELL_LO  0xf0ab00ff
+
+/* TPS_ID_CELL2 */
+#define        R367TER_TPS_ID_CELL2    0xf0ac
+#define        F367TER_TPS_ID_CELL_HI  0xf0ac00ff
+
+/* TPS_RCVD5_SET1 */
+#define        R367TER_TPS_RCVD5_SET1  0xf0ad
+#define        F367TER_TPS_NA  0xf0ad00fC
+#define        F367TER_TPS_SETFRAME    0xf0ad0003
+
+/* TPS_SET2 */
+#define        R367TER_TPS_SET2        0xf0ae
+#define        F367TER_TPS_SETHIERMODE 0xf0ae0070
+#define        F367TER_TPS_SETCONST    0xf0ae0003
+
+/* TPS_SET3 */
+#define        R367TER_TPS_SET3        0xf0af
+#define        F367TER_TPS_SETLPCODE   0xf0af0070
+#define        F367TER_TPS_SETHPCODE   0xf0af0007
+
+/* TPS_CTL */
+#define        R367TER_TPS_CTL 0xf0b0
+#define        F367TER_TPS_IMM 0xf0b00004
+#define        F367TER_TPS_BCHDIS      0xf0b00002
+#define        F367TER_TPS_UPDDIS      0xf0b00001
+
+/* CTL_FFTOSNUM */
+#define        R367TER_CTL_FFTOSNUM    0xf0b1
+#define        F367TER_SYMBOL_NUMBER   0xf0b1007f
+
+/* TESTSELECT */
+#define        R367TER_TESTSELECT      0xf0b2
+#define        F367TER_TEST_SELECT     0xf0b2001f
+
+/* MSC_REV */
+#define        R367TER_MSC_REV 0xf0b3
+#define        F367TER_REV_NUMBER      0xf0b300ff
+
+/* PIR_CTL */
+#define        R367TER_PIR_CTL 0xf0b4
+#define        F367TER_FREEZE  0xf0b40001
+
+/* SNR_CARRIER1 */
+#define        R367TER_SNR_CARRIER1    0xf0b5
+#define        F367TER_SNR_CARRIER_LO  0xf0b500ff
+
+/* SNR_CARRIER2 */
+#define        R367TER_SNR_CARRIER2    0xf0b6
+#define        F367TER_MEAN    0xf0b600c0
+#define        F367TER_SNR_CARRIER_HI  0xf0b6001f
+
+/* PPM_CPAMP */
+#define        R367TER_PPM_CPAMP       0xf0b7
+#define        F367TER_PPM_CPC 0xf0b700ff
+
+/* TSM_AP0 */
+#define        R367TER_TSM_AP0 0xf0b8
+#define        F367TER_ADDRESS_BYTE_0  0xf0b800ff
+
+/* TSM_AP1 */
+#define        R367TER_TSM_AP1 0xf0b9
+#define        F367TER_ADDRESS_BYTE_1  0xf0b900ff
+
+/* TSM_AP2 */
+#define        R367TER_TSM_AP2 0xf0bA
+#define        F367TER_DATA_BYTE_0     0xf0ba00ff
+
+/* TSM_AP3 */
+#define        R367TER_TSM_AP3 0xf0bB
+#define        F367TER_DATA_BYTE_1     0xf0bb00ff
+
+/* TSM_AP4 */
+#define        R367TER_TSM_AP4 0xf0bC
+#define        F367TER_DATA_BYTE_2     0xf0bc00ff
+
+/* TSM_AP5 */
+#define        R367TER_TSM_AP5 0xf0bD
+#define        F367TER_DATA_BYTE_3     0xf0bd00ff
+
+/* TSM_AP6 */
+#define        R367TER_TSM_AP6 0xf0bE
+#define        F367TER_TSM_AP_6        0xf0be00ff
+
+/* TSM_AP7 */
+#define        R367TER_TSM_AP7 0xf0bF
+#define        F367TER_MEM_SELECT_BYTE 0xf0bf00ff
+
+/* TSTRES */
+#define        R367TER_TSTRES  0xf0c0
+#define        F367TER_FRES_DISPLAY    0xf0c00080
+#define        F367TER_FRES_FIFO_AD    0xf0c00020
+#define        F367TER_FRESRS  0xf0c00010
+#define        F367TER_FRESACS 0xf0c00008
+#define        F367TER_FRESFEC 0xf0c00004
+#define        F367TER_FRES_PRIF       0xf0c00002
+#define        F367TER_FRESCORE        0xf0c00001
+
+/* ANACTRL */
+#define        R367TER_ANACTRL 0xf0c1
+#define        F367TER_BYPASS_XTAL     0xf0c10040
+#define        F367TER_BYPASS_PLLXN    0xf0c1000c
+#define        F367TER_DIS_PAD_OSC     0xf0c10002
+#define        F367TER_STDBY_PLLXN     0xf0c10001
+
+/* TSTBUS */
+#define        R367TER_TSTBUS  0xf0c2
+#define        F367TER_TS_BYTE_CLK_INV 0xf0c20080
+#define        F367TER_CFG_IP  0xf0c20070
+#define        F367TER_CFG_TST 0xf0c2000f
+
+/* TSTRATE */
+#define        R367TER_TSTRATE 0xf0c6
+#define        F367TER_FORCEPHA        0xf0c60080
+#define        F367TER_FNEWPHA 0xf0c60010
+#define        F367TER_FROT90  0xf0c60008
+#define        F367TER_FR      0xf0c60007
+
+/* CONSTMODE */
+#define        R367TER_CONSTMODE       0xf0cb
+#define        F367TER_TST_PRIF        0xf0cb00e0
+#define        F367TER_CAR_TYPE        0xf0cb0018
+#define        F367TER_CONST_MODE      0xf0cb0003
+
+/* CONSTCARR1 */
+#define        R367TER_CONSTCARR1      0xf0cc
+#define        F367TER_CONST_CARR_LO   0xf0cc00ff
+
+/* CONSTCARR2 */
+#define        R367TER_CONSTCARR2      0xf0cd
+#define        F367TER_CONST_CARR_HI   0xf0cd001f
+
+/* ICONSTEL */
+#define        R367TER_ICONSTEL        0xf0ce
+#define        F367TER_PICONSTEL       0xf0ce00ff
+
+/* QCONSTEL */
+#define        R367TER_QCONSTEL        0xf0cf
+#define        F367TER_PQCONSTEL       0xf0cf00ff
+
+/* TSTBISTRES0 */
+#define        R367TER_TSTBISTRES0     0xf0d0
+#define        F367TER_BEND_PPM        0xf0d00080
+#define        F367TER_BBAD_PPM        0xf0d00040
+#define        F367TER_BEND_FFTW       0xf0d00020
+#define        F367TER_BBAD_FFTW       0xf0d00010
+#define        F367TER_BEND_FFT_BUF    0xf0d00008
+#define        F367TER_BBAD_FFT_BUF    0xf0d00004
+#define        F367TER_BEND_SYR        0xf0d00002
+#define        F367TER_BBAD_SYR        0xf0d00001
+
+/* TSTBISTRES1 */
+#define        R367TER_TSTBISTRES1     0xf0d1
+#define        F367TER_BEND_CHC_CP     0xf0d10080
+#define        F367TER_BBAD_CHC_CP     0xf0d10040
+#define        F367TER_BEND_CHCI       0xf0d10020
+#define        F367TER_BBAD_CHCI       0xf0d10010
+#define        F367TER_BEND_BDI        0xf0d10008
+#define        F367TER_BBAD_BDI        0xf0d10004
+#define        F367TER_BEND_SDI        0xf0d10002
+#define        F367TER_BBAD_SDI        0xf0d10001
+
+/* TSTBISTRES2 */
+#define        R367TER_TSTBISTRES2     0xf0d2
+#define        F367TER_BEND_CHC_INC    0xf0d20080
+#define        F367TER_BBAD_CHC_INC    0xf0d20040
+#define        F367TER_BEND_CHC_SPP    0xf0d20020
+#define        F367TER_BBAD_CHC_SPP    0xf0d20010
+#define        F367TER_BEND_CHC_CPP    0xf0d20008
+#define        F367TER_BBAD_CHC_CPP    0xf0d20004
+#define        F367TER_BEND_CHC_SP     0xf0d20002
+#define        F367TER_BBAD_CHC_SP     0xf0d20001
+
+/* TSTBISTRES3 */
+#define        R367TER_TSTBISTRES3     0xf0d3
+#define        F367TER_BEND_QAM        0xf0d30080
+#define        F367TER_BBAD_QAM        0xf0d30040
+#define        F367TER_BEND_SFEC_VIT   0xf0d30020
+#define        F367TER_BBAD_SFEC_VIT   0xf0d30010
+#define        F367TER_BEND_SFEC_DLINE 0xf0d30008
+#define        F367TER_BBAD_SFEC_DLINE 0xf0d30004
+#define        F367TER_BEND_SFEC_HW    0xf0d30002
+#define        F367TER_BBAD_SFEC_HW    0xf0d30001
+
+/* RF_AGC1 */
+#define        R367TER_RF_AGC1 0xf0d4
+#define        F367TER_RF_AGC1_LEVEL_HI        0xf0d400ff
+
+/* RF_AGC2 */
+#define        R367TER_RF_AGC2 0xf0d5
+#define        F367TER_REF_ADGP        0xf0d50080
+#define        F367TER_STDBY_ADCGP     0xf0d50020
+#define        F367TER_CHANNEL_SEL     0xf0d5001c
+#define        F367TER_RF_AGC1_LEVEL_LO        0xf0d50003
+
+/* ANADIGCTRL */
+#define        R367TER_ANADIGCTRL      0xf0d7
+#define        F367TER_SEL_CLKDEM      0xf0d70020
+#define        F367TER_EN_BUFFER_Q     0xf0d70010
+#define        F367TER_EN_BUFFER_I     0xf0d70008
+#define        F367TER_ADC_RIS_EGDE    0xf0d70004
+#define        F367TER_SGN_ADC 0xf0d70002
+#define        F367TER_SEL_AD12_SYNC   0xf0d70001
+
+/* PLLMDIV */
+#define        R367TER_PLLMDIV 0xf0d8
+#define        F367TER_PLL_MDIV        0xf0d800ff
+
+/* PLLNDIV */
+#define        R367TER_PLLNDIV 0xf0d9
+#define        F367TER_PLL_NDIV        0xf0d900ff
+
+/* PLLSETUP */
+#define        R367TER_PLLSETUP        0xf0dA
+#define        F367TER_PLL_PDIV        0xf0da0070
+#define        F367TER_PLL_KDIV        0xf0da000f
+
+/* DUAL_AD12 */
+#define        R367TER_DUAL_AD12       0xf0dB
+#define        F367TER_FS20M   0xf0db0020
+#define        F367TER_FS50M   0xf0db0010
+#define        F367TER_INMODe0 0xf0db0008
+#define        F367TER_POFFQ   0xf0db0004
+#define        F367TER_POFFI   0xf0db0002
+#define        F367TER_INMODE1 0xf0db0001
+
+/* TSTBIST */
+#define        R367TER_TSTBIST 0xf0dC
+#define        F367TER_TST_BYP_CLK     0xf0dc0080
+#define        F367TER_TST_GCLKENA_STD 0xf0dc0040
+#define        F367TER_TST_GCLKENA     0xf0dc0020
+#define        F367TER_TST_MEMBIST     0xf0dc001f
+
+/* PAD_COMP_CTRL */
+#define        R367TER_PAD_COMP_CTRL   0xf0dD
+#define        F367TER_COMPTQ  0xf0dd0010
+#define        F367TER_COMPEN  0xf0dd0008
+#define        F367TER_FREEZE2 0xf0dd0004
+#define        F367TER_SLEEP_INHBT     0xf0dd0002
+#define        F367TER_CHIP_SLEEP      0xf0dd0001
+
+/* PAD_COMP_WR */
+#define        R367TER_PAD_COMP_WR     0xf0de
+#define        F367TER_WR_ASRC 0xf0de007f
+
+/* PAD_COMP_RD */
+#define        R367TER_PAD_COMP_RD     0xf0df
+#define        F367TER_COMPOK  0xf0df0080
+#define        F367TER_RD_ASRC 0xf0df007f
+
+/* SYR_TARGET_FFTADJT_MSB */
+#define        R367TER_SYR_TARGET_FFTADJT_MSB  0xf100
+#define        F367TER_SYR_START       0xf1000080
+#define        F367TER_SYR_TARGET_FFTADJ_HI    0xf100000f
+
+/* SYR_TARGET_FFTADJT_LSB */
+#define        R367TER_SYR_TARGET_FFTADJT_LSB  0xf101
+#define        F367TER_SYR_TARGET_FFTADJ_LO    0xf10100ff
+
+/* SYR_TARGET_CHCADJT_MSB */
+#define        R367TER_SYR_TARGET_CHCADJT_MSB  0xf102
+#define        F367TER_SYR_TARGET_CHCADJ_HI    0xf102000f
+
+/* SYR_TARGET_CHCADJT_LSB */
+#define        R367TER_SYR_TARGET_CHCADJT_LSB  0xf103
+#define        F367TER_SYR_TARGET_CHCADJ_LO    0xf10300ff
+
+/* SYR_FLAG */
+#define        R367TER_SYR_FLAG        0xf104
+#define        F367TER_TRIG_FLG1       0xf1040080
+#define        F367TER_TRIG_FLG0       0xf1040040
+#define        F367TER_FFT_FLG1        0xf1040008
+#define        F367TER_FFT_FLG0        0xf1040004
+#define        F367TER_CHC_FLG1        0xf1040002
+#define        F367TER_CHC_FLG0        0xf1040001
+
+/* CRL_TARGET1 */
+#define        R367TER_CRL_TARGET1     0xf105
+#define        F367TER_CRL_START       0xf1050080
+#define        F367TER_CRL_TARGET_VHI  0xf105000f
+
+/* CRL_TARGET2 */
+#define        R367TER_CRL_TARGET2     0xf106
+#define        F367TER_CRL_TARGET_HI   0xf10600ff
+
+/* CRL_TARGET3 */
+#define        R367TER_CRL_TARGET3     0xf107
+#define        F367TER_CRL_TARGET_LO   0xf10700ff
+
+/* CRL_TARGET4 */
+#define        R367TER_CRL_TARGET4     0xf108
+#define        F367TER_CRL_TARGET_VLO  0xf10800ff
+
+/* CRL_FLAG */
+#define        R367TER_CRL_FLAG        0xf109
+#define        F367TER_CRL_FLAG1       0xf1090002
+#define        F367TER_CRL_FLAG0       0xf1090001
+
+/* TRL_TARGET1 */
+#define        R367TER_TRL_TARGET1     0xf10a
+#define        F367TER_TRL_TARGET_HI   0xf10a00ff
+
+/* TRL_TARGET2 */
+#define        R367TER_TRL_TARGET2     0xf10b
+#define        F367TER_TRL_TARGET_LO   0xf10b00ff
+
+/* TRL_CHC */
+#define        R367TER_TRL_CHC 0xf10c
+#define        F367TER_TRL_START       0xf10c0080
+#define        F367TER_CHC_START       0xf10c0040
+#define        F367TER_TRL_FLAG1       0xf10c0002
+#define        F367TER_TRL_FLAG0       0xf10c0001
+
+/* CHC_SNR_TARG */
+#define        R367TER_CHC_SNR_TARG    0xf10d
+#define        F367TER_CHC_SNR_TARGET  0xf10d00ff
+
+/* TOP_TRACK */
+#define        R367TER_TOP_TRACK       0xf10e
+#define        F367TER_TOP_START       0xf10e0080
+#define        F367TER_FIRST_FLAG      0xf10e0070
+#define        F367TER_TOP_FLAG1       0xf10e0008
+#define        F367TER_TOP_FLAG0       0xf10e0004
+#define        F367TER_CHC_FLAG1       0xf10e0002
+#define        F367TER_CHC_FLAG0       0xf10e0001
+
+/* TRACKER_FREE1 */
+#define        R367TER_TRACKER_FREE1   0xf10f
+#define        F367TER_TRACKER_FREE_1  0xf10f00ff
+
+/* ERROR_CRL1 */
+#define        R367TER_ERROR_CRL1      0xf110
+#define        F367TER_ERROR_CRL_VHI   0xf11000ff
+
+/* ERROR_CRL2 */
+#define        R367TER_ERROR_CRL2      0xf111
+#define        F367TER_ERROR_CRL_HI    0xf11100ff
+
+/* ERROR_CRL3 */
+#define        R367TER_ERROR_CRL3      0xf112
+#define        F367TER_ERROR_CRL_LOI   0xf11200ff
+
+/* ERROR_CRL4 */
+#define        R367TER_ERROR_CRL4      0xf113
+#define        F367TER_ERROR_CRL_VLO   0xf11300ff
+
+/* DEC_NCO1 */
+#define        R367TER_DEC_NCO1        0xf114
+#define        F367TER_DEC_NCO_VHI     0xf11400ff
+
+/* DEC_NCO2 */
+#define        R367TER_DEC_NCO2        0xf115
+#define        F367TER_DEC_NCO_HI      0xf11500ff
+
+/* DEC_NCO3 */
+#define        R367TER_DEC_NCO3        0xf116
+#define        F367TER_DEC_NCO_LO      0xf11600ff
+
+/* SNR */
+#define        R367TER_SNR     0xf117
+#define        F367TER_SNRATIO 0xf11700ff
+
+/* SYR_FFTADJ1 */
+#define        R367TER_SYR_FFTADJ1     0xf118
+#define        F367TER_SYR_FFTADJ_HI   0xf11800ff
+
+/* SYR_FFTADJ2 */
+#define        R367TER_SYR_FFTADJ2     0xf119
+#define        F367TER_SYR_FFTADJ_LO   0xf11900ff
+
+/* SYR_CHCADJ1 */
+#define        R367TER_SYR_CHCADJ1     0xf11a
+#define        F367TER_SYR_CHCADJ_HI   0xf11a00ff
+
+/* SYR_CHCADJ2 */
+#define        R367TER_SYR_CHCADJ2     0xf11b
+#define        F367TER_SYR_CHCADJ_LO   0xf11b00ff
+
+/* SYR_OFF */
+#define        R367TER_SYR_OFF 0xf11c
+#define        F367TER_SYR_OFFSET      0xf11c00ff
+
+/* PPM_OFFSET1 */
+#define        R367TER_PPM_OFFSET1     0xf11d
+#define        F367TER_PPM_OFFSET_HI   0xf11d00ff
+
+/* PPM_OFFSET2 */
+#define        R367TER_PPM_OFFSET2     0xf11e
+#define        F367TER_PPM_OFFSET_LO   0xf11e00ff
+
+/* TRACKER_FREE2 */
+#define        R367TER_TRACKER_FREE2   0xf11f
+#define        F367TER_TRACKER_FREE_2  0xf11f00ff
+
+/* DEBG_LT10 */
+#define        R367TER_DEBG_LT10       0xf120
+#define        F367TER_DEBUG_LT10      0xf12000ff
+
+/* DEBG_LT11 */
+#define        R367TER_DEBG_LT11       0xf121
+#define        F367TER_DEBUG_LT11      0xf12100ff
+
+/* DEBG_LT12 */
+#define        R367TER_DEBG_LT12       0xf122
+#define        F367TER_DEBUG_LT12      0xf12200ff
+
+/* DEBG_LT13 */
+#define        R367TER_DEBG_LT13       0xf123
+#define        F367TER_DEBUG_LT13      0xf12300ff
+
+/* DEBG_LT14 */
+#define        R367TER_DEBG_LT14       0xf124
+#define        F367TER_DEBUG_LT14      0xf12400ff
+
+/* DEBG_LT15 */
+#define        R367TER_DEBG_LT15       0xf125
+#define        F367TER_DEBUG_LT15      0xf12500ff
+
+/* DEBG_LT16 */
+#define        R367TER_DEBG_LT16       0xf126
+#define        F367TER_DEBUG_LT16      0xf12600ff
+
+/* DEBG_LT17 */
+#define        R367TER_DEBG_LT17       0xf127
+#define        F367TER_DEBUG_LT17      0xf12700ff
+
+/* DEBG_LT18 */
+#define        R367TER_DEBG_LT18       0xf128
+#define        F367TER_DEBUG_LT18      0xf12800ff
+
+/* DEBG_LT19 */
+#define        R367TER_DEBG_LT19       0xf129
+#define        F367TER_DEBUG_LT19      0xf12900ff
+
+/* DEBG_LT1a */
+#define        R367TER_DEBG_LT1A       0xf12a
+#define        F367TER_DEBUG_LT1A      0xf12a00ff
+
+/* DEBG_LT1b */
+#define        R367TER_DEBG_LT1B       0xf12b
+#define        F367TER_DEBUG_LT1B      0xf12b00ff
+
+/* DEBG_LT1c */
+#define        R367TER_DEBG_LT1C       0xf12c
+#define        F367TER_DEBUG_LT1C      0xf12c00ff
+
+/* DEBG_LT1D */
+#define        R367TER_DEBG_LT1D       0xf12d
+#define        F367TER_DEBUG_LT1D      0xf12d00ff
+
+/* DEBG_LT1E */
+#define        R367TER_DEBG_LT1E       0xf12e
+#define        F367TER_DEBUG_LT1E      0xf12e00ff
+
+/* DEBG_LT1F */
+#define        R367TER_DEBG_LT1F       0xf12f
+#define        F367TER_DEBUG_LT1F      0xf12f00ff
+
+/* RCCFGH */
+#define        R367TER_RCCFGH  0xf200
+#define        F367TER_TSRCFIFO_DVBCI  0xf2000080
+#define        F367TER_TSRCFIFO_SERIAL 0xf2000040
+#define        F367TER_TSRCFIFO_DISABLE        0xf2000020
+#define        F367TER_TSFIFO_2TORC    0xf2000010
+#define        F367TER_TSRCFIFO_HSGNLOUT       0xf2000008
+#define        F367TER_TSRCFIFO_ERRMODE        0xf2000006
+#define        F367TER_RCCFGH_0        0xf2000001
+
+/* RCCFGM */
+#define        R367TER_RCCFGM  0xf201
+#define        F367TER_TSRCFIFO_MANSPEED       0xf20100c0
+#define        F367TER_TSRCFIFO_PERMDATA       0xf2010020
+#define        F367TER_TSRCFIFO_NONEWSGNL      0xf2010010
+#define        F367TER_RCBYTE_OVERSAMPLING     0xf201000e
+#define        F367TER_TSRCFIFO_INVDATA        0xf2010001
+
+/* RCCFGL */
+#define        R367TER_RCCFGL  0xf202
+#define        F367TER_TSRCFIFO_BCLKDEL1cK     0xf20200c0
+#define        F367TER_RCCFGL_5        0xf2020020
+#define        F367TER_TSRCFIFO_DUTY50 0xf2020010
+#define        F367TER_TSRCFIFO_NSGNL2dATA     0xf2020008
+#define        F367TER_TSRCFIFO_DISSERMUX      0xf2020004
+#define        F367TER_RCCFGL_1        0xf2020002
+#define        F367TER_TSRCFIFO_STOPCKDIS      0xf2020001
+
+/* RCINSDELH */
+#define        R367TER_RCINSDELH       0xf203
+#define        F367TER_TSRCDEL_SYNCBYTE        0xf2030080
+#define        F367TER_TSRCDEL_XXHEADER        0xf2030040
+#define        F367TER_TSRCDEL_BBHEADER        0xf2030020
+#define        F367TER_TSRCDEL_DATAFIELD       0xf2030010
+#define        F367TER_TSRCINSDEL_ISCR 0xf2030008
+#define        F367TER_TSRCINSDEL_NPD  0xf2030004
+#define        F367TER_TSRCINSDEL_RSPARITY     0xf2030002
+#define        F367TER_TSRCINSDEL_CRC8 0xf2030001
+
+/* RCINSDELM */
+#define        R367TER_RCINSDELM       0xf204
+#define        F367TER_TSRCINS_BBPADDING       0xf2040080
+#define        F367TER_TSRCINS_BCHFEC  0xf2040040
+#define        F367TER_TSRCINS_LDPCFEC 0xf2040020
+#define        F367TER_TSRCINS_EMODCOD 0xf2040010
+#define        F367TER_TSRCINS_TOKEN   0xf2040008
+#define        F367TER_TSRCINS_XXXERR  0xf2040004
+#define        F367TER_TSRCINS_MATYPE  0xf2040002
+#define        F367TER_TSRCINS_UPL     0xf2040001
+
+/* RCINSDELL */
+#define        R367TER_RCINSDELL       0xf205
+#define        F367TER_TSRCINS_DFL     0xf2050080
+#define        F367TER_TSRCINS_SYNCD   0xf2050040
+#define        F367TER_TSRCINS_BLOCLEN 0xf2050020
+#define        F367TER_TSRCINS_SIGPCOUNT       0xf2050010
+#define        F367TER_TSRCINS_FIFO    0xf2050008
+#define        F367TER_TSRCINS_REALPACK        0xf2050004
+#define        F367TER_TSRCINS_TSCONFIG        0xf2050002
+#define        F367TER_TSRCINS_LATENCY 0xf2050001
+
+/* RCSTATUS */
+#define        R367TER_RCSTATUS        0xf206
+#define        F367TER_TSRCFIFO_LINEOK 0xf2060080
+#define        F367TER_TSRCFIFO_ERROR  0xf2060040
+#define        F367TER_TSRCFIFO_DATA7  0xf2060020
+#define        F367TER_RCSTATUS_4      0xf2060010
+#define        F367TER_TSRCFIFO_DEMODSEL       0xf2060008
+#define        F367TER_TSRC1FIFOSPEED_STORE    0xf2060004
+#define        F367TER_RCSTATUS_1      0xf2060002
+#define        F367TER_TSRCSERIAL_IMPOSSIBLE   0xf2060001
+
+/* RCSPEED */
+#define        R367TER_RCSPEED 0xf207
+#define        F367TER_TSRCFIFO_OUTSPEED       0xf20700ff
+
+/* RCDEBUGM */
+#define        R367TER_RCDEBUGM        0xf208
+#define        F367TER_SD_UNSYNC       0xf2080080
+#define        F367TER_ULFLOCK_DETECTM 0xf2080040
+#define        F367TER_SUL_SELECTOS    0xf2080020
+#define        F367TER_DILUL_NOSCRBLE  0xf2080010
+#define        F367TER_NUL_SCRB        0xf2080008
+#define        F367TER_UL_SCRB 0xf2080004
+#define        F367TER_SCRAULBAD       0xf2080002
+#define        F367TER_SCRAUL_UNSYNC   0xf2080001
+
+/* RCDEBUGL */
+#define        R367TER_RCDEBUGL        0xf209
+#define        F367TER_RS_ERR  0xf2090080
+#define        F367TER_LLFLOCK_DETECTM 0xf2090040
+#define        F367TER_NOT_SUL_SELECTOS        0xf2090020
+#define        F367TER_DILLL_NOSCRBLE  0xf2090010
+#define        F367TER_NLL_SCRB        0xf2090008
+#define        F367TER_LL_SCRB 0xf2090004
+#define        F367TER_SCRALLBAD       0xf2090002
+#define        F367TER_SCRALL_UNSYNC   0xf2090001
+
+/* RCOBSCFG */
+#define        R367TER_RCOBSCFG        0xf20a
+#define        F367TER_TSRCFIFO_OBSCFG 0xf20a00ff
+
+/* RCOBSM */
+#define        R367TER_RCOBSM  0xf20b
+#define        F367TER_TSRCFIFO_OBSDATA_HI     0xf20b00ff
+
+/* RCOBSL */
+#define        R367TER_RCOBSL  0xf20c
+#define        F367TER_TSRCFIFO_OBSDATA_LO     0xf20c00ff
+
+/* RCFECSPY */
+#define        R367TER_RCFECSPY        0xf210
+#define        F367TER_SPYRC_ENABLE    0xf2100080
+#define        F367TER_RCNO_SYNCBYTE   0xf2100040
+#define        F367TER_RCSERIAL_MODE   0xf2100020
+#define        F367TER_RCUNUSUAL_PACKET        0xf2100010
+#define        F367TER_BERRCMETER_DATAMODE     0xf210000c
+#define        F367TER_BERRCMETER_LMODE        0xf2100002
+#define        F367TER_BERRCMETER_RESET        0xf2100001
+
+/* RCFSPYCFG */
+#define        R367TER_RCFSPYCFG       0xf211
+#define        F367TER_FECSPYRC_INPUT  0xf21100c0
+#define        F367TER_RCRST_ON_ERROR  0xf2110020
+#define        F367TER_RCONE_SHOT      0xf2110010
+#define        F367TER_RCI2C_MODE      0xf211000c
+#define        F367TER_SPYRC_HSTERESIS 0xf2110003
+
+/* RCFSPYDATA */
+#define        R367TER_RCFSPYDATA      0xf212
+#define        F367TER_SPYRC_STUFFING  0xf2120080
+#define        F367TER_RCNOERR_PKTJITTER       0xf2120040
+#define        F367TER_SPYRC_CNULLPKT  0xf2120020
+#define        F367TER_SPYRC_OUTDATA_MODE      0xf212001f
+
+/* RCFSPYOUT */
+#define        R367TER_RCFSPYOUT       0xf213
+#define        F367TER_FSPYRC_DIRECT   0xf2130080
+#define        F367TER_RCFSPYOUT_6     0xf2130040
+#define        F367TER_SPYRC_OUTDATA_BUS       0xf2130038
+#define        F367TER_RCSTUFF_MODE    0xf2130007
+
+/* RCFSTATUS */
+#define        R367TER_RCFSTATUS       0xf214
+#define        F367TER_SPYRC_ENDSIM    0xf2140080
+#define        F367TER_RCVALID_SIM     0xf2140040
+#define        F367TER_RCFOUND_SIGNAL  0xf2140020
+#define        F367TER_RCDSS_SYNCBYTE  0xf2140010
+#define        F367TER_RCRESULT_STATE  0xf214000f
+
+/* RCFGOODPACK */
+#define        R367TER_RCFGOODPACK     0xf215
+#define        F367TER_RCGOOD_PACKET   0xf21500ff
+
+/* RCFPACKCNT */
+#define        R367TER_RCFPACKCNT      0xf216
+#define        F367TER_RCPACKET_COUNTER        0xf21600ff
+
+/* RCFSPYMISC */
+#define        R367TER_RCFSPYMISC      0xf217
+#define        F367TER_RCLABEL_COUNTER 0xf21700ff
+
+/* RCFBERCPT4 */
+#define        R367TER_RCFBERCPT4      0xf218
+#define        F367TER_FBERRCMETER_CPT_MMMMSB  0xf21800ff
+
+/* RCFBERCPT3 */
+#define        R367TER_RCFBERCPT3      0xf219
+#define        F367TER_FBERRCMETER_CPT_MMMSB   0xf21900ff
+
+/* RCFBERCPT2 */
+#define        R367TER_RCFBERCPT2      0xf21a
+#define        F367TER_FBERRCMETER_CPT_MMSB    0xf21a00ff
+
+/* RCFBERCPT1 */
+#define        R367TER_RCFBERCPT1      0xf21b
+#define        F367TER_FBERRCMETER_CPT_MSB     0xf21b00ff
+
+/* RCFBERCPT0 */
+#define        R367TER_RCFBERCPT0      0xf21c
+#define        F367TER_FBERRCMETER_CPT_LSB     0xf21c00ff
+
+/* RCFBERERR2 */
+#define        R367TER_RCFBERERR2      0xf21d
+#define        F367TER_FBERRCMETER_ERR_HI      0xf21d00ff
+
+/* RCFBERERR1 */
+#define        R367TER_RCFBERERR1      0xf21e
+#define        F367TER_FBERRCMETER_ERR 0xf21e00ff
+
+/* RCFBERERR0 */
+#define        R367TER_RCFBERERR0      0xf21f
+#define        F367TER_FBERRCMETER_ERR_LO      0xf21f00ff
+
+/* RCFSTATESM */
+#define        R367TER_RCFSTATESM      0xf220
+#define        F367TER_RCRSTATE_F      0xf2200080
+#define        F367TER_RCRSTATE_E      0xf2200040
+#define        F367TER_RCRSTATE_D      0xf2200020
+#define        F367TER_RCRSTATE_C      0xf2200010
+#define        F367TER_RCRSTATE_B      0xf2200008
+#define        F367TER_RCRSTATE_A      0xf2200004
+#define        F367TER_RCRSTATE_9      0xf2200002
+#define        F367TER_RCRSTATE_8      0xf2200001
+
+/* RCFSTATESL */
+#define        R367TER_RCFSTATESL      0xf221
+#define        F367TER_RCRSTATE_7      0xf2210080
+#define        F367TER_RCRSTATE_6      0xf2210040
+#define        F367TER_RCRSTATE_5      0xf2210020
+#define        F367TER_RCRSTATE_4      0xf2210010
+#define        F367TER_RCRSTATE_3      0xf2210008
+#define        F367TER_RCRSTATE_2      0xf2210004
+#define        F367TER_RCRSTATE_1      0xf2210002
+#define        F367TER_RCRSTATE_0      0xf2210001
+
+/* RCFSPYBER */
+#define        R367TER_RCFSPYBER       0xf222
+#define        F367TER_RCFSPYBER_7     0xf2220080
+#define        F367TER_SPYRCOBS_XORREAD        0xf2220040
+#define        F367TER_FSPYRCBER_OBSMODE       0xf2220020
+#define        F367TER_FSPYRCBER_SYNCBYT       0xf2220010
+#define        F367TER_FSPYRCBER_UNSYNC        0xf2220008
+#define        F367TER_FSPYRCBER_CTIME 0xf2220007
+
+/* RCFSPYDISTM */
+#define        R367TER_RCFSPYDISTM     0xf223
+#define        F367TER_RCPKTTIME_DISTANCE_HI   0xf22300ff
+
+/* RCFSPYDISTL */
+#define        R367TER_RCFSPYDISTL     0xf224
+#define        F367TER_RCPKTTIME_DISTANCE_LO   0xf22400ff
+
+/* RCFSPYOBS7 */
+#define        R367TER_RCFSPYOBS7      0xf228
+#define        F367TER_RCSPYOBS_SPYFAIL        0xf2280080
+#define        F367TER_RCSPYOBS_SPYFAIL1       0xf2280040
+#define        F367TER_RCSPYOBS_ERROR  0xf2280020
+#define        F367TER_RCSPYOBS_STROUT 0xf2280010
+#define        F367TER_RCSPYOBS_RESULTSTATE1   0xf228000f
+
+/* RCFSPYOBS6 */
+#define        R367TER_RCFSPYOBS6      0xf229
+#define        F367TER_RCSPYOBS_RESULTSTATe0   0xf22900f0
+#define        F367TER_RCSPYOBS_RESULTSTATEM1  0xf229000f
+
+/* RCFSPYOBS5 */
+#define        R367TER_RCFSPYOBS5      0xf22a
+#define        F367TER_RCSPYOBS_BYTEOFPACKET1  0xf22a00ff
+
+/* RCFSPYOBS4 */
+#define        R367TER_RCFSPYOBS4      0xf22b
+#define        F367TER_RCSPYOBS_BYTEVALUE1     0xf22b00ff
+
+/* RCFSPYOBS3 */
+#define        R367TER_RCFSPYOBS3      0xf22c
+#define        F367TER_RCSPYOBS_DATA1  0xf22c00ff
+
+/* RCFSPYOBS2 */
+#define        R367TER_RCFSPYOBS2      0xf22d
+#define        F367TER_RCSPYOBS_DATa0  0xf22d00ff
+
+/* RCFSPYOBS1 */
+#define        R367TER_RCFSPYOBS1      0xf22e
+#define        F367TER_RCSPYOBS_DATAM1 0xf22e00ff
+
+/* RCFSPYOBS0 */
+#define        R367TER_RCFSPYOBS0      0xf22f
+#define        F367TER_RCSPYOBS_DATAM2 0xf22f00ff
+
+/* TSGENERAL */
+#define        R367TER_TSGENERAL       0xf230
+#define        F367TER_TSGENERAL_7     0xf2300080
+#define        F367TER_TSGENERAL_6     0xf2300040
+#define        F367TER_TSFIFO_BCLK1aLL 0xf2300020
+#define        F367TER_TSGENERAL_4     0xf2300010
+#define        F367TER_MUXSTREAM_OUTMODE       0xf2300008
+#define        F367TER_TSFIFO_PERMPARAL        0xf2300006
+#define        F367TER_RST_REEDSOLO    0xf2300001
+
+/* RC1SPEED */
+#define        R367TER_RC1SPEED        0xf231
+#define        F367TER_TSRCFIFO1_OUTSPEED      0xf23100ff
+
+/* TSGSTATUS */
+#define        R367TER_TSGSTATUS       0xf232
+#define        F367TER_TSGSTATUS_7     0xf2320080
+#define        F367TER_TSGSTATUS_6     0xf2320040
+#define        F367TER_RSMEM_FULL      0xf2320020
+#define        F367TER_RS_MULTCALC     0xf2320010
+#define        F367TER_RSIN_OVERTIME   0xf2320008
+#define        F367TER_TSFIFO3_DEMODSEL        0xf2320004
+#define        F367TER_TSFIFO2_DEMODSEL        0xf2320002
+#define        F367TER_TSFIFO1_DEMODSEL        0xf2320001
+
+
+/* FECM */
+#define        R367TER_FECM    0xf233
+#define        F367TER_DSS_DVB 0xf2330080
+#define        F367TER_DEMOD_BYPASS    0xf2330040
+#define        F367TER_CMP_SLOWMODE    0xf2330020
+#define        F367TER_DSS_SRCH        0xf2330010
+#define        F367TER_FECM_3  0xf2330008
+#define        F367TER_DIFF_MODEVIT    0xf2330004
+#define        F367TER_SYNCVIT 0xf2330002
+#define        F367TER_I2CSYM  0xf2330001
+
+/* VTH12 */
+#define        R367TER_VTH12   0xf234
+#define        F367TER_VTH_12  0xf23400ff
+
+/* VTH23 */
+#define        R367TER_VTH23   0xf235
+#define        F367TER_VTH_23  0xf23500ff
+
+/* VTH34 */
+#define        R367TER_VTH34   0xf236
+#define        F367TER_VTH_34  0xf23600ff
+
+/* VTH56 */
+#define        R367TER_VTH56   0xf237
+#define        F367TER_VTH_56  0xf23700ff
+
+/* VTH67 */
+#define        R367TER_VTH67   0xf238
+#define        F367TER_VTH_67  0xf23800ff
+
+/* VTH78 */
+#define        R367TER_VTH78   0xf239
+#define        F367TER_VTH_78  0xf23900ff
+
+/* VITCURPUN */
+#define        R367TER_VITCURPUN       0xf23a
+#define        F367TER_VIT_MAPPING     0xf23a00e0
+#define        F367TER_VIT_CURPUN      0xf23a001f
+
+/* VERROR */
+#define        R367TER_VERROR  0xf23b
+#define        F367TER_REGERR_VIT      0xf23b00ff
+
+/* PRVIT */
+#define        R367TER_PRVIT   0xf23c
+#define        F367TER_PRVIT_7 0xf23c0080
+#define        F367TER_DIS_VTHLOCK     0xf23c0040
+#define        F367TER_E7_8VIT 0xf23c0020
+#define        F367TER_E6_7VIT 0xf23c0010
+#define        F367TER_E5_6VIT 0xf23c0008
+#define        F367TER_E3_4VIT 0xf23c0004
+#define        F367TER_E2_3VIT 0xf23c0002
+#define        F367TER_E1_2VIT 0xf23c0001
+
+/* VAVSRVIT */
+#define        R367TER_VAVSRVIT        0xf23d
+#define        F367TER_AMVIT   0xf23d0080
+#define        F367TER_FROZENVIT       0xf23d0040
+#define        F367TER_SNVIT   0xf23d0030
+#define        F367TER_TOVVIT  0xf23d000c
+#define        F367TER_HYPVIT  0xf23d0003
+
+/* VSTATUSVIT */
+#define        R367TER_VSTATUSVIT      0xf23e
+#define        F367TER_VITERBI_ON      0xf23e0080
+#define        F367TER_END_LOOPVIT     0xf23e0040
+#define        F367TER_VITERBI_DEPRF   0xf23e0020
+#define        F367TER_PRFVIT  0xf23e0010
+#define        F367TER_LOCKEDVIT       0xf23e0008
+#define        F367TER_VITERBI_DELOCK  0xf23e0004
+#define        F367TER_VIT_DEMODSEL    0xf23e0002
+#define        F367TER_VITERBI_COMPOUT 0xf23e0001
+
+/* VTHINUSE */
+#define        R367TER_VTHINUSE        0xf23f
+#define        F367TER_VIT_INUSE       0xf23f00ff
+
+/* KDIV12 */
+#define        R367TER_KDIV12  0xf240
+#define        F367TER_KDIV12_MANUAL   0xf2400080
+#define        F367TER_K_DIVIDER_12    0xf240007f
+
+/* KDIV23 */
+#define        R367TER_KDIV23  0xf241
+#define        F367TER_KDIV23_MANUAL   0xf2410080
+#define        F367TER_K_DIVIDER_23    0xf241007f
+
+/* KDIV34 */
+#define        R367TER_KDIV34  0xf242
+#define        F367TER_KDIV34_MANUAL   0xf2420080
+#define        F367TER_K_DIVIDER_34    0xf242007f
+
+/* KDIV56 */
+#define        R367TER_KDIV56  0xf243
+#define        F367TER_KDIV56_MANUAL   0xf2430080
+#define        F367TER_K_DIVIDER_56    0xf243007f
+
+/* KDIV67 */
+#define        R367TER_KDIV67  0xf244
+#define        F367TER_KDIV67_MANUAL   0xf2440080
+#define        F367TER_K_DIVIDER_67    0xf244007f
+
+/* KDIV78 */
+#define        R367TER_KDIV78  0xf245
+#define        F367TER_KDIV78_MANUAL   0xf2450080
+#define        F367TER_K_DIVIDER_78    0xf245007f
+
+/* SIGPOWER */
+#define        R367TER_SIGPOWER        0xf246
+#define        F367TER_SIGPOWER_MANUAL 0xf2460080
+#define        F367TER_SIG_POWER       0xf246007f
+
+/* DEMAPVIT */
+#define        R367TER_DEMAPVIT        0xf247
+#define        F367TER_DEMAPVIT_7      0xf2470080
+#define        F367TER_K_DIVIDER_VIT   0xf247007f
+
+/* VITSCALE */
+#define        R367TER_VITSCALE        0xf248
+#define        F367TER_NVTH_NOSRANGE   0xf2480080
+#define        F367TER_VERROR_MAXMODE  0xf2480040
+#define        F367TER_KDIV_MODE       0xf2480030
+#define        F367TER_NSLOWSN_LOCKED  0xf2480008
+#define        F367TER_DELOCK_PRFLOSS  0xf2480004
+#define        F367TER_DIS_RSFLOCK     0xf2480002
+#define        F367TER_VITSCALE_0      0xf2480001
+
+/* FFEC1PRG */
+#define        R367TER_FFEC1PRG        0xf249
+#define        F367TER_FDSS_DVB        0xf2490080
+#define        F367TER_FDSS_SRCH       0xf2490040
+#define        F367TER_FFECPROG_5      0xf2490020
+#define        F367TER_FFECPROG_4      0xf2490010
+#define        F367TER_FFECPROG_3      0xf2490008
+#define        F367TER_FFECPROG_2      0xf2490004
+#define        F367TER_FTS1_DISABLE    0xf2490002
+#define        F367TER_FTS2_DISABLE    0xf2490001
+
+/* FVITCURPUN */
+#define        R367TER_FVITCURPUN      0xf24a
+#define        F367TER_FVIT_MAPPING    0xf24a00e0
+#define        F367TER_FVIT_CURPUN     0xf24a001f
+
+/* FVERROR */
+#define        R367TER_FVERROR 0xf24b
+#define        F367TER_FREGERR_VIT     0xf24b00ff
+
+/* FVSTATUSVIT */
+#define        R367TER_FVSTATUSVIT     0xf24c
+#define        F367TER_FVITERBI_ON     0xf24c0080
+#define        F367TER_F1END_LOOPVIT   0xf24c0040
+#define        F367TER_FVITERBI_DEPRF  0xf24c0020
+#define        F367TER_FPRFVIT 0xf24c0010
+#define        F367TER_FLOCKEDVIT      0xf24c0008
+#define        F367TER_FVITERBI_DELOCK 0xf24c0004
+#define        F367TER_FVIT_DEMODSEL   0xf24c0002
+#define        F367TER_FVITERBI_COMPOUT        0xf24c0001
+
+/* DEBUG_LT1 */
+#define        R367TER_DEBUG_LT1       0xf24d
+#define        F367TER_DBG_LT1 0xf24d00ff
+
+/* DEBUG_LT2 */
+#define        R367TER_DEBUG_LT2       0xf24e
+#define        F367TER_DBG_LT2 0xf24e00ff
+
+/* DEBUG_LT3 */
+#define        R367TER_DEBUG_LT3       0xf24f
+#define        F367TER_DBG_LT3 0xf24f00ff
+
+/*     TSTSFMET */
+#define        R367TER_TSTSFMET        0xf250
+#define F367TER_TSTSFEC_METRIQUES      0xf25000ff
+
+/*     SELOUT */
+#define        R367TER_SELOUT  0xf252
+#define        F367TER_EN_SYNC 0xf2520080
+#define        F367TER_EN_TBUSDEMAP    0xf2520040
+#define        F367TER_SELOUT_5        0xf2520020
+#define        F367TER_SELOUT_4        0xf2520010
+#define        F367TER_TSTSYNCHRO_MODE 0xf2520002
+
+/*     TSYNC */
+#define R367TER_TSYNC  0xf253
+#define F367TER_CURPUN_INCMODE 0xf2530080
+#define F367TER_CERR_TSTMODE   0xf2530040
+#define F367TER_SHIFTSOF_MODE  0xf2530030
+#define F367TER_SLOWPHA_MODE   0xf2530008
+#define F367TER_PXX_BYPALL     0xf2530004
+#define F367TER_FROTA45_FIRST  0xf2530002
+#define F367TER_TST_BCHERROR   0xf2530001
+
+/*     TSTERR */
+#define R367TER_TSTERR 0xf254
+#define F367TER_TST_LONGPKT    0xf2540080
+#define F367TER_TST_ISSYION    0xf2540040
+#define F367TER_TST_NPDON      0xf2540020
+#define F367TER_TSTERR_4       0xf2540010
+#define F367TER_TRACEBACK_MODE 0xf2540008
+#define F367TER_TST_RSPARITY   0xf2540004
+#define F367TER_METRIQUE_MODE  0xf2540003
+
+/*     TSFSYNC */
+#define R367TER_TSFSYNC        0xf255
+#define F367TER_EN_SFECSYNC    0xf2550080
+#define F367TER_EN_SFECDEMAP   0xf2550040
+#define F367TER_SFCERR_TSTMODE 0xf2550020
+#define F367TER_SFECPXX_BYPALL 0xf2550010
+#define F367TER_SFECTSTSYNCHRO_MODE 0xf255000f
+
+/*     TSTSFERR */
+#define R367TER_TSTSFERR       0xf256
+#define F367TER_TSTSTERR_7     0xf2560080
+#define F367TER_TSTSTERR_6     0xf2560040
+#define F367TER_TSTSTERR_5     0xf2560020
+#define F367TER_TSTSTERR_4     0xf2560010
+#define F367TER_SFECTRACEBACK_MODE     0xf2560008
+#define F367TER_SFEC_NCONVPROG 0xf2560004
+#define F367TER_SFECMETRIQUE_MODE      0xf2560003
+
+/*     TSTTSSF1 */
+#define R367TER_TSTTSSF1       0xf258
+#define F367TER_TSTERSSF       0xf2580080
+#define F367TER_TSTTSSFEN      0xf2580040
+#define F367TER_SFEC_OUTMODE   0xf2580030
+#define F367TER_XLSF_NOFTHRESHOLD  0xf2580008
+#define F367TER_TSTTSSF_STACKSEL       0xf2580007
+
+/*     TSTTSSF2 */
+#define R367TER_TSTTSSF2       0xf259
+#define F367TER_DILSF_DBBHEADER        0xf2590080
+#define F367TER_TSTTSSF_DISBUG 0xf2590040
+#define F367TER_TSTTSSF_NOBADSTART     0xf2590020
+#define F367TER_TSTTSSF_SELECT 0xf259001f
+
+/*     TSTTSSF3 */
+#define R367TER_TSTTSSF3       0xf25a
+#define F367TER_TSTTSSF3_7     0xf25a0080
+#define F367TER_TSTTSSF3_6     0xf25a0040
+#define F367TER_TSTTSSF3_5     0xf25a0020
+#define F367TER_TSTTSSF3_4     0xf25a0010
+#define F367TER_TSTTSSF3_3     0xf25a0008
+#define F367TER_TSTTSSF3_2     0xf25a0004
+#define F367TER_TSTTSSF3_1     0xf25a0002
+#define F367TER_DISSF_CLKENABLE        0xf25a0001
+
+/*     TSTTS1 */
+#define R367TER_TSTTS1 0xf25c
+#define F367TER_TSTERS 0xf25c0080
+#define F367TER_TSFIFO_DSSSYNCB        0xf25c0040
+#define F367TER_TSTTS_FSPYBEFRS        0xf25c0020
+#define F367TER_NFORCE_SYNCBYTE        0xf25c0010
+#define F367TER_XL_NOFTHRESHOLD        0xf25c0008
+#define F367TER_TSTTS_FRFORCEPKT       0xf25c0004
+#define F367TER_DESCR_NOTAUTO  0xf25c0002
+#define F367TER_TSTTSEN        0xf25c0001
+
+/*     TSTTS2 */
+#define R367TER_TSTTS2 0xf25d
+#define F367TER_DIL_DBBHEADER  0xf25d0080
+#define F367TER_TSTTS_NOBADXXX 0xf25d0040
+#define F367TER_TSFIFO_DELSPEEDUP      0xf25d0020
+#define F367TER_TSTTS_SELECT   0xf25d001f
+
+/*     TSTTS3 */
+#define R367TER_TSTTS3 0xf25e
+#define F367TER_TSTTS_NOPKTGAIN        0xf25e0080
+#define F367TER_TSTTS_NOPKTENE 0xf25e0040
+#define F367TER_TSTTS_ISOLATION        0xf25e0020
+#define F367TER_TSTTS_DISBUG   0xf25e0010
+#define F367TER_TSTTS_NOBADSTART       0xf25e0008
+#define F367TER_TSTTS_STACKSEL 0xf25e0007
+
+/*     TSTTS4 */
+#define R367TER_TSTTS4 0xf25f
+#define F367TER_TSTTS4_7       0xf25f0080
+#define F367TER_TSTTS4_6       0xf25f0040
+#define F367TER_TSTTS4_5       0xf25f0020
+#define F367TER_TSTTS_DISDSTATE        0xf25f0010
+#define F367TER_TSTTS_FASTNOSYNC       0xf25f0008
+#define F367TER_EXT_FECSPYIN   0xf25f0004
+#define F367TER_TSTTS_NODPZERO 0xf25f0002
+#define F367TER_TSTTS_NODIV3   0xf25f0001
+
+/*     TSTTSRC */
+#define R367TER_TSTTSRC        0xf26c
+#define F367TER_TSTTSRC_7      0xf26c0080
+#define F367TER_TSRCFIFO_DSSSYNCB      0xf26c0040
+#define F367TER_TSRCFIFO_DPUNACTIVE    0xf26c0020
+#define F367TER_TSRCFIFO_DELSPEEDUP    0xf26c0010
+#define F367TER_TSTTSRC_NODIV3 0xf26c0008
+#define F367TER_TSTTSRC_FRFORCEPKT     0xf26c0004
+#define F367TER_SAT25_SDDORIGINE       0xf26c0002
+#define F367TER_TSTTSRC_INACTIVE       0xf26c0001
+
+/*     TSTTSRS */
+#define R367TER_TSTTSRS        0xf26d
+#define F367TER_TSTTSRS_7      0xf26d0080
+#define F367TER_TSTTSRS_6      0xf26d0040
+#define F367TER_TSTTSRS_5      0xf26d0020
+#define F367TER_TSTTSRS_4      0xf26d0010
+#define F367TER_TSTTSRS_3      0xf26d0008
+#define F367TER_TSTTSRS_2      0xf26d0004
+#define F367TER_TSTRS_DISRS2   0xf26d0002
+#define F367TER_TSTRS_DISRS1   0xf26d0001
+
+/* TSSTATEM */
+#define        R367TER_TSSTATEM        0xf270
+#define        F367TER_TSDIL_ON        0xf2700080
+#define        F367TER_TSSKIPRS_ON     0xf2700040
+#define        F367TER_TSRS_ON 0xf2700020
+#define        F367TER_TSDESCRAMB_ON   0xf2700010
+#define        F367TER_TSFRAME_MODE    0xf2700008
+#define        F367TER_TS_DISABLE      0xf2700004
+#define        F367TER_TSACM_MODE      0xf2700002
+#define        F367TER_TSOUT_NOSYNC    0xf2700001
+
+/* TSSTATEL */
+#define        R367TER_TSSTATEL        0xf271
+#define        F367TER_TSNOSYNCBYTE    0xf2710080
+#define        F367TER_TSPARITY_ON     0xf2710040
+#define        F367TER_TSSYNCOUTRS_ON  0xf2710020
+#define        F367TER_TSDVBS2_MODE    0xf2710010
+#define        F367TER_TSISSYI_ON      0xf2710008
+#define        F367TER_TSNPD_ON        0xf2710004
+#define        F367TER_TSCRC8_ON       0xf2710002
+#define        F367TER_TSDSS_PACKET    0xf2710001
+
+/* TSCFGH */
+#define        R367TER_TSCFGH  0xf272
+#define        F367TER_TSFIFO_DVBCI    0xf2720080
+#define        F367TER_TSFIFO_SERIAL   0xf2720040
+#define        F367TER_TSFIFO_TEIUPDATE        0xf2720020
+#define        F367TER_TSFIFO_DUTY50   0xf2720010
+#define        F367TER_TSFIFO_HSGNLOUT 0xf2720008
+#define        F367TER_TSFIFO_ERRMODE  0xf2720006
+#define        F367TER_RST_HWARE       0xf2720001
+
+/* TSCFGM */
+#define        R367TER_TSCFGM  0xf273
+#define        F367TER_TSFIFO_MANSPEED 0xf27300c0
+#define        F367TER_TSFIFO_PERMDATA 0xf2730020
+#define        F367TER_TSFIFO_NONEWSGNL        0xf2730010
+#define        F367TER_TSFIFO_BITSPEED 0xf2730008
+#define        F367TER_NPD_SPECDVBS2   0xf2730004
+#define        F367TER_TSFIFO_STOPCKDIS        0xf2730002
+#define        F367TER_TSFIFO_INVDATA  0xf2730001
+
+/* TSCFGL */
+#define        R367TER_TSCFGL  0xf274
+#define        F367TER_TSFIFO_BCLKDEL1cK       0xf27400c0
+#define        F367TER_BCHERROR_MODE   0xf2740030
+#define        F367TER_TSFIFO_NSGNL2dATA       0xf2740008
+#define        F367TER_TSFIFO_EMBINDVB 0xf2740004
+#define        F367TER_TSFIFO_DPUNACT  0xf2740002
+#define        F367TER_TSFIFO_NPDOFF   0xf2740001
+
+/* TSSYNC */
+#define        R367TER_TSSYNC  0xf275
+#define        F367TER_TSFIFO_PERMUTE  0xf2750080
+#define        F367TER_TSFIFO_FISCR3B  0xf2750060
+#define        F367TER_TSFIFO_SYNCMODE 0xf2750018
+#define        F367TER_TSFIFO_SYNCSEL  0xf2750007
+
+/* TSINSDELH */
+#define        R367TER_TSINSDELH       0xf276
+#define        F367TER_TSDEL_SYNCBYTE  0xf2760080
+#define        F367TER_TSDEL_XXHEADER  0xf2760040
+#define        F367TER_TSDEL_BBHEADER  0xf2760020
+#define        F367TER_TSDEL_DATAFIELD 0xf2760010
+#define        F367TER_TSINSDEL_ISCR   0xf2760008
+#define        F367TER_TSINSDEL_NPD    0xf2760004
+#define        F367TER_TSINSDEL_RSPARITY       0xf2760002
+#define        F367TER_TSINSDEL_CRC8   0xf2760001
+
+/* TSINSDELM */
+#define        R367TER_TSINSDELM       0xf277
+#define        F367TER_TSINS_BBPADDING 0xf2770080
+#define        F367TER_TSINS_BCHFEC    0xf2770040
+#define        F367TER_TSINS_LDPCFEC   0xf2770020
+#define        F367TER_TSINS_EMODCOD   0xf2770010
+#define        F367TER_TSINS_TOKEN     0xf2770008
+#define        F367TER_TSINS_XXXERR    0xf2770004
+#define        F367TER_TSINS_MATYPE    0xf2770002
+#define        F367TER_TSINS_UPL       0xf2770001
+
+/* TSINSDELL */
+#define        R367TER_TSINSDELL       0xf278
+#define        F367TER_TSINS_DFL       0xf2780080
+#define        F367TER_TSINS_SYNCD     0xf2780040
+#define        F367TER_TSINS_BLOCLEN   0xf2780020
+#define        F367TER_TSINS_SIGPCOUNT 0xf2780010
+#define        F367TER_TSINS_FIFO      0xf2780008
+#define        F367TER_TSINS_REALPACK  0xf2780004
+#define        F367TER_TSINS_TSCONFIG  0xf2780002
+#define        F367TER_TSINS_LATENCY   0xf2780001
+
+/* TSDIVN */
+#define        R367TER_TSDIVN  0xf279
+#define        F367TER_TSFIFO_LOWSPEED 0xf2790080
+#define        F367TER_BYTE_OVERSAMPLING       0xf2790070
+#define        F367TER_TSMANUAL_PACKETNBR      0xf279000f
+
+/* TSDIVPM */
+#define        R367TER_TSDIVPM 0xf27a
+#define        F367TER_TSMANUAL_P_HI   0xf27a00ff
+
+/* TSDIVPL */
+#define        R367TER_TSDIVPL 0xf27b
+#define        F367TER_TSMANUAL_P_LO   0xf27b00ff
+
+/* TSDIVQM */
+#define        R367TER_TSDIVQM 0xf27c
+#define        F367TER_TSMANUAL_Q_HI   0xf27c00ff
+
+/* TSDIVQL */
+#define        R367TER_TSDIVQL 0xf27d
+#define        F367TER_TSMANUAL_Q_LO   0xf27d00ff
+
+/* TSDILSTKM */
+#define        R367TER_TSDILSTKM       0xf27e
+#define        F367TER_TSFIFO_DILSTK_HI        0xf27e00ff
+
+/* TSDILSTKL */
+#define        R367TER_TSDILSTKL       0xf27f
+#define        F367TER_TSFIFO_DILSTK_LO        0xf27f00ff
+
+/* TSSPEED */
+#define        R367TER_TSSPEED 0xf280
+#define        F367TER_TSFIFO_OUTSPEED 0xf28000ff
+
+/* TSSTATUS */
+#define        R367TER_TSSTATUS        0xf281
+#define        F367TER_TSFIFO_LINEOK   0xf2810080
+#define        F367TER_TSFIFO_ERROR    0xf2810040
+#define        F367TER_TSFIFO_DATA7    0xf2810020
+#define        F367TER_TSFIFO_NOSYNC   0xf2810010
+#define        F367TER_ISCR_INITIALIZED        0xf2810008
+#define        F367TER_ISCR_UPDATED    0xf2810004
+#define        F367TER_SOFFIFO_UNREGUL 0xf2810002
+#define        F367TER_DIL_READY       0xf2810001
+
+/* TSSTATUS2 */
+#define        R367TER_TSSTATUS2       0xf282
+#define        F367TER_TSFIFO_DEMODSEL 0xf2820080
+#define        F367TER_TSFIFOSPEED_STORE       0xf2820040
+#define        F367TER_DILXX_RESET     0xf2820020
+#define        F367TER_TSSERIAL_IMPOSSIBLE     0xf2820010
+#define        F367TER_TSFIFO_UNDERSPEED       0xf2820008
+#define        F367TER_BITSPEED_EVENT  0xf2820004
+#define        F367TER_UL_SCRAMBDETECT 0xf2820002
+#define        F367TER_ULDTV67_FALSELOCK       0xf2820001
+
+/* TSBITRATEM */
+#define        R367TER_TSBITRATEM      0xf283
+#define        F367TER_TSFIFO_BITRATE_HI       0xf28300ff
+
+/* TSBITRATEL */
+#define        R367TER_TSBITRATEL      0xf284
+#define        F367TER_TSFIFO_BITRATE_LO       0xf28400ff
+
+/* TSPACKLENM */
+#define        R367TER_TSPACKLENM      0xf285
+#define        F367TER_TSFIFO_PACKCPT  0xf28500e0
+#define        F367TER_DIL_RPLEN_HI    0xf285001f
+
+/* TSPACKLENL */
+#define        R367TER_TSPACKLENL      0xf286
+#define        F367TER_DIL_RPLEN_LO    0xf28600ff
+
+/* TSBLOCLENM */
+#define        R367TER_TSBLOCLENM      0xf287
+#define        F367TER_TSFIFO_PFLEN_HI 0xf28700ff
+
+/* TSBLOCLENL */
+#define        R367TER_TSBLOCLENL      0xf288
+#define        F367TER_TSFIFO_PFLEN_LO 0xf28800ff
+
+/* TSDLYH */
+#define        R367TER_TSDLYH  0xf289
+#define        F367TER_SOFFIFO_TSTIMEVALID     0xf2890080
+#define        F367TER_SOFFIFO_SPEEDUP 0xf2890040
+#define        F367TER_SOFFIFO_STOP    0xf2890020
+#define        F367TER_SOFFIFO_REGULATED       0xf2890010
+#define        F367TER_SOFFIFO_REALSBOFF_HI    0xf289000f
+
+/* TSDLYM */
+#define        R367TER_TSDLYM  0xf28a
+#define        F367TER_SOFFIFO_REALSBOFF_MED   0xf28a00ff
+
+/* TSDLYL */
+#define        R367TER_TSDLYL  0xf28b
+#define        F367TER_SOFFIFO_REALSBOFF_LO    0xf28b00ff
+
+/* TSNPDAV */
+#define        R367TER_TSNPDAV 0xf28c
+#define        F367TER_TSNPD_AVERAGE   0xf28c00ff
+
+/* TSBUFSTATH */
+#define        R367TER_TSBUFSTATH      0xf28d
+#define        F367TER_TSISCR_3BYTES   0xf28d0080
+#define        F367TER_TSISCR_NEWDATA  0xf28d0040
+#define        F367TER_TSISCR_BUFSTAT_HI       0xf28d003f
+
+/* TSBUFSTATM */
+#define        R367TER_TSBUFSTATM      0xf28e
+#define        F367TER_TSISCR_BUFSTAT_MED      0xf28e00ff
+
+/* TSBUFSTATL */
+#define        R367TER_TSBUFSTATL      0xf28f
+#define        F367TER_TSISCR_BUFSTAT_LO       0xf28f00ff
+
+/* TSDEBUGM */
+#define        R367TER_TSDEBUGM        0xf290
+#define        F367TER_TSFIFO_ILLPACKET        0xf2900080
+#define        F367TER_DIL_NOSYNC      0xf2900040
+#define        F367TER_DIL_ISCR        0xf2900020
+#define        F367TER_DILOUT_BSYNCB   0xf2900010
+#define        F367TER_TSFIFO_EMPTYPKT 0xf2900008
+#define        F367TER_TSFIFO_EMPTYRD  0xf2900004
+#define        F367TER_SOFFIFO_STOPM   0xf2900002
+#define        F367TER_SOFFIFO_SPEEDUPM        0xf2900001
+
+/* TSDEBUGL */
+#define        R367TER_TSDEBUGL        0xf291
+#define        F367TER_TSFIFO_PACKLENFAIL      0xf2910080
+#define        F367TER_TSFIFO_SYNCBFAIL        0xf2910040
+#define        F367TER_TSFIFO_VITLIBRE 0xf2910020
+#define        F367TER_TSFIFO_BOOSTSPEEDM      0xf2910010
+#define        F367TER_TSFIFO_UNDERSPEEDM      0xf2910008
+#define        F367TER_TSFIFO_ERROR_EVNT       0xf2910004
+#define        F367TER_TSFIFO_FULL     0xf2910002
+#define        F367TER_TSFIFO_OVERFLOWM        0xf2910001
+
+/* TSDLYSETH */
+#define        R367TER_TSDLYSETH       0xf292
+#define        F367TER_SOFFIFO_OFFSET  0xf29200e0
+#define        F367TER_SOFFIFO_SYMBOFFSET_HI   0xf292001f
+
+/* TSDLYSETM */
+#define        R367TER_TSDLYSETM       0xf293
+#define        F367TER_SOFFIFO_SYMBOFFSET_MED  0xf29300ff
+
+/* TSDLYSETL */
+#define        R367TER_TSDLYSETL       0xf294
+#define        F367TER_SOFFIFO_SYMBOFFSET_LO   0xf29400ff
+
+/* TSOBSCFG */
+#define        R367TER_TSOBSCFG        0xf295
+#define        F367TER_TSFIFO_OBSCFG   0xf29500ff
+
+/* TSOBSM */
+#define        R367TER_TSOBSM  0xf296
+#define        F367TER_TSFIFO_OBSDATA_HI       0xf29600ff
+
+/* TSOBSL */
+#define        R367TER_TSOBSL  0xf297
+#define        F367TER_TSFIFO_OBSDATA_LO       0xf29700ff
+
+/* ERRCTRL1 */
+#define        R367TER_ERRCTRL1        0xf298
+#define        F367TER_ERR_SRC1        0xf29800f0
+#define        F367TER_ERRCTRL1_3      0xf2980008
+#define        F367TER_NUM_EVT1        0xf2980007
+
+/* ERRCNT1H */
+#define        R367TER_ERRCNT1H        0xf299
+#define        F367TER_ERRCNT1_OLDVALUE        0xf2990080
+#define        F367TER_ERR_CNT1        0xf299007f
+
+/* ERRCNT1M */
+#define        R367TER_ERRCNT1M        0xf29a
+#define        F367TER_ERR_CNT1_HI     0xf29a00ff
+
+/* ERRCNT1L */
+#define        R367TER_ERRCNT1L        0xf29b
+#define        F367TER_ERR_CNT1_LO     0xf29b00ff
+
+/* ERRCTRL2 */
+#define        R367TER_ERRCTRL2        0xf29c
+#define        F367TER_ERR_SRC2        0xf29c00f0
+#define        F367TER_ERRCTRL2_3      0xf29c0008
+#define        F367TER_NUM_EVT2        0xf29c0007
+
+/* ERRCNT2H */
+#define        R367TER_ERRCNT2H        0xf29d
+#define        F367TER_ERRCNT2_OLDVALUE        0xf29d0080
+#define        F367TER_ERR_CNT2_HI     0xf29d007f
+
+/* ERRCNT2M */
+#define        R367TER_ERRCNT2M        0xf29e
+#define        F367TER_ERR_CNT2_MED    0xf29e00ff
+
+/* ERRCNT2L */
+#define        R367TER_ERRCNT2L        0xf29f
+#define        F367TER_ERR_CNT2_LO     0xf29f00ff
+
+/* FECSPY */
+#define        R367TER_FECSPY  0xf2a0
+#define        F367TER_SPY_ENABLE      0xf2a00080
+#define        F367TER_NO_SYNCBYTE     0xf2a00040
+#define        F367TER_SERIAL_MODE     0xf2a00020
+#define        F367TER_UNUSUAL_PACKET  0xf2a00010
+#define        F367TER_BERMETER_DATAMODE       0xf2a0000c
+#define        F367TER_BERMETER_LMODE  0xf2a00002
+#define        F367TER_BERMETER_RESET  0xf2a00001
+
+/* FSPYCFG */
+#define        R367TER_FSPYCFG 0xf2a1
+#define        F367TER_FECSPY_INPUT    0xf2a100c0
+#define        F367TER_RST_ON_ERROR    0xf2a10020
+#define        F367TER_ONE_SHOT        0xf2a10010
+#define        F367TER_I2C_MOD 0xf2a1000c
+#define        F367TER_SPY_HYSTERESIS  0xf2a10003
+
+/* FSPYDATA */
+#define        R367TER_FSPYDATA        0xf2a2
+#define        F367TER_SPY_STUFFING    0xf2a20080
+#define        F367TER_NOERROR_PKTJITTER       0xf2a20040
+#define        F367TER_SPY_CNULLPKT    0xf2a20020
+#define        F367TER_SPY_OUTDATA_MODE        0xf2a2001f
+
+/* FSPYOUT */
+#define        R367TER_FSPYOUT 0xf2a3
+#define        F367TER_FSPY_DIRECT     0xf2a30080
+#define        F367TER_FSPYOUT_6       0xf2a30040
+#define        F367TER_SPY_OUTDATA_BUS 0xf2a30038
+#define        F367TER_STUFF_MODE      0xf2a30007
+
+/* FSTATUS */
+#define        R367TER_FSTATUS 0xf2a4
+#define        F367TER_SPY_ENDSIM      0xf2a40080
+#define        F367TER_VALID_SIM       0xf2a40040
+#define        F367TER_FOUND_SIGNAL    0xf2a40020
+#define        F367TER_DSS_SYNCBYTE    0xf2a40010
+#define        F367TER_RESULT_STATE    0xf2a4000f
+
+/* FGOODPACK */
+#define        R367TER_FGOODPACK       0xf2a5
+#define        F367TER_FGOOD_PACKET    0xf2a500ff
+
+/* FPACKCNT */
+#define        R367TER_FPACKCNT        0xf2a6
+#define        F367TER_FPACKET_COUNTER 0xf2a600ff
+
+/* FSPYMISC */
+#define        R367TER_FSPYMISC        0xf2a7
+#define        F367TER_FLABEL_COUNTER  0xf2a700ff
+
+/* FBERCPT4 */
+#define        R367TER_FBERCPT4        0xf2a8
+#define        F367TER_FBERMETER_CPT5  0xf2a800ff
+
+/* FBERCPT3 */
+#define        R367TER_FBERCPT3        0xf2a9
+#define        F367TER_FBERMETER_CPT4  0xf2a900ff
+
+/* FBERCPT2 */
+#define        R367TER_FBERCPT2        0xf2aa
+#define        F367TER_FBERMETER_CPT3  0xf2aa00ff
+
+/* FBERCPT1 */
+#define        R367TER_FBERCPT1        0xf2ab
+#define        F367TER_FBERMETER_CPT2  0xf2ab00ff
+
+/* FBERCPT0 */
+#define        R367TER_FBERCPT0        0xf2ac
+#define        F367TER_FBERMETER_CPT1  0xf2ac00ff
+
+/* FBERERR2 */
+#define        R367TER_FBERERR2        0xf2ad
+#define        F367TER_FBERMETER_ERR_HI        0xf2ad00ff
+
+/* FBERERR1 */
+#define        R367TER_FBERERR1        0xf2ae
+#define        F367TER_FBERMETER_ERR_MED       0xf2ae00ff
+
+/* FBERERR0 */
+#define        R367TER_FBERERR0        0xf2af
+#define        F367TER_FBERMETER_ERR_LO        0xf2af00ff
+
+/* FSTATESM */
+#define        R367TER_FSTATESM        0xf2b0
+#define        F367TER_RSTATE_F        0xf2b00080
+#define        F367TER_RSTATE_E        0xf2b00040
+#define        F367TER_RSTATE_D        0xf2b00020
+#define        F367TER_RSTATE_C        0xf2b00010
+#define        F367TER_RSTATE_B        0xf2b00008
+#define        F367TER_RSTATE_A        0xf2b00004
+#define        F367TER_RSTATE_9        0xf2b00002
+#define        F367TER_RSTATE_8        0xf2b00001
+
+/* FSTATESL */
+#define        R367TER_FSTATESL        0xf2b1
+#define        F367TER_RSTATE_7        0xf2b10080
+#define        F367TER_RSTATE_6        0xf2b10040
+#define        F367TER_RSTATE_5        0xf2b10020
+#define        F367TER_RSTATE_4        0xf2b10010
+#define        F367TER_RSTATE_3        0xf2b10008
+#define        F367TER_RSTATE_2        0xf2b10004
+#define        F367TER_RSTATE_1        0xf2b10002
+#define        F367TER_RSTATE_0        0xf2b10001
+
+/* FSPYBER */
+#define        R367TER_FSPYBER 0xf2b2
+#define        F367TER_FSPYBER_7       0xf2b20080
+#define        F367TER_FSPYOBS_XORREAD 0xf2b20040
+#define        F367TER_FSPYBER_OBSMODE 0xf2b20020
+#define        F367TER_FSPYBER_SYNCBYTE        0xf2b20010
+#define        F367TER_FSPYBER_UNSYNC  0xf2b20008
+#define        F367TER_FSPYBER_CTIME   0xf2b20007
+
+/* FSPYDISTM */
+#define        R367TER_FSPYDISTM       0xf2b3
+#define        F367TER_PKTTIME_DISTANCE_HI     0xf2b300ff
+
+/* FSPYDISTL */
+#define        R367TER_FSPYDISTL       0xf2b4
+#define        F367TER_PKTTIME_DISTANCE_LO     0xf2b400ff
+
+/* FSPYOBS7 */
+#define        R367TER_FSPYOBS7        0xf2b8
+#define        F367TER_FSPYOBS_SPYFAIL 0xf2b80080
+#define        F367TER_FSPYOBS_SPYFAIL1        0xf2b80040
+#define        F367TER_FSPYOBS_ERROR   0xf2b80020
+#define        F367TER_FSPYOBS_STROUT  0xf2b80010
+#define        F367TER_FSPYOBS_RESULTSTATE1    0xf2b8000f
+
+/* FSPYOBS6 */
+#define        R367TER_FSPYOBS6        0xf2b9
+#define        F367TER_FSPYOBS_RESULTSTATe0    0xf2b900f0
+#define        F367TER_FSPYOBS_RESULTSTATEM1   0xf2b9000f
+
+/* FSPYOBS5 */
+#define        R367TER_FSPYOBS5        0xf2ba
+#define        F367TER_FSPYOBS_BYTEOFPACKET1   0xf2ba00ff
+
+/* FSPYOBS4 */
+#define        R367TER_FSPYOBS4        0xf2bb
+#define        F367TER_FSPYOBS_BYTEVALUE1      0xf2bb00ff
+
+/* FSPYOBS3 */
+#define        R367TER_FSPYOBS3        0xf2bc
+#define        F367TER_FSPYOBS_DATA1   0xf2bc00ff
+
+/* FSPYOBS2 */
+#define        R367TER_FSPYOBS2        0xf2bd
+#define        F367TER_FSPYOBS_DATa0   0xf2bd00ff
+
+/* FSPYOBS1 */
+#define        R367TER_FSPYOBS1        0xf2be
+#define        F367TER_FSPYOBS_DATAM1  0xf2be00ff
+
+/* FSPYOBS0 */
+#define        R367TER_FSPYOBS0        0xf2bf
+#define        F367TER_FSPYOBS_DATAM2  0xf2bf00ff
+
+/* SFDEMAP */
+#define        R367TER_SFDEMAP 0xf2c0
+#define        F367TER_SFDEMAP_7       0xf2c00080
+#define        F367TER_SFEC_K_DIVIDER_VIT      0xf2c0007f
+
+/* SFERROR */
+#define        R367TER_SFERROR 0xf2c1
+#define        F367TER_SFEC_REGERR_VIT 0xf2c100ff
+
+/* SFAVSR */
+#define        R367TER_SFAVSR  0xf2c2
+#define        F367TER_SFEC_SUMERRORS  0xf2c20080
+#define        F367TER_SERROR_MAXMODE  0xf2c20040
+#define        F367TER_SN_SFEC 0xf2c20030
+#define        F367TER_KDIV_MODE_SFEC  0xf2c2000c
+#define        F367TER_SFAVSR_1        0xf2c20002
+#define        F367TER_SFAVSR_0        0xf2c20001
+
+/* SFECSTATUS */
+#define        R367TER_SFECSTATUS      0xf2c3
+#define        F367TER_SFEC_ON 0xf2c30080
+#define        F367TER_SFSTATUS_6      0xf2c30040
+#define        F367TER_SFSTATUS_5      0xf2c30020
+#define        F367TER_SFSTATUS_4      0xf2c30010
+#define        F367TER_LOCKEDSFEC      0xf2c30008
+#define        F367TER_SFEC_DELOCK     0xf2c30004
+#define        F367TER_SFEC_DEMODSEL1  0xf2c30002
+#define        F367TER_SFEC_OVFON      0xf2c30001
+
+/* SFKDIV12 */
+#define        R367TER_SFKDIV12        0xf2c4
+#define        F367TER_SFECKDIV12_MAN  0xf2c40080
+#define        F367TER_SFEC_K_DIVIDER_12       0xf2c4007f
+
+/* SFKDIV23 */
+#define        R367TER_SFKDIV23        0xf2c5
+#define        F367TER_SFECKDIV23_MAN  0xf2c50080
+#define        F367TER_SFEC_K_DIVIDER_23       0xf2c5007f
+
+/* SFKDIV34 */
+#define        R367TER_SFKDIV34        0xf2c6
+#define        F367TER_SFECKDIV34_MAN  0xf2c60080
+#define        F367TER_SFEC_K_DIVIDER_34       0xf2c6007f
+
+/* SFKDIV56 */
+#define        R367TER_SFKDIV56        0xf2c7
+#define        F367TER_SFECKDIV56_MAN  0xf2c70080
+#define        F367TER_SFEC_K_DIVIDER_56       0xf2c7007f
+
+/* SFKDIV67 */
+#define        R367TER_SFKDIV67        0xf2c8
+#define        F367TER_SFECKDIV67_MAN  0xf2c80080
+#define        F367TER_SFEC_K_DIVIDER_67       0xf2c8007f
+
+/* SFKDIV78 */
+#define        R367TER_SFKDIV78        0xf2c9
+#define        F367TER_SFECKDIV78_MAN  0xf2c90080
+#define        F367TER_SFEC_K_DIVIDER_78       0xf2c9007f
+
+/* SFDILSTKM */
+#define        R367TER_SFDILSTKM       0xf2ca
+#define        F367TER_SFEC_PACKCPT    0xf2ca00e0
+#define        F367TER_SFEC_DILSTK_HI  0xf2ca001f
+
+/* SFDILSTKL */
+#define        R367TER_SFDILSTKL       0xf2cb
+#define        F367TER_SFEC_DILSTK_LO  0xf2cb00ff
+
+/* SFSTATUS */
+#define        R367TER_SFSTATUS        0xf2cc
+#define        F367TER_SFEC_LINEOK     0xf2cc0080
+#define        F367TER_SFEC_ERROR      0xf2cc0040
+#define        F367TER_SFEC_DATA7      0xf2cc0020
+#define        F367TER_SFEC_OVERFLOW   0xf2cc0010
+#define        F367TER_SFEC_DEMODSEL2  0xf2cc0008
+#define        F367TER_SFEC_NOSYNC     0xf2cc0004
+#define        F367TER_SFEC_UNREGULA   0xf2cc0002
+#define        F367TER_SFEC_READY      0xf2cc0001
+
+/* SFDLYH */
+#define        R367TER_SFDLYH  0xf2cd
+#define        F367TER_SFEC_TSTIMEVALID        0xf2cd0080
+#define        F367TER_SFEC_SPEEDUP    0xf2cd0040
+#define        F367TER_SFEC_STOP       0xf2cd0020
+#define        F367TER_SFEC_REGULATED  0xf2cd0010
+#define        F367TER_SFEC_REALSYMBOFFSET     0xf2cd000f
+
+/* SFDLYM */
+#define        R367TER_SFDLYM  0xf2ce
+#define        F367TER_SFEC_REALSYMBOFFSET_HI  0xf2ce00ff
+
+/* SFDLYL */
+#define        R367TER_SFDLYL  0xf2cf
+#define        F367TER_SFEC_REALSYMBOFFSET_LO  0xf2cf00ff
+
+/* SFDLYSETH */
+#define        R367TER_SFDLYSETH       0xf2d0
+#define        F367TER_SFEC_OFFSET     0xf2d000e0
+#define        F367TER_SFECDLYSETH_4   0xf2d00010
+#define        F367TER_RST_SFEC        0xf2d00008
+#define        F367TER_SFECDLYSETH_2   0xf2d00004
+#define        F367TER_SFEC_DISABLE    0xf2d00002
+#define        F367TER_SFEC_UNREGUL    0xf2d00001
+
+/* SFDLYSETM */
+#define        R367TER_SFDLYSETM       0xf2d1
+#define        F367TER_SFECDLYSETM_7   0xf2d10080
+#define        F367TER_SFEC_SYMBOFFSET_HI      0xf2d1007f
+
+/* SFDLYSETL */
+#define        R367TER_SFDLYSETL       0xf2d2
+#define        F367TER_SFEC_SYMBOFFSET_LO      0xf2d200ff
+
+/* SFOBSCFG */
+#define        R367TER_SFOBSCFG        0xf2d3
+#define        F367TER_SFEC_OBSCFG     0xf2d300ff
+
+/* SFOBSM */
+#define        R367TER_SFOBSM  0xf2d4
+#define        F367TER_SFEC_OBSDATA_HI 0xf2d400ff
+
+/* SFOBSL */
+#define        R367TER_SFOBSL  0xf2d5
+#define        F367TER_SFEC_OBSDATA_LO 0xf2d500ff
+
+/* SFECINFO */
+#define        R367TER_SFECINFO        0xf2d6
+#define        F367TER_SFECINFO_7      0xf2d60080
+#define        F367TER_SFEC_SYNCDLSB   0xf2d60070
+#define        F367TER_SFCE_S1cPHASE   0xf2d6000f
+
+/* SFERRCTRL */
+#define        R367TER_SFERRCTRL       0xf2d8
+#define        F367TER_SFEC_ERR_SOURCE 0xf2d800f0
+#define        F367TER_SFERRCTRL_3     0xf2d80008
+#define        F367TER_SFEC_NUM_EVENT  0xf2d80007
+
+/* SFERRCNTH */
+#define        R367TER_SFERRCNTH       0xf2d9
+#define        F367TER_SFERRC_OLDVALUE 0xf2d90080
+#define        F367TER_SFEC_ERR_CNT    0xf2d9007f
+
+/* SFERRCNTM */
+#define        R367TER_SFERRCNTM       0xf2da
+#define        F367TER_SFEC_ERR_CNT_HI 0xf2da00ff
+
+/* SFERRCNTL */
+#define        R367TER_SFERRCNTL       0xf2db
+#define        F367TER_SFEC_ERR_CNT_LO 0xf2db00ff
+
+/* SYMBRATEM */
+#define        R367TER_SYMBRATEM       0xf2e0
+#define        F367TER_DEFGEN_SYMBRATE_HI      0xf2e000ff
+
+/* SYMBRATEL */
+#define        R367TER_SYMBRATEL       0xf2e1
+#define        F367TER_DEFGEN_SYMBRATE_LO      0xf2e100ff
+
+/* SYMBSTATUS */
+#define        R367TER_SYMBSTATUS      0xf2e2
+#define        F367TER_SYMBDLINE2_OFF  0xf2e20080
+#define        F367TER_SDDL_REINIT1    0xf2e20040
+#define        F367TER_SDD_REINIT1     0xf2e20020
+#define        F367TER_TOKENID_ERROR   0xf2e20010
+#define        F367TER_SYMBRATE_OVERFLOW       0xf2e20008
+#define        F367TER_SYMBRATE_UNDERFLOW      0xf2e20004
+#define        F367TER_TOKENID_RSTEVENT        0xf2e20002
+#define        F367TER_TOKENID_RESET1  0xf2e20001
+
+/* SYMBCFG */
+#define        R367TER_SYMBCFG 0xf2e3
+#define        F367TER_SYMBCFG_7       0xf2e30080
+#define        F367TER_SYMBCFG_6       0xf2e30040
+#define        F367TER_SYMBCFG_5       0xf2e30020
+#define        F367TER_SYMBCFG_4       0xf2e30010
+#define        F367TER_SYMRATE_FSPEED  0xf2e3000c
+#define        F367TER_SYMRATE_SSPEED  0xf2e30003
+
+/* SYMBFIFOM */
+#define        R367TER_SYMBFIFOM       0xf2e4
+#define        F367TER_SYMBFIFOM_7     0xf2e40080
+#define        F367TER_SYMBFIFOM_6     0xf2e40040
+#define        F367TER_DEFGEN_SYMFIFO_HI       0xf2e4003f
+
+/* SYMBFIFOL */
+#define        R367TER_SYMBFIFOL       0xf2e5
+#define        F367TER_DEFGEN_SYMFIFO_LO       0xf2e500ff
+
+/* SYMBOFFSM */
+#define        R367TER_SYMBOFFSM       0xf2e6
+#define        F367TER_TOKENID_RESET2  0xf2e60080
+#define        F367TER_SDDL_REINIT2    0xf2e60040
+#define        F367TER_SDD_REINIT2     0xf2e60020
+#define        F367TER_SYMBOFFSM_4     0xf2e60010
+#define        F367TER_SYMBOFFSM_3     0xf2e60008
+#define        F367TER_DEFGEN_SYMBOFFSET_HI    0xf2e60007
+
+/* SYMBOFFSL */
+#define        R367TER_SYMBOFFSL       0xf2e7
+#define        F367TER_DEFGEN_SYMBOFFSET_LO    0xf2e700ff
+
+/* DEBUG_LT4 */
+#define        R367TER_DEBUG_LT4       0xf400
+#define        F367TER_F_DEBUG_LT4     0xf40000ff
+
+/* DEBUG_LT5 */
+#define        R367TER_DEBUG_LT5       0xf401
+#define        F367TER_F_DEBUG_LT5     0xf40100ff
+
+/* DEBUG_LT6 */
+#define        R367TER_DEBUG_LT6       0xf402
+#define        F367TER_F_DEBUG_LT6     0xf40200ff
+
+/* DEBUG_LT7 */
+#define        R367TER_DEBUG_LT7       0xf403
+#define        F367TER_F_DEBUG_LT7     0xf40300ff
+
+/* DEBUG_LT8 */
+#define        R367TER_DEBUG_LT8       0xf404
+#define        F367TER_F_DEBUG_LT8     0xf40400ff
+
+/* DEBUG_LT9 */
+#define        R367TER_DEBUG_LT9       0xf405
+#define        F367TER_F_DEBUG_LT9     0xf40500ff
+
+#define STV0367TER_NBREGS      445
+
+/* ID */
+#define        R367CAB_ID      0xf000
+#define        F367CAB_IDENTIFICATIONREGISTER  0xf00000ff
+
+/* I2CRPT */
+#define        R367CAB_I2CRPT  0xf001
+#define        F367CAB_I2CT_ON 0xf0010080
+#define        F367CAB_ENARPT_LEVEL    0xf0010070
+#define        F367CAB_SCLT_DELAY      0xf0010008
+#define        F367CAB_SCLT_NOD        0xf0010004
+#define        F367CAB_STOP_ENABLE     0xf0010002
+#define        F367CAB_SDAT_NOD        0xf0010001
+
+/* TOPCTRL */
+#define        R367CAB_TOPCTRL 0xf002
+#define        F367CAB_STDBY   0xf0020080
+#define        F367CAB_STDBY_CORE      0xf0020020
+#define        F367CAB_QAM_COFDM       0xf0020010
+#define        F367CAB_TS_DIS  0xf0020008
+#define        F367CAB_DIR_CLK_216     0xf0020004
+
+/* IOCFG0 */
+#define        R367CAB_IOCFG0  0xf003
+#define        F367CAB_OP0_SD  0xf0030080
+#define        F367CAB_OP0_VAL 0xf0030040
+#define        F367CAB_OP0_OD  0xf0030020
+#define        F367CAB_OP0_INV 0xf0030010
+#define        F367CAB_OP0_DACVALUE_HI 0xf003000f
+
+/* DAc0R */
+#define        R367CAB_DAC0R   0xf004
+#define        F367CAB_OP0_DACVALUE_LO 0xf00400ff
+
+/* IOCFG1 */
+#define        R367CAB_IOCFG1  0xf005
+#define        F367CAB_IP0     0xf0050040
+#define        F367CAB_OP1_OD  0xf0050020
+#define        F367CAB_OP1_INV 0xf0050010
+#define        F367CAB_OP1_DACVALUE_HI 0xf005000f
+
+/* DAC1R */
+#define        R367CAB_DAC1R   0xf006
+#define        F367CAB_OP1_DACVALUE_LO 0xf00600ff
+
+/* IOCFG2 */
+#define        R367CAB_IOCFG2  0xf007
+#define        F367CAB_OP2_LOCK_CONF   0xf00700e0
+#define        F367CAB_OP2_OD  0xf0070010
+#define        F367CAB_OP2_VAL 0xf0070008
+#define        F367CAB_OP1_LOCK_CONF   0xf0070007
+
+/* SDFR */
+#define        R367CAB_SDFR    0xf008
+#define        F367CAB_OP0_FREQ        0xf00800f0
+#define        F367CAB_OP1_FREQ        0xf008000f
+
+/* AUX_CLK */
+#define        R367CAB_AUX_CLK 0xf00a
+#define        F367CAB_AUXFEC_CTL      0xf00a00c0
+#define        F367CAB_DIS_CKX4        0xf00a0020
+#define        F367CAB_CKSEL   0xf00a0018
+#define        F367CAB_CKDIV_PROG      0xf00a0006
+#define        F367CAB_AUXCLK_ENA      0xf00a0001
+
+/* FREESYS1 */
+#define        R367CAB_FREESYS1        0xf00b
+#define        F367CAB_FREESYS_1       0xf00b00ff
+
+/* FREESYS2 */
+#define        R367CAB_FREESYS2        0xf00c
+#define        F367CAB_FREESYS_2       0xf00c00ff
+
+/* FREESYS3 */
+#define        R367CAB_FREESYS3        0xf00d
+#define        F367CAB_FREESYS_3       0xf00d00ff
+
+/* GPIO_CFG */
+#define        R367CAB_GPIO_CFG        0xf00e
+#define        F367CAB_GPIO7_OD        0xf00e0080
+#define        F367CAB_GPIO7_CFG       0xf00e0040
+#define        F367CAB_GPIO6_OD        0xf00e0020
+#define        F367CAB_GPIO6_CFG       0xf00e0010
+#define        F367CAB_GPIO5_OD        0xf00e0008
+#define        F367CAB_GPIO5_CFG       0xf00e0004
+#define        F367CAB_GPIO4_OD        0xf00e0002
+#define        F367CAB_GPIO4_CFG       0xf00e0001
+
+/* GPIO_CMD */
+#define        R367CAB_GPIO_CMD        0xf00f
+#define        F367CAB_GPIO7_VAL       0xf00f0008
+#define        F367CAB_GPIO6_VAL       0xf00f0004
+#define        F367CAB_GPIO5_VAL       0xf00f0002
+#define        F367CAB_GPIO4_VAL       0xf00f0001
+
+/* TSTRES */
+#define        R367CAB_TSTRES  0xf0c0
+#define        F367CAB_FRES_DISPLAY    0xf0c00080
+#define        F367CAB_FRES_FIFO_AD    0xf0c00020
+#define        F367CAB_FRESRS  0xf0c00010
+#define        F367CAB_FRESACS 0xf0c00008
+#define        F367CAB_FRESFEC 0xf0c00004
+#define        F367CAB_FRES_PRIF       0xf0c00002
+#define        F367CAB_FRESCORE        0xf0c00001
+
+/* ANACTRL */
+#define        R367CAB_ANACTRL 0xf0c1
+#define        F367CAB_BYPASS_XTAL     0xf0c10040
+#define        F367CAB_BYPASS_PLLXN    0xf0c1000c
+#define        F367CAB_DIS_PAD_OSC     0xf0c10002
+#define        F367CAB_STDBY_PLLXN     0xf0c10001
+
+/* TSTBUS */
+#define        R367CAB_TSTBUS  0xf0c2
+#define        F367CAB_TS_BYTE_CLK_INV 0xf0c20080
+#define        F367CAB_CFG_IP  0xf0c20070
+#define        F367CAB_CFG_TST 0xf0c2000f
+
+/* RF_AGC1 */
+#define        R367CAB_RF_AGC1 0xf0d4
+#define        F367CAB_RF_AGC1_LEVEL_HI        0xf0d400ff
+
+/* RF_AGC2 */
+#define        R367CAB_RF_AGC2 0xf0d5
+#define        F367CAB_REF_ADGP        0xf0d50080
+#define        F367CAB_STDBY_ADCGP     0xf0d50020
+#define        F367CAB_RF_AGC1_LEVEL_LO        0xf0d50003
+
+/* ANADIGCTRL */
+#define        R367CAB_ANADIGCTRL      0xf0d7
+#define        F367CAB_SEL_CLKDEM      0xf0d70020
+#define        F367CAB_EN_BUFFER_Q     0xf0d70010
+#define        F367CAB_EN_BUFFER_I     0xf0d70008
+#define        F367CAB_ADC_RIS_EGDE    0xf0d70004
+#define        F367CAB_SGN_ADC 0xf0d70002
+#define        F367CAB_SEL_AD12_SYNC   0xf0d70001
+
+/* PLLMDIV */
+#define        R367CAB_PLLMDIV 0xf0d8
+#define        F367CAB_PLL_MDIV        0xf0d800ff
+
+/* PLLNDIV */
+#define        R367CAB_PLLNDIV 0xf0d9
+#define        F367CAB_PLL_NDIV        0xf0d900ff
+
+/* PLLSETUP */
+#define        R367CAB_PLLSETUP        0xf0da
+#define        F367CAB_PLL_PDIV        0xf0da0070
+#define        F367CAB_PLL_KDIV        0xf0da000f
+
+/* DUAL_AD12 */
+#define        R367CAB_DUAL_AD12       0xf0db
+#define        F367CAB_FS20M   0xf0db0020
+#define        F367CAB_FS50M   0xf0db0010
+#define        F367CAB_INMODe0 0xf0db0008
+#define        F367CAB_POFFQ   0xf0db0004
+#define        F367CAB_POFFI   0xf0db0002
+#define        F367CAB_INMODE1 0xf0db0001
+
+/* TSTBIST */
+#define        R367CAB_TSTBIST 0xf0dc
+#define        F367CAB_TST_BYP_CLK     0xf0dc0080
+#define        F367CAB_TST_GCLKENA_STD 0xf0dc0040
+#define        F367CAB_TST_GCLKENA     0xf0dc0020
+#define        F367CAB_TST_MEMBIST     0xf0dc001f
+
+/* CTRL_1 */
+#define        R367CAB_CTRL_1  0xf402
+#define        F367CAB_SOFT_RST        0xf4020080
+#define        F367CAB_EQU_RST 0xf4020008
+#define        F367CAB_CRL_RST 0xf4020004
+#define        F367CAB_TRL_RST 0xf4020002
+#define        F367CAB_AGC_RST 0xf4020001
+
+/* CTRL_2 */
+#define        R367CAB_CTRL_2  0xf403
+#define        F367CAB_DEINT_RST       0xf4030008
+#define        F367CAB_RS_RST  0xf4030004
+
+/* IT_STATUS1 */
+#define        R367CAB_IT_STATUS1      0xf408
+#define        F367CAB_SWEEP_OUT       0xf4080080
+#define        F367CAB_FSM_CRL 0xf4080040
+#define        F367CAB_CRL_LOCK        0xf4080020
+#define        F367CAB_MFSM    0xf4080010
+#define        F367CAB_TRL_LOCK        0xf4080008
+#define        F367CAB_TRL_AGC_LIMIT   0xf4080004
+#define        F367CAB_ADJ_AGC_LOCK    0xf4080002
+#define        F367CAB_AGC_QAM_LOCK    0xf4080001
+
+/* IT_STATUS2 */
+#define        R367CAB_IT_STATUS2      0xf409
+#define        F367CAB_TSMF_CNT        0xf4090080
+#define        F367CAB_TSMF_EOF        0xf4090040
+#define        F367CAB_TSMF_RDY        0xf4090020
+#define        F367CAB_FEC_NOCORR      0xf4090010
+#define        F367CAB_SYNCSTATE       0xf4090008
+#define        F367CAB_DEINT_LOCK      0xf4090004
+#define        F367CAB_FADDING_FRZ     0xf4090002
+#define        F367CAB_TAPMON_ALARM    0xf4090001
+
+/* IT_EN1 */
+#define        R367CAB_IT_EN1  0xf40a
+#define        F367CAB_SWEEP_OUTE      0xf40a0080
+#define        F367CAB_FSM_CRLE        0xf40a0040
+#define        F367CAB_CRL_LOCKE       0xf40a0020
+#define        F367CAB_MFSME   0xf40a0010
+#define        F367CAB_TRL_LOCKE       0xf40a0008
+#define        F367CAB_TRL_AGC_LIMITE  0xf40a0004
+#define        F367CAB_ADJ_AGC_LOCKE   0xf40a0002
+#define        F367CAB_AGC_LOCKE       0xf40a0001
+
+/* IT_EN2 */
+#define        R367CAB_IT_EN2  0xf40b
+#define        F367CAB_TSMF_CNTE       0xf40b0080
+#define        F367CAB_TSMF_EOFE       0xf40b0040
+#define        F367CAB_TSMF_RDYE       0xf40b0020
+#define        F367CAB_FEC_NOCORRE     0xf40b0010
+#define        F367CAB_SYNCSTATEE      0xf40b0008
+#define        F367CAB_DEINT_LOCKE     0xf40b0004
+#define        F367CAB_FADDING_FRZE    0xf40b0002
+#define        F367CAB_TAPMON_ALARME   0xf40b0001
+
+/* CTRL_STATUS */
+#define        R367CAB_CTRL_STATUS     0xf40c
+#define        F367CAB_QAMFEC_LOCK     0xf40c0004
+#define        F367CAB_TSMF_LOCK       0xf40c0002
+#define        F367CAB_TSMF_ERROR      0xf40c0001
+
+/* TEST_CTL */
+#define        R367CAB_TEST_CTL        0xf40f
+#define        F367CAB_TST_BLK_SEL     0xf40f0060
+#define        F367CAB_TST_BUS_SEL     0xf40f001f
+
+/* AGC_CTL */
+#define        R367CAB_AGC_CTL 0xf410
+#define        F367CAB_AGC_LCK_TH      0xf41000f0
+#define        F367CAB_AGC_ACCUMRSTSEL 0xf4100007
+
+/* AGC_IF_CFG */
+#define        R367CAB_AGC_IF_CFG      0xf411
+#define        F367CAB_AGC_IF_BWSEL    0xf41100f0
+#define        F367CAB_AGC_IF_FREEZE   0xf4110002
+
+/* AGC_RF_CFG */
+#define        R367CAB_AGC_RF_CFG      0xf412
+#define        F367CAB_AGC_RF_BWSEL    0xf4120070
+#define        F367CAB_AGC_RF_FREEZE   0xf4120002
+
+/* AGC_PWM_CFG */
+#define        R367CAB_AGC_PWM_CFG     0xf413
+#define        F367CAB_AGC_RF_PWM_TST  0xf4130080
+#define        F367CAB_AGC_RF_PWM_INV  0xf4130040
+#define        F367CAB_AGC_IF_PWM_TST  0xf4130008
+#define        F367CAB_AGC_IF_PWM_INV  0xf4130004
+#define        F367CAB_AGC_PWM_CLKDIV  0xf4130003
+
+/* AGC_PWR_REF_L */
+#define        R367CAB_AGC_PWR_REF_L   0xf414
+#define        F367CAB_AGC_PWRREF_LO   0xf41400ff
+
+/* AGC_PWR_REF_H */
+#define        R367CAB_AGC_PWR_REF_H   0xf415
+#define        F367CAB_AGC_PWRREF_HI   0xf4150003
+
+/* AGC_RF_TH_L */
+#define        R367CAB_AGC_RF_TH_L     0xf416
+#define        F367CAB_AGC_RF_TH_LO    0xf41600ff
+
+/* AGC_RF_TH_H */
+#define        R367CAB_AGC_RF_TH_H     0xf417
+#define        F367CAB_AGC_RF_TH_HI    0xf417000f
+
+/* AGC_IF_LTH_L */
+#define        R367CAB_AGC_IF_LTH_L    0xf418
+#define        F367CAB_AGC_IF_THLO_LO  0xf41800ff
+
+/* AGC_IF_LTH_H */
+#define        R367CAB_AGC_IF_LTH_H    0xf419
+#define        F367CAB_AGC_IF_THLO_HI  0xf419000f
+
+/* AGC_IF_HTH_L */
+#define        R367CAB_AGC_IF_HTH_L    0xf41a
+#define        F367CAB_AGC_IF_THHI_LO  0xf41a00ff
+
+/* AGC_IF_HTH_H */
+#define        R367CAB_AGC_IF_HTH_H    0xf41b
+#define        F367CAB_AGC_IF_THHI_HI  0xf41b000f
+
+/* AGC_PWR_RD_L */
+#define        R367CAB_AGC_PWR_RD_L    0xf41c
+#define        F367CAB_AGC_PWR_WORD_LO 0xf41c00ff
+
+/* AGC_PWR_RD_M */
+#define        R367CAB_AGC_PWR_RD_M    0xf41d
+#define        F367CAB_AGC_PWR_WORD_ME 0xf41d00ff
+
+/* AGC_PWR_RD_H */
+#define        R367CAB_AGC_PWR_RD_H    0xf41e
+#define        F367CAB_AGC_PWR_WORD_HI 0xf41e0003
+
+/* AGC_PWM_IFCMD_L */
+#define        R367CAB_AGC_PWM_IFCMD_L 0xf420
+#define        F367CAB_AGC_IF_PWMCMD_LO        0xf42000ff
+
+/* AGC_PWM_IFCMD_H */
+#define        R367CAB_AGC_PWM_IFCMD_H 0xf421
+#define        F367CAB_AGC_IF_PWMCMD_HI        0xf421000f
+
+/* AGC_PWM_RFCMD_L */
+#define        R367CAB_AGC_PWM_RFCMD_L 0xf422
+#define        F367CAB_AGC_RF_PWMCMD_LO        0xf42200ff
+
+/* AGC_PWM_RFCMD_H */
+#define        R367CAB_AGC_PWM_RFCMD_H 0xf423
+#define        F367CAB_AGC_RF_PWMCMD_HI        0xf423000f
+
+/* IQDEM_CFG */
+#define        R367CAB_IQDEM_CFG       0xf424
+#define        F367CAB_IQDEM_CLK_SEL   0xf4240004
+#define        F367CAB_IQDEM_INVIQ     0xf4240002
+#define        F367CAB_IQDEM_A2dTYPE   0xf4240001
+
+/* MIX_NCO_LL */
+#define        R367CAB_MIX_NCO_LL      0xf425
+#define        F367CAB_MIX_NCO_INC_LL  0xf42500ff
+
+/* MIX_NCO_HL */
+#define        R367CAB_MIX_NCO_HL      0xf426
+#define        F367CAB_MIX_NCO_INC_HL  0xf42600ff
+
+/* MIX_NCO_HH */
+#define        R367CAB_MIX_NCO_HH      0xf427
+#define        F367CAB_MIX_NCO_INVCNST 0xf4270080
+#define        F367CAB_MIX_NCO_INC_HH  0xf427007f
+
+/* SRC_NCO_LL */
+#define        R367CAB_SRC_NCO_LL      0xf428
+#define        F367CAB_SRC_NCO_INC_LL  0xf42800ff
+
+/* SRC_NCO_LH */
+#define        R367CAB_SRC_NCO_LH      0xf429
+#define        F367CAB_SRC_NCO_INC_LH  0xf42900ff
+
+/* SRC_NCO_HL */
+#define        R367CAB_SRC_NCO_HL      0xf42a
+#define        F367CAB_SRC_NCO_INC_HL  0xf42a00ff
+
+/* SRC_NCO_HH */
+#define        R367CAB_SRC_NCO_HH      0xf42b
+#define        F367CAB_SRC_NCO_INC_HH  0xf42b007f
+
+/* IQDEM_GAIN_SRC_L */
+#define        R367CAB_IQDEM_GAIN_SRC_L        0xf42c
+#define        F367CAB_GAIN_SRC_LO     0xf42c00ff
+
+/* IQDEM_GAIN_SRC_H */
+#define        R367CAB_IQDEM_GAIN_SRC_H        0xf42d
+#define        F367CAB_GAIN_SRC_HI     0xf42d0003
+
+/* IQDEM_DCRM_CFG_LL */
+#define        R367CAB_IQDEM_DCRM_CFG_LL       0xf430
+#define        F367CAB_DCRM0_DCIN_L    0xf43000ff
+
+/* IQDEM_DCRM_CFG_LH */
+#define        R367CAB_IQDEM_DCRM_CFG_LH       0xf431
+#define        F367CAB_DCRM1_I_DCIN_L  0xf43100fc
+#define        F367CAB_DCRM0_DCIN_H    0xf4310003
+
+/* IQDEM_DCRM_CFG_HL */
+#define        R367CAB_IQDEM_DCRM_CFG_HL       0xf432
+#define        F367CAB_DCRM1_Q_DCIN_L  0xf43200f0
+#define        F367CAB_DCRM1_I_DCIN_H  0xf432000f
+
+/* IQDEM_DCRM_CFG_HH */
+#define        R367CAB_IQDEM_DCRM_CFG_HH       0xf433
+#define        F367CAB_DCRM1_FRZ       0xf4330080
+#define        F367CAB_DCRM0_FRZ       0xf4330040
+#define        F367CAB_DCRM1_Q_DCIN_H  0xf433003f
+
+/* IQDEM_ADJ_COEFf0 */
+#define        R367CAB_IQDEM_ADJ_COEFF0        0xf434
+#define        F367CAB_ADJIIR_COEFF10_L        0xf43400ff
+
+/* IQDEM_ADJ_COEFF1 */
+#define        R367CAB_IQDEM_ADJ_COEFF1        0xf435
+#define        F367CAB_ADJIIR_COEFF11_L        0xf43500fc
+#define        F367CAB_ADJIIR_COEFF10_H        0xf4350003
+
+/* IQDEM_ADJ_COEFF2 */
+#define        R367CAB_IQDEM_ADJ_COEFF2        0xf436
+#define        F367CAB_ADJIIR_COEFF12_L        0xf43600f0
+#define        F367CAB_ADJIIR_COEFF11_H        0xf436000f
+
+/* IQDEM_ADJ_COEFF3 */
+#define        R367CAB_IQDEM_ADJ_COEFF3        0xf437
+#define        F367CAB_ADJIIR_COEFF20_L        0xf43700c0
+#define        F367CAB_ADJIIR_COEFF12_H        0xf437003f
+
+/* IQDEM_ADJ_COEFF4 */
+#define        R367CAB_IQDEM_ADJ_COEFF4        0xf438
+#define        F367CAB_ADJIIR_COEFF20_H        0xf43800ff
+
+/* IQDEM_ADJ_COEFF5 */
+#define        R367CAB_IQDEM_ADJ_COEFF5        0xf439
+#define        F367CAB_ADJIIR_COEFF21_L        0xf43900ff
+
+/* IQDEM_ADJ_COEFF6 */
+#define        R367CAB_IQDEM_ADJ_COEFF6        0xf43a
+#define        F367CAB_ADJIIR_COEFF22_L        0xf43a00fc
+#define        F367CAB_ADJIIR_COEFF21_H        0xf43a0003
+
+/* IQDEM_ADJ_COEFF7 */
+#define        R367CAB_IQDEM_ADJ_COEFF7        0xf43b
+#define        F367CAB_ADJIIR_COEFF22_H        0xf43b000f
+
+/* IQDEM_ADJ_EN */
+#define        R367CAB_IQDEM_ADJ_EN    0xf43c
+#define        F367CAB_ALLPASSFILT_EN  0xf43c0008
+#define        F367CAB_ADJ_AGC_EN      0xf43c0004
+#define        F367CAB_ADJ_COEFF_FRZ   0xf43c0002
+#define        F367CAB_ADJ_EN  0xf43c0001
+
+/* IQDEM_ADJ_AGC_REF */
+#define        R367CAB_IQDEM_ADJ_AGC_REF       0xf43d
+#define        F367CAB_ADJ_AGC_REF     0xf43d00ff
+
+/* ALLPASSFILT1 */
+#define        R367CAB_ALLPASSFILT1    0xf440
+#define        F367CAB_ALLPASSFILT_COEFF1_LO   0xf44000ff
+
+/* ALLPASSFILT2 */
+#define        R367CAB_ALLPASSFILT2    0xf441
+#define        F367CAB_ALLPASSFILT_COEFF1_ME   0xf44100ff
+
+/* ALLPASSFILT3 */
+#define        R367CAB_ALLPASSFILT3    0xf442
+#define        F367CAB_ALLPASSFILT_COEFF2_LO   0xf44200c0
+#define        F367CAB_ALLPASSFILT_COEFF1_HI   0xf442003f
+
+/* ALLPASSFILT4 */
+#define        R367CAB_ALLPASSFILT4    0xf443
+#define        F367CAB_ALLPASSFILT_COEFF2_MEL  0xf44300ff
+
+/* ALLPASSFILT5 */
+#define        R367CAB_ALLPASSFILT5    0xf444
+#define        F367CAB_ALLPASSFILT_COEFF2_MEH  0xf44400ff
+
+/* ALLPASSFILT6 */
+#define        R367CAB_ALLPASSFILT6    0xf445
+#define        F367CAB_ALLPASSFILT_COEFF3_LO   0xf44500f0
+#define        F367CAB_ALLPASSFILT_COEFF2_HI   0xf445000f
+
+/* ALLPASSFILT7 */
+#define        R367CAB_ALLPASSFILT7    0xf446
+#define        F367CAB_ALLPASSFILT_COEFF3_MEL  0xf44600ff
+
+/* ALLPASSFILT8 */
+#define        R367CAB_ALLPASSFILT8    0xf447
+#define        F367CAB_ALLPASSFILT_COEFF3_MEH  0xf44700ff
+
+/* ALLPASSFILT9 */
+#define        R367CAB_ALLPASSFILT9    0xf448
+#define        F367CAB_ALLPASSFILT_COEFF4_LO   0xf44800fc
+#define        F367CAB_ALLPASSFILT_COEFF3_HI   0xf4480003
+
+/* ALLPASSFILT10 */
+#define        R367CAB_ALLPASSFILT10   0xf449
+#define        F367CAB_ALLPASSFILT_COEFF4_ME   0xf44900ff
+
+/* ALLPASSFILT11 */
+#define        R367CAB_ALLPASSFILT11   0xf44a
+#define        F367CAB_ALLPASSFILT_COEFF4_HI   0xf44a00ff
+
+/* TRL_AGC_CFG */
+#define        R367CAB_TRL_AGC_CFG     0xf450
+#define        F367CAB_TRL_AGC_FREEZE  0xf4500080
+#define        F367CAB_TRL_AGC_REF     0xf450007f
+
+/* TRL_LPF_CFG */
+#define        R367CAB_TRL_LPF_CFG     0xf454
+#define        F367CAB_NYQPOINT_INV    0xf4540040
+#define        F367CAB_TRL_SHIFT       0xf4540030
+#define        F367CAB_NYQ_COEFF_SEL   0xf454000c
+#define        F367CAB_TRL_LPF_FREEZE  0xf4540002
+#define        F367CAB_TRL_LPF_CRT     0xf4540001
+
+/* TRL_LPF_ACQ_GAIN */
+#define        R367CAB_TRL_LPF_ACQ_GAIN        0xf455
+#define        F367CAB_TRL_GDIR_ACQ    0xf4550070
+#define        F367CAB_TRL_GINT_ACQ    0xf4550007
+
+/* TRL_LPF_TRK_GAIN */
+#define        R367CAB_TRL_LPF_TRK_GAIN        0xf456
+#define        F367CAB_TRL_GDIR_TRK    0xf4560070
+#define        F367CAB_TRL_GINT_TRK    0xf4560007
+
+/* TRL_LPF_OUT_GAIN */
+#define        R367CAB_TRL_LPF_OUT_GAIN        0xf457
+#define        F367CAB_TRL_GAIN_OUT    0xf4570007
+
+/* TRL_LOCKDET_LTH */
+#define        R367CAB_TRL_LOCKDET_LTH 0xf458
+#define        F367CAB_TRL_LCK_THLO    0xf4580007
+
+/* TRL_LOCKDET_HTH */
+#define        R367CAB_TRL_LOCKDET_HTH 0xf459
+#define        F367CAB_TRL_LCK_THHI    0xf45900ff
+
+/* TRL_LOCKDET_TRGVAL */
+#define        R367CAB_TRL_LOCKDET_TRGVAL      0xf45a
+#define        F367CAB_TRL_LCK_TRG     0xf45a00ff
+
+/* IQ_QAM */
+#define        R367CAB_IQ_QAM  0xf45c
+#define        F367CAB_IQ_INPUT        0xf45c0008
+#define        F367CAB_DETECT_MODE     0xf45c0007
+
+/* FSM_STATE */
+#define        R367CAB_FSM_STATE       0xf460
+#define        F367CAB_CRL_DFE 0xf4600080
+#define        F367CAB_DFE_START       0xf4600040
+#define        F367CAB_CTRLG_START     0xf4600030
+#define        F367CAB_FSM_FORCESTATE  0xf460000f
+
+/* FSM_CTL */
+#define        R367CAB_FSM_CTL 0xf461
+#define        F367CAB_FEC2_EN 0xf4610040
+#define        F367CAB_SIT_EN  0xf4610020
+#define        F367CAB_TRL_AHEAD       0xf4610010
+#define        F367CAB_TRL2_EN 0xf4610008
+#define        F367CAB_FSM_EQA1_EN     0xf4610004
+#define        F367CAB_FSM_BKP_DIS     0xf4610002
+#define        F367CAB_FSM_FORCE_EN    0xf4610001
+
+/* FSM_STS */
+#define        R367CAB_FSM_STS 0xf462
+#define        F367CAB_FSM_STATUS      0xf462000f
+
+/* FSM_SNR0_HTH */
+#define        R367CAB_FSM_SNR0_HTH    0xf463
+#define        F367CAB_SNR0_HTH        0xf46300ff
+
+/* FSM_SNR1_HTH */
+#define        R367CAB_FSM_SNR1_HTH    0xf464
+#define        F367CAB_SNR1_HTH        0xf46400ff
+
+/* FSM_SNR2_HTH */
+#define        R367CAB_FSM_SNR2_HTH    0xf465
+#define        F367CAB_SNR2_HTH        0xf46500ff
+
+/* FSM_SNR0_LTH */
+#define        R367CAB_FSM_SNR0_LTH    0xf466
+#define        F367CAB_SNR0_LTH        0xf46600ff
+
+/* FSM_SNR1_LTH */
+#define        R367CAB_FSM_SNR1_LTH    0xf467
+#define        F367CAB_SNR1_LTH        0xf46700ff
+
+/* FSM_EQA1_HTH */
+#define        R367CAB_FSM_EQA1_HTH    0xf468
+#define        F367CAB_SNR3_HTH_LO     0xf46800f0
+#define        F367CAB_EQA1_HTH        0xf468000f
+
+/* FSM_TEMPO */
+#define        R367CAB_FSM_TEMPO       0xf469
+#define        F367CAB_SIT     0xf46900c0
+#define        F367CAB_WST     0xf4690038
+#define        F367CAB_ELT     0xf4690006
+#define        F367CAB_SNR3_HTH_HI     0xf4690001
+
+/* FSM_CONFIG */
+#define        R367CAB_FSM_CONFIG      0xf46a
+#define        F367CAB_FEC2_DFEOFF     0xf46a0004
+#define        F367CAB_PRIT_STATE      0xf46a0002
+#define        F367CAB_MODMAP_STATE    0xf46a0001
+
+/* EQU_I_TESTTAP_L */
+#define        R367CAB_EQU_I_TESTTAP_L 0xf474
+#define        F367CAB_I_TEST_TAP_L    0xf47400ff
+
+/* EQU_I_TESTTAP_M */
+#define        R367CAB_EQU_I_TESTTAP_M 0xf475
+#define        F367CAB_I_TEST_TAP_M    0xf47500ff
+
+/* EQU_I_TESTTAP_H */
+#define        R367CAB_EQU_I_TESTTAP_H 0xf476
+#define        F367CAB_I_TEST_TAP_H    0xf476001f
+
+/* EQU_TESTAP_CFG */
+#define        R367CAB_EQU_TESTAP_CFG  0xf477
+#define        F367CAB_TEST_FFE_DFE_SEL        0xf4770040
+#define        F367CAB_TEST_TAP_SELECT 0xf477003f
+
+/* EQU_Q_TESTTAP_L */
+#define        R367CAB_EQU_Q_TESTTAP_L 0xf478
+#define        F367CAB_Q_TEST_TAP_L    0xf47800ff
+
+/* EQU_Q_TESTTAP_M */
+#define        R367CAB_EQU_Q_TESTTAP_M 0xf479
+#define        F367CAB_Q_TEST_TAP_M    0xf47900ff
+
+/* EQU_Q_TESTTAP_H */
+#define        R367CAB_EQU_Q_TESTTAP_H 0xf47a
+#define        F367CAB_Q_TEST_TAP_H    0xf47a001f
+
+/* EQU_TAP_CTRL */
+#define        R367CAB_EQU_TAP_CTRL    0xf47b
+#define        F367CAB_MTAP_FRZ        0xf47b0010
+#define        F367CAB_PRE_FREEZE      0xf47b0008
+#define        F367CAB_DFE_TAPMON_EN   0xf47b0004
+#define        F367CAB_FFE_TAPMON_EN   0xf47b0002
+#define        F367CAB_MTAP_ONLY       0xf47b0001
+
+/* EQU_CTR_CRL_CONTROL_L */
+#define        R367CAB_EQU_CTR_CRL_CONTROL_L   0xf47c
+#define        F367CAB_EQU_CTR_CRL_CONTROL_LO  0xf47c00ff
+
+/* EQU_CTR_CRL_CONTROL_H */
+#define        R367CAB_EQU_CTR_CRL_CONTROL_H   0xf47d
+#define        F367CAB_EQU_CTR_CRL_CONTROL_HI  0xf47d00ff
+
+/* EQU_CTR_HIPOW_L */
+#define        R367CAB_EQU_CTR_HIPOW_L 0xf47e
+#define        F367CAB_CTR_HIPOW_L     0xf47e00ff
+
+/* EQU_CTR_HIPOW_H */
+#define        R367CAB_EQU_CTR_HIPOW_H 0xf47f
+#define        F367CAB_CTR_HIPOW_H     0xf47f00ff
+
+/* EQU_I_EQU_LO */
+#define        R367CAB_EQU_I_EQU_LO    0xf480
+#define        F367CAB_EQU_I_EQU_L     0xf48000ff
+
+/* EQU_I_EQU_HI */
+#define        R367CAB_EQU_I_EQU_HI    0xf481
+#define        F367CAB_EQU_I_EQU_H     0xf4810003
+
+/* EQU_Q_EQU_LO */
+#define        R367CAB_EQU_Q_EQU_LO    0xf482
+#define        F367CAB_EQU_Q_EQU_L     0xf48200ff
+
+/* EQU_Q_EQU_HI */
+#define        R367CAB_EQU_Q_EQU_HI    0xf483
+#define        F367CAB_EQU_Q_EQU_H     0xf4830003
+
+/* EQU_MAPPER */
+#define        R367CAB_EQU_MAPPER      0xf484
+#define        F367CAB_QUAD_AUTO       0xf4840080
+#define        F367CAB_QUAD_INV        0xf4840040
+#define        F367CAB_QAM_MODE        0xf4840007
+
+/* EQU_SWEEP_RATE */
+#define        R367CAB_EQU_SWEEP_RATE  0xf485
+#define        F367CAB_SNR_PER 0xf48500c0
+#define        F367CAB_SWEEP_RATE      0xf485003f
+
+/* EQU_SNR_LO */
+#define        R367CAB_EQU_SNR_LO      0xf486
+#define        F367CAB_SNR_LO  0xf48600ff
+
+/* EQU_SNR_HI */
+#define        R367CAB_EQU_SNR_HI      0xf487
+#define        F367CAB_SNR_HI  0xf48700ff
+
+/* EQU_GAMMA_LO */
+#define        R367CAB_EQU_GAMMA_LO    0xf488
+#define        F367CAB_GAMMA_LO        0xf48800ff
+
+/* EQU_GAMMA_HI */
+#define        R367CAB_EQU_GAMMA_HI    0xf489
+#define        F367CAB_GAMMA_ME        0xf48900ff
+
+/* EQU_ERR_GAIN */
+#define        R367CAB_EQU_ERR_GAIN    0xf48a
+#define        F367CAB_EQA1MU  0xf48a0070
+#define        F367CAB_CRL2MU  0xf48a000e
+#define        F367CAB_GAMMA_HI        0xf48a0001
+
+/* EQU_RADIUS */
+#define        R367CAB_EQU_RADIUS      0xf48b
+#define        F367CAB_RADIUS  0xf48b00ff
+
+/* EQU_FFE_MAINTAP */
+#define        R367CAB_EQU_FFE_MAINTAP 0xf48c
+#define        F367CAB_FFE_MAINTAP_INIT        0xf48c00ff
+
+/* EQU_FFE_LEAKAGE */
+#define        R367CAB_EQU_FFE_LEAKAGE 0xf48e
+#define        F367CAB_LEAK_PER        0xf48e00f0
+#define        F367CAB_EQU_OUTSEL      0xf48e0002
+#define        F367CAB_PNT2dFE 0xf48e0001
+
+/* EQU_FFE_MAINTAP_POS */
+#define        R367CAB_EQU_FFE_MAINTAP_POS     0xf48f
+#define        F367CAB_FFE_LEAK_EN     0xf48f0080
+#define        F367CAB_DFE_LEAK_EN     0xf48f0040
+#define        F367CAB_FFE_MAINTAP_POS 0xf48f003f
+
+/* EQU_GAIN_WIDE */
+#define        R367CAB_EQU_GAIN_WIDE   0xf490
+#define        F367CAB_DFE_GAIN_WIDE   0xf49000f0
+#define        F367CAB_FFE_GAIN_WIDE   0xf490000f
+
+/* EQU_GAIN_NARROW */
+#define        R367CAB_EQU_GAIN_NARROW 0xf491
+#define        F367CAB_DFE_GAIN_NARROW 0xf49100f0
+#define        F367CAB_FFE_GAIN_NARROW 0xf491000f
+
+/* EQU_CTR_LPF_GAIN */
+#define        R367CAB_EQU_CTR_LPF_GAIN        0xf492
+#define        F367CAB_CTR_GTO 0xf4920080
+#define        F367CAB_CTR_GDIR        0xf4920070
+#define        F367CAB_SWEEP_EN        0xf4920008
+#define        F367CAB_CTR_GINT        0xf4920007
+
+/* EQU_CRL_LPF_GAIN */
+#define        R367CAB_EQU_CRL_LPF_GAIN        0xf493
+#define        F367CAB_CRL_GTO 0xf4930080
+#define        F367CAB_CRL_GDIR        0xf4930070
+#define        F367CAB_SWEEP_DIR       0xf4930008
+#define        F367CAB_CRL_GINT        0xf4930007
+
+/* EQU_GLOBAL_GAIN */
+#define        R367CAB_EQU_GLOBAL_GAIN 0xf494
+#define        F367CAB_CRL_GAIN        0xf49400f8
+#define        F367CAB_CTR_INC_GAIN    0xf4940004
+#define        F367CAB_CTR_FRAC        0xf4940003
+
+/* EQU_CRL_LD_SEN */
+#define        R367CAB_EQU_CRL_LD_SEN  0xf495
+#define        F367CAB_CTR_BADPOINT_EN 0xf4950080
+#define        F367CAB_CTR_GAIN        0xf4950070
+#define        F367CAB_LIMANEN 0xf4950008
+#define        F367CAB_CRL_LD_SEN      0xf4950007
+
+/* EQU_CRL_LD_VAL */
+#define        R367CAB_EQU_CRL_LD_VAL  0xf496
+#define        F367CAB_CRL_BISTH_LIMIT 0xf4960080
+#define        F367CAB_CARE_EN 0xf4960040
+#define        F367CAB_CRL_LD_PER      0xf4960030
+#define        F367CAB_CRL_LD_WST      0xf496000c
+#define        F367CAB_CRL_LD_TFS      0xf4960003
+
+/* EQU_CRL_TFR */
+#define        R367CAB_EQU_CRL_TFR     0xf497
+#define        F367CAB_CRL_LD_TFR      0xf49700ff
+
+/* EQU_CRL_BISTH_LO */
+#define        R367CAB_EQU_CRL_BISTH_LO        0xf498
+#define        F367CAB_CRL_BISTH_LO    0xf49800ff
+
+/* EQU_CRL_BISTH_HI */
+#define        R367CAB_EQU_CRL_BISTH_HI        0xf499
+#define        F367CAB_CRL_BISTH_HI    0xf49900ff
+
+/* EQU_SWEEP_RANGE_LO */
+#define        R367CAB_EQU_SWEEP_RANGE_LO      0xf49a
+#define        F367CAB_SWEEP_RANGE_LO  0xf49a00ff
+
+/* EQU_SWEEP_RANGE_HI */
+#define        R367CAB_EQU_SWEEP_RANGE_HI      0xf49b
+#define        F367CAB_SWEEP_RANGE_HI  0xf49b00ff
+
+/* EQU_CRL_LIMITER */
+#define        R367CAB_EQU_CRL_LIMITER 0xf49c
+#define        F367CAB_BISECTOR_EN     0xf49c0080
+#define        F367CAB_PHEST128_EN     0xf49c0040
+#define        F367CAB_CRL_LIM 0xf49c003f
+
+/* EQU_MODULUS_MAP */
+#define        R367CAB_EQU_MODULUS_MAP 0xf49d
+#define        F367CAB_PNT_DEPTH       0xf49d00e0
+#define        F367CAB_MODULUS_CMP     0xf49d001f
+
+/* EQU_PNT_GAIN */
+#define        R367CAB_EQU_PNT_GAIN    0xf49e
+#define        F367CAB_PNT_EN  0xf49e0080
+#define        F367CAB_MODULUSMAP_EN   0xf49e0040
+#define        F367CAB_PNT_GAIN        0xf49e003f
+
+/* FEC_AC_CTR_0 */
+#define        R367CAB_FEC_AC_CTR_0    0xf4a8
+#define        F367CAB_BE_BYPASS       0xf4a80020
+#define        F367CAB_REFRESH47       0xf4a80010
+#define        F367CAB_CT_NBST 0xf4a80008
+#define        F367CAB_TEI_ENA 0xf4a80004
+#define        F367CAB_DS_ENA  0xf4a80002
+#define        F367CAB_TSMF_EN 0xf4a80001
+
+/* FEC_AC_CTR_1 */
+#define        R367CAB_FEC_AC_CTR_1    0xf4a9
+#define        F367CAB_DEINT_DEPTH     0xf4a900ff
+
+/* FEC_AC_CTR_2 */
+#define        R367CAB_FEC_AC_CTR_2    0xf4aa
+#define        F367CAB_DEINT_M 0xf4aa00f8
+#define        F367CAB_DIS_UNLOCK      0xf4aa0004
+#define        F367CAB_DESCR_MODE      0xf4aa0003
+
+/* FEC_AC_CTR_3 */
+#define        R367CAB_FEC_AC_CTR_3    0xf4ab
+#define        F367CAB_DI_UNLOCK       0xf4ab0080
+#define        F367CAB_DI_FREEZE       0xf4ab0040
+#define        F367CAB_MISMATCH        0xf4ab0030
+#define        F367CAB_ACQ_MODE        0xf4ab000c
+#define        F367CAB_TRK_MODE        0xf4ab0003
+
+/* FEC_STATUS */
+#define        R367CAB_FEC_STATUS      0xf4ac
+#define        F367CAB_DEINT_SMCNTR    0xf4ac00e0
+#define        F367CAB_DEINT_SYNCSTATE 0xf4ac0018
+#define        F367CAB_DEINT_SYNLOST   0xf4ac0004
+#define        F367CAB_DESCR_SYNCSTATE 0xf4ac0002
+
+/* RS_COUNTER_0 */
+#define        R367CAB_RS_COUNTER_0    0xf4ae
+#define        F367CAB_BK_CT_L 0xf4ae00ff
+
+/* RS_COUNTER_1 */
+#define        R367CAB_RS_COUNTER_1    0xf4af
+#define        F367CAB_BK_CT_H 0xf4af00ff
+
+/* RS_COUNTER_2 */
+#define        R367CAB_RS_COUNTER_2    0xf4b0
+#define        F367CAB_CORR_CT_L       0xf4b000ff
+
+/* RS_COUNTER_3 */
+#define        R367CAB_RS_COUNTER_3    0xf4b1
+#define        F367CAB_CORR_CT_H       0xf4b100ff
+
+/* RS_COUNTER_4 */
+#define        R367CAB_RS_COUNTER_4    0xf4b2
+#define        F367CAB_UNCORR_CT_L     0xf4b200ff
+
+/* RS_COUNTER_5 */
+#define        R367CAB_RS_COUNTER_5    0xf4b3
+#define        F367CAB_UNCORR_CT_H     0xf4b300ff
+
+/* BERT_0 */
+#define        R367CAB_BERT_0  0xf4b4
+#define        F367CAB_RS_NOCORR       0xf4b40004
+#define        F367CAB_CT_HOLD 0xf4b40002
+#define        F367CAB_CT_CLEAR        0xf4b40001
+
+/* BERT_1 */
+#define        R367CAB_BERT_1  0xf4b5
+#define        F367CAB_BERT_ON 0xf4b50020
+#define        F367CAB_BERT_ERR_SRC    0xf4b50010
+#define        F367CAB_BERT_ERR_MODE   0xf4b50008
+#define        F367CAB_BERT_NBYTE      0xf4b50007
+
+/* BERT_2 */
+#define        R367CAB_BERT_2  0xf4b6
+#define        F367CAB_BERT_ERRCOUNT_L 0xf4b600ff
+
+/* BERT_3 */
+#define        R367CAB_BERT_3  0xf4b7
+#define        F367CAB_BERT_ERRCOUNT_H 0xf4b700ff
+
+/* OUTFORMAT_0 */
+#define        R367CAB_OUTFORMAT_0     0xf4b8
+#define        F367CAB_CLK_POLARITY    0xf4b80080
+#define        F367CAB_FEC_TYPE        0xf4b80040
+#define        F367CAB_SYNC_STRIP      0xf4b80008
+#define        F367CAB_TS_SWAP 0xf4b80004
+#define        F367CAB_OUTFORMAT       0xf4b80003
+
+/* OUTFORMAT_1 */
+#define        R367CAB_OUTFORMAT_1     0xf4b9
+#define        F367CAB_CI_DIVRANGE     0xf4b900ff
+
+/* SMOOTHER_2 */
+#define        R367CAB_SMOOTHER_2      0xf4be
+#define        F367CAB_FIFO_BYPASS     0xf4be0020
+
+/* TSMF_CTRL_0 */
+#define        R367CAB_TSMF_CTRL_0     0xf4c0
+#define        F367CAB_TS_NUMBER       0xf4c0001e
+#define        F367CAB_SEL_MODE        0xf4c00001
+
+/* TSMF_CTRL_1 */
+#define        R367CAB_TSMF_CTRL_1     0xf4c1
+#define        F367CAB_CHECK_ERROR_BIT 0xf4c10080
+#define        F367CAB_CHCK_F_SYNC     0xf4c10040
+#define        F367CAB_H_MODE  0xf4c10008
+#define        F367CAB_D_V_MODE        0xf4c10004
+#define        F367CAB_MODE    0xf4c10003
+
+/* TSMF_CTRL_3 */
+#define        R367CAB_TSMF_CTRL_3     0xf4c3
+#define        F367CAB_SYNC_IN_COUNT   0xf4c300f0
+#define        F367CAB_SYNC_OUT_COUNT  0xf4c3000f
+
+/* TS_ON_ID_0 */
+#define        R367CAB_TS_ON_ID_0      0xf4c4
+#define        F367CAB_TS_ID_L 0xf4c400ff
+
+/* TS_ON_ID_1 */
+#define        R367CAB_TS_ON_ID_1      0xf4c5
+#define        F367CAB_TS_ID_H 0xf4c500ff
+
+/* TS_ON_ID_2 */
+#define        R367CAB_TS_ON_ID_2      0xf4c6
+#define        F367CAB_ON_ID_L 0xf4c600ff
+
+/* TS_ON_ID_3 */
+#define        R367CAB_TS_ON_ID_3      0xf4c7
+#define        F367CAB_ON_ID_H 0xf4c700ff
+
+/* RE_STATUS_0 */
+#define        R367CAB_RE_STATUS_0     0xf4c8
+#define        F367CAB_RECEIVE_STATUS_L        0xf4c800ff
+
+/* RE_STATUS_1 */
+#define        R367CAB_RE_STATUS_1     0xf4c9
+#define        F367CAB_RECEIVE_STATUS_LH       0xf4c900ff
+
+/* RE_STATUS_2 */
+#define        R367CAB_RE_STATUS_2     0xf4ca
+#define        F367CAB_RECEIVE_STATUS_HL       0xf4ca00ff
+
+/* RE_STATUS_3 */
+#define        R367CAB_RE_STATUS_3     0xf4cb
+#define        F367CAB_RECEIVE_STATUS_HH       0xf4cb003f
+
+/* TS_STATUS_0 */
+#define        R367CAB_TS_STATUS_0     0xf4cc
+#define        F367CAB_TS_STATUS_L     0xf4cc00ff
+
+/* TS_STATUS_1 */
+#define        R367CAB_TS_STATUS_1     0xf4cd
+#define        F367CAB_TS_STATUS_H     0xf4cd007f
+
+/* TS_STATUS_2 */
+#define        R367CAB_TS_STATUS_2     0xf4ce
+#define        F367CAB_ERROR   0xf4ce0080
+#define        F367CAB_EMERGENCY       0xf4ce0040
+#define        F367CAB_CRE_TS  0xf4ce0030
+#define        F367CAB_VER     0xf4ce000e
+#define        F367CAB_M_LOCK  0xf4ce0001
+
+/* TS_STATUS_3 */
+#define        R367CAB_TS_STATUS_3     0xf4cf
+#define        F367CAB_UPDATE_READY    0xf4cf0080
+#define        F367CAB_END_FRAME_HEADER        0xf4cf0040
+#define        F367CAB_CONTCNT 0xf4cf0020
+#define        F367CAB_TS_IDENTIFIER_SEL       0xf4cf000f
+
+/* T_O_ID_0 */
+#define        R367CAB_T_O_ID_0        0xf4d0
+#define        F367CAB_ON_ID_I_L       0xf4d000ff
+
+/* T_O_ID_1 */
+#define        R367CAB_T_O_ID_1        0xf4d1
+#define        F367CAB_ON_ID_I_H       0xf4d100ff
+
+/* T_O_ID_2 */
+#define        R367CAB_T_O_ID_2        0xf4d2
+#define        F367CAB_TS_ID_I_L       0xf4d200ff
+
+/* T_O_ID_3 */
+#define        R367CAB_T_O_ID_3        0xf4d3
+#define        F367CAB_TS_ID_I_H       0xf4d300ff
+
+#define STV0367CAB_NBREGS      187
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv0900.h b/drivers/media/dvb-frontends/stv0900.h
new file mode 100644 (file)
index 0000000..91c7ee8
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * stv0900.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_H
+#define STV0900_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0900_reg {
+       u16 addr;
+       u8  val;
+};
+
+struct stv0900_config {
+       u8 demod_address;
+       u8 demod_mode;
+       u32 xtal;
+       u8 clkmode;/* 0 for CLKI,  2 for XTALI */
+
+       u8 diseqc_mode;
+
+       u8 path1_mode;
+       u8 path2_mode;
+       struct stv0900_reg *ts_config_regs;
+       u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
+       u8 tun2_maddress;
+       u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
+       u8 tun2_adc;
+       u8 tun1_type;/* for now 3 for stb6100 auto, else - software */
+       u8 tun2_type;
+       /* Set device param to start dma */
+       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
+       /* Hook for Lock LED */
+       void (*set_lock_led)(struct dvb_frontend *fe, int offon);
+};
+
+#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
+                                                       && defined(MODULE))
+extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+                                       struct i2c_adapter *i2c, int demod);
+#else
+static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+                                       struct i2c_adapter *i2c, int demod)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
+
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
new file mode 100644 (file)
index 0000000..7f1bada
--- /dev/null
@@ -0,0 +1,1959 @@
+/*
+ * stv0900_core.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+#include "stv0900_init.h"
+
+int stvdebug = 1;
+module_param_named(debug, stvdebug, int, 0644);
+
+/* internal params node */
+struct stv0900_inode {
+       /* pointer for internal params, one for each pair of demods */
+       struct stv0900_internal         *internal;
+       struct stv0900_inode            *next_inode;
+};
+
+/* first internal params */
+static struct stv0900_inode *stv0900_first_inode;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
+                                                       u8 i2c_addr)
+{
+       struct stv0900_inode *temp_chip = stv0900_first_inode;
+
+       if (temp_chip != NULL) {
+               /*
+                Search of the last stv0900 chip or
+                find it by i2c adapter and i2c address */
+               while ((temp_chip != NULL) &&
+                       ((temp_chip->internal->i2c_adap != i2c_adap) ||
+                       (temp_chip->internal->i2c_addr != i2c_addr)))
+
+                       temp_chip = temp_chip->next_inode;
+
+       }
+
+       return temp_chip;
+}
+
+/* deallocating chip */
+static void remove_inode(struct stv0900_internal *internal)
+{
+       struct stv0900_inode *prev_node = stv0900_first_inode;
+       struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
+                                               internal->i2c_addr);
+
+       if (del_node != NULL) {
+               if (del_node == stv0900_first_inode) {
+                       stv0900_first_inode = del_node->next_inode;
+               } else {
+                       while (prev_node->next_inode != del_node)
+                               prev_node = prev_node->next_inode;
+
+                       if (del_node->next_inode == NULL)
+                               prev_node->next_inode = NULL;
+                       else
+                               prev_node->next_inode =
+                                       prev_node->next_inode->next_inode;
+               }
+
+               kfree(del_node);
+       }
+}
+
+/* allocating new chip */
+static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
+{
+       struct stv0900_inode *new_node = stv0900_first_inode;
+
+       if (new_node == NULL) {
+               new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+               stv0900_first_inode = new_node;
+       } else {
+               while (new_node->next_inode != NULL)
+                       new_node = new_node->next_inode;
+
+               new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
+                                                               GFP_KERNEL);
+               if (new_node->next_inode != NULL)
+                       new_node = new_node->next_inode;
+               else
+                       new_node = NULL;
+       }
+
+       if (new_node != NULL) {
+               new_node->internal = internal;
+               new_node->next_inode = NULL;
+       }
+
+       return new_node;
+}
+
+s32 ge2comp(s32 a, s32 width)
+{
+       if (width == 32)
+               return a;
+       else
+               return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
+}
+
+void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
+                                                               u8 reg_data)
+{
+       u8 data[3];
+       int ret;
+       struct i2c_msg i2cmsg = {
+               .addr  = intp->i2c_addr,
+               .flags = 0,
+               .len   = 3,
+               .buf   = data,
+       };
+
+       data[0] = MSB(reg_addr);
+       data[1] = LSB(reg_addr);
+       data[2] = reg_data;
+
+       ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
+       if (ret != 1)
+               dprintk("%s: i2c error %d\n", __func__, ret);
+}
+
+u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
+{
+       int ret;
+       u8 b0[] = { MSB(reg), LSB(reg) };
+       u8 buf = 0;
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = intp->i2c_addr,
+                       .flags  = 0,
+                       .buf = b0,
+                       .len = 2,
+               }, {
+                       .addr   = intp->i2c_addr,
+                       .flags  = I2C_M_RD,
+                       .buf = &buf,
+                       .len = 1,
+               },
+       };
+
+       ret = i2c_transfer(intp->i2c_adap, msg, 2);
+       if (ret != 2)
+               dprintk("%s: i2c error %d, reg[0x%02x]\n",
+                               __func__, ret, reg);
+
+       return buf;
+}
+
+static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+       u8 position = 0, i = 0;
+
+       (*mask) = label & 0xff;
+
+       while ((position == 0) && (i < 8)) {
+               position = ((*mask) >> i) & 0x01;
+               i++;
+       }
+
+       (*pos) = (i - 1);
+}
+
+void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
+{
+       u8 reg, mask, pos;
+
+       reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
+       extract_mask_pos(label, &mask, &pos);
+
+       val = mask & (val << pos);
+
+       reg = (reg & (~mask)) | val;
+       stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
+
+}
+
+u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
+{
+       u8 val = 0xff;
+       u8 mask, pos;
+
+       extract_mask_pos(label, &mask, &pos);
+
+       val = stv0900_read_reg(intp, label >> 16);
+       val = (val & mask) >> pos;
+
+       return val;
+}
+
+static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
+{
+       s32 i;
+
+       if (intp == NULL)
+               return STV0900_INVALID_HANDLE;
+
+       intp->chip_id = stv0900_read_reg(intp, R0900_MID);
+
+       if (intp->errs != STV0900_NO_ERROR)
+               return intp->errs;
+
+       /*Startup sequence*/
+       stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
+       stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
+       msleep(3);
+       stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
+       stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
+       stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
+       stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
+       stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
+       msleep(3);
+       stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
+
+       switch (intp->clkmode) {
+       case 0:
+       case 2:
+               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
+                               | intp->clkmode);
+               break;
+       default:
+               /* preserve SELOSCI bit */
+               i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
+               break;
+       }
+
+       msleep(3);
+       for (i = 0; i < 181; i++)
+               stv0900_write_reg(intp, STV0900_InitVal[i][0],
+                               STV0900_InitVal[i][1]);
+
+       if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
+               stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
+               for (i = 0; i < 32; i++)
+                       stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
+                                       STV0900_Cut20_AddOnVal[i][1]);
+       }
+
+       stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
+       stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
+
+       stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
+       stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
+
+       stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
+       stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
+
+       stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
+       stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
+
+       return STV0900_NO_ERROR;
+}
+
+static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
+{
+       u32 mclk = 90000000, div = 0, ad_div = 0;
+
+       div = stv0900_get_bits(intp, F0900_M_DIV);
+       ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
+
+       mclk = (div + 1) * ext_clk / ad_div;
+
+       dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
+
+       return mclk;
+}
+
+static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
+{
+       u32 m_div, clk_sel;
+
+       dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+                       intp->quartz);
+
+       if (intp == NULL)
+               return STV0900_INVALID_HANDLE;
+
+       if (intp->errs)
+               return STV0900_I2C_ERROR;
+
+       clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
+       m_div = ((clk_sel * mclk) / intp->quartz) - 1;
+       stv0900_write_bits(intp, F0900_M_DIV, m_div);
+       intp->mclk = stv0900_get_mclk_freq(intp,
+                                       intp->quartz);
+
+       /*Set the DiseqC frequency to 22KHz */
+       /*
+               Formula:
+               DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+               DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+       */
+       m_div = intp->mclk / 704000;
+       stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
+       stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
+
+       stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
+       stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
+
+       if ((intp->errs))
+               return STV0900_I2C_ERROR;
+
+       return STV0900_NO_ERROR;
+}
+
+static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32 lsb, msb, hsb, err_val;
+
+       switch (cntr) {
+       case 0:
+       default:
+               hsb = stv0900_get_bits(intp, ERR_CNT12);
+               msb = stv0900_get_bits(intp, ERR_CNT11);
+               lsb = stv0900_get_bits(intp, ERR_CNT10);
+               break;
+       case 1:
+               hsb = stv0900_get_bits(intp, ERR_CNT22);
+               msb = stv0900_get_bits(intp, ERR_CNT21);
+               lsb = stv0900_get_bits(intp, ERR_CNT20);
+               break;
+       }
+
+       err_val = (hsb << 16) + (msb << 8) + (lsb);
+
+       return err_val;
+}
+
+static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       stv0900_write_bits(intp, I2CT_ON, enable);
+
+       return 0;
+}
+
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
+                                       enum fe_stv0900_clock_type path1_ts,
+                                       enum fe_stv0900_clock_type path2_ts)
+{
+
+       dprintk("%s\n", __func__);
+
+       if (intp->chip_id >= 0x20) {
+               switch (path1_ts) {
+               case STV0900_PARALLEL_PUNCT_CLOCK:
+               case STV0900_DVBCI_CLOCK:
+                       switch (path2_ts) {
+                       case STV0900_SERIAL_PUNCT_CLOCK:
+                       case STV0900_SERIAL_CONT_CLOCK:
+                       default:
+                               stv0900_write_reg(intp, R0900_TSGENERAL,
+                                                       0x00);
+                               break;
+                       case STV0900_PARALLEL_PUNCT_CLOCK:
+                       case STV0900_DVBCI_CLOCK:
+                               stv0900_write_reg(intp, R0900_TSGENERAL,
+                                                       0x06);
+                               stv0900_write_bits(intp,
+                                               F0900_P1_TSFIFO_MANSPEED, 3);
+                               stv0900_write_bits(intp,
+                                               F0900_P2_TSFIFO_MANSPEED, 0);
+                               stv0900_write_reg(intp,
+                                               R0900_P1_TSSPEED, 0x14);
+                               stv0900_write_reg(intp,
+                                               R0900_P2_TSSPEED, 0x28);
+                               break;
+                       }
+                       break;
+               case STV0900_SERIAL_PUNCT_CLOCK:
+               case STV0900_SERIAL_CONT_CLOCK:
+               default:
+                       switch (path2_ts) {
+                       case STV0900_SERIAL_PUNCT_CLOCK:
+                       case STV0900_SERIAL_CONT_CLOCK:
+                       default:
+                               stv0900_write_reg(intp,
+                                               R0900_TSGENERAL, 0x0C);
+                               break;
+                       case STV0900_PARALLEL_PUNCT_CLOCK:
+                       case STV0900_DVBCI_CLOCK:
+                               stv0900_write_reg(intp,
+                                               R0900_TSGENERAL, 0x0A);
+                               dprintk("%s: 0x0a\n", __func__);
+                               break;
+                       }
+                       break;
+               }
+       } else {
+               switch (path1_ts) {
+               case STV0900_PARALLEL_PUNCT_CLOCK:
+               case STV0900_DVBCI_CLOCK:
+                       switch (path2_ts) {
+                       case STV0900_SERIAL_PUNCT_CLOCK:
+                       case STV0900_SERIAL_CONT_CLOCK:
+                       default:
+                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
+                                                       0x10);
+                               break;
+                       case STV0900_PARALLEL_PUNCT_CLOCK:
+                       case STV0900_DVBCI_CLOCK:
+                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
+                                                       0x16);
+                               stv0900_write_bits(intp,
+                                               F0900_P1_TSFIFO_MANSPEED, 3);
+                               stv0900_write_bits(intp,
+                                               F0900_P2_TSFIFO_MANSPEED, 0);
+                               stv0900_write_reg(intp, R0900_P1_TSSPEED,
+                                                       0x14);
+                               stv0900_write_reg(intp, R0900_P2_TSSPEED,
+                                                       0x28);
+                               break;
+                       }
+
+                       break;
+               case STV0900_SERIAL_PUNCT_CLOCK:
+               case STV0900_SERIAL_CONT_CLOCK:
+               default:
+                       switch (path2_ts) {
+                       case STV0900_SERIAL_PUNCT_CLOCK:
+                       case STV0900_SERIAL_CONT_CLOCK:
+                       default:
+                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
+                                                       0x14);
+                               break;
+                       case STV0900_PARALLEL_PUNCT_CLOCK:
+                       case STV0900_DVBCI_CLOCK:
+                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
+                                                       0x12);
+                               dprintk("%s: 0x12\n", __func__);
+                               break;
+                       }
+
+                       break;
+               }
+       }
+
+       switch (path1_ts) {
+       case STV0900_PARALLEL_PUNCT_CLOCK:
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
+               break;
+       case STV0900_DVBCI_CLOCK:
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
+               break;
+       case STV0900_SERIAL_PUNCT_CLOCK:
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
+               break;
+       case STV0900_SERIAL_CONT_CLOCK:
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
+               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
+               break;
+       default:
+               break;
+       }
+
+       switch (path2_ts) {
+       case STV0900_PARALLEL_PUNCT_CLOCK:
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
+               break;
+       case STV0900_DVBCI_CLOCK:
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
+               break;
+       case STV0900_SERIAL_PUNCT_CLOCK:
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
+               break;
+       case STV0900_SERIAL_CONT_CLOCK:
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
+               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
+               break;
+       default:
+               break;
+       }
+
+       stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+       stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+       stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+       stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
+}
+
+void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+                                                       u32 bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops *tuner_ops = NULL;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+
+       if (tuner_ops->set_frequency) {
+               if ((tuner_ops->set_frequency(fe, frequency)) < 0)
+                       dprintk("%s: Invalid parameter\n", __func__);
+               else
+                       dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+       }
+
+       if (tuner_ops->set_bandwidth) {
+               if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+                       dprintk("%s: Invalid parameter\n", __func__);
+               else
+                       dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+       }
+}
+
+void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops *tuner_ops = NULL;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+
+       if (tuner_ops->set_bandwidth) {
+               if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+                       dprintk("%s: Invalid parameter\n", __func__);
+               else
+                       dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+       }
+}
+
+u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod)
+{
+       u32 freq, round;
+       /*      Formulat :
+       Tuner_Frequency(MHz)    = Regs / 64
+       Tuner_granularity(MHz)  = Regs / 2048
+       real_Tuner_Frequency    = Tuner_Frequency(MHz) - Tuner_granularity(MHz)
+       */
+       freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) +
+               (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) +
+               stv0900_get_bits(intp, TUN_RFFREQ0);
+
+       freq = (freq * 1000) / 64;
+
+       round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) +
+               stv0900_get_bits(intp, TUN_RFRESTE0);
+
+       round = (round * 1000) / 2048;
+
+       return freq + round;
+}
+
+void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
+                                               u32 Bandwidth, int demod)
+{
+       u32 tunerFrequency;
+       /* Formulat:
+       Tuner_frequency_reg= Frequency(MHz)*64
+       */
+       tunerFrequency = (Frequency * 64) / 1000;
+
+       stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10));
+       stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff);
+       stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03));
+       /* Low Pass Filter = BW /2 (MHz)*/
+       stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000);
+       /* Tuner Write trig */
+       stv0900_write_reg(intp, TNRLD, 1);
+}
+
+static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
+                               const struct stv0900_table *lookup,
+                               enum fe_stv0900_demod_num demod)
+{
+       s32 agc_gain = 0,
+               imin,
+               imax,
+               i,
+               rf_lvl = 0;
+
+       dprintk("%s\n", __func__);
+
+       if ((lookup == NULL) || (lookup->size <= 0))
+               return 0;
+
+       agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+                               stv0900_get_bits(intp, AGCIQ_VALUE0));
+
+       imin = 0;
+       imax = lookup->size - 1;
+       if (INRANGE(lookup->table[imin].regval, agc_gain,
+                                       lookup->table[imax].regval)) {
+               while ((imax - imin) > 1) {
+                       i = (imax + imin) >> 1;
+
+                       if (INRANGE(lookup->table[imin].regval,
+                                       agc_gain,
+                                       lookup->table[i].regval))
+                               imax = i;
+                       else
+                               imin = i;
+               }
+
+               rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
+               rf_lvl *= (lookup->table[imax].realval -
+                               lookup->table[imin].realval);
+               rf_lvl /= (lookup->table[imax].regval -
+                               lookup->table[imin].regval);
+               rf_lvl += lookup->table[imin].realval;
+       } else if (agc_gain > lookup->table[0].regval)
+               rf_lvl = 5;
+       else if (agc_gain < lookup->table[lookup->size-1].regval)
+               rf_lvl = -100;
+
+       dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
+
+       return rf_lvl;
+}
+
+static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *internal = state->internal;
+       s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
+                                                               state->demod);
+
+       rflevel = (rflevel + 100) * (65535 / 70);
+       if (rflevel < 0)
+               rflevel = 0;
+
+       if (rflevel > 65535)
+               rflevel = 65535;
+
+       *strength = rflevel;
+
+       return 0;
+}
+
+static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
+                                       const struct stv0900_table *lookup)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       s32     c_n = -100,
+               regval,
+               imin,
+               imax,
+               i,
+               noise_field1,
+               noise_field0;
+
+       dprintk("%s\n", __func__);
+
+       if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
+               noise_field1 = NOSPLHT_NORMED1;
+               noise_field0 = NOSPLHT_NORMED0;
+       } else {
+               noise_field1 = NOSDATAT_NORMED1;
+               noise_field0 = NOSDATAT_NORMED0;
+       }
+
+       if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
+               if ((lookup != NULL) && lookup->size) {
+                       regval = 0;
+                       msleep(5);
+                       for (i = 0; i < 16; i++) {
+                               regval += MAKEWORD(stv0900_get_bits(intp,
+                                                               noise_field1),
+                                               stv0900_get_bits(intp,
+                                                               noise_field0));
+                               msleep(1);
+                       }
+
+                       regval /= 16;
+                       imin = 0;
+                       imax = lookup->size - 1;
+                       if (INRANGE(lookup->table[imin].regval,
+                                       regval,
+                                       lookup->table[imax].regval)) {
+                               while ((imax - imin) > 1) {
+                                       i = (imax + imin) >> 1;
+                                       if (INRANGE(lookup->table[imin].regval,
+                                                   regval,
+                                                   lookup->table[i].regval))
+                                               imax = i;
+                                       else
+                                               imin = i;
+                               }
+
+                               c_n = ((regval - lookup->table[imin].regval)
+                                               * (lookup->table[imax].realval
+                                               - lookup->table[imin].realval)
+                                               / (lookup->table[imax].regval
+                                               - lookup->table[imin].regval))
+                                               + lookup->table[imin].realval;
+                       } else if (regval < lookup->table[imin].regval)
+                               c_n = 1000;
+               }
+       }
+
+       return c_n;
+}
+
+static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       u8 err_val1, err_val0;
+       u32 header_err_val = 0;
+
+       *ucblocks = 0x0;
+       if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
+               /* DVB-S2 delineator errors count */
+
+               /* retreiving number for errnous headers */
+               err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
+               err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
+               header_err_val = (err_val1 << 8) | err_val0;
+
+               /* retreiving number for errnous packets */
+               err_val1 = stv0900_read_reg(intp, UPCRCKO1);
+               err_val0 = stv0900_read_reg(intp, UPCRCKO0);
+               *ucblocks = (err_val1 << 8) | err_val0;
+               *ucblocks += header_err_val;
+       }
+
+       return 0;
+}
+
+static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       s32 snrlcl = stv0900_carr_get_quality(fe,
+                       (const struct stv0900_table *)&stv0900_s2_cn);
+       snrlcl = (snrlcl + 30) * 384;
+       if (snrlcl < 0)
+               snrlcl = 0;
+
+       if (snrlcl > 65535)
+               snrlcl = 65535;
+
+       *snr = snrlcl;
+
+       return 0;
+}
+
+static u32 stv0900_get_ber(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       u32 ber = 10000000, i;
+       s32 demod_state;
+
+       demod_state = stv0900_get_bits(intp, HEADER_MODE);
+
+       switch (demod_state) {
+       case STV0900_SEARCH:
+       case STV0900_PLH_DETECTED:
+       default:
+               ber = 10000000;
+               break;
+       case STV0900_DVBS_FOUND:
+               ber = 0;
+               for (i = 0; i < 5; i++) {
+                       msleep(5);
+                       ber += stv0900_get_err_count(intp, 0, demod);
+               }
+
+               ber /= 5;
+               if (stv0900_get_bits(intp, PRFVIT)) {
+                       ber *= 9766;
+                       ber = ber >> 13;
+               }
+
+               break;
+       case STV0900_DVBS2_FOUND:
+               ber = 0;
+               for (i = 0; i < 5; i++) {
+                       msleep(5);
+                       ber += stv0900_get_err_count(intp, 0, demod);
+               }
+
+               ber /= 5;
+               if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
+                       ber *= 9766;
+                       ber = ber >> 13;
+               }
+
+               break;
+       }
+
+       return ber;
+}
+
+static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *internal = state->internal;
+
+       *ber = stv0900_get_ber(internal, state->demod);
+
+       return 0;
+}
+
+int stv0900_get_demod_lock(struct stv0900_internal *intp,
+                       enum fe_stv0900_demod_num demod, s32 time_out)
+{
+       s32 timer = 0,
+               lock = 0;
+
+       enum fe_stv0900_search_state    dmd_state;
+
+       while ((timer < time_out) && (lock == 0)) {
+               dmd_state = stv0900_get_bits(intp, HEADER_MODE);
+               dprintk("Demod State = %d\n", dmd_state);
+               switch (dmd_state) {
+               case STV0900_SEARCH:
+               case STV0900_PLH_DETECTED:
+               default:
+                       lock = 0;
+                       break;
+               case STV0900_DVBS2_FOUND:
+               case STV0900_DVBS_FOUND:
+                       lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
+                       break;
+               }
+
+               if (lock == 0)
+                       msleep(10);
+
+               timer += 10;
+       }
+
+       if (lock)
+               dprintk("DEMOD LOCK OK\n");
+       else
+               dprintk("DEMOD LOCK FAIL\n");
+
+       return lock;
+}
+
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       s32 regflist,
+       i;
+
+       dprintk("%s\n", __func__);
+
+       regflist = MODCODLST0;
+
+       for (i = 0; i < 16; i++)
+               stv0900_write_reg(intp, regflist + i, 0xff);
+}
+
+void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       u32 matype,
+               mod_code,
+               fmod,
+               reg_index,
+               field_index;
+
+       dprintk("%s\n", __func__);
+
+       if (intp->chip_id <= 0x11) {
+               msleep(5);
+
+               mod_code = stv0900_read_reg(intp, PLHMODCOD);
+               matype = mod_code & 0x3;
+               mod_code = (mod_code & 0x7f) >> 2;
+
+               reg_index = MODCODLSTF - mod_code / 2;
+               field_index = mod_code % 2;
+
+               switch (matype) {
+               case 0:
+               default:
+                       fmod = 14;
+                       break;
+               case 1:
+                       fmod = 13;
+                       break;
+               case 2:
+                       fmod = 11;
+                       break;
+               case 3:
+                       fmod = 7;
+                       break;
+               }
+
+               if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
+                                               && (matype <= 1)) {
+                       if (field_index == 0)
+                               stv0900_write_reg(intp, reg_index,
+                                                       0xf0 | fmod);
+                       else
+                               stv0900_write_reg(intp, reg_index,
+                                                       (fmod << 4) | 0xf);
+               }
+
+       } else if (intp->chip_id >= 0x12) {
+               for (reg_index = 0; reg_index < 7; reg_index++)
+                       stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
+
+               stv0900_write_reg(intp, MODCODLSTE, 0xff);
+               stv0900_write_reg(intp, MODCODLSTF, 0xcf);
+               for (reg_index = 0; reg_index < 8; reg_index++)
+                       stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
+
+
+       }
+}
+
+void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32 reg_index;
+
+       dprintk("%s\n", __func__);
+
+       stv0900_write_reg(intp, MODCODLST0, 0xff);
+       stv0900_write_reg(intp, MODCODLST1, 0xf0);
+       stv0900_write_reg(intp, MODCODLSTF, 0x0f);
+       for (reg_index = 0; reg_index < 13; reg_index++)
+               stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
+
+}
+
+static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+void stv0900_start_search(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       u32 freq;
+       s16 freq_s16 ;
+
+       stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+       if (intp->chip_id == 0x10)
+               stv0900_write_reg(intp, CORRELEXP, 0xaa);
+
+       if (intp->chip_id < 0x20)
+               stv0900_write_reg(intp, CARHDR, 0x55);
+
+       if (intp->chip_id <= 0x20) {
+               if (intp->symbol_rate[0] <= 5000000) {
+                       stv0900_write_reg(intp, CARCFG, 0x44);
+                       stv0900_write_reg(intp, CFRUP1, 0x0f);
+                       stv0900_write_reg(intp, CFRUP0, 0xff);
+                       stv0900_write_reg(intp, CFRLOW1, 0xf0);
+                       stv0900_write_reg(intp, CFRLOW0, 0x00);
+                       stv0900_write_reg(intp, RTCS2, 0x68);
+               } else {
+                       stv0900_write_reg(intp, CARCFG, 0xc4);
+                       stv0900_write_reg(intp, RTCS2, 0x44);
+               }
+
+       } else { /*cut 3.0 above*/
+               if (intp->symbol_rate[demod] <= 5000000)
+                       stv0900_write_reg(intp, RTCS2, 0x68);
+               else
+                       stv0900_write_reg(intp, RTCS2, 0x44);
+
+               stv0900_write_reg(intp, CARCFG, 0x46);
+               if (intp->srch_algo[demod] == STV0900_WARM_START) {
+                       freq = 1000 << 16;
+                       freq /= (intp->mclk / 1000);
+                       freq_s16 = (s16)freq;
+               } else {
+                       freq = (intp->srch_range[demod] / 2000);
+                       if (intp->symbol_rate[demod] <= 5000000)
+                               freq += 80;
+                       else
+                               freq += 600;
+
+                       freq = freq << 16;
+                       freq /= (intp->mclk / 1000);
+                       freq_s16 = (s16)freq;
+               }
+
+               stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
+               stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
+               freq_s16 *= (-1);
+               stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
+               stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
+       }
+
+       stv0900_write_reg(intp, CFRINIT1, 0);
+       stv0900_write_reg(intp, CFRINIT0, 0);
+
+       if (intp->chip_id >= 0x20) {
+               stv0900_write_reg(intp, EQUALCFG, 0x41);
+               stv0900_write_reg(intp, FFECFG, 0x41);
+
+               if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+                       (intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
+                       (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
+                       stv0900_write_reg(intp, VITSCALE,
+                                                               0x82);
+                       stv0900_write_reg(intp, VAVSRVIT, 0x0);
+               }
+       }
+
+       stv0900_write_reg(intp, SFRSTEP, 0x00);
+       stv0900_write_reg(intp, TMGTHRISE, 0xe0);
+       stv0900_write_reg(intp, TMGTHFALL, 0xc0);
+       stv0900_write_bits(intp, SCAN_ENABLE, 0);
+       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+       stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
+       stv0900_write_reg(intp, RTC, 0x88);
+       if (intp->chip_id >= 0x20) {
+               if (intp->symbol_rate[demod] < 2000000) {
+                       if (intp->chip_id <= 0x20)
+                               stv0900_write_reg(intp, CARFREQ, 0x39);
+                       else  /*cut 3.0*/
+                               stv0900_write_reg(intp, CARFREQ, 0x89);
+
+                       stv0900_write_reg(intp, CARHDR, 0x40);
+               } else if (intp->symbol_rate[demod] < 10000000) {
+                       stv0900_write_reg(intp, CARFREQ, 0x4c);
+                       stv0900_write_reg(intp, CARHDR, 0x20);
+               } else {
+                       stv0900_write_reg(intp, CARFREQ, 0x4b);
+                       stv0900_write_reg(intp, CARHDR, 0x20);
+               }
+
+       } else {
+               if (intp->symbol_rate[demod] < 10000000)
+                       stv0900_write_reg(intp, CARFREQ, 0xef);
+               else
+                       stv0900_write_reg(intp, CARFREQ, 0xed);
+       }
+
+       switch (intp->srch_algo[demod]) {
+       case STV0900_WARM_START:
+               stv0900_write_reg(intp, DMDISTATE, 0x1f);
+               stv0900_write_reg(intp, DMDISTATE, 0x18);
+               break;
+       case STV0900_COLD_START:
+               stv0900_write_reg(intp, DMDISTATE, 0x1f);
+               stv0900_write_reg(intp, DMDISTATE, 0x15);
+               break;
+       default:
+               break;
+       }
+}
+
+u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
+                                                       s32 pilot, u8 chip_id)
+{
+       u8 aclc_value = 0x29;
+       s32 i;
+       const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
+
+       dprintk("%s\n", __func__);
+
+       if (chip_id <= 0x12) {
+               cls2 = FE_STV0900_S2CarLoop;
+               cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+               cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+       } else if (chip_id == 0x20) {
+               cls2 = FE_STV0900_S2CarLoopCut20;
+               cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
+               cllas2 = FE_STV0900_S2APSKCarLoopCut20;
+       } else {
+               cls2 = FE_STV0900_S2CarLoopCut30;
+               cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
+               cllas2 = FE_STV0900_S2APSKCarLoopCut30;
+       }
+
+       if (modcode < STV0900_QPSK_12) {
+               i = 0;
+               while ((i < 3) && (modcode != cllqs2[i].modcode))
+                       i++;
+
+               if (i >= 3)
+                       i = 2;
+       } else {
+               i = 0;
+               while ((i < 14) && (modcode != cls2[i].modcode))
+                       i++;
+
+               if (i >= 14) {
+                       i = 0;
+                       while ((i < 11) && (modcode != cllas2[i].modcode))
+                               i++;
+
+                       if (i >= 11)
+                               i = 10;
+               }
+       }
+
+       if (modcode <= STV0900_QPSK_25) {
+               if (pilot) {
+                       if (srate <= 3000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_on_2;
+                       else if (srate <= 7000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_on_5;
+                       else if (srate <= 15000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_on_10;
+                       else if (srate <= 25000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_on_20;
+                       else
+                               aclc_value = cllqs2[i].car_loop_pilots_on_30;
+               } else {
+                       if (srate <= 3000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_off_2;
+                       else if (srate <= 7000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_off_5;
+                       else if (srate <= 15000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_off_10;
+                       else if (srate <= 25000000)
+                               aclc_value = cllqs2[i].car_loop_pilots_off_20;
+                       else
+                               aclc_value = cllqs2[i].car_loop_pilots_off_30;
+               }
+
+       } else if (modcode <= STV0900_8PSK_910) {
+               if (pilot) {
+                       if (srate <= 3000000)
+                               aclc_value = cls2[i].car_loop_pilots_on_2;
+                       else if (srate <= 7000000)
+                               aclc_value = cls2[i].car_loop_pilots_on_5;
+                       else if (srate <= 15000000)
+                               aclc_value = cls2[i].car_loop_pilots_on_10;
+                       else if (srate <= 25000000)
+                               aclc_value = cls2[i].car_loop_pilots_on_20;
+                       else
+                               aclc_value = cls2[i].car_loop_pilots_on_30;
+               } else {
+                       if (srate <= 3000000)
+                               aclc_value = cls2[i].car_loop_pilots_off_2;
+                       else if (srate <= 7000000)
+                               aclc_value = cls2[i].car_loop_pilots_off_5;
+                       else if (srate <= 15000000)
+                               aclc_value = cls2[i].car_loop_pilots_off_10;
+                       else if (srate <= 25000000)
+                               aclc_value = cls2[i].car_loop_pilots_off_20;
+                       else
+                               aclc_value = cls2[i].car_loop_pilots_off_30;
+               }
+
+       } else {
+               if (srate <= 3000000)
+                       aclc_value = cllas2[i].car_loop_pilots_on_2;
+               else if (srate <= 7000000)
+                       aclc_value = cllas2[i].car_loop_pilots_on_5;
+               else if (srate <= 15000000)
+                       aclc_value = cllas2[i].car_loop_pilots_on_10;
+               else if (srate <= 25000000)
+                       aclc_value = cllas2[i].car_loop_pilots_on_20;
+               else
+                       aclc_value = cllas2[i].car_loop_pilots_on_30;
+       }
+
+       return aclc_value;
+}
+
+u8 stv0900_get_optim_short_carr_loop(s32 srate,
+                               enum fe_stv0900_modulation modulation,
+                               u8 chip_id)
+{
+       const struct stv0900_short_frames_car_loop_optim *s2scl;
+       const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
+       s32 mod_index = 0;
+       u8 aclc_value = 0x0b;
+
+       dprintk("%s\n", __func__);
+
+       s2scl = FE_STV0900_S2ShortCarLoop;
+       s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
+
+       switch (modulation) {
+       case STV0900_QPSK:
+       default:
+               mod_index = 0;
+               break;
+       case STV0900_8PSK:
+               mod_index = 1;
+               break;
+       case STV0900_16APSK:
+               mod_index = 2;
+               break;
+       case STV0900_32APSK:
+               mod_index = 3;
+               break;
+       }
+
+       if (chip_id >= 0x30) {
+               if (srate <= 3000000)
+                       aclc_value = s2sclc30[mod_index].car_loop_2;
+               else if (srate <= 7000000)
+                       aclc_value = s2sclc30[mod_index].car_loop_5;
+               else if (srate <= 15000000)
+                       aclc_value = s2sclc30[mod_index].car_loop_10;
+               else if (srate <= 25000000)
+                       aclc_value = s2sclc30[mod_index].car_loop_20;
+               else
+                       aclc_value = s2sclc30[mod_index].car_loop_30;
+
+       } else if (chip_id >= 0x20) {
+               if (srate <= 3000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut20_2;
+               else if (srate <= 7000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut20_5;
+               else if (srate <= 15000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut20_10;
+               else if (srate <= 25000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut20_20;
+               else
+                       aclc_value = s2scl[mod_index].car_loop_cut20_30;
+
+       } else {
+               if (srate <= 3000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut12_2;
+               else if (srate <= 7000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut12_5;
+               else if (srate <= 15000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut12_10;
+               else if (srate <= 25000000)
+                       aclc_value = s2scl[mod_index].car_loop_cut12_20;
+               else
+                       aclc_value = s2scl[mod_index].car_loop_cut12_30;
+
+       }
+
+       return aclc_value;
+}
+
+static
+enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_mode LDPC_Mode,
+                                       enum fe_stv0900_demod_num demod)
+{
+       enum fe_stv0900_error error = STV0900_NO_ERROR;
+       s32 reg_ind;
+
+       dprintk("%s\n", __func__);
+
+       switch (LDPC_Mode) {
+       case STV0900_DUAL:
+       default:
+               if ((intp->demod_mode != STV0900_DUAL)
+                       || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
+                       stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
+
+                       intp->demod_mode = STV0900_DUAL;
+
+                       stv0900_write_bits(intp, F0900_FRESFEC, 1);
+                       stv0900_write_bits(intp, F0900_FRESFEC, 0);
+
+                       for (reg_ind = 0; reg_ind < 7; reg_ind++)
+                               stv0900_write_reg(intp,
+                                               R0900_P1_MODCODLST0 + reg_ind,
+                                               0xff);
+                       for (reg_ind = 0; reg_ind < 8; reg_ind++)
+                               stv0900_write_reg(intp,
+                                               R0900_P1_MODCODLST7 + reg_ind,
+                                               0xcc);
+
+                       stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
+                       stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
+
+                       for (reg_ind = 0; reg_ind < 7; reg_ind++)
+                               stv0900_write_reg(intp,
+                                               R0900_P2_MODCODLST0 + reg_ind,
+                                               0xff);
+                       for (reg_ind = 0; reg_ind < 8; reg_ind++)
+                               stv0900_write_reg(intp,
+                                               R0900_P2_MODCODLST7 + reg_ind,
+                                               0xcc);
+
+                       stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
+                       stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
+               }
+
+               break;
+       case STV0900_SINGLE:
+               if (demod == STV0900_DEMOD_2) {
+                       stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
+                       stv0900_activate_s2_modcod_single(intp,
+                                                       STV0900_DEMOD_2);
+                       stv0900_write_reg(intp, R0900_GENCFG, 0x06);
+               } else {
+                       stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
+                       stv0900_activate_s2_modcod_single(intp,
+                                                       STV0900_DEMOD_1);
+                       stv0900_write_reg(intp, R0900_GENCFG, 0x04);
+               }
+
+               intp->demod_mode = STV0900_SINGLE;
+
+               stv0900_write_bits(intp, F0900_FRESFEC, 1);
+               stv0900_write_bits(intp, F0900_FRESFEC, 0);
+               stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
+               stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
+               stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
+               stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
+               break;
+       }
+
+       return error;
+}
+
+static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
+                                       struct stv0900_init_params *p_init)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       enum fe_stv0900_error error = STV0900_NO_ERROR;
+       enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+       struct stv0900_internal *intp = NULL;
+       int selosci, i;
+
+       struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
+                                               state->config->demod_address);
+
+       dprintk("%s\n", __func__);
+
+       if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
+               state->internal = temp_int->internal;
+               (state->internal->dmds_used)++;
+               dprintk("%s: Find Internal Structure!\n", __func__);
+               return STV0900_NO_ERROR;
+       } else {
+               state->internal = kmalloc(sizeof(struct stv0900_internal),
+                                                               GFP_KERNEL);
+               if (state->internal == NULL)
+                       return STV0900_INVALID_HANDLE;
+               temp_int = append_internal(state->internal);
+               if (temp_int == NULL) {
+                       kfree(state->internal);
+                       state->internal = NULL;
+                       return STV0900_INVALID_HANDLE;
+               }
+               state->internal->dmds_used = 1;
+               state->internal->i2c_adap = state->i2c_adap;
+               state->internal->i2c_addr = state->config->demod_address;
+               state->internal->clkmode = state->config->clkmode;
+               state->internal->errs = STV0900_NO_ERROR;
+               dprintk("%s: Create New Internal Structure!\n", __func__);
+       }
+
+       if (state->internal == NULL) {
+               error = STV0900_INVALID_HANDLE;
+               return error;
+       }
+
+       demodError = stv0900_initialize(state->internal);
+       if (demodError == STV0900_NO_ERROR) {
+                       error = STV0900_NO_ERROR;
+       } else {
+               if (demodError == STV0900_INVALID_HANDLE)
+                       error = STV0900_INVALID_HANDLE;
+               else
+                       error = STV0900_I2C_ERROR;
+
+               return error;
+       }
+
+       intp = state->internal;
+
+       intp->demod_mode = p_init->demod_mode;
+       stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1);
+       intp->chip_id = stv0900_read_reg(intp, R0900_MID);
+       intp->rolloff = p_init->rolloff;
+       intp->quartz = p_init->dmd_ref_clk;
+
+       stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+       stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+       intp->ts_config = p_init->ts_config;
+       if (intp->ts_config == NULL)
+               stv0900_set_ts_parallel_serial(intp,
+                               p_init->path1_ts_clock,
+                               p_init->path2_ts_clock);
+       else {
+               for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
+                       stv0900_write_reg(intp,
+                                       intp->ts_config[i].addr,
+                                       intp->ts_config[i].val);
+
+               stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
+               stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
+               stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
+               stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
+       }
+
+       intp->tuner_type[0] = p_init->tuner1_type;
+       intp->tuner_type[1] = p_init->tuner2_type;
+       /* tuner init */
+       switch (p_init->tuner1_type) {
+       case 3: /*FE_AUTO_STB6100:*/
+               stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c);
+               stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86);
+               stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18);
+               stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */
+               stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05);
+               stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17);
+               stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f);
+               stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0);
+               stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3);
+               break;
+       /* case FE_SW_TUNER: */
+       default:
+               stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6);
+               break;
+       }
+
+       stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+       switch (p_init->tuner1_adc) {
+       case 1:
+               stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
+               break;
+       default:
+               break;
+       }
+
+       stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */
+
+       /* tuner init */
+       switch (p_init->tuner2_type) {
+       case 3: /*FE_AUTO_STB6100:*/
+               stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c);
+               stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86);
+               stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18);
+               stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */
+               stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05);
+               stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17);
+               stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f);
+               stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0);
+               stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3);
+               break;
+       /* case FE_SW_TUNER: */
+       default:
+               stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6);
+               break;
+       }
+
+       stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+       switch (p_init->tuner2_adc) {
+       case 1:
+               stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
+               break;
+       default:
+               break;
+       }
+
+       stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */
+
+       stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
+       stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
+       stv0900_set_mclk(intp, 135000000);
+       msleep(3);
+
+       switch (intp->clkmode) {
+       case 0:
+       case 2:
+               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
+               break;
+       default:
+               selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
+               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
+               break;
+       }
+       msleep(3);
+
+       intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
+       if (intp->errs)
+               error = STV0900_I2C_ERROR;
+
+       return error;
+}
+
+static int stv0900_status(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       enum fe_stv0900_search_state demod_state;
+       int locked = FALSE;
+       u8 tsbitrate0_val, tsbitrate1_val;
+       s32 bitrate;
+
+       demod_state = stv0900_get_bits(intp, HEADER_MODE);
+       switch (demod_state) {
+       case STV0900_SEARCH:
+       case STV0900_PLH_DETECTED:
+       default:
+               locked = FALSE;
+               break;
+       case STV0900_DVBS2_FOUND:
+               locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+                               stv0900_get_bits(intp, PKTDELIN_LOCK) &&
+                               stv0900_get_bits(intp, TSFIFO_LINEOK);
+               break;
+       case STV0900_DVBS_FOUND:
+               locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
+                               stv0900_get_bits(intp, LOCKEDVIT) &&
+                               stv0900_get_bits(intp, TSFIFO_LINEOK);
+               break;
+       }
+
+       dprintk("%s: locked = %d\n", __func__, locked);
+
+       if (stvdebug) {
+               /* Print TS bitrate */
+               tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
+               tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
+               /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
+               bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
+                       * (tsbitrate1_val << 8 | tsbitrate0_val);
+               bitrate /= 16384;
+               dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
+       };
+
+       return locked;
+}
+
+static enum dvbfe_search stv0900_search(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+       struct stv0900_search_params p_search;
+       struct stv0900_signal_info p_result = intp->result[demod];
+
+       enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+       dprintk("%s: ", __func__);
+
+       if (!(INRANGE(100000, c->symbol_rate, 70000000)))
+               return DVBFE_ALGO_SEARCH_FAILED;
+
+       if (state->config->set_ts_params)
+               state->config->set_ts_params(fe, 0);
+
+       p_result.locked = FALSE;
+       p_search.path = demod;
+       p_search.frequency = c->frequency;
+       p_search.symbol_rate = c->symbol_rate;
+       p_search.search_range = 10000000;
+       p_search.fec = STV0900_FEC_UNKNOWN;
+       p_search.standard = STV0900_AUTO_SEARCH;
+       p_search.iq_inversion = STV0900_IQ_AUTO;
+       p_search.search_algo = STV0900_BLIND_SEARCH;
+       /* Speeds up DVB-S searching */
+       if (c->delivery_system == SYS_DVBS)
+               p_search.standard = STV0900_SEARCH_DVBS1;
+
+       intp->srch_standard[demod] = p_search.standard;
+       intp->symbol_rate[demod] = p_search.symbol_rate;
+       intp->srch_range[demod] = p_search.search_range;
+       intp->freq[demod] = p_search.frequency;
+       intp->srch_algo[demod] = p_search.search_algo;
+       intp->srch_iq_inv[demod] = p_search.iq_inversion;
+       intp->fec[demod] = p_search.fec;
+       if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+                               (intp->errs == STV0900_NO_ERROR)) {
+               p_result.locked = intp->result[demod].locked;
+               p_result.standard = intp->result[demod].standard;
+               p_result.frequency = intp->result[demod].frequency;
+               p_result.symbol_rate = intp->result[demod].symbol_rate;
+               p_result.fec = intp->result[demod].fec;
+               p_result.modcode = intp->result[demod].modcode;
+               p_result.pilot = intp->result[demod].pilot;
+               p_result.frame_len = intp->result[demod].frame_len;
+               p_result.spectrum = intp->result[demod].spectrum;
+               p_result.rolloff = intp->result[demod].rolloff;
+               p_result.modulation = intp->result[demod].modulation;
+       } else {
+               p_result.locked = FALSE;
+               switch (intp->err[demod]) {
+               case STV0900_I2C_ERROR:
+                       error = STV0900_I2C_ERROR;
+                       break;
+               case STV0900_NO_ERROR:
+               default:
+                       error = STV0900_SEARCH_FAILED;
+                       break;
+               }
+       }
+
+       if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
+               dprintk("Search Success\n");
+               return DVBFE_ALGO_SEARCH_SUCCESS;
+       } else {
+               dprintk("Search Fail\n");
+               return DVBFE_ALGO_SEARCH_FAILED;
+       }
+
+}
+
+static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+
+       dprintk("%s: ", __func__);
+
+       if ((stv0900_status(state->internal, state->demod)) == TRUE) {
+               dprintk("DEMOD LOCK OK\n");
+               *status = FE_HAS_CARRIER
+                       | FE_HAS_VITERBI
+                       | FE_HAS_SYNC
+                       | FE_HAS_LOCK;
+               if (state->config->set_lock_led)
+                       state->config->set_lock_led(fe, 1);
+       } else {
+               *status = 0;
+               if (state->config->set_lock_led)
+                       state->config->set_lock_led(fe, 0);
+               dprintk("DEMOD LOCK FAIL\n");
+       }
+
+       return 0;
+}
+
+static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
+{
+
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       if (stop_ts == TRUE)
+               stv0900_write_bits(intp, RST_HWARE, 1);
+       else
+               stv0900_write_bits(intp, RST_HWARE, 0);
+
+       return 0;
+}
+
+static int stv0900_diseqc_init(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
+       stv0900_write_bits(intp, DISEQC_RESET, 1);
+       stv0900_write_bits(intp, DISEQC_RESET, 0);
+
+       return 0;
+}
+
+static int stv0900_init(struct dvb_frontend *fe)
+{
+       dprintk("%s\n", __func__);
+
+       stv0900_stop_ts(fe, 1);
+       stv0900_diseqc_init(fe);
+
+       return 0;
+}
+
+static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
+                               u32 NbData, enum fe_stv0900_demod_num demod)
+{
+       s32 i = 0;
+
+       stv0900_write_bits(intp, DIS_PRECHARGE, 1);
+       while (i < NbData) {
+               while (stv0900_get_bits(intp, FIFO_FULL))
+                       ;/* checkpatch complains */
+               stv0900_write_reg(intp, DISTXDATA, data[i]);
+               i++;
+       }
+
+       stv0900_write_bits(intp, DIS_PRECHARGE, 0);
+       i = 0;
+       while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
+               msleep(10);
+               i++;
+       }
+
+       return 0;
+}
+
+static int stv0900_send_master_cmd(struct dvb_frontend *fe,
+                                       struct dvb_diseqc_master_cmd *cmd)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+
+       return stv0900_diseqc_send(state->internal,
+                               cmd->msg,
+                               cmd->msg_len,
+                               state->demod);
+}
+
+static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       u8 data;
+
+
+       switch (burst) {
+       case SEC_MINI_A:
+               stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
+               data = 0x00;
+               stv0900_diseqc_send(intp, &data, 1, state->demod);
+               break;
+       case SEC_MINI_B:
+               stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
+               data = 0xff;
+               stv0900_diseqc_send(intp, &data, 1, state->demod);
+               break;
+       }
+
+       return 0;
+}
+
+static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
+                               struct dvb_diseqc_slave_reply *reply)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       s32 i = 0;
+
+       reply->msg_len = 0;
+
+       while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
+               msleep(10);
+               i++;
+       }
+
+       if (stv0900_get_bits(intp, RX_END)) {
+               reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
+
+               for (i = 0; i < reply->msg_len; i++)
+                       reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
+       }
+
+       return 0;
+}
+
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
+
+       switch (toneoff) {
+       case SEC_TONE_ON:
+               /*Set the DiseqC mode to 22Khz _continues_ tone*/
+               stv0900_write_bits(intp, DISTX_MODE, 0);
+               stv0900_write_bits(intp, DISEQC_RESET, 1);
+               /*release DiseqC reset to enable the 22KHz tone*/
+               stv0900_write_bits(intp, DISEQC_RESET, 0);
+               break;
+       case SEC_TONE_OFF:
+               /*return diseqc mode to config->diseqc_mode.
+               Usually it's without _continues_ tone */
+               stv0900_write_bits(intp, DISTX_MODE,
+                               state->config->diseqc_mode);
+               /*maintain the DiseqC reset to disable the 22KHz tone*/
+               stv0900_write_bits(intp, DISEQC_RESET, 1);
+               stv0900_write_bits(intp, DISEQC_RESET, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void stv0900_release(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (state->config->set_lock_led)
+               state->config->set_lock_led(fe, 0);
+
+       if ((--(state->internal->dmds_used)) <= 0) {
+
+               dprintk("%s: Actually removing\n", __func__);
+
+               remove_inode(state->internal);
+               kfree(state->internal);
+       }
+
+       kfree(state);
+}
+
+static int stv0900_sleep(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (state->config->set_lock_led)
+               state->config->set_lock_led(fe, 0);
+
+       return 0;
+}
+
+static int stv0900_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       struct stv0900_signal_info p_result = intp->result[demod];
+
+       p->frequency = p_result.locked ? p_result.frequency : 0;
+       p->symbol_rate = p_result.locked ? p_result.symbol_rate : 0;
+       return 0;
+}
+
+static struct dvb_frontend_ops stv0900_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
+       .info = {
+               .name                   = "STV0900 frontend",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 125,
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .symbol_rate_tolerance  = 500,
+               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+                                         FE_CAN_FEC_7_8 | FE_CAN_QPSK    |
+                                         FE_CAN_2G_MODULATION |
+                                         FE_CAN_FEC_AUTO
+       },
+       .release                        = stv0900_release,
+       .init                           = stv0900_init,
+       .get_frontend                   = stv0900_get_frontend,
+       .sleep                          = stv0900_sleep,
+       .get_frontend_algo              = stv0900_frontend_algo,
+       .i2c_gate_ctrl                  = stv0900_i2c_gate_ctrl,
+       .diseqc_send_master_cmd         = stv0900_send_master_cmd,
+       .diseqc_send_burst              = stv0900_send_burst,
+       .diseqc_recv_slave_reply        = stv0900_recv_slave_reply,
+       .set_tone                       = stv0900_set_tone,
+       .search                         = stv0900_search,
+       .read_status                    = stv0900_read_status,
+       .read_ber                       = stv0900_read_ber,
+       .read_signal_strength           = stv0900_read_signal_strength,
+       .read_snr                       = stv0900_read_snr,
+       .read_ucblocks                  = stv0900_read_ucblocks,
+};
+
+struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+                                       struct i2c_adapter *i2c,
+                                       int demod)
+{
+       struct stv0900_state *state = NULL;
+       struct stv0900_init_params init_params;
+       enum fe_stv0900_error err_stv0900;
+
+       state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->demod            = demod;
+       state->config           = config;
+       state->i2c_adap         = i2c;
+
+       memcpy(&state->frontend.ops, &stv0900_ops,
+                       sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       switch (demod) {
+       case 0:
+       case 1:
+               init_params.dmd_ref_clk         = config->xtal;
+               init_params.demod_mode          = config->demod_mode;
+               init_params.rolloff             = STV0900_35;
+               init_params.path1_ts_clock      = config->path1_mode;
+               init_params.tun1_maddress       = config->tun1_maddress;
+               init_params.tun1_iq_inv         = STV0900_IQ_NORMAL;
+               init_params.tuner1_adc          = config->tun1_adc;
+               init_params.tuner1_type         = config->tun1_type;
+               init_params.path2_ts_clock      = config->path2_mode;
+               init_params.ts_config           = config->ts_config_regs;
+               init_params.tun2_maddress       = config->tun2_maddress;
+               init_params.tuner2_adc          = config->tun2_adc;
+               init_params.tuner2_type         = config->tun2_type;
+               init_params.tun2_iq_inv         = STV0900_IQ_SWAPPED;
+
+               err_stv0900 = stv0900_init_internal(&state->frontend,
+                                                       &init_params);
+
+               if (err_stv0900)
+                       goto error;
+
+               break;
+       default:
+               goto error;
+               break;
+       }
+
+       dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
+       return &state->frontend;
+
+error:
+       dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
+               __func__, demod);
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(stv0900_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0900 frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stv0900_init.h b/drivers/media/dvb-frontends/stv0900_init.h
new file mode 100644 (file)
index 0000000..b684df9
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * stv0900_init.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_INIT_H
+#define STV0900_INIT_H
+
+#include "stv0900_priv.h"
+
+/* DVBS2 C/N Look-Up table */
+static const struct stv0900_table stv0900_s2_cn = {
+       55,
+       {
+               { -30,  13348 }, /*C/N=-3dB*/
+               { -20,  12640 }, /*C/N=-2dB*/
+               { -10,  11883 }, /*C/N=-1dB*/
+               { 0,    11101 }, /*C/N=-0dB*/
+               { 5,    10718 }, /*C/N=0.5dB*/
+               { 10,   10339 }, /*C/N=1.0dB*/
+               { 15,   9947 }, /*C/N=1.5dB*/
+               { 20,   9552 }, /*C/N=2.0dB*/
+               { 25,   9183 }, /*C/N=2.5dB*/
+               { 30,   8799 }, /*C/N=3.0dB*/
+               { 35,   8422 }, /*C/N=3.5dB*/
+               { 40,   8062 }, /*C/N=4.0dB*/
+               { 45,   7707 }, /*C/N=4.5dB*/
+               { 50,   7353 }, /*C/N=5.0dB*/
+               { 55,   7025 }, /*C/N=5.5dB*/
+               { 60,   6684 }, /*C/N=6.0dB*/
+               { 65,   6331 }, /*C/N=6.5dB*/
+               { 70,   6036 }, /*C/N=7.0dB*/
+               { 75,   5727 }, /*C/N=7.5dB*/
+               { 80,   5437 }, /*C/N=8.0dB*/
+               { 85,   5164 }, /*C/N=8.5dB*/
+               { 90,   4902 }, /*C/N=9.0dB*/
+               { 95,   4653 }, /*C/N=9.5dB*/
+               { 100,  4408 }, /*C/N=10.0dB*/
+               { 105,  4187 }, /*C/N=10.5dB*/
+               { 110,  3961 }, /*C/N=11.0dB*/
+               { 115,  3751 }, /*C/N=11.5dB*/
+               { 120,  3558 }, /*C/N=12.0dB*/
+               { 125,  3368 }, /*C/N=12.5dB*/
+               { 130,  3191 }, /*C/N=13.0dB*/
+               { 135,  3017 }, /*C/N=13.5dB*/
+               { 140,  2862 }, /*C/N=14.0dB*/
+               { 145,  2710 }, /*C/N=14.5dB*/
+               { 150,  2565 }, /*C/N=15.0dB*/
+               { 160,  2300 }, /*C/N=16.0dB*/
+               { 170,  2058 }, /*C/N=17.0dB*/
+               { 180,  1849 }, /*C/N=18.0dB*/
+               { 190,  1663 }, /*C/N=19.0dB*/
+               { 200,  1495 }, /*C/N=20.0dB*/
+               { 210,  1349 }, /*C/N=21.0dB*/
+               { 220,  1222 }, /*C/N=22.0dB*/
+               { 230,  1110 }, /*C/N=23.0dB*/
+               { 240,  1011 }, /*C/N=24.0dB*/
+               { 250,  925 }, /*C/N=25.0dB*/
+               { 260,  853 }, /*C/N=26.0dB*/
+               { 270,  789 }, /*C/N=27.0dB*/
+               { 280,  734 }, /*C/N=28.0dB*/
+               { 290,  690 }, /*C/N=29.0dB*/
+               { 300,  650 }, /*C/N=30.0dB*/
+               { 310,  619 }, /*C/N=31.0dB*/
+               { 320,  593 }, /*C/N=32.0dB*/
+               { 330,  571 }, /*C/N=33.0dB*/
+               { 400,  498 }, /*C/N=40.0dB*/
+               { 450,  484 }, /*C/N=45.0dB*/
+               { 500,  481 }  /*C/N=50.0dB*/
+       }
+};
+
+/* RF level C/N Look-Up table */
+static const struct stv0900_table stv0900_rf = {
+       14,
+       {
+               { -5, 0xCAA1 }, /*-5dBm*/
+               { -10, 0xC229 }, /*-10dBm*/
+               { -15, 0xBB08 }, /*-15dBm*/
+               { -20, 0xB4BC }, /*-20dBm*/
+               { -25, 0xAD5A }, /*-25dBm*/
+               { -30, 0xA298 }, /*-30dBm*/
+               { -35, 0x98A8 }, /*-35dBm*/
+               { -40, 0x8389 }, /*-40dBm*/
+               { -45, 0x59BE }, /*-45dBm*/
+               { -50, 0x3A14 }, /*-50dBm*/
+               { -55, 0x2D11 }, /*-55dBm*/
+               { -60, 0x210D }, /*-60dBm*/
+               { -65, 0xA14F }, /*-65dBm*/
+               { -70, 0x7AA }  /*-70dBm*/
+       }
+};
+
+struct stv0900_car_loop_optim {
+       enum fe_stv0900_modcode modcode;
+       u8 car_loop_pilots_on_2;
+       u8 car_loop_pilots_off_2;
+       u8 car_loop_pilots_on_5;
+       u8 car_loop_pilots_off_5;
+       u8 car_loop_pilots_on_10;
+       u8 car_loop_pilots_off_10;
+       u8 car_loop_pilots_on_20;
+       u8 car_loop_pilots_off_20;
+       u8 car_loop_pilots_on_30;
+       u8 car_loop_pilots_off_30;
+
+};
+
+struct stv0900_short_frames_car_loop_optim {
+       enum fe_stv0900_modulation modulation;
+       u8 car_loop_cut12_2;    /* Cut 1.2,   SR<=3msps     */
+       u8 car_loop_cut20_2;    /* Cut 2.0,   SR<3msps      */
+       u8 car_loop_cut12_5;    /* Cut 1.2,   3<SR<=7msps   */
+       u8 car_loop_cut20_5;    /* Cut 2.0,   3<SR<=7msps   */
+       u8 car_loop_cut12_10;   /* Cut 1.2,   7<SR<=15msps  */
+       u8 car_loop_cut20_10;   /* Cut 2.0,   7<SR<=15msps  */
+       u8 car_loop_cut12_20;   /* Cut 1.2,   10<SR<=25msps */
+       u8 car_loop_cut20_20;   /* Cut 2.0,   10<SR<=25msps */
+       u8 car_loop_cut12_30;   /* Cut 1.2,   25<SR<=45msps */
+       u8 car_loop_cut20_30;   /* Cut 2.0,   10<SR<=45msps */
+
+};
+
+struct stv0900_short_frames_car_loop_optim_vs_mod {
+       enum fe_stv0900_modulation modulation;
+       u8 car_loop_2;    /* SR<3msps      */
+       u8 car_loop_5;    /* 3<SR<=7msps   */
+       u8 car_loop_10;   /* 7<SR<=15msps  */
+       u8 car_loop_20;   /* 10<SR<=25msps */
+       u8 car_loop_30;   /* 10<SR<=45msps */
+};
+
+/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_QPSK_12,      0x1C,   0x0D,   0x1B,   0x2C,   0x3A,
+                               0x1C,   0x2A,   0x3B,   0x2A,   0x1B },
+       { STV0900_QPSK_35,      0x2C,   0x0D,   0x2B,   0x2C,   0x3A,
+                               0x0C,   0x3A,   0x2B,   0x2A,   0x0B },
+       { STV0900_QPSK_23,      0x2C,   0x0D,   0x2B,   0x2C,   0x0B,
+                               0x0C,   0x3A,   0x1B,   0x2A,   0x3A },
+       { STV0900_QPSK_34,      0x3C,   0x0D,   0x3B,   0x1C,   0x0B,
+                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
+       { STV0900_QPSK_45,      0x3C,   0x0D,   0x3B,   0x1C,   0x0B,
+                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
+       { STV0900_QPSK_56,      0x0D,   0x0D,   0x3B,   0x1C,   0x0B,
+                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
+       { STV0900_QPSK_89,      0x0D,   0x0D,   0x3B,   0x1C,   0x1B,
+                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
+       { STV0900_QPSK_910,     0x1D,   0x0D,   0x3B,   0x1C,   0x1B,
+                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
+       { STV0900_8PSK_35,      0x29,   0x3B,   0x09,   0x2B,   0x38,
+                               0x0B,   0x18,   0x1A,   0x08,   0x0A },
+       { STV0900_8PSK_23,      0x0A,   0x3B,   0x29,   0x2B,   0x19,
+                               0x0B,   0x38,   0x1A,   0x18,   0x0A },
+       { STV0900_8PSK_34,      0x3A,   0x3B,   0x2A,   0x2B,   0x39,
+                               0x0B,   0x19,   0x1A,   0x38,   0x0A },
+       { STV0900_8PSK_56,      0x1B,   0x3B,   0x0B,   0x2B,   0x1A,
+                               0x0B,   0x39,   0x1A,   0x19,   0x0A },
+       { STV0900_8PSK_89,      0x3B,   0x3B,   0x0B,   0x2B,   0x2A,
+                               0x0B,   0x39,   0x1A,   0x29,   0x39 },
+       { STV0900_8PSK_910,     0x3B,   0x3B,   0x0B,   0x2B,   0x2A,
+                               0x0B,   0x39,   0x1A,   0x29,   0x39 }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_QPSK_12,      0x1F,   0x3F,   0x1E,   0x3F,   0x3D,
+                               0x1F,   0x3D,   0x3E,   0x3D,   0x1E },
+       { STV0900_QPSK_35,      0x2F,   0x3F,   0x2E,   0x2F,   0x3D,
+                               0x0F,   0x0E,   0x2E,   0x3D,   0x0E },
+       { STV0900_QPSK_23,      0x2F,   0x3F,   0x2E,   0x2F,   0x0E,
+                               0x0F,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_QPSK_34,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
+                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_QPSK_45,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
+                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_QPSK_56,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
+                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_QPSK_89,      0x3F,   0x3F,   0x3E,   0x1F,   0x1E,
+                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_QPSK_910,     0x3F,   0x3F,   0x3E,   0x1F,   0x1E,
+                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
+       { STV0900_8PSK_35,      0x3c,   0x0c,   0x1c,   0x3b,   0x0c,
+                               0x3b,   0x2b,   0x2b,   0x1b,   0x2b },
+       { STV0900_8PSK_23,      0x1d,   0x0c,   0x3c,   0x0c,   0x2c,
+                               0x3b,   0x0c,   0x2b,   0x2b,   0x2b },
+       { STV0900_8PSK_34,      0x0e,   0x1c,   0x3d,   0x0c,   0x0d,
+                               0x3b,   0x2c,   0x3b,   0x0c,   0x2b },
+       { STV0900_8PSK_56,      0x2e,   0x3e,   0x1e,   0x2e,   0x2d,
+                               0x1e,   0x3c,   0x2d,   0x2c,   0x1d },
+       { STV0900_8PSK_89,      0x3e,   0x3e,   0x1e,   0x2e,   0x3d,
+                               0x1e,   0x0d,   0x2d,   0x3c,   0x1d },
+       { STV0900_8PSK_910,     0x3e,   0x3e,   0x1e,   0x2e,   0x3d,
+                               0x1e,   0x1d,   0x2d,   0x0d,   0x1d },
+};
+
+
+
+/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
+       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_16APSK_23,    0x0C,   0x0C,   0x0C,   0x0C,   0x1D,
+                               0x0C,   0x3C,   0x0C,   0x2C,   0x0C },
+       { STV0900_16APSK_34,    0x0C,   0x0C,   0x0C,   0x0C,   0x0E,
+                               0x0C,   0x2D,   0x0C,   0x1D,   0x0C },
+       { STV0900_16APSK_45,    0x0C,   0x0C,   0x0C,   0x0C,   0x1E,
+                               0x0C,   0x3D,   0x0C,   0x2D,   0x0C },
+       { STV0900_16APSK_56,    0x0C,   0x0C,   0x0C,   0x0C,   0x1E,
+                               0x0C,   0x3D,   0x0C,   0x2D,   0x0C },
+       { STV0900_16APSK_89,    0x0C,   0x0C,   0x0C,   0x0C,   0x2E,
+                               0x0C,   0x0E,   0x0C,   0x3D,   0x0C },
+       { STV0900_16APSK_910,   0x0C,   0x0C,   0x0C,   0x0C,   0x2E,
+                               0x0C,   0x0E,   0x0C,   0x3D,   0x0C },
+       { STV0900_32APSK_34,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
+                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
+       { STV0900_32APSK_45,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
+                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
+       { STV0900_32APSK_56,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
+                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
+       { STV0900_32APSK_89,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
+                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
+       { STV0900_32APSK_910,   0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
+                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
+       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_QPSK_14,      0x0F,   0x3F,   0x0E,   0x3F,   0x2D,
+                               0x2F,   0x2D,   0x1F,   0x3D,   0x3E },
+       { STV0900_QPSK_13,      0x0F,   0x3F,   0x0E,   0x3F,   0x2D,
+                               0x2F,   0x3D,   0x0F,   0x3D,   0x2E },
+       { STV0900_QPSK_25,      0x1F,   0x3F,   0x1E,   0x3F,   0x3D,
+                               0x1F,   0x3D,   0x3E,   0x3D,   0x2E }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier  short Frame, cut 1.2 and 2.0 */
+static const
+struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+       /*Mod           2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
+                       10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
+       { STV0900_QPSK,         0x3C,   0x2F,   0x2B,   0x2E,   0x0B,
+                               0x0E,   0x3A,   0x0E,   0x2A,   0x3D },
+       { STV0900_8PSK,         0x0B,   0x3E,   0x2A,   0x0E,   0x0A,
+                               0x2D,   0x19,   0x0D,   0x09,   0x3C },
+       { STV0900_16APSK,       0x1B,   0x1E,   0x1B,   0x1E,   0x1B,
+                               0x1E,   0x3A,   0x3D,   0x2A,   0x2D },
+       { STV0900_32APSK,       0x1B,   0x1E,   0x1B,   0x1E,   0x1B,
+                               0x1E,   0x3A,   0x3D,   0x2A,   0x2D }
+};
+
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
+       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_QPSK_12,      0x3C,   0x2C,   0x0C,   0x2C,   0x1B,
+                               0x2C,   0x1B,   0x1C,   0x0B,   0x3B },
+       { STV0900_QPSK_35,      0x0D,   0x0D,   0x0C,   0x0D,   0x1B,
+                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
+       { STV0900_QPSK_23,      0x1D,   0x0D,   0x0C,   0x1D,   0x2B,
+                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
+       { STV0900_QPSK_34,      0x1D,   0x1D,   0x0C,   0x1D,   0x2B,
+                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
+       { STV0900_QPSK_45,      0x2D,   0x1D,   0x1C,   0x1D,   0x2B,
+                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
+       { STV0900_QPSK_56,      0x2D,   0x1D,   0x1C,   0x1D,   0x2B,
+                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
+       { STV0900_QPSK_89,      0x3D,   0x2D,   0x1C,   0x1D,   0x3B,
+                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
+       { STV0900_QPSK_910,     0x3D,   0x2D,   0x1C,   0x1D,   0x3B,
+                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
+       { STV0900_8PSK_35,      0x39,   0x19,   0x39,   0x19,   0x19,
+                               0x19,   0x19,   0x19,   0x09,   0x19 },
+       { STV0900_8PSK_23,      0x2A,   0x39,   0x1A,   0x0A,   0x39,
+                               0x0A,   0x29,   0x39,   0x29,   0x0A },
+       { STV0900_8PSK_34,      0x0B,   0x3A,   0x0B,   0x0B,   0x3A,
+                               0x1B,   0x1A,   0x0B,   0x1A,   0x3A },
+       { STV0900_8PSK_56,      0x0C,   0x1B,   0x3B,   0x2B,   0x1B,
+                               0x3B,   0x3A,   0x3B,   0x3A,   0x1B },
+       { STV0900_8PSK_89,      0x2C,   0x2C,   0x2C,   0x1C,   0x2B,
+                               0x0C,   0x0B,   0x3B,   0x0B,   0x1B },
+       { STV0900_8PSK_910,     0x2C,   0x3C,   0x2C,   0x1C,   0x3B,
+                               0x1C,   0x0B,   0x3B,   0x0B,   0x1B }
+};
+
+static const
+struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
+       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
+       { STV0900_16APSK_23,    0x0A,   0x0A,   0x0A,   0x0A,   0x1A,
+                               0x0A,   0x3A,   0x0A,   0x2A,   0x0A },
+       { STV0900_16APSK_34,    0x0A,   0x0A,   0x0A,   0x0A,   0x0B,
+                               0x0A,   0x3B,   0x0A,   0x1B,   0x0A },
+       { STV0900_16APSK_45,    0x0A,   0x0A,   0x0A,   0x0A,   0x1B,
+                               0x0A,   0x3B,   0x0A,   0x2B,   0x0A },
+       { STV0900_16APSK_56,    0x0A,   0x0A,   0x0A,   0x0A,   0x1B,
+                               0x0A,   0x3B,   0x0A,   0x2B,   0x0A },
+       { STV0900_16APSK_89,    0x0A,   0x0A,   0x0A,   0x0A,   0x2B,
+                               0x0A,   0x0C,   0x0A,   0x3B,   0x0A },
+       { STV0900_16APSK_910,   0x0A,   0x0A,   0x0A,   0x0A,   0x2B,
+                               0x0A,   0x0C,   0x0A,   0x3B,   0x0A },
+       { STV0900_32APSK_34,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
+                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
+       { STV0900_32APSK_45,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
+                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
+       { STV0900_32APSK_56,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
+                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
+       { STV0900_32APSK_89,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
+                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
+       { STV0900_32APSK_910,   0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
+                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A }
+};
+
+static const
+struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
+       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
+                               10MPoff 20MPon  20MPoff 30MPon  30MPoff*/
+       { STV0900_QPSK_14,      0x0C,   0x3C,   0x0B,   0x3C,   0x2A,
+                               0x2C,   0x2A,   0x1C,   0x3A,   0x3B },
+       { STV0900_QPSK_13,      0x0C,   0x3C,   0x0B,   0x3C,   0x2A,
+                               0x2C,   0x3A,   0x0C,   0x3A,   0x2B },
+       { STV0900_QPSK_25,      0x1C,   0x3C,   0x1B,   0x3C,   0x3A,
+                               0x1C,   0x3A,   0x3B,   0x3A,   0x2B }
+};
+
+static const struct stv0900_short_frames_car_loop_optim_vs_mod
+FE_STV0900_S2ShortCarLoopCut30[4] = {
+       /*Mod           2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
+       { STV0900_QPSK,         0x2C,   0x2B,   0x0B,   0x0B,   0x3A },
+       { STV0900_8PSK,         0x3B,   0x0B,   0x2A,   0x0A,   0x39 },
+       { STV0900_16APSK,       0x1B,   0x1B,   0x1B,   0x3A,   0x2A },
+       { STV0900_32APSK,       0x1B,   0x1B,   0x1B,   0x3A,   0x2A },
+
+};
+
+static const u16 STV0900_InitVal[181][2] = {
+       { R0900_OUTCFG          , 0x00  },
+       { R0900_AGCRF1CFG       , 0x11  },
+       { R0900_AGCRF2CFG       , 0x13  },
+       { R0900_TSGENERAL1X     , 0x14  },
+       { R0900_TSTTNR2         , 0x21  },
+       { R0900_TSTTNR4         , 0x21  },
+       { R0900_P2_DISTXCTL     , 0x22  },
+       { R0900_P2_F22TX        , 0xc0  },
+       { R0900_P2_F22RX        , 0xc0  },
+       { R0900_P2_DISRXCTL     , 0x00  },
+       { R0900_P2_TNRSTEPS     , 0x87  },
+       { R0900_P2_TNRGAIN      , 0x09  },
+       { R0900_P2_DMDCFGMD     , 0xF9  },
+       { R0900_P2_DEMOD        , 0x08  },
+       { R0900_P2_DMDCFG3      , 0xc4  },
+       { R0900_P2_CARFREQ      , 0xed  },
+       { R0900_P2_TNRCFG2      , 0x02  },
+       { R0900_P2_TNRCFG3      , 0x02  },
+       { R0900_P2_LDT          , 0xd0  },
+       { R0900_P2_LDT2         , 0xb8  },
+       { R0900_P2_TMGCFG       , 0xd2  },
+       { R0900_P2_TMGTHRISE    , 0x20  },
+       { R0900_P2_TMGTHFALL    , 0x00  },
+       { R0900_P2_FECSPY       , 0x88  },
+       { R0900_P2_FSPYDATA     , 0x3a  },
+       { R0900_P2_FBERCPT4     , 0x00  },
+       { R0900_P2_FSPYBER      , 0x10  },
+       { R0900_P2_ERRCTRL1     , 0x35  },
+       { R0900_P2_ERRCTRL2     , 0xc1  },
+       { R0900_P2_CFRICFG      , 0xf8  },
+       { R0900_P2_NOSCFG       , 0x1c  },
+       { R0900_P2_DMDT0M       , 0x20  },
+       { R0900_P2_CORRELMANT   , 0x70  },
+       { R0900_P2_CORRELABS    , 0x88  },
+       { R0900_P2_AGC2O        , 0x5b  },
+       { R0900_P2_AGC2REF      , 0x38  },
+       { R0900_P2_CARCFG       , 0xe4  },
+       { R0900_P2_ACLC         , 0x1A  },
+       { R0900_P2_BCLC         , 0x09  },
+       { R0900_P2_CARHDR       , 0x08  },
+       { R0900_P2_KREFTMG      , 0xc1  },
+       { R0900_P2_SFRUPRATIO   , 0xf0  },
+       { R0900_P2_SFRLOWRATIO  , 0x70  },
+       { R0900_P2_SFRSTEP      , 0x58  },
+       { R0900_P2_TMGCFG2      , 0x01  },
+       { R0900_P2_CAR2CFG      , 0x26  },
+       { R0900_P2_BCLC2S2Q     , 0x86  },
+       { R0900_P2_BCLC2S28     , 0x86  },
+       { R0900_P2_SMAPCOEF7    , 0x77  },
+       { R0900_P2_SMAPCOEF6    , 0x85  },
+       { R0900_P2_SMAPCOEF5    , 0x77  },
+       { R0900_P2_TSCFGL       , 0x20  },
+       { R0900_P2_DMDCFG2      , 0x3b  },
+       { R0900_P2_MODCODLST0   , 0xff  },
+       { R0900_P2_MODCODLST1   , 0xff  },
+       { R0900_P2_MODCODLST2   , 0xff  },
+       { R0900_P2_MODCODLST3   , 0xff  },
+       { R0900_P2_MODCODLST4   , 0xff  },
+       { R0900_P2_MODCODLST5   , 0xff  },
+       { R0900_P2_MODCODLST6   , 0xff  },
+       { R0900_P2_MODCODLST7   , 0xcc  },
+       { R0900_P2_MODCODLST8   , 0xcc  },
+       { R0900_P2_MODCODLST9   , 0xcc  },
+       { R0900_P2_MODCODLSTA   , 0xcc  },
+       { R0900_P2_MODCODLSTB   , 0xcc  },
+       { R0900_P2_MODCODLSTC   , 0xcc  },
+       { R0900_P2_MODCODLSTD   , 0xcc  },
+       { R0900_P2_MODCODLSTE   , 0xcc  },
+       { R0900_P2_MODCODLSTF   , 0xcf  },
+       { R0900_P1_DISTXCTL     , 0x22  },
+       { R0900_P1_F22TX        , 0xc0  },
+       { R0900_P1_F22RX        , 0xc0  },
+       { R0900_P1_DISRXCTL     , 0x00  },
+       { R0900_P1_TNRSTEPS     , 0x87  },
+       { R0900_P1_TNRGAIN      , 0x09  },
+       { R0900_P1_DMDCFGMD     , 0xf9  },
+       { R0900_P1_DEMOD        , 0x08  },
+       { R0900_P1_DMDCFG3      , 0xc4  },
+       { R0900_P1_DMDT0M       , 0x20  },
+       { R0900_P1_CARFREQ      , 0xed  },
+       { R0900_P1_TNRCFG2      , 0x82  },
+       { R0900_P1_TNRCFG3      , 0x02  },
+       { R0900_P1_LDT          , 0xd0  },
+       { R0900_P1_LDT2         , 0xb8  },
+       { R0900_P1_TMGCFG       , 0xd2  },
+       { R0900_P1_TMGTHRISE    , 0x20  },
+       { R0900_P1_TMGTHFALL    , 0x00  },
+       { R0900_P1_SFRUPRATIO   , 0xf0  },
+       { R0900_P1_SFRLOWRATIO  , 0x70  },
+       { R0900_P1_TSCFGL       , 0x20  },
+       { R0900_P1_FECSPY       , 0x88  },
+       { R0900_P1_FSPYDATA     , 0x3a  },
+       { R0900_P1_FBERCPT4     , 0x00  },
+       { R0900_P1_FSPYBER      , 0x10  },
+       { R0900_P1_ERRCTRL1     , 0x35  },
+       { R0900_P1_ERRCTRL2     , 0xc1  },
+       { R0900_P1_CFRICFG      , 0xf8  },
+       { R0900_P1_NOSCFG       , 0x1c  },
+       { R0900_P1_CORRELMANT   , 0x70  },
+       { R0900_P1_CORRELABS    , 0x88  },
+       { R0900_P1_AGC2O        , 0x5b  },
+       { R0900_P1_AGC2REF      , 0x38  },
+       { R0900_P1_CARCFG       , 0xe4  },
+       { R0900_P1_ACLC         , 0x1A  },
+       { R0900_P1_BCLC         , 0x09  },
+       { R0900_P1_CARHDR       , 0x08  },
+       { R0900_P1_KREFTMG      , 0xc1  },
+       { R0900_P1_SFRSTEP      , 0x58  },
+       { R0900_P1_TMGCFG2      , 0x01  },
+       { R0900_P1_CAR2CFG      , 0x26  },
+       { R0900_P1_BCLC2S2Q     , 0x86  },
+       { R0900_P1_BCLC2S28     , 0x86  },
+       { R0900_P1_SMAPCOEF7    , 0x77  },
+       { R0900_P1_SMAPCOEF6    , 0x85  },
+       { R0900_P1_SMAPCOEF5    , 0x77  },
+       { R0900_P1_DMDCFG2      , 0x3b  },
+       { R0900_P1_MODCODLST0   , 0xff  },
+       { R0900_P1_MODCODLST1   , 0xff  },
+       { R0900_P1_MODCODLST2   , 0xff  },
+       { R0900_P1_MODCODLST3   , 0xff  },
+       { R0900_P1_MODCODLST4   , 0xff  },
+       { R0900_P1_MODCODLST5   , 0xff  },
+       { R0900_P1_MODCODLST6   , 0xff  },
+       { R0900_P1_MODCODLST7   , 0xcc  },
+       { R0900_P1_MODCODLST8   , 0xcc  },
+       { R0900_P1_MODCODLST9   , 0xcc  },
+       { R0900_P1_MODCODLSTA   , 0xcc  },
+       { R0900_P1_MODCODLSTB   , 0xcc  },
+       { R0900_P1_MODCODLSTC   , 0xcc  },
+       { R0900_P1_MODCODLSTD   , 0xcc  },
+       { R0900_P1_MODCODLSTE   , 0xcc  },
+       { R0900_P1_MODCODLSTF   , 0xcf  },
+       { R0900_GENCFG          , 0x1d  },
+       { R0900_NBITER_NF4      , 0x37  },
+       { R0900_NBITER_NF5      , 0x29  },
+       { R0900_NBITER_NF6      , 0x37  },
+       { R0900_NBITER_NF7      , 0x33  },
+       { R0900_NBITER_NF8      , 0x31  },
+       { R0900_NBITER_NF9      , 0x2f  },
+       { R0900_NBITER_NF10     , 0x39  },
+       { R0900_NBITER_NF11     , 0x3a  },
+       { R0900_NBITER_NF12     , 0x29  },
+       { R0900_NBITER_NF13     , 0x37  },
+       { R0900_NBITER_NF14     , 0x33  },
+       { R0900_NBITER_NF15     , 0x2f  },
+       { R0900_NBITER_NF16     , 0x39  },
+       { R0900_NBITER_NF17     , 0x3a  },
+       { R0900_NBITERNOERR     , 0x04  },
+       { R0900_GAINLLR_NF4     , 0x0C  },
+       { R0900_GAINLLR_NF5     , 0x0F  },
+       { R0900_GAINLLR_NF6     , 0x11  },
+       { R0900_GAINLLR_NF7     , 0x14  },
+       { R0900_GAINLLR_NF8     , 0x17  },
+       { R0900_GAINLLR_NF9     , 0x19  },
+       { R0900_GAINLLR_NF10    , 0x20  },
+       { R0900_GAINLLR_NF11    , 0x21  },
+       { R0900_GAINLLR_NF12    , 0x0D  },
+       { R0900_GAINLLR_NF13    , 0x0F  },
+       { R0900_GAINLLR_NF14    , 0x13  },
+       { R0900_GAINLLR_NF15    , 0x1A  },
+       { R0900_GAINLLR_NF16    , 0x1F  },
+       { R0900_GAINLLR_NF17    , 0x21  },
+       { R0900_RCCFG2          , 0x20  },
+       { R0900_P1_FECM         , 0x01  }, /*disable DSS modes*/
+       { R0900_P2_FECM         , 0x01  }, /*disable DSS modes*/
+       { R0900_P1_PRVIT        , 0x2F  }, /*disable puncture rate 6/7*/
+       { R0900_P2_PRVIT        , 0x2F  }, /*disable puncture rate 6/7*/
+       { R0900_STROUT1CFG      , 0x4c  },
+       { R0900_STROUT2CFG      , 0x4c  },
+       { R0900_CLKOUT1CFG      , 0x50  },
+       { R0900_CLKOUT2CFG      , 0x50  },
+       { R0900_DPN1CFG         , 0x4a  },
+       { R0900_DPN2CFG         , 0x4a  },
+       { R0900_DATA71CFG       , 0x52  },
+       { R0900_DATA72CFG       , 0x52  },
+       { R0900_P1_TSCFGM       , 0xc0  },
+       { R0900_P2_TSCFGM       , 0xc0  },
+       { R0900_P1_TSCFGH       , 0xe0  }, /* DVB-CI timings */
+       { R0900_P2_TSCFGH       , 0xe0  }, /* DVB-CI timings */
+       { R0900_P1_TSSPEED      , 0x40  },
+       { R0900_P2_TSSPEED      , 0x40  },
+};
+
+static const u16 STV0900_Cut20_AddOnVal[32][2] = {
+       { R0900_P2_DMDCFG3      , 0xe8  },
+       { R0900_P2_DMDCFG4      , 0x10  },
+       { R0900_P2_CARFREQ      , 0x38  },
+       { R0900_P2_CARHDR       , 0x20  },
+       { R0900_P2_KREFTMG      , 0x5a  },
+       { R0900_P2_SMAPCOEF7    , 0x06  },
+       { R0900_P2_SMAPCOEF6    , 0x00  },
+       { R0900_P2_SMAPCOEF5    , 0x04  },
+       { R0900_P2_NOSCFG       , 0x0c  },
+       { R0900_P1_DMDCFG3      , 0xe8  },
+       { R0900_P1_DMDCFG4      , 0x10  },
+       { R0900_P1_CARFREQ      , 0x38  },
+       { R0900_P1_CARHDR       , 0x20  },
+       { R0900_P1_KREFTMG      , 0x5a  },
+       { R0900_P1_SMAPCOEF7    , 0x06  },
+       { R0900_P1_SMAPCOEF6    , 0x00  },
+       { R0900_P1_SMAPCOEF5    , 0x04  },
+       { R0900_P1_NOSCFG       , 0x0c  },
+       { R0900_GAINLLR_NF4     , 0x21  },
+       { R0900_GAINLLR_NF5     , 0x21  },
+       { R0900_GAINLLR_NF6     , 0x20  },
+       { R0900_GAINLLR_NF7     , 0x1F  },
+       { R0900_GAINLLR_NF8     , 0x1E  },
+       { R0900_GAINLLR_NF9     , 0x1E  },
+       { R0900_GAINLLR_NF10    , 0x1D  },
+       { R0900_GAINLLR_NF11    , 0x1B  },
+       { R0900_GAINLLR_NF12    , 0x20  },
+       { R0900_GAINLLR_NF13    , 0x20  },
+       { R0900_GAINLLR_NF14    , 0x20  },
+       { R0900_GAINLLR_NF15    , 0x20  },
+       { R0900_GAINLLR_NF16    , 0x20  },
+       { R0900_GAINLLR_NF17    , 0x21  }
+
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h
new file mode 100644 (file)
index 0000000..e0ea74c
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * stv0900_priv.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_PRIV_H
+#define STV0900_PRIV_H
+
+#include <linux/i2c.h>
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
+               || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xFF))
+#define MSB(Y) (((Y) >> 8) & 0xFF)
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+#define dprintk(args...) \
+       do { \
+               if (stvdebug) \
+                       printk(KERN_DEBUG args); \
+       } while (0)
+
+#define STV0900_MAXLOOKUPSIZE 500
+#define STV0900_BLIND_SEARCH_AGC2_TH 700
+#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
+#define IQPOWER_THRESHOLD  30
+
+/* One point of the lookup table */
+struct stv000_lookpoint {
+       s32 realval;/* real value */
+       s32 regval;/* binary value */
+};
+
+/* Lookup table definition */
+struct stv0900_table{
+       s32 size;/* Size of the lookup table */
+       struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
+};
+
+enum fe_stv0900_error {
+       STV0900_NO_ERROR = 0,
+       STV0900_INVALID_HANDLE,
+       STV0900_BAD_PARAMETER,
+       STV0900_I2C_ERROR,
+       STV0900_SEARCH_FAILED,
+};
+
+enum fe_stv0900_clock_type {
+       STV0900_USE_REGISTERS_DEFAULT,
+       STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
+       STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
+       STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
+       STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
+};
+
+enum fe_stv0900_search_state {
+       STV0900_SEARCH = 0,
+       STV0900_PLH_DETECTED,
+       STV0900_DVBS2_FOUND,
+       STV0900_DVBS_FOUND
+
+};
+
+enum fe_stv0900_ldpc_state {
+       STV0900_PATH1_OFF_PATH2_OFF = 0,
+       STV0900_PATH1_ON_PATH2_OFF = 1,
+       STV0900_PATH1_OFF_PATH2_ON = 2,
+       STV0900_PATH1_ON_PATH2_ON = 3
+};
+
+enum fe_stv0900_signal_type {
+       STV0900_NOAGC1 = 0,
+       STV0900_AGC1OK,
+       STV0900_NOTIMING,
+       STV0900_ANALOGCARRIER,
+       STV0900_TIMINGOK,
+       STV0900_NOAGC2,
+       STV0900_AGC2OK,
+       STV0900_NOCARRIER,
+       STV0900_CARRIEROK,
+       STV0900_NODATA,
+       STV0900_DATAOK,
+       STV0900_OUTOFRANGE,
+       STV0900_RANGEOK
+};
+
+enum fe_stv0900_demod_num {
+       STV0900_DEMOD_1,
+       STV0900_DEMOD_2
+};
+
+enum fe_stv0900_tracking_standard {
+       STV0900_DVBS1_STANDARD,/* Found Standard*/
+       STV0900_DVBS2_STANDARD,
+       STV0900_DSS_STANDARD,
+       STV0900_TURBOCODE_STANDARD,
+       STV0900_UNKNOWN_STANDARD
+};
+
+enum fe_stv0900_search_standard {
+       STV0900_AUTO_SEARCH,
+       STV0900_SEARCH_DVBS1,/* Search Standard*/
+       STV0900_SEARCH_DVBS2,
+       STV0900_SEARCH_DSS,
+       STV0900_SEARCH_TURBOCODE
+};
+
+enum fe_stv0900_search_algo {
+       STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
+       STV0900_COLD_START,/* only the SR is known */
+       STV0900_WARM_START/* offset freq and SR are known */
+};
+
+enum fe_stv0900_modulation {
+       STV0900_QPSK,
+       STV0900_8PSK,
+       STV0900_16APSK,
+       STV0900_32APSK,
+       STV0900_UNKNOWN
+};
+
+enum fe_stv0900_modcode {
+       STV0900_DUMMY_PLF,
+       STV0900_QPSK_14,
+       STV0900_QPSK_13,
+       STV0900_QPSK_25,
+       STV0900_QPSK_12,
+       STV0900_QPSK_35,
+       STV0900_QPSK_23,
+       STV0900_QPSK_34,
+       STV0900_QPSK_45,
+       STV0900_QPSK_56,
+       STV0900_QPSK_89,
+       STV0900_QPSK_910,
+       STV0900_8PSK_35,
+       STV0900_8PSK_23,
+       STV0900_8PSK_34,
+       STV0900_8PSK_56,
+       STV0900_8PSK_89,
+       STV0900_8PSK_910,
+       STV0900_16APSK_23,
+       STV0900_16APSK_34,
+       STV0900_16APSK_45,
+       STV0900_16APSK_56,
+       STV0900_16APSK_89,
+       STV0900_16APSK_910,
+       STV0900_32APSK_34,
+       STV0900_32APSK_45,
+       STV0900_32APSK_56,
+       STV0900_32APSK_89,
+       STV0900_32APSK_910,
+       STV0900_MODCODE_UNKNOWN
+};
+
+enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
+       STV0900_FEC_1_2 = 0,
+       STV0900_FEC_2_3,
+       STV0900_FEC_3_4,
+       STV0900_FEC_4_5,/*for turbo code only*/
+       STV0900_FEC_5_6,
+       STV0900_FEC_6_7,/*for DSS only */
+       STV0900_FEC_7_8,
+       STV0900_FEC_8_9,/*for turbo code only*/
+       STV0900_FEC_UNKNOWN
+};
+
+enum fe_stv0900_frame_length {
+       STV0900_LONG_FRAME,
+       STV0900_SHORT_FRAME
+};
+
+enum fe_stv0900_pilot {
+       STV0900_PILOTS_OFF,
+       STV0900_PILOTS_ON
+};
+
+enum fe_stv0900_rolloff {
+       STV0900_35,
+       STV0900_25,
+       STV0900_20
+};
+
+enum fe_stv0900_search_iq {
+       STV0900_IQ_AUTO,
+       STV0900_IQ_AUTO_NORMAL_FIRST,
+       STV0900_IQ_FORCE_NORMAL,
+       STV0900_IQ_FORCE_SWAPPED
+};
+
+enum stv0900_iq_inversion {
+       STV0900_IQ_NORMAL,
+       STV0900_IQ_SWAPPED
+};
+
+enum fe_stv0900_diseqc_mode {
+       STV0900_22KHZ_Continues = 0,
+       STV0900_DISEQC_2_3_PWM = 2,
+       STV0900_DISEQC_3_3_PWM = 3,
+       STV0900_DISEQC_2_3_ENVELOP = 4,
+       STV0900_DISEQC_3_3_ENVELOP = 5
+};
+
+enum fe_stv0900_demod_mode {
+       STV0900_SINGLE = 0,
+       STV0900_DUAL
+};
+
+struct stv0900_init_params{
+       u32     dmd_ref_clk;/* Reference,Input clock for the demod in Hz */
+
+       /* Demodulator Type (single demod or dual demod) */
+       enum fe_stv0900_demod_mode      demod_mode;
+       enum fe_stv0900_rolloff         rolloff;
+       enum fe_stv0900_clock_type      path1_ts_clock;
+
+       u8      tun1_maddress;
+       int     tuner1_adc;
+       int     tuner1_type;
+
+       /* IQ from the tuner1 to the demod */
+       enum stv0900_iq_inversion       tun1_iq_inv;
+       enum fe_stv0900_clock_type      path2_ts_clock;
+
+       u8      tun2_maddress;
+       int     tuner2_adc;
+       int     tuner2_type;
+
+       /* IQ from the tuner2 to the demod */
+       enum stv0900_iq_inversion       tun2_iq_inv;
+       struct stv0900_reg              *ts_config;
+};
+
+struct stv0900_search_params {
+       enum fe_stv0900_demod_num       path;/* Path Used demod1 or 2 */
+
+       u32     frequency;/* Transponder frequency (in KHz) */
+       u32     symbol_rate;/* Transponder symbol rate  (in bds)*/
+       u32     search_range;/* Range of the search (in Hz) */
+
+       enum fe_stv0900_search_standard standard;
+       enum fe_stv0900_modulation      modulation;
+       enum fe_stv0900_fec             fec;
+       enum fe_stv0900_modcode         modcode;
+       enum fe_stv0900_search_iq       iq_inversion;
+       enum fe_stv0900_search_algo     search_algo;
+
+};
+
+struct stv0900_signal_info {
+       int     locked;/* Transponder locked */
+       u32     frequency;/* Transponder frequency (in KHz) */
+       u32     symbol_rate;/* Transponder symbol rate  (in Mbds) */
+
+       enum fe_stv0900_tracking_standard       standard;
+       enum fe_stv0900_fec                     fec;
+       enum fe_stv0900_modcode                 modcode;
+       enum fe_stv0900_modulation              modulation;
+       enum fe_stv0900_pilot                   pilot;
+       enum fe_stv0900_frame_length            frame_len;
+       enum stv0900_iq_inversion               spectrum;
+       enum fe_stv0900_rolloff                 rolloff;
+
+       s32 Power;/* Power of the RF signal (dBm) */
+       s32 C_N;/* Carrier to noise ratio (dB x10)*/
+       u32 BER;/* Bit error rate (x10^7) */
+
+};
+
+struct stv0900_internal{
+       s32     quartz;
+       s32     mclk;
+       /* manual RollOff for DVBS1/DSS only */
+       enum fe_stv0900_rolloff         rolloff;
+       /* Demodulator use for single demod or for dual demod) */
+       enum fe_stv0900_demod_mode      demod_mode;
+
+       /*Demods */
+       s32     freq[2];
+       s32     bw[2];
+       s32     symbol_rate[2];
+       s32     srch_range[2];
+       /* for software/auto tuner */
+       int     tuner_type[2];
+
+       /* algorithm for search Blind, Cold or Warm*/
+       enum fe_stv0900_search_algo     srch_algo[2];
+       /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
+       enum fe_stv0900_search_standard srch_standard[2];
+       /* inversion search : auto, auto norma first, normal or inverted */
+       enum fe_stv0900_search_iq       srch_iq_inv[2];
+       enum fe_stv0900_modcode         modcode[2];
+       enum fe_stv0900_modulation      modulation[2];
+       enum fe_stv0900_fec             fec[2];
+
+       struct stv0900_signal_info      result[2];
+       enum fe_stv0900_error           err[2];
+
+
+       struct i2c_adapter      *i2c_adap;
+       u8                      i2c_addr;
+       u8                      clkmode;/* 0 for CLKI, 2 for XTALI */
+       u8                      chip_id;
+       struct stv0900_reg      *ts_config;
+       enum fe_stv0900_error   errs;
+       int dmds_used;
+};
+
+/* state for each demod */
+struct stv0900_state {
+       /* pointer for internal params, one for each pair of demods */
+       struct stv0900_internal         *internal;
+       struct i2c_adapter              *i2c_adap;
+       const struct stv0900_config     *config;
+       struct dvb_frontend             frontend;
+       int demod;
+};
+
+extern int stvdebug;
+
+extern s32 ge2comp(s32 a, s32 width);
+
+extern void stv0900_write_reg(struct stv0900_internal *i_params,
+                               u16 reg_addr, u8 reg_data);
+
+extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
+                               u16 reg_addr);
+
+extern void stv0900_write_bits(struct stv0900_internal *i_params,
+                               u32 label, u8 val);
+
+extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
+                               u32 label);
+
+extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod, s32 time_out);
+extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
+
+extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+                               u32 bandwidth);
+extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
+
+extern void stv0900_start_search(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod);
+
+extern u8 stv0900_get_optim_carr_loop(s32 srate,
+                               enum fe_stv0900_modcode modcode,
+                               s32 pilot, u8 chip_id);
+
+extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
+                               enum fe_stv0900_modulation modulation,
+                               u8 chip_id);
+
+extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
+                               enum fe_stv0900_demod_num demod);
+
+extern enum
+fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+                               enum fe_stv0900_demod_num demod);
+
+extern u32
+stv0900_get_freq_auto(struct stv0900_internal *intp, int demod);
+
+extern void
+stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
+                                               u32 Bandwidth, int demod);
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv0900_reg.h b/drivers/media/dvb-frontends/stv0900_reg.h
new file mode 100644 (file)
index 0000000..731afe9
--- /dev/null
@@ -0,0 +1,3981 @@
+/*
+ * stv0900_reg.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_REG_H
+#define STV0900_REG_H
+
+extern s32 shiftx(s32 x, int demod, s32 shift);
+
+#define REGx(x) shiftx(x, demod, 0x200)
+#define FLDx(x) shiftx(x, demod, 0x2000000)
+
+/*MID*/
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
+
+/*DACR1*/
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
+
+/*DACR2*/
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
+
+/*OUTCFG*/
+#define R0900_OUTCFG 0xf11c
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
+
+/*IRQSTATUS3*/
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
+
+/*IRQSTATUS2*/
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
+
+/*IRQSTATUS1*/
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
+
+/*IRQSTATUS0*/
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
+
+/*IRQMASK3*/
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
+
+/*IRQMASK2*/
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
+
+/*IRQMASK1*/
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
+
+/*IRQMASK0*/
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
+
+/*I2CCFG*/
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_I2CADDR_INC 0xf1290003
+
+/*P1_I2CRPT*/
+#define R0900_P1_I2CRPT 0xf12a
+#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
+
+/*P2_I2CRPT*/
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*IOPVALUE6*/
+#define R0900_IOPVALUE6 0xf138
+#define F0900_VSCL 0xf1380004
+#define F0900_VSDA 0xf1380002
+#define F0900_VDATA3_0 0xf1380001
+
+/*IOPVALUE5*/
+#define R0900_IOPVALUE5 0xf139
+#define F0900_VDATA3_1 0xf1390080
+#define F0900_VDATA3_2 0xf1390040
+#define F0900_VDATA3_3 0xf1390020
+#define F0900_VDATA3_4 0xf1390010
+#define F0900_VDATA3_5 0xf1390008
+#define F0900_VDATA3_6 0xf1390004
+#define F0900_VDATA3_7 0xf1390002
+#define F0900_VCLKOUT3 0xf1390001
+
+/*IOPVALUE4*/
+#define R0900_IOPVALUE4 0xf13a
+#define F0900_VSTROUT3 0xf13a0080
+#define F0900_VDPN3 0xf13a0040
+#define F0900_VERROR3 0xf13a0020
+#define F0900_VDATA2_7 0xf13a0010
+#define F0900_VCLKOUT2 0xf13a0008
+#define F0900_VSTROUT2 0xf13a0004
+#define F0900_VDPN2 0xf13a0002
+#define F0900_VERROR2 0xf13a0001
+
+/*IOPVALUE3*/
+#define R0900_IOPVALUE3 0xf13b
+#define F0900_VDATA1_7 0xf13b0080
+#define F0900_VCLKOUT1 0xf13b0040
+#define F0900_VSTROUT1 0xf13b0020
+#define F0900_VDPN1 0xf13b0010
+#define F0900_VERROR1 0xf13b0008
+#define F0900_VCLKOUT27 0xf13b0004
+#define F0900_VDISEQCOUT2 0xf13b0002
+#define F0900_VSCLT2 0xf13b0001
+
+/*IOPVALUE2*/
+#define R0900_IOPVALUE2 0xf13c
+#define F0900_VSDAT2 0xf13c0080
+#define F0900_VAGCRF2 0xf13c0040
+#define F0900_VDISEQCOUT1 0xf13c0020
+#define F0900_VSCLT1 0xf13c0010
+#define F0900_VSDAT1 0xf13c0008
+#define F0900_VAGCRF1 0xf13c0004
+#define F0900_VDIRCLK 0xf13c0002
+#define F0900_VSTDBY 0xf13c0001
+
+/*IOPVALUE1*/
+#define R0900_IOPVALUE1 0xf13d
+#define F0900_VCS1 0xf13d0080
+#define F0900_VCS0 0xf13d0040
+#define F0900_VGPIO13 0xf13d0020
+#define F0900_VGPIO12 0xf13d0010
+#define F0900_VGPIO11 0xf13d0008
+#define F0900_VGPIO10 0xf13d0004
+#define F0900_VGPIO9 0xf13d0002
+#define F0900_VGPIO8 0xf13d0001
+
+/*IOPVALUE0*/
+#define R0900_IOPVALUE0 0xf13e
+#define F0900_VGPIO7 0xf13e0080
+#define F0900_VGPIO6 0xf13e0040
+#define F0900_VGPIO5 0xf13e0020
+#define F0900_VGPIO4 0xf13e0010
+#define F0900_VGPIO3 0xf13e0008
+#define F0900_VGPIO2 0xf13e0004
+#define F0900_VGPIO1 0xf13e0002
+#define F0900_VCLKI2 0xf13e0001
+
+/*CLKI2CFG*/
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
+
+/*GPIO1CFG*/
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
+
+/*GPIO2CFG*/
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
+
+/*GPIO3CFG*/
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
+
+/*GPIO4CFG*/
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
+
+/*GPIO5CFG*/
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
+
+/*GPIO6CFG*/
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
+
+/*GPIO7CFG*/
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
+
+/*GPIO8CFG*/
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
+
+/*GPIO9CFG*/
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
+
+/*GPIO10CFG*/
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
+
+/*GPIO11CFG*/
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
+
+/*GPIO12CFG*/
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
+
+/*GPIO13CFG*/
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
+
+/*CS0CFG*/
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
+
+/*CS1CFG*/
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
+
+/*STDBYCFG*/
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
+
+/*DIRCLKCFG*/
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
+
+/*AGCRF1CFG*/
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
+
+/*SDAT1CFG*/
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
+
+/*SCLT1CFG*/
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
+
+/*DISEQCO1CFG*/
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
+
+/*AGCRF2CFG*/
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
+
+/*SDAT2CFG*/
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
+
+/*SCLT2CFG*/
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
+
+/*DISEQCO2CFG*/
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
+
+/*CLKOUT27CFG*/
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
+
+/*ERROR1CFG*/
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
+
+/*DPN1CFG*/
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
+
+/*STROUT1CFG*/
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
+
+/*CLKOUT1CFG*/
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
+
+/*DATA71CFG*/
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
+
+/*ERROR2CFG*/
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
+
+/*DPN2CFG*/
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
+
+/*STROUT2CFG*/
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
+
+/*CLKOUT2CFG*/
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
+
+/*DATA72CFG*/
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
+
+/*ERROR3CFG*/
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
+
+/*DPN3CFG*/
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
+
+/*STROUT3CFG*/
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
+
+/*CLKOUT3CFG*/
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
+
+/*DATA73CFG*/
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*STRSTATUS1*/
+#define R0900_STRSTATUS1 0xf16a
+#define F0900_STRSTATUS_SEL2 0xf16a00f0
+#define F0900_STRSTATUS_SEL1 0xf16a000f
+
+/*STRSTATUS2*/
+#define R0900_STRSTATUS2 0xf16b
+#define F0900_STRSTATUS_SEL4 0xf16b00f0
+#define F0900_STRSTATUS_SEL3 0xf16b000f
+
+/*STRSTATUS3*/
+#define R0900_STRSTATUS3 0xf16c
+#define F0900_STRSTATUS_SEL6 0xf16c00f0
+#define F0900_STRSTATUS_SEL5 0xf16c000f
+
+/*FSKTFC2*/
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
+
+/*FSKTFC1*/
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
+
+/*FSKTFC0*/
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
+
+/*FSKTDELTAF1*/
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
+
+/*FSKTDELTAF0*/
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
+
+/*FSKTCTRL*/
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
+
+/*FSKRFC2*/
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
+
+/*FSKRFC1*/
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
+
+/*FSKRFC0*/
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
+
+/*FSKRK1*/
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
+
+/*FSKRK2*/
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
+
+/*FSKRAGCR*/
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
+
+/*FSKRAGC*/
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
+
+/*FSKRALPHA*/
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
+
+/*FSKRPLTH1*/
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
+
+/*FSKRPLTH0*/
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
+
+/*FSKRDF1*/
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
+
+/*FSKRDF0*/
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
+
+/*FSKRSTEPP*/
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
+
+/*FSKRSTEPM*/
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
+
+/*FSKRDET1*/
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
+
+/*FSKRDET0*/
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
+
+/*FSKRDTH1*/
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
+
+/*FSKRDTH0*/
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
+
+/*FSKRLOSS*/
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
+
+/*P2_DISTXCTL*/
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
+
+/*P2_DISRXCTL*/
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT0 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
+
+/*P2_DISRX_ST0*/
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
+
+/*P2_DISRX_ST1*/
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
+
+/*P2_DISRXDATA*/
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
+
+/*P2_DISTXDATA*/
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
+
+/*P2_DISTXSTATUS*/
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
+
+/*P2_F22TX*/
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
+
+/*P2_F22RX*/
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
+
+/*P2_ACRPRESC*/
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_PRESC 0xf19c0007
+
+/*P2_ACRDIV*/
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
+
+/*P1_DISTXCTL*/
+#define R0900_P1_DISTXCTL 0xf1a0
+#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
+#define F0900_P1_DISTX_MODE 0xf1a00007
+#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
+
+/*P1_DISRXCTL*/
+#define R0900_P1_DISRXCTL 0xf1a1
+#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT0 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
+
+/*P1_DISRX_ST0*/
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
+#define F0900_P1_RX_END 0xf1a40080
+#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
+
+/*P1_DISRX_ST1*/
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
+
+/*P1_DISRXDATA*/
+#define R0900_P1_DISRXDATA 0xf1a6
+#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
+#define F0900_P1_DISRX_DATA 0xf1a600ff
+
+/*P1_DISTXDATA*/
+#define R0900_P1_DISTXDATA 0xf1a7
+#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
+
+/*P1_DISTXSTATUS*/
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
+
+/*P1_F22TX*/
+#define R0900_P1_F22TX 0xf1a9
+#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
+#define F0900_P1_F22_REG 0xf1a900ff
+
+/*P1_F22RX*/
+#define R0900_P1_F22RX 0xf1aa
+#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
+#define F0900_P1_F22RX_REG 0xf1aa00ff
+
+/*P1_ACRPRESC*/
+#define R0900_P1_ACRPRESC 0xf1ac
+#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
+#define F0900_P1_ACR_PRESC 0xf1ac0007
+
+/*P1_ACRDIV*/
+#define R0900_P1_ACRDIV 0xf1ad
+#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
+#define F0900_P1_ACR_DIV 0xf1ad00ff
+
+/*NCOARSE*/
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
+
+/*SYNTCTRL*/
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
+
+/*FILTCTRL*/
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
+
+/*PLLSTAT*/
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_PLLLOCK 0xf1b80001
+
+/*STOPCLK1*/
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
+
+/*STOPCLK2*/
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
+#define F0900_STOP_CLKTS 0xf1c30001
+
+/*TSTTNR0*/
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
+
+/*TSTTNR1*/
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
+
+/*TSTTNR2*/
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
+
+/*TSTTNR3*/
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
+
+/*TSTTNR4*/
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
+
+/*P2_IQCONST*/
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
+
+/*P2_NOSCFG*/
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
+
+/*P2_ISYMB*/
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
+
+/*P2_QSYMB*/
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
+
+/*P2_AGC1CFG*/
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
+
+/*P2_AGC1CN*/
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
+
+/*P2_AGC1REF*/
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
+
+/*P2_IDCCOMP*/
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
+
+/*P2_QDCCOMP*/
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
+
+/*P2_POWERI*/
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
+
+/*P2_POWERQ*/
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
+
+/*P2_AGC1AMM*/
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
+
+/*P2_AGC1QUAD*/
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
+
+/*P2_AGCIQIN1*/
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
+
+/*P2_AGCIQIN0*/
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
+
+/*P2_DEMOD*/
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
+
+/*P2_DMDMODCOD*/
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
+
+/*P2_DSTATUS*/
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_OVADC_DETECT 0xf2120001
+
+/*P2_DSTATUS2*/
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
+
+/*P2_DMDCFGMD*/
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_CFR_AUTOSCAN 0xf2140008
+#define F0900_P2_TUN_RNG 0xf2140003
+
+/*P2_DMDCFG2*/
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_INFINITE_RELOCK 0xf2150010
+
+/*P2_DMDISTATE*/
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
+
+/*P2_DMDT0M*/
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
+
+/*P2_DMDSTATE*/
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_HEADER_MODE 0xf21b0060
+
+/*P2_DMDFLYW*/
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
+
+/*P2_DSTATUS3*/
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
+
+/*P2_DMDCFG3*/
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
+
+/*P2_DMDCFG4*/
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
+
+/*P2_CORRELMANT*/
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
+
+/*P2_CORRELABS*/
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
+
+/*P2_CORRELEXP*/
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
+
+/*P2_PLHMODCOD*/
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
+
+/*P2_DMDREG*/
+#define R0900_P2_DMDREG 0xf225
+#define F0900_P2_DECIM_PLFRAMES 0xf2250001
+
+/*P2_AGC2O*/
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2_COEF 0xf22c0007
+
+/*P2_AGC2REF*/
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
+
+/*P2_AGC1ADJ*/
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
+
+/*P2_AGC2I1*/
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
+
+/*P2_AGC2I0*/
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
+
+/*P2_CARCFG*/
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
+
+/*P2_ACLC*/
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
+
+/*P2_BCLC*/
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
+
+/*P2_CARFREQ*/
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
+
+/*P2_CARHDR*/
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
+
+/*P2_LDT*/
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
+
+/*P2_LDT2*/
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
+
+/*P2_CFRICFG*/
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
+
+/*P2_CFRUP1*/
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
+
+/*P2_CFRUP0*/
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
+
+/*P2_CFRLOW1*/
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
+
+/*P2_CFRLOW0*/
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
+
+/*P2_CFRINIT1*/
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
+
+/*P2_CFRINIT0*/
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
+
+/*P2_CFRINC1*/
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a003f
+
+/*P2_CFRINC0*/
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f8
+
+/*P2_CFR2*/
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
+
+/*P2_CFR1*/
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
+
+/*P2_CFR0*/
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
+
+/*P2_LDI*/
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
+
+/*P2_TMGCFG*/
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_TMG_MINFREQ 0xf2500003
+
+/*P2_RTC*/
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
+
+/*P2_RTCS2*/
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
+
+/*P2_TMGTHRISE*/
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
+
+/*P2_TMGTHFALL*/
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
+
+/*P2_SFRUPRATIO*/
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
+
+/*P2_SFRLOWRATIO*/
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
+
+/*P2_KREFTMG*/
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
+
+/*P2_SFRSTEP*/
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
+
+/*P2_TMGCFG2*/
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_KREFTMG2*/
+#define R0900_P2_KREFTMG2 0xf25b
+#define F0900_P2_KREF_TMG2 0xf25b00ff
+
+/*P2_SFRINIT1*/
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e007f
+
+/*P2_SFRINIT0*/
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
+
+/*P2_SFRUP1*/
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
+
+/*P2_SFRUP0*/
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
+
+/*P2_SFRLOW1*/
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
+
+/*P2_SFRLOW0*/
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
+
+/*P2_SFR3*/
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
+
+/*P2_SFR2*/
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
+
+/*P2_SFR1*/
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
+
+/*P2_SFR0*/
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
+
+/*P2_TMGREG2*/
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
+
+/*P2_TMGREG1*/
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
+
+/*P2_TMGREG0*/
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
+
+/*P2_TMGLOCK1*/
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
+
+/*P2_TMGLOCK0*/
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
+
+/*P2_TMGOBS*/
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
+
+/*P2_EQUALCFG*/
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
+
+/*P2_EQUAI1*/
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
+
+/*P2_EQUAQ1*/
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
+
+/*P2_EQUAI2*/
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
+
+/*P2_EQUAQ2*/
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
+
+/*P2_EQUAI3*/
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
+
+/*P2_EQUAQ3*/
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
+
+/*P2_EQUAI4*/
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
+
+/*P2_EQUAQ4*/
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
+
+/*P2_EQUAI5*/
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
+
+/*P2_EQUAQ5*/
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
+
+/*P2_EQUAI6*/
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
+
+/*P2_EQUAQ6*/
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
+
+/*P2_EQUAI7*/
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
+
+/*P2_EQUAQ7*/
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
+
+/*P2_EQUAI8*/
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
+
+/*P2_EQUAQ8*/
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
+
+/*P2_NNOSDATAT1*/
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
+
+/*P2_NNOSDATAT0*/
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
+
+/*P2_NNOSDATA1*/
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
+
+/*P2_NNOSDATA0*/
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
+
+/*P2_NNOSPLHT1*/
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
+
+/*P2_NNOSPLHT0*/
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
+
+/*P2_NNOSPLH1*/
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
+
+/*P2_NNOSPLH0*/
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
+
+/*P2_NOSDATAT1*/
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
+
+/*P2_NOSDATAT0*/
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
+
+/*P2_NOSDATA1*/
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
+
+/*P2_NOSDATA0*/
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
+
+/*P2_NOSPLHT1*/
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
+
+/*P2_NOSPLHT0*/
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
+
+/*P2_NOSPLH1*/
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
+
+/*P2_NOSPLH0*/
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
+
+/*P2_CAR2CFG*/
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_CARRIER3_DISABLE 0xf2900040
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
+
+/*P2_CFR2CFR1*/
+#define R0900_P2_CFR2CFR1 0xf291
+#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
+#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
+#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
+#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
+
+/*P2_CFR22*/
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
+
+/*P2_CFR21*/
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
+
+/*P2_CFR20*/
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
+
+/*P2_ACLC2S2Q*/
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
+
+/*P2_ACLC2S28*/
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
+
+/*P2_ACLC2S216A*/
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_DIS_C3STOPA2 0xf2990080
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
+
+/*P2_ACLC2S232A*/
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
+
+/*P2_BCLC2S2Q*/
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
+
+/*P2_BCLC2S28*/
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
+
+/*P2_BCLC2S216A*/
+#define R0900_P2_BCLC2S216A 0xf29e
+
+/*P2_BCLC2S232A*/
+#define R0900_P2_BCLC2S232A 0xf29f
+
+/*P2_PLROOT2*/
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
+
+/*P2_PLROOT1*/
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
+
+/*P2_PLROOT0*/
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
+
+/*P2_MODCODLST0*/
+#define R0900_P2_MODCODLST0 0xf2b0
+
+/*P2_MODCODLST1*/
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
+
+/*P2_MODCODLST2*/
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
+
+/*P2_MODCODLST3*/
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
+
+/*P2_MODCODLST4*/
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
+
+/*P2_MODCODLST5*/
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
+
+/*P2_MODCODLST6*/
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
+
+/*P2_MODCODLST7*/
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
+
+/*P2_MODCODLST8*/
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
+
+/*P2_MODCODLST9*/
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
+
+/*P2_MODCODLSTA*/
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
+
+/*P2_MODCODLSTB*/
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
+
+/*P2_MODCODLSTC*/
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
+
+/*P2_MODCODLSTD*/
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
+
+/*P2_MODCODLSTE*/
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
+
+/*P2_MODCODLSTF*/
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+
+/*P2_GAUSSR0*/
+#define R0900_P2_GAUSSR0 0xf2c0
+#define F0900_P2_EN_CCIMODE 0xf2c00080
+#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
+
+/*P2_CCIR0*/
+#define R0900_P2_CCIR0 0xf2c1
+#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
+#define F0900_P2_R0_CCI 0xf2c1007f
+
+/*P2_CCIQUANT*/
+#define R0900_P2_CCIQUANT 0xf2c2
+#define F0900_P2_CCI_BETA 0xf2c200e0
+#define F0900_P2_CCI_QUANT 0xf2c2001f
+
+/*P2_CCITHRES*/
+#define R0900_P2_CCITHRES 0xf2c3
+#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
+
+/*P2_CCIACC*/
+#define R0900_P2_CCIACC 0xf2c4
+#define F0900_P2_CCI_VALUE 0xf2c400ff
+
+/*P2_DMDRESCFG*/
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
+
+/*P2_DMDRESADR*/
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
+
+/*P2_DMDRESDATA7*/
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
+
+/*P2_DMDRESDATA6*/
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
+
+/*P2_DMDRESDATA5*/
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
+
+/*P2_DMDRESDATA4*/
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
+
+/*P2_DMDRESDATA3*/
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
+
+/*P2_DMDRESDATA2*/
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
+
+/*P2_DMDRESDATA1*/
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
+
+/*P2_DMDRESDATA0*/
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
+
+/*P2_FFEI1*/
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
+
+/*P2_FFEQ1*/
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
+
+/*P2_FFEI2*/
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
+
+/*P2_FFEQ2*/
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
+
+/*P2_FFEI3*/
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
+
+/*P2_FFEQ3*/
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
+
+/*P2_FFEI4*/
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
+
+/*P2_FFEQ4*/
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
+
+/*P2_FFECFG*/
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
+
+/*P2_TNRCFG*/
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
+
+/*P2_TNRCFG2*/
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
+
+/*P2_TNRXTAL*/
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
+
+/*P2_TNRSTEPS*/
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW0P125 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70170
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70007
+
+/*P2_TNRGAIN*/
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
+
+/*P2_TNRRF1*/
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
+
+/*P2_TNRRF0*/
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
+
+/*P2_TNRBW*/
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
+
+/*P2_TNRADJ*/
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
+
+/*P2_TNRCTL2*/
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
+#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
+#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
+#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
+#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
+#define F0900_P2_STB6XX0_SYN 0xf2ed0001
+
+/*P2_TNRCFG3*/
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
+
+/*P2_TNRLAUNCH*/
+#define R0900_P2_TNRLAUNCH 0xf2f0
+
+/*P2_TNRLD*/
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
+
+/*P2_TNROBSL*/
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
+
+/*P2_TNRRESTE*/
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
+
+/*P2_SMAPCOEF7*/
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
+
+/*P2_SMAPCOEF6*/
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
+
+/*P2_SMAPCOEF5*/
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_NCO2MAX1*/
+#define R0900_P2_NCO2MAX1 0xf314
+#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
+
+/*P2_NCO2MAX0*/
+#define R0900_P2_NCO2MAX0 0xf315
+#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
+
+/*P2_NCO2FR1*/
+#define R0900_P2_NCO2FR1 0xf316
+#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
+
+/*P2_NCO2FR0*/
+#define R0900_P2_NCO2FR0 0xf317
+#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
+
+/*P2_CFR2AVRGE1*/
+#define R0900_P2_CFR2AVRGE1 0xf318
+#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
+
+/*P2_CFR2AVRGE0*/
+#define R0900_P2_CFR2AVRGE0 0xf319
+#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
+
+/*P2_DMDPLHSTAT*/
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
+
+/*P2_LOCKTIME3*/
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
+
+/*P2_LOCKTIME2*/
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
+
+/*P2_LOCKTIME1*/
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
+
+/*P2_LOCKTIME0*/
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
+
+/*P2_VITSCALE*/
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
+
+/*P2_FECM*/
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
+
+/*P2_VTH12*/
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
+
+/*P2_VTH23*/
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
+
+/*P2_VTH34*/
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
+
+/*P2_VTH56*/
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
+
+/*P2_VTH67*/
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
+
+/*P2_VTH78*/
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
+
+/*P2_VITCURPUN*/
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_CURPUN 0xf33a001f
+
+/*P2_VERROR*/
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
+
+/*P2_PRVIT*/
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
+
+/*P2_VAVSRVIT*/
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
+
+/*P2_VSTATUSVIT*/
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
+
+/*P2_VTHINUSE*/
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
+
+/*P2_KDIV12*/
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_K_DIVIDER_12 0xf340007f
+
+/*P2_KDIV23*/
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_K_DIVIDER_23 0xf341007f
+
+/*P2_KDIV34*/
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_K_DIVIDER_34 0xf342007f
+
+/*P2_KDIV56*/
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_K_DIVIDER_56 0xf343007f
+
+/*P2_KDIV67*/
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_K_DIVIDER_67 0xf344007f
+
+/*P2_KDIV78*/
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_K_DIVIDER_78 0xf345007f
+
+/*P2_PDELCTRL1*/
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
+
+/*P2_PDELCTRL2*/
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_FRAME_MODE 0xf3510002
+#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
+
+/*P2_HYSTTHRESH*/
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
+
+/*P2_ISIENTRY*/
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
+
+/*P2_ISIBITENA*/
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
+
+/*P2_MATSTR1*/
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
+
+/*P2_MATSTR0*/
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
+
+/*P2_UPLSTR1*/
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
+
+/*P2_UPLSTR0*/
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
+
+/*P2_DFLSTR1*/
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
+
+/*P2_DFLSTR0*/
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
+
+/*P2_SYNCSTR*/
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
+
+/*P2_SYNCDSTR1*/
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
+
+/*P2_SYNCDSTR0*/
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
+
+/*P2_PDELSTATUS1*/
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
+
+/*P2_PDELSTATUS2*/
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
+
+/*P2_BBFCRCKO1*/
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
+
+/*P2_BBFCRCKO0*/
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
+
+/*P2_UPCRCKO1*/
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
+
+/*P2_UPCRCKO0*/
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_PDELCTRL3*/
+#define R0900_P2_PDELCTRL3 0xf36f
+#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
+#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
+
+/*P2_TSSTATEM*/
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
+
+/*P2_TSCFGH*/
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
+
+/*P2_TSCFGM*/
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
+
+/*P2_TSCFGL*/
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
+
+/*P2_TSINSDELH*/
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSDIVN*/
+#define R0900_P2_TSDIVN 0xf379
+#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
+
+/*P2_TSCFG4*/
+#define R0900_P2_TSCFG4 0xf37a
+#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
+
+/*P2_TSSPEED*/
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
+
+/*P2_TSSTATUS*/
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_DIL_READY 0xf3810001
+
+/*P2_TSSTATUS2*/
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_SCRAMBDETECT 0xf3820002
+
+/*P2_TSBITRATE1*/
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
+
+/*P2_TSBITRATE0*/
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
+
+/*P2_ERRCTRL1*/
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
+
+/*P2_ERRCNT12*/
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
+
+/*P2_ERRCNT11*/
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
+
+/*P2_ERRCNT10*/
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
+
+/*P2_ERRCTRL2*/
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
+
+/*P2_ERRCNT22*/
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
+
+/*P2_ERRCNT21*/
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
+
+/*P2_ERRCNT20*/
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
+
+/*P2_FECSPY*/
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
+
+/*P2_FSPYCFG*/
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
+
+/*P2_FSPYDATA*/
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
+
+/*P2_FSPYOUT*/
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_STUFF_MODE 0xf3a30007
+
+/*P2_FSTATUS*/
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
+
+/*P2_FBERCPT4*/
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
+
+/*P2_FBERCPT3*/
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
+
+/*P2_FBERCPT2*/
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
+
+/*P2_FBERCPT1*/
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
+
+/*P2_FBERCPT0*/
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
+
+/*P2_FBERERR2*/
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
+
+/*P2_FBERERR1*/
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
+
+/*P2_FBERERR0*/
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
+
+/*P2_FSPYBER*/
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
+
+/*P1_IQCONST*/
+#define R0900_P1_IQCONST 0xf400
+#define IQCONST REGx(R0900_P1_IQCONST)
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
+
+/*P1_NOSCFG*/
+#define R0900_P1_NOSCFG 0xf401
+#define NOSCFG REGx(R0900_P1_NOSCFG)
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
+
+/*P1_ISYMB*/
+#define R0900_P1_ISYMB 0xf402
+#define ISYMB REGx(R0900_P1_ISYMB)
+#define F0900_P1_I_SYMBOL 0xf40201ff
+
+/*P1_QSYMB*/
+#define R0900_P1_QSYMB 0xf403
+#define QSYMB REGx(R0900_P1_QSYMB)
+#define F0900_P1_Q_SYMBOL 0xf40301ff
+
+/*P1_AGC1CFG*/
+#define R0900_P1_AGC1CFG 0xf404
+#define AGC1CFG REGx(R0900_P1_AGC1CFG)
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
+
+/*P1_AGC1CN*/
+#define R0900_P1_AGC1CN 0xf406
+#define AGC1CN REGx(R0900_P1_AGC1CN)
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
+
+/*P1_AGC1REF*/
+#define R0900_P1_AGC1REF 0xf407
+#define AGC1REF REGx(R0900_P1_AGC1REF)
+#define F0900_P1_AGCIQ_REF 0xf40700ff
+
+/*P1_IDCCOMP*/
+#define R0900_P1_IDCCOMP 0xf408
+#define IDCCOMP REGx(R0900_P1_IDCCOMP)
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
+
+/*P1_QDCCOMP*/
+#define R0900_P1_QDCCOMP 0xf409
+#define QDCCOMP REGx(R0900_P1_QDCCOMP)
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
+
+/*P1_POWERI*/
+#define R0900_P1_POWERI 0xf40a
+#define POWERI REGx(R0900_P1_POWERI)
+#define F0900_P1_POWER_I 0xf40a00ff
+#define POWER_I FLDx(F0900_P1_POWER_I)
+
+/*P1_POWERQ*/
+#define R0900_P1_POWERQ 0xf40b
+#define POWERQ REGx(R0900_P1_POWERQ)
+#define F0900_P1_POWER_Q 0xf40b00ff
+#define POWER_Q FLDx(F0900_P1_POWER_Q)
+
+/*P1_AGC1AMM*/
+#define R0900_P1_AGC1AMM 0xf40c
+#define AGC1AMM REGx(R0900_P1_AGC1AMM)
+#define F0900_P1_AMM_VALUE 0xf40c00ff
+
+/*P1_AGC1QUAD*/
+#define R0900_P1_AGC1QUAD 0xf40d
+#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
+
+/*P1_AGCIQIN1*/
+#define R0900_P1_AGCIQIN1 0xf40e
+#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
+
+/*P1_AGCIQIN0*/
+#define R0900_P1_AGCIQIN0 0xf40f
+#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
+
+/*P1_DEMOD*/
+#define R0900_P1_DEMOD 0xf410
+#define DEMOD REGx(R0900_P1_DEMOD)
+#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
+#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
+
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
+#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
+
+/*P1_DMDMODCOD*/
+#define R0900_P1_DMDMODCOD 0xf411
+#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
+
+/*P1_DSTATUS*/
+#define R0900_P1_DSTATUS 0xf412
+#define DSTATUS REGx(R0900_P1_DSTATUS)
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
+#define F0900_P1_OVADC_DETECT 0xf4120001
+
+/*P1_DSTATUS2*/
+#define R0900_P1_DSTATUS2 0xf413
+#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
+
+/*P1_DMDCFGMD*/
+#define R0900_P1_DMDCFGMD 0xf414
+#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
+#define F0900_P1_CFR_AUTOSCAN 0xf4140008
+#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
+#define F0900_P1_TUN_RNG 0xf4140003
+
+/*P1_DMDCFG2*/
+#define R0900_P1_DMDCFG2 0xf415
+#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
+#define F0900_P1_INFINITE_RELOCK 0xf4150010
+
+/*P1_DMDISTATE*/
+#define R0900_P1_DMDISTATE 0xf416
+#define DMDISTATE REGx(R0900_P1_DMDISTATE)
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
+
+/*P1_DMDT0M*/
+#define R0900_P1_DMDT0M 0xf417
+#define DMDT0M REGx(R0900_P1_DMDT0M)
+#define F0900_P1_DMDT0_MIN 0xf41700ff
+
+/*P1_DMDSTATE*/
+#define R0900_P1_DMDSTATE 0xf41b
+#define DMDSTATE REGx(R0900_P1_DMDSTATE)
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
+
+/*P1_DMDFLYW*/
+#define R0900_P1_DMDFLYW 0xf41c
+#define DMDFLYW REGx(R0900_P1_DMDFLYW)
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
+
+/*P1_DSTATUS3*/
+#define R0900_P1_DSTATUS3 0xf41d
+#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
+
+/*P1_DMDCFG3*/
+#define R0900_P1_DMDCFG3 0xf41e
+#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
+
+/*P1_DMDCFG4*/
+#define R0900_P1_DMDCFG4 0xf41f
+#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
+
+/*P1_CORRELMANT*/
+#define R0900_P1_CORRELMANT 0xf420
+#define CORRELMANT REGx(R0900_P1_CORRELMANT)
+#define F0900_P1_CORREL_MANT 0xf42000ff
+
+/*P1_CORRELABS*/
+#define R0900_P1_CORRELABS 0xf421
+#define CORRELABS REGx(R0900_P1_CORRELABS)
+#define F0900_P1_CORREL_ABS 0xf42100ff
+
+/*P1_CORRELEXP*/
+#define R0900_P1_CORRELEXP 0xf422
+#define CORRELEXP REGx(R0900_P1_CORRELEXP)
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
+
+/*P1_PLHMODCOD*/
+#define R0900_P1_PLHMODCOD 0xf424
+#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
+
+/*P1_DMDREG*/
+#define R0900_P1_DMDREG 0xf425
+#define DMDREG REGx(R0900_P1_DMDREG)
+#define F0900_P1_DECIM_PLFRAMES 0xf4250001
+
+/*P1_AGC2O*/
+#define R0900_P1_AGC2O 0xf42c
+#define AGC2O REGx(R0900_P1_AGC2O)
+#define F0900_P1_AGC2_COEF 0xf42c0007
+
+/*P1_AGC2REF*/
+#define R0900_P1_AGC2REF 0xf42d
+#define AGC2REF REGx(R0900_P1_AGC2REF)
+#define F0900_P1_AGC2_REF 0xf42d00ff
+
+/*P1_AGC1ADJ*/
+#define R0900_P1_AGC1ADJ 0xf42e
+#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
+#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
+
+/*P1_AGC2I1*/
+#define R0900_P1_AGC2I1 0xf436
+#define AGC2I1 REGx(R0900_P1_AGC2I1)
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
+
+/*P1_AGC2I0*/
+#define R0900_P1_AGC2I0 0xf437
+#define AGC2I0 REGx(R0900_P1_AGC2I0)
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
+
+/*P1_CARCFG*/
+#define R0900_P1_CARCFG 0xf438
+#define CARCFG REGx(R0900_P1_CARCFG)
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
+
+/*P1_ACLC*/
+#define R0900_P1_ACLC 0xf439
+#define ACLC REGx(R0900_P1_ACLC)
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
+
+/*P1_BCLC*/
+#define R0900_P1_BCLC 0xf43a
+#define BCLC REGx(R0900_P1_BCLC)
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
+
+/*P1_CARFREQ*/
+#define R0900_P1_CARFREQ 0xf43d
+#define CARFREQ REGx(R0900_P1_CARFREQ)
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
+
+/*P1_CARHDR*/
+#define R0900_P1_CARHDR 0xf43e
+#define CARHDR REGx(R0900_P1_CARHDR)
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
+
+/*P1_LDT*/
+#define R0900_P1_LDT 0xf43f
+#define LDT REGx(R0900_P1_LDT)
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
+
+/*P1_LDT2*/
+#define R0900_P1_LDT2 0xf440
+#define LDT2 REGx(R0900_P1_LDT2)
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
+
+/*P1_CFRICFG*/
+#define R0900_P1_CFRICFG 0xf441
+#define CFRICFG REGx(R0900_P1_CFRICFG)
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
+
+/*P1_CFRUP1*/
+#define R0900_P1_CFRUP1 0xf442
+#define CFRUP1 REGx(R0900_P1_CFRUP1)
+#define F0900_P1_CFR_UP1 0xf44201ff
+#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
+
+/*P1_CFRUP0*/
+#define R0900_P1_CFRUP0 0xf443
+#define CFRUP0 REGx(R0900_P1_CFRUP0)
+#define F0900_P1_CFR_UP0 0xf44300ff
+#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
+
+/*P1_CFRLOW1*/
+#define R0900_P1_CFRLOW1 0xf446
+#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
+#define F0900_P1_CFR_LOW1 0xf44601ff
+#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
+
+/*P1_CFRLOW0*/
+#define R0900_P1_CFRLOW0 0xf447
+#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
+#define F0900_P1_CFR_LOW0 0xf44700ff
+#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
+
+/*P1_CFRINIT1*/
+#define R0900_P1_CFRINIT1 0xf448
+#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
+#define F0900_P1_CFR_INIT1 0xf44801ff
+#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
+
+/*P1_CFRINIT0*/
+#define R0900_P1_CFRINIT0 0xf449
+#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
+#define F0900_P1_CFR_INIT0 0xf44900ff
+#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
+
+/*P1_CFRINC1*/
+#define R0900_P1_CFRINC1 0xf44a
+#define CFRINC1 REGx(R0900_P1_CFRINC1)
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a003f
+
+/*P1_CFRINC0*/
+#define R0900_P1_CFRINC0 0xf44b
+#define CFRINC0 REGx(R0900_P1_CFRINC0)
+#define F0900_P1_CFR_INC0 0xf44b00f8
+
+/*P1_CFR2*/
+#define R0900_P1_CFR2 0xf44c
+#define CFR2 REGx(R0900_P1_CFR2)
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
+
+/*P1_CFR1*/
+#define R0900_P1_CFR1 0xf44d
+#define CFR1 REGx(R0900_P1_CFR1)
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
+
+/*P1_CFR0*/
+#define R0900_P1_CFR0 0xf44e
+#define CFR0 REGx(R0900_P1_CFR0)
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
+
+/*P1_LDI*/
+#define R0900_P1_LDI 0xf44f
+#define LDI REGx(R0900_P1_LDI)
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
+
+/*P1_TMGCFG*/
+#define R0900_P1_TMGCFG 0xf450
+#define TMGCFG REGx(R0900_P1_TMGCFG)
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_TMG_MINFREQ 0xf4500003
+
+/*P1_RTC*/
+#define R0900_P1_RTC 0xf451
+#define RTC REGx(R0900_P1_RTC)
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
+
+/*P1_RTCS2*/
+#define R0900_P1_RTCS2 0xf452
+#define RTCS2 REGx(R0900_P1_RTCS2)
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
+
+/*P1_TMGTHRISE*/
+#define R0900_P1_TMGTHRISE 0xf453
+#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
+
+/*P1_TMGTHFALL*/
+#define R0900_P1_TMGTHFALL 0xf454
+#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
+
+/*P1_SFRUPRATIO*/
+#define R0900_P1_SFRUPRATIO 0xf455
+#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
+
+/*P1_SFRLOWRATIO*/
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
+
+/*P1_KREFTMG*/
+#define R0900_P1_KREFTMG 0xf458
+#define KREFTMG REGx(R0900_P1_KREFTMG)
+#define F0900_P1_KREF_TMG 0xf45800ff
+
+/*P1_SFRSTEP*/
+#define R0900_P1_SFRSTEP 0xf459
+#define SFRSTEP REGx(R0900_P1_SFRSTEP)
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
+
+/*P1_TMGCFG2*/
+#define R0900_P1_TMGCFG2 0xf45a
+#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_KREFTMG2*/
+#define R0900_P1_KREFTMG2 0xf45b
+#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
+#define F0900_P1_KREF_TMG2 0xf45b00ff
+
+/*P1_SFRINIT1*/
+#define R0900_P1_SFRINIT1 0xf45e
+#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
+#define F0900_P1_SFR_INIT1 0xf45e007f
+
+/*P1_SFRINIT0*/
+#define R0900_P1_SFRINIT0 0xf45f
+#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
+#define F0900_P1_SFR_INIT0 0xf45f00ff
+
+/*P1_SFRUP1*/
+#define R0900_P1_SFRUP1 0xf460
+#define SFRUP1 REGx(R0900_P1_SFRUP1)
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
+
+/*P1_SFRUP0*/
+#define R0900_P1_SFRUP0 0xf461
+#define SFRUP0 REGx(R0900_P1_SFRUP0)
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
+
+/*P1_SFRLOW1*/
+#define R0900_P1_SFRLOW1 0xf462
+#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
+
+/*P1_SFRLOW0*/
+#define R0900_P1_SFRLOW0 0xf463
+#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
+
+/*P1_SFR3*/
+#define R0900_P1_SFR3 0xf464
+#define SFR3 REGx(R0900_P1_SFR3)
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
+
+/*P1_SFR2*/
+#define R0900_P1_SFR2 0xf465
+#define SFR2 REGx(R0900_P1_SFR2)
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
+
+/*P1_SFR1*/
+#define R0900_P1_SFR1 0xf466
+#define SFR1 REGx(R0900_P1_SFR1)
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
+
+/*P1_SFR0*/
+#define R0900_P1_SFR0 0xf467
+#define SFR0 REGx(R0900_P1_SFR0)
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
+
+/*P1_TMGREG2*/
+#define R0900_P1_TMGREG2 0xf468
+#define TMGREG2 REGx(R0900_P1_TMGREG2)
+#define F0900_P1_TMGREG2 0xf46800ff
+
+/*P1_TMGREG1*/
+#define R0900_P1_TMGREG1 0xf469
+#define TMGREG1 REGx(R0900_P1_TMGREG1)
+#define F0900_P1_TMGREG1 0xf46900ff
+
+/*P1_TMGREG0*/
+#define R0900_P1_TMGREG0 0xf46a
+#define TMGREG0 REGx(R0900_P1_TMGREG0)
+#define F0900_P1_TMGREG0 0xf46a00ff
+
+/*P1_TMGLOCK1*/
+#define R0900_P1_TMGLOCK1 0xf46b
+#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
+
+/*P1_TMGLOCK0*/
+#define R0900_P1_TMGLOCK0 0xf46c
+#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
+
+/*P1_TMGOBS*/
+#define R0900_P1_TMGOBS 0xf46d
+#define TMGOBS REGx(R0900_P1_TMGOBS)
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
+
+/*P1_EQUALCFG*/
+#define R0900_P1_EQUALCFG 0xf46f
+#define EQUALCFG REGx(R0900_P1_EQUALCFG)
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
+
+/*P1_EQUAI1*/
+#define R0900_P1_EQUAI1 0xf470
+#define EQUAI1 REGx(R0900_P1_EQUAI1)
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
+
+/*P1_EQUAQ1*/
+#define R0900_P1_EQUAQ1 0xf471
+#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
+
+/*P1_EQUAI2*/
+#define R0900_P1_EQUAI2 0xf472
+#define EQUAI2 REGx(R0900_P1_EQUAI2)
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
+
+/*P1_EQUAQ2*/
+#define R0900_P1_EQUAQ2 0xf473
+#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
+
+/*P1_EQUAI3*/
+#define R0900_P1_EQUAI3 0xf474
+#define EQUAI3 REGx(R0900_P1_EQUAI3)
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
+
+/*P1_EQUAQ3*/
+#define R0900_P1_EQUAQ3 0xf475
+#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
+
+/*P1_EQUAI4*/
+#define R0900_P1_EQUAI4 0xf476
+#define EQUAI4 REGx(R0900_P1_EQUAI4)
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
+
+/*P1_EQUAQ4*/
+#define R0900_P1_EQUAQ4 0xf477
+#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
+
+/*P1_EQUAI5*/
+#define R0900_P1_EQUAI5 0xf478
+#define EQUAI5 REGx(R0900_P1_EQUAI5)
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
+
+/*P1_EQUAQ5*/
+#define R0900_P1_EQUAQ5 0xf479
+#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
+
+/*P1_EQUAI6*/
+#define R0900_P1_EQUAI6 0xf47a
+#define EQUAI6 REGx(R0900_P1_EQUAI6)
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
+
+/*P1_EQUAQ6*/
+#define R0900_P1_EQUAQ6 0xf47b
+#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
+
+/*P1_EQUAI7*/
+#define R0900_P1_EQUAI7 0xf47c
+#define EQUAI7 REGx(R0900_P1_EQUAI7)
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
+
+/*P1_EQUAQ7*/
+#define R0900_P1_EQUAQ7 0xf47d
+#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
+
+/*P1_EQUAI8*/
+#define R0900_P1_EQUAI8 0xf47e
+#define EQUAI8 REGx(R0900_P1_EQUAI8)
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
+
+/*P1_EQUAQ8*/
+#define R0900_P1_EQUAQ8 0xf47f
+#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
+
+/*P1_NNOSDATAT1*/
+#define R0900_P1_NNOSDATAT1 0xf480
+#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
+
+/*P1_NNOSDATAT0*/
+#define R0900_P1_NNOSDATAT0 0xf481
+#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
+
+/*P1_NNOSDATA1*/
+#define R0900_P1_NNOSDATA1 0xf482
+#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
+
+/*P1_NNOSDATA0*/
+#define R0900_P1_NNOSDATA0 0xf483
+#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
+
+/*P1_NNOSPLHT1*/
+#define R0900_P1_NNOSPLHT1 0xf484
+#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
+
+/*P1_NNOSPLHT0*/
+#define R0900_P1_NNOSPLHT0 0xf485
+#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
+
+/*P1_NNOSPLH1*/
+#define R0900_P1_NNOSPLH1 0xf486
+#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
+
+/*P1_NNOSPLH0*/
+#define R0900_P1_NNOSPLH0 0xf487
+#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
+
+/*P1_NOSDATAT1*/
+#define R0900_P1_NOSDATAT1 0xf488
+#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
+
+/*P1_NOSDATAT0*/
+#define R0900_P1_NOSDATAT0 0xf489
+#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
+
+/*P1_NOSDATA1*/
+#define R0900_P1_NOSDATA1 0xf48a
+#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
+
+/*P1_NOSDATA0*/
+#define R0900_P1_NOSDATA0 0xf48b
+#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
+
+/*P1_NOSPLHT1*/
+#define R0900_P1_NOSPLHT1 0xf48c
+#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
+
+/*P1_NOSPLHT0*/
+#define R0900_P1_NOSPLHT0 0xf48d
+#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
+
+/*P1_NOSPLH1*/
+#define R0900_P1_NOSPLH1 0xf48e
+#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
+
+/*P1_NOSPLH0*/
+#define R0900_P1_NOSPLH0 0xf48f
+#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
+
+/*P1_CAR2CFG*/
+#define R0900_P1_CAR2CFG 0xf490
+#define CAR2CFG REGx(R0900_P1_CAR2CFG)
+#define F0900_P1_CARRIER3_DISABLE 0xf4900040
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
+
+/*P1_CFR2CFR1*/
+#define R0900_P1_CFR2CFR1 0xf491
+#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
+#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
+#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
+#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
+#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
+
+/*P1_CFR22*/
+#define R0900_P1_CFR22 0xf493
+#define CFR22 REGx(R0900_P1_CFR22)
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
+
+/*P1_CFR21*/
+#define R0900_P1_CFR21 0xf494
+#define CFR21 REGx(R0900_P1_CFR21)
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
+
+/*P1_CFR20*/
+#define R0900_P1_CFR20 0xf495
+#define CFR20 REGx(R0900_P1_CFR20)
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
+
+/*P1_ACLC2S2Q*/
+#define R0900_P1_ACLC2S2Q 0xf497
+#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
+
+/*P1_ACLC2S28*/
+#define R0900_P1_ACLC2S28 0xf498
+#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
+
+/*P1_ACLC2S216A*/
+#define R0900_P1_ACLC2S216A 0xf499
+#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
+#define F0900_P1_DIS_C3STOPA2 0xf4990080
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
+
+/*P1_ACLC2S232A*/
+#define R0900_P1_ACLC2S232A 0xf49a
+#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
+
+/*P1_BCLC2S2Q*/
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
+
+/*P1_BCLC2S28*/
+#define R0900_P1_BCLC2S28 0xf49d
+#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
+
+/*P1_BCLC2S216A*/
+#define R0900_P1_BCLC2S216A 0xf49e
+#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
+
+/*P1_BCLC2S232A*/
+#define R0900_P1_BCLC2S232A 0xf49f
+#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
+
+/*P1_PLROOT2*/
+#define R0900_P1_PLROOT2 0xf4ac
+#define PLROOT2 REGx(R0900_P1_PLROOT2)
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
+
+/*P1_PLROOT1*/
+#define R0900_P1_PLROOT1 0xf4ad
+#define PLROOT1 REGx(R0900_P1_PLROOT1)
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
+
+/*P1_PLROOT0*/
+#define R0900_P1_PLROOT0 0xf4ae
+#define PLROOT0 REGx(R0900_P1_PLROOT0)
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
+
+/*P1_MODCODLST0*/
+#define R0900_P1_MODCODLST0 0xf4b0
+#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
+
+/*P1_MODCODLST1*/
+#define R0900_P1_MODCODLST1 0xf4b1
+#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
+
+/*P1_MODCODLST2*/
+#define R0900_P1_MODCODLST2 0xf4b2
+#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
+
+/*P1_MODCODLST3*/
+#define R0900_P1_MODCODLST3 0xf4b3
+#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
+
+/*P1_MODCODLST4*/
+#define R0900_P1_MODCODLST4 0xf4b4
+#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
+
+/*P1_MODCODLST5*/
+#define R0900_P1_MODCODLST5 0xf4b5
+#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
+
+/*P1_MODCODLST6*/
+#define R0900_P1_MODCODLST6 0xf4b6
+#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
+
+/*P1_MODCODLST7*/
+#define R0900_P1_MODCODLST7 0xf4b7
+#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
+
+/*P1_MODCODLST8*/
+#define R0900_P1_MODCODLST8 0xf4b8
+#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
+
+/*P1_MODCODLST9*/
+#define R0900_P1_MODCODLST9 0xf4b9
+#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
+
+/*P1_MODCODLSTA*/
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
+
+/*P1_MODCODLSTB*/
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
+
+/*P1_MODCODLSTC*/
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
+
+/*P1_MODCODLSTD*/
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
+
+/*P1_MODCODLSTE*/
+#define R0900_P1_MODCODLSTE 0xf4be
+#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
+
+/*P1_MODCODLSTF*/
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+
+/*P1_GAUSSR0*/
+#define R0900_P1_GAUSSR0 0xf4c0
+#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
+#define F0900_P1_EN_CCIMODE 0xf4c00080
+#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
+
+/*P1_CCIR0*/
+#define R0900_P1_CCIR0 0xf4c1
+#define CCIR0 REGx(R0900_P1_CCIR0)
+#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
+#define F0900_P1_R0_CCI 0xf4c1007f
+
+/*P1_CCIQUANT*/
+#define R0900_P1_CCIQUANT 0xf4c2
+#define CCIQUANT REGx(R0900_P1_CCIQUANT)
+#define F0900_P1_CCI_BETA 0xf4c200e0
+#define F0900_P1_CCI_QUANT 0xf4c2001f
+
+/*P1_CCITHRES*/
+#define R0900_P1_CCITHRES 0xf4c3
+#define CCITHRES REGx(R0900_P1_CCITHRES)
+#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
+
+/*P1_CCIACC*/
+#define R0900_P1_CCIACC 0xf4c4
+#define CCIACC REGx(R0900_P1_CCIACC)
+#define F0900_P1_CCI_VALUE 0xf4c400ff
+
+/*P1_DMDRESCFG*/
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
+
+/*P1_DMDRESADR*/
+#define R0900_P1_DMDRESADR 0xf4c7
+#define DMDRESADR REGx(R0900_P1_DMDRESADR)
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
+
+/*P1_DMDRESDATA7*/
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
+
+/*P1_DMDRESDATA6*/
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
+
+/*P1_DMDRESDATA5*/
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
+
+/*P1_DMDRESDATA4*/
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
+
+/*P1_DMDRESDATA3*/
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
+
+/*P1_DMDRESDATA2*/
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
+
+/*P1_DMDRESDATA1*/
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
+
+/*P1_DMDRESDATA0*/
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
+
+/*P1_FFEI1*/
+#define R0900_P1_FFEI1 0xf4d0
+#define FFEI1 REGx(R0900_P1_FFEI1)
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
+
+/*P1_FFEQ1*/
+#define R0900_P1_FFEQ1 0xf4d1
+#define FFEQ1 REGx(R0900_P1_FFEQ1)
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
+
+/*P1_FFEI2*/
+#define R0900_P1_FFEI2 0xf4d2
+#define FFEI2 REGx(R0900_P1_FFEI2)
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
+
+/*P1_FFEQ2*/
+#define R0900_P1_FFEQ2 0xf4d3
+#define FFEQ2 REGx(R0900_P1_FFEQ2)
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
+
+/*P1_FFEI3*/
+#define R0900_P1_FFEI3 0xf4d4
+#define FFEI3 REGx(R0900_P1_FFEI3)
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
+
+/*P1_FFEQ3*/
+#define R0900_P1_FFEQ3 0xf4d5
+#define FFEQ3 REGx(R0900_P1_FFEQ3)
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
+
+/*P1_FFEI4*/
+#define R0900_P1_FFEI4 0xf4d6
+#define FFEI4 REGx(R0900_P1_FFEI4)
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
+
+/*P1_FFEQ4*/
+#define R0900_P1_FFEQ4 0xf4d7
+#define FFEQ4 REGx(R0900_P1_FFEQ4)
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
+
+/*P1_FFECFG*/
+#define R0900_P1_FFECFG 0xf4d8
+#define FFECFG REGx(R0900_P1_FFECFG)
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
+
+/*P1_TNRCFG*/
+#define R0900_P1_TNRCFG 0xf4e0
+#define TNRCFG REGx(R0900_P1_TNRCFG)
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
+
+/*P1_TNRCFG2*/
+#define R0900_P1_TNRCFG2 0xf4e1
+#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
+
+/*P1_TNRXTAL*/
+#define R0900_P1_TNRXTAL 0xf4e4
+#define TNRXTAL REGx(R0900_P1_TNRXTAL)
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
+
+/*P1_TNRSTEPS*/
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
+#define F0900_P1_TUNER_BW0P125 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70170
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70007
+
+/*P1_TNRGAIN*/
+#define R0900_P1_TNRGAIN 0xf4e8
+#define TNRGAIN REGx(R0900_P1_TNRGAIN)
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
+
+/*P1_TNRRF1*/
+#define R0900_P1_TNRRF1 0xf4e9
+#define TNRRF1 REGx(R0900_P1_TNRRF1)
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
+#define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2)
+
+/*P1_TNRRF0*/
+#define R0900_P1_TNRRF0 0xf4ea
+#define TNRRF0 REGx(R0900_P1_TNRRF0)
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
+#define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1)
+
+/*P1_TNRBW*/
+#define R0900_P1_TNRBW 0xf4eb
+#define TNRBW REGx(R0900_P1_TNRBW)
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0)
+#define F0900_P1_TUN_BW 0xf4eb003f
+#define TUN_BW FLDx(F0900_P1_TUN_BW)
+
+/*P1_TNRADJ*/
+#define R0900_P1_TNRADJ 0xf4ec
+#define TNRADJ REGx(R0900_P1_TNRADJ)
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
+
+/*P1_TNRCTL2*/
+#define R0900_P1_TNRCTL2 0xf4ed
+#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
+#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
+#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
+#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
+#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
+#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
+#define F0900_P1_STB6XX0_SYN 0xf4ed0001
+
+/*P1_TNRCFG3*/
+#define R0900_P1_TNRCFG3 0xf4ee
+#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
+
+/*P1_TNRLAUNCH*/
+#define R0900_P1_TNRLAUNCH 0xf4f0
+#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
+
+/*P1_TNRLD*/
+#define R0900_P1_TNRLD 0xf4f0
+#define TNRLD REGx(R0900_P1_TNRLD)
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
+
+/*P1_TNROBSL*/
+#define R0900_P1_TNROBSL 0xf4f6
+#define TNROBSL REGx(R0900_P1_TNROBSL)
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
+#define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1)
+
+/*P1_TNRRESTE*/
+#define R0900_P1_TNRRESTE 0xf4f7
+#define TNRRESTE REGx(R0900_P1_TNRRESTE)
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
+#define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0)
+
+/*P1_SMAPCOEF7*/
+#define R0900_P1_SMAPCOEF7 0xf500
+#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
+
+/*P1_SMAPCOEF6*/
+#define R0900_P1_SMAPCOEF6 0xf501
+#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
+
+/*P1_SMAPCOEF5*/
+#define R0900_P1_SMAPCOEF5 0xf502
+#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_NCO2MAX1*/
+#define R0900_P1_NCO2MAX1 0xf514
+#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
+#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
+
+/*P1_NCO2MAX0*/
+#define R0900_P1_NCO2MAX0 0xf515
+#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
+#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
+
+/*P1_NCO2FR1*/
+#define R0900_P1_NCO2FR1 0xf516
+#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
+#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
+
+/*P1_NCO2FR0*/
+#define R0900_P1_NCO2FR0 0xf517
+#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
+#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
+
+/*P1_CFR2AVRGE1*/
+#define R0900_P1_CFR2AVRGE1 0xf518
+#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
+#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
+
+/*P1_CFR2AVRGE0*/
+#define R0900_P1_CFR2AVRGE0 0xf519
+#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
+#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
+
+/*P1_DMDPLHSTAT*/
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
+
+/*P1_LOCKTIME3*/
+#define R0900_P1_LOCKTIME3 0xf522
+#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
+
+/*P1_LOCKTIME2*/
+#define R0900_P1_LOCKTIME2 0xf523
+#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
+
+/*P1_LOCKTIME1*/
+#define R0900_P1_LOCKTIME1 0xf524
+#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
+
+/*P1_LOCKTIME0*/
+#define R0900_P1_LOCKTIME0 0xf525
+#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
+
+/*P1_VITSCALE*/
+#define R0900_P1_VITSCALE 0xf532
+#define VITSCALE REGx(R0900_P1_VITSCALE)
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
+
+/*P1_FECM*/
+#define R0900_P1_FECM 0xf533
+#define FECM REGx(R0900_P1_FECM)
+#define F0900_P1_DSS_DVB 0xf5330080
+#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+#define IQINV FLDx(F0900_P1_IQINV)
+
+/*P1_VTH12*/
+#define R0900_P1_VTH12 0xf534
+#define VTH12 REGx(R0900_P1_VTH12)
+#define F0900_P1_VTH12 0xf53400ff
+
+/*P1_VTH23*/
+#define R0900_P1_VTH23 0xf535
+#define VTH23 REGx(R0900_P1_VTH23)
+#define F0900_P1_VTH23 0xf53500ff
+
+/*P1_VTH34*/
+#define R0900_P1_VTH34 0xf536
+#define VTH34 REGx(R0900_P1_VTH34)
+#define F0900_P1_VTH34 0xf53600ff
+
+/*P1_VTH56*/
+#define R0900_P1_VTH56 0xf537
+#define VTH56 REGx(R0900_P1_VTH56)
+#define F0900_P1_VTH56 0xf53700ff
+
+/*P1_VTH67*/
+#define R0900_P1_VTH67 0xf538
+#define VTH67 REGx(R0900_P1_VTH67)
+#define F0900_P1_VTH67 0xf53800ff
+
+/*P1_VTH78*/
+#define R0900_P1_VTH78 0xf539
+#define VTH78 REGx(R0900_P1_VTH78)
+#define F0900_P1_VTH78 0xf53900ff
+
+/*P1_VITCURPUN*/
+#define R0900_P1_VITCURPUN 0xf53a
+#define VITCURPUN REGx(R0900_P1_VITCURPUN)
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
+
+/*P1_VERROR*/
+#define R0900_P1_VERROR 0xf53b
+#define VERROR REGx(R0900_P1_VERROR)
+#define F0900_P1_REGERR_VIT 0xf53b00ff
+
+/*P1_PRVIT*/
+#define R0900_P1_PRVIT 0xf53c
+#define PRVIT REGx(R0900_P1_PRVIT)
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
+
+/*P1_VAVSRVIT*/
+#define R0900_P1_VAVSRVIT 0xf53d
+#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
+
+/*P1_VSTATUSVIT*/
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
+#define F0900_P1_PRFVIT 0xf53e0010
+#define PRFVIT FLDx(F0900_P1_PRFVIT)
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
+
+/*P1_VTHINUSE*/
+#define R0900_P1_VTHINUSE 0xf53f
+#define VTHINUSE REGx(R0900_P1_VTHINUSE)
+#define F0900_P1_VIT_INUSE 0xf53f00ff
+
+/*P1_KDIV12*/
+#define R0900_P1_KDIV12 0xf540
+#define KDIV12 REGx(R0900_P1_KDIV12)
+#define F0900_P1_K_DIVIDER_12 0xf540007f
+
+/*P1_KDIV23*/
+#define R0900_P1_KDIV23 0xf541
+#define KDIV23 REGx(R0900_P1_KDIV23)
+#define F0900_P1_K_DIVIDER_23 0xf541007f
+
+/*P1_KDIV34*/
+#define R0900_P1_KDIV34 0xf542
+#define KDIV34 REGx(R0900_P1_KDIV34)
+#define F0900_P1_K_DIVIDER_34 0xf542007f
+
+/*P1_KDIV56*/
+#define R0900_P1_KDIV56 0xf543
+#define KDIV56 REGx(R0900_P1_KDIV56)
+#define F0900_P1_K_DIVIDER_56 0xf543007f
+
+/*P1_KDIV67*/
+#define R0900_P1_KDIV67 0xf544
+#define KDIV67 REGx(R0900_P1_KDIV67)
+#define F0900_P1_K_DIVIDER_67 0xf544007f
+
+/*P1_KDIV78*/
+#define R0900_P1_KDIV78 0xf545
+#define KDIV78 REGx(R0900_P1_KDIV78)
+#define F0900_P1_K_DIVIDER_78 0xf545007f
+
+/*P1_PDELCTRL1*/
+#define R0900_P1_PDELCTRL1 0xf550
+#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
+
+/*P1_PDELCTRL2*/
+#define R0900_P1_PDELCTRL2 0xf551
+#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
+#define F0900_P1_FRAME_MODE 0xf5510002
+#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
+
+/*P1_HYSTTHRESH*/
+#define R0900_P1_HYSTTHRESH 0xf554
+#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
+
+/*P1_ISIENTRY*/
+#define R0900_P1_ISIENTRY 0xf55e
+#define ISIENTRY REGx(R0900_P1_ISIENTRY)
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
+
+/*P1_ISIBITENA*/
+#define R0900_P1_ISIBITENA 0xf55f
+#define ISIBITENA REGx(R0900_P1_ISIBITENA)
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
+
+/*P1_MATSTR1*/
+#define R0900_P1_MATSTR1 0xf560
+#define MATSTR1 REGx(R0900_P1_MATSTR1)
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
+
+/*P1_MATSTR0*/
+#define R0900_P1_MATSTR0 0xf561
+#define MATSTR0 REGx(R0900_P1_MATSTR0)
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
+
+/*P1_UPLSTR1*/
+#define R0900_P1_UPLSTR1 0xf562
+#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
+
+/*P1_UPLSTR0*/
+#define R0900_P1_UPLSTR0 0xf563
+#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
+
+/*P1_DFLSTR1*/
+#define R0900_P1_DFLSTR1 0xf564
+#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
+
+/*P1_DFLSTR0*/
+#define R0900_P1_DFLSTR0 0xf565
+#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
+
+/*P1_SYNCSTR*/
+#define R0900_P1_SYNCSTR 0xf566
+#define SYNCSTR REGx(R0900_P1_SYNCSTR)
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
+
+/*P1_SYNCDSTR1*/
+#define R0900_P1_SYNCDSTR1 0xf567
+#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
+
+/*P1_SYNCDSTR0*/
+#define R0900_P1_SYNCDSTR0 0xf568
+#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
+
+/*P1_PDELSTATUS1*/
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
+#define F0900_P1_FIRST_LOCK 0xf5690001
+
+/*P1_PDELSTATUS2*/
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
+
+/*P1_BBFCRCKO1*/
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
+
+/*P1_BBFCRCKO0*/
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
+
+/*P1_UPCRCKO1*/
+#define R0900_P1_UPCRCKO1 0xf56d
+#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
+
+/*P1_UPCRCKO0*/
+#define R0900_P1_UPCRCKO0 0xf56e
+#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_PDELCTRL3*/
+#define R0900_P1_PDELCTRL3 0xf56f
+#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
+#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
+#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
+
+/*P1_TSSTATEM*/
+#define R0900_P1_TSSTATEM 0xf570
+#define TSSTATEM REGx(R0900_P1_TSSTATEM)
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
+
+/*P1_TSCFGH*/
+#define R0900_P1_TSCFGH 0xf572
+#define TSCFGH REGx(R0900_P1_TSCFGH)
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
+
+/*P1_TSCFGM*/
+#define R0900_P1_TSCFGM 0xf573
+#define TSCFGM REGx(R0900_P1_TSCFGM)
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
+
+/*P1_TSCFGL*/
+#define R0900_P1_TSCFGL 0xf574
+#define TSCFGL REGx(R0900_P1_TSCFGL)
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
+
+/*P1_TSINSDELH*/
+#define R0900_P1_TSINSDELH 0xf576
+#define TSINSDELH REGx(R0900_P1_TSINSDELH)
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSDIVN*/
+#define R0900_P1_TSDIVN 0xf579
+#define TSDIVN REGx(R0900_P1_TSDIVN)
+#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
+
+/*P1_TSCFG4*/
+#define R0900_P1_TSCFG4 0xf57a
+#define TSCFG4 REGx(R0900_P1_TSCFG4)
+#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
+
+/*P1_TSSPEED*/
+#define R0900_P1_TSSPEED 0xf580
+#define TSSPEED REGx(R0900_P1_TSSPEED)
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
+
+/*P1_TSSTATUS*/
+#define R0900_P1_TSSTATUS 0xf581
+#define TSSTATUS REGx(R0900_P1_TSSTATUS)
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_DIL_READY 0xf5810001
+
+/*P1_TSSTATUS2*/
+#define R0900_P1_TSSTATUS2 0xf582
+#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_SCRAMBDETECT 0xf5820002
+
+/*P1_TSBITRATE1*/
+#define R0900_P1_TSBITRATE1 0xf583
+#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
+
+/*P1_TSBITRATE0*/
+#define R0900_P1_TSBITRATE0 0xf584
+#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
+
+/*P1_ERRCTRL1*/
+#define R0900_P1_ERRCTRL1 0xf598
+#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
+
+/*P1_ERRCNT12*/
+#define R0900_P1_ERRCNT12 0xf599
+#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
+
+/*P1_ERRCNT11*/
+#define R0900_P1_ERRCNT11 0xf59a
+#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
+
+/*P1_ERRCNT10*/
+#define R0900_P1_ERRCNT10 0xf59b
+#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
+
+/*P1_ERRCTRL2*/
+#define R0900_P1_ERRCTRL2 0xf59c
+#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
+
+/*P1_ERRCNT22*/
+#define R0900_P1_ERRCNT22 0xf59d
+#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
+
+/*P1_ERRCNT21*/
+#define R0900_P1_ERRCNT21 0xf59e
+#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
+
+/*P1_ERRCNT20*/
+#define R0900_P1_ERRCNT20 0xf59f
+#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
+
+/*P1_FECSPY*/
+#define R0900_P1_FECSPY 0xf5a0
+#define FECSPY REGx(R0900_P1_FECSPY)
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
+
+/*P1_FSPYCFG*/
+#define R0900_P1_FSPYCFG 0xf5a1
+#define FSPYCFG REGx(R0900_P1_FSPYCFG)
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
+
+/*P1_FSPYDATA*/
+#define R0900_P1_FSPYDATA 0xf5a2
+#define FSPYDATA REGx(R0900_P1_FSPYDATA)
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
+
+/*P1_FSPYOUT*/
+#define R0900_P1_FSPYOUT 0xf5a3
+#define FSPYOUT REGx(R0900_P1_FSPYOUT)
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_STUFF_MODE 0xf5a30007
+
+/*P1_FSTATUS*/
+#define R0900_P1_FSTATUS 0xf5a4
+#define FSTATUS REGx(R0900_P1_FSTATUS)
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
+
+/*P1_FBERCPT4*/
+#define R0900_P1_FBERCPT4 0xf5a8
+#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
+
+/*P1_FBERCPT3*/
+#define R0900_P1_FBERCPT3 0xf5a9
+#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
+
+/*P1_FBERCPT2*/
+#define R0900_P1_FBERCPT2 0xf5aa
+#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
+
+/*P1_FBERCPT1*/
+#define R0900_P1_FBERCPT1 0xf5ab
+#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
+
+/*P1_FBERCPT0*/
+#define R0900_P1_FBERCPT0 0xf5ac
+#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
+
+/*P1_FBERERR2*/
+#define R0900_P1_FBERERR2 0xf5ad
+#define FBERERR2 REGx(R0900_P1_FBERERR2)
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
+
+/*P1_FBERERR1*/
+#define R0900_P1_FBERERR1 0xf5ae
+#define FBERERR1 REGx(R0900_P1_FBERERR1)
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
+
+/*P1_FBERERR0*/
+#define R0900_P1_FBERERR0 0xf5af
+#define FBERERR0 REGx(R0900_P1_FBERERR0)
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
+
+/*P1_FSPYBER*/
+#define R0900_P1_FSPYBER 0xf5b2
+#define FSPYBER REGx(R0900_P1_FSPYBER)
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
+
+/*RCCFG2*/
+#define R0900_RCCFG2 0xf600
+
+/*TSGENERAL*/
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_DISTS2PAR 0xf6300040
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
+
+/*TSGENERAL1X*/
+#define R0900_TSGENERAL1X 0xf670
+
+/*NBITER_NF4*/
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
+
+/*NBITER_NF5*/
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
+
+/*NBITER_NF6*/
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
+
+/*NBITER_NF7*/
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
+
+/*NBITER_NF8*/
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
+
+/*NBITER_NF9*/
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
+
+/*NBITER_NF10*/
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
+
+/*NBITER_NF11*/
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
+
+/*NBITER_NF12*/
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
+
+/*NBITER_NF13*/
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
+
+/*NBITER_NF14*/
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
+
+/*NBITER_NF15*/
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
+
+/*NBITER_NF16*/
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
+
+/*NBITER_NF17*/
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
+
+/*NBITERNOERR*/
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
+
+/*GAINLLR_NF4*/
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
+
+/*GAINLLR_NF5*/
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
+
+/*GAINLLR_NF6*/
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
+
+/*GAINLLR_NF7*/
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
+
+/*GAINLLR_NF8*/
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
+
+/*GAINLLR_NF9*/
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
+
+/*GAINLLR_NF10*/
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
+
+/*GAINLLR_NF11*/
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
+
+/*GAINLLR_NF12*/
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
+
+/*GAINLLR_NF13*/
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
+
+/*GAINLLR_NF14*/
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
+
+/*GAINLLR_NF15*/
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
+
+/*GAINLLR_NF16*/
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
+
+/*GAINLLR_NF17*/
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
+
+/*CFGEXT*/
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
+
+/*GENCFG*/
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
+
+/*LDPCERR1*/
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
+
+/*LDPCERR0*/
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
+
+/*BCHERR*/
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
+
+/*TSTRES0*/
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+
+/*P2_TCTL4*/
+#define R0900_P2_TCTL4 0xff28
+#define F0900_P2_PN4_SELECT 0xff280020
+
+/*P1_TCTL4*/
+#define R0900_P1_TCTL4 0xff48
+#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
+#define F0900_P1_PN4_SELECT 0xff480020
+
+/*P2_TSTDISRX*/
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_PIN_SELECT1 0xff650008
+
+/*P1_TSTDISRX*/
+#define R0900_P1_TSTDISRX 0xff67
+#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
+#define F0900_P1_PIN_SELECT1 0xff670008
+#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
+
+#define STV0900_NBREGS 723
+#define STV0900_NBFIELDS 1420
+
+#endif
+
diff --git a/drivers/media/dvb-frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c
new file mode 100644 (file)
index 0000000..4af2078
--- /dev/null
@@ -0,0 +1,2032 @@
+/*
+ * stv0900_sw.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+
+s32 shiftx(s32 x, int demod, s32 shift)
+{
+       if (demod == 1)
+               return x - shift;
+
+       return x;
+}
+
+int stv0900_check_signal_presence(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32     carr_offset,
+               agc2_integr,
+               max_carrier;
+
+       int no_signal = FALSE;
+
+       carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
+                                       | stv0900_read_reg(intp, CFR1);
+       carr_offset = ge2comp(carr_offset, 16);
+       agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
+                                       | stv0900_read_reg(intp, AGC2I0);
+       max_carrier = intp->srch_range[demod] / 1000;
+
+       max_carrier += (max_carrier / 10);
+       max_carrier = 65536 * (max_carrier / 2);
+       max_carrier /= intp->mclk / 1000;
+       if (max_carrier > 0x4000)
+               max_carrier = 0x4000;
+
+       if ((agc2_integr > 0x2000)
+                       || (carr_offset > (2 * max_carrier))
+                       || (carr_offset < (-2 * max_carrier)))
+               no_signal = TRUE;
+
+       return no_signal;
+}
+
+static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
+                               s32 *frequency_inc, s32 *sw_timeout,
+                               s32 *steps,
+                               enum fe_stv0900_demod_num demod)
+{
+       s32 timeout, freq_inc, max_steps, srate, max_carrier;
+
+       enum fe_stv0900_search_standard standard;
+
+       srate = intp->symbol_rate[demod];
+       max_carrier = intp->srch_range[demod] / 1000;
+       max_carrier += max_carrier / 10;
+       standard = intp->srch_standard[demod];
+
+       max_carrier = 65536 * (max_carrier / 2);
+       max_carrier /= intp->mclk / 1000;
+
+       if (max_carrier > 0x4000)
+               max_carrier = 0x4000;
+
+       freq_inc = srate;
+       freq_inc /= intp->mclk >> 10;
+       freq_inc = freq_inc << 6;
+
+       switch (standard) {
+       case STV0900_SEARCH_DVBS1:
+       case STV0900_SEARCH_DSS:
+               freq_inc *= 3;
+               timeout = 20;
+               break;
+       case STV0900_SEARCH_DVBS2:
+               freq_inc *= 4;
+               timeout = 25;
+               break;
+       case STV0900_AUTO_SEARCH:
+       default:
+               freq_inc *= 3;
+               timeout = 25;
+               break;
+       }
+
+       freq_inc /= 100;
+
+       if ((freq_inc > max_carrier) || (freq_inc < 0))
+               freq_inc = max_carrier / 2;
+
+       timeout *= 27500;
+
+       if (srate > 0)
+               timeout /= srate / 1000;
+
+       if ((timeout > 100) || (timeout < 0))
+               timeout = 100;
+
+       max_steps = (max_carrier / freq_inc) + 1;
+
+       if ((max_steps > 100) || (max_steps < 0)) {
+               max_steps =  100;
+               freq_inc = max_carrier / max_steps;
+       }
+
+       *frequency_inc = freq_inc;
+       *sw_timeout = timeout;
+       *steps = max_steps;
+
+}
+
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
+                               s32 FreqIncr, s32 Timeout, int zigzag,
+                               s32 MaxStep, enum fe_stv0900_demod_num demod)
+{
+       int     no_signal,
+               lock = FALSE;
+       s32     stepCpt,
+               freqOffset,
+               max_carrier;
+
+       max_carrier = intp->srch_range[demod] / 1000;
+       max_carrier += (max_carrier / 10);
+
+       max_carrier = 65536 * (max_carrier / 2);
+       max_carrier /= intp->mclk / 1000;
+
+       if (max_carrier > 0x4000)
+               max_carrier = 0x4000;
+
+       if (zigzag == TRUE)
+               freqOffset = 0;
+       else
+               freqOffset = -max_carrier + FreqIncr;
+
+       stepCpt = 0;
+
+       do {
+               stv0900_write_reg(intp, DMDISTATE, 0x1c);
+               stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
+               stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
+               stv0900_write_reg(intp, DMDISTATE, 0x18);
+               stv0900_write_bits(intp, ALGOSWRST, 1);
+
+               if (intp->chip_id == 0x12) {
+                       stv0900_write_bits(intp, RST_HWARE, 1);
+                       stv0900_write_bits(intp, RST_HWARE, 0);
+               }
+
+               if (zigzag == TRUE) {
+                       if (freqOffset >= 0)
+                               freqOffset = -freqOffset - 2 * FreqIncr;
+                       else
+                               freqOffset = -freqOffset;
+               } else
+                       freqOffset += + 2 * FreqIncr;
+
+               stepCpt++;
+               lock = stv0900_get_demod_lock(intp, demod, Timeout);
+               no_signal = stv0900_check_signal_presence(intp, demod);
+
+       } while ((lock == FALSE)
+                       && (no_signal == FALSE)
+                       && ((freqOffset - FreqIncr) <  max_carrier)
+                       && ((freqOffset + FreqIncr) > -max_carrier)
+                       && (stepCpt < MaxStep));
+
+       stv0900_write_bits(intp, ALGOSWRST, 0);
+
+       return lock;
+}
+
+static int stv0900_sw_algo(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       int     lock = FALSE,
+               no_signal,
+               zigzag;
+       s32     s2fw,
+               fqc_inc,
+               sft_stp_tout,
+               trial_cntr,
+               max_steps;
+
+       stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
+                                       &max_steps, demod);
+       switch (intp->srch_standard[demod]) {
+       case STV0900_SEARCH_DVBS1:
+       case STV0900_SEARCH_DSS:
+               if (intp->chip_id >= 0x20)
+                       stv0900_write_reg(intp, CARFREQ, 0x3b);
+               else
+                       stv0900_write_reg(intp, CARFREQ, 0xef);
+
+               stv0900_write_reg(intp, DMDCFGMD, 0x49);
+               zigzag = FALSE;
+               break;
+       case STV0900_SEARCH_DVBS2:
+               if (intp->chip_id >= 0x20)
+                       stv0900_write_reg(intp, CORRELABS, 0x79);
+               else
+                       stv0900_write_reg(intp, CORRELABS, 0x68);
+
+               stv0900_write_reg(intp, DMDCFGMD, 0x89);
+
+               zigzag = TRUE;
+               break;
+       case STV0900_AUTO_SEARCH:
+       default:
+               if (intp->chip_id >= 0x20) {
+                       stv0900_write_reg(intp, CARFREQ, 0x3b);
+                       stv0900_write_reg(intp, CORRELABS, 0x79);
+               } else {
+                       stv0900_write_reg(intp, CARFREQ, 0xef);
+                       stv0900_write_reg(intp, CORRELABS, 0x68);
+               }
+
+               stv0900_write_reg(intp, DMDCFGMD, 0xc9);
+               zigzag = FALSE;
+               break;
+       }
+
+       trial_cntr = 0;
+       do {
+               lock = stv0900_search_carr_sw_loop(intp,
+                                               fqc_inc,
+                                               sft_stp_tout,
+                                               zigzag,
+                                               max_steps,
+                                               demod);
+               no_signal = stv0900_check_signal_presence(intp, demod);
+               trial_cntr++;
+               if ((lock == TRUE)
+                               || (no_signal == TRUE)
+                               || (trial_cntr == 2)) {
+
+                       if (intp->chip_id >= 0x20) {
+                               stv0900_write_reg(intp, CARFREQ, 0x49);
+                               stv0900_write_reg(intp, CORRELABS, 0x9e);
+                       } else {
+                               stv0900_write_reg(intp, CARFREQ, 0xed);
+                               stv0900_write_reg(intp, CORRELABS, 0x88);
+                       }
+
+                       if ((stv0900_get_bits(intp, HEADER_MODE) ==
+                                               STV0900_DVBS2_FOUND) &&
+                                                       (lock == TRUE)) {
+                               msleep(sft_stp_tout);
+                               s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
+
+                               if (s2fw < 0xd) {
+                                       msleep(sft_stp_tout);
+                                       s2fw = stv0900_get_bits(intp,
+                                                               FLYWHEEL_CPT);
+                               }
+
+                               if (s2fw < 0xd) {
+                                       lock = FALSE;
+
+                                       if (trial_cntr < 2) {
+                                               if (intp->chip_id >= 0x20)
+                                                       stv0900_write_reg(intp,
+                                                               CORRELABS,
+                                                               0x79);
+                                               else
+                                                       stv0900_write_reg(intp,
+                                                               CORRELABS,
+                                                               0x68);
+
+                                               stv0900_write_reg(intp,
+                                                               DMDCFGMD,
+                                                               0x89);
+                                       }
+                               }
+                       }
+               }
+
+       } while ((lock == FALSE)
+               && (trial_cntr < 2)
+               && (no_signal == FALSE));
+
+       return lock;
+}
+
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
+                                       u32 mclk,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32     rem1, rem2, intval1, intval2, srate;
+
+       srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
+               (stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
+               (stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
+               (stv0900_get_bits(intp, SYMB_FREQ0));
+       dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
+               srate, stv0900_get_bits(intp, SYMB_FREQ0),
+               stv0900_get_bits(intp, SYMB_FREQ1),
+               stv0900_get_bits(intp, SYMB_FREQ2),
+               stv0900_get_bits(intp, SYMB_FREQ3));
+
+       intval1 = (mclk) >> 16;
+       intval2 = (srate) >> 16;
+
+       rem1 = (mclk) % 0x10000;
+       rem2 = (srate) % 0x10000;
+       srate = (intval1 * intval2) +
+               ((intval1 * rem2) >> 16) +
+               ((intval2 * rem1) >> 16);
+
+       return srate;
+}
+
+static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
+                                       u32 mclk, u32 srate,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32 symb;
+
+       dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+                                                       srate, demod);
+
+       if (srate > 60000000) {
+               symb = srate << 4;
+               symb /= (mclk >> 12);
+       } else if (srate > 6000000) {
+               symb = srate << 6;
+               symb /= (mclk >> 10);
+       } else {
+               symb = srate << 9;
+               symb /= (mclk >> 7);
+       }
+
+       stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
+       stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
+}
+
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
+                                       u32 mclk, u32 srate,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32 symb;
+
+       srate = 105 * (srate / 100);
+
+       if (srate > 60000000) {
+               symb = srate << 4;
+               symb /= (mclk >> 12);
+       } else if (srate > 6000000) {
+               symb = srate << 6;
+               symb /= (mclk >> 10);
+       } else {
+               symb = srate << 9;
+               symb /= (mclk >> 7);
+       }
+
+       if (symb < 0x7fff) {
+               stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
+               stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
+       } else {
+               stv0900_write_reg(intp, SFRUP1, 0x7f);
+               stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
+       }
+}
+
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
+                                       u32 mclk, u32 srate,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32     symb;
+
+       srate = 95 * (srate / 100);
+       if (srate > 60000000) {
+               symb = srate << 4;
+               symb /= (mclk >> 12);
+
+       } else if (srate > 6000000) {
+               symb = srate << 6;
+               symb /= (mclk >> 10);
+
+       } else {
+               symb = srate << 9;
+               symb /= (mclk >> 7);
+       }
+
+       stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
+       stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
+}
+
+static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
+                                       u32 srate,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32 timingoffset;
+
+
+       timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
+                      (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
+                      (stv0900_read_reg(intp, TMGREG2 + 2));
+
+       timingoffset = ge2comp(timingoffset, 24);
+
+
+       if (timingoffset == 0)
+               timingoffset = 1;
+
+       timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
+       timingoffset /= 320;
+
+       return timingoffset;
+}
+
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32 rolloff;
+
+       if (intp->chip_id == 0x10) {
+               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+               rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
+               stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
+       } else if (intp->chip_id <= 0x20)
+               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
+       else /* cut 3.0 */
+               stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
+}
+
+static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
+{
+       u32 rolloff;
+
+       switch (ro) {
+       case STV0900_20:
+               rolloff = 20;
+               break;
+       case STV0900_25:
+               rolloff = 25;
+               break;
+       case STV0900_35:
+       default:
+               rolloff = 35;
+               break;
+       }
+
+       return srate  + (srate * rolloff) / 100;
+}
+
+static int stv0900_check_timing_lock(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod)
+{
+       int timingLock = FALSE;
+       s32     i,
+               timingcpt = 0;
+       u8      car_freq,
+               tmg_th_high,
+               tmg_th_low;
+
+       car_freq = stv0900_read_reg(intp, CARFREQ);
+       tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
+       tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
+       stv0900_write_reg(intp, TMGTHRISE, 0x20);
+       stv0900_write_reg(intp, TMGTHFALL, 0x0);
+       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+       stv0900_write_reg(intp, RTC, 0x80);
+       stv0900_write_reg(intp, RTCS2, 0x40);
+       stv0900_write_reg(intp, CARFREQ, 0x0);
+       stv0900_write_reg(intp, CFRINIT1, 0x0);
+       stv0900_write_reg(intp, CFRINIT0, 0x0);
+       stv0900_write_reg(intp, AGC2REF, 0x65);
+       stv0900_write_reg(intp, DMDISTATE, 0x18);
+       msleep(7);
+
+       for (i = 0; i < 10; i++) {
+               if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+                       timingcpt++;
+
+               msleep(1);
+       }
+
+       if (timingcpt >= 3)
+               timingLock = TRUE;
+
+       stv0900_write_reg(intp, AGC2REF, 0x38);
+       stv0900_write_reg(intp, RTC, 0x88);
+       stv0900_write_reg(intp, RTCS2, 0x68);
+       stv0900_write_reg(intp, CARFREQ, car_freq);
+       stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
+       stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
+
+       return  timingLock;
+}
+
+static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
+                                       s32 demod_timeout)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       int     lock = FALSE,
+               d = demod;
+       s32     srate,
+               search_range,
+               locktimeout,
+               currier_step,
+               nb_steps,
+               current_step,
+               direction,
+               tuner_freq,
+               timeout,
+               freq;
+
+       srate = intp->symbol_rate[d];
+       search_range = intp->srch_range[d];
+
+       if (srate >= 10000000)
+               locktimeout = demod_timeout / 3;
+       else
+               locktimeout = demod_timeout / 2;
+
+       lock = stv0900_get_demod_lock(intp, d, locktimeout);
+
+       if (lock != FALSE)
+               return lock;
+
+       if (srate >= 10000000) {
+               if (stv0900_check_timing_lock(intp, d) == TRUE) {
+                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
+                       stv0900_write_reg(intp, DMDISTATE, 0x15);
+                       lock = stv0900_get_demod_lock(intp, d, demod_timeout);
+               } else
+                       lock = FALSE;
+
+               return lock;
+       }
+
+       if (intp->chip_id <= 0x20) {
+               if (srate <= 1000000)
+                       currier_step = 500;
+               else if (srate <= 4000000)
+                       currier_step = 1000;
+               else if (srate <= 7000000)
+                       currier_step = 2000;
+               else if (srate <= 10000000)
+                       currier_step = 3000;
+               else
+                       currier_step = 5000;
+
+               if (srate >= 2000000) {
+                       timeout = (demod_timeout / 3);
+                       if (timeout > 1000)
+                               timeout = 1000;
+               } else
+                       timeout = (demod_timeout / 2);
+       } else {
+               /*cut 3.0 */
+               currier_step = srate / 4000;
+               timeout = (demod_timeout * 3) / 4;
+       }
+
+       nb_steps = ((search_range / 1000) / currier_step);
+
+       if ((nb_steps % 2) != 0)
+               nb_steps += 1;
+
+       if (nb_steps <= 0)
+               nb_steps = 2;
+       else if (nb_steps > 12)
+               nb_steps = 12;
+
+       current_step = 1;
+       direction = 1;
+
+       if (intp->chip_id <= 0x20) {
+               tuner_freq = intp->freq[d];
+               intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
+                               intp->rolloff) + intp->symbol_rate[d];
+       } else
+               tuner_freq = 0;
+
+       while ((current_step <= nb_steps) && (lock == FALSE)) {
+               if (direction > 0)
+                       tuner_freq += (current_step * currier_step);
+               else
+                       tuner_freq -= (current_step * currier_step);
+
+               if (intp->chip_id <= 0x20) {
+                       if (intp->tuner_type[d] == 3)
+                               stv0900_set_tuner_auto(intp, tuner_freq,
+                                               intp->bw[d], demod);
+                       else
+                               stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
+
+                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
+                       stv0900_write_reg(intp, CFRINIT1, 0);
+                       stv0900_write_reg(intp, CFRINIT0, 0);
+                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
+                       stv0900_write_reg(intp, DMDISTATE, 0x15);
+               } else {
+                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
+                       freq = (tuner_freq * 65536) / (intp->mclk / 1000);
+                       stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
+                       stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
+                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
+                       stv0900_write_reg(intp, DMDISTATE, 0x05);
+               }
+
+               lock = stv0900_get_demod_lock(intp, d, timeout);
+               direction *= -1;
+               current_step++;
+       }
+
+       return  lock;
+}
+
+static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
+                                       s32 srate,
+                                       enum fe_stv0900_search_algo algo)
+{
+       switch (algo) {
+       case STV0900_BLIND_SEARCH:
+               if (srate <= 1500000) {
+                       (*demod_timeout) = 1500;
+                       (*fec_timeout) = 400;
+               } else if (srate <= 5000000) {
+                       (*demod_timeout) = 1000;
+                       (*fec_timeout) = 300;
+               } else {
+                       (*demod_timeout) = 700;
+                       (*fec_timeout) = 100;
+               }
+
+               break;
+       case STV0900_COLD_START:
+       case STV0900_WARM_START:
+       default:
+               if (srate <= 1000000) {
+                       (*demod_timeout) = 3000;
+                       (*fec_timeout) = 1700;
+               } else if (srate <= 2000000) {
+                       (*demod_timeout) = 2500;
+                       (*fec_timeout) = 1100;
+               } else if (srate <= 5000000) {
+                       (*demod_timeout) = 1000;
+                       (*fec_timeout) = 550;
+               } else if (srate <= 10000000) {
+                       (*demod_timeout) = 700;
+                       (*fec_timeout) = 250;
+               } else if (srate <= 20000000) {
+                       (*demod_timeout) = 400;
+                       (*fec_timeout) = 130;
+               } else {
+                       (*demod_timeout) = 300;
+                       (*fec_timeout) = 100;
+               }
+
+               break;
+
+       }
+
+       if (algo == STV0900_WARM_START)
+               (*demod_timeout) /= 2;
+}
+
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+
+       s32 vth_reg = VTH12;
+
+       dprintk("%s\n", __func__);
+
+       stv0900_write_reg(intp, vth_reg++, 0xd0);
+       stv0900_write_reg(intp, vth_reg++, 0x7d);
+       stv0900_write_reg(intp, vth_reg++, 0x53);
+       stv0900_write_reg(intp, vth_reg++, 0x2f);
+       stv0900_write_reg(intp, vth_reg++, 0x24);
+       stv0900_write_reg(intp, vth_reg++, 0x1f);
+}
+
+static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
+                                  enum fe_stv0900_search_standard standard,
+                                  enum fe_stv0900_fec fec,
+                                  enum fe_stv0900_demod_num demod)
+{
+       dprintk("%s: ViterbiStandard = ", __func__);
+
+       switch (standard) {
+       case STV0900_AUTO_SEARCH:
+               dprintk("Auto\n");
+               stv0900_write_reg(intp, FECM, 0x10);
+               stv0900_write_reg(intp, PRVIT, 0x3f);
+               break;
+       case STV0900_SEARCH_DVBS1:
+               dprintk("DVBS1\n");
+               stv0900_write_reg(intp, FECM, 0x00);
+               switch (fec) {
+               case STV0900_FEC_UNKNOWN:
+               default:
+                       stv0900_write_reg(intp, PRVIT, 0x2f);
+                       break;
+               case STV0900_FEC_1_2:
+                       stv0900_write_reg(intp, PRVIT, 0x01);
+                       break;
+               case STV0900_FEC_2_3:
+                       stv0900_write_reg(intp, PRVIT, 0x02);
+                       break;
+               case STV0900_FEC_3_4:
+                       stv0900_write_reg(intp, PRVIT, 0x04);
+                       break;
+               case STV0900_FEC_5_6:
+                       stv0900_write_reg(intp, PRVIT, 0x08);
+                       break;
+               case STV0900_FEC_7_8:
+                       stv0900_write_reg(intp, PRVIT, 0x20);
+                       break;
+               }
+
+               break;
+       case STV0900_SEARCH_DSS:
+               dprintk("DSS\n");
+               stv0900_write_reg(intp, FECM, 0x80);
+               switch (fec) {
+               case STV0900_FEC_UNKNOWN:
+               default:
+                       stv0900_write_reg(intp, PRVIT, 0x13);
+                       break;
+               case STV0900_FEC_1_2:
+                       stv0900_write_reg(intp, PRVIT, 0x01);
+                       break;
+               case STV0900_FEC_2_3:
+                       stv0900_write_reg(intp, PRVIT, 0x02);
+                       break;
+               case STV0900_FEC_6_7:
+                       stv0900_write_reg(intp, PRVIT, 0x10);
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
+                                               enum fe_stv0900_demod_num demod)
+{
+       enum fe_stv0900_fec prate;
+       s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
+
+       switch (rate_fld) {
+       case 13:
+               prate = STV0900_FEC_1_2;
+               break;
+       case 18:
+               prate = STV0900_FEC_2_3;
+               break;
+       case 21:
+               prate = STV0900_FEC_3_4;
+               break;
+       case 24:
+               prate = STV0900_FEC_5_6;
+               break;
+       case 25:
+               prate = STV0900_FEC_6_7;
+               break;
+       case 26:
+               prate = STV0900_FEC_7_8;
+               break;
+       default:
+               prate = STV0900_FEC_UNKNOWN;
+               break;
+       }
+
+       return prate;
+}
+
+static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod,
+                                       u32 srate)
+{
+       if (intp->chip_id >= 0x30) {
+               if (srate >= 15000000) {
+                       stv0900_write_reg(intp, ACLC, 0x2b);
+                       stv0900_write_reg(intp, BCLC, 0x1a);
+               } else if ((srate >= 7000000) && (15000000 > srate)) {
+                       stv0900_write_reg(intp, ACLC, 0x0c);
+                       stv0900_write_reg(intp, BCLC, 0x1b);
+               } else if (srate < 7000000) {
+                       stv0900_write_reg(intp, ACLC, 0x2c);
+                       stv0900_write_reg(intp, BCLC, 0x1c);
+               }
+
+       } else { /*cut 2.0 and 1.x*/
+               stv0900_write_reg(intp, ACLC, 0x1a);
+               stv0900_write_reg(intp, BCLC, 0x09);
+       }
+
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       s32     srate,
+               pilots,
+               aclc,
+               freq1,
+               freq0,
+               i = 0,
+               timed,
+               timef,
+               blind_tun_sw = 0,
+               modulation;
+
+       enum fe_stv0900_modcode foundModcod;
+
+       dprintk("%s\n", __func__);
+
+       srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+       srate += stv0900_get_timing_offst(intp, srate, demod);
+
+       switch (intp->result[demod].standard) {
+       case STV0900_DVBS1_STANDARD:
+       case STV0900_DSS_STANDARD:
+               dprintk("%s: found DVB-S or DSS\n", __func__);
+               if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
+                       stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+                       stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+               }
+
+               stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
+               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+
+               if (intp->chip_id < 0x30) {
+                       stv0900_write_reg(intp, ERRCTRL1, 0x75);
+                       break;
+               }
+
+               if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
+                       stv0900_write_reg(intp, GAUSSR0, 0x98);
+                       stv0900_write_reg(intp, CCIR0, 0x18);
+               } else {
+                       stv0900_write_reg(intp, GAUSSR0, 0x18);
+                       stv0900_write_reg(intp, CCIR0, 0x18);
+               }
+
+               stv0900_write_reg(intp, ERRCTRL1, 0x75);
+               break;
+       case STV0900_DVBS2_STANDARD:
+               dprintk("%s: found DVB-S2\n", __func__);
+               stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+               stv0900_write_reg(intp, ACLC, 0);
+               stv0900_write_reg(intp, BCLC, 0);
+               if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
+                       foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
+                       pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+                       aclc = stv0900_get_optim_carr_loop(srate,
+                                                       foundModcod,
+                                                       pilots,
+                                                       intp->chip_id);
+                       if (foundModcod <= STV0900_QPSK_910)
+                               stv0900_write_reg(intp, ACLC2S2Q, aclc);
+                       else if (foundModcod <= STV0900_8PSK_910) {
+                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                               stv0900_write_reg(intp, ACLC2S28, aclc);
+                       }
+
+                       if ((intp->demod_mode == STV0900_SINGLE) &&
+                                       (foundModcod > STV0900_8PSK_910)) {
+                               if (foundModcod <= STV0900_16APSK_910) {
+                                       stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                                       stv0900_write_reg(intp, ACLC2S216A,
+                                                                       aclc);
+                               } else if (foundModcod <= STV0900_32APSK_910) {
+                                       stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                                       stv0900_write_reg(intp, ACLC2S232A,
+                                                                       aclc);
+                               }
+                       }
+
+               } else {
+                       modulation = intp->result[demod].modulation;
+                       aclc = stv0900_get_optim_short_carr_loop(srate,
+                                       modulation, intp->chip_id);
+                       if (modulation == STV0900_QPSK)
+                               stv0900_write_reg(intp, ACLC2S2Q, aclc);
+                       else if (modulation == STV0900_8PSK) {
+                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                               stv0900_write_reg(intp, ACLC2S28, aclc);
+                       } else if (modulation == STV0900_16APSK) {
+                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                               stv0900_write_reg(intp, ACLC2S216A, aclc);
+                       } else if (modulation == STV0900_32APSK) {
+                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
+                               stv0900_write_reg(intp, ACLC2S232A, aclc);
+                       }
+
+               }
+
+               if (intp->chip_id <= 0x11) {
+                       if (intp->demod_mode != STV0900_SINGLE)
+                               stv0900_activate_s2_modcod(intp, demod);
+
+               }
+
+               stv0900_write_reg(intp, ERRCTRL1, 0x67);
+               break;
+       case STV0900_UNKNOWN_STANDARD:
+       default:
+               dprintk("%s: found unknown standard\n", __func__);
+               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+               break;
+       }
+
+       freq1 = stv0900_read_reg(intp, CFR2);
+       freq0 = stv0900_read_reg(intp, CFR1);
+       if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+               stv0900_write_reg(intp, SFRSTEP, 0x00);
+               stv0900_write_bits(intp, SCAN_ENABLE, 0);
+               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+               stv0900_write_reg(intp, TMGCFG2, 0xc1);
+               stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
+               blind_tun_sw = 1;
+               if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
+                       stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
+
+       }
+
+       if (intp->chip_id >= 0x20) {
+               if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
+                               (intp->srch_standard[demod] ==
+                                                       STV0900_SEARCH_DSS) ||
+                               (intp->srch_standard[demod] ==
+                                                       STV0900_AUTO_SEARCH)) {
+                       stv0900_write_reg(intp, VAVSRVIT, 0x0a);
+                       stv0900_write_reg(intp, VITSCALE, 0x0);
+               }
+       }
+
+       if (intp->chip_id < 0x20)
+               stv0900_write_reg(intp, CARHDR, 0x08);
+
+       if (intp->chip_id == 0x10)
+               stv0900_write_reg(intp, CORRELEXP, 0x0a);
+
+       stv0900_write_reg(intp, AGC2REF, 0x38);
+
+       if ((intp->chip_id >= 0x20) ||
+                       (blind_tun_sw == 1) ||
+                       (intp->symbol_rate[demod] < 10000000)) {
+               stv0900_write_reg(intp, CFRINIT1, freq1);
+               stv0900_write_reg(intp, CFRINIT0, freq0);
+               intp->bw[demod] = stv0900_carrier_width(srate,
+                                       intp->rolloff) + 10000000;
+
+               if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
+                       if (intp->srch_algo[demod] != STV0900_WARM_START) {
+                               if (intp->tuner_type[demod] == 3)
+                                       stv0900_set_tuner_auto(intp,
+                                                       intp->freq[demod],
+                                                       intp->bw[demod],
+                                                       demod);
+                               else
+                                       stv0900_set_bandwidth(fe,
+                                                       intp->bw[demod]);
+                       }
+               }
+
+               if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
+                               (intp->symbol_rate[demod] < 10000000))
+                       msleep(50);
+               else
+                       msleep(5);
+
+               stv0900_get_lock_timeout(&timed, &timef, srate,
+                                               STV0900_WARM_START);
+
+               if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
+                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
+                       stv0900_write_reg(intp, CFRINIT1, freq1);
+                       stv0900_write_reg(intp, CFRINIT0, freq0);
+                       stv0900_write_reg(intp, DMDISTATE, 0x18);
+                       i = 0;
+                       while ((stv0900_get_demod_lock(intp,
+                                                       demod,
+                                                       timed / 2) == FALSE) &&
+                                               (i <= 2)) {
+                               stv0900_write_reg(intp, DMDISTATE, 0x1f);
+                               stv0900_write_reg(intp, CFRINIT1, freq1);
+                               stv0900_write_reg(intp, CFRINIT0, freq0);
+                               stv0900_write_reg(intp, DMDISTATE, 0x18);
+                               i++;
+                       }
+               }
+
+       }
+
+       if (intp->chip_id >= 0x20)
+               stv0900_write_reg(intp, CARFREQ, 0x49);
+
+       if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
+                       (intp->result[demod].standard == STV0900_DSS_STANDARD))
+               stv0900_set_viterbi_tracq(intp, demod);
+
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod, s32 time_out)
+{
+       s32 timer = 0, lock = 0;
+
+       enum fe_stv0900_search_state dmd_state;
+
+       dprintk("%s\n", __func__);
+
+       dmd_state = stv0900_get_bits(intp, HEADER_MODE);
+
+       while ((timer < time_out) && (lock == 0)) {
+               switch (dmd_state) {
+               case STV0900_SEARCH:
+               case STV0900_PLH_DETECTED:
+               default:
+                       lock = 0;
+                       break;
+               case STV0900_DVBS2_FOUND:
+                       lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
+                       break;
+               case STV0900_DVBS_FOUND:
+                       lock = stv0900_get_bits(intp, LOCKEDVIT);
+                       break;
+               }
+
+               if (lock == 0) {
+                       msleep(10);
+                       timer += 10;
+               }
+       }
+
+       if (lock)
+               dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
+       else
+               dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
+
+       return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *intp,
+                               enum fe_stv0900_demod_num demod,
+                               s32 dmd_timeout, s32 fec_timeout)
+{
+
+       s32 timer = 0, lock = 0;
+
+       dprintk("%s\n", __func__);
+
+       lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
+
+       if (lock)
+               lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
+
+       if (lock) {
+               lock = 0;
+
+               dprintk("%s: Timer = %d, time_out = %d\n",
+                               __func__, timer, fec_timeout);
+
+               while ((timer < fec_timeout) && (lock == 0)) {
+                       lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
+                       msleep(1);
+                       timer++;
+               }
+       }
+
+       if (lock)
+               dprintk("%s: DEMOD LOCK OK\n", __func__);
+       else
+               dprintk("%s: DEMOD LOCK FAIL\n", __func__);
+
+       if (lock)
+               return TRUE;
+       else
+               return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+                                               enum fe_stv0900_demod_num demod)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_tracking_standard fnd_standard;
+
+       int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
+
+       switch (hdr_mode) {
+       case 2:
+               fnd_standard = STV0900_DVBS2_STANDARD;
+               break;
+       case 3:
+               if (stv0900_get_bits(intp, DSS_DVB) == 1)
+                       fnd_standard = STV0900_DSS_STANDARD;
+               else
+                       fnd_standard = STV0900_DVBS1_STANDARD;
+
+               break;
+       default:
+               fnd_standard = STV0900_UNKNOWN_STANDARD;
+       }
+
+       dprintk("%s: standard %d\n", __func__, fnd_standard);
+
+       return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32     derot,
+               rem1,
+               rem2,
+               intval1,
+               intval2;
+
+       derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
+               (stv0900_get_bits(intp, CAR_FREQ1) << 8) +
+               (stv0900_get_bits(intp, CAR_FREQ0));
+
+       derot = ge2comp(derot, 24);
+       intval1 = mclk >> 12;
+       intval2 = derot >> 12;
+       rem1 = mclk % 0x1000;
+       rem2 = derot % 0x1000;
+       derot = (intval1 * intval2) +
+               ((intval1 * rem2) >> 12) +
+               ((intval2 * rem1) >> 12);
+
+       return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops *tuner_ops = NULL;
+       u32 freq = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+
+       if (tuner_ops->get_frequency) {
+               if ((tuner_ops->get_frequency(fe, &freq)) < 0)
+                       dprintk("%s: Invalid parameter\n", __func__);
+               else
+                       dprintk("%s: Frequency=%d\n", __func__, freq);
+
+       }
+
+       return freq;
+}
+
+static enum
+fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
+       struct stv0900_signal_info *result = &intp->result[demod];
+       s32     offsetFreq,
+               srate_offset;
+       int     i = 0,
+               d = demod;
+
+       u8 timing;
+
+       msleep(5);
+       if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
+               timing = stv0900_read_reg(intp, TMGREG2);
+               i = 0;
+               stv0900_write_reg(intp, SFRSTEP, 0x5c);
+
+               while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+                       timing = stv0900_read_reg(intp, TMGREG2);
+                       msleep(5);
+                       i += 5;
+               }
+       }
+
+       result->standard = stv0900_get_standard(fe, d);
+       if (intp->tuner_type[demod] == 3)
+               result->frequency = stv0900_get_freq_auto(intp, d);
+       else
+               result->frequency = stv0900_get_tuner_freq(fe);
+
+       offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
+       result->frequency += offsetFreq;
+       result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
+       srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
+       result->symbol_rate += srate_offset;
+       result->fec = stv0900_get_vit_fec(intp, d);
+       result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
+       result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
+       result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
+       result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
+
+       dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
+
+       switch (result->standard) {
+       case STV0900_DVBS2_STANDARD:
+               result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
+               if (result->modcode <= STV0900_QPSK_910)
+                       result->modulation = STV0900_QPSK;
+               else if (result->modcode <= STV0900_8PSK_910)
+                       result->modulation = STV0900_8PSK;
+               else if (result->modcode <= STV0900_16APSK_910)
+                       result->modulation = STV0900_16APSK;
+               else if (result->modcode <= STV0900_32APSK_910)
+                       result->modulation = STV0900_32APSK;
+               else
+                       result->modulation = STV0900_UNKNOWN;
+               break;
+       case STV0900_DVBS1_STANDARD:
+       case STV0900_DSS_STANDARD:
+               result->spectrum = stv0900_get_bits(intp, IQINV);
+               result->modulation = STV0900_QPSK;
+               break;
+       default:
+               break;
+       }
+
+       if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
+                               (intp->symbol_rate[d] < 10000000)) {
+               offsetFreq = result->frequency - intp->freq[d];
+               if (intp->tuner_type[demod] == 3)
+                       intp->freq[d] = stv0900_get_freq_auto(intp, d);
+               else
+                       intp->freq[d] = stv0900_get_tuner_freq(fe);
+
+               if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+                       range = STV0900_RANGEOK;
+               else if (ABS(offsetFreq) <=
+                               (stv0900_carrier_width(result->symbol_rate,
+                                               result->rolloff) / 2000))
+                       range = STV0900_RANGEOK;
+
+       } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
+               range = STV0900_RANGEOK;
+
+       dprintk("%s: range %d\n", __func__, range);
+
+       return range;
+}
+
+static enum
+fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
+
+       s32     srate,
+               demod_timeout,
+               fec_timeout,
+               freq1,
+               freq0;
+
+       intp->result[demod].locked = FALSE;
+
+       if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
+               srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+               srate += stv0900_get_timing_offst(intp, srate, demod);
+               if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
+                       stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
+
+               stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+                                       srate, STV0900_WARM_START);
+               freq1 = stv0900_read_reg(intp, CFR2);
+               freq0 = stv0900_read_reg(intp, CFR1);
+               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+               stv0900_write_bits(intp, SPECINV_CONTROL,
+                                       STV0900_IQ_FORCE_SWAPPED);
+               stv0900_write_reg(intp, DMDISTATE, 0x1c);
+               stv0900_write_reg(intp, CFRINIT1, freq1);
+               stv0900_write_reg(intp, CFRINIT0, freq0);
+               stv0900_write_reg(intp, DMDISTATE, 0x18);
+               if (stv0900_wait_for_lock(intp, demod,
+                               demod_timeout, fec_timeout) == TRUE) {
+                       intp->result[demod].locked = TRUE;
+                       signal_type = stv0900_get_signal_params(fe);
+                       stv0900_track_optimization(fe);
+               } else {
+                       stv0900_write_bits(intp, SPECINV_CONTROL,
+                                       STV0900_IQ_FORCE_NORMAL);
+                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
+                       stv0900_write_reg(intp, CFRINIT1, freq1);
+                       stv0900_write_reg(intp, CFRINIT0, freq0);
+                       stv0900_write_reg(intp, DMDISTATE, 0x18);
+                       if (stv0900_wait_for_lock(intp, demod,
+                                       demod_timeout, fec_timeout) == TRUE) {
+                               intp->result[demod].locked = TRUE;
+                               signal_type = stv0900_get_signal_params(fe);
+                               stv0900_track_optimization(fe);
+                       }
+
+               }
+
+       } else
+               intp->result[demod].locked = FALSE;
+
+       return signal_type;
+}
+
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       u32 minagc2level = 0xffff,
+               agc2level,
+               init_freq, freq_step;
+
+       s32 i, j, nb_steps, direction;
+
+       dprintk("%s\n", __func__);
+
+       stv0900_write_reg(intp, AGC2REF, 0x38);
+       stv0900_write_bits(intp, SCAN_ENABLE, 0);
+       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+
+       stv0900_write_bits(intp, AUTO_GUP, 1);
+       stv0900_write_bits(intp, AUTO_GLOW, 1);
+
+       stv0900_write_reg(intp, DMDT0M, 0x0);
+
+       stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+       nb_steps = -1 + (intp->srch_range[demod] / 1000000);
+       nb_steps /= 2;
+       nb_steps = (2 * nb_steps) + 1;
+
+       if (nb_steps < 0)
+               nb_steps = 1;
+
+       direction = 1;
+
+       freq_step = (1000000 << 8) / (intp->mclk >> 8);
+
+       init_freq = 0;
+
+       for (i = 0; i < nb_steps; i++) {
+               if (direction > 0)
+                       init_freq = init_freq + (freq_step * i);
+               else
+                       init_freq = init_freq - (freq_step * i);
+
+               direction *= -1;
+               stv0900_write_reg(intp, DMDISTATE, 0x5C);
+               stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
+               stv0900_write_reg(intp, CFRINIT0, init_freq  & 0xff);
+               stv0900_write_reg(intp, DMDISTATE, 0x58);
+               msleep(10);
+               agc2level = 0;
+
+               for (j = 0; j < 10; j++)
+                       agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
+                                       | stv0900_read_reg(intp, AGC2I0);
+
+               agc2level /= 10;
+
+               if (agc2level < minagc2level)
+                       minagc2level = agc2level;
+
+       }
+
+       return (u16)minagc2level;
+}
+
+static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       int timing_lck = FALSE;
+       s32 i, timingcpt = 0,
+               direction = 1,
+               nb_steps,
+               current_step = 0,
+               tuner_freq;
+       u32 agc2_th,
+               coarse_srate = 0,
+               agc2_integr = 0,
+               currier_step = 1200;
+
+       if (intp->chip_id >= 0x30)
+               agc2_th = 0x2e00;
+       else
+               agc2_th = 0x1f00;
+
+       stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
+       stv0900_write_reg(intp, TMGCFG, 0x12);
+       stv0900_write_reg(intp, TMGTHRISE, 0xf0);
+       stv0900_write_reg(intp, TMGTHFALL, 0xe0);
+       stv0900_write_bits(intp, SCAN_ENABLE, 1);
+       stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
+       stv0900_write_reg(intp, SFRUP1, 0x83);
+       stv0900_write_reg(intp, SFRUP0, 0xc0);
+       stv0900_write_reg(intp, SFRLOW1, 0x82);
+       stv0900_write_reg(intp, SFRLOW0, 0xa0);
+       stv0900_write_reg(intp, DMDT0M, 0x0);
+       stv0900_write_reg(intp, AGC2REF, 0x50);
+
+       if (intp->chip_id >= 0x30) {
+               stv0900_write_reg(intp, CARFREQ, 0x99);
+               stv0900_write_reg(intp, SFRSTEP, 0x98);
+       } else if (intp->chip_id >= 0x20) {
+               stv0900_write_reg(intp, CARFREQ, 0x6a);
+               stv0900_write_reg(intp, SFRSTEP, 0x95);
+       } else {
+               stv0900_write_reg(intp, CARFREQ, 0xed);
+               stv0900_write_reg(intp, SFRSTEP, 0x73);
+       }
+
+       if (intp->symbol_rate[demod] <= 2000000)
+               currier_step = 1000;
+       else if (intp->symbol_rate[demod] <= 5000000)
+               currier_step = 2000;
+       else if (intp->symbol_rate[demod] <= 12000000)
+               currier_step = 3000;
+       else
+                       currier_step = 5000;
+
+       nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
+       nb_steps /= 2;
+       nb_steps = (2 * nb_steps) + 1;
+
+       if (nb_steps < 0)
+               nb_steps = 1;
+       else if (nb_steps > 10) {
+               nb_steps = 11;
+               currier_step = (intp->srch_range[demod] / 1000) / 10;
+       }
+
+       current_step = 0;
+       direction = 1;
+
+       tuner_freq = intp->freq[demod];
+
+       while ((timing_lck == FALSE) && (current_step < nb_steps)) {
+               stv0900_write_reg(intp, DMDISTATE, 0x5f);
+               stv0900_write_bits(intp, DEMOD_MODE, 0);
+
+               msleep(50);
+
+               for (i = 0; i < 10; i++) {
+                       if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
+                               timingcpt++;
+
+                       agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
+                                       stv0900_read_reg(intp, AGC2I0);
+               }
+
+               agc2_integr /= 10;
+               coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+               current_step++;
+               direction *= -1;
+
+               dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
+                       " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
+                       tuner_freq, agc2_integr, coarse_srate, timingcpt);
+
+               if ((timingcpt >= 5) &&
+                               (agc2_integr < agc2_th) &&
+                               (coarse_srate < 55000000) &&
+                               (coarse_srate > 850000))
+                       timing_lck = TRUE;
+               else if (current_step < nb_steps) {
+                       if (direction > 0)
+                               tuner_freq += (current_step * currier_step);
+                       else
+                               tuner_freq -= (current_step * currier_step);
+
+                       if (intp->tuner_type[demod] == 3)
+                               stv0900_set_tuner_auto(intp, tuner_freq,
+                                               intp->bw[demod], demod);
+                       else
+                               stv0900_set_tuner(fe, tuner_freq,
+                                               intp->bw[demod]);
+               }
+       }
+
+       if (timing_lck == FALSE)
+               coarse_srate = 0;
+       else
+               coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+
+       return coarse_srate;
+}
+
+static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       u32     coarse_srate,
+               coarse_freq,
+               symb,
+               symbmax,
+               symbmin,
+               symbcomp;
+
+       coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
+
+       if (coarse_srate > 3000000) {
+               symbmax = 13 * (coarse_srate / 10);
+               symbmax = (symbmax / 1000) * 65536;
+               symbmax /= (intp->mclk / 1000);
+
+               symbmin = 10 * (coarse_srate / 13);
+               symbmin = (symbmin / 1000)*65536;
+               symbmin /= (intp->mclk / 1000);
+
+               symb = (coarse_srate / 1000) * 65536;
+               symb /= (intp->mclk / 1000);
+       } else {
+               symbmax = 13 * (coarse_srate / 10);
+               symbmax = (symbmax / 100) * 65536;
+               symbmax /= (intp->mclk / 100);
+
+               symbmin = 10 * (coarse_srate / 14);
+               symbmin = (symbmin / 100) * 65536;
+               symbmin /= (intp->mclk / 100);
+
+               symb = (coarse_srate / 100) * 65536;
+               symb /= (intp->mclk / 100);
+       }
+
+       symbcomp = 13 * (coarse_srate / 10);
+               coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
+                                       | stv0900_read_reg(intp, CFR1);
+
+       if (symbcomp < intp->symbol_rate[demod])
+               coarse_srate = 0;
+       else {
+               stv0900_write_reg(intp, DMDISTATE, 0x1f);
+               stv0900_write_reg(intp, TMGCFG2, 0xc1);
+               stv0900_write_reg(intp, TMGTHRISE, 0x20);
+               stv0900_write_reg(intp, TMGTHFALL, 0x00);
+               stv0900_write_reg(intp, TMGCFG, 0xd2);
+               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
+               stv0900_write_reg(intp, AGC2REF, 0x38);
+
+               if (intp->chip_id >= 0x30)
+                       stv0900_write_reg(intp, CARFREQ, 0x79);
+               else if (intp->chip_id >= 0x20)
+                       stv0900_write_reg(intp, CARFREQ, 0x49);
+               else
+                       stv0900_write_reg(intp, CARFREQ, 0xed);
+
+               stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
+               stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
+
+               stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
+               stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
+
+               stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
+               stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
+
+               stv0900_write_reg(intp, DMDT0M, 0x20);
+               stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
+               stv0900_write_reg(intp, CFRINIT0, coarse_freq  & 0xff);
+               stv0900_write_reg(intp, DMDISTATE, 0x15);
+       }
+
+       return coarse_srate;
+}
+
+static int stv0900_blind_search_algo(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+       u8      k_ref_tmg,
+               k_ref_tmg_max,
+               k_ref_tmg_min;
+       u32     coarse_srate,
+               agc2_th;
+       int     lock = FALSE,
+               coarse_fail = FALSE;
+       s32     demod_timeout = 500,
+               fec_timeout = 50,
+               fail_cpt,
+               i,
+               agc2_overflow;
+       u16     agc2_int;
+       u8      dstatus2;
+
+       dprintk("%s\n", __func__);
+
+       if (intp->chip_id < 0x20) {
+               k_ref_tmg_max = 233;
+               k_ref_tmg_min = 143;
+       } else {
+               k_ref_tmg_max = 110;
+               k_ref_tmg_min = 10;
+       }
+
+       if (intp->chip_id <= 0x20)
+               agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
+       else
+               agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
+
+       agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
+
+       dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
+       if (agc2_int > agc2_th)
+               return FALSE;
+
+       if (intp->chip_id == 0x10)
+               stv0900_write_reg(intp, CORRELEXP, 0xaa);
+
+       if (intp->chip_id < 0x20)
+               stv0900_write_reg(intp, CARHDR, 0x55);
+       else
+               stv0900_write_reg(intp, CARHDR, 0x20);
+
+       if (intp->chip_id <= 0x20)
+               stv0900_write_reg(intp, CARCFG, 0xc4);
+       else
+               stv0900_write_reg(intp, CARCFG, 0x6);
+
+       stv0900_write_reg(intp, RTCS2, 0x44);
+
+       if (intp->chip_id >= 0x20) {
+               stv0900_write_reg(intp, EQUALCFG, 0x41);
+               stv0900_write_reg(intp, FFECFG, 0x41);
+               stv0900_write_reg(intp, VITSCALE, 0x82);
+               stv0900_write_reg(intp, VAVSRVIT, 0x0);
+       }
+
+       k_ref_tmg = k_ref_tmg_max;
+
+       do {
+               stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
+               if (stv0900_search_srate_coarse(fe) != 0) {
+                       coarse_srate = stv0900_search_srate_fine(fe);
+
+                       if (coarse_srate != 0) {
+                               stv0900_get_lock_timeout(&demod_timeout,
+                                                       &fec_timeout,
+                                                       coarse_srate,
+                                                       STV0900_BLIND_SEARCH);
+                               lock = stv0900_get_demod_lock(intp,
+                                                       demod,
+                                                       demod_timeout);
+                       } else
+                               lock = FALSE;
+               } else {
+                       fail_cpt = 0;
+                       agc2_overflow = 0;
+
+                       for (i = 0; i < 10; i++) {
+                               agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
+                                       | stv0900_read_reg(intp, AGC2I0);
+
+                               if (agc2_int >= 0xff00)
+                                       agc2_overflow++;
+
+                               dstatus2 = stv0900_read_reg(intp, DSTATUS2);
+
+                               if (((dstatus2 & 0x1) == 0x1) &&
+                                               ((dstatus2 >> 7) == 1))
+                                       fail_cpt++;
+                       }
+
+                       if ((fail_cpt > 7) || (agc2_overflow > 7))
+                               coarse_fail = TRUE;
+
+                       lock = FALSE;
+               }
+               k_ref_tmg -= 30;
+       } while ((k_ref_tmg >= k_ref_tmg_min) &&
+                               (lock == FALSE) &&
+                               (coarse_fail == FALSE));
+
+       return lock;
+}
+
+static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+       s32 vth_reg = VTH12;
+
+       dprintk("%s\n", __func__);
+
+       stv0900_write_reg(intp, vth_reg++, 0x96);
+       stv0900_write_reg(intp, vth_reg++, 0x64);
+       stv0900_write_reg(intp, vth_reg++, 0x36);
+       stv0900_write_reg(intp, vth_reg++, 0x23);
+       stv0900_write_reg(intp, vth_reg++, 0x1e);
+       stv0900_write_reg(intp, vth_reg++, 0x19);
+}
+
+static void stv0900_set_search_standard(struct stv0900_internal *intp,
+                                       enum fe_stv0900_demod_num demod)
+{
+
+       dprintk("%s\n", __func__);
+
+       switch (intp->srch_standard[demod]) {
+       case STV0900_SEARCH_DVBS1:
+               dprintk("Search Standard = DVBS1\n");
+               break;
+       case STV0900_SEARCH_DSS:
+               dprintk("Search Standard = DSS\n");
+       case STV0900_SEARCH_DVBS2:
+               break;
+               dprintk("Search Standard = DVBS2\n");
+       case STV0900_AUTO_SEARCH:
+       default:
+               dprintk("Search Standard = AUTO\n");
+               break;
+       }
+
+       switch (intp->srch_standard[demod]) {
+       case STV0900_SEARCH_DVBS1:
+       case STV0900_SEARCH_DSS:
+               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+               stv0900_write_bits(intp, DVBS2_ENABLE, 0);
+               stv0900_write_bits(intp, STOP_CLKVIT, 0);
+               stv0900_set_dvbs1_track_car_loop(intp,
+                                               demod,
+                                               intp->symbol_rate[demod]);
+               stv0900_write_reg(intp, CAR2CFG, 0x22);
+
+               stv0900_set_viterbi_acq(intp, demod);
+               stv0900_set_viterbi_standard(intp,
+                                       intp->srch_standard[demod],
+                                       intp->fec[demod], demod);
+
+               break;
+       case STV0900_SEARCH_DVBS2:
+               stv0900_write_bits(intp, DVBS1_ENABLE, 0);
+               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+               stv0900_write_bits(intp, STOP_CLKVIT, 1);
+               stv0900_write_reg(intp, ACLC, 0x1a);
+               stv0900_write_reg(intp, BCLC, 0x09);
+               if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+                       stv0900_write_reg(intp, CAR2CFG, 0x26);
+               else
+                       stv0900_write_reg(intp, CAR2CFG, 0x66);
+
+               if (intp->demod_mode != STV0900_SINGLE) {
+                       if (intp->chip_id <= 0x11)
+                               stv0900_stop_all_s2_modcod(intp, demod);
+                       else
+                               stv0900_activate_s2_modcod(intp, demod);
+
+               } else
+                       stv0900_activate_s2_modcod_single(intp, demod);
+
+               stv0900_set_viterbi_tracq(intp, demod);
+
+               break;
+       case STV0900_AUTO_SEARCH:
+       default:
+               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
+               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
+               stv0900_write_bits(intp, STOP_CLKVIT, 0);
+               stv0900_write_reg(intp, ACLC, 0x1a);
+               stv0900_write_reg(intp, BCLC, 0x09);
+               stv0900_set_dvbs1_track_car_loop(intp,
+                                               demod,
+                                               intp->symbol_rate[demod]);
+               if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
+                       stv0900_write_reg(intp, CAR2CFG, 0x26);
+               else
+                       stv0900_write_reg(intp, CAR2CFG, 0x66);
+
+               if (intp->demod_mode != STV0900_SINGLE) {
+                       if (intp->chip_id <= 0x11)
+                               stv0900_stop_all_s2_modcod(intp, demod);
+                       else
+                               stv0900_activate_s2_modcod(intp, demod);
+
+               } else
+                       stv0900_activate_s2_modcod_single(intp, demod);
+
+               stv0900_set_viterbi_tracq(intp, demod);
+               stv0900_set_viterbi_standard(intp,
+                                               intp->srch_standard[demod],
+                                               intp->fec[demod], demod);
+
+               break;
+       }
+}
+
+enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
+{
+       struct stv0900_state *state = fe->demodulator_priv;
+       struct stv0900_internal *intp = state->internal;
+       enum fe_stv0900_demod_num demod = state->demod;
+
+       s32 demod_timeout = 500, fec_timeout = 50;
+       s32 aq_power, agc1_power, i;
+
+       int lock = FALSE, low_sr = FALSE;
+
+       enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
+       enum fe_stv0900_search_algo algo;
+       int no_signal = FALSE;
+
+       dprintk("%s\n", __func__);
+
+       algo = intp->srch_algo[demod];
+       stv0900_write_bits(intp, RST_HWARE, 1);
+       stv0900_write_reg(intp, DMDISTATE, 0x5c);
+       if (intp->chip_id >= 0x20) {
+               if (intp->symbol_rate[demod] > 5000000)
+                       stv0900_write_reg(intp, CORRELABS, 0x9e);
+               else
+                       stv0900_write_reg(intp, CORRELABS, 0x82);
+       } else
+               stv0900_write_reg(intp, CORRELABS, 0x88);
+
+       stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
+                               intp->symbol_rate[demod],
+                               intp->srch_algo[demod]);
+
+       if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
+               intp->bw[demod] = 2 * 36000000;
+
+               stv0900_write_reg(intp, TMGCFG2, 0xc0);
+               stv0900_write_reg(intp, CORRELMANT, 0x70);
+
+               stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
+       } else {
+               stv0900_write_reg(intp, DMDT0M, 0x20);
+               stv0900_write_reg(intp, TMGCFG, 0xd2);
+
+               if (intp->symbol_rate[demod] < 2000000)
+                       stv0900_write_reg(intp, CORRELMANT, 0x63);
+               else
+                       stv0900_write_reg(intp, CORRELMANT, 0x70);
+
+               stv0900_write_reg(intp, AGC2REF, 0x38);
+
+               intp->bw[demod] =
+                               stv0900_carrier_width(intp->symbol_rate[demod],
+                                                               intp->rolloff);
+               if (intp->chip_id >= 0x20) {
+                       stv0900_write_reg(intp, KREFTMG, 0x5a);
+
+                       if (intp->srch_algo[demod] == STV0900_COLD_START) {
+                               intp->bw[demod] += 10000000;
+                               intp->bw[demod] *= 15;
+                               intp->bw[demod] /= 10;
+                       } else if (intp->srch_algo[demod] == STV0900_WARM_START)
+                               intp->bw[demod] += 10000000;
+
+               } else {
+                       stv0900_write_reg(intp, KREFTMG, 0xc1);
+                       intp->bw[demod] += 10000000;
+                       intp->bw[demod] *= 15;
+                       intp->bw[demod] /= 10;
+               }
+
+               stv0900_write_reg(intp, TMGCFG2, 0xc1);
+
+               stv0900_set_symbol_rate(intp, intp->mclk,
+                                       intp->symbol_rate[demod], demod);
+               stv0900_set_max_symbol_rate(intp, intp->mclk,
+                                       intp->symbol_rate[demod], demod);
+               stv0900_set_min_symbol_rate(intp, intp->mclk,
+                                       intp->symbol_rate[demod], demod);
+               if (intp->symbol_rate[demod] >= 10000000)
+                       low_sr = FALSE;
+               else
+                       low_sr = TRUE;
+
+       }
+
+       if (intp->tuner_type[demod] == 3)
+               stv0900_set_tuner_auto(intp, intp->freq[demod],
+                               intp->bw[demod], demod);
+       else
+               stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
+
+       agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
+                               stv0900_get_bits(intp, AGCIQ_VALUE0));
+
+       aq_power = 0;
+
+       if (agc1_power == 0) {
+               for (i = 0; i < 5; i++)
+                       aq_power += (stv0900_get_bits(intp, POWER_I) +
+                                       stv0900_get_bits(intp, POWER_Q)) / 2;
+
+               aq_power /= 5;
+       }
+
+       if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
+               intp->result[demod].locked = FALSE;
+               signal_type = STV0900_NOAGC1;
+               dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
+       } else {
+               stv0900_write_bits(intp, SPECINV_CONTROL,
+                                       intp->srch_iq_inv[demod]);
+               if (intp->chip_id <= 0x20) /*cut 2.0*/
+                       stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
+               else /*cut 3.0*/
+                       stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
+
+               stv0900_set_search_standard(intp, demod);
+
+               if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
+                       stv0900_start_search(intp, demod);
+       }
+
+       if (signal_type == STV0900_NOAGC1)
+               return signal_type;
+
+       if (intp->chip_id == 0x12) {
+               stv0900_write_bits(intp, RST_HWARE, 0);
+               msleep(3);
+               stv0900_write_bits(intp, RST_HWARE, 1);
+               stv0900_write_bits(intp, RST_HWARE, 0);
+       }
+
+       if (algo == STV0900_BLIND_SEARCH)
+               lock = stv0900_blind_search_algo(fe);
+       else if (algo == STV0900_COLD_START)
+               lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
+       else if (algo == STV0900_WARM_START)
+               lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
+
+       if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
+               if (low_sr == FALSE) {
+                       if (stv0900_check_timing_lock(intp, demod) == TRUE)
+                               lock = stv0900_sw_algo(intp, demod);
+               }
+       }
+
+       if (lock == TRUE)
+               signal_type = stv0900_get_signal_params(fe);
+
+       if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
+               stv0900_track_optimization(fe);
+               if (intp->chip_id <= 0x11) {
+                       if ((stv0900_get_standard(fe, 0) ==
+                                               STV0900_DVBS1_STANDARD) &&
+                          (stv0900_get_standard(fe, 1) ==
+                                               STV0900_DVBS1_STANDARD)) {
+                               msleep(20);
+                               stv0900_write_bits(intp, RST_HWARE, 0);
+                       } else {
+                               stv0900_write_bits(intp, RST_HWARE, 0);
+                               msleep(3);
+                               stv0900_write_bits(intp, RST_HWARE, 1);
+                               stv0900_write_bits(intp, RST_HWARE, 0);
+                       }
+
+               } else if (intp->chip_id >= 0x20) {
+                       stv0900_write_bits(intp, RST_HWARE, 0);
+                       msleep(3);
+                       stv0900_write_bits(intp, RST_HWARE, 1);
+                       stv0900_write_bits(intp, RST_HWARE, 0);
+               }
+
+               if (stv0900_wait_for_lock(intp, demod,
+                                       fec_timeout, fec_timeout) == TRUE) {
+                       lock = TRUE;
+                       intp->result[demod].locked = TRUE;
+                       if (intp->result[demod].standard ==
+                                               STV0900_DVBS2_STANDARD) {
+                               stv0900_set_dvbs2_rolloff(intp, demod);
+                               stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
+                               stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
+                               stv0900_write_reg(intp, ERRCTRL1, 0x67);
+                       } else {
+                               stv0900_write_reg(intp, ERRCTRL1, 0x75);
+                       }
+
+                       stv0900_write_reg(intp, FBERCPT4, 0);
+                       stv0900_write_reg(intp, ERRCTRL2, 0xc1);
+               } else {
+                       lock = FALSE;
+                       signal_type = STV0900_NODATA;
+                       no_signal = stv0900_check_signal_presence(intp, demod);
+
+                               intp->result[demod].locked = FALSE;
+               }
+       }
+
+       if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
+               return signal_type;
+
+       if (intp->chip_id > 0x11) {
+               intp->result[demod].locked = FALSE;
+               return signal_type;
+       }
+
+       if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
+          (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
+               signal_type = stv0900_dvbs1_acq_workaround(fe);
+
+       return signal_type;
+}
+
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
new file mode 100644 (file)
index 0000000..ea86a56
--- /dev/null
@@ -0,0 +1,4823 @@
+/*
+       STV0900/0903 Multistandard Broadcast Frontend driver
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#include "stv6110x.h" /* for demodulator internal modes */
+
+#include "stv090x_reg.h"
+#include "stv090x.h"
+#include "stv090x_priv.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+
+/* internal params node */
+struct stv090x_dev {
+       /* pointer for internal params, one for each pair of demods */
+       struct stv090x_internal         *internal;
+       struct stv090x_dev              *next_dev;
+};
+
+/* first internal params */
+static struct stv090x_dev *stv090x_first_dev;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,
+                                       u8 i2c_addr)
+{
+       struct stv090x_dev *temp_dev = stv090x_first_dev;
+
+       /*
+        Search of the last stv0900 chip or
+        find it by i2c adapter and i2c address */
+       while ((temp_dev != NULL) &&
+               ((temp_dev->internal->i2c_adap != i2c_adap) ||
+               (temp_dev->internal->i2c_addr != i2c_addr))) {
+
+               temp_dev = temp_dev->next_dev;
+       }
+
+       return temp_dev;
+}
+
+/* deallocating chip */
+static void remove_dev(struct stv090x_internal *internal)
+{
+       struct stv090x_dev *prev_dev = stv090x_first_dev;
+       struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,
+                                               internal->i2c_addr);
+
+       if (del_dev != NULL) {
+               if (del_dev == stv090x_first_dev) {
+                       stv090x_first_dev = del_dev->next_dev;
+               } else {
+                       while (prev_dev->next_dev != del_dev)
+                               prev_dev = prev_dev->next_dev;
+
+                       prev_dev->next_dev = del_dev->next_dev;
+               }
+
+               kfree(del_dev);
+       }
+}
+
+/* allocating new chip */
+static struct stv090x_dev *append_internal(struct stv090x_internal *internal)
+{
+       struct stv090x_dev *new_dev;
+       struct stv090x_dev *temp_dev;
+
+       new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);
+       if (new_dev != NULL) {
+               new_dev->internal = internal;
+               new_dev->next_dev = NULL;
+
+               /* append to list */
+               if (stv090x_first_dev == NULL) {
+                       stv090x_first_dev = new_dev;
+               } else {
+                       temp_dev = stv090x_first_dev;
+                       while (temp_dev->next_dev != NULL)
+                               temp_dev = temp_dev->next_dev;
+
+                       temp_dev->next_dev = new_dev;
+               }
+       }
+
+       return new_dev;
+}
+
+
+/* DVBS1 and DSS C/N Lookup table */
+static const struct stv090x_tab stv090x_s1cn_tab[] = {
+       {   0, 8917 }, /*  0.0dB */
+       {   5, 8801 }, /*  0.5dB */
+       {  10, 8667 }, /*  1.0dB */
+       {  15, 8522 }, /*  1.5dB */
+       {  20, 8355 }, /*  2.0dB */
+       {  25, 8175 }, /*  2.5dB */
+       {  30, 7979 }, /*  3.0dB */
+       {  35, 7763 }, /*  3.5dB */
+       {  40, 7530 }, /*  4.0dB */
+       {  45, 7282 }, /*  4.5dB */
+       {  50, 7026 }, /*  5.0dB */
+       {  55, 6781 }, /*  5.5dB */
+       {  60, 6514 }, /*  6.0dB */
+       {  65, 6241 }, /*  6.5dB */
+       {  70, 5965 }, /*  7.0dB */
+       {  75, 5690 }, /*  7.5dB */
+       {  80, 5424 }, /*  8.0dB */
+       {  85, 5161 }, /*  8.5dB */
+       {  90, 4902 }, /*  9.0dB */
+       {  95, 4654 }, /*  9.5dB */
+       { 100, 4417 }, /* 10.0dB */
+       { 105, 4186 }, /* 10.5dB */
+       { 110, 3968 }, /* 11.0dB */
+       { 115, 3757 }, /* 11.5dB */
+       { 120, 3558 }, /* 12.0dB */
+       { 125, 3366 }, /* 12.5dB */
+       { 130, 3185 }, /* 13.0dB */
+       { 135, 3012 }, /* 13.5dB */
+       { 140, 2850 }, /* 14.0dB */
+       { 145, 2698 }, /* 14.5dB */
+       { 150, 2550 }, /* 15.0dB */
+       { 160, 2283 }, /* 16.0dB */
+       { 170, 2042 }, /* 17.0dB */
+       { 180, 1827 }, /* 18.0dB */
+       { 190, 1636 }, /* 19.0dB */
+       { 200, 1466 }, /* 20.0dB */
+       { 210, 1315 }, /* 21.0dB */
+       { 220, 1181 }, /* 22.0dB */
+       { 230, 1064 }, /* 23.0dB */
+       { 240,  960 }, /* 24.0dB */
+       { 250,  869 }, /* 25.0dB */
+       { 260,  792 }, /* 26.0dB */
+       { 270,  724 }, /* 27.0dB */
+       { 280,  665 }, /* 28.0dB */
+       { 290,  616 }, /* 29.0dB */
+       { 300,  573 }, /* 30.0dB */
+       { 310,  537 }, /* 31.0dB */
+       { 320,  507 }, /* 32.0dB */
+       { 330,  483 }, /* 33.0dB */
+       { 400,  398 }, /* 40.0dB */
+       { 450,  381 }, /* 45.0dB */
+       { 500,  377 }  /* 50.0dB */
+};
+
+/* DVBS2 C/N Lookup table */
+static const struct stv090x_tab stv090x_s2cn_tab[] = {
+       { -30, 13348 }, /* -3.0dB */
+       { -20, 12640 }, /* -2d.0B */
+       { -10, 11883 }, /* -1.0dB */
+       {   0, 11101 }, /* -0.0dB */
+       {   5, 10718 }, /*  0.5dB */
+       {  10, 10339 }, /*  1.0dB */
+       {  15,  9947 }, /*  1.5dB */
+       {  20,  9552 }, /*  2.0dB */
+       {  25,  9183 }, /*  2.5dB */
+       {  30,  8799 }, /*  3.0dB */
+       {  35,  8422 }, /*  3.5dB */
+       {  40,  8062 }, /*  4.0dB */
+       {  45,  7707 }, /*  4.5dB */
+       {  50,  7353 }, /*  5.0dB */
+       {  55,  7025 }, /*  5.5dB */
+       {  60,  6684 }, /*  6.0dB */
+       {  65,  6331 }, /*  6.5dB */
+       {  70,  6036 }, /*  7.0dB */
+       {  75,  5727 }, /*  7.5dB */
+       {  80,  5437 }, /*  8.0dB */
+       {  85,  5164 }, /*  8.5dB */
+       {  90,  4902 }, /*  9.0dB */
+       {  95,  4653 }, /*  9.5dB */
+       { 100,  4408 }, /* 10.0dB */
+       { 105,  4187 }, /* 10.5dB */
+       { 110,  3961 }, /* 11.0dB */
+       { 115,  3751 }, /* 11.5dB */
+       { 120,  3558 }, /* 12.0dB */
+       { 125,  3368 }, /* 12.5dB */
+       { 130,  3191 }, /* 13.0dB */
+       { 135,  3017 }, /* 13.5dB */
+       { 140,  2862 }, /* 14.0dB */
+       { 145,  2710 }, /* 14.5dB */
+       { 150,  2565 }, /* 15.0dB */
+       { 160,  2300 }, /* 16.0dB */
+       { 170,  2058 }, /* 17.0dB */
+       { 180,  1849 }, /* 18.0dB */
+       { 190,  1663 }, /* 19.0dB */
+       { 200,  1495 }, /* 20.0dB */
+       { 210,  1349 }, /* 21.0dB */
+       { 220,  1222 }, /* 22.0dB */
+       { 230,  1110 }, /* 23.0dB */
+       { 240,  1011 }, /* 24.0dB */
+       { 250,   925 }, /* 25.0dB */
+       { 260,   853 }, /* 26.0dB */
+       { 270,   789 }, /* 27.0dB */
+       { 280,   734 }, /* 28.0dB */
+       { 290,   690 }, /* 29.0dB */
+       { 300,   650 }, /* 30.0dB */
+       { 310,   619 }, /* 31.0dB */
+       { 320,   593 }, /* 32.0dB */
+       { 330,   571 }, /* 33.0dB */
+       { 400,   498 }, /* 40.0dB */
+       { 450,   484 }, /* 45.0dB */
+       { 500,   481 }  /* 50.0dB */
+};
+
+/* RF level C/N lookup table */
+static const struct stv090x_tab stv090x_rf_tab[] = {
+       {  -5, 0xcaa1 }, /*  -5dBm */
+       { -10, 0xc229 }, /* -10dBm */
+       { -15, 0xbb08 }, /* -15dBm */
+       { -20, 0xb4bc }, /* -20dBm */
+       { -25, 0xad5a }, /* -25dBm */
+       { -30, 0xa298 }, /* -30dBm */
+       { -35, 0x98a8 }, /* -35dBm */
+       { -40, 0x8389 }, /* -40dBm */
+       { -45, 0x59be }, /* -45dBm */
+       { -50, 0x3a14 }, /* -50dBm */
+       { -55, 0x2d11 }, /* -55dBm */
+       { -60, 0x210d }, /* -60dBm */
+       { -65, 0xa14f }, /* -65dBm */
+       { -70, 0x07aa }  /* -70dBm */
+};
+
+
+static struct stv090x_reg stv0900_initval[] = {
+
+       { STV090x_OUTCFG,               0x00 },
+       { STV090x_MODECFG,              0xff },
+       { STV090x_AGCRF1CFG,            0x11 },
+       { STV090x_AGCRF2CFG,            0x13 },
+       { STV090x_TSGENERAL1X,          0x14 },
+       { STV090x_TSTTNR2,              0x21 },
+       { STV090x_TSTTNR4,              0x21 },
+       { STV090x_P2_DISTXCTL,          0x22 },
+       { STV090x_P2_F22TX,             0xc0 },
+       { STV090x_P2_F22RX,             0xc0 },
+       { STV090x_P2_DISRXCTL,          0x00 },
+       { STV090x_P2_DMDCFGMD,          0xF9 },
+       { STV090x_P2_DEMOD,             0x08 },
+       { STV090x_P2_DMDCFG3,           0xc4 },
+       { STV090x_P2_CARFREQ,           0xed },
+       { STV090x_P2_LDT,               0xd0 },
+       { STV090x_P2_LDT2,              0xb8 },
+       { STV090x_P2_TMGCFG,            0xd2 },
+       { STV090x_P2_TMGTHRISE,         0x20 },
+       { STV090x_P1_TMGCFG,            0xd2 },
+
+       { STV090x_P2_TMGTHFALL,         0x00 },
+       { STV090x_P2_FECSPY,            0x88 },
+       { STV090x_P2_FSPYDATA,          0x3a },
+       { STV090x_P2_FBERCPT4,          0x00 },
+       { STV090x_P2_FSPYBER,           0x10 },
+       { STV090x_P2_ERRCTRL1,          0x35 },
+       { STV090x_P2_ERRCTRL2,          0xc1 },
+       { STV090x_P2_CFRICFG,           0xf8 },
+       { STV090x_P2_NOSCFG,            0x1c },
+       { STV090x_P2_DMDTOM,            0x20 },
+       { STV090x_P2_CORRELMANT,        0x70 },
+       { STV090x_P2_CORRELABS,         0x88 },
+       { STV090x_P2_AGC2O,             0x5b },
+       { STV090x_P2_AGC2REF,           0x38 },
+       { STV090x_P2_CARCFG,            0xe4 },
+       { STV090x_P2_ACLC,              0x1A },
+       { STV090x_P2_BCLC,              0x09 },
+       { STV090x_P2_CARHDR,            0x08 },
+       { STV090x_P2_KREFTMG,           0xc1 },
+       { STV090x_P2_SFRUPRATIO,        0xf0 },
+       { STV090x_P2_SFRLOWRATIO,       0x70 },
+       { STV090x_P2_SFRSTEP,           0x58 },
+       { STV090x_P2_TMGCFG2,           0x01 },
+       { STV090x_P2_CAR2CFG,           0x26 },
+       { STV090x_P2_BCLC2S2Q,          0x86 },
+       { STV090x_P2_BCLC2S28,          0x86 },
+       { STV090x_P2_SMAPCOEF7,         0x77 },
+       { STV090x_P2_SMAPCOEF6,         0x85 },
+       { STV090x_P2_SMAPCOEF5,         0x77 },
+       { STV090x_P2_TSCFGL,            0x20 },
+       { STV090x_P2_DMDCFG2,           0x3b },
+       { STV090x_P2_MODCODLST0,        0xff },
+       { STV090x_P2_MODCODLST1,        0xff },
+       { STV090x_P2_MODCODLST2,        0xff },
+       { STV090x_P2_MODCODLST3,        0xff },
+       { STV090x_P2_MODCODLST4,        0xff },
+       { STV090x_P2_MODCODLST5,        0xff },
+       { STV090x_P2_MODCODLST6,        0xff },
+       { STV090x_P2_MODCODLST7,        0xcc },
+       { STV090x_P2_MODCODLST8,        0xcc },
+       { STV090x_P2_MODCODLST9,        0xcc },
+       { STV090x_P2_MODCODLSTA,        0xcc },
+       { STV090x_P2_MODCODLSTB,        0xcc },
+       { STV090x_P2_MODCODLSTC,        0xcc },
+       { STV090x_P2_MODCODLSTD,        0xcc },
+       { STV090x_P2_MODCODLSTE,        0xcc },
+       { STV090x_P2_MODCODLSTF,        0xcf },
+       { STV090x_P1_DISTXCTL,          0x22 },
+       { STV090x_P1_F22TX,             0xc0 },
+       { STV090x_P1_F22RX,             0xc0 },
+       { STV090x_P1_DISRXCTL,          0x00 },
+       { STV090x_P1_DMDCFGMD,          0xf9 },
+       { STV090x_P1_DEMOD,             0x08 },
+       { STV090x_P1_DMDCFG3,           0xc4 },
+       { STV090x_P1_DMDTOM,            0x20 },
+       { STV090x_P1_CARFREQ,           0xed },
+       { STV090x_P1_LDT,               0xd0 },
+       { STV090x_P1_LDT2,              0xb8 },
+       { STV090x_P1_TMGCFG,            0xd2 },
+       { STV090x_P1_TMGTHRISE,         0x20 },
+       { STV090x_P1_TMGTHFALL,         0x00 },
+       { STV090x_P1_SFRUPRATIO,        0xf0 },
+       { STV090x_P1_SFRLOWRATIO,       0x70 },
+       { STV090x_P1_TSCFGL,            0x20 },
+       { STV090x_P1_FECSPY,            0x88 },
+       { STV090x_P1_FSPYDATA,          0x3a },
+       { STV090x_P1_FBERCPT4,          0x00 },
+       { STV090x_P1_FSPYBER,           0x10 },
+       { STV090x_P1_ERRCTRL1,          0x35 },
+       { STV090x_P1_ERRCTRL2,          0xc1 },
+       { STV090x_P1_CFRICFG,           0xf8 },
+       { STV090x_P1_NOSCFG,            0x1c },
+       { STV090x_P1_CORRELMANT,        0x70 },
+       { STV090x_P1_CORRELABS,         0x88 },
+       { STV090x_P1_AGC2O,             0x5b },
+       { STV090x_P1_AGC2REF,           0x38 },
+       { STV090x_P1_CARCFG,            0xe4 },
+       { STV090x_P1_ACLC,              0x1A },
+       { STV090x_P1_BCLC,              0x09 },
+       { STV090x_P1_CARHDR,            0x08 },
+       { STV090x_P1_KREFTMG,           0xc1 },
+       { STV090x_P1_SFRSTEP,           0x58 },
+       { STV090x_P1_TMGCFG2,           0x01 },
+       { STV090x_P1_CAR2CFG,           0x26 },
+       { STV090x_P1_BCLC2S2Q,          0x86 },
+       { STV090x_P1_BCLC2S28,          0x86 },
+       { STV090x_P1_SMAPCOEF7,         0x77 },
+       { STV090x_P1_SMAPCOEF6,         0x85 },
+       { STV090x_P1_SMAPCOEF5,         0x77 },
+       { STV090x_P1_DMDCFG2,           0x3b },
+       { STV090x_P1_MODCODLST0,        0xff },
+       { STV090x_P1_MODCODLST1,        0xff },
+       { STV090x_P1_MODCODLST2,        0xff },
+       { STV090x_P1_MODCODLST3,        0xff },
+       { STV090x_P1_MODCODLST4,        0xff },
+       { STV090x_P1_MODCODLST5,        0xff },
+       { STV090x_P1_MODCODLST6,        0xff },
+       { STV090x_P1_MODCODLST7,        0xcc },
+       { STV090x_P1_MODCODLST8,        0xcc },
+       { STV090x_P1_MODCODLST9,        0xcc },
+       { STV090x_P1_MODCODLSTA,        0xcc },
+       { STV090x_P1_MODCODLSTB,        0xcc },
+       { STV090x_P1_MODCODLSTC,        0xcc },
+       { STV090x_P1_MODCODLSTD,        0xcc },
+       { STV090x_P1_MODCODLSTE,        0xcc },
+       { STV090x_P1_MODCODLSTF,        0xcf },
+       { STV090x_GENCFG,               0x1d },
+       { STV090x_NBITER_NF4,           0x37 },
+       { STV090x_NBITER_NF5,           0x29 },
+       { STV090x_NBITER_NF6,           0x37 },
+       { STV090x_NBITER_NF7,           0x33 },
+       { STV090x_NBITER_NF8,           0x31 },
+       { STV090x_NBITER_NF9,           0x2f },
+       { STV090x_NBITER_NF10,          0x39 },
+       { STV090x_NBITER_NF11,          0x3a },
+       { STV090x_NBITER_NF12,          0x29 },
+       { STV090x_NBITER_NF13,          0x37 },
+       { STV090x_NBITER_NF14,          0x33 },
+       { STV090x_NBITER_NF15,          0x2f },
+       { STV090x_NBITER_NF16,          0x39 },
+       { STV090x_NBITER_NF17,          0x3a },
+       { STV090x_NBITERNOERR,          0x04 },
+       { STV090x_GAINLLR_NF4,          0x0C },
+       { STV090x_GAINLLR_NF5,          0x0F },
+       { STV090x_GAINLLR_NF6,          0x11 },
+       { STV090x_GAINLLR_NF7,          0x14 },
+       { STV090x_GAINLLR_NF8,          0x17 },
+       { STV090x_GAINLLR_NF9,          0x19 },
+       { STV090x_GAINLLR_NF10,         0x20 },
+       { STV090x_GAINLLR_NF11,         0x21 },
+       { STV090x_GAINLLR_NF12,         0x0D },
+       { STV090x_GAINLLR_NF13,         0x0F },
+       { STV090x_GAINLLR_NF14,         0x13 },
+       { STV090x_GAINLLR_NF15,         0x1A },
+       { STV090x_GAINLLR_NF16,         0x1F },
+       { STV090x_GAINLLR_NF17,         0x21 },
+       { STV090x_RCCFGH,               0x20 },
+       { STV090x_P1_FECM,              0x01 }, /* disable DSS modes */
+       { STV090x_P2_FECM,              0x01 }, /* disable DSS modes */
+       { STV090x_P1_PRVIT,             0x2F }, /* disable PR 6/7 */
+       { STV090x_P2_PRVIT,             0x2F }, /* disable PR 6/7 */
+};
+
+static struct stv090x_reg stv0903_initval[] = {
+       { STV090x_OUTCFG,               0x00 },
+       { STV090x_AGCRF1CFG,            0x11 },
+       { STV090x_STOPCLK1,             0x48 },
+       { STV090x_STOPCLK2,             0x14 },
+       { STV090x_TSTTNR1,              0x27 },
+       { STV090x_TSTTNR2,              0x21 },
+       { STV090x_P1_DISTXCTL,          0x22 },
+       { STV090x_P1_F22TX,             0xc0 },
+       { STV090x_P1_F22RX,             0xc0 },
+       { STV090x_P1_DISRXCTL,          0x00 },
+       { STV090x_P1_DMDCFGMD,          0xF9 },
+       { STV090x_P1_DEMOD,             0x08 },
+       { STV090x_P1_DMDCFG3,           0xc4 },
+       { STV090x_P1_CARFREQ,           0xed },
+       { STV090x_P1_TNRCFG2,           0x82 },
+       { STV090x_P1_LDT,               0xd0 },
+       { STV090x_P1_LDT2,              0xb8 },
+       { STV090x_P1_TMGCFG,            0xd2 },
+       { STV090x_P1_TMGTHRISE,         0x20 },
+       { STV090x_P1_TMGTHFALL,         0x00 },
+       { STV090x_P1_SFRUPRATIO,        0xf0 },
+       { STV090x_P1_SFRLOWRATIO,       0x70 },
+       { STV090x_P1_TSCFGL,            0x20 },
+       { STV090x_P1_FECSPY,            0x88 },
+       { STV090x_P1_FSPYDATA,          0x3a },
+       { STV090x_P1_FBERCPT4,          0x00 },
+       { STV090x_P1_FSPYBER,           0x10 },
+       { STV090x_P1_ERRCTRL1,          0x35 },
+       { STV090x_P1_ERRCTRL2,          0xc1 },
+       { STV090x_P1_CFRICFG,           0xf8 },
+       { STV090x_P1_NOSCFG,            0x1c },
+       { STV090x_P1_DMDTOM,            0x20 },
+       { STV090x_P1_CORRELMANT,        0x70 },
+       { STV090x_P1_CORRELABS,         0x88 },
+       { STV090x_P1_AGC2O,             0x5b },
+       { STV090x_P1_AGC2REF,           0x38 },
+       { STV090x_P1_CARCFG,            0xe4 },
+       { STV090x_P1_ACLC,              0x1A },
+       { STV090x_P1_BCLC,              0x09 },
+       { STV090x_P1_CARHDR,            0x08 },
+       { STV090x_P1_KREFTMG,           0xc1 },
+       { STV090x_P1_SFRSTEP,           0x58 },
+       { STV090x_P1_TMGCFG2,           0x01 },
+       { STV090x_P1_CAR2CFG,           0x26 },
+       { STV090x_P1_BCLC2S2Q,          0x86 },
+       { STV090x_P1_BCLC2S28,          0x86 },
+       { STV090x_P1_SMAPCOEF7,         0x77 },
+       { STV090x_P1_SMAPCOEF6,         0x85 },
+       { STV090x_P1_SMAPCOEF5,         0x77 },
+       { STV090x_P1_DMDCFG2,           0x3b },
+       { STV090x_P1_MODCODLST0,        0xff },
+       { STV090x_P1_MODCODLST1,        0xff },
+       { STV090x_P1_MODCODLST2,        0xff },
+       { STV090x_P1_MODCODLST3,        0xff },
+       { STV090x_P1_MODCODLST4,        0xff },
+       { STV090x_P1_MODCODLST5,        0xff },
+       { STV090x_P1_MODCODLST6,        0xff },
+       { STV090x_P1_MODCODLST7,        0xcc },
+       { STV090x_P1_MODCODLST8,        0xcc },
+       { STV090x_P1_MODCODLST9,        0xcc },
+       { STV090x_P1_MODCODLSTA,        0xcc },
+       { STV090x_P1_MODCODLSTB,        0xcc },
+       { STV090x_P1_MODCODLSTC,        0xcc },
+       { STV090x_P1_MODCODLSTD,        0xcc },
+       { STV090x_P1_MODCODLSTE,        0xcc },
+       { STV090x_P1_MODCODLSTF,        0xcf },
+       { STV090x_GENCFG,               0x1c },
+       { STV090x_NBITER_NF4,           0x37 },
+       { STV090x_NBITER_NF5,           0x29 },
+       { STV090x_NBITER_NF6,           0x37 },
+       { STV090x_NBITER_NF7,           0x33 },
+       { STV090x_NBITER_NF8,           0x31 },
+       { STV090x_NBITER_NF9,           0x2f },
+       { STV090x_NBITER_NF10,          0x39 },
+       { STV090x_NBITER_NF11,          0x3a },
+       { STV090x_NBITER_NF12,          0x29 },
+       { STV090x_NBITER_NF13,          0x37 },
+       { STV090x_NBITER_NF14,          0x33 },
+       { STV090x_NBITER_NF15,          0x2f },
+       { STV090x_NBITER_NF16,          0x39 },
+       { STV090x_NBITER_NF17,          0x3a },
+       { STV090x_NBITERNOERR,          0x04 },
+       { STV090x_GAINLLR_NF4,          0x0C },
+       { STV090x_GAINLLR_NF5,          0x0F },
+       { STV090x_GAINLLR_NF6,          0x11 },
+       { STV090x_GAINLLR_NF7,          0x14 },
+       { STV090x_GAINLLR_NF8,          0x17 },
+       { STV090x_GAINLLR_NF9,          0x19 },
+       { STV090x_GAINLLR_NF10,         0x20 },
+       { STV090x_GAINLLR_NF11,         0x21 },
+       { STV090x_GAINLLR_NF12,         0x0D },
+       { STV090x_GAINLLR_NF13,         0x0F },
+       { STV090x_GAINLLR_NF14,         0x13 },
+       { STV090x_GAINLLR_NF15,         0x1A },
+       { STV090x_GAINLLR_NF16,         0x1F },
+       { STV090x_GAINLLR_NF17,         0x21 },
+       { STV090x_RCCFGH,               0x20 },
+       { STV090x_P1_FECM,              0x01 }, /*disable the DSS mode */
+       { STV090x_P1_PRVIT,             0x2f }  /*disable puncture rate 6/7*/
+};
+
+static struct stv090x_reg stv0900_cut20_val[] = {
+
+       { STV090x_P2_DMDCFG3,           0xe8 },
+       { STV090x_P2_DMDCFG4,           0x10 },
+       { STV090x_P2_CARFREQ,           0x38 },
+       { STV090x_P2_CARHDR,            0x20 },
+       { STV090x_P2_KREFTMG,           0x5a },
+       { STV090x_P2_SMAPCOEF7,         0x06 },
+       { STV090x_P2_SMAPCOEF6,         0x00 },
+       { STV090x_P2_SMAPCOEF5,         0x04 },
+       { STV090x_P2_NOSCFG,            0x0c },
+       { STV090x_P1_DMDCFG3,           0xe8 },
+       { STV090x_P1_DMDCFG4,           0x10 },
+       { STV090x_P1_CARFREQ,           0x38 },
+       { STV090x_P1_CARHDR,            0x20 },
+       { STV090x_P1_KREFTMG,           0x5a },
+       { STV090x_P1_SMAPCOEF7,         0x06 },
+       { STV090x_P1_SMAPCOEF6,         0x00 },
+       { STV090x_P1_SMAPCOEF5,         0x04 },
+       { STV090x_P1_NOSCFG,            0x0c },
+       { STV090x_GAINLLR_NF4,          0x21 },
+       { STV090x_GAINLLR_NF5,          0x21 },
+       { STV090x_GAINLLR_NF6,          0x20 },
+       { STV090x_GAINLLR_NF7,          0x1F },
+       { STV090x_GAINLLR_NF8,          0x1E },
+       { STV090x_GAINLLR_NF9,          0x1E },
+       { STV090x_GAINLLR_NF10,         0x1D },
+       { STV090x_GAINLLR_NF11,         0x1B },
+       { STV090x_GAINLLR_NF12,         0x20 },
+       { STV090x_GAINLLR_NF13,         0x20 },
+       { STV090x_GAINLLR_NF14,         0x20 },
+       { STV090x_GAINLLR_NF15,         0x20 },
+       { STV090x_GAINLLR_NF16,         0x20 },
+       { STV090x_GAINLLR_NF17,         0x21 },
+};
+
+static struct stv090x_reg stv0903_cut20_val[] = {
+       { STV090x_P1_DMDCFG3,           0xe8 },
+       { STV090x_P1_DMDCFG4,           0x10 },
+       { STV090x_P1_CARFREQ,           0x38 },
+       { STV090x_P1_CARHDR,            0x20 },
+       { STV090x_P1_KREFTMG,           0x5a },
+       { STV090x_P1_SMAPCOEF7,         0x06 },
+       { STV090x_P1_SMAPCOEF6,         0x00 },
+       { STV090x_P1_SMAPCOEF5,         0x04 },
+       { STV090x_P1_NOSCFG,            0x0c },
+       { STV090x_GAINLLR_NF4,          0x21 },
+       { STV090x_GAINLLR_NF5,          0x21 },
+       { STV090x_GAINLLR_NF6,          0x20 },
+       { STV090x_GAINLLR_NF7,          0x1F },
+       { STV090x_GAINLLR_NF8,          0x1E },
+       { STV090x_GAINLLR_NF9,          0x1E },
+       { STV090x_GAINLLR_NF10,         0x1D },
+       { STV090x_GAINLLR_NF11,         0x1B },
+       { STV090x_GAINLLR_NF12,         0x20 },
+       { STV090x_GAINLLR_NF13,         0x20 },
+       { STV090x_GAINLLR_NF14,         0x20 },
+       { STV090x_GAINLLR_NF15,         0x20 },
+       { STV090x_GAINLLR_NF16,         0x20 },
+       { STV090x_GAINLLR_NF17,         0x21 }
+};
+
+/* Cut 2.0 Long Frame Tracking CR loop */
+static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_QPSK_12,  0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },
+       { STV090x_QPSK_35,  0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },
+       { STV090x_QPSK_23,  0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_QPSK_34,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_QPSK_45,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_QPSK_56,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_QPSK_89,  0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
+       { STV090x_8PSK_35,  0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },
+       { STV090x_8PSK_23,  0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },
+       { STV090x_8PSK_34,  0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },
+       { STV090x_8PSK_56,  0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
+       { STV090x_8PSK_89,  0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
+       { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
+};
+
+/* Cut 3.0 Long Frame Tracking CR loop */
+static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_QPSK_12,  0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },
+       { STV090x_QPSK_35,  0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+       { STV090x_QPSK_23,  0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+       { STV090x_QPSK_34,  0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
+       { STV090x_QPSK_45,  0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+       { STV090x_QPSK_56,  0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+       { STV090x_QPSK_89,  0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+       { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
+       { STV090x_8PSK_35,  0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },
+       { STV090x_8PSK_23,  0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },
+       { STV090x_8PSK_34,  0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },
+       { STV090x_8PSK_56,  0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },
+       { STV090x_8PSK_89,  0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },
+       { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }
+};
+
+/* Cut 2.0 Long Frame Tracking CR Loop */
+static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_16APSK_23,  0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },
+       { STV090x_16APSK_34,  0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },
+       { STV090x_16APSK_45,  0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
+       { STV090x_16APSK_56,  0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
+       { STV090x_16APSK_89,  0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
+       { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
+       { STV090x_32APSK_34,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+       { STV090x_32APSK_45,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+       { STV090x_32APSK_56,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+       { STV090x_32APSK_89,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
+       { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }
+};
+
+/* Cut 3.0 Long Frame Tracking CR Loop */
+static struct stv090x_long_frame_crloop        stv090x_s2_apsk_crl_cut30[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_16APSK_23,  0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },
+       { STV090x_16APSK_34,  0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },
+       { STV090x_16APSK_45,  0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
+       { STV090x_16APSK_56,  0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
+       { STV090x_16APSK_89,  0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
+       { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
+       { STV090x_32APSK_34,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+       { STV090x_32APSK_45,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+       { STV090x_32APSK_56,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+       { STV090x_32APSK_89,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
+       { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }
+};
+
+static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_QPSK_14,  0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },
+       { STV090x_QPSK_13,  0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },
+       { STV090x_QPSK_25,  0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }
+};
+
+static struct stv090x_long_frame_crloop        stv090x_s2_lowqpsk_crl_cut30[] = {
+       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+       { STV090x_QPSK_14,  0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },
+       { STV090x_QPSK_13,  0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },
+       { STV090x_QPSK_25,  0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }
+};
+
+/* Cut 2.0 Short Frame Tracking CR Loop */
+static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
+       /* MODCOD         2M    5M    10M   20M   30M */
+       { STV090x_QPSK,   0x2f, 0x2e, 0x0e, 0x0e, 0x3d },
+       { STV090x_8PSK,   0x3e, 0x0e, 0x2d, 0x0d, 0x3c },
+       { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },
+       { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }
+};
+
+/* Cut 3.0 Short Frame Tracking CR Loop */
+static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
+       /* MODCOD         2M    5M    10M   20M   30M */
+       { STV090x_QPSK,   0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
+       { STV090x_8PSK,   0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
+       { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
+       { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }
+};
+
+static inline s32 comp2(s32 __x, s32 __width)
+{
+       if (__width == 32)
+               return __x;
+       else
+               return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;
+}
+
+static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
+{
+       const struct stv090x_config *config = state->config;
+       int ret;
+
+       u8 b0[] = { reg >> 8, reg & 0xff };
+       u8 buf;
+
+       struct i2c_msg msg[] = {
+               { .addr = config->address, .flags       = 0,            .buf = b0,   .len = 2 },
+               { .addr = config->address, .flags       = I2C_M_RD,     .buf = &buf, .len = 1 }
+       };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+       if (ret != 2) {
+               if (ret != -ERESTARTSYS)
+                       dprintk(FE_ERROR, 1,
+                               "Read error, Reg=[0x%02x], Status=%d",
+                               reg, ret);
+
+               return ret < 0 ? ret : -EREMOTEIO;
+       }
+       if (unlikely(*state->verbose >= FE_DEBUGREG))
+               dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
+                       reg, buf);
+
+       return (unsigned int) buf;
+}
+
+static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)
+{
+       const struct stv090x_config *config = state->config;
+       int ret;
+       u8 buf[2 + count];
+       struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
+
+       buf[0] = reg >> 8;
+       buf[1] = reg & 0xff;
+       memcpy(&buf[2], data, count);
+
+       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+               int i;
+
+               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+               for (i = 0; i < count; i++)
+                       printk(" %02x", data[i]);
+               printk("\n");
+       }
+
+       ret = i2c_transfer(state->i2c, &i2c_msg, 1);
+       if (ret != 1) {
+               if (ret != -ERESTARTSYS)
+                       dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
+                               reg, data[0], count, ret);
+               return ret < 0 ? ret : -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
+{
+       return stv090x_write_regs(state, reg, &data, 1);
+}
+
+static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
+{
+       u32 reg;
+
+       /*
+        * NOTE! A lock is used as a FSM to control the state in which
+        * access is serialized between two tuners on the same demod.
+        * This has nothing to do with a lock to protect a critical section
+        * which may in some other cases be confused with protecting I/O
+        * access to the demodulator gate.
+        * In case of any error, the lock is unlocked and exit within the
+        * relevant operations themselves.
+        */
+       if (enable) {
+               if (state->config->tuner_i2c_lock)
+                       state->config->tuner_i2c_lock(&state->frontend, 1);
+               else
+                       mutex_lock(&state->internal->tuner_lock);
+       }
+
+       reg = STV090x_READ_DEMOD(state, I2CRPT);
+       if (enable) {
+               dprintk(FE_DEBUG, 1, "Enable Gate");
+               STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)
+                       goto err;
+
+       } else {
+               dprintk(FE_DEBUG, 1, "Disable Gate");
+               STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);
+               if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
+                       goto err;
+       }
+
+       if (!enable) {
+               if (state->config->tuner_i2c_lock)
+                       state->config->tuner_i2c_lock(&state->frontend, 0);
+               else
+                       mutex_unlock(&state->internal->tuner_lock);
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       if (state->config->tuner_i2c_lock)
+               state->config->tuner_i2c_lock(&state->frontend, 0);
+       else
+               mutex_unlock(&state->internal->tuner_lock);
+       return -1;
+}
+
+static void stv090x_get_lock_tmg(struct stv090x_state *state)
+{
+       switch (state->algo) {
+       case STV090x_BLIND_SEARCH:
+               dprintk(FE_DEBUG, 1, "Blind Search");
+               if (state->srate <= 1500000) {  /*10Msps< SR <=15Msps*/
+                       state->DemodTimeout = 1500;
+                       state->FecTimeout = 400;
+               } else if (state->srate <= 5000000) {  /*10Msps< SR <=15Msps*/
+                       state->DemodTimeout = 1000;
+                       state->FecTimeout = 300;
+               } else {  /*SR >20Msps*/
+                       state->DemodTimeout = 700;
+                       state->FecTimeout = 100;
+               }
+               break;
+
+       case STV090x_COLD_SEARCH:
+       case STV090x_WARM_SEARCH:
+       default:
+               dprintk(FE_DEBUG, 1, "Normal Search");
+               if (state->srate <= 1000000) {  /*SR <=1Msps*/
+                       state->DemodTimeout = 4500;
+                       state->FecTimeout = 1700;
+               } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */
+                       state->DemodTimeout = 2500;
+                       state->FecTimeout = 1100;
+               } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */
+                       state->DemodTimeout = 1000;
+                       state->FecTimeout = 550;
+               } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */
+                       state->DemodTimeout = 700;
+                       state->FecTimeout = 250;
+               } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */
+                       state->DemodTimeout = 400;
+                       state->FecTimeout = 130;
+               } else {   /*SR >20Msps*/
+                       state->DemodTimeout = 300;
+                       state->FecTimeout = 100;
+               }
+               break;
+       }
+
+       if (state->algo == STV090x_WARM_SEARCH)
+               state->DemodTimeout /= 2;
+}
+
+static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
+{
+       u32 sym;
+
+       if (srate > 60000000) {
+               sym  = (srate << 4); /* SR * 2^16 / master_clk */
+               sym /= (state->internal->mclk >> 12);
+       } else if (srate > 6000000) {
+               sym  = (srate << 6);
+               sym /= (state->internal->mclk >> 10);
+       } else {
+               sym  = (srate << 9);
+               sym /= (state->internal->mclk >> 7);
+       }
+
+       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)
+{
+       u32 sym;
+
+       srate = 105 * (srate / 100);
+       if (srate > 60000000) {
+               sym  = (srate << 4); /* SR * 2^16 / master_clk */
+               sym /= (state->internal->mclk >> 12);
+       } else if (srate > 6000000) {
+               sym  = (srate << 6);
+               sym /= (state->internal->mclk >> 10);
+       } else {
+               sym  = (srate << 9);
+               sym /= (state->internal->mclk >> 7);
+       }
+
+       if (sym < 0x7fff) {
+               if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */
+                       goto err;
+       } else {
+               if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */
+                       goto err;
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)
+{
+       u32 sym;
+
+       srate = 95 * (srate / 100);
+       if (srate > 60000000) {
+               sym  = (srate << 4); /* SR * 2^16 / master_clk */
+               sym /= (state->internal->mclk >> 12);
+       } else if (srate > 6000000) {
+               sym  = (srate << 6);
+               sym /= (state->internal->mclk >> 10);
+       } else {
+               sym  = (srate << 9);
+               sym /= (state->internal->mclk >> 7);
+       }
+
+       if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
+               goto err;
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)
+{
+       u32 ro;
+
+       switch (rolloff) {
+       case STV090x_RO_20:
+               ro = 20;
+               break;
+       case STV090x_RO_25:
+               ro = 25;
+               break;
+       case STV090x_RO_35:
+       default:
+               ro = 35;
+               break;
+       }
+
+       return srate + (srate * ro) / 100;
+}
+
+static int stv090x_set_vit_thacq(struct stv090x_state *state)
+{
+       if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)
+               goto err;
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_set_vit_thtracq(struct stv090x_state *state)
+{
+       if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)
+               goto err;
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_set_viterbi(struct stv090x_state *state)
+{
+       switch (state->search_mode) {
+       case STV090x_SEARCH_AUTO:
+               if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */
+                       goto err;
+               break;
+       case STV090x_SEARCH_DVBS1:
+               if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */
+                       goto err;
+               switch (state->fec) {
+               case STV090x_PR12:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR23:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR34:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR56:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR78:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)
+                               goto err;
+                       break;
+
+               default:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */
+                               goto err;
+                       break;
+               }
+               break;
+       case STV090x_SEARCH_DSS:
+               if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)
+                       goto err;
+               switch (state->fec) {
+               case STV090x_PR12:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR23:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
+                               goto err;
+                       break;
+
+               case STV090x_PR67:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)
+                               goto err;
+                       break;
+
+               default:
+                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */
+                               goto err;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_stop_modcod(struct stv090x_state *state)
+{
+       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)
+               goto err;
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_activate_modcod(struct stv090x_state *state)
+{
+       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_activate_modcod_single(struct stv090x_state *state)
+{
+
+       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)
+               goto err;
+
+       return 0;
+
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
+{
+       u32 reg;
+
+       switch (state->demod) {
+       case STV090x_DEMODULATOR_0:
+               mutex_lock(&state->internal->demod_lock);
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               mutex_unlock(&state->internal->demod_lock);
+               break;
+
+       case STV090x_DEMODULATOR_1:
+               mutex_lock(&state->internal->demod_lock);
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               mutex_unlock(&state->internal->demod_lock);
+               break;
+
+       default:
+               dprintk(FE_ERROR, 1, "Wrong demodulator!");
+               break;
+       }
+       return 0;
+err:
+       mutex_unlock(&state->internal->demod_lock);
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_dvbs_track_crl(struct stv090x_state *state)
+{
+       if (state->internal->dev_ver >= 0x30) {
+               /* Set ACLC BCLC optimised value vs SR */
+               if (state->srate >= 15000000) {
+                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)
+                               goto err;
+               } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {
+                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)
+                               goto err;
+               } else if (state->srate < 7000000) {
+                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)
+                               goto err;
+               }
+
+       } else {
+               /* Cut 2.0 */
+               if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
+                       goto err;
+       }
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_delivery_search(struct stv090x_state *state)
+{
+       u32 reg;
+
+       switch (state->search_mode) {
+       case STV090x_SEARCH_DVBS1:
+       case STV090x_SEARCH_DSS:
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+
+               /* Activate Viterbi decoder in legacy search,
+                * do not use FRESVIT1, might impact VITERBI2
+                */
+               if (stv090x_vitclk_ctl(state, 0) < 0)
+                       goto err;
+
+               if (stv090x_dvbs_track_crl(state) < 0)
+                       goto err;
+
+               if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */
+                       goto err;
+
+               if (stv090x_set_vit_thacq(state) < 0)
+                       goto err;
+               if (stv090x_set_viterbi(state) < 0)
+                       goto err;
+               break;
+
+       case STV090x_SEARCH_DVBS2:
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+
+               if (stv090x_vitclk_ctl(state, 1) < 0)
+                       goto err;
+
+               if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver <= 0x20) {
+                       /* enable S2 carrier loop */
+                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
+                               goto err;
+               } else {
+                       /* > Cut 3: Stop carrier 3 */
+                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
+                               goto err;
+               }
+
+               if (state->demod_mode != STV090x_SINGLE) {
+                       /* Cut 2: enable link during search */
+                       if (stv090x_activate_modcod(state) < 0)
+                               goto err;
+               } else {
+                       /* Single demodulator
+                        * Authorize SHORT and LONG frames,
+                        * QPSK, 8PSK, 16APSK and 32APSK
+                        */
+                       if (stv090x_activate_modcod_single(state) < 0)
+                               goto err;
+               }
+
+               if (stv090x_set_vit_thtracq(state) < 0)
+                       goto err;
+               break;
+
+       case STV090x_SEARCH_AUTO:
+       default:
+               /* enable DVB-S2 and DVB-S2 in Auto MODE */
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+
+               if (stv090x_vitclk_ctl(state, 0) < 0)
+                       goto err;
+
+               if (stv090x_dvbs_track_crl(state) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver <= 0x20) {
+                       /* enable S2 carrier loop */
+                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
+                               goto err;
+               } else {
+                       /* > Cut 3: Stop carrier 3 */
+                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
+                               goto err;
+               }
+
+               if (state->demod_mode != STV090x_SINGLE) {
+                       /* Cut 2: enable link during search */
+                       if (stv090x_activate_modcod(state) < 0)
+                               goto err;
+               } else {
+                       /* Single demodulator
+                        * Authorize SHORT and LONG frames,
+                        * QPSK, 8PSK, 16APSK and 32APSK
+                        */
+                       if (stv090x_activate_modcod_single(state) < 0)
+                               goto err;
+               }
+
+               if (stv090x_set_vit_thacq(state) < 0)
+                       goto err;
+
+               if (stv090x_set_viterbi(state) < 0)
+                       goto err;
+               break;
+       }
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_start_search(struct stv090x_state *state)
+{
+       u32 reg, freq_abs;
+       s16 freq;
+
+       /* Reset demodulator */
+       reg = STV090x_READ_DEMOD(state, DMDISTATE);
+       STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);
+       if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+               goto err;
+
+       if (state->internal->dev_ver <= 0x20) {
+               if (state->srate <= 5000000) {
+                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)
+                               goto err;
+
+                       /*enlarge the timing bandwidth for Low SR*/
+                       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)
+                               goto err;
+               } else {
+                       /* If the symbol rate is >5 Msps
+                       Set The carrier search up and low to auto mode */
+                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
+                               goto err;
+                       /*reduce the timing bandwidth for high SR*/
+                       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
+                               goto err;
+               }
+       } else {
+               /* >= Cut 3 */
+               if (state->srate <= 5000000) {
+                       /* enlarge the timing bandwidth for Low SR */
+                       STV090x_WRITE_DEMOD(state, RTCS2, 0x68);
+               } else {
+                       /* reduce timing bandwidth for high SR */
+                       STV090x_WRITE_DEMOD(state, RTCS2, 0x44);
+               }
+
+               /* Set CFR min and max to manual mode */
+               STV090x_WRITE_DEMOD(state, CARCFG, 0x46);
+
+               if (state->algo == STV090x_WARM_SEARCH) {
+                       /* WARM Start
+                        * CFR min = -1MHz,
+                        * CFR max = +1MHz
+                        */
+                       freq_abs  = 1000 << 16;
+                       freq_abs /= (state->internal->mclk / 1000);
+                       freq      = (s16) freq_abs;
+               } else {
+                       /* COLD Start
+                        * CFR min =- (SearchRange / 2 + 600KHz)
+                        * CFR max = +(SearchRange / 2 + 600KHz)
+                        * (600KHz for the tuner step size)
+                        */
+                       freq_abs  = (state->search_range / 2000) + 600;
+                       freq_abs  = freq_abs << 16;
+                       freq_abs /= (state->internal->mclk / 1000);
+                       freq      = (s16) freq_abs;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
+                       goto err;
+
+               freq *= -1;
+
+               if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)
+                       goto err;
+
+       }
+
+       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
+               goto err;
+
+       if (state->internal->dev_ver >= 0x20) {
+               if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
+                       goto err;
+
+               if ((state->search_mode == STV090x_SEARCH_DVBS1)        ||
+                       (state->search_mode == STV090x_SEARCH_DSS)      ||
+                       (state->search_mode == STV090x_SEARCH_AUTO)) {
+
+                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)
+                               goto err;
+               }
+       }
+
+       if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)
+               goto err;
+
+       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
+       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+               goto err;
+       reg = STV090x_READ_DEMOD(state, DMDCFG2);
+       STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);
+       if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
+               goto err;
+
+       if (state->internal->dev_ver >= 0x20) {
+               /*Frequency offset detector setting*/
+               if (state->srate < 2000000) {
+                       if (state->internal->dev_ver <= 0x20) {
+                               /* Cut 2 */
+                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
+                                       goto err;
+                       } else {
+                               /* Cut 3 */
+                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
+                                       goto err;
+                       }
+                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
+                               goto err;
+               } else if (state->srate < 10000000) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+                               goto err;
+               } else {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
+                               goto err;
+               }
+       } else {
+               if (state->srate < 10000000) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)
+                               goto err;
+               } else {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)
+                               goto err;
+               }
+       }
+
+       switch (state->algo) {
+       case STV090x_WARM_SEARCH:
+               /* The symbol rate and the exact
+                * carrier Frequency are known
+                */
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+                       goto err;
+               break;
+
+       case STV090x_COLD_SEARCH:
+               /* The symbol rate is known */
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+                       goto err;
+               break;
+
+       default:
+               break;
+       }
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_get_agc2_min_level(struct stv090x_state *state)
+{
+       u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
+       s32 i, j, steps, dir;
+
+       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+               goto err;
+       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
+       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */
+               goto err;
+       if (stv090x_set_srate(state, 1000000) < 0)
+               goto err;
+
+       steps  = state->search_range / 1000000;
+       if (steps <= 0)
+               steps = 1;
+
+       dir = 1;
+       freq_step = (1000000 * 256) / (state->internal->mclk / 256);
+       freq_init = 0;
+
+       for (i = 0; i < steps; i++) {
+               if (dir > 0)
+                       freq_init = freq_init + (freq_step * i);
+               else
+                       freq_init = freq_init - (freq_step * i);
+
+               dir *= -1;
+
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
+                       goto err;
+               msleep(10);
+
+               agc2 = 0;
+               for (j = 0; j < 10; j++) {
+                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+                               STV090x_READ_DEMOD(state, AGC2I0);
+               }
+               agc2 /= 10;
+               if (agc2 < agc2_min)
+                       agc2_min = agc2;
+       }
+
+       return agc2_min;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)
+{
+       u8 r3, r2, r1, r0;
+       s32 srate, int_1, int_2, tmp_1, tmp_2;
+
+       r3 = STV090x_READ_DEMOD(state, SFR3);
+       r2 = STV090x_READ_DEMOD(state, SFR2);
+       r1 = STV090x_READ_DEMOD(state, SFR1);
+       r0 = STV090x_READ_DEMOD(state, SFR0);
+
+       srate = ((r3 << 24) | (r2 << 16) | (r1 <<  8) | r0);
+
+       int_1 = clk >> 16;
+       int_2 = srate >> 16;
+
+       tmp_1 = clk % 0x10000;
+       tmp_2 = srate % 0x10000;
+
+       srate = (int_1 * int_2) +
+               ((int_1 * tmp_2) >> 16) +
+               ((int_2 * tmp_1) >> 16);
+
+       return srate;
+}
+
+static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
+{
+       struct dvb_frontend *fe = &state->frontend;
+
+       int tmg_lock = 0, i;
+       s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
+       u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
+       u32 agc2th;
+
+       if (state->internal->dev_ver >= 0x30)
+               agc2th = 0x2e00;
+       else
+               agc2th = 0x1f00;
+
+       reg = STV090x_READ_DEMOD(state, DMDISTATE);
+       STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
+       if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
+               goto err;
+       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
+       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
+               goto err;
+
+       if (state->internal->dev_ver >= 0x30) {
+               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
+                       goto err;
+
+       } else if (state->internal->dev_ver >= 0x20) {
+               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
+                       goto err;
+       }
+
+       if (state->srate <= 2000000)
+               car_step = 1000;
+       else if (state->srate <= 5000000)
+               car_step = 2000;
+       else if (state->srate <= 12000000)
+               car_step = 3000;
+       else
+               car_step = 5000;
+
+       steps  = -1 + ((state->search_range / 1000) / car_step);
+       steps /= 2;
+       steps  = (2 * steps) + 1;
+       if (steps < 0)
+               steps = 1;
+       else if (steps > 10) {
+               steps = 11;
+               car_step = (state->search_range / 1000) / 10;
+       }
+       cur_step = 0;
+       dir = 1;
+       freq = state->frequency;
+
+       while ((!tmg_lock) && (cur_step < steps)) {
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
+                       goto err;
+               /* trigger acquisition */
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
+                       goto err;
+               msleep(50);
+               for (i = 0; i < 10; i++) {
+                       reg = STV090x_READ_DEMOD(state, DSTATUS);
+                       if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
+                               tmg_cpt++;
+                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+                               STV090x_READ_DEMOD(state, AGC2I0);
+               }
+               agc2 /= 10;
+               srate_coarse = stv090x_get_srate(state, state->internal->mclk);
+               cur_step++;
+               dir *= -1;
+               if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
+                   (srate_coarse < 50000000) && (srate_coarse > 850000))
+                       tmg_lock = 1;
+               else if (cur_step < steps) {
+                       if (dir > 0)
+                               freq += cur_step * car_step;
+                       else
+                               freq -= cur_step * car_step;
+
+                       /* Setup tuner */
+                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                               goto err;
+
+                       if (state->config->tuner_set_frequency) {
+                               if (state->config->tuner_set_frequency(fe, freq) < 0)
+                                       goto err_gateoff;
+                       }
+
+                       if (state->config->tuner_set_bandwidth) {
+                               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+                                       goto err_gateoff;
+                       }
+
+                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                               goto err;
+
+                       msleep(50);
+
+                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                               goto err;
+
+                       if (state->config->tuner_get_status) {
+                               if (state->config->tuner_get_status(fe, &reg) < 0)
+                                       goto err_gateoff;
+                       }
+
+                       if (reg)
+                               dprintk(FE_DEBUG, 1, "Tuner phase locked");
+                       else
+                               dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                               goto err;
+
+               }
+       }
+       if (!tmg_lock)
+               srate_coarse = 0;
+       else
+               srate_coarse = stv090x_get_srate(state, state->internal->mclk);
+
+       return srate_coarse;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
+{
+       u32 srate_coarse, freq_coarse, sym, reg;
+
+       srate_coarse = stv090x_get_srate(state, state->internal->mclk);
+       freq_coarse  = STV090x_READ_DEMOD(state, CFR2) << 8;
+       freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
+       sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+
+       if (sym < state->srate)
+               srate_coarse = 0;
+       else {
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
+                       goto err;
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+
+               if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver >= 0x30) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
+                               goto err;
+               } else if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+                               goto err;
+               }
+
+               if (srate_coarse > 3000000) {
+                       sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+                       sym  = (sym / 1000) * 65536;
+                       sym /= (state->internal->mclk / 1000);
+                       if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
+                               goto err;
+                       sym  = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
+                       sym  = (sym / 1000) * 65536;
+                       sym /= (state->internal->mclk / 1000);
+                       if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
+                               goto err;
+                       sym  = (srate_coarse / 1000) * 65536;
+                       sym /= (state->internal->mclk / 1000);
+                       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
+                               goto err;
+               } else {
+                       sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
+                       sym  = (sym / 100) * 65536;
+                       sym /= (state->internal->mclk / 100);
+                       if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
+                               goto err;
+                       sym  = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
+                       sym  = (sym / 100) * 65536;
+                       sym /= (state->internal->mclk / 100);
+                       if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
+                               goto err;
+                       sym  = (srate_coarse / 100) * 65536;
+                       sym /= (state->internal->mclk / 100);
+                       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
+                               goto err;
+               }
+               if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */
+                       goto err;
+       }
+
+       return srate_coarse;
+
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
+{
+       s32 timer = 0, lock = 0;
+       u32 reg;
+       u8 stat;
+
+       while ((timer < timeout) && (!lock)) {
+               reg = STV090x_READ_DEMOD(state, DMDSTATE);
+               stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+               switch (stat) {
+               case 0: /* searching */
+               case 1: /* first PLH detected */
+               default:
+                       dprintk(FE_DEBUG, 1, "Demodulator searching ..");
+                       lock = 0;
+                       break;
+               case 2: /* DVB-S2 mode */
+               case 3: /* DVB-S1/legacy mode */
+                       reg = STV090x_READ_DEMOD(state, DSTATUS);
+                       lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+                       break;
+               }
+
+               if (!lock)
+                       msleep(10);
+               else
+                       dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");
+
+               timer += 10;
+       }
+       return lock;
+}
+
+static int stv090x_blind_search(struct stv090x_state *state)
+{
+       u32 agc2, reg, srate_coarse;
+       s32 cpt_fail, agc2_ovflw, i;
+       u8 k_ref, k_max, k_min;
+       int coarse_fail = 0;
+       int lock;
+
+       k_max = 110;
+       k_min = 10;
+
+       agc2 = stv090x_get_agc2_min_level(state);
+
+       if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {
+               lock = 0;
+       } else {
+
+               if (state->internal->dev_ver <= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
+                               goto err;
+               } else {
+                       /* > Cut 3 */
+                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)
+                               goto err;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */
+                               goto err;
+               }
+
+               k_ref = k_max;
+               do {
+                       if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)
+                               goto err;
+                       if (stv090x_srate_srch_coarse(state) != 0) {
+                               srate_coarse = stv090x_srate_srch_fine(state);
+                               if (srate_coarse != 0) {
+                                       stv090x_get_lock_tmg(state);
+                                       lock = stv090x_get_dmdlock(state,
+                                                       state->DemodTimeout);
+                               } else {
+                                       lock = 0;
+                               }
+                       } else {
+                               cpt_fail = 0;
+                               agc2_ovflw = 0;
+                               for (i = 0; i < 10; i++) {
+                                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
+                                               STV090x_READ_DEMOD(state, AGC2I0);
+                                       if (agc2 >= 0xff00)
+                                               agc2_ovflw++;
+                                       reg = STV090x_READ_DEMOD(state, DSTATUS2);
+                                       if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&
+                                           (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))
+
+                                               cpt_fail++;
+                               }
+                               if ((cpt_fail > 7) || (agc2_ovflw > 7))
+                                       coarse_fail = 1;
+
+                               lock = 0;
+                       }
+                       k_ref -= 20;
+               } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
+       }
+
+       return lock;
+
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_chk_tmg(struct stv090x_state *state)
+{
+       u32 reg;
+       s32 tmg_cpt = 0, i;
+       u8 freq, tmg_thh, tmg_thl;
+       int tmg_lock = 0;
+
+       freq = STV090x_READ_DEMOD(state, CARFREQ);
+       tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
+       tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);
+       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
+               goto err;
+
+       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */
+       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */
+               goto err;
+       msleep(10);
+
+       for (i = 0; i < 10; i++) {
+               reg = STV090x_READ_DEMOD(state, DSTATUS);
+               if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
+                       tmg_cpt++;
+               msleep(1);
+       }
+       if (tmg_cpt >= 3)
+               tmg_lock = 1;
+
+       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)
+               goto err;
+
+       return  tmg_lock;
+
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
+{
+       struct dvb_frontend *fe = &state->frontend;
+
+       u32 reg;
+       s32 car_step, steps, cur_step, dir, freq, timeout_lock;
+       int lock = 0;
+
+       if (state->srate >= 10000000)
+               timeout_lock = timeout_dmd / 3;
+       else
+               timeout_lock = timeout_dmd / 2;
+
+       lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
+       if (!lock) {
+               if (state->srate >= 10000000) {
+                       if (stv090x_chk_tmg(state)) {
+                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+                                       goto err;
+                               lock = stv090x_get_dmdlock(state, timeout_dmd);
+                       } else {
+                               lock = 0;
+                       }
+               } else {
+                       if (state->srate <= 4000000)
+                               car_step = 1000;
+                       else if (state->srate <= 7000000)
+                               car_step = 2000;
+                       else if (state->srate <= 10000000)
+                               car_step = 3000;
+                       else
+                               car_step = 5000;
+
+                       steps  = (state->search_range / 1000) / car_step;
+                       steps /= 2;
+                       steps  = 2 * (steps + 1);
+                       if (steps < 0)
+                               steps = 2;
+                       else if (steps > 12)
+                               steps = 12;
+
+                       cur_step = 1;
+                       dir = 1;
+
+                       if (!lock) {
+                               freq = state->frequency;
+                               state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
+                               while ((cur_step <= steps) && (!lock)) {
+                                       if (dir > 0)
+                                               freq += cur_step * car_step;
+                                       else
+                                               freq -= cur_step * car_step;
+
+                                       /* Setup tuner */
+                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                                               goto err;
+
+                                       if (state->config->tuner_set_frequency) {
+                                               if (state->config->tuner_set_frequency(fe, freq) < 0)
+                                                       goto err_gateoff;
+                                       }
+
+                                       if (state->config->tuner_set_bandwidth) {
+                                               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+                                                       goto err_gateoff;
+                                       }
+
+                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                                               goto err;
+
+                                       msleep(50);
+
+                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                                               goto err;
+
+                                       if (state->config->tuner_get_status) {
+                                               if (state->config->tuner_get_status(fe, &reg) < 0)
+                                                       goto err_gateoff;
+                                       }
+
+                                       if (reg)
+                                               dprintk(FE_DEBUG, 1, "Tuner phase locked");
+                                       else
+                                               dprintk(FE_DEBUG, 1, "Tuner unlocked");
+
+                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                                               goto err;
+
+                                       STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
+                                       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
+                                               goto err;
+                                       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
+                                               goto err;
+                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                                               goto err;
+                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
+                                               goto err;
+                                       lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
+
+                                       dir *= -1;
+                                       cur_step++;
+                               }
+                       }
+               }
+       }
+
+       return lock;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)
+{
+       s32 timeout, inc, steps_max, srate, car_max;
+
+       srate = state->srate;
+       car_max = state->search_range / 1000;
+       car_max += car_max / 10;
+       car_max  = 65536 * (car_max / 2);
+       car_max /= (state->internal->mclk / 1000);
+
+       if (car_max > 0x4000)
+               car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
+
+       inc  = srate;
+       inc /= state->internal->mclk / 1000;
+       inc *= 256;
+       inc *= 256;
+       inc /= 1000;
+
+       switch (state->search_mode) {
+       case STV090x_SEARCH_DVBS1:
+       case STV090x_SEARCH_DSS:
+               inc *= 3; /* freq step = 3% of srate */
+               timeout = 20;
+               break;
+
+       case STV090x_SEARCH_DVBS2:
+               inc *= 4;
+               timeout = 25;
+               break;
+
+       case STV090x_SEARCH_AUTO:
+       default:
+               inc *= 3;
+               timeout = 25;
+               break;
+       }
+       inc /= 100;
+       if ((inc > car_max) || (inc < 0))
+               inc = car_max / 2; /* increment <= 1/8 Mclk */
+
+       timeout *= 27500; /* 27.5 Msps reference */
+       if (srate > 0)
+               timeout /= (srate / 1000);
+
+       if ((timeout > 100) || (timeout < 0))
+               timeout = 100;
+
+       steps_max = (car_max / inc) + 1; /* min steps = 3 */
+       if ((steps_max > 100) || (steps_max < 0)) {
+               steps_max = 100; /* max steps <= 100 */
+               inc = car_max / steps_max;
+       }
+       *freq_inc = inc;
+       *timeout_sw = timeout;
+       *steps = steps_max;
+
+       return 0;
+}
+
+static int stv090x_chk_signal(struct stv090x_state *state)
+{
+       s32 offst_car, agc2, car_max;
+       int no_signal;
+
+       offst_car  = STV090x_READ_DEMOD(state, CFR2) << 8;
+       offst_car |= STV090x_READ_DEMOD(state, CFR1);
+       offst_car = comp2(offst_car, 16);
+
+       agc2  = STV090x_READ_DEMOD(state, AGC2I1) << 8;
+       agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
+       car_max = state->search_range / 1000;
+
+       car_max += (car_max / 10); /* 10% margin */
+       car_max  = (65536 * car_max / 2);
+       car_max /= state->internal->mclk / 1000;
+
+       if (car_max > 0x4000)
+               car_max = 0x4000;
+
+       if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {
+               no_signal = 1;
+               dprintk(FE_DEBUG, 1, "No Signal");
+       } else {
+               no_signal = 0;
+               dprintk(FE_DEBUG, 1, "Found Signal");
+       }
+
+       return no_signal;
+}
+
+static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)
+{
+       int no_signal, lock = 0;
+       s32 cpt_step = 0, offst_freq, car_max;
+       u32 reg;
+
+       car_max  = state->search_range / 1000;
+       car_max += (car_max / 10);
+       car_max  = (65536 * car_max / 2);
+       car_max /= (state->internal->mclk / 1000);
+       if (car_max > 0x4000)
+               car_max = 0x4000;
+
+       if (zigzag)
+               offst_freq = 0;
+       else
+               offst_freq = -car_max + inc;
+
+       do {
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+                       goto err;
+
+               reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */
+               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+                       goto err;
+
+               if (zigzag) {
+                       if (offst_freq >= 0)
+                               offst_freq = -offst_freq - 2 * inc;
+                       else
+                               offst_freq = -offst_freq;
+               } else {
+                       offst_freq += 2 * inc;
+               }
+
+               cpt_step++;
+
+               lock = stv090x_get_dmdlock(state, timeout);
+               no_signal = stv090x_chk_signal(state);
+
+       } while ((!lock) &&
+                (!no_signal) &&
+                 ((offst_freq - inc) < car_max) &&
+                 ((offst_freq + inc) > -car_max) &&
+                 (cpt_step < steps_max));
+
+       reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+       STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+                       goto err;
+
+       return lock;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_sw_algo(struct stv090x_state *state)
+{
+       int no_signal, zigzag, lock = 0;
+       u32 reg;
+
+       s32 dvbs2_fly_wheel;
+       s32 inc, timeout_step, trials, steps_max;
+
+       /* get params */
+       stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);
+
+       switch (state->search_mode) {
+       case STV090x_SEARCH_DVBS1:
+       case STV090x_SEARCH_DSS:
+               /* accelerate the frequency detector */
+               if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
+                               goto err;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)
+                       goto err;
+               zigzag = 0;
+               break;
+
+       case STV090x_SEARCH_DVBS2:
+               if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+                               goto err;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
+                       goto err;
+               zigzag = 1;
+               break;
+
+       case STV090x_SEARCH_AUTO:
+       default:
+               /* accelerate the frequency detector */
+               if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+                               goto err;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)
+                       goto err;
+               zigzag = 0;
+               break;
+       }
+
+       trials = 0;
+       do {
+               lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);
+               no_signal = stv090x_chk_signal(state);
+               trials++;
+
+               /*run the SW search 2 times maximum*/
+               if (lock || no_signal || (trials == 2)) {
+                       /*Check if the demod is not losing lock in DVBS2*/
+                       if (state->internal->dev_ver >= 0x20) {
+                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
+                                       goto err;
+                       }
+
+                       reg = STV090x_READ_DEMOD(state, DMDSTATE);
+                       if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {
+                               /*Check if the demod is not losing lock in DVBS2*/
+                               msleep(timeout_step);
+                               reg = STV090x_READ_DEMOD(state, DMDFLYW);
+                               dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
+                               if (dvbs2_fly_wheel < 0xd) {     /*if correct frames is decrementing */
+                                       msleep(timeout_step);
+                                       reg = STV090x_READ_DEMOD(state, DMDFLYW);
+                                       dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
+                               }
+                               if (dvbs2_fly_wheel < 0xd) {
+                                       /*FALSE lock, The demod is losing lock */
+                                       lock = 0;
+                                       if (trials < 2) {
+                                               if (state->internal->dev_ver >= 0x20) {
+                                                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
+                                                               goto err;
+                                               }
+
+                                               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
+                                                       goto err;
+                                       }
+                               }
+                       }
+               }
+       } while ((!lock) && (trials < 2) && (!no_signal));
+
+       return lock;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)
+{
+       u32 reg;
+       enum stv090x_delsys delsys;
+
+       reg = STV090x_READ_DEMOD(state, DMDSTATE);
+       if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)
+               delsys = STV090x_DVBS2;
+       else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {
+               reg = STV090x_READ_DEMOD(state, FECM);
+               if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)
+                       delsys = STV090x_DSS;
+               else
+                       delsys = STV090x_DVBS1;
+       } else {
+               delsys = STV090x_ERROR;
+       }
+
+       return delsys;
+}
+
+/* in Hz */
+static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
+{
+       s32 derot, int_1, int_2, tmp_1, tmp_2;
+
+       derot  = STV090x_READ_DEMOD(state, CFR2) << 16;
+       derot |= STV090x_READ_DEMOD(state, CFR1) <<  8;
+       derot |= STV090x_READ_DEMOD(state, CFR0);
+
+       derot = comp2(derot, 24);
+       int_1 = mclk >> 12;
+       int_2 = derot >> 12;
+
+       /* carrier_frequency = MasterClock * Reg / 2^24 */
+       tmp_1 = mclk % 0x1000;
+       tmp_2 = derot % 0x1000;
+
+       derot = (int_1 * int_2) +
+               ((int_1 * tmp_2) >> 12) +
+               ((int_2 * tmp_1) >> 12);
+
+       return derot;
+}
+
+static int stv090x_get_viterbi(struct stv090x_state *state)
+{
+       u32 reg, rate;
+
+       reg = STV090x_READ_DEMOD(state, VITCURPUN);
+       rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);
+
+       switch (rate) {
+       case 13:
+               state->fec = STV090x_PR12;
+               break;
+
+       case 18:
+               state->fec = STV090x_PR23;
+               break;
+
+       case 21:
+               state->fec = STV090x_PR34;
+               break;
+
+       case 24:
+               state->fec = STV090x_PR56;
+               break;
+
+       case 25:
+               state->fec = STV090x_PR67;
+               break;
+
+       case 26:
+               state->fec = STV090x_PR78;
+               break;
+
+       default:
+               state->fec = STV090x_PRERR;
+               break;
+       }
+
+       return 0;
+}
+
+static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)
+{
+       struct dvb_frontend *fe = &state->frontend;
+
+       u8 tmg;
+       u32 reg;
+       s32 i = 0, offst_freq;
+
+       msleep(5);
+
+       if (state->algo == STV090x_BLIND_SEARCH) {
+               tmg = STV090x_READ_DEMOD(state, TMGREG2);
+               STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);
+               while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {
+                       tmg = STV090x_READ_DEMOD(state, TMGREG2);
+                       msleep(5);
+                       i += 5;
+               }
+       }
+       state->delsys = stv090x_get_std(state);
+
+       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+               goto err;
+
+       if (state->config->tuner_get_frequency) {
+               if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
+                       goto err_gateoff;
+       }
+
+       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+               goto err;
+
+       offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
+       state->frequency += offst_freq;
+
+       if (stv090x_get_viterbi(state) < 0)
+               goto err;
+
+       reg = STV090x_READ_DEMOD(state, DMDMODCOD);
+       state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
+       state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
+       state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;
+       reg = STV090x_READ_DEMOD(state, TMGOBS);
+       state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
+       reg = STV090x_READ_DEMOD(state, FECM);
+       state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);
+
+       if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
+
+               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                       goto err;
+
+               if (state->config->tuner_get_frequency) {
+                       if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
+                               goto err_gateoff;
+               }
+
+               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                       goto err;
+
+               if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
+                       return STV090x_RANGEOK;
+               else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
+                       return STV090x_RANGEOK;
+               else
+                       return STV090x_OUTOFRANGE; /* Out of Range */
+       } else {
+               if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
+                       return STV090x_RANGEOK;
+               else
+                       return STV090x_OUTOFRANGE;
+       }
+
+       return STV090x_OUTOFRANGE;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)
+{
+       s32 offst_tmg;
+
+       offst_tmg  = STV090x_READ_DEMOD(state, TMGREG2) << 16;
+       offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) <<  8;
+       offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);
+
+       offst_tmg = comp2(offst_tmg, 24); /* 2's complement */
+       if (!offst_tmg)
+               offst_tmg = 1;
+
+       offst_tmg  = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);
+       offst_tmg /= 320;
+
+       return offst_tmg;
+}
+
+static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)
+{
+       u8 aclc = 0x29;
+       s32 i;
+       struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
+
+       if (state->internal->dev_ver == 0x20) {
+               car_loop                = stv090x_s2_crl_cut20;
+               car_loop_qpsk_low       = stv090x_s2_lowqpsk_crl_cut20;
+               car_loop_apsk_low       = stv090x_s2_apsk_crl_cut20;
+       } else {
+               /* >= Cut 3 */
+               car_loop                = stv090x_s2_crl_cut30;
+               car_loop_qpsk_low       = stv090x_s2_lowqpsk_crl_cut30;
+               car_loop_apsk_low       = stv090x_s2_apsk_crl_cut30;
+       }
+
+       if (modcod < STV090x_QPSK_12) {
+               i = 0;
+               while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))
+                       i++;
+
+               if (i >= 3)
+                       i = 2;
+
+       } else {
+               i = 0;
+               while ((i < 14) && (modcod != car_loop[i].modcod))
+                       i++;
+
+               if (i >= 14) {
+                       i = 0;
+                       while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))
+                               i++;
+
+                       if (i >= 11)
+                               i = 10;
+               }
+       }
+
+       if (modcod <= STV090x_QPSK_25) {
+               if (pilots) {
+                       if (state->srate <= 3000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_on_2;
+                       else if (state->srate <= 7000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_on_5;
+                       else if (state->srate <= 15000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_on_10;
+                       else if (state->srate <= 25000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_on_20;
+                       else
+                               aclc = car_loop_qpsk_low[i].crl_pilots_on_30;
+               } else {
+                       if (state->srate <= 3000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_off_2;
+                       else if (state->srate <= 7000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_off_5;
+                       else if (state->srate <= 15000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_off_10;
+                       else if (state->srate <= 25000000)
+                               aclc = car_loop_qpsk_low[i].crl_pilots_off_20;
+                       else
+                               aclc = car_loop_qpsk_low[i].crl_pilots_off_30;
+               }
+
+       } else if (modcod <= STV090x_8PSK_910) {
+               if (pilots) {
+                       if (state->srate <= 3000000)
+                               aclc = car_loop[i].crl_pilots_on_2;
+                       else if (state->srate <= 7000000)
+                               aclc = car_loop[i].crl_pilots_on_5;
+                       else if (state->srate <= 15000000)
+                               aclc = car_loop[i].crl_pilots_on_10;
+                       else if (state->srate <= 25000000)
+                               aclc = car_loop[i].crl_pilots_on_20;
+                       else
+                               aclc = car_loop[i].crl_pilots_on_30;
+               } else {
+                       if (state->srate <= 3000000)
+                               aclc = car_loop[i].crl_pilots_off_2;
+                       else if (state->srate <= 7000000)
+                               aclc = car_loop[i].crl_pilots_off_5;
+                       else if (state->srate <= 15000000)
+                               aclc = car_loop[i].crl_pilots_off_10;
+                       else if (state->srate <= 25000000)
+                               aclc = car_loop[i].crl_pilots_off_20;
+                       else
+                               aclc = car_loop[i].crl_pilots_off_30;
+               }
+       } else { /* 16APSK and 32APSK */
+               if (state->srate <= 3000000)
+                       aclc = car_loop_apsk_low[i].crl_pilots_on_2;
+               else if (state->srate <= 7000000)
+                       aclc = car_loop_apsk_low[i].crl_pilots_on_5;
+               else if (state->srate <= 15000000)
+                       aclc = car_loop_apsk_low[i].crl_pilots_on_10;
+               else if (state->srate <= 25000000)
+                       aclc = car_loop_apsk_low[i].crl_pilots_on_20;
+               else
+                       aclc = car_loop_apsk_low[i].crl_pilots_on_30;
+       }
+
+       return aclc;
+}
+
+static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
+{
+       struct stv090x_short_frame_crloop *short_crl = NULL;
+       s32 index = 0;
+       u8 aclc = 0x0b;
+
+       switch (state->modulation) {
+       case STV090x_QPSK:
+       default:
+               index = 0;
+               break;
+       case STV090x_8PSK:
+               index = 1;
+               break;
+       case STV090x_16APSK:
+               index = 2;
+               break;
+       case STV090x_32APSK:
+               index = 3;
+               break;
+       }
+
+       if (state->internal->dev_ver >= 0x30) {
+               /* Cut 3.0 and up */
+               short_crl = stv090x_s2_short_crl_cut30;
+       } else {
+               /* Cut 2.0 and up: we don't support cuts older than 2.0 */
+               short_crl = stv090x_s2_short_crl_cut20;
+       }
+
+       if (state->srate <= 3000000)
+               aclc = short_crl[index].crl_2;
+       else if (state->srate <= 7000000)
+               aclc = short_crl[index].crl_5;
+       else if (state->srate <= 15000000)
+               aclc = short_crl[index].crl_10;
+       else if (state->srate <= 25000000)
+               aclc = short_crl[index].crl_20;
+       else
+               aclc = short_crl[index].crl_30;
+
+       return aclc;
+}
+
+static int stv090x_optimize_track(struct stv090x_state *state)
+{
+       struct dvb_frontend *fe = &state->frontend;
+
+       enum stv090x_modcod modcod;
+
+       s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
+       u32 reg;
+
+       srate  = stv090x_get_srate(state, state->internal->mclk);
+       srate += stv090x_get_tmgoffst(state, srate);
+
+       switch (state->delsys) {
+       case STV090x_DVBS1:
+       case STV090x_DSS:
+               if (state->search_mode == STV090x_SEARCH_AUTO) {
+                       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+                       STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+                       STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
+                       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                               goto err;
+               }
+               reg = STV090x_READ_DEMOD(state, DEMOD);
+               STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
+               STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);
+               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver >= 0x30) {
+                       if (stv090x_get_viterbi(state) < 0)
+                               goto err;
+
+                       if (state->fec == STV090x_PR12) {
+                               if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
+                                       goto err;
+                       } else {
+                               if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
+                                       goto err;
+                       }
+               }
+
+               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
+                       goto err;
+               break;
+
+       case STV090x_DVBS2:
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+               if (state->internal->dev_ver >= 0x30) {
+                       if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
+                               goto err;
+               }
+               if (state->frame_len == STV090x_LONG_FRAME) {
+                       reg = STV090x_READ_DEMOD(state, DMDMODCOD);
+                       modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
+                       pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
+                       aclc = stv090x_optimize_carloop(state, modcod, pilots);
+                       if (modcod <= STV090x_QPSK_910) {
+                               STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);
+                       } else if (modcod <= STV090x_8PSK_910) {
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
+                                       goto err;
+                       }
+                       if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {
+                               if (modcod <= STV090x_16APSK_910) {
+                                       if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                               goto err;
+                                       if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
+                                               goto err;
+                               } else {
+                                       if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                               goto err;
+                                       if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
+                                               goto err;
+                               }
+                       }
+               } else {
+                       /*Carrier loop setting for short frame*/
+                       aclc = stv090x_optimize_carloop_short(state);
+                       if (state->modulation == STV090x_QPSK) {
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)
+                                       goto err;
+                       } else if (state->modulation == STV090x_8PSK) {
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
+                                       goto err;
+                       } else if (state->modulation == STV090x_16APSK) {
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
+                                       goto err;
+                       } else if (state->modulation == STV090x_32APSK)  {
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
+                                       goto err;
+                       }
+               }
+
+               STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
+               break;
+
+       case STV090x_ERROR:
+       default:
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
+               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+               break;
+       }
+
+       f_1 = STV090x_READ_DEMOD(state, CFR2);
+       f_0 = STV090x_READ_DEMOD(state, CFR1);
+       reg = STV090x_READ_DEMOD(state, TMGOBS);
+
+       if (state->algo == STV090x_BLIND_SEARCH) {
+               STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
+               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
+               STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);
+               STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
+               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
+                       goto err;
+
+               if (stv090x_set_srate(state, srate) < 0)
+                       goto err;
+               blind_tune = 1;
+
+               if (stv090x_dvbs_track_crl(state) < 0)
+                       goto err;
+       }
+
+       if (state->internal->dev_ver >= 0x20) {
+               if ((state->search_mode == STV090x_SEARCH_DVBS1)        ||
+                   (state->search_mode == STV090x_SEARCH_DSS)          ||
+                   (state->search_mode == STV090x_SEARCH_AUTO)) {
+
+                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)
+                               goto err;
+               }
+       }
+
+       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+               goto err;
+
+       /* AUTO tracking MODE */
+       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)
+               goto err;
+       /* AUTO tracking MODE */
+       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
+               goto err;
+
+       if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||
+           (state->srate < 10000000)) {
+               /* update initial carrier freq with the found freq offset */
+               if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+                       goto err;
+               state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
+
+               if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {
+
+                       if (state->algo != STV090x_WARM_SEARCH) {
+
+                               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                                       goto err;
+
+                               if (state->config->tuner_set_bandwidth) {
+                                       if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+                                               goto err_gateoff;
+                               }
+
+                               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                                       goto err;
+
+                       }
+               }
+               if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))
+                       msleep(50); /* blind search: wait 50ms for SR stabilization */
+               else
+                       msleep(5);
+
+               stv090x_get_lock_tmg(state);
+
+               if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {
+                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+                               goto err;
+
+                       i = 0;
+
+                       while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {
+
+                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
+                                       goto err;
+                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
+                                       goto err;
+                               i++;
+                       }
+               }
+
+       }
+
+       if (state->internal->dev_ver >= 0x20) {
+               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
+                       goto err;
+       }
+
+       if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))
+               stv090x_set_vit_thtracq(state);
+
+       return 0;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)
+{
+       s32 timer = 0, lock = 0, stat;
+       u32 reg;
+
+       while ((timer < timeout) && (!lock)) {
+               reg = STV090x_READ_DEMOD(state, DMDSTATE);
+               stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+               switch (stat) {
+               case 0: /* searching */
+               case 1: /* first PLH detected */
+               default:
+                       lock = 0;
+                       break;
+
+               case 2: /* DVB-S2 mode */
+                       reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
+                       lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);
+                       break;
+
+               case 3: /* DVB-S1/legacy mode */
+                       reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
+                       lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);
+                       break;
+               }
+               if (!lock) {
+                       msleep(10);
+                       timer += 10;
+               }
+       }
+       return lock;
+}
+
+static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)
+{
+       u32 reg;
+       s32 timer = 0;
+       int lock;
+
+       lock = stv090x_get_dmdlock(state, timeout_dmd);
+       if (lock)
+               lock = stv090x_get_feclock(state, timeout_fec);
+
+       if (lock) {
+               lock = 0;
+
+               while ((timer < timeout_fec) && (!lock)) {
+                       reg = STV090x_READ_DEMOD(state, TSSTATUS);
+                       lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);
+                       msleep(1);
+                       timer++;
+               }
+       }
+
+       return lock;
+}
+
+static int stv090x_set_s2rolloff(struct stv090x_state *state)
+{
+       u32 reg;
+
+       if (state->internal->dev_ver <= 0x20) {
+               /* rolloff to auto mode if DVBS2 */
+               reg = STV090x_READ_DEMOD(state, DEMOD);
+               STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
+               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+                       goto err;
+       } else {
+               /* DVB-S2 rolloff to auto mode if DVBS2 */
+               reg = STV090x_READ_DEMOD(state, DEMOD);
+               STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);
+               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+                       goto err;
+       }
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+
+static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
+{
+       struct dvb_frontend *fe = &state->frontend;
+       enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
+       u32 reg;
+       s32 agc1_power, power_iq = 0, i;
+       int lock = 0, low_sr = 0;
+
+       reg = STV090x_READ_DEMOD(state, TSCFGH);
+       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
+       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+               goto err;
+
+       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
+               goto err;
+
+       if (state->internal->dev_ver >= 0x20) {
+               if (state->srate > 5000000) {
+                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
+                               goto err;
+               } else {
+                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
+                               goto err;
+               }
+       }
+
+       stv090x_get_lock_tmg(state);
+
+       if (state->algo == STV090x_BLIND_SEARCH) {
+               state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */
+               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
+                       goto err;
+               if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */
+                       goto err;
+       } else {
+               /* known srate */
+               if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
+                       goto err;
+               if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
+                       goto err;
+
+               if (state->srate < 2000000) {
+                       /* SR < 2MSPS */
+                       if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)
+                               goto err;
+               } else {
+                       /* SR >= 2Msps */
+                       if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
+                               goto err;
+               }
+
+               if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
+                       goto err;
+
+               if (state->internal->dev_ver >= 0x20) {
+                       if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
+                               goto err;
+                       if (state->algo == STV090x_COLD_SEARCH)
+                               state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;
+                       else if (state->algo == STV090x_WARM_SEARCH)
+                               state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;
+               }
+
+               /* if cold start or warm  (Symbolrate is known)
+                * use a Narrow symbol rate scan range
+                */
+               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */
+                       goto err;
+
+               if (stv090x_set_srate(state, state->srate) < 0)
+                       goto err;
+
+               if (stv090x_set_max_srate(state, state->internal->mclk,
+                                         state->srate) < 0)
+                       goto err;
+               if (stv090x_set_min_srate(state, state->internal->mclk,
+                                         state->srate) < 0)
+                       goto err;
+
+               if (state->srate >= 10000000)
+                       low_sr = 0;
+               else
+                       low_sr = 1;
+       }
+
+       /* Setup tuner */
+       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+               goto err;
+
+       if (state->config->tuner_set_bbgain) {
+               reg = state->config->tuner_bbgain;
+               if (reg == 0)
+                       reg = 10; /* default: 10dB */
+               if (state->config->tuner_set_bbgain(fe, reg) < 0)
+                       goto err_gateoff;
+       }
+
+       if (state->config->tuner_set_frequency) {
+               if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
+                       goto err_gateoff;
+       }
+
+       if (state->config->tuner_set_bandwidth) {
+               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
+                       goto err_gateoff;
+       }
+
+       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+               goto err;
+
+       msleep(50);
+
+       if (state->config->tuner_get_status) {
+               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                       goto err;
+               if (state->config->tuner_get_status(fe, &reg) < 0)
+                       goto err_gateoff;
+               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                       goto err;
+
+               if (reg)
+                       dprintk(FE_DEBUG, 1, "Tuner phase locked");
+               else {
+                       dprintk(FE_DEBUG, 1, "Tuner unlocked");
+                       return STV090x_NOCARRIER;
+               }
+       }
+
+       msleep(10);
+       agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
+                               STV090x_READ_DEMOD(state, AGCIQIN0));
+
+       if (agc1_power == 0) {
+               /* If AGC1 integrator value is 0
+                * then read POWERI, POWERQ
+                */
+               for (i = 0; i < 5; i++) {
+                       power_iq += (STV090x_READ_DEMOD(state, POWERI) +
+                                    STV090x_READ_DEMOD(state, POWERQ)) >> 1;
+               }
+               power_iq /= 5;
+       }
+
+       if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
+               dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
+               lock = 0;
+               signal_state = STV090x_NOAGC1;
+       } else {
+               reg = STV090x_READ_DEMOD(state, DEMOD);
+               STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
+
+               if (state->internal->dev_ver <= 0x20) {
+                       /* rolloff to auto mode if DVBS2 */
+                       STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
+               } else {
+                       /* DVB-S2 rolloff to auto mode if DVBS2 */
+                       STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);
+               }
+               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+                       goto err;
+
+               if (stv090x_delivery_search(state) < 0)
+                       goto err;
+
+               if (state->algo != STV090x_BLIND_SEARCH) {
+                       if (stv090x_start_search(state) < 0)
+                               goto err;
+               }
+       }
+
+       if (signal_state == STV090x_NOAGC1)
+               return signal_state;
+
+       if (state->algo == STV090x_BLIND_SEARCH)
+               lock = stv090x_blind_search(state);
+
+       else if (state->algo == STV090x_COLD_SEARCH)
+               lock = stv090x_get_coldlock(state, state->DemodTimeout);
+
+       else if (state->algo == STV090x_WARM_SEARCH)
+               lock = stv090x_get_dmdlock(state, state->DemodTimeout);
+
+       if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
+               if (!low_sr) {
+                       if (stv090x_chk_tmg(state))
+                               lock = stv090x_sw_algo(state);
+               }
+       }
+
+       if (lock)
+               signal_state = stv090x_get_sig_params(state);
+
+       if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
+               stv090x_optimize_track(state);
+
+               if (state->internal->dev_ver >= 0x20) {
+                       /* >= Cut 2.0 :release TS reset after
+                        * demod lock and optimized Tracking
+                        */
+                       reg = STV090x_READ_DEMOD(state, TSCFGH);
+                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
+                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+                               goto err;
+
+                       msleep(3);
+
+                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */
+                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+                               goto err;
+
+                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
+                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
+                               goto err;
+               }
+
+               lock = stv090x_get_lock(state, state->FecTimeout,
+                               state->FecTimeout);
+               if (lock) {
+                       if (state->delsys == STV090x_DVBS2) {
+                               stv090x_set_s2rolloff(state);
+
+                               reg = STV090x_READ_DEMOD(state, PDELCTRL2);
+                               STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);
+                               if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
+                                       goto err;
+                               /* Reset DVBS2 packet delinator error counter */
+                               reg = STV090x_READ_DEMOD(state, PDELCTRL2);
+                               STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);
+                               if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
+                                       goto err;
+
+                               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */
+                                       goto err;
+                       } else {
+                               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
+                                       goto err;
+                       }
+                       /* Reset the Total packet counter */
+                       if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)
+                               goto err;
+                       /* Reset the packet Error counter2 */
+                       if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
+                               goto err;
+               } else {
+                       signal_state = STV090x_NODATA;
+                       stv090x_chk_signal(state);
+               }
+       }
+       return signal_state;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       struct dtv_frontend_properties *props = &fe->dtv_property_cache;
+
+       if (props->frequency == 0)
+               return DVBFE_ALGO_SEARCH_INVALID;
+
+       state->delsys = props->delivery_system;
+       state->frequency = props->frequency;
+       state->srate = props->symbol_rate;
+       state->search_mode = STV090x_SEARCH_AUTO;
+       state->algo = STV090x_COLD_SEARCH;
+       state->fec = STV090x_PRERR;
+       if (state->srate > 10000000) {
+               dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
+               state->search_range = 10000000;
+       } else {
+               dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
+               state->search_range = 5000000;
+       }
+
+       if (stv090x_algo(state) == STV090x_RANGEOK) {
+               dprintk(FE_DEBUG, 1, "Search success!");
+               return DVBFE_ALGO_SEARCH_SUCCESS;
+       } else {
+               dprintk(FE_DEBUG, 1, "Search failed!");
+               return DVBFE_ALGO_SEARCH_FAILED;
+       }
+
+       return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg, dstatus;
+       u8 search_state;
+
+       *status = 0;
+
+       dstatus = STV090x_READ_DEMOD(state, DSTATUS);
+       if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD))
+               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+       reg = STV090x_READ_DEMOD(state, DMDSTATE);
+       search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
+
+       switch (search_state) {
+       case 0: /* searching */
+       case 1: /* first PLH detected */
+       default:
+               dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
+               break;
+
+       case 2: /* DVB-S2 mode */
+               dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
+               if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
+                       reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
+                       if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
+                               *status |= FE_HAS_VITERBI;
+                               reg = STV090x_READ_DEMOD(state, TSSTATUS);
+                               if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))
+                                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+                       }
+               }
+               break;
+
+       case 3: /* DVB-S1/legacy mode */
+               dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
+               if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
+                       reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
+                       if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
+                               *status |= FE_HAS_VITERBI;
+                               reg = STV090x_READ_DEMOD(state, TSSTATUS);
+                               if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))
+                                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+                       }
+               }
+               break;
+       }
+
+       return 0;
+}
+
+static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+
+       s32 count_4, count_3, count_2, count_1, count_0, count;
+       u32 reg, h, m, l;
+       enum fe_status status;
+
+       stv090x_read_status(fe, &status);
+       if (!(status & FE_HAS_LOCK)) {
+               *per = 1 << 23; /* Max PER */
+       } else {
+               /* Counter 2 */
+               reg = STV090x_READ_DEMOD(state, ERRCNT22);
+               h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);
+
+               reg = STV090x_READ_DEMOD(state, ERRCNT21);
+               m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);
+
+               reg = STV090x_READ_DEMOD(state, ERRCNT20);
+               l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);
+
+               *per = ((h << 16) | (m << 8) | l);
+
+               count_4 = STV090x_READ_DEMOD(state, FBERCPT4);
+               count_3 = STV090x_READ_DEMOD(state, FBERCPT3);
+               count_2 = STV090x_READ_DEMOD(state, FBERCPT2);
+               count_1 = STV090x_READ_DEMOD(state, FBERCPT1);
+               count_0 = STV090x_READ_DEMOD(state, FBERCPT0);
+
+               if ((!count_4) && (!count_3)) {
+                       count  = (count_2 & 0xff) << 16;
+                       count |= (count_1 & 0xff) <<  8;
+                       count |=  count_0 & 0xff;
+               } else {
+                       count = 1 << 24;
+               }
+               if (count == 0)
+                       *per = 1;
+       }
+       if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
+{
+       int res = 0;
+       int min = 0, med;
+
+       if ((val >= tab[min].read && val < tab[max].read) ||
+           (val >= tab[max].read && val < tab[min].read)) {
+               while ((max - min) > 1) {
+                       med = (max + min) / 2;
+                       if ((val >= tab[min].read && val < tab[med].read) ||
+                           (val >= tab[med].read && val < tab[min].read))
+                               max = med;
+                       else
+                               min = med;
+               }
+               res = ((val - tab[min].read) *
+                      (tab[max].real - tab[min].real) /
+                      (tab[max].read - tab[min].read)) +
+                       tab[min].real;
+       } else {
+               if (tab[min].read < tab[max].read) {
+                       if (val < tab[min].read)
+                               res = tab[min].real;
+                       else if (val >= tab[max].read)
+                               res = tab[max].real;
+               } else {
+                       if (val >= tab[min].read)
+                               res = tab[min].real;
+                       else if (val < tab[max].read)
+                               res = tab[max].real;
+               }
+       }
+
+       return res;
+}
+
+static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg;
+       s32 agc_0, agc_1, agc;
+       s32 str;
+
+       reg = STV090x_READ_DEMOD(state, AGCIQIN1);
+       agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+       reg = STV090x_READ_DEMOD(state, AGCIQIN0);
+       agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
+       agc = MAKEWORD16(agc_1, agc_0);
+
+       str = stv090x_table_lookup(stv090x_rf_tab,
+               ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
+       if (agc > stv090x_rf_tab[0].read)
+               str = 0;
+       else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
+               str = -100;
+       *strength = (str + 100) * 0xFFFF / 100;
+
+       return 0;
+}
+
+static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg_0, reg_1, reg, i;
+       s32 val_0, val_1, val = 0;
+       u8 lock_f;
+       s32 div;
+       u32 last;
+
+       switch (state->delsys) {
+       case STV090x_DVBS2:
+               reg = STV090x_READ_DEMOD(state, DSTATUS);
+               lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+               if (lock_f) {
+                       msleep(5);
+                       for (i = 0; i < 16; i++) {
+                               reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
+                               val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
+                               reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
+                               val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
+                               val  += MAKEWORD16(val_1, val_0);
+                               msleep(1);
+                       }
+                       val /= 16;
+                       last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
+                       div = stv090x_s2cn_tab[0].read -
+                             stv090x_s2cn_tab[last].read;
+                       *cnr = 0xFFFF - ((val * 0xFFFF) / div);
+               }
+               break;
+
+       case STV090x_DVBS1:
+       case STV090x_DSS:
+               reg = STV090x_READ_DEMOD(state, DSTATUS);
+               lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
+               if (lock_f) {
+                       msleep(5);
+                       for (i = 0; i < 16; i++) {
+                               reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
+                               val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
+                               reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
+                               val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
+                               val  += MAKEWORD16(val_1, val_0);
+                               msleep(1);
+                       }
+                       val /= 16;
+                       last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
+                       div = stv090x_s1cn_tab[0].read -
+                             stv090x_s1cn_tab[last].read;
+                       *cnr = 0xFFFF - ((val * 0xFFFF) / div);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg;
+
+       reg = STV090x_READ_DEMOD(state, DISTXCTL);
+       switch (tone) {
+       case SEC_TONE_ON:
+               STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
+               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+                       goto err;
+               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+                       goto err;
+               break;
+
+       case SEC_TONE_OFF:
+               STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
+               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+                       goto err;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+
+static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)
+{
+       return DVBFE_ALGO_CUSTOM;
+}
+
+static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg, idle = 0, fifo_full = 1;
+       int i;
+
+       reg = STV090x_READ_DEMOD(state, DISTXCTL);
+
+       STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
+               (state->config->diseqc_envelope_mode) ? 4 : 2);
+       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       for (i = 0; i < cmd->msg_len; i++) {
+
+               while (fifo_full) {
+                       reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+                       fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
+               }
+
+               if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)
+                       goto err;
+       }
+       reg = STV090x_READ_DEMOD(state, DISTXCTL);
+       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       i = 0;
+
+       while ((!idle) && (i < 10)) {
+               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+               idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
+               msleep(10);
+               i++;
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg, idle = 0, fifo_full = 1;
+       u8 mode, value;
+       int i;
+
+       reg = STV090x_READ_DEMOD(state, DISTXCTL);
+
+       if (burst == SEC_MINI_A) {
+               mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
+               value = 0x00;
+       } else {
+               mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
+               value = 0xFF;
+       }
+
+       STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);
+       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       while (fifo_full) {
+               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+               fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
+       }
+
+       if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)
+               goto err;
+
+       reg = STV090x_READ_DEMOD(state, DISTXCTL);
+       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
+       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
+               goto err;
+
+       i = 0;
+
+       while ((!idle) && (i < 10)) {
+               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
+               idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
+               msleep(10);
+               i++;
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg = 0, i = 0, rx_end = 0;
+
+       while ((rx_end != 1) && (i < 10)) {
+               msleep(10);
+               i++;
+               reg = STV090x_READ_DEMOD(state, DISRX_ST0);
+               rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);
+       }
+
+       if (rx_end) {
+               reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);
+               for (i = 0; i < reply->msg_len; i++)
+                       reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);
+       }
+
+       return 0;
+}
+
+static int stv090x_sleep(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg;
+       u8 full_standby = 0;
+
+       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+               goto err;
+
+       if (state->config->tuner_sleep) {
+               if (state->config->tuner_sleep(fe) < 0)
+                       goto err_gateoff;
+       }
+
+       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+               goto err;
+
+       dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
+               state->device == STV0900 ? "STV0900" : "STV0903",
+               state->demod);
+
+       mutex_lock(&state->internal->demod_lock);
+
+       switch (state->demod) {
+       case STV090x_DEMODULATOR_0:
+               /* power off ADC 1 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+               STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+                       goto err;
+               /* power off DiSEqC 1 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR2);
+               STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
+                       goto err;
+
+               /* check whether path 2 is already sleeping, that is when
+                  ADC2 is off */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
+               if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
+                       full_standby = 1;
+
+               /* stop clocks */
+               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
+               /* packet delineator 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
+               /* ADC 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
+               /* FEC clock is shared between the two paths, only stop it
+                  when full standby is possible */
+               if (full_standby)
+                       STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
+                       goto err;
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               /* sampling 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
+               /* viterbi 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
+               /* TS clock is shared between the two paths, only stop it
+                  when full standby is possible */
+               if (full_standby)
+                       STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_DEMODULATOR_1:
+               /* power off ADC 2 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
+               STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
+                       goto err;
+               /* power off DiSEqC 2 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR4);
+               STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
+                       goto err;
+
+               /* check whether path 1 is already sleeping, that is when
+                  ADC1 is off */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+               if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
+                       full_standby = 1;
+
+               /* stop clocks */
+               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
+               /* packet delineator 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
+               /* ADC 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
+               /* FEC clock is shared between the two paths, only stop it
+                  when full standby is possible */
+               if (full_standby)
+                       STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
+                       goto err;
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               /* sampling 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
+               /* viterbi 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
+               /* TS clock is shared between the two paths, only stop it
+                  when full standby is possible */
+               if (full_standby)
+                       STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               break;
+
+       default:
+               dprintk(FE_ERROR, 1, "Wrong demodulator!");
+               break;
+       }
+
+       if (full_standby) {
+               /* general power off */
+               reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+               STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
+               if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
+                       goto err;
+       }
+
+       mutex_unlock(&state->internal->demod_lock);
+       return 0;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       mutex_unlock(&state->internal->demod_lock);
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_wakeup(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u32 reg;
+
+       dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
+               state->device == STV0900 ? "STV0900" : "STV0903",
+               state->demod);
+
+       mutex_lock(&state->internal->demod_lock);
+
+       /* general power on */
+       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+       STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
+       if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
+               goto err;
+
+       switch (state->demod) {
+       case STV090x_DEMODULATOR_0:
+               /* power on ADC 1 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+               STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+                       goto err;
+               /* power on DiSEqC 1 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR2);
+               STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
+                       goto err;
+
+               /* activate clocks */
+               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
+               /* packet delineator 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
+               /* ADC 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
+               /* FEC clock */
+               STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
+                       goto err;
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               /* sampling 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
+               /* viterbi 1 clock */
+               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
+               /* TS clock */
+               STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_DEMODULATOR_1:
+               /* power on ADC 2 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
+               STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
+                       goto err;
+               /* power on DiSEqC 2 */
+               reg = stv090x_read_reg(state, STV090x_TSTTNR4);
+               STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
+               if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
+                       goto err;
+
+               /* activate clocks */
+               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
+               /* packet delineator 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
+               /* ADC 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
+               /* FEC clock */
+               STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
+                       goto err;
+               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
+               /* sampling 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
+               /* viterbi 2 clock */
+               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
+               /* TS clock */
+               STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
+               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
+                       goto err;
+               break;
+
+       default:
+               dprintk(FE_ERROR, 1, "Wrong demodulator!");
+               break;
+       }
+
+       mutex_unlock(&state->internal->demod_lock);
+       return 0;
+err:
+       mutex_unlock(&state->internal->demod_lock);
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static void stv090x_release(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+
+       state->internal->num_used--;
+       if (state->internal->num_used <= 0) {
+
+               dprintk(FE_ERROR, 1, "Actually removing");
+
+               remove_dev(state->internal);
+               kfree(state->internal);
+       }
+
+       kfree(state);
+}
+
+static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)
+{
+       u32 reg = 0;
+
+       reg = stv090x_read_reg(state, STV090x_GENCFG);
+
+       switch (ldpc_mode) {
+       case STV090x_DUAL:
+       default:
+               if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {
+                       /* set LDPC to dual mode */
+                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)
+                               goto err;
+
+                       state->demod_mode = STV090x_DUAL;
+
+                       reg = stv090x_read_reg(state, STV090x_TSTRES0);
+                       STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
+                       if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+                               goto err;
+                       STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
+                       if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+                               goto err;
+
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
+                               goto err;
+
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
+                               goto err;
+
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
+                               goto err;
+                       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
+                               goto err;
+               }
+               break;
+
+       case STV090x_SINGLE:
+               if (stv090x_stop_modcod(state) < 0)
+                       goto err;
+               if (stv090x_activate_modcod_single(state) < 0)
+                       goto err;
+
+               if (state->demod == STV090x_DEMODULATOR_1) {
+                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */
+                               goto err;
+               } else {
+                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */
+                               goto err;
+               }
+
+               reg = stv090x_read_reg(state, STV090x_TSTRES0);
+               STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
+               if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+                       goto err;
+               STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
+               if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
+                       goto err;
+
+               reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);
+               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+                       goto err;
+               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);
+               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+                       goto err;
+               break;
+       }
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+/* return (Hz), clk in Hz*/
+static u32 stv090x_get_mclk(struct stv090x_state *state)
+{
+       const struct stv090x_config *config = state->config;
+       u32 div, reg;
+       u8 ratio;
+
+       div = stv090x_read_reg(state, STV090x_NCOARSE);
+       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+       ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;
+
+       return (div + 1) * config->xtal / ratio; /* kHz */
+}
+
+static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
+{
+       const struct stv090x_config *config = state->config;
+       u32 reg, div, clk_sel;
+
+       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
+       clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);
+
+       div = ((clk_sel * mclk) / config->xtal) - 1;
+
+       reg = stv090x_read_reg(state, STV090x_NCOARSE);
+       STV090x_SETFIELD(reg, M_DIV_FIELD, div);
+       if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
+               goto err;
+
+       state->internal->mclk = stv090x_get_mclk(state);
+
+       /*Set the DiseqC frequency to 22KHz */
+       div = state->internal->mclk / 704000;
+       if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
+               goto err;
+       if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_set_tspath(struct stv090x_state *state)
+{
+       u32 reg;
+
+       if (state->internal->dev_ver >= 0x20) {
+               switch (state->config->ts1_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+                       switch (state->config->ts2_mode) {
+                       case STV090x_TSMODE_SERIAL_PUNCTURED:
+                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       default:
+                               stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
+                               break;
+
+                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+                       case STV090x_TSMODE_DVBCI:
+                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */
+                                       goto err;
+                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+                                       goto err;
+                               reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
+                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+                               if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
+                                       goto err;
+                               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
+                                       goto err;
+                               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
+                                       goto err;
+                               break;
+                       }
+                       break;
+
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+               default:
+                       switch (state->config->ts2_mode) {
+                       case STV090x_TSMODE_SERIAL_PUNCTURED:
+                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       default:
+                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
+                                       goto err;
+                               break;
+
+                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+                       case STV090x_TSMODE_DVBCI:
+                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)
+                                       goto err;
+                               break;
+                       }
+                       break;
+               }
+       } else {
+               switch (state->config->ts1_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+                       switch (state->config->ts2_mode) {
+                       case STV090x_TSMODE_SERIAL_PUNCTURED:
+                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       default:
+                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
+                               break;
+
+                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+                       case STV090x_TSMODE_DVBCI:
+                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);
+                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+                                       goto err;
+                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);
+                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+                                       goto err;
+                               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
+                                       goto err;
+                               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
+                                       goto err;
+                               break;
+                       }
+                       break;
+
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+               default:
+                       switch (state->config->ts2_mode) {
+                       case STV090x_TSMODE_SERIAL_PUNCTURED:
+                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       default:
+                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
+                               break;
+
+                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+                       case STV090x_TSMODE_DVBCI:
+                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       switch (state->config->ts1_mode) {
+       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_DVBCI:
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_SERIAL_PUNCTURED:
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       default:
+               break;
+       }
+
+       switch (state->config->ts2_mode) {
+       case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_DVBCI:
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_SERIAL_PUNCTURED:
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       case STV090x_TSMODE_SERIAL_CONTINUOUS:
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
+               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
+               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+                       goto err;
+               break;
+
+       default:
+               break;
+       }
+
+       if (state->config->ts1_clk > 0) {
+               u32 speed;
+
+               switch (state->config->ts1_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+               default:
+                       speed = state->internal->mclk /
+                               (state->config->ts1_clk / 4);
+                       if (speed < 0x08)
+                               speed = 0x08;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       speed = state->internal->mclk /
+                               (state->config->ts1_clk / 32);
+                       if (speed < 0x20)
+                               speed = 0x20;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               }
+               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
+               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
+                       goto err;
+               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
+                       goto err;
+       }
+
+       if (state->config->ts2_clk > 0) {
+               u32 speed;
+
+               switch (state->config->ts2_mode) {
+               case STV090x_TSMODE_PARALLEL_PUNCTURED:
+               case STV090x_TSMODE_DVBCI:
+               default:
+                       speed = state->internal->mclk /
+                               (state->config->ts2_clk / 4);
+                       if (speed < 0x08)
+                               speed = 0x08;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               case STV090x_TSMODE_SERIAL_PUNCTURED:
+               case STV090x_TSMODE_SERIAL_CONTINUOUS:
+                       speed = state->internal->mclk /
+                               (state->config->ts2_clk / 32);
+                       if (speed < 0x20)
+                               speed = 0x20;
+                       if (speed > 0xFF)
+                               speed = 0xFF;
+                       break;
+               }
+               reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
+               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
+               if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
+                       goto err;
+               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
+                       goto err;
+       }
+
+       reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
+       if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+               goto err;
+       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
+       if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
+               goto err;
+
+       reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
+       if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+               goto err;
+       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
+       if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_init(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       const struct stv090x_config *config = state->config;
+       u32 reg;
+
+       if (state->internal->mclk == 0) {
+               /* call tuner init to configure the tuner's clock output
+                  divider directly before setting up the master clock of
+                  the stv090x. */
+               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+                       goto err;
+
+               if (config->tuner_init) {
+                       if (config->tuner_init(fe) < 0)
+                               goto err_gateoff;
+               }
+
+               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+                       goto err;
+
+               stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
+               msleep(5);
+               if (stv090x_write_reg(state, STV090x_SYNTCTRL,
+                                     0x20 | config->clk_mode) < 0)
+                       goto err;
+               stv090x_get_mclk(state);
+       }
+
+       if (stv090x_wakeup(fe) < 0) {
+               dprintk(FE_ERROR, 1, "Error waking device");
+               goto err;
+       }
+
+       if (stv090x_ldpc_mode(state, state->demod_mode) < 0)
+               goto err;
+
+       reg = STV090x_READ_DEMOD(state, TNRCFG2);
+       STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);
+       if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)
+               goto err;
+       reg = STV090x_READ_DEMOD(state, DEMOD);
+       STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
+       if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
+               goto err;
+
+       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
+               goto err;
+
+       if (config->tuner_set_mode) {
+               if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
+                       goto err_gateoff;
+       }
+
+       if (config->tuner_init) {
+               if (config->tuner_init(fe) < 0)
+                       goto err_gateoff;
+       }
+
+       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
+               goto err;
+
+       if (stv090x_set_tspath(state) < 0)
+               goto err;
+
+       return 0;
+
+err_gateoff:
+       stv090x_i2c_gate_ctrl(state, 0);
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+static int stv090x_setup(struct dvb_frontend *fe)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       const struct stv090x_config *config = state->config;
+       const struct stv090x_reg *stv090x_initval = NULL;
+       const struct stv090x_reg *stv090x_cut20_val = NULL;
+       unsigned long t1_size = 0, t2_size = 0;
+       u32 reg = 0;
+
+       int i;
+
+       if (state->device == STV0900) {
+               dprintk(FE_DEBUG, 1, "Initializing STV0900");
+               stv090x_initval = stv0900_initval;
+               t1_size = ARRAY_SIZE(stv0900_initval);
+               stv090x_cut20_val = stv0900_cut20_val;
+               t2_size = ARRAY_SIZE(stv0900_cut20_val);
+       } else if (state->device == STV0903) {
+               dprintk(FE_DEBUG, 1, "Initializing STV0903");
+               stv090x_initval = stv0903_initval;
+               t1_size = ARRAY_SIZE(stv0903_initval);
+               stv090x_cut20_val = stv0903_cut20_val;
+               t2_size = ARRAY_SIZE(stv0903_cut20_val);
+       }
+
+       /* STV090x init */
+
+       /* Stop Demod */
+       if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
+               goto err;
+       if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
+               goto err;
+
+       msleep(5);
+
+       /* Set No Tuner Mode */
+       if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
+               goto err;
+       if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
+               goto err;
+
+       /* I2C repeater OFF */
+       STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
+       if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
+               goto err;
+       if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
+               goto err;
+
+       if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
+               goto err;
+       msleep(5);
+       if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */
+               goto err;
+       if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */
+               goto err;
+       msleep(5);
+
+       /* write initval */
+       dprintk(FE_DEBUG, 1, "Setting up initial values");
+       for (i = 0; i < t1_size; i++) {
+               if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)
+                       goto err;
+       }
+
+       state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
+       if (state->internal->dev_ver >= 0x20) {
+               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
+                       goto err;
+
+               /* write cut20_val*/
+               dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");
+               for (i = 0; i < t2_size; i++) {
+                       if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)
+                               goto err;
+               }
+
+       } else if (state->internal->dev_ver < 0x20) {
+               dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
+                       state->internal->dev_ver);
+
+               goto err;
+       } else if (state->internal->dev_ver > 0x30) {
+               /* we shouldn't bail out from here */
+               dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
+                       state->internal->dev_ver);
+       }
+
+       /* ADC1 range */
+       reg = stv090x_read_reg(state, STV090x_TSTTNR1);
+       STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,
+               (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);
+       if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
+               goto err;
+
+       /* ADC2 range */
+       reg = stv090x_read_reg(state, STV090x_TSTTNR3);
+       STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,
+               (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);
+       if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
+               goto err;
+
+       if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
+               goto err;
+       if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
+               goto err;
+
+       return 0;
+err:
+       dprintk(FE_ERROR, 1, "I/O error");
+       return -1;
+}
+
+int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
+               u8 xor_value)
+{
+       struct stv090x_state *state = fe->demodulator_priv;
+       u8 reg = 0;
+
+       STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
+       STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
+       STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
+
+       return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
+}
+EXPORT_SYMBOL(stv090x_set_gpio);
+
+static struct dvb_frontend_ops stv090x_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
+       .info = {
+               .name                   = "STV090x Multistandard",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 0,
+               .frequency_tolerance    = 0,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+               .caps                   = FE_CAN_INVERSION_AUTO |
+                                         FE_CAN_FEC_AUTO       |
+                                         FE_CAN_QPSK           |
+                                         FE_CAN_2G_MODULATION
+       },
+
+       .release                        = stv090x_release,
+       .init                           = stv090x_init,
+
+       .sleep                          = stv090x_sleep,
+       .get_frontend_algo              = stv090x_frontend_algo,
+
+       .diseqc_send_master_cmd         = stv090x_send_diseqc_msg,
+       .diseqc_send_burst              = stv090x_send_diseqc_burst,
+       .diseqc_recv_slave_reply        = stv090x_recv_slave_reply,
+       .set_tone                       = stv090x_set_tone,
+
+       .search                         = stv090x_search,
+       .read_status                    = stv090x_read_status,
+       .read_ber                       = stv090x_read_per,
+       .read_signal_strength           = stv090x_read_signal_strength,
+       .read_snr                       = stv090x_read_cnr,
+};
+
+
+struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+                                   struct i2c_adapter *i2c,
+                                   enum stv090x_demodulator demod)
+{
+       struct stv090x_state *state = NULL;
+       struct stv090x_dev *temp_int;
+
+       state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->verbose                          = &verbose;
+       state->config                           = config;
+       state->i2c                              = i2c;
+       state->frontend.ops                     = stv090x_ops;
+       state->frontend.demodulator_priv        = state;
+       state->demod                            = demod;
+       state->demod_mode                       = config->demod_mode; /* Single or Dual mode */
+       state->device                           = config->device;
+       state->rolloff                          = STV090x_RO_35; /* default */
+
+       temp_int = find_dev(state->i2c,
+                               state->config->address);
+
+       if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
+               state->internal = temp_int->internal;
+               state->internal->num_used++;
+               dprintk(FE_INFO, 1, "Found Internal Structure!");
+       } else {
+               state->internal = kmalloc(sizeof(struct stv090x_internal),
+                                         GFP_KERNEL);
+               if (!state->internal)
+                       goto error;
+               temp_int = append_internal(state->internal);
+               if (!temp_int) {
+                       kfree(state->internal);
+                       goto error;
+               }
+               state->internal->num_used = 1;
+               state->internal->mclk = 0;
+               state->internal->dev_ver = 0;
+               state->internal->i2c_adap = state->i2c;
+               state->internal->i2c_addr = state->config->address;
+               dprintk(FE_INFO, 1, "Create New Internal Structure!");
+
+               mutex_init(&state->internal->demod_lock);
+               mutex_init(&state->internal->tuner_lock);
+
+               if (stv090x_setup(&state->frontend) < 0) {
+                       dprintk(FE_ERROR, 1, "Error setting up device");
+                       goto err_remove;
+               }
+       }
+
+       /* workaround for stuck DiSEqC output */
+       if (config->diseqc_envelope_mode)
+               stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
+
+       dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
+              state->device == STV0900 ? "STV0900" : "STV0903",
+              demod,
+              state->internal->dev_ver);
+
+       return &state->frontend;
+
+err_remove:
+       remove_dev(state->internal);
+       kfree(state->internal);
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(stv090x_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stv090x.h b/drivers/media/dvb-frontends/stv090x.h
new file mode 100644 (file)
index 0000000..29cdc2b
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+       STV0900/0903 Multistandard Broadcast Frontend driver
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV090x_H
+#define __STV090x_H
+
+enum stv090x_demodulator {
+       STV090x_DEMODULATOR_0 = 1,
+       STV090x_DEMODULATOR_1
+};
+
+enum stv090x_device {
+       STV0903 =  0,
+       STV0900,
+};
+
+enum stv090x_mode {
+       STV090x_DUAL = 0,
+       STV090x_SINGLE
+};
+
+enum stv090x_tsmode {
+       STV090x_TSMODE_SERIAL_PUNCTURED = 1,
+       STV090x_TSMODE_SERIAL_CONTINUOUS,
+       STV090x_TSMODE_PARALLEL_PUNCTURED,
+       STV090x_TSMODE_DVBCI
+};
+
+enum stv090x_clkmode {
+       STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
+       STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
+};
+
+enum stv090x_i2crpt {
+       STV090x_RPTLEVEL_256    = 0,
+       STV090x_RPTLEVEL_128    = 1,
+       STV090x_RPTLEVEL_64     = 2,
+       STV090x_RPTLEVEL_32     = 3,
+       STV090x_RPTLEVEL_16     = 4,
+       STV090x_RPTLEVEL_8      = 5,
+       STV090x_RPTLEVEL_4      = 6,
+       STV090x_RPTLEVEL_2      = 7,
+};
+
+enum stv090x_adc_range {
+       STV090x_ADC_2Vpp        = 0,
+       STV090x_ADC_1Vpp        = 1
+};
+
+struct stv090x_config {
+       enum stv090x_device     device;
+       enum stv090x_mode       demod_mode;
+       enum stv090x_clkmode    clk_mode;
+
+       u32 xtal; /* default: 8000000 */
+       u8 address; /* default: 0x68 */
+
+       u8 ts1_mode;
+       u8 ts2_mode;
+       u32 ts1_clk;
+       u32 ts2_clk;
+
+       u8 ts1_tei : 1;
+       u8 ts2_tei : 1;
+
+       enum stv090x_i2crpt     repeater_level;
+
+       u8                      tuner_bbgain; /* default: 10db */
+       enum stv090x_adc_range  adc1_range; /* default: 2Vpp */
+       enum stv090x_adc_range  adc2_range; /* default: 2Vpp */
+
+       bool diseqc_envelope_mode;
+
+       int (*tuner_init) (struct dvb_frontend *fe);
+       int (*tuner_sleep) (struct dvb_frontend *fe);
+       int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
+       int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
+       int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
+       int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
+       int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
+       int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
+       int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
+       int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk);
+       int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
+       void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
+};
+
+#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+                                          struct i2c_adapter *i2c,
+                                          enum stv090x_demodulator demod);
+
+/* dir = 0 -> output, dir = 1 -> input/open-drain */
+extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
+               u8 dir, u8 value, u8 xor_value);
+
+#else
+
+static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
+                                                 struct i2c_adapter *i2c,
+                                                 enum stv090x_demodulator demod)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
+               u8 opd, u8 value, u8 xor_value)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -ENODEV;
+}
+#endif /* CONFIG_DVB_STV090x */
+
+#endif /* __STV090x_H */
diff --git a/drivers/media/dvb-frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h
new file mode 100644 (file)
index 0000000..5b780c8
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+       STV0900/0903 Multistandard Broadcast Frontend driver
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV090x_PRIV_H
+#define __STV090x_PRIV_H
+
+#include "dvb_frontend.h"
+
+#define FE_ERROR                               0
+#define FE_NOTICE                              1
+#define FE_INFO                                        2
+#define FE_DEBUG                               3
+#define FE_DEBUGREG                            4
+
+#define dprintk(__y, __z, format, arg...) do {                                         \
+       if (__z) {                                                                      \
+               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
+               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((verbose > FE_INFO) && (verbose > __y))                        \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
+               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (verbose > __y)                                                      \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while (0)
+
+#define STV090x_READ_DEMOD(__state, __reg) ((                  \
+       (__state)->demod == STV090x_DEMODULATOR_1)      ?       \
+       stv090x_read_reg(__state, STV090x_P2_##__reg) :         \
+       stv090x_read_reg(__state, STV090x_P1_##__reg))
+
+#define STV090x_WRITE_DEMOD(__state, __reg, __data) ((         \
+       (__state)->demod == STV090x_DEMODULATOR_1)      ?       \
+       stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
+       stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
+
+#define STV090x_ADDR_OFFST(__state, __x) ((                    \
+       (__state->demod) == STV090x_DEMODULATOR_1)      ?       \
+               STV090x_P1_##__x :                              \
+               STV090x_P2_##__x)
+
+
+#define STV090x_SETFIELD(mask, bitf, val)      (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
+                                                        STV090x_OFFST_##bitf))) | \
+                                                        (val << STV090x_OFFST_##bitf))
+
+#define STV090x_GETFIELD(val, bitf)            ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
+
+
+#define STV090x_SETFIELD_Px(mask, bitf, val)   (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
+                                                        STV090x_OFFST_Px_##bitf))) | \
+                                                        (val << STV090x_OFFST_Px_##bitf))
+
+#define STV090x_GETFIELD_Px(val, bitf)         ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
+
+#define MAKEWORD16(__a, __b)                   (((__a) << 8) | (__b))
+
+#define MSB(__x)                               ((__x >> 8) & 0xff)
+#define LSB(__x)                               (__x & 0xff)
+
+
+#define STV090x_IQPOWER_THRESHOLD        30
+#define STV090x_SEARCH_AGC2_TH_CUT20    700
+#define STV090x_SEARCH_AGC2_TH_CUT30   1400
+
+#define STV090x_SEARCH_AGC2_TH(__ver)  \
+       ((__ver <= 0x20) ?              \
+       STV090x_SEARCH_AGC2_TH_CUT20 :  \
+       STV090x_SEARCH_AGC2_TH_CUT30)
+
+enum stv090x_signal_state {
+       STV090x_NOAGC1,
+       STV090x_NOCARRIER,
+       STV090x_NODATA,
+       STV090x_DATAOK,
+       STV090x_RANGEOK,
+       STV090x_OUTOFRANGE
+};
+
+enum stv090x_fec {
+       STV090x_PR12 = 0,
+       STV090x_PR23,
+       STV090x_PR34,
+       STV090x_PR45,
+       STV090x_PR56,
+       STV090x_PR67,
+       STV090x_PR78,
+       STV090x_PR89,
+       STV090x_PR910,
+       STV090x_PRERR
+};
+
+enum stv090x_modulation {
+       STV090x_QPSK,
+       STV090x_8PSK,
+       STV090x_16APSK,
+       STV090x_32APSK,
+       STV090x_UNKNOWN
+};
+
+enum stv090x_frame {
+       STV090x_LONG_FRAME,
+       STV090x_SHORT_FRAME
+};
+
+enum stv090x_pilot {
+       STV090x_PILOTS_OFF,
+       STV090x_PILOTS_ON
+};
+
+enum stv090x_rolloff {
+       STV090x_RO_35,
+       STV090x_RO_25,
+       STV090x_RO_20
+};
+
+enum stv090x_inversion {
+       STV090x_IQ_AUTO,
+       STV090x_IQ_NORMAL,
+       STV090x_IQ_SWAP
+};
+
+enum stv090x_modcod {
+       STV090x_DUMMY_PLF = 0,
+       STV090x_QPSK_14,
+       STV090x_QPSK_13,
+       STV090x_QPSK_25,
+       STV090x_QPSK_12,
+       STV090x_QPSK_35,
+       STV090x_QPSK_23,
+       STV090x_QPSK_34,
+       STV090x_QPSK_45,
+       STV090x_QPSK_56,
+       STV090x_QPSK_89,
+       STV090x_QPSK_910,
+       STV090x_8PSK_35,
+       STV090x_8PSK_23,
+       STV090x_8PSK_34,
+       STV090x_8PSK_56,
+       STV090x_8PSK_89,
+       STV090x_8PSK_910,
+       STV090x_16APSK_23,
+       STV090x_16APSK_34,
+       STV090x_16APSK_45,
+       STV090x_16APSK_56,
+       STV090x_16APSK_89,
+       STV090x_16APSK_910,
+       STV090x_32APSK_34,
+       STV090x_32APSK_45,
+       STV090x_32APSK_56,
+       STV090x_32APSK_89,
+       STV090x_32APSK_910,
+       STV090x_MODCODE_UNKNOWN
+};
+
+enum stv090x_search {
+       STV090x_SEARCH_DSS = 0,
+       STV090x_SEARCH_DVBS1,
+       STV090x_SEARCH_DVBS2,
+       STV090x_SEARCH_AUTO
+};
+
+enum stv090x_algo {
+       STV090x_BLIND_SEARCH,
+       STV090x_COLD_SEARCH,
+       STV090x_WARM_SEARCH
+};
+
+enum stv090x_delsys {
+       STV090x_ERROR = 0,
+       STV090x_DVBS1 = 1,
+       STV090x_DVBS2,
+       STV090x_DSS
+};
+
+struct stv090x_long_frame_crloop {
+       enum stv090x_modcod     modcod;
+
+       u8 crl_pilots_on_2;
+       u8 crl_pilots_off_2;
+       u8 crl_pilots_on_5;
+       u8 crl_pilots_off_5;
+       u8 crl_pilots_on_10;
+       u8 crl_pilots_off_10;
+       u8 crl_pilots_on_20;
+       u8 crl_pilots_off_20;
+       u8 crl_pilots_on_30;
+       u8 crl_pilots_off_30;
+};
+
+struct stv090x_short_frame_crloop {
+       enum stv090x_modulation modulation;
+
+       u8 crl_2;  /*      SR <   3M */
+       u8 crl_5;  /*  3 < SR <=  7M */
+       u8 crl_10; /*  7 < SR <= 15M */
+       u8 crl_20; /* 10 < SR <= 25M */
+       u8 crl_30; /* 10 < SR <= 45M */
+};
+
+struct stv090x_reg {
+       u16 addr;
+       u8  data;
+};
+
+struct stv090x_tab {
+       s32 real;
+       s32 read;
+};
+
+struct stv090x_internal {
+       struct i2c_adapter      *i2c_adap;
+       u8                      i2c_addr;
+
+       struct mutex            demod_lock; /* Lock access to shared register */
+       struct mutex            tuner_lock; /* Lock access to tuners */
+       s32                     mclk; /* Masterclock Divider factor */
+       u32                     dev_ver;
+
+       int                     num_used;
+};
+
+struct stv090x_state {
+       enum stv090x_device             device;
+       enum stv090x_demodulator        demod;
+       enum stv090x_mode               demod_mode;
+       struct stv090x_internal         *internal;
+
+       struct i2c_adapter              *i2c;
+       const struct stv090x_config     *config;
+       struct dvb_frontend             frontend;
+
+       u32                             *verbose; /* Cached module verbosity */
+
+       enum stv090x_delsys             delsys;
+       enum stv090x_fec                fec;
+       enum stv090x_modulation         modulation;
+       enum stv090x_modcod             modcod;
+       enum stv090x_search             search_mode;
+       enum stv090x_frame              frame_len;
+       enum stv090x_pilot              pilots;
+       enum stv090x_rolloff            rolloff;
+       enum stv090x_inversion          inversion;
+       enum stv090x_algo               algo;
+
+       u32                             frequency;
+       u32                             srate;
+
+       s32                             tuner_bw;
+
+       s32                             search_range;
+
+       s32                             DemodTimeout;
+       s32                             FecTimeout;
+};
+
+#endif /* __STV090x_PRIV_H */
diff --git a/drivers/media/dvb-frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h
new file mode 100644 (file)
index 0000000..93741ee
--- /dev/null
@@ -0,0 +1,2371 @@
+/*
+       STV0900/0903 Multistandard Broadcast Frontend driver
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV090x_REG_H
+#define __STV090x_REG_H
+
+#define STV090x_MID                            0xf100
+#define STV090x_OFFST_MCHIP_IDENT_FIELD                4
+#define STV090x_WIDTH_MCHIP_IDENT_FIELD                4
+#define STV090x_OFFST_MRELEASE_FIELD           0
+#define STV090x_WIDTH_MRELEASE_FIELD           4
+
+#define STV090x_DACR1                          0xf113
+#define STV090x_OFFST_DACR1_MODE_FIELD         5
+#define STV090x_WIDTH_DACR1_MODE_FIELD         3
+#define STV090x_OFFST_DACR1_VALUE_FIELD                0
+#define STV090x_WIDTH_DACR1_VALUE_FIELD                4
+
+#define STV090x_DACR2                          0xf114
+#define STV090x_OFFST_DACR2_VALUE_FIELD                0
+#define STV090x_WIDTH_DACR2_VALUE_FIELD                8
+
+#define STV090x_OUTCFG                         0xf11c
+#define STV090x_OFFST_OUTSERRS1_HZ_FIELD       6
+#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD       1
+#define STV090x_OFFST_OUTSERRS2_HZ_FIELD       5
+#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD       1
+#define STV090x_OFFST_OUTSERRS3_HZ_FIELD       4
+#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD       1
+#define STV090x_OFFST_OUTPARRS3_HZ_FIELD       3
+#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD       1
+
+#define STV090x_MODECFG                                0xf11d
+
+#define STV090x_IRQSTATUS3                     0xf120
+#define STV090x_OFFST_SPLL_LOCK_FIELD          5
+#define STV090x_WIDTH_SPLL_LOCK_FIELD          1
+#define STV090x_OFFST_SSTREAM_LCK_3_FIELD      4
+#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD      1
+#define STV090x_OFFST_SSTREAM_LCK_2_FIELD      3
+#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD      1
+#define STV090x_OFFST_SSTREAM_LCK_1_FIELD      2
+#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD      1
+#define STV090x_OFFST_SDVBS1_PRF_2_FIELD       1
+#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD       1
+#define STV090x_OFFST_SDVBS1_PRF_1_FIELD       0
+#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD       1
+
+#define STV090x_IRQSTATUS2                     0xf121
+#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD      7
+#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD      1
+#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD      6
+#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD      1
+#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD      5
+#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD      1
+#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD    4
+#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD    1
+#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD    3
+#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD    1
+#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD     2
+#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD     1
+#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD    1
+#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD    1
+#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD    0
+#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD    1
+
+#define STV090x_IRQSTATUS1                     0xf122
+#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD     7
+#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD     1
+#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD     2
+#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD     1
+#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD      1
+#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD      1
+#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD       0
+#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD       1
+
+#define STV090x_IRQSTATUS0                     0xf123
+#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD     7
+#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD     1
+#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD      6
+#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD      1
+#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD       5
+#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD       1
+#define STV090x_OFFST_SBCH_ERRFLAG_FIELD       4
+#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD       1
+#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD     3
+#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD     1
+#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD     2
+#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD     1
+#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD     1
+#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD     1
+#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD     0
+#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD     1
+
+#define STV090x_IRQMASK3                       0xf124
+#define STV090x_OFFST_MPLL_LOCK_FIELD          5
+#define STV090x_WIDTH_MPLL_LOCK_FIELD          1
+#define STV090x_OFFST_MSTREAM_LCK_3_FIELD      4
+#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD      1
+#define STV090x_OFFST_MSTREAM_LCK_2_FIELD      3
+#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD      1
+#define STV090x_OFFST_MSTREAM_LCK_1_FIELD      2
+#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD      1
+#define STV090x_OFFST_MDVBS1_PRF_2_FIELD       1
+#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD       1
+#define STV090x_OFFST_MDVBS1_PRF_1_FIELD       0
+#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD       1
+
+#define STV090x_IRQMASK2                       0xf125
+#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD      7
+#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD      1
+#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD      6
+#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD      1
+#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD      5
+#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD      1
+#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD    4
+#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD    1
+#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD    3
+#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD    1
+#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD     2
+#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD     1
+#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD    1
+#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD    1
+#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD    0
+#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD    1
+
+#define STV090x_IRQMASK1                       0xf126
+#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD     7
+#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD     1
+#define STV090x_OFFST_MEXTPINB2_FIELD          6
+#define STV090x_WIDTH_MEXTPINB2_FIELD          1
+#define STV090x_OFFST_MEXTPIN2_FIELD           5
+#define STV090x_WIDTH_MEXTPIN2_FIELD           1
+#define STV090x_OFFST_MEXTPINB1_FIELD          4
+#define STV090x_WIDTH_MEXTPINB1_FIELD          1
+#define STV090x_OFFST_MEXTPIN1_FIELD           3
+#define STV090x_WIDTH_MEXTPIN1_FIELD           1
+#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD     2
+#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD     1
+#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD      1
+#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD      1
+#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD       0
+#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD       1
+
+#define STV090x_IRQMASK0                       0xf127
+#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD     7
+#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD     1
+#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD      6
+#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD      1
+#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD       5
+#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD       1
+#define STV090x_OFFST_MBCH_ERRFLAG_FIELD       4
+#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD       1
+#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD     3
+#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD     1
+#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD     2
+#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD     1
+#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD     1
+#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD     1
+#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD     0
+#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD     1
+
+#define STV090x_I2CCFG                         0xf129
+#define STV090x_OFFST_12C_FASTMODE_FIELD       3
+#define STV090x_WIDTH_12C_FASTMODE_FIELD       1
+#define STV090x_OFFST_12CADDR_INC_FIELD                0
+#define STV090x_WIDTH_12CADDR_INC_FIELD                2
+
+#define STV090x_Px_I2CRPT(__x)                 (0xf12a + (__x - 1) * 0x1)
+#define STV090x_P1_I2CRPT                      STV090x_Px_I2CRPT(1)
+#define STV090x_P2_I2CRPT                      STV090x_Px_I2CRPT(2)
+#define STV090x_OFFST_Px_I2CT_ON_FIELD         7
+#define STV090x_WIDTH_Px_I2CT_ON_FIELD         1
+#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD    4
+#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD    3
+#define STV090x_OFFST_Px_SCLT_DELAY_FIELD      3
+#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD      1
+#define STV090x_OFFST_Px_STOP_ENABLE_FIELD     2
+#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD     1
+#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD   1
+#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD   1
+
+#define STV090x_CLKI2CFG                       0xf140
+#define STV090x_OFFST_CLKI2_OPD_FIELD          7
+#define STV090x_WIDTH_CLKI2_OPD_FIELD          1
+#define STV090x_OFFST_CLKI2_CONFIG_FIELD       1
+#define STV090x_WIDTH_CLKI2_CONFIG_FIELD       6
+#define STV090x_OFFST_CLKI2_XOR_FIELD          0
+#define STV090x_WIDTH_CLKI2_XOR_FIELD          1
+
+#define STV090x_GPIOxCFG(__x)                  (0xf141 + (__x - 1))
+#define STV090x_GPIO1CFG                       STV090x_GPIOxCFG(1)
+#define STV090x_GPIO2CFG                       STV090x_GPIOxCFG(2)
+#define STV090x_GPIO3CFG                       STV090x_GPIOxCFG(3)
+#define STV090x_GPIO4CFG                       STV090x_GPIOxCFG(4)
+#define STV090x_GPIO5CFG                       STV090x_GPIOxCFG(5)
+#define STV090x_GPIO6CFG                       STV090x_GPIOxCFG(6)
+#define STV090x_GPIO7CFG                       STV090x_GPIOxCFG(7)
+#define STV090x_GPIO8CFG                       STV090x_GPIOxCFG(8)
+#define STV090x_GPIO9CFG                       STV090x_GPIOxCFG(9)
+#define STV090x_GPIO10CFG                      STV090x_GPIOxCFG(10)
+#define STV090x_GPIO11CFG                      STV090x_GPIOxCFG(11)
+#define STV090x_GPIO12CFG                      STV090x_GPIOxCFG(12)
+#define STV090x_GPIO13CFG                      STV090x_GPIOxCFG(13)
+#define STV090x_OFFST_GPIOx_OPD_FIELD          7
+#define STV090x_WIDTH_GPIOx_OPD_FIELD          1
+#define STV090x_OFFST_GPIOx_CONFIG_FIELD       1
+#define STV090x_WIDTH_GPIOx_CONFIG_FIELD       6
+#define STV090x_OFFST_GPIOx_XOR_FIELD          0
+#define STV090x_WIDTH_GPIOx_XOR_FIELD          1
+
+#define STV090x_CSxCFG(__x)                    (0xf14e + __x * 0x1)
+#define STV090x_CS0CFG                         STV090x_CSxCFG(0)
+#define STV090x_CS1CFG                         STV090x_CSxCFG(1)
+#define STV090x_OFFST_CSX_OPD_FIELD            7
+#define STV090x_WIDTH_CSX_OPD_FIELD            1
+#define STV090x_OFFST_CSX_CONFIG_FIELD         1
+#define STV090x_WIDTH_CSX_CONFIG_FIELD         6
+#define STV090x_OFFST_CSX_XOR_FIELD            0
+#define STV090x_WIDTH_CSX_XOR_FIELD            1
+
+
+#define STV090x_STDBYCFG                       0xf150
+#define STV090x_OFFST_STDBY_OPD_FIELD          7
+#define STV090x_WIDTH_STDBY_OPD_FIELD          1
+#define STV090x_OFFST_STDBY_CONFIG_FIELD       1
+#define STV090x_WIDTH_STDBY_CONFIG_FIELD       6
+#define STV090x_OFFST_STDBY_XOR_FIELD          0
+#define STV090x_WIDTH_STDBY_XOR_FIELD          1
+
+#define STV090x_DIRCLKCFG                      0xf151
+#define STV090x_OFFST_DIRCLK_OPD_FIELD         7
+#define STV090x_WIDTH_DIRCLK_OPD_FIELD         1
+#define STV090x_OFFST_DIRCLK_CONFIG_FIELD      1
+#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD      6
+#define STV090x_OFFST_DIRCLK_XOR_FIELD         0
+#define STV090x_WIDTH_DIRCLK_XOR_FIELD         1
+
+
+#define STV090x_AGCRFxCFG(__x)                 (0xf152 + (__x - 1) * 0x4)
+#define STV090x_AGCRF1CFG                      STV090x_AGCRFxCFG(1)
+#define STV090x_AGCRF2CFG                      STV090x_AGCRFxCFG(2)
+#define STV090x_OFFST_AGCRFx_OPD_FIELD         7
+#define STV090x_WIDTH_AGCRFx_OPD_FIELD         1
+#define STV090x_OFFST_AGCRFx_CONFIG_FIELD      1
+#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD      6
+#define STV090x_OFFST_AGCRFx_XOR_FIELD         0
+#define STV090x_WIDTH_AGCRFx_XOR_FIELD         1
+
+#define STV090x_SDATxCFG(__x)                  (0xf153 + (__x - 1) * 0x4)
+#define STV090x_SDAT1CFG                       STV090x_SDATxCFG(1)
+#define STV090x_SDAT2CFG                       STV090x_SDATxCFG(2)
+#define STV090x_OFFST_SDATx_OPD_FIELD          7
+#define STV090x_WIDTH_SDATx_OPD_FIELD          1
+#define STV090x_OFFST_SDATx_CONFIG_FIELD       1
+#define STV090x_WIDTH_SDATx_CONFIG_FIELD       6
+#define STV090x_OFFST_SDATx_XOR_FIELD          0
+#define STV090x_WIDTH_SDATx_XOR_FIELD          1
+
+#define STV090x_SCLTxCFG(__x)                  (0xf154 + (__x - 1) * 0x4)
+#define STV090x_SCLT1CFG                       STV090x_SCLTxCFG(1)
+#define STV090x_SCLT2CFG                       STV090x_SCLTxCFG(2)
+#define STV090x_OFFST_SCLTx_OPD_FIELD          7
+#define STV090x_WIDTH_SCLTx_OPD_FIELD          1
+#define STV090x_OFFST_SCLTx_CONFIG_FIELD       1
+#define STV090x_WIDTH_SCLTx_CONFIG_FIELD       6
+#define STV090x_OFFST_SCLTx_XOR_FIELD          0
+#define STV090x_WIDTH_SCLTx_XOR_FIELD          1
+
+#define STV090x_DISEQCOxCFG(__x)               (0xf155 + (__x - 1) * 0x4)
+#define STV090x_DISEQCO1CFG                    STV090x_DISEQCOxCFG(1)
+#define STV090x_DISEQCO2CFG                    STV090x_DISEQCOxCFG(2)
+#define STV090x_OFFST_DISEQCOx_OPD_FIELD       7
+#define STV090x_WIDTH_DISEQCOx_OPD_FIELD       1
+#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD    1
+#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD    6
+#define STV090x_OFFST_DISEQCOx_XOR_FIELD       0
+#define STV090x_WIDTH_DISEQCOx_XOR_FIELD       1
+
+#define STV090x_CLKOUT27CFG                    0xf15a
+#define STV090x_OFFST_CLKOUT27_OPD_FIELD       7
+#define STV090x_WIDTH_CLKOUT27_OPD_FIELD       1
+#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD    1
+#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD    6
+#define STV090x_OFFST_CLKOUT27_XOR_FIELD       0
+#define STV090x_WIDTH_CLKOUT27_XOR_FIELD       1
+
+#define STV090x_ERRORxCFG(__x)                 (0xf15b + (__x - 1) * 0x5)
+#define STV090x_ERROR1CFG                      STV090x_ERRORxCFG(1)
+#define STV090x_ERROR2CFG                      STV090x_ERRORxCFG(2)
+#define STV090x_ERROR3CFG                      STV090x_ERRORxCFG(3)
+#define STV090x_OFFST_ERRORx_OPD_FIELD         7
+#define STV090x_WIDTH_ERRORx_OPD_FIELD         1
+#define STV090x_OFFST_ERRORx_CONFIG_FIELD      1
+#define STV090x_WIDTH_ERRORx_CONFIG_FIELD      6
+#define STV090x_OFFST_ERRORx_XOR_FIELD         0
+#define STV090x_WIDTH_ERRORx_XOR_FIELD         1
+
+#define STV090x_DPNxCFG(__x)                   (0xf15c + (__x - 1) * 0x5)
+#define STV090x_DPN1CFG                                STV090x_DPNxCFG(1)
+#define STV090x_DPN2CFG                                STV090x_DPNxCFG(2)
+#define STV090x_DPN3CFG                                STV090x_DPNxCFG(3)
+#define STV090x_OFFST_DPNx_OPD_FIELD           7
+#define STV090x_WIDTH_DPNx_OPD_FIELD           1
+#define STV090x_OFFST_DPNx_CONFIG_FIELD                1
+#define STV090x_WIDTH_DPNx_CONFIG_FIELD                6
+#define STV090x_OFFST_DPNx_XOR_FIELD           0
+#define STV090x_WIDTH_DPNx_XOR_FIELD           1
+
+#define STV090x_STROUTxCFG(__x)                        (0xf15d + (__x - 1) * 0x5)
+#define STV090x_STROUT1CFG                     STV090x_STROUTxCFG(1)
+#define STV090x_STROUT2CFG                     STV090x_STROUTxCFG(2)
+#define STV090x_STROUT3CFG                     STV090x_STROUTxCFG(3)
+#define STV090x_OFFST_STROUTx_OPD_FIELD                7
+#define STV090x_WIDTH_STROUTx_OPD_FIELD                1
+#define STV090x_OFFST_STROUTx_CONFIG_FIELD     1
+#define STV090x_WIDTH_STROUTx_CONFIG_FIELD     6
+#define STV090x_OFFST_STROUTx_XOR_FIELD                0
+#define STV090x_WIDTH_STROUTx_XOR_FIELD                1
+
+#define STV090x_CLKOUTxCFG(__x)                        (0xf15e + (__x - 1) * 0x5)
+#define STV090x_CLKOUT1CFG                     STV090x_CLKOUTxCFG(1)
+#define STV090x_CLKOUT2CFG                     STV090x_CLKOUTxCFG(2)
+#define STV090x_CLKOUT3CFG                     STV090x_CLKOUTxCFG(3)
+#define STV090x_OFFST_CLKOUTx_OPD_FIELD                7
+#define STV090x_WIDTH_CLKOUTx_OPD_FIELD                1
+#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD     1
+#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD     6
+#define STV090x_OFFST_CLKOUTx_XOR_FIELD                0
+#define STV090x_WIDTH_CLKOUTx_XOR_FIELD                1
+
+#define STV090x_DATAxCFG(__x)                  (0xf15f + (__x - 71) * 0x5)
+#define STV090x_DATA71CFG                      STV090x_DATAxCFG(71)
+#define STV090x_DATA72CFG                      STV090x_DATAxCFG(72)
+#define STV090x_DATA73CFG                      STV090x_DATAxCFG(73)
+#define STV090x_OFFST_DATAx_OPD_FIELD          7
+#define STV090x_WIDTH_DATAx_OPD_FIELD          1
+#define STV090x_OFFST_DATAx_CONFIG_FIELD       1
+#define STV090x_WIDTH_DATAx_CONFIG_FIELD       6
+#define STV090x_OFFST_DATAx_XOR_FIELD          0
+#define STV090x_WIDTH_DATAx_XOR_FIELD          1
+
+#define STV090x_NCOARSE                                0xf1b3
+#define STV090x_OFFST_M_DIV_FIELD              0
+#define STV090x_WIDTH_M_DIV_FIELD              8
+
+#define STV090x_SYNTCTRL                       0xf1b6
+#define STV090x_OFFST_STANDBY_FIELD            7
+#define STV090x_WIDTH_STANDBY_FIELD            1
+#define STV090x_OFFST_BYPASSPLLCORE_FIELD      6
+#define STV090x_WIDTH_BYPASSPLLCORE_FIELD      1
+#define STV090x_OFFST_SELX1RATIO_FIELD         5
+#define STV090x_WIDTH_SELX1RATIO_FIELD         1
+#define STV090x_OFFST_STOP_PLL_FIELD           3
+#define STV090x_WIDTH_STOP_PLL_FIELD           1
+#define STV090x_OFFST_BYPASSPLLFSK_FIELD       2
+#define STV090x_WIDTH_BYPASSPLLFSK_FIELD       1
+#define STV090x_OFFST_SELOSCI_FIELD            1
+#define STV090x_WIDTH_SELOSCI_FIELD            1
+#define STV090x_OFFST_BYPASSPLLADC_FIELD       0
+#define STV090x_WIDTH_BYPASSPLLADC_FIELD       1
+
+#define STV090x_FILTCTRL                       0xf1b7
+#define STV090x_OFFST_INV_CLK135_FIELD         7
+#define STV090x_WIDTH_INV_CLK135_FIELD         1
+#define STV090x_OFFST_SEL_FSKCKDIV_FIELD       2
+#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD       1
+#define STV090x_OFFST_INV_CLKFSK_FIELD         1
+#define STV090x_WIDTH_INV_CLKFSK_FIELD         1
+#define STV090x_OFFST_BYPASS_APPLI_FIELD       0
+#define STV090x_WIDTH_BYPASS_APPLI_FIELD       1
+
+#define STV090x_PLLSTAT                                0xf1b8
+#define STV090x_OFFST_PLLLOCK_FIELD            0
+#define STV090x_WIDTH_PLLLOCK_FIELD            1
+
+#define STV090x_STOPCLK1                       0xf1c2
+#define STV090x_OFFST_STOP_CLKPKDT2_FIELD      6
+#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD      1
+#define STV090x_OFFST_STOP_CLKPKDT1_FIELD      5
+#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD      1
+#define STV090x_OFFST_STOP_CLKFEC_FIELD                4
+#define STV090x_WIDTH_STOP_CLKFEC_FIELD                1
+#define STV090x_OFFST_STOP_CLKADCI2_FIELD      3
+#define STV090x_WIDTH_STOP_CLKADCI2_FIELD      1
+#define STV090x_OFFST_INV_CLKADCI2_FIELD       2
+#define STV090x_WIDTH_INV_CLKADCI2_FIELD       1
+#define STV090x_OFFST_STOP_CLKADCI1_FIELD      1
+#define STV090x_WIDTH_STOP_CLKADCI1_FIELD      1
+#define STV090x_OFFST_INV_CLKADCI1_FIELD       0
+#define STV090x_WIDTH_INV_CLKADCI1_FIELD       1
+
+#define STV090x_STOPCLK2                       0xf1c3
+#define STV090x_OFFST_STOP_CLKSAMP2_FIELD      4
+#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD      1
+#define STV090x_OFFST_STOP_CLKSAMP1_FIELD      3
+#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD      1
+#define STV090x_OFFST_STOP_CLKVIT2_FIELD       2
+#define STV090x_WIDTH_STOP_CLKVIT2_FIELD       1
+#define STV090x_OFFST_STOP_CLKVIT1_FIELD       1
+#define STV090x_WIDTH_STOP_CLKVIT1_FIELD       1
+#define STV090x_OFFST_STOP_CLKTS_FIELD         0
+#define STV090x_WIDTH_STOP_CLKTS_FIELD         1
+
+#define STV090x_TSTTNR0                                0xf1df
+#define STV090x_OFFST_SEL_FSK_FIELD            7
+#define STV090x_WIDTH_SEL_FSK_FIELD            1
+#define STV090x_OFFST_FSK_PON_FIELD            2
+#define STV090x_WIDTH_FSK_PON_FIELD            1
+
+#define STV090x_TSTTNR1                                0xf1e0
+#define STV090x_OFFST_ADC1_PON_FIELD           1
+#define STV090x_WIDTH_ADC1_PON_FIELD           1
+#define STV090x_OFFST_ADC1_INMODE_FIELD                0
+#define STV090x_WIDTH_ADC1_INMODE_FIELD                1
+
+#define STV090x_TSTTNR2                                0xf1e1
+#define STV090x_OFFST_DISEQC1_PON_FIELD                5
+#define STV090x_WIDTH_DISEQC1_PON_FIELD                1
+
+#define STV090x_TSTTNR3                                0xf1e2
+#define STV090x_OFFST_ADC2_PON_FIELD           1
+#define STV090x_WIDTH_ADC2_PON_FIELD           1
+#define STV090x_OFFST_ADC2_INMODE_FIELD                0
+#define STV090x_WIDTH_ADC2_INMODE_FIELD                1
+
+#define STV090x_TSTTNR4                                0xf1e3
+#define STV090x_OFFST_DISEQC2_PON_FIELD                5
+#define STV090x_WIDTH_DISEQC2_PON_FIELD                1
+
+#define STV090x_FSKTFC2                                0xf170
+#define STV090x_OFFST_FSKT_KMOD_FIELD          2
+#define STV090x_WIDTH_FSKT_KMOD_FIELD          6
+#define STV090x_OFFST_FSKT_CAR_FIELD           0
+#define STV090x_WIDTH_FSKT_CAR_FIELD           2
+
+#define STV090x_FSKTFC1                                0xf171
+#define STV090x_OFFST_FSKTC1_CAR_FIELD         0
+#define STV090x_WIDTH_FSKTC1_CAR_FIELD         8
+
+#define STV090x_FSKTFC0                                0xf172
+#define STV090x_OFFST_FSKTC0_CAR_FIELD         0
+#define STV090x_WIDTH_FSKTC0_CAR_FIELD         8
+
+#define STV090x_FSKTDELTAF1                    0xf173
+#define STV090x_OFFST_FSKTF1_DELTAF_FIELD      0
+#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD      4
+
+#define STV090x_FSKTDELTAF0                    0xf174
+#define STV090x_OFFST_FSKTF0_DELTAF_FIELD      0
+#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD      8
+
+#define STV090x_FSKTCTRL                       0xf175
+#define STV090x_OFFST_FSKT_EN_SGN_FIELD                6
+#define STV090x_WIDTH_FSKT_EN_SGN_FIELD                1
+#define STV090x_OFFST_FSKT_MOD_SGN_FIELD       5
+#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD       1
+#define STV090x_OFFST_FSKT_MOD_EN_FIELD                2
+#define STV090x_WIDTH_FSKT_MOD_EN_FIELD                3
+#define STV090x_OFFST_FSKT_DACMODE_FIELD       0
+#define STV090x_WIDTH_FSKT_DACMODE_FIELD       2
+
+#define STV090x_FSKRFC2                                0xf176
+#define STV090x_OFFST_FSKRC2_DETSGN_FIELD      6
+#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD      1
+#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD      5
+#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD      1
+#define STV090x_OFFST_FSKRC2_KAGC_FIELD                2
+#define STV090x_WIDTH_FSKRC2_KAGC_FIELD                3
+#define STV090x_OFFST_FSKRC2_CAR_FIELD         0
+#define STV090x_WIDTH_FSKRC2_CAR_FIELD         2
+
+#define STV090x_FSKRFC1                                0xf177
+#define STV090x_OFFST_FSKRC1_CAR_FIELD         0
+#define STV090x_WIDTH_FSKRC1_CAR_FIELD         8
+
+#define STV090x_FSKRFC0                                0xf178
+#define STV090x_OFFST_FSKRC0_CAR_FIELD         0
+#define STV090x_WIDTH_FSKRC0_CAR_FIELD         8
+
+#define STV090x_FSKRK1                         0xf179
+#define STV090x_OFFST_FSKR_K1_EXP_FIELD                5
+#define STV090x_WIDTH_FSKR_K1_EXP_FIELD                3
+#define STV090x_OFFST_FSKR_K1_MANT_FIELD       0
+#define STV090x_WIDTH_FSKR_K1_MANT_FIELD       5
+
+#define STV090x_FSKRK2                         0xf17a
+#define STV090x_OFFST_FSKR_K2_EXP_FIELD                5
+#define STV090x_WIDTH_FSKR_K2_EXP_FIELD                3
+#define STV090x_OFFST_FSKR_K2_MANT_FIELD       0
+#define STV090x_WIDTH_FSKR_K2_MANT_FIELD       5
+
+#define STV090x_FSKRAGCR                       0xf17b
+#define STV090x_OFFST_FSKR_OUTCTL_FIELD                6
+#define STV090x_WIDTH_FSKR_OUTCTL_FIELD                2
+#define STV090x_OFFST_FSKR_AGC_REF_FIELD       0
+#define STV090x_WIDTH_FSKR_AGC_REF_FIELD       6
+
+#define STV090x_FSKRAGC                                0xf17c
+#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD      0
+#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD      8
+
+#define STV090x_FSKRALPHA                      0xf17d
+#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD     2
+#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD     3
+#define STV090x_OFFST_FSKR_ALPHA_M_FIELD       0
+#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD       2
+
+#define STV090x_FSKRPLTH1                      0xf17e
+#define STV090x_OFFST_FSKR_BETA_FIELD          4
+#define STV090x_WIDTH_FSKR_BETA_FIELD          4
+#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD    0
+#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD    4
+
+#define STV090x_FSKRPLTH0                      0xf17f
+#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD    0
+#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD    8
+
+#define STV090x_FSKRDF1                                0xf180
+#define STV090x_OFFST_FSKR_DELTAF1_FIELD       0
+#define STV090x_WIDTH_FSKR_DELTAF1_FIELD       5
+
+#define STV090x_FSKRDF0                                0xf181
+#define STV090x_OFFST_FSKR_DELTAF0_FIELD       0
+#define STV090x_WIDTH_FSKR_DELTAF0_FIELD       8
+
+#define STV090x_FSKRSTEPP                      0xf182
+#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD     0
+#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD     8
+
+#define STV090x_FSKRSTEPM                      0xf183
+#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD    0
+#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD    8
+
+#define STV090x_FSKRDET1                       0xf184
+#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD  0
+#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD  4
+
+#define STV090x_FSKRDET0                       0xf185
+#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD  0
+#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD  8
+
+#define STV090x_FSKRDTH1                               0xf186
+#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD       4
+#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD       4
+#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD                0
+#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD                4
+
+#define STV090x_FSKRDTH0                       0xf187
+#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD        0
+#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD        8
+
+#define STV090x_FSKRLOSS                       0xf188
+#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD        0
+#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD        8
+
+#define STV090x_Px_DISTXCTL(__x)               (0xF1A0 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXCTL                    STV090x_Px_DISTXCTL(1)
+#define STV090x_P2_DISTXCTL                    STV090x_Px_DISTXCTL(2)
+#define STV090x_OFFST_Px_TIM_OFF_FIELD         7
+#define STV090x_WIDTH_Px_TIM_OFF_FIELD         1
+#define STV090x_OFFST_Px_DISEQC_RESET_FIELD    6
+#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD    1
+#define STV090x_OFFST_Px_TIM_CMD_FIELD         4
+#define STV090x_WIDTH_Px_TIM_CMD_FIELD         2
+#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD   3
+#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD   1
+#define STV090x_OFFST_Px_DISTX_MODE_FIELD      0
+#define STV090x_WIDTH_Px_DISTX_MODE_FIELD      3
+
+#define STV090x_Px_DISRXCTL(__x)               (0xf1a1 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRXCTL                    STV090x_Px_DISRXCTL(1)
+#define STV090x_P2_DISRXCTL                    STV090x_Px_DISRXCTL(2)
+#define STV090x_OFFST_Px_RECEIVER_ON_FIELD     7
+#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD     1
+#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD   6
+#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD   1
+#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD     5
+#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD     1
+#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD     4
+#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD     1
+#define STV090x_OFFST_Px_PIN_SELECT_FIELD      2
+#define STV090x_WIDTH_Px_PIN_SELECT_FIELD      2
+#define STV090x_OFFST_Px_IRQ_RXEND_FIELD       1
+#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD       1
+#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD     0
+#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD     1
+
+#define STV090x_Px_DISRX_ST0(__x)              (0xf1a4 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRX_ST0                   STV090x_Px_DISRX_ST0(1)
+#define STV090x_P2_DISRX_ST0                   STV090x_Px_DISRX_ST0(2)
+#define STV090x_OFFST_Px_RX_END_FIELD          7
+#define STV090x_WIDTH_Px_RX_END_FIELD          1
+#define STV090x_OFFST_Px_RX_ACTIVE_FIELD       6
+#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD       1
+#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD     5
+#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD     1
+#define STV090x_OFFST_Px_CONT_TONE_FIELD       4
+#define STV090x_WIDTH_Px_CONT_TONE_FIELD       1
+#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD    3
+#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD    1
+#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD      2
+#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD      1
+#define STV090x_OFFST_Px_ABORT_DISRX_FIELD     0
+#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD     1
+
+#define STV090x_Px_DISRX_ST1(__x)              (0xf1a5 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRX_ST1                   STV090x_Px_DISRX_ST1(1)
+#define STV090x_P2_DISRX_ST1                   STV090x_Px_DISRX_ST1(2)
+#define STV090x_OFFST_Px_RX_FAIL_FIELD         7
+#define STV090x_WIDTH_Px_RX_FAIL_FIELD         1
+#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6
+#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1
+#define STV090x_OFFST_Px_RX_NONBYTE_FIELD      5
+#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD      1
+#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD   4
+#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD   1
+#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD    0
+#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD    4
+
+#define STV090x_Px_DISRXDATA(__x)              (0xf1a6 - (__x - 1) * 0x10)
+#define STV090x_P1_DISRXDATA                   STV090x_Px_DISRXDATA(1)
+#define STV090x_P2_DISRXDATA                   STV090x_Px_DISRXDATA(2)
+#define STV090x_OFFST_Px_DISRX_DATA_FIELD      0
+#define STV090x_WIDTH_Px_DISRX_DATA_FIELD      8
+
+#define STV090x_Px_DISTXDATA(__x)              (0xf1a7 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXDATA                   STV090x_Px_DISTXDATA(1)
+#define STV090x_P2_DISTXDATA                   STV090x_Px_DISTXDATA(2)
+#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD     0
+#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD     8
+
+#define STV090x_Px_DISTXSTATUS(__x)            (0xf1a8 - (__x - 1) * 0x10)
+#define STV090x_P1_DISTXSTATUS                 STV090x_Px_DISTXSTATUS(1)
+#define STV090x_P2_DISTXSTATUS                 STV090x_Px_DISTXSTATUS(2)
+#define STV090x_OFFST_Px_TX_FAIL_FIELD         7
+#define STV090x_WIDTH_Px_TX_FAIL_FIELD         1
+#define STV090x_OFFST_Px_FIFO_FULL_FIELD       6
+#define STV090x_WIDTH_Px_FIFO_FULL_FIELD       1
+#define STV090x_OFFST_Px_TX_IDLE_FIELD         5
+#define STV090x_WIDTH_Px_TX_IDLE_FIELD         1
+#define STV090x_OFFST_Px_GAP_BURST_FIELD       4
+#define STV090x_WIDTH_Px_GAP_BURST_FIELD       1
+#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD    0
+#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD    4
+
+#define STV090x_Px_F22TX(__x)                  (0xf1a9 - (__x - 1) * 0x10)
+#define STV090x_P1_F22TX                       STV090x_Px_F22TX(1)
+#define STV090x_P2_F22TX                       STV090x_Px_F22TX(2)
+#define STV090x_OFFST_Px_F22_REG_FIELD         0
+#define STV090x_WIDTH_Px_F22_REG_FIELD         8
+
+#define STV090x_Px_F22RX(__x)                  (0xf1aa - (__x - 1) * 0x10)
+#define STV090x_P1_F22RX                       STV090x_Px_F22RX(1)
+#define STV090x_P2_F22RX                       STV090x_Px_F22RX(2)
+#define STV090x_OFFST_Px_F22RX_REG_FIELD       0
+#define STV090x_WIDTH_Px_F22RX_REG_FIELD       8
+
+#define STV090x_Px_ACRPRESC(__x)               (0xf1ac - (__x - 1) * 0x10)
+#define STV090x_P1_ACRPRESC                    STV090x_Px_ACRPRESC(1)
+#define STV090x_P2_ACRPRESC                    STV090x_Px_ACRPRESC(2)
+#define STV090x_OFFST_Px_ACR_PRESC_FIELD       0
+#define STV090x_WIDTH_Px_ACR_PRESC_FIELD       3
+
+#define STV090x_Px_ACRDIV(__x)                 (0xf1ad - (__x - 1) * 0x10)
+#define STV090x_P1_ACRDIV                      STV090x_Px_ACRDIV(1)
+#define STV090x_P2_ACRDIV                      STV090x_Px_ACRDIV(2)
+#define STV090x_OFFST_Px_ACR_DIV_FIELD         0
+#define STV090x_WIDTH_Px_ACR_DIV_FIELD         8
+
+#define STV090x_Px_IQCONST(__x)                        (0xF400 - (__x - 1) * 0x200)
+#define STV090x_P1_IQCONST                     STV090x_Px_IQCONST(1)
+#define STV090x_P2_IQCONST                     STV090x_Px_IQCONST(2)
+#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD  5
+#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD  2
+
+#define STV090x_Px_NOSCFG(__x)                 (0xF401 - (__x - 1) * 0x200)
+#define STV090x_P1_NOSCFG                      STV090x_Px_NOSCFG(1)
+#define STV090x_P2_NOSCFG                      STV090x_Px_NOSCFG(2)
+#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD     3
+#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD     2
+#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD    0
+#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD    3
+
+#define STV090x_Px_ISYMB(__x)                  (0xF402 - (__x - 1) * 0x200)
+#define STV090x_P1_ISYMB                       STV090x_Px_ISYMB(1)
+#define STV090x_P2_ISYMB                       STV090x_Px_ISYMB(2)
+#define STV090x_OFFST_Px_I_SYMBOL_FIELD                0
+#define STV090x_WIDTH_Px_I_SYMBOL_FIELD                8
+
+#define STV090x_Px_QSYMB(__x)                  (0xF403 - (__x - 1) * 0x200)
+#define STV090x_P1_QSYMB                       STV090x_Px_QSYMB(1)
+#define STV090x_P2_QSYMB                       STV090x_Px_QSYMB(2)
+#define STV090x_OFFST_Px_Q_SYMBOL_FIELD                0
+#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD                8
+
+#define STV090x_Px_AGC1CFG(__x)                        (0xF404 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1CFG                     STV090x_Px_AGC1CFG(1)
+#define STV090x_P2_AGC1CFG                     STV090x_Px_AGC1CFG(2)
+#define STV090x_OFFST_Px_DC_FROZEN_FIELD       7
+#define STV090x_WIDTH_Px_DC_FROZEN_FIELD       1
+#define STV090x_OFFST_Px_DC_CORRECT_FIELD      6
+#define STV090x_WIDTH_Px_DC_CORRECT_FIELD      1
+#define STV090x_OFFST_Px_AMM_FROZEN_FIELD      5
+#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD      1
+#define STV090x_OFFST_Px_AMM_CORRECT_FIELD     4
+#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD     1
+#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD     3
+#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD     1
+#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD    2
+#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD    1
+
+#define STV090x_Px_AGC1CN(__x)                 (0xF406 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1CN                      STV090x_Px_AGC1CN(1)
+#define STV090x_P2_AGC1CN                      STV090x_Px_AGC1CN(2)
+#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD     7
+#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD     1
+#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD   4
+#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD   1
+#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD     3
+#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD     1
+#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD      0
+#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD      3
+
+#define STV090x_Px_AGC1REF(__x)                        (0xF407 - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1REF                     STV090x_Px_AGC1REF(1)
+#define STV090x_P2_AGC1REF                     STV090x_Px_AGC1REF(2)
+#define STV090x_OFFST_Px_AGCIQ_REF_FIELD       0
+#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD       8
+
+#define STV090x_Px_IDCCOMP(__x)                        (0xF408 - (__x - 1) * 0x200)
+#define STV090x_P1_IDCCOMP                     STV090x_Px_IDCCOMP(1)
+#define STV090x_P2_IDCCOMP                     STV090x_Px_IDCCOMP(2)
+#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD    0
+#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD    8
+
+#define STV090x_Px_QDCCOMP(__x)                        (0xF409 - (__x - 1) * 0x200)
+#define STV090x_P1_QDCCOMP                     STV090x_Px_QDCCOMP(1)
+#define STV090x_P2_QDCCOMP                     STV090x_Px_QDCCOMP(2)
+#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD    0
+#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD    8
+
+#define STV090x_Px_POWERI(__x)                 (0xF40A - (__x - 1) * 0x200)
+#define STV090x_P1_POWERI                      STV090x_Px_POWERI(1)
+#define STV090x_P2_POWERI                      STV090x_Px_POWERI(2)
+#define STV090x_OFFST_Px_POWER_I_FIELD         0
+#define STV090x_WIDTH_Px_POWER_I_FIELD         8
+
+#define STV090x_Px_POWERQ(__x)                 (0xF40B - (__x - 1) * 0x200)
+#define STV090x_P1_POWERQ                      STV090x_Px_POWERQ(1)
+#define STV090x_P2_POWERQ                      STV090x_Px_POWERQ(2)
+#define STV090x_OFFST_Px_POWER_Q_FIELD         0
+#define STV090x_WIDTH_Px_POWER_Q_FIELD         8
+
+#define STV090x_Px_AGC1AMM(__x)                        (0xF40C - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1AMM                     STV090x_Px_AGC1AMM(1)
+#define STV090x_P2_AGC1AMM                     STV090x_Px_AGC1AMM(2)
+#define STV090x_OFFST_Px_AMM_VALUE_FIELD       0
+#define STV090x_WIDTH_Px_AMM_VALUE_FIELD       8
+
+#define STV090x_Px_AGC1QUAD(__x)               (0xF40D - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1QUAD                    STV090x_Px_AGC1QUAD(1)
+#define STV090x_P2_AGC1QUAD                    STV090x_Px_AGC1QUAD(2)
+#define STV090x_OFFST_Px_QUAD_VALUE_FIELD      0
+#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD      8
+
+#define STV090x_Px_AGCIQINy(__x, __y)          (0xF40F - (__x-1) * 0x200 - __y * 0x1)
+#define STV090x_P1_AGCIQIN0                    STV090x_Px_AGCIQINy(1, 0)
+#define STV090x_P1_AGCIQIN1                    STV090x_Px_AGCIQINy(1, 1)
+#define STV090x_P2_AGCIQIN0                    STV090x_Px_AGCIQINy(2, 0)
+#define STV090x_P2_AGCIQIN1                    STV090x_Px_AGCIQINy(2, 1)
+#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD     0
+#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD     8
+
+#define STV090x_Px_DEMOD(__x)                  (0xF410 - (__x - 1) * 0x200)
+#define STV090x_P1_DEMOD                       STV090x_Px_DEMOD(1)
+#define STV090x_P2_DEMOD                       STV090x_Px_DEMOD(2)
+#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD        7
+#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD        1
+#define STV090x_OFFST_Px_DEMOD_STOP_FIELD      6
+#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD      1
+#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4
+#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2
+#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD   3
+#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD   1
+#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD        2
+#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD        1
+#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0
+#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2
+
+#define STV090x_Px_DMDMODCOD(__x)              (0xF411 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDMODCOD                   STV090x_Px_DMDMODCOD(1)
+#define STV090x_P2_DMDMODCOD                   STV090x_Px_DMDMODCOD(2)
+#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD   7
+#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD   1
+#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD    2
+#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD    5
+#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD      0
+#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD      2
+
+#define STV090x_Px_DSTATUS(__x)                        (0xF412 - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS                     STV090x_Px_DSTATUS(1)
+#define STV090x_P2_DSTATUS                     STV090x_Px_DSTATUS(2)
+#define STV090x_OFFST_Px_CAR_LOCK_FIELD                7
+#define STV090x_WIDTH_Px_CAR_LOCK_FIELD                1
+#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5
+#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2
+#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD  3
+#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD  1
+
+#define STV090x_Px_DSTATUS2(__x)               (0xF413 - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS2                    STV090x_Px_DSTATUS2(1)
+#define STV090x_P2_DSTATUS2                    STV090x_Px_DSTATUS2(2)
+#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD    7
+#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD    1
+#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD        3
+#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD        1
+#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD   2
+#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD   1
+#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD    1
+#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD    1
+#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0
+#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1
+
+#define STV090x_Px_DMDCFGMD(__x)               (0xF414 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFGMD                    STV090x_Px_DMDCFGMD(1)
+#define STV090x_P2_DMDCFGMD                    STV090x_Px_DMDCFGMD(2)
+#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD    7
+#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD    1
+#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD    6
+#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD    1
+#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD     4
+#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD     1
+#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD    3
+#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD    1
+#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD  2
+#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD  1
+#define STV090x_OFFST_Px_TUN_RNG_FIELD         0
+#define STV090x_WIDTH_Px_TUN_RNG_FIELD         2
+
+#define STV090x_Px_DMDCFG2(__x)                        (0xF415 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG2                     STV090x_Px_DMDCFG2(1)
+#define STV090x_P2_DMDCFG2                     STV090x_Px_DMDCFG2(2)
+#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6
+#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1
+
+#define STV090x_Px_DMDISTATE(__x)              (0xF416 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDISTATE                   STV090x_Px_DMDISTATE(1)
+#define STV090x_P2_DMDISTATE                   STV090x_Px_DMDISTATE(2)
+#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD  0
+#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD  5
+
+#define STV090x_Px_DMDTOM(__x)                 (0xF417 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_DMDTOM                      STV090x_Px_DMDTOM(1)
+#define STV090x_P2_DMDTOM                      STV090x_Px_DMDTOM(2)
+
+#define STV090x_Px_DMDSTATE(__x)               (0xF41B - (__x - 1) * 0x200)
+#define STV090x_P1_DMDSTATE                    STV090x_Px_DMDSTATE(1)
+#define STV090x_P2_DMDSTATE                    STV090x_Px_DMDSTATE(2)
+#define STV090x_OFFST_Px_HEADER_MODE_FIELD     5
+#define STV090x_WIDTH_Px_HEADER_MODE_FIELD     2
+
+#define STV090x_Px_DMDFLYW(__x)                        (0xF41C - (__x - 1) * 0x200)
+#define STV090x_P1_DMDFLYW                     STV090x_Px_DMDFLYW(1)
+#define STV090x_P2_DMDFLYW                     STV090x_Px_DMDFLYW(2)
+#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD      4
+#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD      4
+#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD    0
+#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD    4
+
+#define STV090x_Px_DSTATUS3(__x)               (0xF41D - (__x - 1) * 0x200)
+#define STV090x_P1_DSTATUS3                    STV090x_Px_DSTATUS3(1)
+#define STV090x_P2_DSTATUS3                    STV090x_Px_DSTATUS3(2)
+#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD   5
+#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD   2
+
+#define STV090x_Px_DMDCFG3(__x)                        (0xF41E - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG3                     STV090x_Px_DMDCFG3(1)
+#define STV090x_P2_DMDCFG3                     STV090x_Px_DMDCFG3(2)
+#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3
+#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1
+
+#define STV090x_Px_DMDCFG4(__x)                        (0xf41f - (__x - 1) * 0x200)
+#define STV090x_P1_DMDCFG4                     STV090x_Px_DMDCFG4(1)
+#define STV090x_P2_DMDCFG4                     STV090x_Px_DMDCFG4(2)
+
+#define STV090x_Px_CORRELMANT(__x)             (0xF420 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELMANT                  STV090x_Px_CORRELMANT(1)
+#define STV090x_P2_CORRELMANT                  STV090x_Px_CORRELMANT(2)
+#define STV090x_OFFST_Px_CORREL_MANT_FIELD     0
+#define STV090x_WIDTH_Px_CORREL_MANT_FIELD     8
+
+#define STV090x_Px_CORRELABS(__x)              (0xF421 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELABS                   STV090x_Px_CORRELABS(1)
+#define STV090x_P2_CORRELABS                   STV090x_Px_CORRELABS(2)
+#define STV090x_OFFST_Px_CORREL_ABS_FIELD      0
+#define STV090x_WIDTH_Px_CORREL_ABS_FIELD      8
+
+#define STV090x_Px_CORRELEXP(__x)              (0xF422 - (__x - 1) * 0x200)
+#define STV090x_P1_CORRELEXP                   STV090x_Px_CORRELEXP(1)
+#define STV090x_P2_CORRELEXP                   STV090x_Px_CORRELEXP(2)
+#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD   4
+#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD   4
+#define STV090x_OFFST_Px_CORREL_EXP_FIELD      0
+#define STV090x_WIDTH_Px_CORREL_EXP_FIELD      4
+
+#define STV090x_Px_PLHMODCOD(__x)              (0xF424 - (__x - 1) * 0x200)
+#define STV090x_P1_PLHMODCOD                   STV090x_Px_PLHMODCOD(1)
+#define STV090x_P2_PLHMODCOD                   STV090x_Px_PLHMODCOD(2)
+#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD   7
+#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD   1
+#define STV090x_OFFST_Px_PLH_MODCOD_FIELD      2
+#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD      5
+#define STV090x_OFFST_Px_PLH_TYPE_FIELD                0
+#define STV090x_WIDTH_Px_PLH_TYPE_FIELD                2
+
+#define STV090x_Px_AGCK32(__x)                 (0xf42b - (__x - 1) * 0x200)
+#define STV090x_P1_AGCK32                      STV090x_Px_AGCK32(1)
+#define STV090x_P2_AGCK32                      STV090x_Px_AGCK32(2)
+
+#define STV090x_Px_AGC2O(__x)                  (0xF42C - (__x - 1) * 0x200)
+#define STV090x_P1_AGC2O                       STV090x_Px_AGC2O(1)
+#define STV090x_P2_AGC2O                       STV090x_Px_AGC2O(2)
+
+#define STV090x_Px_AGC2REF(__x)                        (0xF42D - (__x - 1) * 0x200)
+#define STV090x_P1_AGC2REF                     STV090x_Px_AGC2REF(1)
+#define STV090x_P2_AGC2REF                     STV090x_Px_AGC2REF(2)
+#define STV090x_OFFST_Px_AGC2_REF_FIELD                0
+#define STV090x_WIDTH_Px_AGC2_REF_FIELD                8
+
+#define STV090x_Px_AGC1ADJ(__x)                        (0xF42E - (__x - 1) * 0x200)
+#define STV090x_P1_AGC1ADJ                     STV090x_Px_AGC1ADJ(1)
+#define STV090x_P2_AGC1ADJ                     STV090x_Px_AGC1ADJ(2)
+#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD   0
+#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD   7
+
+#define STV090x_Px_AGC2Iy(__x, __y)            (0xF437 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_AGC2I0                      STV090x_Px_AGC2Iy(1, 0)
+#define STV090x_P1_AGC2I1                      STV090x_Px_AGC2Iy(1, 1)
+#define STV090x_P2_AGC2I0                      STV090x_Px_AGC2Iy(2, 0)
+#define STV090x_P2_AGC2I1                      STV090x_Px_AGC2Iy(2, 1)
+#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0
+#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8
+
+#define STV090x_Px_CARCFG(__x)                 (0xF438 - (__x - 1) * 0x200)
+#define STV090x_P1_CARCFG                      STV090x_Px_CARCFG(1)
+#define STV090x_P2_CARCFG                      STV090x_Px_CARCFG(2)
+#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD   5
+#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD   1
+#define STV090x_OFFST_Px_ROTATON_FIELD         2
+#define STV090x_WIDTH_Px_ROTATON_FIELD         1
+#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD     0
+#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD     2
+
+#define STV090x_Px_ACLC(__x)                   (0xF439 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC                                STV090x_Px_ACLC(1)
+#define STV090x_P2_ACLC                                STV090x_Px_ACLC(2)
+#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD  4
+#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD  2
+#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD   0
+#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD   4
+
+#define STV090x_Px_BCLC(__x)                   (0xF43A - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC                                STV090x_Px_BCLC(1)
+#define STV090x_P2_BCLC                                STV090x_Px_BCLC(2)
+#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD   4
+#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD   2
+#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD    0
+#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD    4
+
+#define STV090x_Px_CARFREQ(__x)                        (0xF43D - (__x - 1) * 0x200)
+#define STV090x_P1_CARFREQ                     STV090x_Px_CARFREQ(1)
+#define STV090x_P2_CARFREQ                     STV090x_Px_CARFREQ(2)
+#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD   4
+#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD   4
+#define STV090x_OFFST_Px_BETA_FREQ_FIELD       0
+#define STV090x_WIDTH_Px_BETA_FREQ_FIELD       4
+
+#define STV090x_Px_CARHDR(__x)                 (0xF43E - (__x - 1) * 0x200)
+#define STV090x_P1_CARHDR                      STV090x_Px_CARHDR(1)
+#define STV090x_P2_CARHDR                      STV090x_Px_CARHDR(2)
+#define STV090x_OFFST_Px_FREQ_HDR_FIELD                0
+#define STV090x_WIDTH_Px_FREQ_HDR_FIELD                8
+
+#define STV090x_Px_LDT(__x)                    (0xF43F - (__x - 1) * 0x200)
+#define STV090x_P1_LDT                         STV090x_Px_LDT(1)
+#define STV090x_P2_LDT                         STV090x_Px_LDT(2)
+#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD   0
+#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD   8
+
+#define STV090x_Px_LDT2(__x)                   (0xF440 - (__x - 1) * 0x200)
+#define STV090x_P1_LDT2                                STV090x_Px_LDT2(1)
+#define STV090x_P2_LDT2                                STV090x_Px_LDT2(2)
+#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD  0
+#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD  8
+
+#define STV090x_Px_CFRICFG(__x)                        (0xF441 - (__x - 1) * 0x200)
+#define STV090x_P1_CFRICFG                     STV090x_Px_CFRICFG(1)
+#define STV090x_P2_CFRICFG                     STV090x_Px_CFRICFG(2)
+#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD     0
+#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD     1
+
+#define STV090x_Pn_CFRUPy(__x, __y)            (0xF443 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRUP0                      STV090x_Pn_CFRUPy(1, 0)
+#define STV090x_P1_CFRUP1                      STV090x_Pn_CFRUPy(1, 1)
+#define STV090x_P2_CFRUP0                      STV090x_Pn_CFRUPy(2, 0)
+#define STV090x_P2_CFRUP1                      STV090x_Pn_CFRUPy(2, 1)
+#define STV090x_OFFST_Px_CFR_UP_FIELD          0
+#define STV090x_WIDTH_Px_CFR_UP_FIELD          8
+
+#define STV090x_Pn_CFRLOWy(__x, __y)           (0xF447 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRLOW0                     STV090x_Pn_CFRLOWy(1, 0)
+#define STV090x_P1_CFRLOW1                     STV090x_Pn_CFRLOWy(1, 1)
+#define STV090x_P2_CFRLOW0                     STV090x_Pn_CFRLOWy(2, 0)
+#define STV090x_P2_CFRLOW1                     STV090x_Pn_CFRLOWy(2, 1)
+#define STV090x_OFFST_Px_CFR_LOW_FIELD         0
+#define STV090x_WIDTH_Px_CFR_LOW_FIELD         8
+
+#define STV090x_Pn_CFRINITy(__x, __y)          (0xF449 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFRINIT0                    STV090x_Pn_CFRINITy(1, 0)
+#define STV090x_P1_CFRINIT1                    STV090x_Pn_CFRINITy(1, 1)
+#define STV090x_P2_CFRINIT0                    STV090x_Pn_CFRINITy(2, 0)
+#define STV090x_P2_CFRINIT1                    STV090x_Pn_CFRINITy(2, 1)
+#define STV090x_OFFST_Px_CFR_INIT_FIELD                0
+#define STV090x_WIDTH_Px_CFR_INIT_FIELD                8
+
+#define STV090x_Px_CFRINC1(__x)                        (0xF44A - (__x - 1) * 0x200)
+#define STV090x_P1_CFRINC1                     STV090x_Px_CFRINC1(1)
+#define STV090x_P2_CFRINC1                     STV090x_Px_CFRINC1(2)
+#define STV090x_OFFST_Px_CFR_INC1_FIELD                0
+#define STV090x_WIDTH_Px_CFR_INC1_FIELD                7 /* check */
+
+#define STV090x_Px_CFRINC0(__x)                        (0xF44B - (__x - 1) * 0x200)
+#define STV090x_P1_CFRINC0                     STV090x_Px_CFRINC0(1)
+#define STV090x_P2_CFRINC0                     STV090x_Px_CFRINC0(2)
+#define STV090x_OFFST_Px_CFR_INC0_FIELD                4 /* check */
+#define STV090x_WIDTH_Px_CFR_INC0_FIELD                4
+
+#define STV090x_Pn_CFRy(__x, __y)              (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_CFR0                                STV090x_Pn_CFRy(1, 0)
+#define STV090x_P1_CFR1                                STV090x_Pn_CFRy(1, 1)
+#define STV090x_P1_CFR2                                STV090x_Pn_CFRy(1, 2)
+#define STV090x_P2_CFR0                                STV090x_Pn_CFRy(2, 0)
+#define STV090x_P2_CFR1                                STV090x_Pn_CFRy(2, 1)
+#define STV090x_P2_CFR2                                STV090x_Pn_CFRy(2, 2)
+#define STV090x_OFFST_Px_CAR_FREQ_FIELD                0
+#define STV090x_WIDTH_Px_CAR_FREQ_FIELD                8
+
+#define STV090x_Px_LDI(__x)                    (0xF44F - (__x - 1) * 0x200)
+#define STV090x_P1_LDI                         STV090x_Px_LDI(1)
+#define STV090x_P2_LDI                         STV090x_Px_LDI(2)
+#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0
+#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8
+
+#define STV090x_Px_TMGCFG(__x)                 (0xF450 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGCFG                      STV090x_Px_TMGCFG(1)
+#define STV090x_P2_TMGCFG                      STV090x_Px_TMGCFG(2)
+#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD    6
+#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD    2
+#define STV090x_OFFST_Px_DO_TIMING_FIELD       4
+#define STV090x_WIDTH_Px_DO_TIMING_FIELD       1
+#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD     0
+#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD     2
+
+#define STV090x_Px_RTC(__x)                    (0xF451 - (__x - 1) * 0x200)
+#define STV090x_P1_RTC                         STV090x_Px_RTC(1)
+#define STV090x_P2_RTC                         STV090x_Px_RTC(2)
+#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD    4
+#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD    4
+#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD     0
+#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD     4
+
+#define STV090x_Px_RTCS2(__x)                  (0xF452 - (__x - 1) * 0x200)
+#define STV090x_P1_RTCS2                       STV090x_Px_RTCS2(1)
+#define STV090x_P2_RTCS2                       STV090x_Px_RTCS2(2)
+#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD  4
+#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD  4
+#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD   0
+#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD   4
+
+#define STV090x_Px_TMGTHRISE(__x)              (0xF453 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGTHRISE                   STV090x_Px_TMGTHRISE(1)
+#define STV090x_P2_TMGTHRISE                   STV090x_Px_TMGTHRISE(2)
+#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD  0
+#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD  8
+
+#define STV090x_Px_TMGTHFALL(__x)              (0xF454 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGTHFALL                   STV090x_Px_TMGTHFALL(1)
+#define STV090x_P2_TMGTHFALL                   STV090x_Px_TMGTHFALL(2)
+#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD  0
+#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD  8
+
+#define STV090x_Px_SFRUPRATIO(__x)             (0xF455 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUPRATIO                  STV090x_Px_SFRUPRATIO(1)
+#define STV090x_P2_SFRUPRATIO                  STV090x_Px_SFRUPRATIO(2)
+#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD     0
+#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD     8
+
+#define STV090x_Px_SFRLOWRATIO(__x)            (0xF456 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOWRATIO                 STV090x_Px_SFRLOWRATIO(1)
+#define STV090x_P2_SFRLOWRATIO                 STV090x_Px_SFRLOWRATIO(2)
+#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD    0
+#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD    8
+
+#define STV090x_Px_KREFTMG(__x)                        (0xF458 - (__x - 1) * 0x200)
+#define STV090x_P1_KREFTMG                     STV090x_Px_KREFTMG(1)
+#define STV090x_P2_KREFTMG                     STV090x_Px_KREFTMG(2)
+#define STV090x_OFFST_Px_KREF_TMG_FIELD                0
+#define STV090x_WIDTH_Px_KREF_TMG_FIELD                8
+
+#define STV090x_Px_SFRSTEP(__x)                        (0xF459 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRSTEP                     STV090x_Px_SFRSTEP(1)
+#define STV090x_P2_SFRSTEP                     STV090x_Px_SFRSTEP(2)
+#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD    4
+#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD    4
+#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD  0
+#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD  4
+
+#define STV090x_Px_TMGCFG2(__x)                        (0xF45A - (__x - 1) * 0x200)
+#define STV090x_P1_TMGCFG2                     STV090x_Px_TMGCFG2(1)
+#define STV090x_P2_TMGCFG2                     STV090x_Px_TMGCFG2(2)
+#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD   0
+#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD   1
+
+#define STV090x_Px_SFRINIT1(__x)               (0xF45E - (__x - 1) * 0x200)
+#define STV090x_P1_SFRINIT1                    STV090x_Px_SFRINIT1(1)
+#define STV090x_P2_SFRINIT1                    STV090x_Px_SFRINIT1(2)
+#define STV090x_OFFST_Px_SFR_INIT1_FIELD       0
+#define STV090x_WIDTH_Px_SFR_INIT1_FIELD       7
+
+#define STV090x_Px_SFRINIT0(__x)               (0xF45F - (__x - 1) * 0x200)
+#define STV090x_P1_SFRINIT0                    STV090x_Px_SFRINIT0(1)
+#define STV090x_P2_SFRINIT0                    STV090x_Px_SFRINIT0(2)
+#define STV090x_OFFST_Px_SFR_INIT0_FIELD       0
+#define STV090x_WIDTH_Px_SFR_INIT0_FIELD       8
+
+#define STV090x_Px_SFRUP1(__x)                 (0xF460 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUP1                      STV090x_Px_SFRUP1(1)
+#define STV090x_P2_SFRUP1                      STV090x_Px_SFRUP1(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD   0
+#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD   7
+
+#define STV090x_Px_SFRUP0(__x)                 (0xF461 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRUP0                      STV090x_Px_SFRUP0(1)
+#define STV090x_P2_SFRUP0                      STV090x_Px_SFRUP0(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD   0
+#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD   8
+
+#define STV090x_Px_SFRLOW1(__x)                        (0xF462 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOW1                     STV090x_Px_SFRLOW1(1)
+#define STV090x_P2_SFRLOW1                     STV090x_Px_SFRLOW1(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD  0
+#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD  7
+
+#define STV090x_Px_SFRLOW0(__x)                        (0xF463 - (__x - 1) * 0x200)
+#define STV090x_P1_SFRLOW0                     STV090x_Px_SFRLOW0(1)
+#define STV090x_P2_SFRLOW0                     STV090x_Px_SFRLOW0(2)
+#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD  0
+#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD  8
+
+#define STV090x_Px_SFRy(__x, __y)              (0xF467 - (__x-1) * 0x200 - __y)
+#define STV090x_P1_SFR0                                STV090x_Px_SFRy(1, 0)
+#define STV090x_P1_SFR1                                STV090x_Px_SFRy(1, 1)
+#define STV090x_P1_SFR2                                STV090x_Px_SFRy(1, 2)
+#define STV090x_P1_SFR3                                STV090x_Px_SFRy(1, 3)
+#define STV090x_P2_SFR0                                STV090x_Px_SFRy(2, 0)
+#define STV090x_P2_SFR1                                STV090x_Px_SFRy(2, 1)
+#define STV090x_P2_SFR2                                STV090x_Px_SFRy(2, 2)
+#define STV090x_P2_SFR3                                STV090x_Px_SFRy(2, 3)
+#define STV090x_OFFST_Px_SYMB_FREQ_FIELD       0
+#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD       8
+
+#define STV090x_Px_TMGREG2(__x)                        (0xF468 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG2                     STV090x_Px_TMGREG2(1)
+#define STV090x_P2_TMGREG2                     STV090x_Px_TMGREG2(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD          0
+#define STV090x_WIDTH_Px_TMGREG_FIELD          8
+
+#define STV090x_Px_TMGREG1(__x)                        (0xF469 - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG1                     STV090x_Px_TMGREG1(1)
+#define STV090x_P2_TMGREG1                     STV090x_Px_TMGREG1(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD          0
+#define STV090x_WIDTH_Px_TMGREG_FIELD          8
+
+#define STV090x_Px_TMGREG0(__x)                        (0xF46A - (__x - 1) * 0x200)
+#define STV090x_P1_TMGREG0                     STV090x_Px_TMGREG0(1)
+#define STV090x_P2_TMGREG0                     STV090x_Px_TMGREG0(2)
+#define STV090x_OFFST_Px_TMGREG_FIELD          0
+#define STV090x_WIDTH_Px_TMGREG_FIELD          8
+
+#define STV090x_Px_TMGLOCKy(__x, __y)          (0xF46C - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_TMGLOCK0                    STV090x_Px_TMGLOCKy(1, 0)
+#define STV090x_P1_TMGLOCK1                    STV090x_Px_TMGLOCKy(1, 1)
+#define STV090x_P2_TMGLOCK0                    STV090x_Px_TMGLOCKy(2, 0)
+#define STV090x_P2_TMGLOCK1                    STV090x_Px_TMGLOCKy(2, 1)
+#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD   0
+#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD   8
+
+#define STV090x_Px_TMGOBS(__x)                 (0xF46D - (__x - 1) * 0x200)
+#define STV090x_P1_TMGOBS                      STV090x_Px_TMGOBS(1)
+#define STV090x_P2_TMGOBS                      STV090x_Px_TMGOBS(2)
+#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD  6
+#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD  2
+
+#define STV090x_Px_EQUALCFG(__x)               (0xF46F - (__x - 1) * 0x200)
+#define STV090x_P1_EQUALCFG                    STV090x_Px_EQUALCFG(1)
+#define STV090x_P2_EQUALCFG                    STV090x_Px_EQUALCFG(2)
+#define STV090x_OFFST_Px_EQUAL_ON_FIELD                6
+#define STV090x_WIDTH_Px_EQUAL_ON_FIELD                1
+#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD     0
+#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD     3
+
+#define STV090x_Px_EQUAIy(__x, __y)    (0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
+#define STV090x_P1_EQUAI1                      STV090x_Px_EQUAIy(1, 1)
+#define STV090x_P1_EQUAI2                      STV090x_Px_EQUAIy(1, 2)
+#define STV090x_P1_EQUAI3                      STV090x_Px_EQUAIy(1, 3)
+#define STV090x_P1_EQUAI4                      STV090x_Px_EQUAIy(1, 4)
+#define STV090x_P1_EQUAI5                      STV090x_Px_EQUAIy(1, 5)
+#define STV090x_P1_EQUAI6                      STV090x_Px_EQUAIy(1, 6)
+#define STV090x_P1_EQUAI7                      STV090x_Px_EQUAIy(1, 7)
+#define STV090x_P1_EQUAI8                      STV090x_Px_EQUAIy(1, 8)
+
+#define STV090x_P2_EQUAI1                      STV090x_Px_EQUAIy(2, 1)
+#define STV090x_P2_EQUAI2                      STV090x_Px_EQUAIy(2, 2)
+#define STV090x_P2_EQUAI3                      STV090x_Px_EQUAIy(2, 3)
+#define STV090x_P2_EQUAI4                      STV090x_Px_EQUAIy(2, 4)
+#define STV090x_P2_EQUAI5                      STV090x_Px_EQUAIy(2, 5)
+#define STV090x_P2_EQUAI6                      STV090x_Px_EQUAIy(2, 6)
+#define STV090x_P2_EQUAI7                      STV090x_Px_EQUAIy(2, 7)
+#define STV090x_P2_EQUAI8                      STV090x_Px_EQUAIy(2, 8)
+#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD      0
+#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD      8
+
+#define STV090x_Px_EQUAQy(__x, __y)    (0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
+#define STV090x_P1_EQUAQ1                      STV090x_Px_EQUAQy(1, 1)
+#define STV090x_P1_EQUAQ2                      STV090x_Px_EQUAQy(1, 2)
+#define STV090x_P1_EQUAQ3                      STV090x_Px_EQUAQy(1, 3)
+#define STV090x_P1_EQUAQ4                      STV090x_Px_EQUAQy(1, 4)
+#define STV090x_P1_EQUAQ5                      STV090x_Px_EQUAQy(1, 5)
+#define STV090x_P1_EQUAQ6                      STV090x_Px_EQUAQy(1, 6)
+#define STV090x_P1_EQUAQ7                      STV090x_Px_EQUAQy(1, 7)
+#define STV090x_P1_EQUAQ8                      STV090x_Px_EQUAQy(1, 8)
+
+#define STV090x_P2_EQUAQ1                      STV090x_Px_EQUAQy(2, 1)
+#define STV090x_P2_EQUAQ2                      STV090x_Px_EQUAQy(2, 2)
+#define STV090x_P2_EQUAQ3                      STV090x_Px_EQUAQy(2, 3)
+#define STV090x_P2_EQUAQ4                      STV090x_Px_EQUAQy(2, 4)
+#define STV090x_P2_EQUAQ5                      STV090x_Px_EQUAQy(2, 5)
+#define STV090x_P2_EQUAQ6                      STV090x_Px_EQUAQy(2, 6)
+#define STV090x_P2_EQUAQ7                      STV090x_Px_EQUAQy(2, 7)
+#define STV090x_P2_EQUAQ8                      STV090x_Px_EQUAQy(2, 8)
+#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD      0
+#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD      8
+
+#define STV090x_Px_NNOSDATATy(__x, __y)                (0xf481 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSDATAT0                  STV090x_Px_NNOSDATATy(1, 0)
+#define STV090x_P1_NNOSDATAT1                  STV090x_Px_NNOSDATATy(1, 1)
+#define STV090x_P2_NNOSDATAT0                  STV090x_Px_NNOSDATATy(2, 0)
+#define STV090x_P2_NNOSDATAT1                  STV090x_Px_NNOSDATATy(2, 1)
+#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8
+
+#define STV090x_Px_NNOSDATAy(__x, __y)         (0xf483 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSDATA0                   STV090x_Px_NNOSDATAy(1, 0)
+#define STV090x_P1_NNOSDATA1                   STV090x_Px_NNOSDATAy(1, 1)
+#define STV090x_P2_NNOSDATA0                   STV090x_Px_NNOSDATAy(2, 0)
+#define STV090x_P2_NNOSDATA1                   STV090x_Px_NNOSDATAy(2, 1)
+#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD  0
+#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD  8
+
+#define STV090x_Px_NNOSPLHTy(__x, __y)         (0xf485 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSPLHT0                   STV090x_Px_NNOSPLHTy(1, 0)
+#define STV090x_P1_NNOSPLHT1                   STV090x_Px_NNOSPLHTy(1, 1)
+#define STV090x_P2_NNOSPLHT0                   STV090x_Px_NNOSPLHTy(2, 0)
+#define STV090x_P2_NNOSPLHT1                   STV090x_Px_NNOSPLHTy(2, 1)
+#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD  0
+#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD  8
+
+#define STV090x_Px_NNOSPLHy(__x, __y)          (0xf487 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NNOSPLH0                    STV090x_Px_NNOSPLHy(1, 0)
+#define STV090x_P1_NNOSPLH1                    STV090x_Px_NNOSPLHy(1, 1)
+#define STV090x_P2_NNOSPLH0                    STV090x_Px_NNOSPLHy(2, 0)
+#define STV090x_P2_NNOSPLH1                    STV090x_Px_NNOSPLHy(2, 1)
+#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD   0
+#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD   8
+
+#define STV090x_Px_NOSDATATy(__x, __y)                 (0xf489 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSDATAT0                           STV090x_Px_NOSDATATy(1, 0)
+#define STV090x_P1_NOSDATAT1                           STV090x_Px_NOSDATATy(1, 1)
+#define STV090x_P2_NOSDATAT0                           STV090x_Px_NOSDATATy(2, 0)
+#define STV090x_P2_NOSDATAT1                           STV090x_Px_NOSDATATy(2, 1)
+#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD       0
+#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD       8
+
+#define STV090x_Px_NOSDATAy(__x, __y)          (0xf48b - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSDATA0                    STV090x_Px_NOSDATAy(1, 0)
+#define STV090x_P1_NOSDATA1                    STV090x_Px_NOSDATAy(1, 1)
+#define STV090x_P2_NOSDATA0                    STV090x_Px_NOSDATAy(2, 0)
+#define STV090x_P2_NOSDATA1                    STV090x_Px_NOSDATAy(2, 1)
+#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD        0
+#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD        8
+
+#define STV090x_Px_NOSPLHTy(__x, __y)          (0xf48d - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSPLHT0                    STV090x_Px_NOSPLHTy(1, 0)
+#define STV090x_P1_NOSPLHT1                    STV090x_Px_NOSPLHTy(1, 1)
+#define STV090x_P2_NOSPLHT0                    STV090x_Px_NOSPLHTy(2, 0)
+#define STV090x_P2_NOSPLHT1                    STV090x_Px_NOSPLHTy(2, 1)
+#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD        0
+#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD        8
+
+#define STV090x_Px_NOSPLHy(__x, __y)           (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_NOSPLH0                     STV090x_Px_NOSPLHy(1, 0)
+#define STV090x_P1_NOSPLH1                     STV090x_Px_NOSPLHy(1, 1)
+#define STV090x_P2_NOSPLH0                     STV090x_Px_NOSPLHy(2, 0)
+#define STV090x_P2_NOSPLH1                     STV090x_Px_NOSPLHy(2, 1)
+#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
+#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
+
+#define STV090x_Px_CAR2CFG(__x)                        (0xf490 - (__x - 1) * 0x200)
+#define STV090x_P1_CAR2CFG                     STV090x_Px_CAR2CFG(1)
+#define STV090x_P2_CAR2CFG                     STV090x_Px_CAR2CFG(2)
+#define STV090x_OFFST_Px_PN4_SELECT_FIELD      6
+#define STV090x_WIDTH_Px_PN4_SELECT_FIELD      1
+#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD  5
+#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD  1
+#define STV090x_OFFST_Px_ROTA2ON_FIELD         2
+#define STV090x_WIDTH_Px_ROTA2ON_FIELD         1
+#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD    0
+#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD    2
+
+#define STV090x_Px_ACLC2(__x)                  (0xf491 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2                       STV090x_Px_ACLC2(1)
+#define STV090x_P2_ACLC2                       STV090x_Px_ACLC2(2)
+#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4
+#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2
+#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD  0
+#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD  4
+
+#define STV090x_Px_BCLC2(__x)                  (0xf492 - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2                       STV090x_Px_BCLC2(1)
+#define STV090x_P2_BCLC2                       STV090x_Px_BCLC2(2)
+#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD  4
+#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD  2
+#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD   0
+#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD   4
+
+#define STV090x_Px_ACLC2S2Q(__x)               (0xf497 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S2Q                    STV090x_Px_ACLC2S2Q(1)
+#define STV090x_P2_ACLC2S2Q                    STV090x_Px_ACLC2S2Q(2)
+#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD   7
+#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD   1
+#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4
+
+#define STV090x_Px_ACLC2S28(__x)               (0xf498 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S28                    STV090x_Px_ACLC2S28(1)
+#define STV090x_P2_ACLC2S28                    STV090x_Px_ACLC2S28(2)
+#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4
+
+#define STV090x_Px_ACLC2S216A(__x)             (0xf499 - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S216A                  STV090x_Px_ACLC2S216A(1)
+#define STV090x_P2_ACLC2S216A                  STV090x_Px_ACLC2S216A(2)
+#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD       4
+#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD       2
+#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD       0
+#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD       4
+
+#define STV090x_Px_ACLC2S232A(__x)             (0xf49A - (__x - 1) * 0x200)
+#define STV090x_P1_ACLC2S232A                  STV090x_Px_ACLC2S232A(1)
+#define STV090x_P2_ACLC2S232A                  STV090x_Px_ACLC2S232A(2)
+#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD       4
+#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD       2
+#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD       0
+#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD       4
+
+#define STV090x_Px_BCLC2S2Q(__x)               (0xf49c - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S2Q                    STV090x_Px_BCLC2S2Q(1)
+#define STV090x_P2_BCLC2S2Q                    STV090x_Px_BCLC2S2Q(2)
+#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4
+
+#define STV090x_Px_BCLC2S28(__x)               (0xf49d - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S28                    STV090x_Px_BCLC2S28(1)
+#define STV090x_P2_BCLC2S28                    STV090x_Px_BCLC2S28(2)
+#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
+#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
+#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
+#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
+
+#define STV090x_Px_BCLC2S216A(__x)             (0xf49e - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S216A                  STV090x_Px_BCLC2S216A(1)
+#define STV090x_P2_BCLC2S216A                  STV090x_Px_BCLC2S216A(2)
+#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD       4
+#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD       2
+#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD       0
+#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD       4
+
+#define STV090x_Px_BCLC2S232A(__x)             (0xf49f - (__x - 1) * 0x200)
+#define STV090x_P1_BCLC2S232A                  STV090x_Px_BCLC2S232A(1)
+#define STV090x_P2_BCLC2S232A                  STV090x_Px_BCLC2S232A(2)
+#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD       4
+#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD       2
+#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD       0
+#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD       4
+
+#define STV090x_Px_PLROOT2(__x)                        (0xf4ac - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT2                     STV090x_Px_PLROOT2(1)
+#define STV090x_P2_PLROOT2                     STV090x_Px_PLROOT2(2)
+#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD   2
+#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD   2
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD   0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD   2
+
+#define STV090x_Px_PLROOT1(__x)                        (0xf4ad - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT1                     STV090x_Px_PLROOT1(1)
+#define STV090x_P2_PLROOT1                     STV090x_Px_PLROOT1(2)
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD  0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD  8
+
+#define STV090x_Px_PLROOT0(__x)                        (0xf4ae - (__x - 1) * 0x200)
+#define STV090x_P1_PLROOT0                     STV090x_Px_PLROOT0(1)
+#define STV090x_P2_PLROOT0                     STV090x_Px_PLROOT0(2)
+#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD  0
+#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD  8
+
+#define STV090x_Px_MODCODLST0(__x)             (0xf4b0 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_MODCODLST0                  STV090x_Px_MODCODLST0(1)
+#define STV090x_P2_MODCODLST0                  STV090x_Px_MODCODLST0(2)
+
+#define STV090x_Px_MODCODLST1(__x)             (0xf4b1 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST1                  STV090x_Px_MODCODLST1(1)
+#define STV090x_P2_MODCODLST1                  STV090x_Px_MODCODLST1(2)
+#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD    4
+#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD    4
+#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD  0
+#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD  4
+
+#define STV090x_Px_MODCODLST2(__x)             (0xf4b2 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST2                  STV090x_Px_MODCODLST2(1)
+#define STV090x_P2_MODCODLST2                  STV090x_Px_MODCODLST2(2)
+#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD   4
+#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD   4
+#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD   0
+#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD   4
+
+#define STV090x_Px_MODCODLST3(__x)             (0xf4b3 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST3                  STV090x_Px_MODCODLST3(1)
+#define STV090x_P2_MODCODLST3                  STV090x_Px_MODCODLST3(2)
+#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD   4
+#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD   4
+#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD   0
+#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD   4
+
+#define STV090x_Px_MODCODLST4(__x)             (0xf4b4 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST4                  STV090x_Px_MODCODLST4(1)
+#define STV090x_P2_MODCODLST4                  STV090x_Px_MODCODLST4(2)
+#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD  4
+#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD  4
+#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD   0
+#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD   4
+
+#define STV090x_Px_MODCODLST5(__x)             (0xf4b5 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST5                  STV090x_Px_MODCODLST5(1)
+#define STV090x_P2_MODCODLST5                  STV090x_Px_MODCODLST5(2)
+#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD   4
+#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD   4
+#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD   0
+#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD   4
+
+#define STV090x_Px_MODCODLST6(__x)             (0xf4b6 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST6                  STV090x_Px_MODCODLST6(1)
+#define STV090x_P2_MODCODLST6                  STV090x_Px_MODCODLST6(2)
+#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD   4
+#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD   4
+#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD   0
+#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD   4
+
+#define STV090x_Px_MODCODLST7(__x)             (0xf4b7 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST7                  STV090x_Px_MODCODLST7(1)
+#define STV090x_P2_MODCODLST7                  STV090x_Px_MODCODLST7(2)
+#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD     4
+#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD     4
+#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD      0
+#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD      4
+
+#define STV090x_Px_MODCODLST8(__x)             (0xf4b8 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST8                  STV090x_Px_MODCODLST8(1)
+#define STV090x_P2_MODCODLST8                  STV090x_Px_MODCODLST8(2)
+#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD      4
+#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD      4
+#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD      0
+#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD      4
+
+#define STV090x_Px_MODCODLST9(__x)             (0xf4b9 - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLST9                  STV090x_Px_MODCODLST9(1)
+#define STV090x_P2_MODCODLST9                  STV090x_Px_MODCODLST9(2)
+#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD      4
+#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD      4
+#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD      0
+#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD      4
+
+#define STV090x_Px_MODCODLSTA(__x)             (0xf4ba - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTA                  STV090x_Px_MODCODLSTA(1)
+#define STV090x_P2_MODCODLSTA                  STV090x_Px_MODCODLSTA(2)
+#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD     4
+#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD     4
+#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD      0
+#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD      4
+
+#define STV090x_Px_MODCODLSTB(__x)             (0xf4bb - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTB                  STV090x_Px_MODCODLSTB(1)
+#define STV090x_P2_MODCODLSTB                  STV090x_Px_MODCODLSTB(2)
+#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD      4
+#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD      4
+#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD      0
+#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD      4
+
+#define STV090x_Px_MODCODLSTC(__x)             (0xf4bc - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTC                  STV090x_Px_MODCODLSTC(1)
+#define STV090x_P2_MODCODLSTC                  STV090x_Px_MODCODLSTC(2)
+#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD      4
+#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD      4
+#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD      0
+#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD      4
+
+#define STV090x_Px_MODCODLSTD(__x)             (0xf4bd - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTD                  STV090x_Px_MODCODLSTD(1)
+#define STV090x_P2_MODCODLSTD                  STV090x_Px_MODCODLSTD(2)
+#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD      4
+#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD      4
+#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD      0
+#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD      4
+
+#define STV090x_Px_MODCODLSTE(__x)             (0xf4be - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTE                  STV090x_Px_MODCODLSTE(1)
+#define STV090x_P2_MODCODLSTE                  STV090x_Px_MODCODLSTE(2)
+#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD      4
+#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD      4
+#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD      0
+#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD      4
+
+#define STV090x_Px_MODCODLSTF(__x)             (0xf4bf - (__x - 1) * 0x200)
+#define STV090x_P1_MODCODLSTF                  STV090x_Px_MODCODLSTF(1)
+#define STV090x_P2_MODCODLSTF                  STV090x_Px_MODCODLSTF(2)
+#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD      4
+#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD      4
+
+#define STV090x_Px_GAUSSR0(__x)                        (0xf4c0 - (__x - 1) * 0x200)
+#define STV090x_P1_GAUSSR0                     STV090x_Px_GAUSSR0(1)
+#define STV090x_P2_GAUSSR0                     STV090x_Px_GAUSSR0(2)
+#define STV090x_OFFST_Px_EN_CCIMODE_FIELD      7
+#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD      1
+#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD     0
+#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD     7
+
+#define STV090x_Px_CCIR0(__x)                  (0xf4c1 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIR0                       STV090x_Px_CCIR0(1)
+#define STV090x_P2_CCIR0                       STV090x_Px_CCIR0(2)
+#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD   7
+#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD   1
+#define STV090x_OFFST_Px_R0_CCI_FIELD          0
+#define STV090x_WIDTH_Px_R0_CCI_FIELD          7
+
+#define STV090x_Px_CCIQUANT(__x)               (0xf4c2 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIQUANT                    STV090x_Px_CCIQUANT(1)
+#define STV090x_P2_CCIQUANT                    STV090x_Px_CCIQUANT(2)
+#define STV090x_OFFST_Px_CCI_BETA_FIELD                5
+#define STV090x_WIDTH_Px_CCI_BETA_FIELD                3
+#define STV090x_OFFST_Px_CCI_QUANT_FIELD       0
+#define STV090x_WIDTH_Px_CCI_QUANT_FIELD       5
+
+#define STV090x_Px_CCITHRESH(__x)              (0xf4c3 - (__x - 1) * 0x200)
+#define STV090x_P1_CCITHRESH                   STV090x_Px_CCITHRESH(1)
+#define STV090x_P2_CCITHRESH                   STV090x_Px_CCITHRESH(2)
+#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD   0
+#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD   8
+
+#define STV090x_Px_CCIACC(__x)                 (0xf4c4 - (__x - 1) * 0x200)
+#define STV090x_P1_CCIACC                      STV090x_Px_CCIACC(1)
+#define STV090x_P2_CCIACC                      STV090x_Px_CCIACC(2)
+#define STV090x_OFFST_Px_CCI_VALUE_FIELD       0
+#define STV090x_WIDTH_Px_CCI_VALUE_FIELD       8
+
+#define STV090x_Px_DMDRESCFG(__x)              (0xF4C6 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDRESCFG                   STV090x_Px_DMDRESCFG(1)
+#define STV090x_P2_DMDRESCFG                   STV090x_Px_DMDRESCFG(2)
+#define STV090x_OFFST_Px_DMDRES_RESET_FIELD    7
+#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD    1
+
+#define STV090x_Px_DMDRESADR(__x)              (0xF4C7 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDRESADR                   STV090x_Px_DMDRESADR(1)
+#define STV090x_P2_DMDRESADR                   STV090x_Px_DMDRESADR(2)
+#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD   0
+#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD   4
+
+#define STV090x_Px_DMDRESDATAy(__x, __y)       (0xF4C8 - (__x - 1) * 0x200 + (7 - __y))
+#define STV090x_P1_DMDRESDATA0                 STV090x_Px_DMDRESDATAy(1, 0)
+#define STV090x_P1_DMDRESDATA1                 STV090x_Px_DMDRESDATAy(1, 1)
+#define STV090x_P1_DMDRESDATA2                 STV090x_Px_DMDRESDATAy(1, 2)
+#define STV090x_P1_DMDRESDATA3                 STV090x_Px_DMDRESDATAy(1, 3)
+#define STV090x_P1_DMDRESDATA4                 STV090x_Px_DMDRESDATAy(1, 4)
+#define STV090x_P1_DMDRESDATA5                 STV090x_Px_DMDRESDATAy(1, 5)
+#define STV090x_P1_DMDRESDATA6                 STV090x_Px_DMDRESDATAy(1, 6)
+#define STV090x_P1_DMDRESDATA7                 STV090x_Px_DMDRESDATAy(1, 7)
+#define STV090x_P2_DMDRESDATA0                 STV090x_Px_DMDRESDATAy(2, 0)
+#define STV090x_P2_DMDRESDATA1                 STV090x_Px_DMDRESDATAy(2, 1)
+#define STV090x_P2_DMDRESDATA2                 STV090x_Px_DMDRESDATAy(2, 2)
+#define STV090x_P2_DMDRESDATA3                 STV090x_Px_DMDRESDATAy(2, 3)
+#define STV090x_P2_DMDRESDATA4                 STV090x_Px_DMDRESDATAy(2, 4)
+#define STV090x_P2_DMDRESDATA5                 STV090x_Px_DMDRESDATAy(2, 5)
+#define STV090x_P2_DMDRESDATA6                 STV090x_Px_DMDRESDATAy(2, 6)
+#define STV090x_P2_DMDRESDATA7                 STV090x_Px_DMDRESDATAy(2, 7)
+#define STV090x_OFFST_Px_DMDRES_DATA_FIELD     0
+#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD     8
+
+#define STV090x_Px_FFEIy(__x, __y)             (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
+#define STV090x_P1_FFEI1                       STV090x_Px_FFEIy(1, 1)
+#define STV090x_P1_FFEI2                       STV090x_Px_FFEIy(1, 2)
+#define STV090x_P1_FFEI3                       STV090x_Px_FFEIy(1, 3)
+#define STV090x_P1_FFEI4                       STV090x_Px_FFEIy(1, 4)
+#define STV090x_P2_FFEI1                       STV090x_Px_FFEIy(2, 1)
+#define STV090x_P2_FFEI2                       STV090x_Px_FFEIy(2, 2)
+#define STV090x_P2_FFEI3                       STV090x_Px_FFEIy(2, 3)
+#define STV090x_P2_FFEI4                       STV090x_Px_FFEIy(2, 4)
+#define STV090x_OFFST_Px_FFE_ACCIy_FIELD       0
+#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD       8
+
+#define STV090x_Px_FFEQy(__x, __y)             (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
+#define STV090x_P1_FFEQ1                       STV090x_Px_FFEQy(1, 1)
+#define STV090x_P1_FFEQ2                       STV090x_Px_FFEQy(1, 2)
+#define STV090x_P1_FFEQ3                       STV090x_Px_FFEQy(1, 3)
+#define STV090x_P1_FFEQ4                       STV090x_Px_FFEQy(1, 4)
+#define STV090x_P2_FFEQ1                       STV090x_Px_FFEQy(2, 1)
+#define STV090x_P2_FFEQ2                       STV090x_Px_FFEQy(2, 2)
+#define STV090x_P2_FFEQ3                       STV090x_Px_FFEQy(2, 3)
+#define STV090x_P2_FFEQ4                       STV090x_Px_FFEQy(2, 4)
+#define STV090x_OFFST_Px_FFE_ACCQy_FIELD       0
+#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD       8
+
+#define STV090x_Px_FFECFG(__x)                 (0xf4d8 - (__x - 1) * 0x200)
+#define STV090x_P1_FFECFG                      STV090x_Px_FFECFG(1)
+#define STV090x_P2_FFECFG                      STV090x_Px_FFECFG(2)
+#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD     6
+#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD     1
+
+#define STV090x_Px_SMAPCOEF7(__x)              (0xf500 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF7                   STV090x_Px_SMAPCOEF7(1)
+#define STV090x_P2_SMAPCOEF7                   STV090x_Px_SMAPCOEF7(2)
+#define STV090x_OFFST_Px_DIS_QSCALE_FIELD      7
+#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD      1
+#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD        0
+#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD        7
+
+#define STV090x_Px_SMAPCOEF6(__x)              (0xf501 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF6                   STV090x_Px_SMAPCOEF6(1)
+#define STV090x_P2_SMAPCOEF6                   STV090x_Px_SMAPCOEF6(2)
+#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD    2
+#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD    1
+#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD    1
+#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD    1
+#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD      0
+#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD      1
+
+#define STV090x_Px_SMAPCOEF5(__x)                      (0xf502 - (__x - 1) * 0x200)
+#define STV090x_P1_SMAPCOEF5                           STV090x_Px_SMAPCOEF5(1)
+#define STV090x_P2_SMAPCOEF5                           STV090x_Px_SMAPCOEF5(2)
+#define STV090x_OFFST_Px_DIS_8SCALE_FIELD              7
+#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD              1
+#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD       0
+#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD       7
+
+#define STV090x_Px_DMDPLHSTAT(__x)             (0xF520 - (__x - 1) * 0x200)
+#define STV090x_P1_DMDPLHSTAT                  STV090x_Px_DMDPLHSTAT(1)
+#define STV090x_P2_DMDPLHSTAT                  STV090x_Px_DMDPLHSTAT(2)
+#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD   0
+#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD   8
+
+#define STV090x_Px_LOCKTIMEy(__x, __y)         (0xF525 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_LOCKTIME0                   STV090x_Px_LOCKTIMEy(1, 0)
+#define STV090x_P1_LOCKTIME1                   STV090x_Px_LOCKTIMEy(1, 1)
+#define STV090x_P1_LOCKTIME2                   STV090x_Px_LOCKTIMEy(1, 2)
+#define STV090x_P1_LOCKTIME3                   STV090x_Px_LOCKTIMEy(1, 3)
+#define STV090x_P2_LOCKTIME0                   STV090x_Px_LOCKTIMEy(2, 0)
+#define STV090x_P2_LOCKTIME1                   STV090x_Px_LOCKTIMEy(2, 1)
+#define STV090x_P2_LOCKTIME2                   STV090x_Px_LOCKTIMEy(2, 2)
+#define STV090x_P2_LOCKTIME3                   STV090x_Px_LOCKTIMEy(2, 3)
+#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD  0
+#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD  8
+
+#define STV090x_Px_TNRCFG(__x)                 (0xf4e0 - (__x - 1) * 0x200) /* check */
+#define STV090x_P1_TNRCFG                      STV090x_Px_TNRCFG(1)
+#define STV090x_P2_TNRCFG                      STV090x_Px_TNRCFG(2)
+
+#define STV090x_Px_TNRCFG2(__x)                        (0xf4e1 - (__x - 1) * 0x200)
+#define STV090x_P1_TNRCFG2                     STV090x_Px_TNRCFG2(1)
+#define STV090x_P2_TNRCFG2                     STV090x_Px_TNRCFG2(2)
+#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD      7
+#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD      1
+
+#define STV090x_Px_VITSCALE(__x)               (0xf532 - (__x - 1) * 0x200)
+#define STV090x_P1_VITSCALE                    STV090x_Px_VITSCALE(1)
+#define STV090x_P2_VITSCALE                    STV090x_Px_VITSCALE(2)
+#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD   7
+#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD   1
+#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD  6
+#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD  1
+#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD  3
+#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD  1
+#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD     1
+#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD     1
+
+#define STV090x_Px_FECM(__x)                   (0xf533 - (__x - 1) * 0x200)
+#define STV090x_P1_FECM                                STV090x_Px_FECM(1)
+#define STV090x_P2_FECM                                STV090x_Px_FECM(2)
+#define STV090x_OFFST_Px_DSS_DVB_FIELD         7
+#define STV090x_WIDTH_Px_DSS_DVB_FIELD         1
+#define STV090x_OFFST_Px_DSS_SRCH_FIELD                4
+#define STV090x_WIDTH_Px_DSS_SRCH_FIELD                1
+#define STV090x_OFFST_Px_SYNCVIT_FIELD         1
+#define STV090x_WIDTH_Px_SYNCVIT_FIELD         1
+#define STV090x_OFFST_Px_IQINV_FIELD           0
+#define STV090x_WIDTH_Px_IQINV_FIELD           1
+
+#define STV090x_Px_VTH12(__x)                  (0xf534 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH12                       STV090x_Px_VTH12(1)
+#define STV090x_P2_VTH12                       STV090x_Px_VTH12(2)
+#define STV090x_OFFST_Px_VTH12_FIELD           0
+#define STV090x_WIDTH_Px_VTH12_FIELD           8
+
+#define STV090x_Px_VTH23(__x)                  (0xf535 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH23                       STV090x_Px_VTH23(1)
+#define STV090x_P2_VTH23                       STV090x_Px_VTH23(2)
+#define STV090x_OFFST_Px_VTH23_FIELD           0
+#define STV090x_WIDTH_Px_VTH23_FIELD           8
+
+#define STV090x_Px_VTH34(__x)                  (0xf536 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH34                       STV090x_Px_VTH34(1)
+#define STV090x_P2_VTH34                       STV090x_Px_VTH34(2)
+#define STV090x_OFFST_Px_VTH34_FIELD           0
+#define STV090x_WIDTH_Px_VTH34_FIELD           8
+
+#define STV090x_Px_VTH56(__x)                  (0xf537 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH56                       STV090x_Px_VTH56(1)
+#define STV090x_P2_VTH56                       STV090x_Px_VTH56(2)
+#define STV090x_OFFST_Px_VTH56_FIELD           0
+#define STV090x_WIDTH_Px_VTH56_FIELD           8
+
+#define STV090x_Px_VTH67(__x)                  (0xf538 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH67                       STV090x_Px_VTH67(1)
+#define STV090x_P2_VTH67                       STV090x_Px_VTH67(2)
+#define STV090x_OFFST_Px_VTH67_FIELD           0
+#define STV090x_WIDTH_Px_VTH67_FIELD           8
+
+#define STV090x_Px_VTH78(__x)                  (0xf539 - (__x - 1) * 0x200)
+#define STV090x_P1_VTH78                       STV090x_Px_VTH78(1)
+#define STV090x_P2_VTH78                       STV090x_Px_VTH78(2)
+#define STV090x_OFFST_Px_VTH78_FIELD           0
+#define STV090x_WIDTH_Px_VTH78_FIELD           8
+
+#define STV090x_Px_VITCURPUN(__x)              (0xf53a - (__x - 1) * 0x200)
+#define STV090x_P1_VITCURPUN                   STV090x_Px_VITCURPUN(1)
+#define STV090x_P2_VITCURPUN                   STV090x_Px_VITCURPUN(2)
+#define STV090x_OFFST_Px_VIT_CURPUN_FIELD      0
+#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD      5
+
+#define STV090x_Px_VERROR(__x)                 (0xf53b - (__x - 1) * 0x200)
+#define STV090x_P1_VERROR                      STV090x_Px_VERROR(1)
+#define STV090x_P2_VERROR                      STV090x_Px_VERROR(2)
+#define STV090x_OFFST_Px_REGERR_VIT_FIELD      0
+#define STV090x_WIDTH_Px_REGERR_VIT_FIELD      8
+
+#define STV090x_Px_PRVIT(__x)                  (0xf53c - (__x - 1) * 0x200)
+#define STV090x_P1_PRVIT                       STV090x_Px_PRVIT(1)
+#define STV090x_P2_PRVIT                       STV090x_Px_PRVIT(2)
+#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD     6
+#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD     1
+#define STV090x_OFFST_Px_E7_8VIT_FIELD         5
+#define STV090x_WIDTH_Px_E7_8VIT_FIELD         1
+#define STV090x_OFFST_Px_E6_7VIT_FIELD         4
+#define STV090x_WIDTH_Px_E6_7VIT_FIELD         1
+#define STV090x_OFFST_Px_E5_6VIT_FIELD         3
+#define STV090x_WIDTH_Px_E5_6VIT_FIELD         1
+#define STV090x_OFFST_Px_E3_4VIT_FIELD         2
+#define STV090x_WIDTH_Px_E3_4VIT_FIELD         1
+#define STV090x_OFFST_Px_E2_3VIT_FIELD         1
+#define STV090x_WIDTH_Px_E2_3VIT_FIELD         1
+#define STV090x_OFFST_Px_E1_2VIT_FIELD         0
+#define STV090x_WIDTH_Px_E1_2VIT_FIELD         1
+
+#define STV090x_Px_VAVSRVIT(__x)               (0xf53d - (__x - 1) * 0x200)
+#define STV090x_P1_VAVSRVIT                    STV090x_Px_VAVSRVIT(1)
+#define STV090x_P2_VAVSRVIT                    STV090x_Px_VAVSRVIT(2)
+#define STV090x_OFFST_Px_SNVIT_FIELD           4
+#define STV090x_WIDTH_Px_SNVIT_FIELD           2
+#define STV090x_OFFST_Px_TOVVIT_FIELD          2
+#define STV090x_WIDTH_Px_TOVVIT_FIELD          2
+#define STV090x_OFFST_Px_HYPVIT_FIELD          0
+#define STV090x_WIDTH_Px_HYPVIT_FIELD          2
+
+#define STV090x_Px_VSTATUSVIT(__x)             (0xf53e - (__x - 1) * 0x200)
+#define STV090x_P1_VSTATUSVIT                  STV090x_Px_VSTATUSVIT(1)
+#define STV090x_P2_VSTATUSVIT                  STV090x_Px_VSTATUSVIT(2)
+#define STV090x_OFFST_Px_PRFVIT_FIELD          4
+#define STV090x_WIDTH_Px_PRFVIT_FIELD          1
+#define STV090x_OFFST_Px_LOCKEDVIT_FIELD       3
+#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD       1
+
+#define STV090x_Px_VTHINUSE(__x)               (0xf53f - (__x - 1) * 0x200)
+#define STV090x_P1_VTHINUSE                    STV090x_Px_VTHINUSE(1)
+#define STV090x_P2_VTHINUSE                    STV090x_Px_VTHINUSE(2)
+#define STV090x_OFFST_Px_VIT_INUSE_FIELD       0
+#define STV090x_WIDTH_Px_VIT_INUSE_FIELD       8
+
+#define STV090x_Px_KDIV12(__x)                 (0xf540 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV12                      STV090x_Px_KDIV12(1)
+#define STV090x_P2_KDIV12                      STV090x_Px_KDIV12(2)
+#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD    7
+
+#define STV090x_Px_KDIV23(__x)                 (0xf541 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV23                      STV090x_Px_KDIV23(1)
+#define STV090x_P2_KDIV23                      STV090x_Px_KDIV23(2)
+#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD    7
+
+#define STV090x_Px_KDIV34(__x)                 (0xf542 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV34                      STV090x_Px_KDIV34(1)
+#define STV090x_P2_KDIV34                      STV090x_Px_KDIV34(2)
+#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD    7
+
+#define STV090x_Px_KDIV56(__x)                 (0xf543 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV56                      STV090x_Px_KDIV56(1)
+#define STV090x_P2_KDIV56                      STV090x_Px_KDIV56(2)
+#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD    7
+
+#define STV090x_Px_KDIV67(__x)                 (0xf544 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV67                      STV090x_Px_KDIV67(1)
+#define STV090x_P2_KDIV67                      STV090x_Px_KDIV67(2)
+#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD    7
+
+#define STV090x_Px_KDIV78(__x)                 (0xf545 - (__x - 1) * 0x200)
+#define STV090x_P1_KDIV78                      STV090x_Px_KDIV78(1)
+#define STV090x_P2_KDIV78                      STV090x_Px_KDIV78(2)
+#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD    0
+#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD    7
+
+#define STV090x_Px_PDELCTRL1(__x)              (0xf550 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELCTRL1                   STV090x_Px_PDELCTRL1(1)
+#define STV090x_P2_PDELCTRL1                   STV090x_Px_PDELCTRL1(2)
+#define STV090x_OFFST_Px_INV_MISMASK_FIELD     7
+#define STV090x_WIDTH_Px_INV_MISMASK_FIELD     1
+#define STV090x_OFFST_Px_FILTER_EN_FIELD       5
+#define STV090x_WIDTH_Px_FILTER_EN_FIELD       1
+#define STV090x_OFFST_Px_EN_MIS00_FIELD                1
+#define STV090x_WIDTH_Px_EN_MIS00_FIELD                1
+#define STV090x_OFFST_Px_ALGOSWRST_FIELD       0
+#define STV090x_WIDTH_Px_ALGOSWRST_FIELD       1
+
+#define STV090x_Px_PDELCTRL2(__x)              (0xf551 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELCTRL2                   STV090x_Px_PDELCTRL2(1)
+#define STV090x_P2_PDELCTRL2                   STV090x_Px_PDELCTRL2(2)
+#define STV090x_OFFST_Px_FORCE_CONTINUOUS      7
+#define STV090x_WIDTH_Px_FORCE_CONTINUOUS      1
+#define STV090x_OFFST_Px_RESET_UPKO_COUNT      6
+#define STV090x_WIDTH_Px_RESET_UPKO_COUNT      1
+#define STV090x_OFFST_Px_USER_PKTDELIN_NB      5
+#define STV090x_WIDTH_Px_USER_PKTDELIN_NB      1
+#define STV090x_OFFST_Px_FORCE_LOCKED          4
+#define STV090x_WIDTH_Px_FORCE_LOCKED          1
+#define STV090x_OFFST_Px_DATA_UNBBSCRAM                3
+#define STV090x_WIDTH_Px_DATA_UNBBSCRAM                1
+#define STV090x_OFFST_Px_FORCE_LONGPACKET      2
+#define STV090x_WIDTH_Px_FORCE_LONGPACKET      1
+#define STV090x_OFFST_Px_FRAME_MODE_FIELD      1
+#define STV090x_WIDTH_Px_FRAME_MODE_FIELD      1
+
+#define STV090x_Px_HYSTTHRESH(__x)             (0xf554 - (__x - 1) * 0x200)
+#define STV090x_P1_HYSTTHRESH                  STV090x_Px_HYSTTHRESH(1)
+#define STV090x_P2_HYSTTHRESH                  STV090x_Px_HYSTTHRESH(2)
+#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD    4
+#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD    4
+#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD        0
+#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD        4
+
+#define STV090x_Px_ISIENTRY(__x)               (0xf55e - (__x - 1) * 0x200)
+#define STV090x_P1_ISIENTRY                    STV090x_Px_ISIENTRY(1)
+#define STV090x_P2_ISIENTRY                    STV090x_Px_ISIENTRY(2)
+#define STV090x_OFFST_Px_ISI_ENTRY_FIELD       0
+#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD       8
+
+#define STV090x_Px_ISIBITENA(__x)              (0xf55f - (__x - 1) * 0x200)
+#define STV090x_P1_ISIBITENA                   STV090x_Px_ISIBITENA(1)
+#define STV090x_P2_ISIBITENA                   STV090x_Px_ISIBITENA(2)
+#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD      0
+#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD      8
+
+#define STV090x_Px_MATSTRy(__x, __y)           (0xf561 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_MATSTR0                     STV090x_Px_MATSTRy(1, 0)
+#define STV090x_P1_MATSTR1                     STV090x_Px_MATSTRy(1, 1)
+#define STV090x_P2_MATSTR0                     STV090x_Px_MATSTRy(2, 0)
+#define STV090x_P2_MATSTR1                     STV090x_Px_MATSTRy(2, 1)
+#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD  0
+#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD  8
+
+#define STV090x_Px_UPLSTRy(__x, __y)           (0xf563 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_UPLSTR0                     STV090x_Px_UPLSTRy(1, 0)
+#define STV090x_P1_UPLSTR1                     STV090x_Px_UPLSTRy(1, 1)
+#define STV090x_P2_UPLSTR0                     STV090x_Px_UPLSTRy(2, 0)
+#define STV090x_P2_UPLSTR1                     STV090x_Px_UPLSTRy(2, 1)
+#define STV090x_OFFST_Px_UPL_CURRENT_FIELD     0
+#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD     8
+
+#define STV090x_Px_DFLSTRy(__x, __y)           (0xf565 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_DFLSTR0                     STV090x_Px_DFLSTRy(1, 0)
+#define STV090x_P1_DFLSTR1                     STV090x_Px_DFLSTRy(1, 1)
+#define STV090x_P2_DFLSTR0                     STV090x_Px_DFLSTRy(2, 0)
+#define STV090x_P2_DFLSTR1                     STV090x_Px_DFLSTRy(2, 1)
+#define STV090x_OFFST_Px_DFL_CURRENT_FIELD     0
+#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD     8
+
+#define STV090x_Px_SYNCSTR(__x)                        (0xf566 - (__x - 1) * 0x200)
+#define STV090x_P1_SYNCSTR                     STV090x_Px_SYNCSTR(1)
+#define STV090x_P2_SYNCSTR                     STV090x_Px_SYNCSTR(2)
+#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD    0
+#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD    8
+
+#define STV090x_Px_SYNCDSTRy(__x, __y)         (0xf568 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_SYNCDSTR0                   STV090x_Px_SYNCDSTRy(1, 0)
+#define STV090x_P1_SYNCDSTR1                   STV090x_Px_SYNCDSTRy(1, 1)
+#define STV090x_P2_SYNCDSTR0                   STV090x_Px_SYNCDSTRy(2, 0)
+#define STV090x_P2_SYNCDSTR1                   STV090x_Px_SYNCDSTRy(2, 1)
+#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD   0
+#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD   8
+
+#define STV090x_Px_PDELSTATUS1(__x)            (0xf569 - (__x - 1) * 0x200)
+#define STV090x_P1_PDELSTATUS1                 STV090x_Px_PDELSTATUS1(1)
+#define STV090x_P2_PDELSTATUS1                 STV090x_Px_PDELSTATUS1(2)
+#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD   1
+#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD   1
+#define STV090x_OFFST_Px_FIRST_LOCK_FIELD      0
+#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD      1
+
+#define STV090x_Px_PDELSTATUS2(__x)            (0xf56a - (__x - 1) * 0x200)
+#define STV090x_P1_PDELSTATUS2                 STV090x_Px_PDELSTATUS2(1)
+#define STV090x_P2_PDELSTATUS2                 STV090x_Px_PDELSTATUS2(2)
+#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD    2
+#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD    5
+#define STV090x_OFFST_Px_FRAME_TYPE_FIELD      0
+#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD      2
+
+#define STV090x_Px_BBFCRCKO1(__x)              (0xf56b - (__x - 1) * 0x200)
+#define STV090x_P1_BBFCRCKO1                   STV090x_Px_BBFCRCKO1(1)
+#define STV090x_P2_BBFCRCKO1                   STV090x_Px_BBFCRCKO1(2)
+#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD    0
+#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD    8
+
+#define STV090x_Px_BBFCRCKO0(__x)              (0xf56c - (__x - 1) * 0x200)
+#define STV090x_P1_BBFCRCKO0                   STV090x_Px_BBFCRCKO0(1)
+#define STV090x_P2_BBFCRCKO0                   STV090x_Px_BBFCRCKO0(2)
+#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD    0
+#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD    8
+
+#define STV090x_Px_UPCRCKO1(__x)               (0xf56d - (__x - 1) * 0x200)
+#define STV090x_P1_UPCRCKO1                    STV090x_Px_UPCRCKO1(1)
+#define STV090x_P2_UPCRCKO1                    STV090x_Px_UPCRCKO1(2)
+#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD    0
+#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD    8
+
+#define STV090x_Px_UPCRCKO0(__x)               (0xf56e - (__x - 1) * 0x200)
+#define STV090x_P1_UPCRCKO0                    STV090x_Px_UPCRCKO0(1)
+#define STV090x_P2_UPCRCKO0                    STV090x_Px_UPCRCKO0(2)
+#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD    0
+#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD    8
+
+#define STV090x_NBITER_NFx(__x)                                (0xFA03 + (__x - 4) * 0x1)
+#define STV090x_NBITER_NF4                             STV090x_NBITER_NFx(4)
+#define STV090x_NBITER_NF5                             STV090x_NBITER_NFx(5)
+#define STV090x_NBITER_NF6                             STV090x_NBITER_NFx(6)
+#define STV090x_NBITER_NF7                             STV090x_NBITER_NFx(7)
+#define STV090x_NBITER_NF8                             STV090x_NBITER_NFx(8)
+#define STV090x_NBITER_NF9                             STV090x_NBITER_NFx(9)
+#define STV090x_NBITER_NF10                            STV090x_NBITER_NFx(10)
+#define STV090x_NBITER_NF11                            STV090x_NBITER_NFx(11)
+#define STV090x_NBITER_NF12                            STV090x_NBITER_NFx(12)
+#define STV090x_NBITER_NF13                            STV090x_NBITER_NFx(13)
+#define STV090x_NBITER_NF14                            STV090x_NBITER_NFx(14)
+#define STV090x_NBITER_NF15                            STV090x_NBITER_NFx(15)
+#define STV090x_NBITER_NF16                            STV090x_NBITER_NFx(16)
+#define STV090x_NBITER_NF17                            STV090x_NBITER_NFx(17)
+
+#define STV090x_NBITERNOERR                            0xFA3F
+#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD           0
+#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD           4
+
+#define STV090x_GAINLLR_NFx(__x)                       (0xFA43 + (__x - 4) * 0x1)
+#define STV090x_GAINLLR_NF4                            STV090x_GAINLLR_NFx(4)
+#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD          7
+
+#define STV090x_GAINLLR_NF5                            STV090x_GAINLLR_NFx(5)
+#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD          7
+
+#define STV090x_GAINLLR_NF6                            STV090x_GAINLLR_NFx(6)
+#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD          7
+
+#define STV090x_GAINLLR_NF7                            STV090x_GAINLLR_NFx(7)
+#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD          7
+
+#define STV090x_GAINLLR_NF8                            STV090x_GAINLLR_NFx(8)
+#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD          7
+
+#define STV090x_GAINLLR_NF9                            STV090x_GAINLLR_NFx(9)
+#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD          7
+
+#define STV090x_GAINLLR_NF10                           STV090x_GAINLLR_NFx(10)
+#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD          7
+
+#define STV090x_GAINLLR_NF11                           STV090x_GAINLLR_NFx(11)
+#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD         0
+#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD         7
+
+#define STV090x_GAINLLR_NF12                           STV090x_GAINLLR_NFx(12)
+#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD          7
+
+#define STV090x_GAINLLR_NF13                           STV090x_GAINLLR_NFx(13)
+#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD          7
+
+#define STV090x_GAINLLR_NF14                           STV090x_GAINLLR_NFx(14)
+#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD          7
+
+#define STV090x_GAINLLR_NF15                           STV090x_GAINLLR_NFx(15)
+#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD          7
+
+#define STV090x_GAINLLR_NF16                           STV090x_GAINLLR_NFx(16)
+#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD          0
+#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD          7
+
+#define STV090x_GAINLLR_NF17                           STV090x_GAINLLR_NFx(17)
+#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD         0
+#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD         7
+
+#define STV090x_GENCFG                                 0xFA86
+#define STV090x_OFFST_BROADCAST_FIELD                  4
+#define STV090x_WIDTH_BROADCAST_FIELD                  1
+#define STV090x_OFFST_PRIORITY_FIELD                   1
+#define STV090x_WIDTH_PRIORITY_FIELD                   1
+#define STV090x_OFFST_DDEMOD_FIELD                     0
+#define STV090x_WIDTH_DDEMOD_FIELD                     1
+
+#define STV090x_LDPCERRx(__x)                          (0xFA97 - (__x  * 0x1))
+#define STV090x_LDPCERR0                               STV090x_LDPCERRx(0)
+#define STV090x_LDPCERR1                               STV090x_LDPCERRx(1)
+#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD     0
+#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD     8
+
+#define STV090x_BCHERR                                 0xFA98
+#define STV090x_OFFST_Px_ERRORFLAG_FIELD               4
+#define STV090x_WIDTH_Px_ERRORFLAG_FIELD               1
+#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD      0
+#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD      4
+
+#define STV090x_Px_TSSTATEM(__x)                       (0xF570 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATEM                            STV090x_Px_TSSTATEM(1)
+#define STV090x_P2_TSSTATEM                            STV090x_Px_TSSTATEM(2)
+#define STV090x_OFFST_Px_TSDIL_ON_FIELD                        7
+#define STV090x_WIDTH_Px_TSDIL_ON_FIELD                        1
+#define STV090x_OFFST_Px_TSRS_ON_FIELD                 5
+#define STV090x_WIDTH_Px_TSRS_ON_FIELD                 1
+
+#define STV090x_Px_TSCFGH(__x)                         (0xF572 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGH                              STV090x_Px_TSCFGH(1)
+#define STV090x_P2_TSCFGH                              STV090x_Px_TSCFGH(2)
+#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD            7
+#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD            1
+#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD           6
+#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD           1
+#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD                5
+#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD                1
+#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD           4
+#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD           1
+#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD         3
+#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD         1
+#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD                1
+#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD                2
+#define STV090x_OFFST_Px_RST_HWARE_FIELD               0
+#define STV090x_WIDTH_Px_RST_HWARE_FIELD               1
+
+#define STV090x_Px_TSCFGM(__x)                         (0xF573 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGM                              STV090x_Px_TSCFGM(1)
+#define STV090x_P2_TSCFGM                              STV090x_Px_TSCFGM(2)
+#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD         6
+#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD         2
+#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD         5
+#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD         1
+#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD          0
+#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD          1
+
+#define STV090x_Px_TSCFGL(__x)                         (0xF574 - (__x - 1) * 0x200)
+#define STV090x_P1_TSCFGL                              STV090x_Px_TSCFGL(1)
+#define STV090x_P2_TSCFGL                              STV090x_Px_TSCFGL(2)
+#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD       6
+#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD       2
+#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD           4
+#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD           2
+#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD       3
+#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD       1
+#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD         2
+#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD         1
+#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD          1
+#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD          1
+
+#define STV090x_Px_TSINSDELH(__x)                      (0xF576 - (__x - 1) * 0x200)
+#define STV090x_P1_TSINSDELH                           STV090x_Px_TSINSDELH(1)
+#define STV090x_P2_TSINSDELH                           STV090x_Px_TSINSDELH(2)
+#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD          7
+#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD          1
+#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD          6
+#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD          1
+
+#define STV090x_Px_TSSPEED(__x)                                (0xF580 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSPEED                             STV090x_Px_TSSPEED(1)
+#define STV090x_P2_TSSPEED                             STV090x_Px_TSSPEED(2)
+#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD         0
+#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD         8
+
+#define STV090x_Px_TSSTATUS(__x)                       (0xF581 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATUS                            STV090x_Px_TSSTATUS(1)
+#define STV090x_P2_TSSTATUS                            STV090x_Px_TSSTATUS(2)
+#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD           7
+#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD           1
+#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD            6
+#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD            1
+
+#define STV090x_Px_TSSTATUS2(__x)                      (0xF582 - (__x - 1) * 0x200)
+#define STV090x_P1_TSSTATUS2                           STV090x_Px_TSSTATUS2(1)
+#define STV090x_P2_TSSTATUS2                           STV090x_Px_TSSTATUS2(2)
+#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD         7
+#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD         1
+#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD       6
+#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD       1
+#define STV090x_OFFST_Px_DILXX_RESET_FIELD             5
+#define STV090x_WIDTH_Px_DILXX_RESET_FIELD             1
+#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD          4
+#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD          1
+#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD            1
+#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD            1
+
+#define STV090x_Px_TSBITRATEy(__x, __y)                        (0xF584 - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_TSBITRATE0                          STV090x_Px_TSBITRATEy(1, 0)
+#define STV090x_P1_TSBITRATE1                          STV090x_Px_TSBITRATEy(1, 1)
+#define STV090x_P2_TSBITRATE0                          STV090x_Px_TSBITRATEy(2, 0)
+#define STV090x_P2_TSBITRATE1                          STV090x_Px_TSBITRATEy(2, 1)
+#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD          0
+#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD          8
+
+#define STV090x_Px_ERRCTRL1(__x)                       (0xF598 - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCTRL1                            STV090x_Px_ERRCTRL1(1)
+#define STV090x_P2_ERRCTRL1                            STV090x_Px_ERRCTRL1(2)
+#define STV090x_OFFST_Px_ERR_SOURCE_FIELD              4
+#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD              4
+#define STV090x_OFFST_Px_NUM_EVENT_FIELD               0
+#define STV090x_WIDTH_Px_NUM_EVENT_FIELD               3
+
+#define STV090x_Px_ERRCNT12(__x)                       (0xF599 - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT12                            STV090x_Px_ERRCNT12(1)
+#define STV090x_P2_ERRCNT12                            STV090x_Px_ERRCNT12(2)
+#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD                7
+#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD                1
+#define STV090x_OFFST_Px_ERR_CNT12_FIELD               0
+#define STV090x_WIDTH_Px_ERR_CNT12_FIELD               7
+
+#define STV090x_Px_ERRCNT11(__x)                       (0xF59A - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT11                            STV090x_Px_ERRCNT11(1)
+#define STV090x_P2_ERRCNT11                            STV090x_Px_ERRCNT11(2)
+#define STV090x_OFFST_Px_ERR_CNT11_FIELD               0
+#define STV090x_WIDTH_Px_ERR_CNT11_FIELD               8
+
+#define STV090x_Px_ERRCNT10(__x)                       (0xF59B - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT10                            STV090x_Px_ERRCNT10(1)
+#define STV090x_P2_ERRCNT10                            STV090x_Px_ERRCNT10(2)
+#define STV090x_OFFST_Px_ERR_CNT10_FIELD               0
+#define STV090x_WIDTH_Px_ERR_CNT10_FIELD               8
+
+#define STV090x_Px_ERRCTRL2(__x)                       (0xF59C - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCTRL2                            STV090x_Px_ERRCTRL2(1)
+#define STV090x_P2_ERRCTRL2                            STV090x_Px_ERRCTRL2(2)
+#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD             4
+#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD             4
+#define STV090x_OFFST_Px_NUM_EVENT2_FIELD              0
+#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD              3
+
+#define STV090x_Px_ERRCNT22(__x)                       (0xF59D - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT22                            STV090x_Px_ERRCNT22(1)
+#define STV090x_P2_ERRCNT22                            STV090x_Px_ERRCNT22(2)
+#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD                7
+#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD                1
+#define STV090x_OFFST_Px_ERR_CNT2_FIELD                        0
+#define STV090x_WIDTH_Px_ERR_CNT2_FIELD                        7
+
+#define STV090x_Px_ERRCNT21(__x)                       (0xF59E - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT21                            STV090x_Px_ERRCNT21(1)
+#define STV090x_P2_ERRCNT21                            STV090x_Px_ERRCNT21(2)
+#define STV090x_OFFST_Px_ERR_CNT21_FIELD               0
+#define STV090x_WIDTH_Px_ERR_CNT21_FIELD               8
+
+#define STV090x_Px_ERRCNT20(__x)                       (0xF59F - (__x - 1) * 0x200)
+#define STV090x_P1_ERRCNT20                            STV090x_Px_ERRCNT20(1)
+#define STV090x_P2_ERRCNT20                            STV090x_Px_ERRCNT20(2)
+#define STV090x_OFFST_Px_ERR_CNT20_FIELD               0
+#define STV090x_WIDTH_Px_ERR_CNT20_FIELD               8
+
+#define STV090x_Px_FECSPY(__x)                         (0xF5A0 - (__x - 1) * 0x200)
+#define STV090x_P1_FECSPY                              STV090x_Px_FECSPY(1)
+#define STV090x_P2_FECSPY                              STV090x_Px_FECSPY(2)
+#define STV090x_OFFST_Px_SPY_ENABLE_FIELD              7
+#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD              1
+#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD      2
+#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD      2
+
+#define STV090x_Px_FSPYCFG(__x)                                (0xF5A1 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYCFG                             STV090x_Px_FSPYCFG(1)
+#define STV090x_P2_FSPYCFG                             STV090x_Px_FSPYCFG(2)
+#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD            5
+#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD            1
+#define STV090x_OFFST_Px_ONE_SHOT_FIELD                        4
+#define STV090x_WIDTH_Px_ONE_SHOT_FIELD                        1
+#define STV090x_OFFST_Px_I2C_MODE_FIELD                        2
+#define STV090x_WIDTH_Px_I2C_MODE_FIELD                        2
+
+#define STV090x_Px_FSPYDATA(__x)                       (0xF5A2 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYDATA                            STV090x_Px_FSPYDATA(1)
+#define STV090x_P2_FSPYDATA                            STV090x_Px_FSPYDATA(2)
+#define STV090x_OFFST_Px_SPY_STUFFING_FIELD            7
+#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD            1
+#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD            5
+#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD            1
+#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD                0
+#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD                5
+
+#define STV090x_Px_FSPYOUT(__x)                                (0xF5A3 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYOUT                             STV090x_Px_FSPYOUT(1)
+#define STV090x_P2_FSPYOUT                             STV090x_Px_FSPYOUT(2)
+#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD             7
+#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD             1
+#define STV090x_OFFST_Px_STUFF_MODE_FIELD              0
+#define STV090x_WIDTH_Px_STUFF_MODE_FIELD              3
+
+#define STV090x_Px_FSTATUS(__x)                                (0xF5A4 - (__x - 1) * 0x200)
+#define STV090x_P1_FSTATUS                             STV090x_Px_FSTATUS(1)
+#define STV090x_P2_FSTATUS                             STV090x_Px_FSTATUS(2)
+#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD              7
+#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD              1
+#define STV090x_OFFST_Px_VALID_SIM_FIELD               6
+#define STV090x_WIDTH_Px_VALID_SIM_FIELD               1
+#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD            5
+#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD            1
+#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD            4
+#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD            1
+#define STV090x_OFFST_Px_RESULT_STATE_FIELD            0
+#define STV090x_WIDTH_Px_RESULT_STATE_FIELD            4
+
+#define STV090x_Px_FBERCPT4(__x)                       (0xF5A8 - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT4                            STV090x_Px_FBERCPT4(1)
+#define STV090x_P2_FBERCPT4                            STV090x_Px_FBERCPT4(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
+
+#define STV090x_Px_FBERCPT3(__x)                       (0xF5A9 - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT3                            STV090x_Px_FBERCPT3(1)
+#define STV090x_P2_FBERCPT3                            STV090x_Px_FBERCPT3(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
+
+#define STV090x_Px_FBERCPT2(__x)                       (0xF5AA - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT2                            STV090x_Px_FBERCPT2(1)
+#define STV090x_P2_FBERCPT2                            STV090x_Px_FBERCPT2(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
+
+#define STV090x_Px_FBERCPT1(__x)                       (0xF5AB - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT1                            STV090x_Px_FBERCPT1(1)
+#define STV090x_P2_FBERCPT1                            STV090x_Px_FBERCPT1(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
+
+#define STV090x_Px_FBERCPT0(__x)                       (0xF5AC - (__x - 1) * 0x200)
+#define STV090x_P1_FBERCPT0                            STV090x_Px_FBERCPT0(1)
+#define STV090x_P2_FBERCPT0                            STV090x_Px_FBERCPT0(2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
+
+#define STV090x_Px_FBERERRy(__x, __y)                  (0xF5AF - (__x - 1) * 0x200 - __y * 0x1)
+#define STV090x_P1_FBERERR0                            STV090x_Px_FBERERRy(1, 0)
+#define STV090x_P1_FBERERR1                            STV090x_Px_FBERERRy(1, 1)
+#define STV090x_P1_FBERERR2                            STV090x_Px_FBERERRy(1, 2)
+#define STV090x_P2_FBERERR0                            STV090x_Px_FBERERRy(2, 0)
+#define STV090x_P2_FBERERR1                            STV090x_Px_FBERERRy(2, 1)
+#define STV090x_P2_FBERERR2                            STV090x_Px_FBERERRy(2, 2)
+#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD       0
+#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD       8
+
+#define STV090x_Px_FSPYBER(__x)                                (0xF5B2 - (__x - 1) * 0x200)
+#define STV090x_P1_FSPYBER                             STV090x_Px_FSPYBER(1)
+#define STV090x_P2_FSPYBER                             STV090x_Px_FSPYBER(2)
+#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD                4
+#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD                1
+#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD          3
+#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD          1
+#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD           0
+#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD           3
+
+#define STV090x_RCCFGH                                 0xf600
+
+#define STV090x_TSGENERAL                              0xF630
+#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD           3
+#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD           1
+#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD                1
+#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD                2
+
+#define STV090x_TSGENERAL1X                            0xf670
+#define STV090x_CFGEXT                                 0xfa80
+
+#define STV090x_TSTRES0                                        0xFF11
+#define STV090x_OFFST_FRESFEC_FIELD                    7
+#define STV090x_WIDTH_FRESFEC_FIELD                    1
+
+#define STV090x_Px_TSTDISRX(__x)                       (0xFF67 - (__x - 1) * 0x2)
+#define STV090x_P1_TSTDISRX                            STV090x_Px_TSTDISRX(1)
+#define STV090x_P2_TSTDISRX                            STV090x_Px_TSTDISRX(2)
+#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD         3
+#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD         1
+
+#endif /* __STV090x_REG_H */
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
new file mode 100644 (file)
index 0000000..20b5fa9
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * stv6110.c
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+
+#include <linux/types.h>
+
+#include "stv6110.h"
+
+static int debug;
+
+struct stv6110_priv {
+       int i2c_address;
+       struct i2c_adapter *i2c;
+
+       u32 mclk;
+       u8 clk_div;
+       u8 gain;
+       u8 regs[8];
+};
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG args); \
+       } while (0)
+
+static s32 abssub(s32 a, s32 b)
+{
+       if (a > b)
+               return a - b;
+       else
+               return b - a;
+};
+
+static int stv6110_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
+                                                       int start, int len)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       int rc;
+       u8 cmdbuf[len + 1];
+       struct i2c_msg msg = {
+               .addr   = priv->i2c_address,
+               .flags  = 0,
+               .buf    = cmdbuf,
+               .len    = len + 1
+       };
+
+       dprintk("%s\n", __func__);
+
+       if (start + len > 8)
+               return -EINVAL;
+
+       memcpy(&cmdbuf[1], buf, len);
+       cmdbuf[0] = start;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       rc = i2c_transfer(priv->i2c, &msg, 1);
+       if (rc != 1)
+               dprintk("%s: i2c error\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
+                                                       int start, int len)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       int rc;
+       u8 reg[] = { start };
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = priv->i2c_address,
+                       .flags  = 0,
+                       .buf    = reg,
+                       .len    = 1,
+               }, {
+                       .addr   = priv->i2c_address,
+                       .flags  = I2C_M_RD,
+                       .buf    = regs,
+                       .len    = len,
+               },
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       rc = i2c_transfer(priv->i2c, msg, 2);
+       if (rc != 2)
+               dprintk("%s: i2c error\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       memcpy(&priv->regs[start], regs, len);
+
+       return 0;
+}
+
+static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+{
+       u8 buf[] = { 0 };
+       stv6110_read_regs(fe, buf, start, 1);
+
+       return buf[0];
+}
+
+static int stv6110_sleep(struct dvb_frontend *fe)
+{
+       u8 reg[] = { 0 };
+       stv6110_write_regs(fe, reg, 0, 1);
+
+       return 0;
+}
+
+static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
+{
+       u32 rlf;
+
+       switch (rolloff) {
+       case ROLLOFF_20:
+               rlf = 20;
+               break;
+       case ROLLOFF_25:
+               rlf = 25;
+               break;
+       default:
+               rlf = 35;
+               break;
+       }
+
+       return symbol_rate  + ((symbol_rate * rlf) / 100);
+}
+
+static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       u8 r8, ret = 0x04;
+       int i;
+
+       if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
+               r8 = 31;
+       else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
+               r8 = 0;
+       else /*if 5 < BW/2 < 36*/
+               r8 = (bandwidth / 2) / 1000000 - 5;
+
+       /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
+       /* ctrl3, CF = r8 Set the LPF value */
+       priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
+       priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
+       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+       /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
+       priv->regs[RSTV6110_STAT1] |= 0x02;
+       stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
+
+       i = 0;
+       /* Wait for CALRCSTRT == 0 */
+       while ((i < 10) && (ret != 0)) {
+               ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
+               mdelay(1);      /* wait for LPF auto calibration */
+               i++;
+       }
+
+       /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
+       priv->regs[RSTV6110_CTRL3] |= (1 << 6);
+       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+       return 0;
+}
+
+static int stv6110_init(struct dvb_frontend *fe)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+       memcpy(priv->regs, buf0, 8);
+       /* K = (Reference / 1000000) - 16 */
+       priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+       priv->regs[RSTV6110_CTRL1] |=
+                               ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+       /* divisor value for the output clock */
+       priv->regs[RSTV6110_CTRL2] &= ~0xc0;
+       priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);
+
+       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
+       msleep(1);
+       stv6110_set_bandwidth(fe, 72000000);
+
+       return 0;
+}
+
+static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       u32 nbsteps, divider, psd2, freq;
+       u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+       stv6110_read_regs(fe, regs, 0, 8);
+       /*N*/
+       divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
+       divider += priv->regs[RSTV6110_TUNING1];
+
+       /*R*/
+       nbsteps  = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
+       /*p*/
+       psd2  = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
+
+       freq = divider * (priv->mclk / 1000);
+       freq /= (1 << (nbsteps + psd2));
+       freq /= 4;
+
+       *frequency = freq;
+
+       return 0;
+}
+
+static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u8 ret = 0x04;
+       u32 divider, ref, p, presc, i, result_freq, vco_freq;
+       s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
+       s32 srate;
+
+       dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
+                                               frequency, priv->mclk);
+
+       /* K = (Reference / 1000000) - 16 */
+       priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+       priv->regs[RSTV6110_CTRL1] |=
+                               ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+       /* BB_GAIN = db/2 */
+       if (fe->ops.set_property && fe->ops.get_property) {
+               srate = c->symbol_rate;
+               dprintk("%s: Get Frontend parameters: srate=%d\n",
+                                                       __func__, srate);
+       } else
+               srate = 15000000;
+
+       priv->regs[RSTV6110_CTRL2] &= ~0x0f;
+       priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
+
+       if (frequency <= 1023000) {
+               p = 1;
+               presc = 0;
+       } else if (frequency <= 1300000) {
+               p = 1;
+               presc = 1;
+       } else if (frequency <= 2046000) {
+               p = 0;
+               presc = 0;
+       } else {
+               p = 0;
+               presc = 1;
+       }
+       /* DIV4SEL = p*/
+       priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
+       priv->regs[RSTV6110_TUNING2] |= (p << 4);
+
+       /* PRESC32ON = presc */
+       priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
+       priv->regs[RSTV6110_TUNING2] |= (presc << 5);
+
+       p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
+       for (r_div = 0; r_div <= 3; r_div++) {
+               p_calc = (priv->mclk / 100000);
+               p_calc /= (1 << (r_div + 1));
+               if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
+                       r_div_opt = r_div;
+
+               p_calc_opt = (priv->mclk / 100000);
+               p_calc_opt /= (1 << (r_div_opt + 1));
+       }
+
+       ref = priv->mclk / ((1 << (r_div_opt + 1))  * (1 << (p + 1)));
+       divider = (((frequency * 1000) + (ref >> 1)) / ref);
+
+       /* RDIV = r_div_opt */
+       priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
+       priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
+
+       /* NDIV_MSB = MSB(divider) */
+       priv->regs[RSTV6110_TUNING2] &= ~0x0f;
+       priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
+
+       /* NDIV_LSB, LSB(divider) */
+       priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
+
+       /* CALVCOSTRT = 1 VCO Auto Calibration */
+       priv->regs[RSTV6110_STAT1] |= 0x04;
+       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
+                                               RSTV6110_CTRL1, 8);
+
+       i = 0;
+       /* Wait for CALVCOSTRT == 0 */
+       while ((i < 10) && (ret != 0)) {
+               ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
+               msleep(1); /* wait for VCO auto calibration */
+               i++;
+       }
+
+       ret = stv6110_read_reg(fe, RSTV6110_STAT1);
+       stv6110_get_frequency(fe, &result_freq);
+
+       vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
+       dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
+                                               ret, result_freq, vco_freq);
+
+       return 0;
+}
+
+static int stv6110_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
+
+       stv6110_set_frequency(fe, c->frequency);
+       stv6110_set_bandwidth(fe, bandwidth);
+
+       return 0;
+}
+
+static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct stv6110_priv *priv = fe->tuner_priv;
+       u8 r8 = 0;
+       u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+       stv6110_read_regs(fe, regs, 0, 8);
+
+       /* CF */
+       r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
+       *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
+
+       return 0;
+}
+
+static struct dvb_tuner_ops stv6110_tuner_ops = {
+       .info = {
+               .name = "ST STV6110",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_step = 1000,
+       },
+       .init = stv6110_init,
+       .release = stv6110_release,
+       .sleep = stv6110_sleep,
+       .set_params = stv6110_set_params,
+       .get_frequency = stv6110_get_frequency,
+       .set_frequency = stv6110_set_frequency,
+       .get_bandwidth = stv6110_get_bandwidth,
+       .set_bandwidth = stv6110_set_bandwidth,
+
+};
+
+struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+                                       const struct stv6110_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       struct stv6110_priv *priv = NULL;
+       u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+       struct i2c_msg msg[] = {
+               {
+                       .addr = config->i2c_address,
+                       .flags = 0,
+                       .buf = reg0,
+                       .len = 9
+               }
+       };
+       int ret;
+
+       /* divisor value for the output clock */
+       reg0[2] &= ~0xc0;
+       reg0[2] |= (config->clk_div << 6);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       ret = i2c_transfer(i2c, msg, 1);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret != 1)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c_address = config->i2c_address;
+       priv->i2c = i2c;
+       priv->mclk = config->mclk;
+       priv->clk_div = config->clk_div;
+       priv->gain = config->gain;
+
+       memcpy(&priv->regs, &reg0[1], 8);
+
+       memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
+                               sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = priv;
+       printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
+
+       return fe;
+}
+EXPORT_SYMBOL(stv6110_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV6110 driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stv6110.h b/drivers/media/dvb-frontends/stv6110.h
new file mode 100644 (file)
index 0000000..fe71bba
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * stv6110.h
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DVB_STV6110_H__
+#define __DVB_STV6110_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* registers */
+#define RSTV6110_CTRL1         0
+#define RSTV6110_CTRL2         1
+#define RSTV6110_TUNING1       2
+#define RSTV6110_TUNING2       3
+#define RSTV6110_CTRL3         4
+#define RSTV6110_STAT1         5
+#define RSTV6110_STAT2         6
+#define RSTV6110_STAT3         7
+
+struct stv6110_config {
+       u8 i2c_address;
+       u32 mclk;
+       u8 gain;
+       u8 clk_div;     /* divisor value for the output clock */
+};
+
+#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
+                                                       && defined(MODULE))
+extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+                                       const struct stv6110_config *config,
+                                       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+                                       const struct stv6110_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
new file mode 100644 (file)
index 0000000..f36cab1
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+       STV6110(A) Silicon tuner driver
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "dvb_frontend.h"
+
+#include "stv6110x_reg.h"
+#include "stv6110x.h"
+#include "stv6110x_priv.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
+{
+       int ret;
+       const struct stv6110x_config *config = stv6110x->config;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               { .addr = config->addr, .flags = 0,        .buf = b0, .len = 1 },
+               { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+       };
+
+       ret = i2c_transfer(stv6110x->i2c, msg, 2);
+       if (ret != 2) {
+               dprintk(FE_ERROR, 1, "I/O Error");
+               return -EREMOTEIO;
+       }
+       *data = b1[0];
+
+       return 0;
+}
+
+static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
+{
+       int ret;
+       const struct stv6110x_config *config = stv6110x->config;
+       u8 buf[len + 1];
+       struct i2c_msg msg = {
+               .addr = config->addr,
+               .flags = 0,
+               .buf = buf,
+               .len = len + 1
+       };
+
+       if (start + len > 8)
+               return -EINVAL;
+
+       buf[0] = start;
+       memcpy(&buf[1], data, len);
+
+       ret = i2c_transfer(stv6110x->i2c, &msg, 1);
+       if (ret != 1) {
+               dprintk(FE_ERROR, 1, "I/O Error");
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+{
+       return stv6110x_write_regs(stv6110x, reg, &data, 1);
+}
+
+static int stv6110x_init(struct dvb_frontend *fe)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+       int ret;
+
+       ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
+                                 ARRAY_SIZE(stv6110x->regs));
+       if (ret < 0) {
+               dprintk(FE_ERROR, 1, "Initialization failed");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+       u32 rDiv, divider;
+       s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
+       u8 i;
+
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
+
+       if (frequency <= 1023000) {
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+               pVal = 40;
+       } else if (frequency <= 1300000) {
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+               pVal = 40;
+       } else if (frequency <= 2046000) {
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
+               pVal = 20;
+       } else {
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
+               pVal = 20;
+       }
+
+       for (rDiv = 0; rDiv <= 3; rDiv++) {
+               pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
+
+               if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
+                       rDivOpt = rDiv;
+
+               pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
+       }
+
+       divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
+       divider = (divider + 5) / 10;
+
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
+
+       /* VCO Auto calibration */
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
+
+       stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
+       stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
+       stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
+       stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
+
+       for (i = 0; i < TRIALS; i++) {
+               stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
+               if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
+                               break;
+               msleep(1);
+       }
+
+       return 0;
+}
+
+static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
+       stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
+
+       *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
+                                STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
+
+       *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
+                            STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
+
+       *frequency >>= 2;
+
+       return 0;
+}
+
+static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+       u32 halfbw;
+       u8 i;
+
+       halfbw = bandwidth >> 1;
+
+       if (halfbw > 36000000)
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
+       else if (halfbw < 5000000)
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
+       else
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
+
+
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
+
+       stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
+       stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
+
+       for (i = 0; i < TRIALS; i++) {
+               stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
+               if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
+                       break;
+               msleep(1);
+       }
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
+       stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
+
+       return 0;
+}
+
+static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
+       *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
+
+       return 0;
+}
+
+static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       /* setup divider */
+       switch (refclock) {
+       default:
+       case 1:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
+               break;
+       case 2:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
+               break;
+       case 4:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
+               break;
+       case 8:
+       case 0:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
+               break;
+       }
+       stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
+
+       return 0;
+}
+
+static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
+       *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
+
+       return 0;
+}
+
+static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
+       stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
+
+       return 0;
+}
+
+static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+       int ret;
+
+       switch (mode) {
+       case TUNER_SLEEP:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
+               break;
+
+       case TUNER_WAKE:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
+               break;
+       }
+
+       ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
+       if (ret < 0) {
+               dprintk(FE_ERROR, 1, "I/O Error");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int stv6110x_sleep(struct dvb_frontend *fe)
+{
+       if (fe->tuner_priv)
+               return stv6110x_set_mode(fe, TUNER_SLEEP);
+
+       return 0;
+}
+
+static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
+
+       if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
+               *status = TUNER_PHASELOCKED;
+       else
+               *status = 0;
+
+       return 0;
+}
+
+
+static int stv6110x_release(struct dvb_frontend *fe)
+{
+       struct stv6110x_state *stv6110x = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(stv6110x);
+
+       return 0;
+}
+
+static struct dvb_tuner_ops stv6110x_ops = {
+       .info = {
+               .name           = "STV6110(A) Silicon Tuner",
+               .frequency_min  =  950000,
+               .frequency_max  = 2150000,
+               .frequency_step = 0,
+       },
+       .release                = stv6110x_release
+};
+
+static struct stv6110x_devctl stv6110x_ctl = {
+       .tuner_init             = stv6110x_init,
+       .tuner_sleep            = stv6110x_sleep,
+       .tuner_set_mode         = stv6110x_set_mode,
+       .tuner_set_frequency    = stv6110x_set_frequency,
+       .tuner_get_frequency    = stv6110x_get_frequency,
+       .tuner_set_bandwidth    = stv6110x_set_bandwidth,
+       .tuner_get_bandwidth    = stv6110x_get_bandwidth,
+       .tuner_set_bbgain       = stv6110x_set_bbgain,
+       .tuner_get_bbgain       = stv6110x_get_bbgain,
+       .tuner_set_refclk       = stv6110x_set_refclock,
+       .tuner_get_status       = stv6110x_get_status,
+};
+
+struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+                                       const struct stv6110x_config *config,
+                                       struct i2c_adapter *i2c)
+{
+       struct stv6110x_state *stv6110x;
+       u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
+
+       stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
+       if (!stv6110x)
+               return NULL;
+
+       stv6110x->i2c           = i2c;
+       stv6110x->config        = config;
+       stv6110x->devctl        = &stv6110x_ctl;
+       memcpy(stv6110x->regs, default_regs, 8);
+
+       /* setup divider */
+       switch (stv6110x->config->clk_div) {
+       default:
+       case 1:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
+               break;
+       case 2:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
+               break;
+       case 4:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
+               break;
+       case 8:
+       case 0:
+               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
+               break;
+       }
+
+       fe->tuner_priv          = stv6110x;
+       fe->ops.tuner_ops       = stv6110x_ops;
+
+       printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
+       return stv6110x->devctl;
+}
+EXPORT_SYMBOL(stv6110x_attach);
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STV6110x Silicon tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/stv6110x.h b/drivers/media/dvb-frontends/stv6110x.h
new file mode 100644 (file)
index 0000000..4751675
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+       STV6110(A) Silicon tuner driver
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV6110x_H
+#define __STV6110x_H
+
+struct stv6110x_config {
+       u8      addr;
+       u32     refclk;
+       u8      clk_div; /* divisor value for the output clock */
+};
+
+enum tuner_mode {
+       TUNER_SLEEP = 1,
+       TUNER_WAKE,
+};
+
+enum tuner_status {
+       TUNER_PHASELOCKED = 1,
+};
+
+struct stv6110x_devctl {
+       int (*tuner_init) (struct dvb_frontend *fe);
+       int (*tuner_sleep) (struct dvb_frontend *fe);
+       int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
+       int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
+       int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
+       int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
+       int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
+       int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
+       int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
+       int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk);
+       int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
+};
+
+
+#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
+
+extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+                                              const struct stv6110x_config *config,
+                                              struct i2c_adapter *i2c);
+
+#else
+static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+                                                     const struct stv6110x_config *config,
+                                                     struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif /* CONFIG_DVB_STV6110x */
+
+#endif /* __STV6110x_H */
diff --git a/drivers/media/dvb-frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h
new file mode 100644 (file)
index 0000000..0ec936a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+       STV6110(A) Silicon tuner driver
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV6110x_PRIV_H
+#define __STV6110x_PRIV_H
+
+#define FE_ERROR                               0
+#define FE_NOTICE                              1
+#define FE_INFO                                        2
+#define FE_DEBUG                               3
+#define FE_DEBUGREG                            4
+
+#define dprintk(__y, __z, format, arg...) do {                                         \
+       if (__z) {                                                                      \
+               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
+                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
+               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
+                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
+               else if ((verbose > FE_INFO) && (verbose > __y))                        \
+                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
+               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
+                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
+       } else {                                                                        \
+               if (verbose > __y)                                                      \
+                       printk(format, ##arg);                                          \
+       }                                                                               \
+} while (0)
+
+
+#define STV6110x_SETFIELD(mask, bitf, val)                             \
+       (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) <<        \
+                                 STV6110x_OFFST_##bitf))) |            \
+                         (val << STV6110x_OFFST_##bitf))
+
+#define STV6110x_GETFIELD(bitf, val)                                   \
+       ((val >> STV6110x_OFFST_##bitf) &                               \
+       ((1 << STV6110x_WIDTH_##bitf) - 1))
+
+#define MAKEWORD16(a, b)                       (((a) << 8) | (b))
+
+#define LSB(x)                                 ((x & 0xff))
+#define MSB(y)                                 ((y >> 8) & 0xff)
+
+#define TRIALS                                 10
+#define R_DIV(__div)                           (1 << (__div + 1))
+#define REFCLOCK_kHz                           (stv6110x->config->refclk /    1000)
+#define REFCLOCK_MHz                           (stv6110x->config->refclk / 1000000)
+
+struct stv6110x_state {
+       struct i2c_adapter              *i2c;
+       const struct stv6110x_config    *config;
+       u8                              regs[8];
+
+       struct stv6110x_devctl          *devctl;
+};
+
+#endif /* __STV6110x_PRIV_H */
diff --git a/drivers/media/dvb-frontends/stv6110x_reg.h b/drivers/media/dvb-frontends/stv6110x_reg.h
new file mode 100644 (file)
index 0000000..93e5c70
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+       STV6110(A) Silicon tuner driver
+
+       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
+
+       Copyright (C) ST Microelectronics
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STV6110x_REG_H
+#define __STV6110x_REG_H
+
+#define STV6110x_CTRL1                         0x00
+#define STV6110x_OFFST_CTRL1_K                 3
+#define STV6110x_WIDTH_CTRL1_K                 5
+#define STV6110x_OFFST_CTRL1_LPT               2
+#define STV6110x_WIDTH_CTRL1_LPT               1
+#define STV6110x_OFFST_CTRL1_RX                        1
+#define STV6110x_WIDTH_CTRL1_RX                        1
+#define STV6110x_OFFST_CTRL1_SYN               0
+#define STV6110x_WIDTH_CTRL1_SYN               1
+
+#define STV6110x_CTRL2                         0x01
+#define STV6110x_OFFST_CTRL2_CO_DIV            6
+#define STV6110x_WIDTH_CTRL2_CO_DIV            2
+#define STV6110x_OFFST_CTRL2_RSVD              5
+#define STV6110x_WIDTH_CTRL2_RSVD              1
+#define STV6110x_OFFST_CTRL2_REFOUT_SEL                4
+#define STV6110x_WIDTH_CTRL2_REFOUT_SEL                1
+#define STV6110x_OFFST_CTRL2_BBGAIN            0
+#define STV6110x_WIDTH_CTRL2_BBGAIN            4
+
+#define STV6110x_TNG0                          0x02
+#define STV6110x_OFFST_TNG0_N_DIV_7_0          0
+#define STV6110x_WIDTH_TNG0_N_DIV_7_0          8
+
+#define STV6110x_TNG1                          0x03
+#define STV6110x_OFFST_TNG1_R_DIV              6
+#define STV6110x_WIDTH_TNG1_R_DIV              2
+#define STV6110x_OFFST_TNG1_PRESC32_ON         5
+#define STV6110x_WIDTH_TNG1_PRESC32_ON         1
+#define STV6110x_OFFST_TNG1_DIV4SEL            4
+#define STV6110x_WIDTH_TNG1_DIV4SEL            1
+#define STV6110x_OFFST_TNG1_N_DIV_11_8         0
+#define STV6110x_WIDTH_TNG1_N_DIV_11_8         4
+
+
+#define STV6110x_CTRL3                         0x04
+#define STV6110x_OFFST_CTRL3_DCLOOP_OFF                7
+#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF                1
+#define STV6110x_OFFST_CTRL3_RCCLK_OFF         6
+#define STV6110x_WIDTH_CTRL3_RCCLK_OFF         1
+#define STV6110x_OFFST_CTRL3_ICP               5
+#define STV6110x_WIDTH_CTRL3_ICP               1
+#define STV6110x_OFFST_CTRL3_CF                        0
+#define STV6110x_WIDTH_CTRL3_CF                        5
+
+#define STV6110x_STAT1                         0x05
+#define STV6110x_OFFST_STAT1_CALVCO_STRT       2
+#define STV6110x_WIDTH_STAT1_CALVCO_STRT       1
+#define STV6110x_OFFST_STAT1_CALRC_STRT                1
+#define STV6110x_WIDTH_STAT1_CALRC_STRT                1
+#define STV6110x_OFFST_STAT1_LOCK              0
+#define STV6110x_WIDTH_STAT1_LOCK              1
+
+#define STV6110x_STAT2                         0x06
+#define STV6110x_STAT3                         0x07
+
+#endif /* __STV6110x_REG_H */
diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c
new file mode 100644 (file)
index 0000000..1bff7f4
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+    TDA10021  - Single Chip Cable Channel Receiver driver module
+              used on the Siemens DVB-C cards
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
+                  Support for TDA10021
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda1002x.h"
+
+
+struct tda10021_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct tda1002x_config* config;
+       struct dvb_frontend frontend;
+
+       u8 pwm;
+       u8 reg0;
+};
+
+
+#if 0
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+static int verbose;
+
+#define XIN 57840000UL
+
+#define FIN (XIN >> 4)
+
+static int tda10021_inittab_size = 0x40;
+static u8 tda10021_inittab[0x40]=
+{
+       0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
+       0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
+       0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
+       0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
+       0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
+       0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
+       0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
+       0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
+};
+
+static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+       int ret;
+
+       ret = i2c_transfer (state->i2c, &msg, 1);
+       if (ret != 1)
+               printk("DVB: TDA10021(%d): %s, writereg error "
+                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+                       state->frontend.dvb->num, __func__, reg, data, ret);
+
+       msleep(10);
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
+{
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                                 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+       int ret;
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+       // Don't print an error message if the id is read.
+       if (ret != 2 && reg != 0x1a)
+               printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
+                               __func__, ret);
+       return b1[0];
+}
+
+//get access to tuner
+static int lock_tuner(struct tda10021_state* state)
+{
+       u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
+       struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+       if(i2c_transfer(state->i2c, &msg, 1) != 1)
+       {
+               printk("tda10021: lock tuner fails\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+//release access from tuner
+static int unlock_tuner(struct tda10021_state* state)
+{
+       u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
+       struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+       if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
+       {
+               printk("tda10021: unlock tuner fails\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
+                               fe_spectral_inversion_t inversion)
+{
+       reg0 |= state->reg0 & 0x63;
+
+       if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
+               reg0 &= ~0x20;
+       else
+               reg0 |= 0x20;
+
+       _tda10021_writereg (state, 0x00, reg0 & 0xfe);
+       _tda10021_writereg (state, 0x00, reg0 | 0x01);
+
+       state->reg0 = reg0;
+       return 0;
+}
+
+static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
+{
+       s32 BDR;
+       s32 BDRI;
+       s16 SFIL=0;
+       u16 NDEC = 0;
+       u32 tmp, ratio;
+
+       if (symbolrate > XIN/2)
+               symbolrate = XIN/2;
+       if (symbolrate < 500000)
+               symbolrate = 500000;
+
+       if (symbolrate < XIN/16) NDEC = 1;
+       if (symbolrate < XIN/32) NDEC = 2;
+       if (symbolrate < XIN/64) NDEC = 3;
+
+       if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
+       if (symbolrate < (u32)(XIN/16))  SFIL = 0;
+       if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
+       if (symbolrate < (u32)(XIN/32))  SFIL = 0;
+       if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
+       if (symbolrate < (u32)(XIN/64))  SFIL = 0;
+       if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
+
+       symbolrate <<= NDEC;
+       ratio = (symbolrate << 4) / FIN;
+       tmp =  ((symbolrate << 4) % FIN) << 8;
+       ratio = (ratio << 8) + tmp / FIN;
+       tmp = (tmp % FIN) << 8;
+       ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
+
+       BDR = ratio;
+       BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
+
+       if (BDRI > 0xFF)
+               BDRI = 0xFF;
+
+       SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
+
+       NDEC = (NDEC << 6) | tda10021_inittab[0x03];
+
+       _tda10021_writereg (state, 0x03, NDEC);
+       _tda10021_writereg (state, 0x0a, BDR&0xff);
+       _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
+       _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
+
+       _tda10021_writereg (state, 0x0d, BDRI);
+       _tda10021_writereg (state, 0x0e, SFIL);
+
+       return 0;
+}
+
+static int tda10021_init (struct dvb_frontend *fe)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+       int i;
+
+       dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
+
+       //_tda10021_writereg (fe, 0, 0);
+
+       for (i=0; i<tda10021_inittab_size; i++)
+               _tda10021_writereg (state, i, tda10021_inittab[i]);
+
+       _tda10021_writereg (state, 0x34, state->pwm);
+
+       //Comment by markus
+       //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
+       //0x2A[4] == BYPPLL -> Power down mode (default 1)
+       //0x2A[5] == LCK -> PLL Lock Flag
+       //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
+
+       //Activate PLL
+       _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
+       return 0;
+}
+
+struct qam_params {
+       u8 conf, agcref, lthr, mseth, aref;
+};
+
+static int tda10021_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys  = c->delivery_system;
+       unsigned qam = c->modulation;
+       bool is_annex_c;
+       u32 reg0x3d;
+       struct tda10021_state* state = fe->demodulator_priv;
+       static const struct qam_params qam_params[] = {
+               /* Modulation  Conf  AGCref  LTHR  MSETH  AREF */
+               [QPSK]     = { 0x14, 0x78,   0x78, 0x8c,  0x96 },
+               [QAM_16]   = { 0x00, 0x8c,   0x87, 0xa2,  0x91 },
+               [QAM_32]   = { 0x04, 0x8c,   0x64, 0x74,  0x96 },
+               [QAM_64]   = { 0x08, 0x6a,   0x46, 0x43,  0x6a },
+               [QAM_128]  = { 0x0c, 0x78,   0x36, 0x34,  0x7e },
+               [QAM_256]  = { 0x10, 0x5c,   0x26, 0x23,  0x6b },
+       };
+
+       switch (delsys) {
+       case SYS_DVBC_ANNEX_A:
+               is_annex_c = false;
+               break;
+       case SYS_DVBC_ANNEX_C:
+               is_annex_c = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * gcc optimizes the code bellow the same way as it would code:
+        *           "if (qam > 5) return -EINVAL;"
+        * Yet, the code is clearer, as it shows what QAM standards are
+        * supported by the driver, and avoids the usage of magic numbers on
+        * it.
+        */
+       switch (qam) {
+       case QPSK:
+       case QAM_16:
+       case QAM_32:
+       case QAM_64:
+       case QAM_128:
+       case QAM_256:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF)
+               return -EINVAL;
+
+       /*printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->symbol_rate);*/
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       tda10021_set_symbolrate(state, c->symbol_rate);
+       _tda10021_writereg(state, 0x34, state->pwm);
+
+       _tda10021_writereg(state, 0x01, qam_params[qam].agcref);
+       _tda10021_writereg(state, 0x05, qam_params[qam].lthr);
+       _tda10021_writereg(state, 0x08, qam_params[qam].mseth);
+       _tda10021_writereg(state, 0x09, qam_params[qam].aref);
+
+       /*
+        * Bit 0 == 0 means roll-off = 0.15 (Annex A)
+        *       == 1 means roll-off = 0.13 (Annex C)
+        */
+       reg0x3d = tda10021_readreg (state, 0x3d);
+       if (is_annex_c)
+               _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d);
+       else
+               _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d);
+       tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion);
+
+       return 0;
+}
+
+static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+       int sync;
+
+       *status = 0;
+       //0x11[0] == EQALGO -> Equalizer algorithms state
+       //0x11[1] == CARLOCK -> Carrier locked
+       //0x11[2] == FSYNC -> Frame synchronisation
+       //0x11[3] == FEL -> Front End locked
+       //0x11[6] == NODVB -> DVB Mode Information
+       sync = tda10021_readreg (state, 0x11);
+
+       if (sync & 2)
+               *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
+
+       if (sync & 4)
+               *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
+
+       if (sync & 8)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       u32 _ber = tda10021_readreg(state, 0x14) |
+               (tda10021_readreg(state, 0x15) << 8) |
+               ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
+       _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0)
+                                       | (tda10021_inittab[0x10] & 0xc0));
+       *ber = 10 * _ber;
+
+       return 0;
+}
+
+static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       u8 config = tda10021_readreg(state, 0x02);
+       u8 gain = tda10021_readreg(state, 0x17);
+       if (config & 0x02)
+               /* the agc value is inverted */
+               gain = ~gain;
+       *strength = (gain << 8) | gain;
+
+       return 0;
+}
+
+static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       u8 quality = ~tda10021_readreg(state, 0x18);
+       *snr = (quality << 8) | quality;
+
+       return 0;
+}
+
+static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
+       if (*ucblocks == 0x7f)
+               *ucblocks = 0xffffffff;
+
+       /* reset uncorrected block counter */
+       _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
+       _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
+
+       return 0;
+}
+
+static int tda10021_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda10021_state* state = fe->demodulator_priv;
+       int sync;
+       s8 afc = 0;
+
+       sync = tda10021_readreg(state, 0x11);
+       afc = tda10021_readreg(state, 0x19);
+       if (verbose) {
+               /* AFC only valid when carrier has been recovered */
+               printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
+                                 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
+                       state->frontend.dvb->num, afc,
+                      -((s32)p->symbol_rate * afc) >> 10);
+       }
+
+       p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
+       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
+
+       p->fec_inner = FEC_NONE;
+       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+
+       if (sync & 2)
+               p->frequency -= ((s32)p->symbol_rate * afc) >> 10;
+
+       return 0;
+}
+
+static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               lock_tuner(state);
+       } else {
+               unlock_tuner(state);
+       }
+       return 0;
+}
+
+static int tda10021_sleep(struct dvb_frontend* fe)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+
+       _tda10021_writereg (state, 0x1b, 0x02);  /* pdown ADC */
+       _tda10021_writereg (state, 0x00, 0x80);  /* standby */
+
+       return 0;
+}
+
+static void tda10021_release(struct dvb_frontend* fe)
+{
+       struct tda10021_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops tda10021_ops;
+
+struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
+                                    struct i2c_adapter* i2c,
+                                    u8 pwm)
+{
+       struct tda10021_state* state = NULL;
+       u8 id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->pwm = pwm;
+       state->reg0 = tda10021_inittab[0];
+
+       /* check if the demod is there */
+       id = tda10021_readreg(state, 0x1a);
+       if ((id & 0xf0) != 0x70) goto error;
+
+       /* Don't claim TDA10023 */
+       if (id == 0x7d)
+               goto error;
+
+       printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
+              state->config->demod_address, id);
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops tda10021_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
+       .info = {
+               .name = "Philips TDA10021 DVB-C",
+               .frequency_stepsize = 62500,
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
+               .symbol_rate_min = (XIN/2)/64,     /* SACLK/64 == (XIN/2)/64 */
+               .symbol_rate_max = (XIN/2)/4,      /* SACLK/4 */
+       #if 0
+               .frequency_tolerance = ???,
+               .symbol_rate_tolerance = ???,  /* ppm */  /* == 8% (spec p. 5) */
+       #endif
+               .caps = 0x400 | //FE_CAN_QAM_4
+                       FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+                       FE_CAN_FEC_AUTO
+       },
+
+       .release = tda10021_release,
+
+       .init = tda10021_init,
+       .sleep = tda10021_sleep,
+       .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
+
+       .set_frontend = tda10021_set_parameters,
+       .get_frontend = tda10021_get_frontend,
+
+       .read_status = tda10021_read_status,
+       .read_ber = tda10021_read_ber,
+       .read_signal_strength = tda10021_read_signal_strength,
+       .read_snr = tda10021_read_snr,
+       .read_ucblocks = tda10021_read_ucblocks,
+};
+
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
+
+MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
+MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c
new file mode 100644 (file)
index 0000000..ca1e0d5
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+    TDA10023  - DVB-C decoder
+    (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
+
+    Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
+    Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
+
+    Remotely based on tda10021.c
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
+                  Support for TDA10021
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "tda1002x.h"
+
+#define REG0_INIT_VAL 0x23
+
+struct tda10023_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct tda10023_config *config;
+       struct dvb_frontend frontend;
+
+       u8 pwm;
+       u8 reg0;
+
+       /* clock settings */
+       u32 xtal;
+       u8 pll_m;
+       u8 pll_p;
+       u8 pll_n;
+       u32 sysclk;
+};
+
+#define dprintk(x...)
+
+static int verbose;
+
+static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
+{
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+                                 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+       int ret;
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+       if (ret != 2) {
+               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+               printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
+                       "(reg == 0x%02x, ret == %i)\n",
+                       num, __func__, reg, ret);
+       }
+       return b1[0];
+}
+
+static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
+{
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+       int ret;
+
+       ret = i2c_transfer (state->i2c, &msg, 1);
+       if (ret != 1) {
+               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+               printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
+                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+                       num, __func__, reg, data, ret);
+       }
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+
+static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
+{
+       if (mask==0xff)
+               return tda10023_writereg(state, reg, data);
+       else {
+               u8 val;
+               val=tda10023_readreg(state,reg);
+               val&=~mask;
+               val|=(data&mask);
+               return tda10023_writereg(state, reg, val);
+       }
+}
+
+static void tda10023_writetab(struct tda10023_state* state, u8* tab)
+{
+       u8 r,m,v;
+       while (1) {
+               r=*tab++;
+               m=*tab++;
+               v=*tab++;
+               if (r==0xff) {
+                       if (m==0xff)
+                               break;
+                       else
+                               msleep(m);
+               }
+               else
+                       tda10023_writebit(state,r,m,v);
+       }
+}
+
+//get access to tuner
+static int lock_tuner(struct tda10023_state* state)
+{
+       u8 buf[2] = { 0x0f, 0xc0 };
+       struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+       if(i2c_transfer(state->i2c, &msg, 1) != 1)
+       {
+               printk("tda10023: lock tuner fails\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+//release access from tuner
+static int unlock_tuner(struct tda10023_state* state)
+{
+       u8 buf[2] = { 0x0f, 0x40 };
+       struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+       if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
+       {
+               printk("tda10023: unlock tuner fails\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
+{
+       reg0 |= state->reg0 & 0x63;
+
+       tda10023_writereg (state, 0x00, reg0 & 0xfe);
+       tda10023_writereg (state, 0x00, reg0 | 0x01);
+
+       state->reg0 = reg0;
+       return 0;
+}
+
+static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
+{
+       s32 BDR;
+       s32 BDRI;
+       s16 SFIL=0;
+       u16 NDEC = 0;
+
+       /* avoid floating point operations multiplying syscloc and divider
+          by 10 */
+       u32 sysclk_x_10 = state->sysclk * 10;
+
+       if (sr < (u32)(sysclk_x_10/984)) {
+               NDEC=3;
+               SFIL=1;
+       } else if (sr < (u32)(sysclk_x_10/640)) {
+               NDEC=3;
+               SFIL=0;
+       } else if (sr < (u32)(sysclk_x_10/492)) {
+               NDEC=2;
+               SFIL=1;
+       } else if (sr < (u32)(sysclk_x_10/320)) {
+               NDEC=2;
+               SFIL=0;
+       } else if (sr < (u32)(sysclk_x_10/246)) {
+               NDEC=1;
+               SFIL=1;
+       } else if (sr < (u32)(sysclk_x_10/160)) {
+               NDEC=1;
+               SFIL=0;
+       } else if (sr < (u32)(sysclk_x_10/123)) {
+               NDEC=0;
+               SFIL=1;
+       }
+
+       BDRI = (state->sysclk)*16;
+       BDRI>>=NDEC;
+       BDRI +=sr/2;
+       BDRI /=sr;
+
+       if (BDRI>255)
+               BDRI=255;
+
+       {
+               u64 BDRX;
+
+               BDRX=1<<(24+NDEC);
+               BDRX*=sr;
+               do_div(BDRX, state->sysclk);    /* BDRX/=SYSCLK; */
+
+               BDR=(s32)BDRX;
+       }
+       dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
+               sr, BDR, BDRI, NDEC);
+       tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
+       tda10023_writereg (state, 0x0a, BDR&255);
+       tda10023_writereg (state, 0x0b, (BDR>>8)&255);
+       tda10023_writereg (state, 0x0c, (BDR>>16)&31);
+       tda10023_writereg (state, 0x0d, BDRI);
+       tda10023_writereg (state, 0x3d, (SFIL<<7));
+       return 0;
+}
+
+static int tda10023_init (struct dvb_frontend *fe)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       u8 tda10023_inittab[] = {
+/*        reg  mask val */
+/* 000 */ 0x2a, 0xff, 0x02,  /* PLL3, Bypass, Power Down */
+/* 003 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
+/* 006 */ 0x2a, 0xff, 0x03,  /* PLL3, Bypass, Power Down */
+/* 009 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
+                          /* PLL1 */
+/* 012 */ 0x28, 0xff, (state->pll_m-1),
+                          /* PLL2 */
+/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
+                          /* GPR FSAMPLING=1 */
+/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
+/* 021 */ 0x2a, 0xff, 0x08,  /* PLL3 PSACLK=1 */
+/* 024 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
+/* 027 */ 0x1f, 0xff, 0x00,  /* RESET */
+/* 030 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
+/* 033 */ 0xe6, 0x0c, 0x04,  /* RSCFG_IND */
+/* 036 */ 0x10, 0xc0, 0x80,  /* DECDVBCFG1 PBER=1 */
+
+/* 039 */ 0x0e, 0xff, 0x82,  /* GAIN1 */
+/* 042 */ 0x03, 0x08, 0x08,  /* CLKCONF DYN=1 */
+/* 045 */ 0x2e, 0xbf, 0x30,  /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
+                                      PPWMTUN=0 PPWMIF=0 */
+/* 048 */ 0x01, 0xff, 0x30,  /* AGCREF */
+/* 051 */ 0x1e, 0x84, 0x84,  /* CONTROL SACLK_ON=1 */
+/* 054 */ 0x1b, 0xff, 0xc8,  /* ADC TWOS=1 */
+/* 057 */ 0x3b, 0xff, 0xff,  /* IFMAX */
+/* 060 */ 0x3c, 0xff, 0x00,  /* IFMIN */
+/* 063 */ 0x34, 0xff, 0x00,  /* PWMREF */
+/* 066 */ 0x35, 0xff, 0xff,  /* TUNMAX */
+/* 069 */ 0x36, 0xff, 0x00,  /* TUNMIN */
+/* 072 */ 0x06, 0xff, 0x7f,  /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
+/* 075 */ 0x1c, 0x30, 0x30,  /* EQCONF2 STEPALGO=SGNALGO=1 */
+/* 078 */ 0x37, 0xff, 0xf6,  /* DELTAF_LSB */
+/* 081 */ 0x38, 0xff, 0xff,  /* DELTAF_MSB */
+/* 084 */ 0x02, 0xff, 0x93,  /* AGCCONF1  IFS=1 KAGCIF=2 KAGCTUN=3 */
+/* 087 */ 0x2d, 0xff, 0xf6,  /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
+/* 090 */ 0x04, 0x10, 0x00,  /* SWRAMP=1 */
+/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
+                               INTP1 POCLKP=1 FEL=1 MFS=0 */
+/* 096 */ 0x2b, 0x01, 0xa1,  /* INTS1 */
+/* 099 */ 0x20, 0xff, 0x04,  /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
+/* 102 */ 0x2c, 0xff, 0x0d,  /* INTP/S TRIP=0 TRIS=0 */
+/* 105 */ 0xc4, 0xff, 0x00,
+/* 108 */ 0xc3, 0x30, 0x00,
+/* 111 */ 0xb5, 0xff, 0x19,  /* ERAGC_THD */
+/* 114 */ 0x00, 0x03, 0x01,  /* GPR, CLBS soft reset */
+/* 117 */ 0x00, 0x03, 0x03,  /* GPR, CLBS soft reset */
+/* 120 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
+/* 123 */ 0xff, 0xff, 0xff
+};
+       dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
+
+       /* override default values if set in config */
+       if (state->config->deltaf) {
+               tda10023_inittab[80] = (state->config->deltaf & 0xff);
+               tda10023_inittab[83] = (state->config->deltaf >> 8);
+       }
+
+       if (state->config->output_mode)
+               tda10023_inittab[95] = state->config->output_mode;
+
+       tda10023_writetab(state, tda10023_inittab);
+
+       return 0;
+}
+
+struct qam_params {
+       u8 qam, lockthr, mseth, aref, agcrefnyq, eragnyq_thd;
+};
+
+static int tda10023_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys  = c->delivery_system;
+       unsigned qam = c->modulation;
+       bool is_annex_c;
+       struct tda10023_state* state = fe->demodulator_priv;
+       static const struct qam_params qam_params[] = {
+               /* Modulation  QAM    LOCKTHR   MSETH   AREF AGCREFNYQ ERAGCNYQ_THD */
+               [QPSK]    = { (5<<2),  0x78,    0x8c,   0x96,   0x78,   0x4c  },
+               [QAM_16]  = { (0<<2),  0x87,    0xa2,   0x91,   0x8c,   0x57  },
+               [QAM_32]  = { (1<<2),  0x64,    0x74,   0x96,   0x8c,   0x57  },
+               [QAM_64]  = { (2<<2),  0x46,    0x43,   0x6a,   0x6a,   0x44  },
+               [QAM_128] = { (3<<2),  0x36,    0x34,   0x7e,   0x78,   0x4c  },
+               [QAM_256] = { (4<<2),  0x26,    0x23,   0x6c,   0x5c,   0x3c  },
+       };
+
+       switch (delsys) {
+       case SYS_DVBC_ANNEX_A:
+               is_annex_c = false;
+               break;
+       case SYS_DVBC_ANNEX_C:
+               is_annex_c = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * gcc optimizes the code bellow the same way as it would code:
+        *               "if (qam > 5) return -EINVAL;"
+        * Yet, the code is clearer, as it shows what QAM standards are
+        * supported by the driver, and avoids the usage of magic numbers on
+        * it.
+        */
+       switch (qam) {
+       case QPSK:
+       case QAM_16:
+       case QAM_32:
+       case QAM_64:
+       case QAM_128:
+       case QAM_256:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       tda10023_set_symbolrate(state, c->symbol_rate);
+       tda10023_writereg(state, 0x05, qam_params[qam].lockthr);
+       tda10023_writereg(state, 0x08, qam_params[qam].mseth);
+       tda10023_writereg(state, 0x09, qam_params[qam].aref);
+       tda10023_writereg(state, 0xb4, qam_params[qam].agcrefnyq);
+       tda10023_writereg(state, 0xb6, qam_params[qam].eragnyq_thd);
+#if 0
+       tda10023_writereg(state, 0x04, (c->inversion ? 0x12 : 0x32));
+       tda10023_writebit(state, 0x04, 0x60, (c->inversion ? 0 : 0x20));
+#endif
+       tda10023_writebit(state, 0x04, 0x40, 0x40);
+
+       if (is_annex_c)
+               tda10023_writebit(state, 0x3d, 0xfc, 0x03);
+       else
+               tda10023_writebit(state, 0x3d, 0xfc, 0x02);
+
+       tda10023_setup_reg0(state, qam_params[qam].qam);
+
+       return 0;
+}
+
+static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       int sync;
+
+       *status = 0;
+
+       //0x11[1] == CARLOCK -> Carrier locked
+       //0x11[2] == FSYNC -> Frame synchronisation
+       //0x11[3] == FEL -> Front End locked
+       //0x11[6] == NODVB -> DVB Mode Information
+       sync = tda10023_readreg (state, 0x11);
+
+       if (sync & 2)
+               *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
+
+       if (sync & 4)
+               *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
+
+       if (sync & 8)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       u8 a,b,c;
+       a=tda10023_readreg(state, 0x14);
+       b=tda10023_readreg(state, 0x15);
+       c=tda10023_readreg(state, 0x16)&0xf;
+       tda10023_writebit (state, 0x10, 0xc0, 0x00);
+
+       *ber = a | (b<<8)| (c<<16);
+       return 0;
+}
+
+static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       u8 ifgain=tda10023_readreg(state, 0x2f);
+
+       u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
+       // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
+       if (gain>0x90)
+               gain=gain+2*(gain-0x90);
+       if (gain>255)
+               gain=255;
+
+       *strength = (gain<<8)|gain;
+       return 0;
+}
+
+static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+
+       u8 quality = ~tda10023_readreg(state, 0x18);
+       *snr = (quality << 8) | quality;
+       return 0;
+}
+
+static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       u8 a,b,c,d;
+       a= tda10023_readreg (state, 0x74);
+       b= tda10023_readreg (state, 0x75);
+       c= tda10023_readreg (state, 0x76);
+       d= tda10023_readreg (state, 0x77);
+       *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
+
+       tda10023_writebit (state, 0x10, 0x20,0x00);
+       tda10023_writebit (state, 0x10, 0x20,0x20);
+       tda10023_writebit (state, 0x13, 0x01, 0x00);
+
+       return 0;
+}
+
+static int tda10023_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda10023_state* state = fe->demodulator_priv;
+       int sync,inv;
+       s8 afc = 0;
+
+       sync = tda10023_readreg(state, 0x11);
+       afc = tda10023_readreg(state, 0x19);
+       inv = tda10023_readreg(state, 0x04);
+
+       if (verbose) {
+               /* AFC only valid when carrier has been recovered */
+               printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
+                                 "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
+                       state->frontend.dvb->num, afc,
+                      -((s32)p->symbol_rate * afc) >> 10);
+       }
+
+       p->inversion = (inv&0x20?0:1);
+       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
+
+       p->fec_inner = FEC_NONE;
+       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+
+       if (sync & 2)
+               p->frequency -= ((s32)p->symbol_rate * afc) >> 10;
+
+       return 0;
+}
+
+static int tda10023_sleep(struct dvb_frontend* fe)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+
+       tda10023_writereg (state, 0x1b, 0x02);  /* pdown ADC */
+       tda10023_writereg (state, 0x00, 0x80);  /* standby */
+
+       return 0;
+}
+
+static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               lock_tuner(state);
+       } else {
+               unlock_tuner(state);
+       }
+       return 0;
+}
+
+static void tda10023_release(struct dvb_frontend* fe)
+{
+       struct tda10023_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops tda10023_ops;
+
+struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
+                                    struct i2c_adapter *i2c,
+                                    u8 pwm)
+{
+       struct tda10023_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* wakeup if in standby */
+       tda10023_writereg (state, 0x00, 0x33);
+       /* check if the demod is there */
+       if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+       state->pwm = pwm;
+       state->reg0 = REG0_INIT_VAL;
+       if (state->config->xtal) {
+               state->xtal  = state->config->xtal;
+               state->pll_m = state->config->pll_m;
+               state->pll_p = state->config->pll_p;
+               state->pll_n = state->config->pll_n;
+       } else {
+               /* set default values if not defined in config */
+               state->xtal  = 28920000;
+               state->pll_m = 8;
+               state->pll_p = 4;
+               state->pll_n = 1;
+       }
+
+       /* calc sysclk */
+       state->sysclk = (state->xtal * state->pll_m / \
+                       (state->pll_n * state->pll_p));
+
+       state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
+       state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
+
+       dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
+               __func__, state->xtal, state->pll_m, state->pll_p,
+               state->pll_n);
+
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops tda10023_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
+       .info = {
+               .name = "Philips TDA10023 DVB-C",
+               .frequency_stepsize = 62500,
+               .frequency_min =  47000000,
+               .frequency_max = 862000000,
+               .symbol_rate_min = 0,  /* set in tda10023_attach */
+               .symbol_rate_max = 0,  /* set in tda10023_attach */
+               .caps = 0x400 | //FE_CAN_QAM_4
+                       FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+                       FE_CAN_FEC_AUTO
+       },
+
+       .release = tda10023_release,
+
+       .init = tda10023_init,
+       .sleep = tda10023_sleep,
+       .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
+
+       .set_frontend = tda10023_set_parameters,
+       .get_frontend = tda10023_get_frontend,
+       .read_status = tda10023_read_status,
+       .read_ber = tda10023_read_ber,
+       .read_signal_strength = tda10023_read_signal_strength,
+       .read_snr = tda10023_read_snr,
+       .read_ucblocks = tda10023_read_ucblocks,
+};
+
+
+MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
+MODULE_AUTHOR("Georg Acher, Hartmut Birr");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10023_attach);
diff --git a/drivers/media/dvb-frontends/tda1002x.h b/drivers/media/dvb-frontends/tda1002x.h
new file mode 100644 (file)
index 0000000..04d1941
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+    TDA10021/TDA10023  - Single Chip Cable Channel Receiver driver module
+                        used on the the Siemens DVB-C cards
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
+                  Support for TDA10021
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef TDA1002x_H
+#define TDA1002x_H
+
+#include <linux/dvb/frontend.h>
+
+struct tda1002x_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+       u8 invert;
+};
+
+enum tda10023_output_mode {
+       TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
+       TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
+       TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
+       TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
+};
+
+struct tda10023_config {
+       /* the demodulator's i2c address */
+       u8 demod_address;
+       u8 invert;
+
+       /* clock settings */
+       u32 xtal; /* defaults: 28920000 */
+       u8 pll_m; /* defaults: 8 */
+       u8 pll_p; /* defaults: 4 */
+       u8 pll_n; /* defaults: 1 */
+
+       /* MPEG2 TS output mode */
+       u8 output_mode;
+
+       /* input freq offset + baseband conversion type */
+       u16 deltaf;
+};
+
+#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
+                                           struct i2c_adapter* i2c, u8 pwm);
+#else
+static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
+                                           struct i2c_adapter* i2c, u8 pwm)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA10021
+
+#if defined(CONFIG_DVB_TDA10023) || \
+       (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10023_attach(
+       const struct tda10023_config *config,
+       struct i2c_adapter *i2c, u8 pwm);
+#else
+static inline struct dvb_frontend *tda10023_attach(
+       const struct tda10023_config *config,
+       struct i2c_adapter *i2c, u8 pwm)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA10023
+
+#endif // TDA1002x_H
diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
new file mode 100644 (file)
index 0000000..71fb632
--- /dev/null
@@ -0,0 +1,1191 @@
+/*
+    NXP TDA10048HN DVB OFDM demodulator driver
+
+    Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/math64.h>
+#include <asm/div64.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "tda10048.h"
+
+#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
+#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878
+
+/* Register name definitions */
+#define TDA10048_IDENTITY          0x00
+#define TDA10048_VERSION           0x01
+#define TDA10048_DSP_CODE_CPT      0x0C
+#define TDA10048_DSP_CODE_IN       0x0E
+#define TDA10048_IN_CONF1          0x10
+#define TDA10048_IN_CONF2          0x11
+#define TDA10048_IN_CONF3          0x12
+#define TDA10048_OUT_CONF1         0x14
+#define TDA10048_OUT_CONF2         0x15
+#define TDA10048_OUT_CONF3         0x16
+#define TDA10048_AUTO              0x18
+#define TDA10048_SYNC_STATUS       0x1A
+#define TDA10048_CONF_C4_1         0x1E
+#define TDA10048_CONF_C4_2         0x1F
+#define TDA10048_CODE_IN_RAM       0x20
+#define TDA10048_CHANNEL_INFO1_R   0x22
+#define TDA10048_CHANNEL_INFO2_R   0x23
+#define TDA10048_CHANNEL_INFO1     0x24
+#define TDA10048_CHANNEL_INFO2     0x25
+#define TDA10048_TIME_ERROR_R      0x26
+#define TDA10048_TIME_ERROR        0x27
+#define TDA10048_FREQ_ERROR_LSB_R  0x28
+#define TDA10048_FREQ_ERROR_MSB_R  0x29
+#define TDA10048_FREQ_ERROR_LSB    0x2A
+#define TDA10048_FREQ_ERROR_MSB    0x2B
+#define TDA10048_IT_SEL            0x30
+#define TDA10048_IT_STAT           0x32
+#define TDA10048_DSP_AD_LSB        0x3C
+#define TDA10048_DSP_AD_MSB        0x3D
+#define TDA10048_DSP_REG_LSB       0x3E
+#define TDA10048_DSP_REG_MSB       0x3F
+#define TDA10048_CONF_TRISTATE1    0x44
+#define TDA10048_CONF_TRISTATE2    0x45
+#define TDA10048_CONF_POLARITY     0x46
+#define TDA10048_GPIO_SP_DS0       0x48
+#define TDA10048_GPIO_SP_DS1       0x49
+#define TDA10048_GPIO_SP_DS2       0x4A
+#define TDA10048_GPIO_SP_DS3       0x4B
+#define TDA10048_GPIO_OUT_SEL      0x4C
+#define TDA10048_GPIO_SELECT       0x4D
+#define TDA10048_IC_MODE           0x4E
+#define TDA10048_CONF_XO           0x50
+#define TDA10048_CONF_PLL1         0x51
+#define TDA10048_CONF_PLL2         0x52
+#define TDA10048_CONF_PLL3         0x53
+#define TDA10048_CONF_ADC          0x54
+#define TDA10048_CONF_ADC_2        0x55
+#define TDA10048_CONF_C1_1         0x60
+#define TDA10048_CONF_C1_3         0x62
+#define TDA10048_AGC_CONF          0x70
+#define TDA10048_AGC_THRESHOLD_LSB 0x72
+#define TDA10048_AGC_THRESHOLD_MSB 0x73
+#define TDA10048_AGC_RENORM        0x74
+#define TDA10048_AGC_GAINS         0x76
+#define TDA10048_AGC_TUN_MIN       0x78
+#define TDA10048_AGC_TUN_MAX       0x79
+#define TDA10048_AGC_IF_MIN        0x7A
+#define TDA10048_AGC_IF_MAX        0x7B
+#define TDA10048_AGC_TUN_LEVEL     0x7E
+#define TDA10048_AGC_IF_LEVEL      0x7F
+#define TDA10048_DIG_AGC_LEVEL     0x81
+#define TDA10048_FREQ_PHY2_LSB     0x86
+#define TDA10048_FREQ_PHY2_MSB     0x87
+#define TDA10048_TIME_INVWREF_LSB  0x88
+#define TDA10048_TIME_INVWREF_MSB  0x89
+#define TDA10048_TIME_WREF_LSB     0x8A
+#define TDA10048_TIME_WREF_MID1    0x8B
+#define TDA10048_TIME_WREF_MID2    0x8C
+#define TDA10048_TIME_WREF_MSB     0x8D
+#define TDA10048_NP_OUT            0xA2
+#define TDA10048_CELL_ID_LSB       0xA4
+#define TDA10048_CELL_ID_MSB       0xA5
+#define TDA10048_EXTTPS_ODD        0xAA
+#define TDA10048_EXTTPS_EVEN       0xAB
+#define TDA10048_TPS_LENGTH        0xAC
+#define TDA10048_FREE_REG_1        0xB2
+#define TDA10048_FREE_REG_2        0xB3
+#define TDA10048_CONF_C3_1         0xC0
+#define TDA10048_CVBER_CTRL        0xC2
+#define TDA10048_CBER_NMAX_LSB     0xC4
+#define TDA10048_CBER_NMAX_MSB     0xC5
+#define TDA10048_CBER_LSB          0xC6
+#define TDA10048_CBER_MSB          0xC7
+#define TDA10048_VBER_LSB          0xC8
+#define TDA10048_VBER_MID          0xC9
+#define TDA10048_VBER_MSB          0xCA
+#define TDA10048_CVBER_LUT         0xCC
+#define TDA10048_UNCOR_CTRL        0xCD
+#define TDA10048_UNCOR_CPT_LSB     0xCE
+#define TDA10048_UNCOR_CPT_MSB     0xCF
+#define TDA10048_SOFT_IT_C3        0xD6
+#define TDA10048_CONF_TS2          0xE0
+#define TDA10048_CONF_TS1          0xE1
+
+static unsigned int debug;
+
+#define dprintk(level, fmt, arg...)\
+       do { if (debug >= level)\
+               printk(KERN_DEBUG "tda10048: " fmt, ## arg);\
+       } while (0)
+
+struct tda10048_state {
+
+       struct i2c_adapter *i2c;
+
+       /* We'll cache and update the attach config settings */
+       struct tda10048_config config;
+       struct dvb_frontend frontend;
+
+       int fwloaded;
+
+       u32 freq_if_hz;
+       u32 xtal_hz;
+       u32 pll_mfactor;
+       u32 pll_nfactor;
+       u32 pll_pfactor;
+       u32 sample_freq;
+
+       u32 bandwidth;
+};
+
+static struct init_tab {
+       u8      reg;
+       u16     data;
+} init_tab[] = {
+       { TDA10048_CONF_PLL1, 0x08 },
+       { TDA10048_CONF_ADC_2, 0x00 },
+       { TDA10048_CONF_C4_1, 0x00 },
+       { TDA10048_CONF_PLL1, 0x0f },
+       { TDA10048_CONF_PLL2, 0x0a },
+       { TDA10048_CONF_PLL3, 0x43 },
+       { TDA10048_FREQ_PHY2_LSB, 0x02 },
+       { TDA10048_FREQ_PHY2_MSB, 0x0a },
+       { TDA10048_TIME_WREF_LSB, 0xbd },
+       { TDA10048_TIME_WREF_MID1, 0xe4 },
+       { TDA10048_TIME_WREF_MID2, 0xa8 },
+       { TDA10048_TIME_WREF_MSB, 0x02 },
+       { TDA10048_TIME_INVWREF_LSB, 0x04 },
+       { TDA10048_TIME_INVWREF_MSB, 0x06 },
+       { TDA10048_CONF_C4_1, 0x00 },
+       { TDA10048_CONF_C1_1, 0xa8 },
+       { TDA10048_AGC_CONF, 0x16 },
+       { TDA10048_CONF_C1_3, 0x0b },
+       { TDA10048_AGC_TUN_MIN, 0x00 },
+       { TDA10048_AGC_TUN_MAX, 0xff },
+       { TDA10048_AGC_IF_MIN, 0x00 },
+       { TDA10048_AGC_IF_MAX, 0xff },
+       { TDA10048_AGC_THRESHOLD_MSB, 0x00 },
+       { TDA10048_AGC_THRESHOLD_LSB, 0x70 },
+       { TDA10048_CVBER_CTRL, 0x38 },
+       { TDA10048_AGC_GAINS, 0x12 },
+       { TDA10048_CONF_XO, 0x00 },
+       { TDA10048_CONF_TS1, 0x07 },
+       { TDA10048_IC_MODE, 0x00 },
+       { TDA10048_CONF_TS2, 0xc0 },
+       { TDA10048_CONF_TRISTATE1, 0x21 },
+       { TDA10048_CONF_TRISTATE2, 0x00 },
+       { TDA10048_CONF_POLARITY, 0x00 },
+       { TDA10048_CONF_C4_2, 0x04 },
+       { TDA10048_CONF_ADC, 0x60 },
+       { TDA10048_CONF_ADC_2, 0x10 },
+       { TDA10048_CONF_ADC, 0x60 },
+       { TDA10048_CONF_ADC_2, 0x00 },
+       { TDA10048_CONF_C1_1, 0xa8 },
+       { TDA10048_UNCOR_CTRL, 0x00 },
+       { TDA10048_CONF_C4_2, 0x04 },
+};
+
+static struct pll_tab {
+       u32     clk_freq_khz;
+       u32     if_freq_khz;
+} pll_tab[] = {
+       { TDA10048_CLK_4000,  TDA10048_IF_36130 },
+       { TDA10048_CLK_16000, TDA10048_IF_3300 },
+       { TDA10048_CLK_16000, TDA10048_IF_3500 },
+       { TDA10048_CLK_16000, TDA10048_IF_3800 },
+       { TDA10048_CLK_16000, TDA10048_IF_4000 },
+       { TDA10048_CLK_16000, TDA10048_IF_4300 },
+       { TDA10048_CLK_16000, TDA10048_IF_4500 },
+       { TDA10048_CLK_16000, TDA10048_IF_5000 },
+       { TDA10048_CLK_16000, TDA10048_IF_36130 },
+};
+
+static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
+{
+       struct tda10048_config *config = &state->config;
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = {
+               .addr = config->demod_address,
+               .flags = 0, .buf = buf, .len = 2 };
+
+       dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data);
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk("%s: writereg error (ret == %i)\n", __func__, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
+{
+       struct tda10048_config *config = &state->config;
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               { .addr = config->demod_address,
+                       .flags = 0, .buf = b0, .len = 1 },
+               { .addr = config->demod_address,
+                       .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg);
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+                       __func__, ret);
+
+       return b1[0];
+}
+
+static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
+                                const u8 *data, u16 len)
+{
+       struct tda10048_config *config = &state->config;
+       int ret = -EREMOTEIO;
+       struct i2c_msg msg;
+       u8 *buf;
+
+       dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len);
+
+       buf = kmalloc(len + 1, GFP_KERNEL);
+       if (buf == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       *buf = reg;
+       memcpy(buf + 1, data, len);
+
+       msg.addr = config->demod_address;
+       msg.flags = 0;
+       msg.buf = buf;
+       msg.len = len + 1;
+
+       dprintk(2, "%s():  write len = %d\n",
+               __func__, msg.len);
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+       if (ret != 1) {
+               printk(KERN_ERR "%s(): writereg error err %i\n",
+                        __func__, ret);
+               ret = -EREMOTEIO;
+       }
+
+error:
+       kfree(buf);
+
+       return ret;
+}
+
+static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz,
+                            u32 if_hz)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u64 t;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (sample_freq_hz == 0)
+               return -EINVAL;
+
+       if (if_hz < (sample_freq_hz / 2)) {
+               /* PHY2 = (if2/fs) * 2^15 */
+               t = if_hz;
+               t *= 10;
+               t *= 32768;
+               do_div(t, sample_freq_hz);
+               t += 5;
+               do_div(t, 10);
+       } else {
+               /* PHY2 = ((IF1-fs)/fs) * 2^15 */
+               t = sample_freq_hz - if_hz;
+               t *= 10;
+               t *= 32768;
+               do_div(t, sample_freq_hz);
+               t += 5;
+               do_div(t, 10);
+               t = ~t + 1;
+       }
+
+       tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t);
+       tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8));
+
+       return 0;
+}
+
+static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz,
+                            u32 bw)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u64 t, z;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (sample_freq_hz == 0)
+               return -EINVAL;
+
+       /* WREF = (B / (7 * fs)) * 2^31 */
+       t = bw * 10;
+       /* avoid warning: this decimal constant is unsigned only in ISO C90 */
+       /* t *= 2147483648 on 32bit platforms */
+       t *= (2048 * 1024);
+       t *= 1024;
+       z = 7 * sample_freq_hz;
+       do_div(t, z);
+       t += 5;
+       do_div(t, 10);
+
+       tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t);
+       tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8));
+       tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16));
+       tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24));
+
+       return 0;
+}
+
+static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz,
+                               u32 bw)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u64 t;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (sample_freq_hz == 0)
+               return -EINVAL;
+
+       /* INVWREF = ((7 * fs) / B) * 2^5 */
+       t = sample_freq_hz;
+       t *= 7;
+       t *= 32;
+       t *= 10;
+       do_div(t, bw);
+       t += 5;
+       do_div(t, 10);
+
+       tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t);
+       tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8));
+
+       return 0;
+}
+
+static int tda10048_set_bandwidth(struct dvb_frontend *fe,
+       u32 bw)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       dprintk(1, "%s(bw=%d)\n", __func__, bw);
+
+       /* Bandwidth setting may need to be adjusted */
+       switch (bw) {
+       case 6000000:
+       case 7000000:
+       case 8000000:
+               tda10048_set_wref(fe, state->sample_freq, bw);
+               tda10048_set_invwref(fe, state->sample_freq, bw);
+               break;
+       default:
+               printk(KERN_ERR "%s() invalid bandwidth\n", __func__);
+               return -EINVAL;
+       }
+
+       state->bandwidth = bw;
+
+       return 0;
+}
+
+static int tda10048_set_if(struct dvb_frontend *fe, u32 bw)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       struct tda10048_config *config = &state->config;
+       int i;
+       u32 if_freq_khz;
+
+       dprintk(1, "%s(bw = %d)\n", __func__, bw);
+
+       /* based on target bandwidth and clk we calculate pll factors */
+       switch (bw) {
+       case 6000000:
+               if_freq_khz = config->dtv6_if_freq_khz;
+               break;
+       case 7000000:
+               if_freq_khz = config->dtv7_if_freq_khz;
+               break;
+       case 8000000:
+               if_freq_khz = config->dtv8_if_freq_khz;
+               break;
+       default:
+               printk(KERN_ERR "%s() no default\n", __func__);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(pll_tab); i++) {
+               if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) &&
+                       (pll_tab[i].if_freq_khz == if_freq_khz)) {
+
+                       state->freq_if_hz = pll_tab[i].if_freq_khz * 1000;
+                       state->xtal_hz = pll_tab[i].clk_freq_khz * 1000;
+                       break;
+               }
+       }
+       if (i == ARRAY_SIZE(pll_tab)) {
+               printk(KERN_ERR "%s() Incorrect attach settings\n",
+                       __func__);
+               return -EINVAL;
+       }
+
+       dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz);
+       dprintk(1, "- xtal_hz = %d\n", state->xtal_hz);
+       dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor);
+       dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor);
+       dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
+
+       /* Calculate the sample frequency */
+       state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
+       state->sample_freq /= (state->pll_nfactor + 1);
+       state->sample_freq /= (state->pll_pfactor + 4);
+       dprintk(1, "- sample_freq = %d\n", state->sample_freq);
+
+       /* Update the I/F */
+       tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz);
+
+       return 0;
+}
+
+static int tda10048_firmware_upload(struct dvb_frontend *fe)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       struct tda10048_config *config = &state->config;
+       const struct firmware *fw;
+       int ret;
+       int pos = 0;
+       int cnt;
+       u8 wlen = config->fwbulkwritelen;
+
+       if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50))
+               wlen = TDA10048_BULKWRITE_200;
+
+       /* request the firmware, this will block and timeout */
+       printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n",
+               __func__,
+               TDA10048_DEFAULT_FIRMWARE);
+
+       ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
+               state->i2c->dev.parent);
+       if (ret) {
+               printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
+                       __func__);
+               return -EIO;
+       } else {
+               printk(KERN_INFO "%s: firmware read %Zu bytes.\n",
+                       __func__,
+                       fw->size);
+               ret = 0;
+       }
+
+       if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
+               printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
+               ret = -EIO;
+       } else {
+               printk(KERN_INFO "%s: firmware uploading\n", __func__);
+
+               /* Soft reset */
+               tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
+                       tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
+                               & 0xfe);
+               tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
+                       tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
+                               | 0x01);
+
+               /* Put the demod into host download mode */
+               tda10048_writereg(state, TDA10048_CONF_C4_1,
+                       tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9);
+
+               /* Boot the DSP */
+               tda10048_writereg(state, TDA10048_CONF_C4_1,
+                       tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08);
+
+               /* Prepare for download */
+               tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0);
+
+               /* Download the firmware payload */
+               while (pos < fw->size) {
+
+                       if ((fw->size - pos) > wlen)
+                               cnt = wlen;
+                       else
+                               cnt = fw->size - pos;
+
+                       tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN,
+                               &fw->data[pos], cnt);
+
+                       pos += cnt;
+               }
+
+               ret = -EIO;
+               /* Wait up to 250ms for the DSP to boot */
+               for (cnt = 0; cnt < 250 ; cnt += 10) {
+
+                       msleep(10);
+
+                       if (tda10048_readreg(state, TDA10048_SYNC_STATUS)
+                               & 0x40) {
+                               ret = 0;
+                               break;
+                       }
+               }
+       }
+
+       release_firmware(fw);
+
+       if (ret == 0) {
+               printk(KERN_INFO "%s: firmware uploaded\n", __func__);
+               state->fwloaded = 1;
+       } else
+               printk(KERN_ERR "%s: firmware upload failed\n", __func__);
+
+       return ret;
+}
+
+static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+
+       dprintk(1, "%s(%d)\n", __func__, inversion);
+
+       if (inversion == TDA10048_INVERSION_ON)
+               tda10048_writereg(state, TDA10048_CONF_C1_1,
+                       tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20);
+       else
+               tda10048_writereg(state, TDA10048_CONF_C1_1,
+                       tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf);
+
+       return 0;
+}
+
+/* Retrieve the demod settings */
+static int tda10048_get_tps(struct tda10048_state *state,
+       struct dtv_frontend_properties *p)
+{
+       u8 val;
+
+       /* Make sure the TPS regs are valid */
+       if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01))
+               return -EAGAIN;
+
+       val = tda10048_readreg(state, TDA10048_OUT_CONF2);
+       switch ((val & 0x60) >> 5) {
+       case 0:
+               p->modulation = QPSK;
+               break;
+       case 1:
+               p->modulation = QAM_16;
+               break;
+       case 2:
+               p->modulation = QAM_64;
+               break;
+       }
+       switch ((val & 0x18) >> 3) {
+       case 0:
+               p->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               p->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               p->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               p->hierarchy = HIERARCHY_4;
+               break;
+       }
+       switch (val & 0x07) {
+       case 0:
+               p->code_rate_HP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_HP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_HP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_HP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_HP = FEC_7_8;
+               break;
+       }
+
+       val = tda10048_readreg(state, TDA10048_OUT_CONF3);
+       switch (val & 0x07) {
+       case 0:
+               p->code_rate_LP = FEC_1_2;
+               break;
+       case 1:
+               p->code_rate_LP = FEC_2_3;
+               break;
+       case 2:
+               p->code_rate_LP = FEC_3_4;
+               break;
+       case 3:
+               p->code_rate_LP = FEC_5_6;
+               break;
+       case 4:
+               p->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       val = tda10048_readreg(state, TDA10048_OUT_CONF1);
+       switch ((val & 0x0c) >> 2) {
+       case 0:
+               p->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               p->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               p->guard_interval =  GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               p->guard_interval =  GUARD_INTERVAL_1_4;
+               break;
+       }
+       switch (val & 0x03) {
+       case 0:
+               p->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               p->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+
+       return 0;
+}
+
+static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       struct tda10048_config *config = &state->config;
+       dprintk(1, "%s(%d)\n", __func__, enable);
+
+       if (config->disable_gate_access)
+               return 0;
+
+       if (enable)
+               return tda10048_writereg(state, TDA10048_CONF_C4_1,
+                       tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
+       else
+               return tda10048_writereg(state, TDA10048_CONF_C4_1,
+                       tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
+}
+
+static int tda10048_output_mode(struct dvb_frontend *fe, int serial)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       dprintk(1, "%s(%d)\n", __func__, serial);
+
+       /* Ensure pins are out of tri-state */
+       tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21);
+       tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00);
+
+       if (serial) {
+               tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20);
+               tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0);
+       } else {
+               tda10048_writereg(state, TDA10048_IC_MODE, 0x00);
+               tda10048_writereg(state, TDA10048_CONF_TS2, 0x01);
+       }
+
+       return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+/* TODO: Support manual tuning with specific params */
+static int tda10048_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda10048_state *state = fe->demodulator_priv;
+
+       dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
+
+       /* Update the I/F pll's if the bandwidth changes */
+       if (p->bandwidth_hz != state->bandwidth) {
+               tda10048_set_if(fe, p->bandwidth_hz);
+               tda10048_set_bandwidth(fe, p->bandwidth_hz);
+       }
+
+       if (fe->ops.tuner_ops.set_params) {
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               fe->ops.tuner_ops.set_params(fe);
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* Enable demod TPS auto detection and begin acquisition */
+       tda10048_writereg(state, TDA10048_AUTO, 0x57);
+       /* trigger cber and vber acquisition */
+       tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B);
+
+       return 0;
+}
+
+/* Establish sane defaults and load firmware. */
+static int tda10048_init(struct dvb_frontend *fe)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       struct tda10048_config *config = &state->config;
+       int ret = 0, i;
+
+       dprintk(1, "%s()\n", __func__);
+
+       /* PLL */
+       init_tab[4].data = (u8)(state->pll_mfactor);
+       init_tab[5].data = (u8)(state->pll_nfactor) | 0x40;
+
+       /* Apply register defaults */
+       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+               tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);
+
+       if (state->fwloaded == 0)
+               ret = tda10048_firmware_upload(fe);
+
+       /* Set either serial or parallel */
+       tda10048_output_mode(fe, config->output_mode);
+
+       /* Set inversion */
+       tda10048_set_inversion(fe, config->inversion);
+
+       /* Establish default RF values */
+       tda10048_set_if(fe, 8000000);
+       tda10048_set_bandwidth(fe, 8000000);
+
+       /* Ensure we leave the gate closed */
+       tda10048_i2c_gate_ctrl(fe, 0);
+
+       return ret;
+}
+
+static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u8 reg;
+
+       *status = 0;
+
+       reg = tda10048_readreg(state, TDA10048_SYNC_STATUS);
+
+       dprintk(1, "%s() status =0x%02x\n", __func__, reg);
+
+       if (reg & 0x02)
+               *status |= FE_HAS_CARRIER;
+
+       if (reg & 0x04)
+               *status |= FE_HAS_SIGNAL;
+
+       if (reg & 0x08) {
+               *status |= FE_HAS_LOCK;
+               *status |= FE_HAS_VITERBI;
+               *status |= FE_HAS_SYNC;
+       }
+
+       return 0;
+}
+
+static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       static u32 cber_current;
+       u32 cber_nmax;
+       u64 cber_tmp;
+
+       dprintk(1, "%s()\n", __func__);
+
+       /* update cber on interrupt */
+       if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) {
+               cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
+                       tda10048_readreg(state, TDA10048_CBER_LSB);
+               cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 |
+                       tda10048_readreg(state, TDA10048_CBER_NMAX_LSB);
+               cber_tmp *= 100000000;
+               cber_tmp *= 2;
+               cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1);
+               cber_current = (u32)cber_tmp;
+               /* retrigger cber acquisition */
+               tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39);
+       }
+       /* actual cber is (*ber)/1e8 */
+       *ber = cber_current;
+
+       return 0;
+}
+
+static int tda10048_read_signal_strength(struct dvb_frontend *fe,
+       u16 *signal_strength)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u8 v;
+
+       dprintk(1, "%s()\n", __func__);
+
+       *signal_strength = 65535;
+
+       v = tda10048_readreg(state, TDA10048_NP_OUT);
+       if (v > 0)
+               *signal_strength -= (v << 8) | v;
+
+       return 0;
+}
+
+/* SNR lookup table */
+static struct snr_tab {
+       u8 val;
+       u8 data;
+} snr_tab[] = {
+       {   0,   0 },
+       {   1, 246 },
+       {   2, 215 },
+       {   3, 198 },
+       {   4, 185 },
+       {   5, 176 },
+       {   6, 168 },
+       {   7, 161 },
+       {   8, 155 },
+       {   9, 150 },
+       {  10, 146 },
+       {  11, 141 },
+       {  12, 138 },
+       {  13, 134 },
+       {  14, 131 },
+       {  15, 128 },
+       {  16, 125 },
+       {  17, 122 },
+       {  18, 120 },
+       {  19, 118 },
+       {  20, 115 },
+       {  21, 113 },
+       {  22, 111 },
+       {  23, 109 },
+       {  24, 107 },
+       {  25, 106 },
+       {  26, 104 },
+       {  27, 102 },
+       {  28, 101 },
+       {  29,  99 },
+       {  30,  98 },
+       {  31,  96 },
+       {  32,  95 },
+       {  33,  94 },
+       {  34,  92 },
+       {  35,  91 },
+       {  36,  90 },
+       {  37,  89 },
+       {  38,  88 },
+       {  39,  86 },
+       {  40,  85 },
+       {  41,  84 },
+       {  42,  83 },
+       {  43,  82 },
+       {  44,  81 },
+       {  45,  80 },
+       {  46,  79 },
+       {  47,  78 },
+       {  48,  77 },
+       {  49,  76 },
+       {  50,  76 },
+       {  51,  75 },
+       {  52,  74 },
+       {  53,  73 },
+       {  54,  72 },
+       {  56,  71 },
+       {  57,  70 },
+       {  58,  69 },
+       {  60,  68 },
+       {  61,  67 },
+       {  63,  66 },
+       {  64,  65 },
+       {  66,  64 },
+       {  67,  63 },
+       {  68,  62 },
+       {  69,  62 },
+       {  70,  61 },
+       {  72,  60 },
+       {  74,  59 },
+       {  75,  58 },
+       {  77,  57 },
+       {  79,  56 },
+       {  81,  55 },
+       {  83,  54 },
+       {  85,  53 },
+       {  87,  52 },
+       {  89,  51 },
+       {  91,  50 },
+       {  93,  49 },
+       {  95,  48 },
+       {  97,  47 },
+       { 100,  46 },
+       { 102,  45 },
+       { 104,  44 },
+       { 107,  43 },
+       { 109,  42 },
+       { 112,  41 },
+       { 114,  40 },
+       { 117,  39 },
+       { 120,  38 },
+       { 123,  37 },
+       { 125,  36 },
+       { 128,  35 },
+       { 131,  34 },
+       { 134,  33 },
+       { 138,  32 },
+       { 141,  31 },
+       { 144,  30 },
+       { 147,  29 },
+       { 151,  28 },
+       { 154,  27 },
+       { 158,  26 },
+       { 162,  25 },
+       { 165,  24 },
+       { 169,  23 },
+       { 173,  22 },
+       { 177,  21 },
+       { 181,  20 },
+       { 186,  19 },
+       { 190,  18 },
+       { 194,  17 },
+       { 199,  16 },
+       { 204,  15 },
+       { 208,  14 },
+       { 213,  13 },
+       { 218,  12 },
+       { 223,  11 },
+       { 229,  10 },
+       { 234,   9 },
+       { 239,   8 },
+       { 245,   7 },
+       { 251,   6 },
+       { 255,   5 },
+};
+
+static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       u8 v;
+       int i, ret = -EINVAL;
+
+       dprintk(1, "%s()\n", __func__);
+
+       v = tda10048_readreg(state, TDA10048_NP_OUT);
+       for (i = 0; i < ARRAY_SIZE(snr_tab); i++) {
+               if (v <= snr_tab[i].val) {
+                       *snr = snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+
+       dprintk(1, "%s()\n", __func__);
+
+       *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |
+               tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);
+       /* clear the uncorrected TS packets counter when saturated */
+       if (*ucblocks == 0xFFFF)
+               tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80);
+
+       return 0;
+}
+
+static int tda10048_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda10048_state *state = fe->demodulator_priv;
+
+       dprintk(1, "%s()\n", __func__);
+
+       p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1)
+               & 0x20 ? INVERSION_ON : INVERSION_OFF;
+
+       return tda10048_get_tps(state, p);
+}
+
+static int tda10048_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void tda10048_release(struct dvb_frontend *fe)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       dprintk(1, "%s()\n", __func__);
+       kfree(state);
+}
+
+static void tda10048_establish_defaults(struct dvb_frontend *fe)
+{
+       struct tda10048_state *state = fe->demodulator_priv;
+       struct tda10048_config *config = &state->config;
+
+       /* Validate/default the config */
+       if (config->dtv6_if_freq_khz == 0) {
+               config->dtv6_if_freq_khz = TDA10048_IF_4300;
+               printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz "
+                       "is not set (defaulting to %d)\n",
+                       __func__,
+                       config->dtv6_if_freq_khz);
+       }
+
+       if (config->dtv7_if_freq_khz == 0) {
+               config->dtv7_if_freq_khz = TDA10048_IF_4300;
+               printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz "
+                       "is not set (defaulting to %d)\n",
+                       __func__,
+                       config->dtv7_if_freq_khz);
+       }
+
+       if (config->dtv8_if_freq_khz == 0) {
+               config->dtv8_if_freq_khz = TDA10048_IF_4300;
+               printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz "
+                       "is not set (defaulting to %d)\n",
+                       __func__,
+                       config->dtv8_if_freq_khz);
+       }
+
+       if (config->clk_freq_khz == 0) {
+               config->clk_freq_khz = TDA10048_CLK_16000;
+               printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz "
+                       "is not set (defaulting to %d)\n",
+                       __func__,
+                       config->clk_freq_khz);
+       }
+}
+
+static struct dvb_frontend_ops tda10048_ops;
+
+struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
+       struct i2c_adapter *i2c)
+{
+       struct tda10048_state *state = NULL;
+
+       dprintk(1, "%s()\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state and clone the config */
+       memcpy(&state->config, config, sizeof(*config));
+       state->i2c = i2c;
+       state->fwloaded = config->no_firmware;
+       state->bandwidth = 8000000;
+
+       /* check if the demod is present */
+       if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10048_ops,
+               sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* set pll */
+       if (config->set_pll) {
+               state->pll_mfactor = config->pll_m;
+               state->pll_nfactor = config->pll_n;
+               state->pll_pfactor = config->pll_p;
+       } else {
+               state->pll_mfactor = 10;
+               state->pll_nfactor = 3;
+               state->pll_pfactor = 0;
+       }
+
+       /* Establish any defaults the the user didn't pass */
+       tda10048_establish_defaults(&state->frontend);
+
+       /* Set the xtal and freq defaults */
+       if (tda10048_set_if(&state->frontend, 8000000) != 0)
+               goto error;
+
+       /* Default bandwidth */
+       if (tda10048_set_bandwidth(&state->frontend, 8000000) != 0)
+               goto error;
+
+       /* Leave the gate closed */
+       tda10048_i2c_gate_ctrl(&state->frontend, 0);
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(tda10048_attach);
+
+static struct dvb_frontend_ops tda10048_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "NXP TDA10048HN DVB-T",
+               .frequency_min          = 177000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+               FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+               FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+       },
+
+       .release = tda10048_release,
+       .init = tda10048_init,
+       .i2c_gate_ctrl = tda10048_i2c_gate_ctrl,
+       .set_frontend = tda10048_set_frontend,
+       .get_frontend = tda10048_get_frontend,
+       .get_tune_settings = tda10048_get_tune_settings,
+       .read_status = tda10048_read_status,
+       .read_ber = tda10048_read_ber,
+       .read_signal_strength = tda10048_read_signal_strength,
+       .read_snr = tda10048_read_snr,
+       .read_ucblocks = tda10048_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda10048.h b/drivers/media/dvb-frontends/tda10048.h
new file mode 100644 (file)
index 0000000..fb2ef5a
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+    NXP TDA10048HN DVB OFDM demodulator driver
+
+    Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef TDA10048_H
+#define TDA10048_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct tda10048_config {
+
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* serial/parallel output */
+#define TDA10048_PARALLEL_OUTPUT 0
+#define TDA10048_SERIAL_OUTPUT   1
+       u8 output_mode;
+
+#define TDA10048_BULKWRITE_200 200
+#define TDA10048_BULKWRITE_50  50
+       u8 fwbulkwritelen;
+
+       /* Spectral Inversion */
+#define TDA10048_INVERSION_OFF 0
+#define TDA10048_INVERSION_ON  1
+       u8 inversion;
+
+#define TDA10048_IF_3300  3300
+#define TDA10048_IF_3500  3500
+#define TDA10048_IF_3800  3800
+#define TDA10048_IF_4000  4000
+#define TDA10048_IF_4300  4300
+#define TDA10048_IF_4500  4500
+#define TDA10048_IF_4750  4750
+#define TDA10048_IF_5000  5000
+#define TDA10048_IF_36130 36130
+       u16 dtv6_if_freq_khz;
+       u16 dtv7_if_freq_khz;
+       u16 dtv8_if_freq_khz;
+
+#define TDA10048_CLK_4000  4000
+#define TDA10048_CLK_16000 16000
+       u16 clk_freq_khz;
+
+       /* Disable I2C gate access */
+       u8 disable_gate_access;
+
+       bool no_firmware;
+
+       bool set_pll;
+       u8 pll_m;
+       u8 pll_p;
+       u8 pll_n;
+};
+
+#if defined(CONFIG_DVB_TDA10048) || \
+       (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10048_attach(
+       const struct tda10048_config *config,
+       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *tda10048_attach(
+       const struct tda10048_config *config,
+       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_TDA10048 */
+
+#endif /* TDA10048_H */
diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
new file mode 100644 (file)
index 0000000..35d72b4
--- /dev/null
@@ -0,0 +1,1381 @@
+  /*
+     Driver for Philips tda1004xh OFDM Demodulator
+
+     (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   */
+/*
+ * This driver needs external firmware. Please use the commands
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
+ * download/extract them, and then copy them to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
+ */
+#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
+#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda1004x.h"
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "tda1004x: " args); \
+       } while (0)
+
+#define TDA1004X_CHIPID                 0x00
+#define TDA1004X_AUTO           0x01
+#define TDA1004X_IN_CONF1       0x02
+#define TDA1004X_IN_CONF2       0x03
+#define TDA1004X_OUT_CONF1      0x04
+#define TDA1004X_OUT_CONF2      0x05
+#define TDA1004X_STATUS_CD      0x06
+#define TDA1004X_CONFC4                 0x07
+#define TDA1004X_DSSPARE2       0x0C
+#define TDA10045H_CODE_IN       0x0D
+#define TDA10045H_FWPAGE        0x0E
+#define TDA1004X_SCAN_CPT       0x10
+#define TDA1004X_DSP_CMD        0x11
+#define TDA1004X_DSP_ARG        0x12
+#define TDA1004X_DSP_DATA1      0x13
+#define TDA1004X_DSP_DATA2      0x14
+#define TDA1004X_CONFADC1       0x15
+#define TDA1004X_CONFC1                 0x16
+#define TDA10045H_S_AGC                 0x1a
+#define TDA10046H_AGC_TUN_LEVEL         0x1a
+#define TDA1004X_SNR            0x1c
+#define TDA1004X_CONF_TS1       0x1e
+#define TDA1004X_CONF_TS2       0x1f
+#define TDA1004X_CBER_RESET     0x20
+#define TDA1004X_CBER_MSB       0x21
+#define TDA1004X_CBER_LSB       0x22
+#define TDA1004X_CVBER_LUT      0x23
+#define TDA1004X_VBER_MSB       0x24
+#define TDA1004X_VBER_MID       0x25
+#define TDA1004X_VBER_LSB       0x26
+#define TDA1004X_UNCOR          0x27
+
+#define TDA10045H_CONFPLL_P     0x2D
+#define TDA10045H_CONFPLL_M_MSB         0x2E
+#define TDA10045H_CONFPLL_M_LSB         0x2F
+#define TDA10045H_CONFPLL_N     0x30
+
+#define TDA10046H_CONFPLL1      0x2D
+#define TDA10046H_CONFPLL2      0x2F
+#define TDA10046H_CONFPLL3      0x30
+#define TDA10046H_TIME_WREF1    0x31
+#define TDA10046H_TIME_WREF2    0x32
+#define TDA10046H_TIME_WREF3    0x33
+#define TDA10046H_TIME_WREF4    0x34
+#define TDA10046H_TIME_WREF5    0x35
+
+#define TDA10045H_UNSURW_MSB    0x31
+#define TDA10045H_UNSURW_LSB    0x32
+#define TDA10045H_WREF_MSB      0x33
+#define TDA10045H_WREF_MID      0x34
+#define TDA10045H_WREF_LSB      0x35
+#define TDA10045H_MUXOUT        0x36
+#define TDA1004X_CONFADC2       0x37
+
+#define TDA10045H_IOFFSET       0x38
+
+#define TDA10046H_CONF_TRISTATE1 0x3B
+#define TDA10046H_CONF_TRISTATE2 0x3C
+#define TDA10046H_CONF_POLARITY         0x3D
+#define TDA10046H_FREQ_OFFSET   0x3E
+#define TDA10046H_GPIO_OUT_SEL  0x41
+#define TDA10046H_GPIO_SELECT   0x42
+#define TDA10046H_AGC_CONF      0x43
+#define TDA10046H_AGC_THR       0x44
+#define TDA10046H_AGC_RENORM    0x45
+#define TDA10046H_AGC_GAINS     0x46
+#define TDA10046H_AGC_TUN_MIN   0x47
+#define TDA10046H_AGC_TUN_MAX   0x48
+#define TDA10046H_AGC_IF_MIN    0x49
+#define TDA10046H_AGC_IF_MAX    0x4A
+
+#define TDA10046H_FREQ_PHY2_MSB         0x4D
+#define TDA10046H_FREQ_PHY2_LSB         0x4E
+
+#define TDA10046H_CVBER_CTRL    0x4F
+#define TDA10046H_AGC_IF_LEVEL  0x52
+#define TDA10046H_CODE_CPT      0x57
+#define TDA10046H_CODE_IN       0x58
+
+
+static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+       dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data);
+
+       msg.addr = state->config->demod_address;
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
+                       __func__, reg, data, ret);
+
+       dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
+               reg, data, ret);
+       return (ret != 1) ? -1 : 0;
+}
+
+static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
+                               { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
+
+       dprintk("%s: reg=0x%x\n", __func__, reg);
+
+       msg[0].addr = state->config->demod_address;
+       msg[1].addr = state->config->demod_address;
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
+                       ret);
+               return -EINVAL;
+       }
+
+       dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
+               reg, b1[0], ret);
+       return b1[0];
+}
+
+static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
+{
+       int val;
+       dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg,
+               mask, data);
+
+       // read a byte and check
+       val = tda1004x_read_byte(state, reg);
+       if (val < 0)
+               return val;
+
+       // mask if off
+       val = val & ~mask;
+       val |= data & 0xff;
+
+       // write it out again
+       return tda1004x_write_byteI(state, reg, val);
+}
+
+static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
+{
+       int i;
+       int result;
+
+       dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len);
+
+       result = 0;
+       for (i = 0; i < len; i++) {
+               result = tda1004x_write_byteI(state, reg + i, buf[i]);
+               if (result != 0)
+                       break;
+       }
+
+       return result;
+}
+
+static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
+{
+       int result;
+       dprintk("%s\n", __func__);
+
+       result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
+       msleep(20);
+       return result;
+}
+
+static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
+{
+       dprintk("%s\n", __func__);
+
+       return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
+}
+
+static int tda10045h_set_bandwidth(struct tda1004x_state *state,
+                                  u32 bandwidth)
+{
+       static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
+       static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
+       static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
+
+       switch (bandwidth) {
+       case 6000000:
+               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+               break;
+
+       case 7000000:
+               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+               break;
+
+       case 8000000:
+               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
+
+       return 0;
+}
+
+static int tda10046h_set_bandwidth(struct tda1004x_state *state,
+                                  u32 bandwidth)
+{
+       static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
+       static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
+       static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
+
+       static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
+       static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
+       static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
+       int tda10046_clk53m;
+
+       if ((state->config->if_freq == TDA10046_FREQ_045) ||
+           (state->config->if_freq == TDA10046_FREQ_052))
+               tda10046_clk53m = 0;
+       else
+               tda10046_clk53m = 1;
+       switch (bandwidth) {
+       case 6000000:
+               if (tda10046_clk53m)
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
+                                                 sizeof(bandwidth_6mhz_53M));
+               else
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
+                                                 sizeof(bandwidth_6mhz_48M));
+               if (state->config->if_freq == TDA10046_FREQ_045) {
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
+               }
+               break;
+
+       case 7000000:
+               if (tda10046_clk53m)
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
+                                                 sizeof(bandwidth_7mhz_53M));
+               else
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
+                                                 sizeof(bandwidth_7mhz_48M));
+               if (state->config->if_freq == TDA10046_FREQ_045) {
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
+               }
+               break;
+
+       case 8000000:
+               if (tda10046_clk53m)
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
+                                                 sizeof(bandwidth_8mhz_53M));
+               else
+                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
+                                                 sizeof(bandwidth_8mhz_48M));
+               if (state->config->if_freq == TDA10046_FREQ_045) {
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
+                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
+               }
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int tda1004x_do_upload(struct tda1004x_state *state,
+                             const unsigned char *mem, unsigned int len,
+                             u8 dspCodeCounterReg, u8 dspCodeInReg)
+{
+       u8 buf[65];
+       struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
+       int tx_size;
+       int pos = 0;
+
+       /* clear code counter */
+       tda1004x_write_byteI(state, dspCodeCounterReg, 0);
+       fw_msg.addr = state->config->demod_address;
+
+       buf[0] = dspCodeInReg;
+       while (pos != len) {
+               // work out how much to send this time
+               tx_size = len - pos;
+               if (tx_size > 0x10)
+                       tx_size = 0x10;
+
+               // send the chunk
+               memcpy(buf + 1, mem + pos, tx_size);
+               fw_msg.len = tx_size + 1;
+               if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
+                       printk(KERN_ERR "tda1004x: Error during firmware upload\n");
+                       return -EIO;
+               }
+               pos += tx_size;
+
+               dprintk("%s: fw_pos=0x%x\n", __func__, pos);
+       }
+       // give the DSP a chance to settle 03/10/05 Hac
+       msleep(100);
+
+       return 0;
+}
+
+static int tda1004x_check_upload_ok(struct tda1004x_state *state)
+{
+       u8 data1, data2;
+       unsigned long timeout;
+
+       if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
+               timeout = jiffies + 2 * HZ;
+               while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
+                       if (time_after(jiffies, timeout)) {
+                               printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
+                               break;
+                       }
+                       msleep(1);
+               }
+       } else
+               msleep(100);
+
+       // check upload was OK
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
+       tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
+
+       data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
+       data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
+       if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
+               printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
+               return -EIO;
+       }
+       printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
+       return 0;
+}
+
+static int tda10045_fwupload(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int ret;
+       const struct firmware *fw;
+
+       /* don't re-upload unless necessary */
+       if (tda1004x_check_upload_ok(state) == 0)
+               return 0;
+
+       /* request the firmware, this will block until someone uploads it */
+       printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
+       ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
+       if (ret) {
+               printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
+               return ret;
+       }
+
+       /* reset chip */
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
+       msleep(10);
+
+       /* set parameters */
+       tda10045h_set_bandwidth(state, 8000000);
+
+       ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
+       release_firmware(fw);
+       if (ret)
+               return ret;
+       printk(KERN_INFO "tda1004x: firmware upload complete\n");
+
+       /* wait for DSP to initialise */
+       /* DSPREADY doesn't seem to work on the TDA10045H */
+       msleep(100);
+
+       return tda1004x_check_upload_ok(state);
+}
+
+static void tda10046_init_plls(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tda10046_clk53m;
+
+       if ((state->config->if_freq == TDA10046_FREQ_045) ||
+           (state->config->if_freq == TDA10046_FREQ_052))
+               tda10046_clk53m = 0;
+       else
+               tda10046_clk53m = 1;
+
+       tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
+       if(tda10046_clk53m) {
+               printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
+               tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
+       } else {
+               printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
+               tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
+       }
+       if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
+               dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__);
+               tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
+       } else {
+               dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__);
+               tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
+       }
+       if(tda10046_clk53m)
+               tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
+       else
+               tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
+       /* Note clock frequency is handled implicitly */
+       switch (state->config->if_freq) {
+       case TDA10046_FREQ_045:
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
+               break;
+       case TDA10046_FREQ_052:
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
+               break;
+       case TDA10046_FREQ_3617:
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
+               break;
+       case TDA10046_FREQ_3613:
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
+               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
+               break;
+       }
+       tda10046h_set_bandwidth(state, 8000000); /* default bandwidth 8 MHz */
+       /* let the PLLs settle */
+       msleep(120);
+}
+
+static int tda10046_fwupload(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int ret, confc4;
+       const struct firmware *fw;
+
+       /* reset + wake up chip */
+       if (state->config->xtal_freq == TDA10046_XTAL_4M) {
+               confc4 = 0;
+       } else {
+               dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
+               confc4 = 0x80;
+       }
+       tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+       tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
+       /* set GPIO 1 and 3 */
+       if (state->config->gpio_config != TDA10046_GPTRI) {
+               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
+       }
+       /* let the clocks recover from sleep */
+       msleep(10);
+
+       /* The PLLs need to be reprogrammed after sleep */
+       tda10046_init_plls(fe);
+       tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
+
+       /* don't re-upload unless necessary */
+       if (tda1004x_check_upload_ok(state) == 0)
+               return 0;
+
+       /*
+          For i2c normal work, we need to slow down the bus speed.
+          However, the slow down breaks the eeprom firmware load.
+          So, use normal speed for eeprom booting and then restore the
+          i2c speed after that. Tested with MSI TV @nyware A/D board,
+          that comes with firmware version 29 inside their eeprom.
+
+          It should also be noticed that no other I2C transfer should
+          be in course while booting from eeprom, otherwise, tda10046
+          goes into an instable state. So, proper locking are needed
+          at the i2c bus master.
+        */
+       printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
+       tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
+       msleep(300);
+       tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+       /* Checks if eeprom firmware went without troubles */
+       if (tda1004x_check_upload_ok(state) == 0)
+               return 0;
+
+       /* eeprom firmware didn't work. Load one manually. */
+
+       if (state->config->request_firmware != NULL) {
+               /* request the firmware, this will block until someone uploads it */
+               printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
+               ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
+               if (ret) {
+                       /* remain compatible to old bug: try to load with tda10045 image name */
+                       ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
+                       if (ret) {
+                               printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
+                               return ret;
+                       } else {
+                               printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
+                                                 TDA10046_DEFAULT_FIRMWARE);
+                       }
+               }
+       } else {
+               printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
+               return -EIO;
+       }
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+       ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
+       release_firmware(fw);
+       return tda1004x_check_upload_ok(state);
+}
+
+static int tda1004x_encode_fec(int fec)
+{
+       // convert known FEC values
+       switch (fec) {
+       case FEC_1_2:
+               return 0;
+       case FEC_2_3:
+               return 1;
+       case FEC_3_4:
+               return 2;
+       case FEC_5_6:
+               return 3;
+       case FEC_7_8:
+               return 4;
+       }
+
+       // unsupported
+       return -EINVAL;
+}
+
+static int tda1004x_decode_fec(int tdafec)
+{
+       // convert known FEC values
+       switch (tdafec) {
+       case 0:
+               return FEC_1_2;
+       case 1:
+               return FEC_2_3;
+       case 2:
+               return FEC_3_4;
+       case 3:
+               return FEC_5_6;
+       case 4:
+               return FEC_7_8;
+       }
+
+       // unsupported
+       return -1;
+}
+
+static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+
+       if (len != 2)
+               return -EINVAL;
+
+       return tda1004x_write_byteI(state, buf[0], buf[1]);
+}
+
+static int tda10045_init(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       if (tda10045_fwupload(fe)) {
+               printk("tda1004x: firmware upload failed\n");
+               return -EIO;
+       }
+
+       tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
+
+       // tda setup
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
+       tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
+       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
+       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
+       tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
+       tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
+       tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
+       tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
+       tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
+       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
+       tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
+
+       tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
+
+       return 0;
+}
+
+static int tda10046_init(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       dprintk("%s\n", __func__);
+
+       if (tda10046_fwupload(fe)) {
+               printk("tda1004x: firmware upload failed\n");
+                       return -EIO;
+       }
+
+       // tda setup
+       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
+       tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87);    // 100 ppm crystal, select HP stream
+       tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88);      // enable pulse killer
+
+       switch (state->config->agc_config) {
+       case TDA10046_AGC_DEFAULT:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
+               break;
+       case TDA10046_AGC_IFO_AUTO_NEG:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
+               break;
+       case TDA10046_AGC_IFO_AUTO_POS:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00);  // set AGC polarities
+               break;
+       case TDA10046_AGC_TDA827X:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
+               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
+               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
+               break;
+       }
+       if (state->config->ts_mode == 0) {
+               tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
+               tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
+       } else {
+               tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
+               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
+                                                       state->config->invert_oclk << 4);
+       }
+       tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
+       tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
+       tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);    // }
+       tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
+       tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);     // }
+       tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }
+       tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
+       tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
+       tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
+       tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+       // tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
+
+       return 0;
+}
+
+static int tda1004x_set_fe(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tmp;
+       int inversion;
+
+       dprintk("%s\n", __func__);
+
+       if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
+               // setup auto offset
+               tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
+
+               // disable agc_conf[2]
+               tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
+       }
+
+       // set frequency
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       // Hardcoded to use auto as much as possible on the TDA10045 as it
+       // is very unreliable if AUTO mode is _not_ used.
+       if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
+               fe_params->code_rate_HP = FEC_AUTO;
+               fe_params->guard_interval = GUARD_INTERVAL_AUTO;
+               fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
+       }
+
+       // Set standard params.. or put them to auto
+       if ((fe_params->code_rate_HP == FEC_AUTO) ||
+               (fe_params->code_rate_LP == FEC_AUTO) ||
+               (fe_params->modulation == QAM_AUTO) ||
+               (fe_params->hierarchy == HIERARCHY_AUTO)) {
+               tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1);        // enable auto
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); /* turn off modulation bits */
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
+               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
+       } else {
+               tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0);        // disable auto
+
+               // set HP FEC
+               tmp = tda1004x_encode_fec(fe_params->code_rate_HP);
+               if (tmp < 0)
+                       return tmp;
+               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
+
+               // set LP FEC
+               tmp = tda1004x_encode_fec(fe_params->code_rate_LP);
+               if (tmp < 0)
+                       return tmp;
+               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
+
+               /* set modulation */
+               switch (fe_params->modulation) {
+               case QPSK:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
+                       break;
+
+               case QAM_16:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
+                       break;
+
+               case QAM_64:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
+                       break;
+
+               default:
+                       return -EINVAL;
+               }
+
+               // set hierarchy
+               switch (fe_params->hierarchy) {
+               case HIERARCHY_NONE:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
+                       break;
+
+               case HIERARCHY_1:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
+                       break;
+
+               case HIERARCHY_2:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
+                       break;
+
+               case HIERARCHY_4:
+                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
+                       break;
+
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       // set bandwidth
+       switch (state->demod_type) {
+       case TDA1004X_DEMOD_TDA10045:
+               tda10045h_set_bandwidth(state, fe_params->bandwidth_hz);
+               break;
+
+       case TDA1004X_DEMOD_TDA10046:
+               tda10046h_set_bandwidth(state, fe_params->bandwidth_hz);
+               break;
+       }
+
+       // set inversion
+       inversion = fe_params->inversion;
+       if (state->config->invert)
+               inversion = inversion ? INVERSION_OFF : INVERSION_ON;
+       switch (inversion) {
+       case INVERSION_OFF:
+               tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
+               break;
+
+       case INVERSION_ON:
+               tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // set guard interval
+       switch (fe_params->guard_interval) {
+       case GUARD_INTERVAL_1_32:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
+               break;
+
+       case GUARD_INTERVAL_1_16:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
+               break;
+
+       case GUARD_INTERVAL_1_8:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
+               break;
+
+       case GUARD_INTERVAL_1_4:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
+               break;
+
+       case GUARD_INTERVAL_AUTO:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // set transmission mode
+       switch (fe_params->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
+               break;
+
+       case TRANSMISSION_MODE_8K:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
+               break;
+
+       case TRANSMISSION_MODE_AUTO:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
+               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       // start the lock
+       switch (state->demod_type) {
+       case TDA1004X_DEMOD_TDA10045:
+               tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
+               tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
+               break;
+
+       case TDA1004X_DEMOD_TDA10046:
+               tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
+               msleep(1);
+               tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
+               break;
+       }
+
+       msleep(10);
+
+       return 0;
+}
+
+static int tda1004x_get_fe(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
+       struct tda1004x_state* state = fe->demodulator_priv;
+
+       dprintk("%s\n", __func__);
+
+       // inversion status
+       fe_params->inversion = INVERSION_OFF;
+       if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
+               fe_params->inversion = INVERSION_ON;
+       if (state->config->invert)
+               fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
+
+       // bandwidth
+       switch (state->demod_type) {
+       case TDA1004X_DEMOD_TDA10045:
+               switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
+               case 0x14:
+                       fe_params->bandwidth_hz = 8000000;
+                       break;
+               case 0xdb:
+                       fe_params->bandwidth_hz = 7000000;
+                       break;
+               case 0x4f:
+                       fe_params->bandwidth_hz = 6000000;
+                       break;
+               }
+               break;
+       case TDA1004X_DEMOD_TDA10046:
+               switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
+               case 0x5c:
+               case 0x54:
+                       fe_params->bandwidth_hz = 8000000;
+                       break;
+               case 0x6a:
+               case 0x60:
+                       fe_params->bandwidth_hz = 7000000;
+                       break;
+               case 0x7b:
+               case 0x70:
+                       fe_params->bandwidth_hz = 6000000;
+                       break;
+               }
+               break;
+       }
+
+       // FEC
+       fe_params->code_rate_HP =
+           tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
+       fe_params->code_rate_LP =
+           tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
+
+       /* modulation */
+       switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
+       case 0:
+               fe_params->modulation = QPSK;
+               break;
+       case 1:
+               fe_params->modulation = QAM_16;
+               break;
+       case 2:
+               fe_params->modulation = QAM_64;
+               break;
+       }
+
+       // transmission mode
+       fe_params->transmission_mode = TRANSMISSION_MODE_2K;
+       if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)
+               fe_params->transmission_mode = TRANSMISSION_MODE_8K;
+
+       // guard interval
+       switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
+       case 0:
+               fe_params->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               fe_params->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               fe_params->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               fe_params->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       // hierarchy
+       switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
+       case 0:
+               fe_params->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               fe_params->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               fe_params->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               fe_params->hierarchy = HIERARCHY_4;
+               break;
+       }
+
+       return 0;
+}
+
+static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int status;
+       int cber;
+       int vber;
+
+       dprintk("%s\n", __func__);
+
+       // read status
+       status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
+       if (status == -1)
+               return -EIO;
+
+       // decode
+       *fe_status = 0;
+       if (status & 4)
+               *fe_status |= FE_HAS_SIGNAL;
+       if (status & 2)
+               *fe_status |= FE_HAS_CARRIER;
+       if (status & 8)
+               *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+
+       // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
+       // is getting anything valid
+       if (!(*fe_status & FE_HAS_VITERBI)) {
+               // read the CBER
+               cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
+               if (cber == -1)
+                       return -EIO;
+               status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
+               if (status == -1)
+                       return -EIO;
+               cber |= (status << 8);
+               // The address 0x20 should be read to cope with a TDA10046 bug
+               tda1004x_read_byte(state, TDA1004X_CBER_RESET);
+
+               if (cber != 65535)
+                       *fe_status |= FE_HAS_VITERBI;
+       }
+
+       // if we DO have some valid VITERBI output, but don't already have SYNC
+       // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
+       if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
+               // read the VBER
+               vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
+               if (vber == -1)
+                       return -EIO;
+               status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
+               if (status == -1)
+                       return -EIO;
+               vber |= (status << 8);
+               status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
+               if (status == -1)
+                       return -EIO;
+               vber |= (status & 0x0f) << 16;
+               // The CVBER_LUT should be read to cope with TDA10046 hardware bug
+               tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
+
+               // if RS has passed some valid TS packets, then we must be
+               // getting some SYNC bytes
+               if (vber < 16632)
+                       *fe_status |= FE_HAS_SYNC;
+       }
+
+       // success
+       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+       return 0;
+}
+
+static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tmp;
+       int reg = 0;
+
+       dprintk("%s\n", __func__);
+
+       // determine the register to use
+       switch (state->demod_type) {
+       case TDA1004X_DEMOD_TDA10045:
+               reg = TDA10045H_S_AGC;
+               break;
+
+       case TDA1004X_DEMOD_TDA10046:
+               reg = TDA10046H_AGC_IF_LEVEL;
+               break;
+       }
+
+       // read it
+       tmp = tda1004x_read_byte(state, reg);
+       if (tmp < 0)
+               return -EIO;
+
+       *signal = (tmp << 8) | tmp;
+       dprintk("%s: signal=0x%x\n", __func__, *signal);
+       return 0;
+}
+
+static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tmp;
+
+       dprintk("%s\n", __func__);
+
+       // read it
+       tmp = tda1004x_read_byte(state, TDA1004X_SNR);
+       if (tmp < 0)
+               return -EIO;
+       tmp = 255 - tmp;
+
+       *snr = ((tmp << 8) | tmp);
+       dprintk("%s: snr=0x%x\n", __func__, *snr);
+       return 0;
+}
+
+static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tmp;
+       int tmp2;
+       int counter;
+
+       dprintk("%s\n", __func__);
+
+       // read the UCBLOCKS and reset
+       counter = 0;
+       tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
+       if (tmp < 0)
+               return -EIO;
+       tmp &= 0x7f;
+       while (counter++ < 5) {
+               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
+               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
+               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
+
+               tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
+               if (tmp2 < 0)
+                       return -EIO;
+               tmp2 &= 0x7f;
+               if ((tmp2 < tmp) || (tmp2 == 0))
+                       break;
+       }
+
+       if (tmp != 0x7f)
+               *ucblocks = tmp;
+       else
+               *ucblocks = 0xffffffff;
+
+       dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
+       return 0;
+}
+
+static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int tmp;
+
+       dprintk("%s\n", __func__);
+
+       // read it in
+       tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
+       if (tmp < 0)
+               return -EIO;
+       *ber = tmp << 1;
+       tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
+       if (tmp < 0)
+               return -EIO;
+       *ber |= (tmp << 9);
+       // The address 0x20 should be read to cope with a TDA10046 bug
+       tda1004x_read_byte(state, TDA1004X_CBER_RESET);
+
+       dprintk("%s: ber=0x%x\n", __func__, *ber);
+       return 0;
+}
+
+static int tda1004x_sleep(struct dvb_frontend* fe)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+       int gpio_conf;
+
+       switch (state->demod_type) {
+       case TDA1004X_DEMOD_TDA10045:
+               tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
+               break;
+
+       case TDA1004X_DEMOD_TDA10046:
+               /* set outputs to tristate */
+               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
+               /* invert GPIO 1 and 3 if desired*/
+               gpio_conf = state->config->gpio_config;
+               if (gpio_conf >= TDA10046_GP00_I)
+                       tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
+                                                       (gpio_conf & 0x0f) ^ 0x0a);
+
+               tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
+               tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
+               break;
+       }
+
+       return 0;
+}
+
+static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct tda1004x_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return tda1004x_enable_tuner_i2c(state);
+       } else {
+               return tda1004x_disable_tuner_i2c(state);
+       }
+}
+
+static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       fesettings->min_delay_ms = 800;
+       /* Drift compensation makes no sense for DVB-T */
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void tda1004x_release(struct dvb_frontend* fe)
+{
+       struct tda1004x_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops tda10045_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Philips TDA10045H DVB-T",
+               .frequency_min = 51000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 166667,
+               .caps =
+                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                   FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                   FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                   FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
+       },
+
+       .release = tda1004x_release,
+
+       .init = tda10045_init,
+       .sleep = tda1004x_sleep,
+       .write = tda1004x_write,
+       .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
+
+       .set_frontend = tda1004x_set_fe,
+       .get_frontend = tda1004x_get_fe,
+       .get_tune_settings = tda1004x_get_tune_settings,
+
+       .read_status = tda1004x_read_status,
+       .read_ber = tda1004x_read_ber,
+       .read_signal_strength = tda1004x_read_signal_strength,
+       .read_snr = tda1004x_read_snr,
+       .read_ucblocks = tda1004x_read_ucblocks,
+};
+
+struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct tda1004x_state *state;
+       int id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       if (!state) {
+               printk(KERN_ERR "Can't allocate memory for tda10045 state\n");
+               return NULL;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->demod_type = TDA1004X_DEMOD_TDA10045;
+
+       /* check if the demod is there */
+       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+       if (id < 0) {
+               printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
+               kfree(state);
+               return NULL;
+       }
+
+       if (id != 0x25) {
+               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
+               kfree(state);
+               return NULL;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+static struct dvb_frontend_ops tda10046_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name = "Philips TDA10046H DVB-T",
+               .frequency_min = 51000000,
+               .frequency_max = 858000000,
+               .frequency_stepsize = 166667,
+               .caps =
+                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                   FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                   FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                   FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
+       },
+
+       .release = tda1004x_release,
+
+       .init = tda10046_init,
+       .sleep = tda1004x_sleep,
+       .write = tda1004x_write,
+       .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
+
+       .set_frontend = tda1004x_set_fe,
+       .get_frontend = tda1004x_get_fe,
+       .get_tune_settings = tda1004x_get_tune_settings,
+
+       .read_status = tda1004x_read_status,
+       .read_ber = tda1004x_read_ber,
+       .read_signal_strength = tda1004x_read_signal_strength,
+       .read_snr = tda1004x_read_snr,
+       .read_ucblocks = tda1004x_read_ucblocks,
+};
+
+struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct tda1004x_state *state;
+       int id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       if (!state) {
+               printk(KERN_ERR "Can't allocate memory for tda10046 state\n");
+               return NULL;
+       }
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->demod_type = TDA1004X_DEMOD_TDA10046;
+
+       /* check if the demod is there */
+       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+       if (id < 0) {
+               printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
+               kfree(state);
+               return NULL;
+       }
+       if (id != 0x46) {
+               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
+               kfree(state);
+               return NULL;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
+MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10045_attach);
+EXPORT_SYMBOL(tda10046_attach);
diff --git a/drivers/media/dvb-frontends/tda1004x.h b/drivers/media/dvb-frontends/tda1004x.h
new file mode 100644 (file)
index 0000000..4e27ffb
--- /dev/null
@@ -0,0 +1,149 @@
+  /*
+     Driver for Philips tda1004xh OFDM Frontend
+
+     (c) 2004 Andrew de Quincey
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   */
+
+#ifndef TDA1004X_H
+#define TDA1004X_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+enum tda10046_xtal {
+       TDA10046_XTAL_4M,
+       TDA10046_XTAL_16M,
+};
+
+enum tda10046_agc {
+       TDA10046_AGC_DEFAULT,           /* original configuration */
+       TDA10046_AGC_IFO_AUTO_NEG,      /* IF AGC only, automatic, negtive */
+       TDA10046_AGC_IFO_AUTO_POS,      /* IF AGC only, automatic, positive */
+       TDA10046_AGC_TDA827X,           /* IF AGC only, special setup for tda827x */
+};
+
+/* Many (hybrid) boards use GPIO 1 and 3
+       GPIO1   analog - dvb switch
+       GPIO3   firmware eeprom address switch
+*/
+enum tda10046_gpio {
+       TDA10046_GPTRI  = 0x00,         /* All GPIOs tristate */
+       TDA10046_GP00   = 0x40,         /* GPIO3=0, GPIO1=0 */
+       TDA10046_GP01   = 0x42,         /* GPIO3=0, GPIO1=1 */
+       TDA10046_GP10   = 0x48,         /* GPIO3=1, GPIO1=0 */
+       TDA10046_GP11   = 0x4a,         /* GPIO3=1, GPIO1=1 */
+       TDA10046_GP00_I = 0x80,         /* GPIO3=0, GPIO1=0, invert in sleep mode*/
+       TDA10046_GP01_I = 0x82,         /* GPIO3=0, GPIO1=1, invert in sleep mode */
+       TDA10046_GP10_I = 0x88,         /* GPIO3=1, GPIO1=0, invert in sleep mode */
+       TDA10046_GP11_I = 0x8a,         /* GPIO3=1, GPIO1=1, invert in sleep mode */
+};
+
+enum tda10046_if {
+       TDA10046_FREQ_3617,             /* original config, 36,166 MHZ */
+       TDA10046_FREQ_3613,             /* 36,13 MHZ */
+       TDA10046_FREQ_045,              /* low IF, 4.0, 4.5, or 5.0 MHZ */
+       TDA10046_FREQ_052,              /* low IF, 5.1667 MHZ for tda9889 */
+};
+
+enum tda10046_tsout {
+       TDA10046_TS_PARALLEL  = 0x00,   /* parallel transport stream, default */
+       TDA10046_TS_SERIAL    = 0x01,   /* serial transport stream */
+};
+
+struct tda1004x_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* does the "inversion" need inverted? */
+       u8 invert;
+
+       /* Does the OCLK signal need inverted? */
+       u8 invert_oclk;
+
+       /* parallel or serial transport stream */
+       enum tda10046_tsout ts_mode;
+
+       /* Xtal frequency, 4 or 16MHz*/
+       enum tda10046_xtal xtal_freq;
+
+       /* IF frequency */
+       enum tda10046_if if_freq;
+
+       /* AGC configuration */
+       enum tda10046_agc agc_config;
+
+       /* setting of GPIO1 and 3 */
+       enum tda10046_gpio gpio_config;
+
+       /* slave address and configuration of the tuner */
+       u8 tuner_address;
+       u8 antenna_switch;
+
+       /* if the board uses another I2c Bridge (tda8290), its address */
+       u8 i2c_gate;
+
+       /* request firmware for device */
+       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+enum tda1004x_demod {
+       TDA1004X_DEMOD_TDA10045,
+       TDA1004X_DEMOD_TDA10046,
+};
+
+struct tda1004x_state {
+       struct i2c_adapter* i2c;
+       const struct tda1004x_config* config;
+       struct dvb_frontend frontend;
+
+       /* private demod data */
+       enum tda1004x_demod demod_type;
+};
+
+#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
+                                           struct i2c_adapter* i2c);
+
+extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
+                                           struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
+                                           struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
+                                           struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA1004X
+
+static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
+       int r = 0;
+       u8 buf[] = {reg, val};
+       if (fe->ops.write)
+               r = fe->ops.write(fe, buf, 2);
+       return r;
+}
+
+#endif // TDA1004X_H
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
new file mode 100644 (file)
index 0000000..703c3d0
--- /dev/null
@@ -0,0 +1,1284 @@
+/*
+ * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#include "tda10071_priv.h"
+
+static struct dvb_frontend_ops tda10071_ops;
+
+/* write multiple registers */
+static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
+       int len)
+{
+       int ret;
+       u8 buf[len+1];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg.i2c_address,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple registers */
+static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
+       int len)
+{
+       int ret;
+       u8 buf[len];
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg.i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = priv->cfg.i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               memcpy(val, buf, len);
+               ret = 0;
+       } else {
+               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* write single register */
+static int tda10071_wr_reg(struct tda10071_priv *priv, u8 reg, u8 val)
+{
+       return tda10071_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int tda10071_rd_reg(struct tda10071_priv *priv, u8 reg, u8 *val)
+{
+       return tda10071_rd_regs(priv, reg, val, 1);
+}
+
+/* write single register with mask */
+int tda10071_wr_reg_mask(struct tda10071_priv *priv, u8 reg, u8 val, u8 mask)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = tda10071_rd_regs(priv, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return tda10071_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register with mask */
+int tda10071_rd_reg_mask(struct tda10071_priv *priv, u8 reg, u8 *val, u8 mask)
+{
+       int ret, i;
+       u8 tmp;
+
+       ret = tda10071_rd_regs(priv, reg, &tmp, 1);
+       if (ret)
+               return ret;
+
+       tmp &= mask;
+
+       /* find position of the first bit */
+       for (i = 0; i < 8; i++) {
+               if ((mask >> i) & 0x01)
+                       break;
+       }
+       *val = tmp >> i;
+
+       return 0;
+}
+
+/* execute firmware command */
+static int tda10071_cmd_execute(struct tda10071_priv *priv,
+       struct tda10071_cmd *cmd)
+{
+       int ret, i;
+       u8 tmp;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       /* write cmd and args for firmware */
+       ret = tda10071_wr_regs(priv, 0x00, cmd->args, cmd->len);
+       if (ret)
+               goto error;
+
+       /* start cmd execution */
+       ret = tda10071_wr_reg(priv, 0x1f, 1);
+       if (ret)
+               goto error;
+
+       /* wait cmd execution terminate */
+       for (i = 1000, tmp = 1; i && tmp; i--) {
+               ret = tda10071_rd_reg(priv, 0x1f, &tmp);
+               if (ret)
+                       goto error;
+
+               usleep_range(200, 5000);
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
+
+       if (i == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
+       }
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_set_tone(struct dvb_frontend *fe,
+       fe_sec_tone_mode_t fe_sec_tone_mode)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret;
+       u8 tone;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: tone_mode=%d\n", __func__,
+                       fe_sec_tone_mode);
+
+       switch (fe_sec_tone_mode) {
+       case SEC_TONE_ON:
+               tone = 1;
+               break;
+       case SEC_TONE_OFF:
+               tone = 0;
+               break;
+       default:
+               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n",
+                               __func__);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       cmd.args[0] = CMD_LNB_PCB_CONFIG;
+       cmd.args[1] = 0;
+       cmd.args[2] = 0x00;
+       cmd.args[3] = 0x00;
+       cmd.args[4] = tone;
+       cmd.len = 5;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_set_voltage(struct dvb_frontend *fe,
+       fe_sec_voltage_t fe_sec_voltage)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret;
+       u8 voltage;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: voltage=%d\n", __func__, fe_sec_voltage);
+
+       switch (fe_sec_voltage) {
+       case SEC_VOLTAGE_13:
+               voltage = 0;
+               break;
+       case SEC_VOLTAGE_18:
+               voltage = 1;
+               break;
+       case SEC_VOLTAGE_OFF:
+               voltage = 0;
+               break;
+       default:
+               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
+                               __func__);
+               ret = -EINVAL;
+               goto error;
+       };
+
+       cmd.args[0] = CMD_LNB_SET_DC_LEVEL;
+       cmd.args[1] = 0;
+       cmd.args[2] = voltage;
+       cmd.len = 3;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
+       struct dvb_diseqc_master_cmd *diseqc_cmd)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i;
+       u8 tmp;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: msg_len=%d\n", __func__,
+                       diseqc_cmd->msg_len);
+
+       if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* wait LNB TX */
+       for (i = 500, tmp = 0; i && !tmp; i--) {
+               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01);
+               if (ret)
+                       goto error;
+
+               usleep_range(10000, 20000);
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
+
+       if (i == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
+       }
+
+       ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01);
+       if (ret)
+               goto error;
+
+       cmd.args[0] = CMD_LNB_SEND_DISEQC;
+       cmd.args[1] = 0;
+       cmd.args[2] = 0;
+       cmd.args[3] = 0;
+       cmd.args[4] = 2;
+       cmd.args[5] = 0;
+       cmd.args[6] = diseqc_cmd->msg_len;
+       memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len);
+       cmd.len = 7 + diseqc_cmd->msg_len;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
+       struct dvb_diseqc_slave_reply *reply)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i;
+       u8 tmp;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+       /* wait LNB RX */
+       for (i = 500, tmp = 0; i && !tmp; i--) {
+               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x02);
+               if (ret)
+                       goto error;
+
+               usleep_range(10000, 20000);
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
+
+       if (i == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
+       }
+
+       /* reply len */
+       ret = tda10071_rd_reg(priv, 0x46, &tmp);
+       if (ret)
+               goto error;
+
+       reply->msg_len = tmp & 0x1f; /* [4:0] */;
+       if (reply->msg_len > sizeof(reply->msg))
+               reply->msg_len = sizeof(reply->msg); /* truncate API max */
+
+       /* read reply */
+       cmd.args[0] = CMD_LNB_UPDATE_REPLY;
+       cmd.args[1] = 0;
+       cmd.len = 2;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       ret = tda10071_rd_regs(priv, cmd.len, reply->msg, reply->msg_len);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
+       fe_sec_mini_cmd_t fe_sec_mini_cmd)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i;
+       u8 tmp, burst;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
+                       fe_sec_mini_cmd);
+
+       switch (fe_sec_mini_cmd) {
+       case SEC_MINI_A:
+               burst = 0;
+               break;
+       case SEC_MINI_B:
+               burst = 1;
+               break;
+       default:
+               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n",
+                               __func__);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* wait LNB TX */
+       for (i = 500, tmp = 0; i && !tmp; i--) {
+               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01);
+               if (ret)
+                       goto error;
+
+               usleep_range(10000, 20000);
+       }
+
+       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
+
+       if (i == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
+       }
+
+       ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01);
+       if (ret)
+               goto error;
+
+       cmd.args[0] = CMD_LNB_SEND_TONEBURST;
+       cmd.args[1] = 0;
+       cmd.args[2] = burst;
+       cmd.len = 3;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 tmp;
+
+       *status = 0;
+
+       if (!priv->warm) {
+               ret = 0;
+               goto error;
+       }
+
+       ret = tda10071_rd_reg(priv, 0x39, &tmp);
+       if (ret)
+               goto error;
+
+       if (tmp & 0x01) /* tuner PLL */
+               *status |= FE_HAS_SIGNAL;
+       if (tmp & 0x02) /* demod PLL */
+               *status |= FE_HAS_CARRIER;
+       if (tmp & 0x04) /* viterbi or LDPC*/
+               *status |= FE_HAS_VITERBI;
+       if (tmp & 0x08) /* RS or BCH */
+               *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+
+       priv->fe_status = *status;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       int ret;
+       u8 buf[2];
+
+       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
+               *snr = 0;
+               ret = 0;
+               goto error;
+       }
+
+       ret = tda10071_rd_regs(priv, 0x3a, buf, 2);
+       if (ret)
+               goto error;
+
+       /* Es/No dBx10 */
+       *snr = buf[0] << 8 | buf[1];
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret;
+       u8 tmp;
+
+       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
+               *strength = 0;
+               ret = 0;
+               goto error;
+       }
+
+       cmd.args[0] = CMD_GET_AGCACC;
+       cmd.args[1] = 0;
+       cmd.len = 2;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       /* input power estimate dBm */
+       ret = tda10071_rd_reg(priv, 0x50, &tmp);
+       if (ret)
+               goto error;
+
+       if (tmp < 181)
+               tmp = 181; /* -75 dBm */
+       else if (tmp > 236)
+               tmp = 236; /* -20 dBm */
+
+       /* scale value to 0x0000-0xffff */
+       *strength = (tmp-181) * 0xffff / (236-181);
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i, len;
+       u8 tmp, reg, buf[8];
+
+       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
+               *ber = priv->ber = 0;
+               ret = 0;
+               goto error;
+       }
+
+       switch (priv->delivery_system) {
+       case SYS_DVBS:
+               reg = 0x4c;
+               len = 8;
+               i = 1;
+               break;
+       case SYS_DVBS2:
+               reg = 0x4d;
+               len = 4;
+               i = 0;
+               break;
+       default:
+               *ber = priv->ber = 0;
+               return 0;
+       }
+
+       ret = tda10071_rd_reg(priv, reg, &tmp);
+       if (ret)
+               goto error;
+
+       if (priv->meas_count[i] == tmp) {
+               dev_dbg(&priv->i2c->dev, "%s: meas not ready=%02x\n", __func__,
+                               tmp);
+               *ber = priv->ber;
+               return 0;
+       } else {
+               priv->meas_count[i] = tmp;
+       }
+
+       cmd.args[0] = CMD_BER_UPDATE_COUNTERS;
+       cmd.args[1] = 0;
+       cmd.args[2] = i;
+       cmd.len = 3;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       ret = tda10071_rd_regs(priv, cmd.len, buf, len);
+       if (ret)
+               goto error;
+
+       if (priv->delivery_system == SYS_DVBS) {
+               *ber = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+               priv->ucb += (buf[4] << 8) | buf[5];
+       } else {
+               *ber = (buf[0] << 8) | buf[1];
+       }
+       priv->ber = *ber;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       int ret = 0;
+
+       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
+               *ucblocks = 0;
+               goto error;
+       }
+
+       /* UCB is updated when BER is read. Assume BER is read anyway. */
+
+       *ucblocks = priv->ucb;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_set_frontend(struct dvb_frontend *fe)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       u8 mode, rolloff, pilot, inversion, div;
+
+       dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
+               "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
+               "rolloff=%d\n", __func__, c->delivery_system, c->modulation,
+               c->frequency, c->symbol_rate, c->inversion, c->pilot,
+               c->rolloff);
+
+       priv->delivery_system = SYS_UNDEFINED;
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       switch (c->inversion) {
+       case INVERSION_OFF:
+               inversion = 1;
+               break;
+       case INVERSION_ON:
+               inversion = 0;
+               break;
+       case INVERSION_AUTO:
+               /* 2 = auto; try first on then off
+                * 3 = auto; try first off then on */
+               inversion = 3;
+               break;
+       default:
+               dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n", __func__);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       switch (c->delivery_system) {
+       case SYS_DVBS:
+               rolloff = 0;
+               pilot = 2;
+               break;
+       case SYS_DVBS2:
+               switch (c->rolloff) {
+               case ROLLOFF_20:
+                       rolloff = 2;
+                       break;
+               case ROLLOFF_25:
+                       rolloff = 1;
+                       break;
+               case ROLLOFF_35:
+                       rolloff = 0;
+                       break;
+               case ROLLOFF_AUTO:
+               default:
+                       dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n",
+                                       __func__);
+                       ret = -EINVAL;
+                       goto error;
+               }
+
+               switch (c->pilot) {
+               case PILOT_OFF:
+                       pilot = 0;
+                       break;
+               case PILOT_ON:
+                       pilot = 1;
+                       break;
+               case PILOT_AUTO:
+                       pilot = 2;
+                       break;
+               default:
+                       dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
+                                       __func__);
+                       ret = -EINVAL;
+                       goto error;
+               }
+               break;
+       default:
+               dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
+                               __func__);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
+               if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
+                       c->modulation == TDA10071_MODCOD[i].modulation &&
+                       c->fec_inner == TDA10071_MODCOD[i].fec) {
+                       mode = TDA10071_MODCOD[i].val;
+                       dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
+                                       __func__, mode);
+                       break;
+               }
+       }
+
+       if (mode == 0xff) {
+               dev_dbg(&priv->i2c->dev, "%s: invalid parameter combination\n",
+                               __func__);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (c->symbol_rate <= 5000000)
+               div = 14;
+       else
+               div = 4;
+
+       ret = tda10071_wr_reg(priv, 0x81, div);
+       if (ret)
+               goto error;
+
+       ret = tda10071_wr_reg(priv, 0xe3, div);
+       if (ret)
+               goto error;
+
+       cmd.args[0] = CMD_CHANGE_CHANNEL;
+       cmd.args[1] = 0;
+       cmd.args[2] = mode;
+       cmd.args[3] = (c->frequency >> 16) & 0xff;
+       cmd.args[4] = (c->frequency >>  8) & 0xff;
+       cmd.args[5] = (c->frequency >>  0) & 0xff;
+       cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff;
+       cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff;
+       cmd.args[8] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff;
+       cmd.args[9] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff;
+       cmd.args[10] = rolloff;
+       cmd.args[11] = inversion;
+       cmd.args[12] = pilot;
+       cmd.args[13] = 0x00;
+       cmd.args[14] = 0x00;
+       cmd.len = 15;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       priv->delivery_system = c->delivery_system;
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_get_frontend(struct dvb_frontend *fe)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       u8 buf[5], tmp;
+
+       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       ret = tda10071_rd_regs(priv, 0x30, buf, 5);
+       if (ret)
+               goto error;
+
+       tmp = buf[0] & 0x3f;
+       for (i = 0; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
+               if (tmp == TDA10071_MODCOD[i].val) {
+                       c->modulation = TDA10071_MODCOD[i].modulation;
+                       c->fec_inner = TDA10071_MODCOD[i].fec;
+                       c->delivery_system = TDA10071_MODCOD[i].delivery_system;
+               }
+       }
+
+       switch ((buf[1] >> 0) & 0x01) {
+       case 0:
+               c->inversion = INVERSION_OFF;
+               break;
+       case 1:
+               c->inversion = INVERSION_ON;
+               break;
+       }
+
+       switch ((buf[1] >> 7) & 0x01) {
+       case 0:
+               c->pilot = PILOT_OFF;
+               break;
+       case 1:
+               c->pilot = PILOT_ON;
+               break;
+       }
+
+       c->frequency = (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0);
+
+       ret = tda10071_rd_regs(priv, 0x52, buf, 3);
+       if (ret)
+               goto error;
+
+       c->symbol_rate = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0);
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_init(struct dvb_frontend *fe)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i, len, remaining, fw_size;
+       const struct firmware *fw;
+       u8 *fw_file = TDA10071_DEFAULT_FIRMWARE;
+       u8 tmp, buf[4];
+       struct tda10071_reg_val_mask tab[] = {
+               { 0xcd, 0x00, 0x07 },
+               { 0x80, 0x00, 0x02 },
+               { 0xcd, 0x00, 0xc0 },
+               { 0xce, 0x00, 0x1b },
+               { 0x9d, 0x00, 0x01 },
+               { 0x9d, 0x00, 0x02 },
+               { 0x9e, 0x00, 0x01 },
+               { 0x87, 0x00, 0x80 },
+               { 0xce, 0x00, 0x08 },
+               { 0xce, 0x00, 0x10 },
+       };
+       struct tda10071_reg_val_mask tab2[] = {
+               { 0xf1, 0x70, 0xff },
+               { 0x88, priv->cfg.pll_multiplier, 0x3f },
+               { 0x89, 0x00, 0x10 },
+               { 0x89, 0x10, 0x10 },
+               { 0xc0, 0x01, 0x01 },
+               { 0xc0, 0x00, 0x01 },
+               { 0xe0, 0xff, 0xff },
+               { 0xe0, 0x00, 0xff },
+               { 0x96, 0x1e, 0x7e },
+               { 0x8b, 0x08, 0x08 },
+               { 0x8b, 0x00, 0x08 },
+               { 0x8f, 0x1a, 0x7e },
+               { 0x8c, 0x68, 0xff },
+               { 0x8d, 0x08, 0xff },
+               { 0x8e, 0x4c, 0xff },
+               { 0x8f, 0x01, 0x01 },
+               { 0x8b, 0x04, 0x04 },
+               { 0x8b, 0x00, 0x04 },
+               { 0x87, 0x05, 0x07 },
+               { 0x80, 0x00, 0x20 },
+               { 0xc8, 0x01, 0xff },
+               { 0xb4, 0x47, 0xff },
+               { 0xb5, 0x9c, 0xff },
+               { 0xb6, 0x7d, 0xff },
+               { 0xba, 0x00, 0x03 },
+               { 0xb7, 0x47, 0xff },
+               { 0xb8, 0x9c, 0xff },
+               { 0xb9, 0x7d, 0xff },
+               { 0xba, 0x00, 0x0c },
+               { 0xc8, 0x00, 0xff },
+               { 0xcd, 0x00, 0x04 },
+               { 0xcd, 0x00, 0x20 },
+               { 0xe8, 0x02, 0xff },
+               { 0xcf, 0x20, 0xff },
+               { 0x9b, 0xd7, 0xff },
+               { 0x9a, 0x01, 0x03 },
+               { 0xa8, 0x05, 0x0f },
+               { 0xa8, 0x65, 0xf0 },
+               { 0xa6, 0xa0, 0xf0 },
+               { 0x9d, 0x50, 0xfc },
+               { 0x9e, 0x20, 0xe0 },
+               { 0xa3, 0x1c, 0x7c },
+               { 0xd5, 0x03, 0x03 },
+       };
+
+       /* firmware status */
+       ret = tda10071_rd_reg(priv, 0x51, &tmp);
+       if (ret)
+               goto error;
+
+       if (!tmp) {
+               /* warm state - wake up device from sleep */
+               priv->warm = 1;
+
+               for (i = 0; i < ARRAY_SIZE(tab); i++) {
+                       ret = tda10071_wr_reg_mask(priv, tab[i].reg,
+                               tab[i].val, tab[i].mask);
+                       if (ret)
+                               goto error;
+               }
+
+               cmd.args[0] = CMD_SET_SLEEP_MODE;
+               cmd.args[1] = 0;
+               cmd.args[2] = 0;
+               cmd.len = 3;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+       } else {
+               /* cold state - try to download firmware */
+               priv->warm = 0;
+
+               /* request the firmware, this will block and timeout */
+               ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
+               if (ret) {
+                       dev_err(&priv->i2c->dev, "%s: did not find the " \
+                                       "firmware file. (%s) Please see " \
+                                       "linux/Documentation/dvb/ for more " \
+                                       "details on firmware-problems. (%d)\n",
+                                       KBUILD_MODNAME, fw_file, ret);
+                       goto error;
+               }
+
+               /* init */
+               for (i = 0; i < ARRAY_SIZE(tab2); i++) {
+                       ret = tda10071_wr_reg_mask(priv, tab2[i].reg,
+                               tab2[i].val, tab2[i].mask);
+                       if (ret)
+                               goto error_release_firmware;
+               }
+
+               /*  download firmware */
+               ret = tda10071_wr_reg(priv, 0xe0, 0x7f);
+               if (ret)
+                       goto error_release_firmware;
+
+               ret = tda10071_wr_reg(priv, 0xf7, 0x81);
+               if (ret)
+                       goto error_release_firmware;
+
+               ret = tda10071_wr_reg(priv, 0xf8, 0x00);
+               if (ret)
+                       goto error_release_firmware;
+
+               ret = tda10071_wr_reg(priv, 0xf9, 0x00);
+               if (ret)
+                       goto error_release_firmware;
+
+               dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \
+                               "will try to load a firmware\n", KBUILD_MODNAME,
+                               tda10071_ops.info.name);
+               dev_info(&priv->i2c->dev, "%s: downloading firmware from " \
+                               "file '%s'\n", KBUILD_MODNAME, fw_file);
+
+               /* do not download last byte */
+               fw_size = fw->size - 1;
+
+               for (remaining = fw_size; remaining > 0;
+                       remaining -= (priv->cfg.i2c_wr_max - 1)) {
+                       len = remaining;
+                       if (len > (priv->cfg.i2c_wr_max - 1))
+                               len = (priv->cfg.i2c_wr_max - 1);
+
+                       ret = tda10071_wr_regs(priv, 0xfa,
+                               (u8 *) &fw->data[fw_size - remaining], len);
+                       if (ret) {
+                               dev_err(&priv->i2c->dev, "%s: firmware " \
+                                               "download failed=%d\n",
+                                               KBUILD_MODNAME, ret);
+                               if (ret)
+                                       goto error_release_firmware;
+                       }
+               }
+               release_firmware(fw);
+
+               ret = tda10071_wr_reg(priv, 0xf7, 0x0c);
+               if (ret)
+                       goto error;
+
+               ret = tda10071_wr_reg(priv, 0xe0, 0x00);
+               if (ret)
+                       goto error;
+
+               /* wait firmware start */
+               msleep(250);
+
+               /* firmware status */
+               ret = tda10071_rd_reg(priv, 0x51, &tmp);
+               if (ret)
+                       goto error;
+
+               if (tmp) {
+                       dev_info(&priv->i2c->dev, "%s: firmware did not run\n",
+                                       KBUILD_MODNAME);
+                       ret = -EFAULT;
+                       goto error;
+               } else {
+                       priv->warm = 1;
+               }
+
+               cmd.args[0] = CMD_GET_FW_VERSION;
+               cmd.len = 1;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+
+               ret = tda10071_rd_regs(priv, cmd.len, buf, 4);
+               if (ret)
+                       goto error;
+
+               dev_info(&priv->i2c->dev, "%s: firmware version %d.%d.%d.%d\n",
+                               KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]);
+               dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n",
+                               KBUILD_MODNAME, tda10071_ops.info.name);
+
+               ret = tda10071_rd_regs(priv, 0x81, buf, 2);
+               if (ret)
+                       goto error;
+
+               cmd.args[0] = CMD_DEMOD_INIT;
+               cmd.args[1] = ((priv->cfg.xtal / 1000) >> 8) & 0xff;
+               cmd.args[2] = ((priv->cfg.xtal / 1000) >> 0) & 0xff;
+               cmd.args[3] = buf[0];
+               cmd.args[4] = buf[1];
+               cmd.args[5] = priv->cfg.pll_multiplier;
+               cmd.args[6] = priv->cfg.spec_inv;
+               cmd.args[7] = 0x00;
+               cmd.len = 8;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+
+               cmd.args[0] = CMD_TUNER_INIT;
+               cmd.args[1] = 0x00;
+               cmd.args[2] = 0x00;
+               cmd.args[3] = 0x00;
+               cmd.args[4] = 0x00;
+               cmd.args[5] = 0x14;
+               cmd.args[6] = 0x00;
+               cmd.args[7] = 0x03;
+               cmd.args[8] = 0x02;
+               cmd.args[9] = 0x02;
+               cmd.args[10] = 0x00;
+               cmd.args[11] = 0x00;
+               cmd.args[12] = 0x00;
+               cmd.args[13] = 0x00;
+               cmd.args[14] = 0x00;
+               cmd.len = 15;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+
+               cmd.args[0] = CMD_MPEG_CONFIG;
+               cmd.args[1] = 0;
+               cmd.args[2] = priv->cfg.ts_mode;
+               cmd.args[3] = 0x00;
+               cmd.args[4] = 0x04;
+               cmd.args[5] = 0x00;
+               cmd.len = 6;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+
+               ret = tda10071_wr_reg_mask(priv, 0xf0, 0x01, 0x01);
+               if (ret)
+                       goto error;
+
+               cmd.args[0] = CMD_LNB_CONFIG;
+               cmd.args[1] = 0;
+               cmd.args[2] = 150;
+               cmd.args[3] = 3;
+               cmd.args[4] = 22;
+               cmd.args[5] = 1;
+               cmd.args[6] = 1;
+               cmd.args[7] = 30;
+               cmd.args[8] = 30;
+               cmd.args[9] = 30;
+               cmd.args[10] = 30;
+               cmd.len = 11;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+
+               cmd.args[0] = CMD_BER_CONTROL;
+               cmd.args[1] = 0;
+               cmd.args[2] = 14;
+               cmd.args[3] = 14;
+               cmd.len = 4;
+               ret = tda10071_cmd_execute(priv, &cmd);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error_release_firmware:
+       release_firmware(fw);
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_sleep(struct dvb_frontend *fe)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       struct tda10071_cmd cmd;
+       int ret, i;
+       struct tda10071_reg_val_mask tab[] = {
+               { 0xcd, 0x07, 0x07 },
+               { 0x80, 0x02, 0x02 },
+               { 0xcd, 0xc0, 0xc0 },
+               { 0xce, 0x1b, 0x1b },
+               { 0x9d, 0x01, 0x01 },
+               { 0x9d, 0x02, 0x02 },
+               { 0x9e, 0x01, 0x01 },
+               { 0x87, 0x80, 0x80 },
+               { 0xce, 0x08, 0x08 },
+               { 0xce, 0x10, 0x10 },
+       };
+
+       if (!priv->warm) {
+               ret = -EFAULT;
+               goto error;
+       }
+
+       cmd.args[0] = CMD_SET_SLEEP_MODE;
+       cmd.args[1] = 0;
+       cmd.args[2] = 1;
+       cmd.len = 3;
+       ret = tda10071_cmd_execute(priv, &cmd);
+       if (ret)
+               goto error;
+
+       for (i = 0; i < ARRAY_SIZE(tab); i++) {
+               ret = tda10071_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+                       tab[i].mask);
+               if (ret)
+                       goto error;
+       }
+
+       return ret;
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       return ret;
+}
+
+static int tda10071_get_tune_settings(struct dvb_frontend *fe,
+       struct dvb_frontend_tune_settings *s)
+{
+       s->min_delay_ms = 8000;
+       s->step_size = 0;
+       s->max_drift = 0;
+
+       return 0;
+}
+
+static void tda10071_release(struct dvb_frontend *fe)
+{
+       struct tda10071_priv *priv = fe->demodulator_priv;
+       kfree(priv);
+}
+
+struct dvb_frontend *tda10071_attach(const struct tda10071_config *config,
+       struct i2c_adapter *i2c)
+{
+       int ret;
+       struct tda10071_priv *priv = NULL;
+       u8 tmp;
+
+       /* allocate memory for the internal priv */
+       priv = kzalloc(sizeof(struct tda10071_priv), GFP_KERNEL);
+       if (priv == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       /* setup the priv */
+       priv->i2c = i2c;
+       memcpy(&priv->cfg, config, sizeof(struct tda10071_config));
+
+       /* chip ID */
+       ret = tda10071_rd_reg(priv, 0xff, &tmp);
+       if (ret || tmp != 0x0f)
+               goto error;
+
+       /* chip type */
+       ret = tda10071_rd_reg(priv, 0xdd, &tmp);
+       if (ret || tmp != 0x00)
+               goto error;
+
+       /* chip version */
+       ret = tda10071_rd_reg(priv, 0xfe, &tmp);
+       if (ret || tmp != 0x01)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&priv->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops));
+       priv->fe.demodulator_priv = priv;
+
+       return &priv->fe;
+error:
+       dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(tda10071_attach);
+
+static struct dvb_frontend_ops tda10071_ops = {
+       .delsys = { SYS_DVBS, SYS_DVBS2 },
+       .info = {
+               .name = "NXP TDA10071",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_tolerance = 5000,
+               .symbol_rate_min = 1000000,
+               .symbol_rate_max = 45000000,
+               .caps = FE_CAN_INVERSION_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_6_7 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_8_9 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_RECOVER |
+                       FE_CAN_2G_MODULATION
+       },
+
+       .release = tda10071_release,
+
+       .get_tune_settings = tda10071_get_tune_settings,
+
+       .init = tda10071_init,
+       .sleep = tda10071_sleep,
+
+       .set_frontend = tda10071_set_frontend,
+       .get_frontend = tda10071_get_frontend,
+
+       .read_status = tda10071_read_status,
+       .read_snr = tda10071_read_snr,
+       .read_signal_strength = tda10071_read_signal_strength,
+       .read_ber = tda10071_read_ber,
+       .read_ucblocks = tda10071_read_ucblocks,
+
+       .diseqc_send_master_cmd = tda10071_diseqc_send_master_cmd,
+       .diseqc_recv_slave_reply = tda10071_diseqc_recv_slave_reply,
+       .diseqc_send_burst = tda10071_diseqc_send_burst,
+
+       .set_tone = tda10071_set_tone,
+       .set_voltage = tda10071_set_voltage,
+};
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h
new file mode 100644 (file)
index 0000000..21163c4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef TDA10071_H
+#define TDA10071_H
+
+#include <linux/dvb/frontend.h>
+
+struct tda10071_config {
+       /* Demodulator I2C address.
+        * Default: none, must set
+        * Values: 0x55,
+        */
+       u8 i2c_address;
+
+       /* Max bytes I2C provider can write at once.
+        * Note: Buffer is taken from the stack currently!
+        * Default: none, must set
+        * Values:
+        */
+       u16 i2c_wr_max;
+
+       /* TS output mode.
+        * Default: TDA10071_TS_SERIAL
+        * Values:
+        */
+#define TDA10071_TS_SERIAL        0
+#define TDA10071_TS_PARALLEL      1
+       u8 ts_mode;
+
+       /* Input spectrum inversion.
+        * Default: 0
+        * Values: 0, 1
+        */
+       bool spec_inv;
+
+       /* Xtal frequency Hz
+        * Default: none, must set
+        * Values:
+        */
+       u32 xtal;
+
+       /* PLL multiplier.
+        * Default: none, must set
+        * Values:
+        */
+       u8 pll_multiplier;
+};
+
+
+#if defined(CONFIG_DVB_TDA10071) || \
+       (defined(CONFIG_DVB_TDA10071_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10071_attach(
+       const struct tda10071_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *tda10071_attach(
+       const struct tda10071_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* TDA10071_H */
diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
new file mode 100644 (file)
index 0000000..0fa85cf
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; 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.
+ */
+
+#ifndef TDA10071_PRIV
+#define TDA10071_PRIV
+
+#include "dvb_frontend.h"
+#include "tda10071.h"
+#include <linux/firmware.h>
+
+struct tda10071_priv {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend fe;
+       struct tda10071_config cfg;
+
+       u8 meas_count[2];
+       u32 ber;
+       u32 ucb;
+       fe_status_t fe_status;
+       fe_delivery_system_t delivery_system;
+       bool warm; /* FW running */
+};
+
+static struct tda10071_modcod {
+       fe_delivery_system_t delivery_system;
+       fe_modulation_t modulation;
+       fe_code_rate_t fec;
+       u8 val;
+} TDA10071_MODCOD[] = {
+       /* NBC-QPSK */
+       { SYS_DVBS2, QPSK,  FEC_AUTO, 0x00 },
+       { SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
+       { SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
+       { SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
+       { SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
+       { SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
+       { SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
+       { SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
+       { SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
+       /* 8PSK */
+       { SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
+       { SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
+       { SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
+       { SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
+       { SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
+       { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
+       /* QPSK */
+       { SYS_DVBS,  QPSK,  FEC_AUTO, 0x2d },
+       { SYS_DVBS,  QPSK,  FEC_1_2,  0x2e },
+       { SYS_DVBS,  QPSK,  FEC_2_3,  0x2f },
+       { SYS_DVBS,  QPSK,  FEC_3_4,  0x30 },
+       { SYS_DVBS,  QPSK,  FEC_5_6,  0x31 },
+       { SYS_DVBS,  QPSK,  FEC_7_8,  0x32 },
+};
+
+struct tda10071_reg_val_mask {
+       u8 reg;
+       u8 val;
+       u8 mask;
+};
+
+/* firmware filename */
+#define TDA10071_DEFAULT_FIRMWARE      "dvb-fe-tda10071.fw"
+
+/* firmware commands */
+#define CMD_DEMOD_INIT          0x10
+#define CMD_CHANGE_CHANNEL      0x11
+#define CMD_MPEG_CONFIG         0x13
+#define CMD_TUNER_INIT          0x15
+#define CMD_GET_AGCACC          0x1a
+
+#define CMD_LNB_CONFIG          0x20
+#define CMD_LNB_SEND_DISEQC     0x21
+#define CMD_LNB_SET_DC_LEVEL    0x22
+#define CMD_LNB_PCB_CONFIG      0x23
+#define CMD_LNB_SEND_TONEBURST  0x24
+#define CMD_LNB_UPDATE_REPLY    0x25
+
+#define CMD_GET_FW_VERSION      0x35
+#define CMD_SET_SLEEP_MODE      0x36
+#define CMD_BER_CONTROL         0x3e
+#define CMD_BER_UPDATE_COUNTERS 0x3f
+
+/* firmare command struct */
+#define TDA10071_ARGLEN      30
+struct tda10071_cmd {
+       u8 args[TDA10071_ARGLEN];
+       u8 len;
+};
+
+
+#endif /* TDA10071_PRIV */
diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
new file mode 100644 (file)
index 0000000..fcfe2e0
--- /dev/null
@@ -0,0 +1,777 @@
+  /*
+     Driver for Philips tda10086 DVBS Demodulator
+
+     (c) 2006 Andrew de Quincey
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda10086.h"
+
+#define SACLK 96000000
+
+struct tda10086_state {
+       struct i2c_adapter* i2c;
+       const struct tda10086_config* config;
+       struct dvb_frontend frontend;
+
+       /* private demod data */
+       u32 frequency;
+       u32 symbol_rate;
+       bool has_lock;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "tda10086: " args); \
+       } while (0)
+
+static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
+{
+       int ret;
+       u8 b0[] = { reg, data };
+       struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };
+
+       msg.addr = state->config->demod_address;
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
+                       __func__, reg, data, ret);
+
+       return (ret != 1) ? ret : 0;
+}
+
+static int tda10086_read_byte(struct tda10086_state *state, int reg)
+{
+       int ret;
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
+                               { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
+
+       msg[0].addr = state->config->demod_address;
+       msg[1].addr = state->config->demod_address;
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
+                       ret);
+               return ret;
+       }
+
+       return b1[0];
+}
+
+static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
+{
+       int val;
+
+       /* read a byte and check */
+       val = tda10086_read_byte(state, reg);
+       if (val < 0)
+               return val;
+
+       /* mask if off */
+       val = val & ~mask;
+       val |= data & 0xff;
+
+       /* write it out again */
+       return tda10086_write_byte(state, reg, val);
+}
+
+static int tda10086_init(struct dvb_frontend* fe)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 t22k_off = 0x80;
+
+       dprintk ("%s\n", __func__);
+
+       if (state->config->diseqc_tone)
+               t22k_off = 0;
+       /* reset */
+       tda10086_write_byte(state, 0x00, 0x00);
+       msleep(10);
+
+       /* misc setup */
+       tda10086_write_byte(state, 0x01, 0x94);
+       tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */
+       tda10086_write_byte(state, 0x03, 0xe4);
+       tda10086_write_byte(state, 0x04, 0x43);
+       tda10086_write_byte(state, 0x0c, 0x0c);
+       tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */
+       tda10086_write_byte(state, 0x20, 0x89); /* misc */
+       tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */
+       tda10086_write_byte(state, 0x32, 0x00); /* irq off */
+       tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */
+
+       /* setup PLL (this assumes SACLK = 96MHz) */
+       tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */
+       if (state->config->xtal_freq == TDA10086_XTAL_16M) {
+               tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */
+               tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */
+       } else {
+               tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */
+               tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */
+       }
+       tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */
+
+       /* setup TS interface */
+       tda10086_write_byte(state, 0x11, 0x81);
+       tda10086_write_byte(state, 0x12, 0x81);
+       tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */
+       tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */
+       tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */
+       tda10086_write_byte(state, 0x10, 0x2a);
+
+       /* setup ADC */
+       tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */
+       tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */
+
+       /* setup AGC */
+       tda10086_write_byte(state, 0x05, 0x0B);
+       tda10086_write_byte(state, 0x37, 0x63);
+       tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */
+       tda10086_write_byte(state, 0x40, 0x64);
+       tda10086_write_byte(state, 0x41, 0x4f);
+       tda10086_write_byte(state, 0x42, 0x43);
+
+       /* setup viterbi */
+       tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */
+
+       /* setup carrier recovery */
+       tda10086_write_byte(state, 0x3d, 0x80);
+
+       /* setup SEC */
+       tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */
+       tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));
+       tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8);
+
+       return 0;
+}
+
+static void tda10086_diseqc_wait(struct tda10086_state *state)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(200);
+       while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
+               if(time_after(jiffies, timeout)) {
+                       printk("%s: diseqc queue not ready, command may be lost.\n", __func__);
+                       break;
+               }
+               msleep(10);
+       }
+}
+
+static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 t22k_off = 0x80;
+
+       dprintk ("%s\n", __func__);
+
+       if (state->config->diseqc_tone)
+               t22k_off = 0;
+
+       switch (tone) {
+       case SEC_TONE_OFF:
+               tda10086_write_byte(state, 0x36, t22k_off);
+               break;
+
+       case SEC_TONE_ON:
+               tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
+               break;
+       }
+
+       return 0;
+}
+
+static int tda10086_send_master_cmd (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd* cmd)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       int i;
+       u8 oldval;
+       u8 t22k_off = 0x80;
+
+       dprintk ("%s\n", __func__);
+
+       if (state->config->diseqc_tone)
+               t22k_off = 0;
+
+       if (cmd->msg_len > 6)
+               return -EINVAL;
+       oldval = tda10086_read_byte(state, 0x36);
+
+       for(i=0; i< cmd->msg_len; i++) {
+               tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
+       }
+       tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
+                                       | ((cmd->msg_len - 1) << 4));
+
+       tda10086_diseqc_wait(state);
+
+       tda10086_write_byte(state, 0x36, oldval);
+
+       return 0;
+}
+
+static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 oldval = tda10086_read_byte(state, 0x36);
+       u8 t22k_off = 0x80;
+
+       dprintk ("%s\n", __func__);
+
+       if (state->config->diseqc_tone)
+               t22k_off = 0;
+
+       switch(minicmd) {
+       case SEC_MINI_A:
+               tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
+               break;
+
+       case SEC_MINI_B:
+               tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
+               break;
+       }
+
+       tda10086_diseqc_wait(state);
+
+       tda10086_write_byte(state, 0x36, oldval);
+
+       return 0;
+}
+
+static int tda10086_set_inversion(struct tda10086_state *state,
+                                 struct dtv_frontend_properties *fe_params)
+{
+       u8 invval = 0x80;
+
+       dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert);
+
+       switch(fe_params->inversion) {
+       case INVERSION_OFF:
+               if (state->config->invert)
+                       invval = 0x40;
+               break;
+       case INVERSION_ON:
+               if (!state->config->invert)
+                       invval = 0x40;
+               break;
+       case INVERSION_AUTO:
+               invval = 0x00;
+               break;
+       }
+       tda10086_write_mask(state, 0x0c, 0xc0, invval);
+
+       return 0;
+}
+
+static int tda10086_set_symbol_rate(struct tda10086_state *state,
+                                   struct dtv_frontend_properties *fe_params)
+{
+       u8 dfn = 0;
+       u8 afs = 0;
+       u8 byp = 0;
+       u8 reg37 = 0x43;
+       u8 reg42 = 0x43;
+       u64 big;
+       u32 tmp;
+       u32 bdr;
+       u32 bdri;
+       u32 symbol_rate = fe_params->symbol_rate;
+
+       dprintk ("%s %i\n", __func__, symbol_rate);
+
+       /* setup the decimation and anti-aliasing filters.. */
+       if (symbol_rate < (u32) (SACLK * 0.0137)) {
+               dfn=4;
+               afs=1;
+       } else if (symbol_rate < (u32) (SACLK * 0.0208)) {
+               dfn=4;
+               afs=0;
+       } else if (symbol_rate < (u32) (SACLK * 0.0270)) {
+               dfn=3;
+               afs=1;
+       } else if (symbol_rate < (u32) (SACLK * 0.0416)) {
+               dfn=3;
+               afs=0;
+       } else if (symbol_rate < (u32) (SACLK * 0.0550)) {
+               dfn=2;
+               afs=1;
+       } else if (symbol_rate < (u32) (SACLK * 0.0833)) {
+               dfn=2;
+               afs=0;
+       } else if (symbol_rate < (u32) (SACLK * 0.1100)) {
+               dfn=1;
+               afs=1;
+       } else if (symbol_rate < (u32) (SACLK * 0.1666)) {
+               dfn=1;
+               afs=0;
+       } else if (symbol_rate < (u32) (SACLK * 0.2200)) {
+               dfn=0;
+               afs=1;
+       } else if (symbol_rate < (u32) (SACLK * 0.3333)) {
+               dfn=0;
+               afs=0;
+       } else {
+               reg37 = 0x63;
+               reg42 = 0x4f;
+               byp=1;
+       }
+
+       /* calculate BDR */
+       big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
+       big += ((SACLK/1000ULL)-1ULL);
+       do_div(big, (SACLK/1000ULL));
+       bdr = big & 0xfffff;
+
+       /* calculate BDRI */
+       tmp = (1<<dfn)*(symbol_rate/1000);
+       bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
+
+       tda10086_write_byte(state, 0x21, (afs << 7) | dfn);
+       tda10086_write_mask(state, 0x20, 0x08, byp << 3);
+       tda10086_write_byte(state, 0x06, bdr);
+       tda10086_write_byte(state, 0x07, bdr >> 8);
+       tda10086_write_byte(state, 0x08, bdr >> 16);
+       tda10086_write_byte(state, 0x09, bdri);
+       tda10086_write_byte(state, 0x37, reg37);
+       tda10086_write_byte(state, 0x42, reg42);
+
+       return 0;
+}
+
+static int tda10086_set_fec(struct tda10086_state *state,
+                           struct dtv_frontend_properties *fe_params)
+{
+       u8 fecval;
+
+       dprintk("%s %i\n", __func__, fe_params->fec_inner);
+
+       switch (fe_params->fec_inner) {
+       case FEC_1_2:
+               fecval = 0x00;
+               break;
+       case FEC_2_3:
+               fecval = 0x01;
+               break;
+       case FEC_3_4:
+               fecval = 0x02;
+               break;
+       case FEC_4_5:
+               fecval = 0x03;
+               break;
+       case FEC_5_6:
+               fecval = 0x04;
+               break;
+       case FEC_6_7:
+               fecval = 0x05;
+               break;
+       case FEC_7_8:
+               fecval = 0x06;
+               break;
+       case FEC_8_9:
+               fecval = 0x07;
+               break;
+       case FEC_AUTO:
+               fecval = 0x08;
+               break;
+       default:
+               return -1;
+       }
+       tda10086_write_byte(state, 0x0d, fecval);
+
+       return 0;
+}
+
+static int tda10086_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
+       struct tda10086_state *state = fe->demodulator_priv;
+       int ret;
+       u32 freq = 0;
+       int freqoff;
+
+       dprintk ("%s\n", __func__);
+
+       /* modify parameters for tuning */
+       tda10086_write_byte(state, 0x02, 0x35);
+       state->has_lock = false;
+
+       /* set params */
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+               if (fe->ops.tuner_ops.get_frequency)
+                       fe->ops.tuner_ops.get_frequency(fe, &freq);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       /* calcluate the frequency offset (in *Hz* not kHz) */
+       freqoff = fe_params->frequency - freq;
+       freqoff = ((1<<16) * freqoff) / (SACLK/1000);
+       tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
+       tda10086_write_byte(state, 0x3e, freqoff);
+
+       if ((ret = tda10086_set_inversion(state, fe_params)) < 0)
+               return ret;
+       if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0)
+               return ret;
+       if ((ret = tda10086_set_fec(state, fe_params)) < 0)
+               return ret;
+
+       /* soft reset + disable TS output until lock */
+       tda10086_write_mask(state, 0x10, 0x40, 0x40);
+       tda10086_write_mask(state, 0x00, 0x01, 0x00);
+
+       state->symbol_rate = fe_params->symbol_rate;
+       state->frequency = fe_params->frequency;
+       return 0;
+}
+
+static int tda10086_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 val;
+       int tmp;
+       u64 tmp64;
+
+       dprintk ("%s\n", __func__);
+
+       /* check for invalid symbol rate */
+       if (fe_params->symbol_rate < 500000)
+               return -EINVAL;
+
+       /* calculate the updated frequency (note: we convert from Hz->kHz) */
+       tmp64 = tda10086_read_byte(state, 0x52);
+       tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
+       if (tmp64 & 0x8000)
+               tmp64 |= 0xffffffffffff0000ULL;
+       tmp64 = (tmp64 * (SACLK/1000ULL));
+       do_div(tmp64, (1ULL<<15) * (1ULL<<1));
+       fe_params->frequency = (int) state->frequency + (int) tmp64;
+
+       /* the inversion */
+       val = tda10086_read_byte(state, 0x0c);
+       if (val & 0x80) {
+               switch(val & 0x40) {
+               case 0x00:
+                       fe_params->inversion = INVERSION_OFF;
+                       if (state->config->invert)
+                               fe_params->inversion = INVERSION_ON;
+                       break;
+               default:
+                       fe_params->inversion = INVERSION_ON;
+                       if (state->config->invert)
+                               fe_params->inversion = INVERSION_OFF;
+                       break;
+               }
+       } else {
+               tda10086_read_byte(state, 0x0f);
+               switch(val & 0x02) {
+               case 0x00:
+                       fe_params->inversion = INVERSION_OFF;
+                       if (state->config->invert)
+                               fe_params->inversion = INVERSION_ON;
+                       break;
+               default:
+                       fe_params->inversion = INVERSION_ON;
+                       if (state->config->invert)
+                               fe_params->inversion = INVERSION_OFF;
+                       break;
+               }
+       }
+
+       /* calculate the updated symbol rate */
+       tmp = tda10086_read_byte(state, 0x1d);
+       if (tmp & 0x80)
+               tmp |= 0xffffff00;
+       tmp = (tmp * 480 * (1<<1)) / 128;
+       tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
+       fe_params->symbol_rate = state->symbol_rate + tmp;
+
+       /* the FEC */
+       val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
+       switch(val) {
+       case 0x00:
+               fe_params->fec_inner = FEC_1_2;
+               break;
+       case 0x01:
+               fe_params->fec_inner = FEC_2_3;
+               break;
+       case 0x02:
+               fe_params->fec_inner = FEC_3_4;
+               break;
+       case 0x03:
+               fe_params->fec_inner = FEC_4_5;
+               break;
+       case 0x04:
+               fe_params->fec_inner = FEC_5_6;
+               break;
+       case 0x05:
+               fe_params->fec_inner = FEC_6_7;
+               break;
+       case 0x06:
+               fe_params->fec_inner = FEC_7_8;
+               break;
+       case 0x07:
+               fe_params->fec_inner = FEC_8_9;
+               break;
+       }
+
+       return 0;
+}
+
+static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk ("%s\n", __func__);
+
+       val = tda10086_read_byte(state, 0x0e);
+       *fe_status = 0;
+       if (val & 0x01)
+               *fe_status |= FE_HAS_SIGNAL;
+       if (val & 0x02)
+               *fe_status |= FE_HAS_CARRIER;
+       if (val & 0x04)
+               *fe_status |= FE_HAS_VITERBI;
+       if (val & 0x08)
+               *fe_status |= FE_HAS_SYNC;
+       if (val & 0x10) {
+               *fe_status |= FE_HAS_LOCK;
+               if (!state->has_lock) {
+                       state->has_lock = true;
+                       /* modify parameters for stable reception */
+                       tda10086_write_byte(state, 0x02, 0x00);
+               }
+       }
+
+       return 0;
+}
+
+static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 _str;
+
+       dprintk ("%s\n", __func__);
+
+       _str = 0xff - tda10086_read_byte(state, 0x43);
+       *signal = (_str << 8) | _str;
+
+       return 0;
+}
+
+static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+       u8 _snr;
+
+       dprintk ("%s\n", __func__);
+
+       _snr = 0xff - tda10086_read_byte(state, 0x1c);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+
+       dprintk ("%s\n", __func__);
+
+       /* read it */
+       *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
+
+       /* reset counter */
+       tda10086_write_byte(state, 0x18, 0x00);
+       tda10086_write_byte(state, 0x18, 0x80);
+
+       return 0;
+}
+
+static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+
+       dprintk ("%s\n", __func__);
+
+       /* read it */
+       *ber = 0;
+       *ber |= tda10086_read_byte(state, 0x15);
+       *ber |= tda10086_read_byte(state, 0x16) << 8;
+       *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16;
+
+       return 0;
+}
+
+static int tda10086_sleep(struct dvb_frontend* fe)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+
+       dprintk ("%s\n", __func__);
+
+       tda10086_write_mask(state, 0x00, 0x08, 0x08);
+
+       return 0;
+}
+
+static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct tda10086_state* state = fe->demodulator_priv;
+
+       dprintk ("%s\n", __func__);
+
+       if (enable) {
+               tda10086_write_mask(state, 0x00, 0x10, 0x10);
+       } else {
+               tda10086_write_mask(state, 0x00, 0x10, 0x00);
+       }
+
+       return 0;
+}
+
+static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+       if (p->symbol_rate > 20000000) {
+               fesettings->min_delay_ms = 50;
+               fesettings->step_size = 2000;
+               fesettings->max_drift = 8000;
+       } else if (p->symbol_rate > 12000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 1500;
+               fesettings->max_drift = 9000;
+       } else if (p->symbol_rate > 8000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 1000;
+               fesettings->max_drift = 8000;
+       } else if (p->symbol_rate > 4000000) {
+               fesettings->min_delay_ms = 100;
+               fesettings->step_size = 500;
+               fesettings->max_drift = 7000;
+       } else if (p->symbol_rate > 2000000) {
+               fesettings->min_delay_ms = 200;
+               fesettings->step_size = p->symbol_rate / 8000;
+               fesettings->max_drift = 14 * fesettings->step_size;
+       } else {
+               fesettings->min_delay_ms = 200;
+               fesettings->step_size =  p->symbol_rate / 8000;
+               fesettings->max_drift = 18 * fesettings->step_size;
+       }
+
+       return 0;
+}
+
+static void tda10086_release(struct dvb_frontend* fe)
+{
+       struct tda10086_state *state = fe->demodulator_priv;
+       tda10086_sleep(fe);
+       kfree(state);
+}
+
+static struct dvb_frontend_ops tda10086_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name     = "Philips TDA10086 DVB-S",
+               .frequency_min    = 950000,
+               .frequency_max    = 2150000,
+               .frequency_stepsize = 125,     /* kHz for QPSK frontends */
+               .symbol_rate_min  = 1000000,
+               .symbol_rate_max  = 45000000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK
+       },
+
+       .release = tda10086_release,
+
+       .init = tda10086_init,
+       .sleep = tda10086_sleep,
+       .i2c_gate_ctrl = tda10086_i2c_gate_ctrl,
+
+       .set_frontend = tda10086_set_frontend,
+       .get_frontend = tda10086_get_frontend,
+       .get_tune_settings = tda10086_get_tune_settings,
+
+       .read_status = tda10086_read_status,
+       .read_ber = tda10086_read_ber,
+       .read_signal_strength = tda10086_read_signal_strength,
+       .read_snr = tda10086_read_snr,
+       .read_ucblocks = tda10086_read_ucblocks,
+
+       .diseqc_send_master_cmd = tda10086_send_master_cmd,
+       .diseqc_send_burst = tda10086_send_burst,
+       .set_tone = tda10086_set_tone,
+};
+
+struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+                                    struct i2c_adapter* i2c)
+{
+       struct tda10086_state *state;
+
+       dprintk ("%s\n", __func__);
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if (tda10086_read_byte(state, 0x1e) != 0xe1) {
+               kfree(state);
+               return NULL;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+}
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10086_attach);
diff --git a/drivers/media/dvb-frontends/tda10086.h b/drivers/media/dvb-frontends/tda10086.h
new file mode 100644 (file)
index 0000000..61148c5
--- /dev/null
@@ -0,0 +1,61 @@
+  /*
+     Driver for Philips tda10086 DVBS Frontend
+
+     (c) 2006 Andrew de Quincey
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   */
+
+#ifndef TDA10086_H
+#define TDA10086_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+enum tda10086_xtal {
+       TDA10086_XTAL_16M,
+       TDA10086_XTAL_4M
+};
+
+struct tda10086_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* does the "inversion" need inverted? */
+       u8 invert;
+
+       /* do we need the diseqc signal with carrier? */
+       u8 diseqc_tone;
+
+       /* frequency of the reference xtal */
+       enum tda10086_xtal xtal_freq;
+};
+
+#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+                                           struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+                                                  struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_TDA10086 */
+
+#endif /* TDA10086_H */
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
new file mode 100644 (file)
index 0000000..ad7c72e
--- /dev/null
@@ -0,0 +1,1246 @@
+/*
+ * tda18271c2dd: Driver for the TDA18271C2 tuner
+ *
+ * Copyright (C) 2010 Digital Devices GmbH
+ *
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+
+struct SStandardParam {
+       s32   m_IFFrequency;
+       u32   m_BandWidth;
+       u8    m_EP3_4_0;
+       u8    m_EB22;
+};
+
+struct SMap {
+       u32   m_Frequency;
+       u8    m_Param;
+};
+
+struct SMapI {
+       u32   m_Frequency;
+       s32    m_Param;
+};
+
+struct SMap2 {
+       u32   m_Frequency;
+       u8    m_Param1;
+       u8    m_Param2;
+};
+
+struct SRFBandMap {
+       u32   m_RF_max;
+       u32   m_RF1_Default;
+       u32   m_RF2_Default;
+       u32   m_RF3_Default;
+};
+
+enum ERegister {
+       ID = 0,
+       TM,
+       PL,
+       EP1, EP2, EP3, EP4, EP5,
+       CPD, CD1, CD2, CD3,
+       MPD, MD1, MD2, MD3,
+       EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
+       EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
+       EB21, EB22, EB23,
+       NUM_REGS
+};
+
+struct tda_state {
+       struct i2c_adapter *i2c;
+       u8 adr;
+
+       u32   m_Frequency;
+       u32   IF;
+
+       u8    m_IFLevelAnalog;
+       u8    m_IFLevelDigital;
+       u8    m_IFLevelDVBC;
+       u8    m_IFLevelDVBT;
+
+       u8    m_EP4;
+       u8    m_EP3_Standby;
+
+       bool  m_bMaster;
+
+       s32   m_SettlingTime;
+
+       u8    m_Regs[NUM_REGS];
+
+       /* Tracking filter settings for band 0..6 */
+       u32   m_RF1[7];
+       s32   m_RF_A1[7];
+       s32   m_RF_B1[7];
+       u32   m_RF2[7];
+       s32   m_RF_A2[7];
+       s32   m_RF_B2[7];
+       u32   m_RF3[7];
+
+       u8    m_TMValue_RFCal;    /* Calibration temperatur */
+
+       bool  m_bFMInput;         /* true to use Pin 8 for FM Radio */
+
+};
+
+static int PowerScan(struct tda_state *state,
+                    u8 RFBand, u32 RF_in,
+                    u32 *pRF_Out, bool *pbcal);
+
+static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
+{
+       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
+                                  .buf  = data, .len   = len} };
+       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
+}
+
+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
+{
+       struct i2c_msg msg = {.addr = adr, .flags = 0,
+                             .buf = data, .len = len};
+
+       if (i2c_transfer(adap, &msg, 1) != 1) {
+               printk(KERN_ERR "tda18271c2dd: i2c write error at addr %i\n", adr);
+               return -1;
+       }
+       return 0;
+}
+
+static int WriteRegs(struct tda_state *state,
+                    u8 SubAddr, u8 *Regs, u16 nRegs)
+{
+       u8 data[nRegs+1];
+
+       data[0] = SubAddr;
+       memcpy(data + 1, Regs, nRegs);
+       return i2c_write(state->i2c, state->adr, data, nRegs+1);
+}
+
+static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
+{
+       u8 msg[2] = {SubAddr, Reg};
+
+       return i2c_write(state->i2c, state->adr, msg, 2);
+}
+
+static int Read(struct tda_state *state, u8 * Regs)
+{
+       return i2c_readn(state->i2c, state->adr, Regs, 16);
+}
+
+static int ReadExtented(struct tda_state *state, u8 * Regs)
+{
+       return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
+}
+
+static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
+{
+       return WriteRegs(state, RegFrom,
+                        &state->m_Regs[RegFrom], RegTo-RegFrom+1);
+}
+static int UpdateReg(struct tda_state *state, u8 Reg)
+{
+       return WriteReg(state, Reg, state->m_Regs[Reg]);
+}
+
+#include "tda18271c2dd_maps.h"
+
+static void reset(struct tda_state *state)
+{
+       u32   ulIFLevelAnalog = 0;
+       u32   ulIFLevelDigital = 2;
+       u32   ulIFLevelDVBC = 7;
+       u32   ulIFLevelDVBT = 6;
+       u32   ulXTOut = 0;
+       u32   ulStandbyMode = 0x06;    /* Send in stdb, but leave osc on */
+       u32   ulSlave = 0;
+       u32   ulFMInput = 0;
+       u32   ulSettlingTime = 100;
+
+       state->m_Frequency         = 0;
+       state->m_SettlingTime = 100;
+       state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
+       state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
+       state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
+       state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
+
+       state->m_EP4 = 0x20;
+       if (ulXTOut != 0)
+               state->m_EP4 |= 0x40;
+
+       state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
+       state->m_bMaster = (ulSlave == 0);
+
+       state->m_SettlingTime = ulSettlingTime;
+
+       state->m_bFMInput = (ulFMInput == 2);
+}
+
+static bool SearchMap1(struct SMap Map[],
+                      u32 Frequency, u8 *pParam)
+{
+       int i = 0;
+
+       while ((Map[i].m_Frequency != 0) && (Frequency > Map[i].m_Frequency))
+               i += 1;
+       if (Map[i].m_Frequency == 0)
+               return false;
+       *pParam = Map[i].m_Param;
+       return true;
+}
+
+static bool SearchMap2(struct SMapI Map[],
+                      u32 Frequency, s32 *pParam)
+{
+       int i = 0;
+
+       while ((Map[i].m_Frequency != 0) &&
+              (Frequency > Map[i].m_Frequency))
+               i += 1;
+       if (Map[i].m_Frequency == 0)
+               return false;
+       *pParam = Map[i].m_Param;
+       return true;
+}
+
+static bool SearchMap3(struct SMap2 Map[], u32 Frequency,
+                      u8 *pParam1, u8 *pParam2)
+{
+       int i = 0;
+
+       while ((Map[i].m_Frequency != 0) &&
+              (Frequency > Map[i].m_Frequency))
+               i += 1;
+       if (Map[i].m_Frequency == 0)
+               return false;
+       *pParam1 = Map[i].m_Param1;
+       *pParam2 = Map[i].m_Param2;
+       return true;
+}
+
+static bool SearchMap4(struct SRFBandMap Map[],
+                      u32 Frequency, u8 *pRFBand)
+{
+       int i = 0;
+
+       while (i < 7 && (Frequency > Map[i].m_RF_max))
+               i += 1;
+       if (i == 7)
+               return false;
+       *pRFBand = i;
+       return true;
+}
+
+static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
+{
+       int status = 0;
+
+       do {
+               u8 Regs[16];
+               state->m_Regs[TM] |= 0x10;
+               status = UpdateReg(state, TM);
+               if (status < 0)
+                       break;
+               status = Read(state, Regs);
+               if (status < 0)
+                       break;
+               if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
+                   ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
+                       state->m_Regs[TM] ^= 0x20;
+                       status = UpdateReg(state, TM);
+                       if (status < 0)
+                               break;
+                       msleep(10);
+                       status = Read(state, Regs);
+                       if (status < 0)
+                               break;
+               }
+               *pTM_Value = (Regs[TM] & 0x20)
+                               ? m_Thermometer_Map_2[Regs[TM] & 0x0F]
+                               : m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
+               state->m_Regs[TM] &= ~0x10;        /* Thermometer off */
+               status = UpdateReg(state, TM);
+               if (status < 0)
+                       break;
+               state->m_Regs[EP4] &= ~0x03;       /* CAL_mode = 0 ????????? */
+               status = UpdateReg(state, EP4);
+               if (status < 0)
+                       break;
+       } while (0);
+
+       return status;
+}
+
+static int StandBy(struct tda_state *state)
+{
+       int status = 0;
+       do {
+               state->m_Regs[EB12] &= ~0x20;  /* PD_AGC1_Det = 0 */
+               status = UpdateReg(state, EB12);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB18] &= ~0x83;  /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
+               status = UpdateReg(state, EB18);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
+               state->m_Regs[EP3] = state->m_EP3_Standby;
+               status = UpdateReg(state, EP3);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
+               status = UpdateRegs(state, EB21, EB23);
+               if (status < 0)
+                       break;
+       } while (0);
+       return status;
+}
+
+static int CalcMainPLL(struct tda_state *state, u32 freq)
+{
+
+       u8  PostDiv;
+       u8  Div;
+       u64 OscFreq;
+       u32 MainDiv;
+
+       if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
+               return -EINVAL;
+
+       OscFreq = (u64) freq * (u64) Div;
+       OscFreq *= (u64) 16384;
+       do_div(OscFreq, (u64)16000000);
+       MainDiv = OscFreq;
+
+       state->m_Regs[MPD] = PostDiv & 0x77;
+       state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
+       state->m_Regs[MD2] = ((MainDiv >>  8) & 0xFF);
+       state->m_Regs[MD3] = (MainDiv & 0xFF);
+
+       return UpdateRegs(state, MPD, MD3);
+}
+
+static int CalcCalPLL(struct tda_state *state, u32 freq)
+{
+       u8 PostDiv;
+       u8 Div;
+       u64 OscFreq;
+       u32 CalDiv;
+
+       if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
+               return -EINVAL;
+
+       OscFreq = (u64)freq * (u64)Div;
+       /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
+       OscFreq *= (u64)16384;
+       do_div(OscFreq, (u64)16000000);
+       CalDiv = OscFreq;
+
+       state->m_Regs[CPD] = PostDiv;
+       state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
+       state->m_Regs[CD2] = ((CalDiv >>  8) & 0xFF);
+       state->m_Regs[CD3] = (CalDiv & 0xFF);
+
+       return UpdateRegs(state, CPD, CD3);
+}
+
+static int CalibrateRF(struct tda_state *state,
+                      u8 RFBand, u32 freq, s32 *pCprog)
+{
+       int status = 0;
+       u8 Regs[NUM_REGS];
+       do {
+               u8 BP_Filter = 0;
+               u8 GainTaper = 0;
+               u8 RFC_K = 0;
+               u8 RFC_M = 0;
+
+               state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
+               status = UpdateReg(state, EP4);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB18] |= 0x03;  /* AGC1_Gain = 3 */
+               status = UpdateReg(state, EB18);
+               if (status < 0)
+                       break;
+
+               /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
+               /* (Readout of Cprog is allways 255) */
+               if (state->m_Regs[ID] != 0x83)    /* C1: ID == 83, C2: ID == 84 */
+                       state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
+
+               if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
+                       SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
+                       SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
+                       return -EINVAL;
+
+               state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
+               state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
+
+               state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
+
+               status = UpdateRegs(state, EP1, EP3);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EB13);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB4] |= 0x20;    /* LO_ForceSrce = 1 */
+               status = UpdateReg(state, EB4);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB7] |= 0x20;    /* CAL_ForceSrce = 1 */
+               status = UpdateReg(state, EB7);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
+               status = UpdateReg(state, EB14);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB20] &= ~0x20;  /* ForceLock = 0; */
+               status = UpdateReg(state, EB20);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EP4] |= 0x03;  /* CAL_Mode = 3 */
+               status = UpdateRegs(state, EP4, EP5);
+               if (status < 0)
+                       break;
+
+               status = CalcCalPLL(state, freq);
+               if (status < 0)
+                       break;
+               status = CalcMainPLL(state, freq + 1000000);
+               if (status < 0)
+                       break;
+
+               msleep(5);
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB4] &= ~0x20;    /* LO_ForceSrce = 0 */
+               status = UpdateReg(state, EB4);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EB7] &= ~0x20;    /* CAL_ForceSrce = 0 */
+               status = UpdateReg(state, EB7);
+               if (status < 0)
+                       break;
+               msleep(10);
+
+               state->m_Regs[EB20] |= 0x20;  /* ForceLock = 1; */
+               status = UpdateReg(state, EB20);
+               if (status < 0)
+                       break;
+               msleep(60);
+
+               state->m_Regs[EP4] &= ~0x03;  /* CAL_Mode = 0 */
+               state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
+               state->m_Regs[EB18] &= ~0x03;  /* AGC1_Gain = 0 */
+               status = UpdateReg(state, EB18);
+               if (status < 0)
+                       break;
+               status = UpdateRegs(state, EP3, EP4);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+
+               status = ReadExtented(state, Regs);
+               if (status < 0)
+                       break;
+
+               *pCprog = Regs[EB14];
+
+       } while (0);
+       return status;
+}
+
+static int RFTrackingFiltersInit(struct tda_state *state,
+                                u8 RFBand)
+{
+       int status = 0;
+
+       u32   RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
+       u32   RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
+       u32   RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
+       bool    bcal = false;
+
+       s32    Cprog_cal1 = 0;
+       s32    Cprog_table1 = 0;
+       s32    Cprog_cal2 = 0;
+       s32    Cprog_table2 = 0;
+       s32    Cprog_cal3 = 0;
+       s32    Cprog_table3 = 0;
+
+       state->m_RF_A1[RFBand] = 0;
+       state->m_RF_B1[RFBand] = 0;
+       state->m_RF_A2[RFBand] = 0;
+       state->m_RF_B2[RFBand] = 0;
+
+       do {
+               status = PowerScan(state, RFBand, RF1, &RF1, &bcal);
+               if (status < 0)
+                       break;
+               if (bcal) {
+                       status = CalibrateRF(state, RFBand, RF1, &Cprog_cal1);
+                       if (status < 0)
+                               break;
+               }
+               SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
+               if (!bcal)
+                       Cprog_cal1 = Cprog_table1;
+               state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
+               /* state->m_RF_A1[RF_Band] = ???? */
+
+               if (RF2 == 0)
+                       break;
+
+               status = PowerScan(state, RFBand, RF2, &RF2, &bcal);
+               if (status < 0)
+                       break;
+               if (bcal) {
+                       status = CalibrateRF(state, RFBand, RF2, &Cprog_cal2);
+                       if (status < 0)
+                               break;
+               }
+               SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
+               if (!bcal)
+                       Cprog_cal2 = Cprog_table2;
+
+               state->m_RF_A1[RFBand] =
+                       (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
+                       ((s32)(RF2) - (s32)(RF1));
+
+               if (RF3 == 0)
+                       break;
+
+               status = PowerScan(state, RFBand, RF3, &RF3, &bcal);
+               if (status < 0)
+                       break;
+               if (bcal) {
+                       status = CalibrateRF(state, RFBand, RF3, &Cprog_cal3);
+                       if (status < 0)
+                               break;
+               }
+               SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
+               if (!bcal)
+                       Cprog_cal3 = Cprog_table3;
+               state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
+               state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
+
+       } while (0);
+
+       state->m_RF1[RFBand] = RF1;
+       state->m_RF2[RFBand] = RF2;
+       state->m_RF3[RFBand] = RF3;
+
+#if 0
+       printk(KERN_ERR "tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
+              RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
+              state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
+#endif
+
+       return status;
+}
+
+static int PowerScan(struct tda_state *state,
+                    u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
+{
+       int status = 0;
+       do {
+               u8   Gain_Taper = 0;
+               s32  RFC_Cprog = 0;
+               u8   CID_Target = 0;
+               u8   CountLimit = 0;
+               u32  freq_MainPLL;
+               u8   Regs[NUM_REGS];
+               u8   CID_Gain;
+               s32  Count = 0;
+               int  sign  = 1;
+               bool wait = false;
+
+               if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
+                     SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
+                     SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
+
+                       printk(KERN_ERR "tda18271c2dd: %s Search map failed\n", __func__);
+                       return -EINVAL;
+               }
+
+               state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
+               state->m_Regs[EB14] = (RFC_Cprog);
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EB14);
+               if (status < 0)
+                       break;
+
+               freq_MainPLL = RF_in + 1000000;
+               status = CalcMainPLL(state, freq_MainPLL);
+               if (status < 0)
+                       break;
+               msleep(5);
+               state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1;    /* CAL_mode = 1 */
+               status = UpdateReg(state, EP4);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP2);  /* Launch power measurement */
+               if (status < 0)
+                       break;
+               status = ReadExtented(state, Regs);
+               if (status < 0)
+                       break;
+               CID_Gain = Regs[EB10] & 0x3F;
+               state->m_Regs[ID] = Regs[ID];  /* Chip version, (needed for C1 workarround in CalibrateRF) */
+
+               *pRF_Out = RF_in;
+
+               while (CID_Gain < CID_Target) {
+                       freq_MainPLL = RF_in + sign * Count + 1000000;
+                       status = CalcMainPLL(state, freq_MainPLL);
+                       if (status < 0)
+                               break;
+                       msleep(wait ? 5 : 1);
+                       wait = false;
+                       status = UpdateReg(state, EP2);  /* Launch power measurement */
+                       if (status < 0)
+                               break;
+                       status = ReadExtented(state, Regs);
+                       if (status < 0)
+                               break;
+                       CID_Gain = Regs[EB10] & 0x3F;
+                       Count += 200000;
+
+                       if (Count < CountLimit * 100000)
+                               continue;
+                       if (sign < 0)
+                               break;
+
+                       sign = -sign;
+                       Count = 200000;
+                       wait = true;
+               }
+               status = status;
+               if (status < 0)
+                       break;
+               if (CID_Gain >= CID_Target) {
+                       *pbcal = true;
+                       *pRF_Out = freq_MainPLL - 1000000;
+               } else
+                       *pbcal = false;
+       } while (0);
+
+       return status;
+}
+
+static int PowerScanInit(struct tda_state *state)
+{
+       int status = 0;
+       do {
+               state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
+               state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
+               status = UpdateRegs(state, EP3, EP4);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
+               status = UpdateReg(state, EB18);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
+               state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
+               status = UpdateRegs(state, EB21, EB23);
+               if (status < 0)
+                       break;
+       } while (0);
+       return status;
+}
+
+static int CalcRFFilterCurve(struct tda_state *state)
+{
+       int status = 0;
+       do {
+               msleep(200);      /* Temperature stabilisation */
+               status = PowerScanInit(state);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 0);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 1);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 2);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 3);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 4);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 5);
+               if (status < 0)
+                       break;
+               status = RFTrackingFiltersInit(state, 6);
+               if (status < 0)
+                       break;
+               status = ThermometerRead(state, &state->m_TMValue_RFCal); /* also switches off Cal mode !!! */
+               if (status < 0)
+                       break;
+       } while (0);
+
+       return status;
+}
+
+static int FixedContentsI2CUpdate(struct tda_state *state)
+{
+       static u8 InitRegs[] = {
+               0x08, 0x80, 0xC6,
+               0xDF, 0x16, 0x60, 0x80,
+               0x80, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00,
+               0xFC, 0x01, 0x84, 0x41,
+               0x01, 0x84, 0x40, 0x07,
+               0x00, 0x00, 0x96, 0x3F,
+               0xC1, 0x00, 0x8F, 0x00,
+               0x00, 0x8C, 0x00, 0x20,
+               0xB3, 0x48, 0xB0,
+       };
+       int status = 0;
+       memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
+       do {
+               status = UpdateRegs(state, TM, EB23);
+               if (status < 0)
+                       break;
+
+               /* AGC1 gain setup */
+               state->m_Regs[EB17] = 0x00;
+               status = UpdateReg(state, EB17);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB17] = 0x03;
+               status = UpdateReg(state, EB17);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB17] = 0x43;
+               status = UpdateReg(state, EB17);
+               if (status < 0)
+                       break;
+               state->m_Regs[EB17] = 0x4C;
+               status = UpdateReg(state, EB17);
+               if (status < 0)
+                       break;
+
+               /* IRC Cal Low band */
+               state->m_Regs[EP3] = 0x1F;
+               state->m_Regs[EP4] = 0x66;
+               state->m_Regs[EP5] = 0x81;
+               state->m_Regs[CPD] = 0xCC;
+               state->m_Regs[CD1] = 0x6C;
+               state->m_Regs[CD2] = 0x00;
+               state->m_Regs[CD3] = 0x00;
+               state->m_Regs[MPD] = 0xC5;
+               state->m_Regs[MD1] = 0x77;
+               state->m_Regs[MD2] = 0x08;
+               state->m_Regs[MD3] = 0x00;
+               status = UpdateRegs(state, EP2, MD3); /* diff between sw and datasheet (ep3-md3) */
+               if (status < 0)
+                       break;
+
+#if 0
+               state->m_Regs[EB4] = 0x61;          /* missing in sw */
+               status = UpdateReg(state, EB4);
+               if (status < 0)
+                       break;
+               msleep(1);
+               state->m_Regs[EB4] = 0x41;
+               status = UpdateReg(state, EB4);
+               if (status < 0)
+                       break;
+#endif
+
+               msleep(5);
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+               msleep(5);
+
+               state->m_Regs[EP5] = 0x85;
+               state->m_Regs[CPD] = 0xCB;
+               state->m_Regs[CD1] = 0x66;
+               state->m_Regs[CD2] = 0x70;
+               status = UpdateRegs(state, EP3, CD3);
+               if (status < 0)
+                       break;
+               msleep(5);
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               msleep(30);
+
+               /* IRC Cal mid band */
+               state->m_Regs[EP5] = 0x82;
+               state->m_Regs[CPD] = 0xA8;
+               state->m_Regs[CD2] = 0x00;
+               state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
+               state->m_Regs[MD1] = 0x73;
+               state->m_Regs[MD2] = 0x1A;
+               status = UpdateRegs(state, EP3, MD3);
+               if (status < 0)
+                       break;
+
+               msleep(5);
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+               msleep(5);
+
+               state->m_Regs[EP5] = 0x86;
+               state->m_Regs[CPD] = 0xA8;
+               state->m_Regs[CD1] = 0x66;
+               state->m_Regs[CD2] = 0xA0;
+               status = UpdateRegs(state, EP3, CD3);
+               if (status < 0)
+                       break;
+               msleep(5);
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               msleep(30);
+
+               /* IRC Cal high band */
+               state->m_Regs[EP5] = 0x83;
+               state->m_Regs[CPD] = 0x98;
+               state->m_Regs[CD1] = 0x65;
+               state->m_Regs[CD2] = 0x00;
+               state->m_Regs[MPD] = 0x91;  /* Datasheet = 0x91 */
+               state->m_Regs[MD1] = 0x71;
+               state->m_Regs[MD2] = 0xCD;
+               status = UpdateRegs(state, EP3, MD3);
+               if (status < 0)
+                       break;
+               msleep(5);
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+               msleep(5);
+               state->m_Regs[EP5] = 0x87;
+               state->m_Regs[CD1] = 0x65;
+               state->m_Regs[CD2] = 0x50;
+               status = UpdateRegs(state, EP3, CD3);
+               if (status < 0)
+                       break;
+               msleep(5);
+               status = UpdateReg(state, EP2);
+               if (status < 0)
+                       break;
+               msleep(30);
+
+               /* Back to normal */
+               state->m_Regs[EP4] = 0x64;
+               status = UpdateReg(state, EP4);
+               if (status < 0)
+                       break;
+               status = UpdateReg(state, EP1);
+               if (status < 0)
+                       break;
+
+       } while (0);
+       return status;
+}
+
+static int InitCal(struct tda_state *state)
+{
+       int status = 0;
+
+       do {
+               status = FixedContentsI2CUpdate(state);
+               if (status < 0)
+                       break;
+               status = CalcRFFilterCurve(state);
+               if (status < 0)
+                       break;
+               status = StandBy(state);
+               if (status < 0)
+                       break;
+               /* m_bInitDone = true; */
+       } while (0);
+       return status;
+};
+
+static int RFTrackingFiltersCorrection(struct tda_state *state,
+                                      u32 Frequency)
+{
+       int status = 0;
+       s32 Cprog_table;
+       u8 RFBand;
+       u8 dCoverdT;
+
+       if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
+           !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
+           !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
+
+               return -EINVAL;
+
+       do {
+               u8 TMValue_Current;
+               u32   RF1 = state->m_RF1[RFBand];
+               u32   RF2 = state->m_RF1[RFBand];
+               u32   RF3 = state->m_RF1[RFBand];
+               s32    RF_A1 = state->m_RF_A1[RFBand];
+               s32    RF_B1 = state->m_RF_B1[RFBand];
+               s32    RF_A2 = state->m_RF_A2[RFBand];
+               s32    RF_B2 = state->m_RF_B2[RFBand];
+               s32 Capprox = 0;
+               int TComp;
+
+               state->m_Regs[EP3] &= ~0xE0;  /* Power up */
+               status = UpdateReg(state, EP3);
+               if (status < 0)
+                       break;
+
+               status = ThermometerRead(state, &TMValue_Current);
+               if (status < 0)
+                       break;
+
+               if (RF3 == 0 || Frequency < RF2)
+                       Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
+               else
+                       Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
+
+               TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
+
+               Capprox += TComp;
+
+               if (Capprox < 0)
+                       Capprox = 0;
+               else if (Capprox > 255)
+                       Capprox = 255;
+
+
+               /* TODO Temperature compensation. There is defenitely a scale factor */
+               /*      missing in the datasheet, so leave it out for now.           */
+               state->m_Regs[EB14] = Capprox;
+
+               status = UpdateReg(state, EB14);
+               if (status < 0)
+                       break;
+
+       } while (0);
+       return status;
+}
+
+static int ChannelConfiguration(struct tda_state *state,
+                               u32 Frequency, int Standard)
+{
+
+       s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
+       int status = 0;
+
+       u8 BP_Filter = 0;
+       u8 RF_Band = 0;
+       u8 GainTaper = 0;
+       u8 IR_Meas = 0;
+
+       state->IF = IntermediateFrequency;
+       /* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
+       /* get values from tables */
+
+       if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
+              SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
+              SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
+              SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
+
+               printk(KERN_ERR "tda18271c2dd: %s SearchMap failed\n", __func__);
+               return -EINVAL;
+       }
+
+       do {
+               state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
+               state->m_Regs[EP3] &= ~0x04;   /* switch RFAGC to high speed mode */
+
+               /* m_EP4 default for XToutOn, CAL_Mode (0) */
+               state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
+               /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
+               if (Standard <= HF_AnalogMax)
+                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
+               else if (Standard <= HF_ATSC)
+                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
+               else if (Standard <= HF_DVBC)
+                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
+               else
+                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
+
+               if ((Standard == HF_FM_Radio) && state->m_bFMInput)
+                       state->m_Regs[EP4] |= 80;
+
+               state->m_Regs[MPD] &= ~0x80;
+               if (Standard > HF_AnalogMax)
+                       state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
+
+               state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
+
+               /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
+               if (Standard == HF_FM_Radio)
+                       state->m_Regs[EB23] |=  0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
+               else
+                       state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
+
+               status = UpdateRegs(state, EB22, EB23);
+               if (status < 0)
+                       break;
+
+               state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter;   /* Dis_Power_level = 1, Filter */
+               state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
+               state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
+
+               state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
+                       (state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
+               /* AGC1_always_master = 0 */
+               /* AGC_firstn = 0 */
+               status = UpdateReg(state, EB1);
+               if (status < 0)
+                       break;
+
+               if (state->m_bMaster) {
+                       status = CalcMainPLL(state, Frequency + IntermediateFrequency);
+                       if (status < 0)
+                               break;
+                       status = UpdateRegs(state, TM, EP5);
+                       if (status < 0)
+                               break;
+                       state->m_Regs[EB4] |= 0x20;    /* LO_forceSrce = 1 */
+                       status = UpdateReg(state, EB4);
+                       if (status < 0)
+                               break;
+                       msleep(1);
+                       state->m_Regs[EB4] &= ~0x20;   /* LO_forceSrce = 0 */
+                       status = UpdateReg(state, EB4);
+                       if (status < 0)
+                               break;
+               } else {
+                       u8 PostDiv = 0;
+                       u8 Div;
+                       status = CalcCalPLL(state, Frequency + IntermediateFrequency);
+                       if (status < 0)
+                               break;
+
+                       SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
+                       state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
+                       status = UpdateReg(state, MPD);
+                       if (status < 0)
+                               break;
+                       status = UpdateRegs(state, TM, EP5);
+                       if (status < 0)
+                               break;
+
+                       state->m_Regs[EB7] |= 0x20;    /* CAL_forceSrce = 1 */
+                       status = UpdateReg(state, EB7);
+                       if (status < 0)
+                               break;
+                       msleep(1);
+                       state->m_Regs[EB7] &= ~0x20;   /* CAL_forceSrce = 0 */
+                       status = UpdateReg(state, EB7);
+                       if (status < 0)
+                               break;
+               }
+               msleep(20);
+               if (Standard != HF_FM_Radio)
+                       state->m_Regs[EP3] |= 0x04;    /* RFAGC to normal mode */
+               status = UpdateReg(state, EP3);
+               if (status < 0)
+                       break;
+
+       } while (0);
+       return status;
+}
+
+static int sleep(struct dvb_frontend *fe)
+{
+       struct tda_state *state = fe->tuner_priv;
+
+       StandBy(state);
+       return 0;
+}
+
+static int init(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static int release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+
+static int set_params(struct dvb_frontend *fe)
+{
+       struct tda_state *state = fe->tuner_priv;
+       int status = 0;
+       int Standard;
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       u32 delsys  = fe->dtv_property_cache.delivery_system;
+
+       state->m_Frequency = fe->dtv_property_cache.frequency;
+
+       switch (delsys) {
+       case  SYS_DVBT:
+       case  SYS_DVBT2:
+               switch (bw) {
+               case 6000000:
+                       Standard = HF_DVBT_6MHZ;
+                       break;
+               case 7000000:
+                       Standard = HF_DVBT_7MHZ;
+                       break;
+               case 8000000:
+                       Standard = HF_DVBT_8MHZ;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               if (bw <= 6000000)
+                       Standard = HF_DVBC_6MHZ;
+               else if (bw <= 7000000)
+                       Standard = HF_DVBC_7MHZ;
+               else
+                       Standard = HF_DVBC_8MHZ;
+               break;
+       default:
+               return -EINVAL;
+       }
+       do {
+               status = RFTrackingFiltersCorrection(state, state->m_Frequency);
+               if (status < 0)
+                       break;
+               status = ChannelConfiguration(state, state->m_Frequency,
+                                             Standard);
+               if (status < 0)
+                       break;
+
+               msleep(state->m_SettlingTime);  /* Allow AGC's to settle down */
+       } while (0);
+       return status;
+}
+
+#if 0
+static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
+{
+       if (IFAgc < 500) {
+               /* Scale this from 0 to 50000 */
+               *pSignalStrength = IFAgc * 100;
+       } else {
+               /* Scale range 500-1500 to 50000-80000 */
+               *pSignalStrength = 50000 + (IFAgc - 500) * 30;
+       }
+
+       return 0;
+}
+#endif
+
+static int get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda_state *state = fe->tuner_priv;
+
+       *frequency = state->IF;
+       return 0;
+}
+
+static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       /* struct tda_state *state = fe->tuner_priv; */
+       /* *bandwidth = priv->bandwidth; */
+       return 0;
+}
+
+
+static struct dvb_tuner_ops tuner_ops = {
+       .info = {
+               .name = "NXP TDA18271C2D",
+               .frequency_min  =  47125000,
+               .frequency_max  = 865000000,
+               .frequency_step =     62500
+       },
+       .init              = init,
+       .sleep             = sleep,
+       .set_params        = set_params,
+       .release           = release,
+       .get_if_frequency  = get_if_frequency,
+       .get_bandwidth     = get_bandwidth,
+};
+
+struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
+                                        struct i2c_adapter *i2c, u8 adr)
+{
+       struct tda_state *state;
+
+       state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       fe->tuner_priv = state;
+       state->adr = adr;
+       state->i2c = i2c;
+       memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
+       reset(state);
+       InitCal(state);
+
+       return fe;
+}
+EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
+
+MODULE_DESCRIPTION("TDA18271C2 driver");
+MODULE_AUTHOR("DD");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h
new file mode 100644 (file)
index 0000000..1389c74
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _TDA18271C2DD_H_
+#define _TDA18271C2DD_H_
+#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
+        && defined(MODULE))
+struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
+                                        struct i2c_adapter *i2c, u8 adr);
+#else
+static inline struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
+                                        struct i2c_adapter *i2c, u8 adr)
+{
+        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+        return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
new file mode 100644 (file)
index 0000000..b87661b
--- /dev/null
@@ -0,0 +1,814 @@
+enum HF_S {
+       HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio,
+       HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ,
+       HF_DVBT, HF_ATSC,  HF_DVBC_6MHZ,  HF_DVBC_7MHZ,
+       HF_DVBC_8MHZ, HF_DVBC
+};
+
+struct SStandardParam m_StandardTable[] = {
+       {       0,        0, 0x00, 0x00 },    /* HF_None */
+       { 6000000,  7000000, 0x1D, 0x2C },    /* HF_B, */
+       { 6900000,  8000000, 0x1E, 0x2C },    /* HF_DK, */
+       { 7100000,  8000000, 0x1E, 0x2C },    /* HF_G, */
+       { 7250000,  8000000, 0x1E, 0x2C },    /* HF_I, */
+       { 6900000,  8000000, 0x1E, 0x2C },    /* HF_L, */
+       { 1250000,  8000000, 0x1E, 0x2C },    /* HF_L1, */
+       { 5400000,  6000000, 0x1C, 0x2C },    /* HF_MN, */
+       { 1250000,   500000, 0x18, 0x2C },    /* HF_FM_Radio, */
+       {       0,        0, 0x00, 0x00 },    /* HF_AnalogMax (Unused) */
+       { 3300000,  6000000, 0x1C, 0x58 },    /* HF_DVBT_6MHZ */
+       { 3500000,  7000000, 0x1C, 0x37 },    /* HF_DVBT_7MHZ */
+       { 4000000,  8000000, 0x1D, 0x37 },    /* HF_DVBT_8MHZ */
+       {       0,        0, 0x00, 0x00 },    /* HF_DVBT (Unused) */
+       { 5000000,  6000000, 0x1C, 0x37 },    /* HF_ATSC  (center = 3.25 MHz) */
+       { 4000000,  6000000, 0x1D, 0x58 },    /* HF_DVBC_6MHZ (Chicago) */
+       { 4500000,  7000000, 0x1E, 0x37 },    /* HF_DVBC_7MHZ (not documented by NXP) */
+       { 5000000,  8000000, 0x1F, 0x37 },    /* HF_DVBC_8MHZ */
+       {       0,        0, 0x00, 0x00 },    /* HF_DVBC (Unused) */
+};
+
+struct SMap  m_BP_Filter_Map[] = {
+       {   62000000,  0x00 },
+       {   84000000,  0x01 },
+       {  100000000,  0x02 },
+       {  140000000,  0x03 },
+       {  170000000,  0x04 },
+       {  180000000,  0x05 },
+       {  865000000,  0x06 },
+       {          0,  0x00 },    /* Table End */
+};
+
+static struct SMapI m_RF_Cal_Map[] = {
+       {   41000000,  0x0F },
+       {   43000000,  0x1C },
+       {   45000000,  0x2F },
+       {   46000000,  0x39 },
+       {   47000000,  0x40 },
+       {   47900000,  0x50 },
+       {   49100000,  0x16 },
+       {   50000000,  0x18 },
+       {   51000000,  0x20 },
+       {   53000000,  0x28 },
+       {   55000000,  0x2B },
+       {   56000000,  0x32 },
+       {   57000000,  0x35 },
+       {   58000000,  0x3E },
+       {   59000000,  0x43 },
+       {   60000000,  0x4E },
+       {   61100000,  0x55 },
+       {   63000000,  0x0F },
+       {   64000000,  0x11 },
+       {   65000000,  0x12 },
+       {   66000000,  0x15 },
+       {   67000000,  0x16 },
+       {   68000000,  0x17 },
+       {   70000000,  0x19 },
+       {   71000000,  0x1C },
+       {   72000000,  0x1D },
+       {   73000000,  0x1F },
+       {   74000000,  0x20 },
+       {   75000000,  0x21 },
+       {   76000000,  0x24 },
+       {   77000000,  0x25 },
+       {   78000000,  0x27 },
+       {   80000000,  0x28 },
+       {   81000000,  0x29 },
+       {   82000000,  0x2D },
+       {   83000000,  0x2E },
+       {   84000000,  0x2F },
+       {   85000000,  0x31 },
+       {   86000000,  0x33 },
+       {   87000000,  0x34 },
+       {   88000000,  0x35 },
+       {   89000000,  0x37 },
+       {   90000000,  0x38 },
+       {   91000000,  0x39 },
+       {   93000000,  0x3C },
+       {   94000000,  0x3E },
+       {   95000000,  0x3F },
+       {   96000000,  0x40 },
+       {   97000000,  0x42 },
+       {   99000000,  0x45 },
+       {  100000000,  0x46 },
+       {  102000000,  0x48 },
+       {  103000000,  0x4A },
+       {  105000000,  0x4D },
+       {  106000000,  0x4E },
+       {  107000000,  0x50 },
+       {  108000000,  0x51 },
+       {  110000000,  0x54 },
+       {  111000000,  0x56 },
+       {  112000000,  0x57 },
+       {  113000000,  0x58 },
+       {  114000000,  0x59 },
+       {  115000000,  0x5C },
+       {  116000000,  0x5D },
+       {  117000000,  0x5F },
+       {  119000000,  0x60 },
+       {  120000000,  0x64 },
+       {  121000000,  0x65 },
+       {  122000000,  0x66 },
+       {  123000000,  0x68 },
+       {  124000000,  0x69 },
+       {  125000000,  0x6C },
+       {  126000000,  0x6D },
+       {  127000000,  0x6E },
+       {  128000000,  0x70 },
+       {  129000000,  0x71 },
+       {  130000000,  0x75 },
+       {  131000000,  0x77 },
+       {  132000000,  0x78 },
+       {  133000000,  0x7B },
+       {  134000000,  0x7E },
+       {  135000000,  0x81 },
+       {  136000000,  0x82 },
+       {  137000000,  0x87 },
+       {  138000000,  0x88 },
+       {  139000000,  0x8D },
+       {  140000000,  0x8E },
+       {  141000000,  0x91 },
+       {  142000000,  0x95 },
+       {  143000000,  0x9A },
+       {  144000000,  0x9D },
+       {  145000000,  0xA1 },
+       {  146000000,  0xA2 },
+       {  147000000,  0xA4 },
+       {  148000000,  0xA9 },
+       {  149000000,  0xAE },
+       {  150000000,  0xB0 },
+       {  151000000,  0xB1 },
+       {  152000000,  0xB7 },
+       {  152600000,  0xBD },
+       {  154000000,  0x20 },
+       {  155000000,  0x22 },
+       {  156000000,  0x24 },
+       {  157000000,  0x25 },
+       {  158000000,  0x27 },
+       {  159000000,  0x29 },
+       {  160000000,  0x2C },
+       {  161000000,  0x2D },
+       {  163000000,  0x2E },
+       {  164000000,  0x2F },
+       {  164700000,  0x30 },
+       {  166000000,  0x11 },
+       {  167000000,  0x12 },
+       {  168000000,  0x13 },
+       {  169000000,  0x14 },
+       {  170000000,  0x15 },
+       {  172000000,  0x16 },
+       {  173000000,  0x17 },
+       {  174000000,  0x18 },
+       {  175000000,  0x1A },
+       {  176000000,  0x1B },
+       {  178000000,  0x1D },
+       {  179000000,  0x1E },
+       {  180000000,  0x1F },
+       {  181000000,  0x20 },
+       {  182000000,  0x21 },
+       {  183000000,  0x22 },
+       {  184000000,  0x24 },
+       {  185000000,  0x25 },
+       {  186000000,  0x26 },
+       {  187000000,  0x27 },
+       {  188000000,  0x29 },
+       {  189000000,  0x2A },
+       {  190000000,  0x2C },
+       {  191000000,  0x2D },
+       {  192000000,  0x2E },
+       {  193000000,  0x2F },
+       {  194000000,  0x30 },
+       {  195000000,  0x33 },
+       {  196000000,  0x35 },
+       {  198000000,  0x36 },
+       {  200000000,  0x38 },
+       {  201000000,  0x3C },
+       {  202000000,  0x3D },
+       {  203500000,  0x3E },
+       {  206000000,  0x0E },
+       {  208000000,  0x0F },
+       {  212000000,  0x10 },
+       {  216000000,  0x11 },
+       {  217000000,  0x12 },
+       {  218000000,  0x13 },
+       {  220000000,  0x14 },
+       {  222000000,  0x15 },
+       {  225000000,  0x16 },
+       {  228000000,  0x17 },
+       {  231000000,  0x18 },
+       {  234000000,  0x19 },
+       {  235000000,  0x1A },
+       {  236000000,  0x1B },
+       {  237000000,  0x1C },
+       {  240000000,  0x1D },
+       {  242000000,  0x1E },
+       {  244000000,  0x1F },
+       {  247000000,  0x20 },
+       {  249000000,  0x21 },
+       {  252000000,  0x22 },
+       {  253000000,  0x23 },
+       {  254000000,  0x24 },
+       {  256000000,  0x25 },
+       {  259000000,  0x26 },
+       {  262000000,  0x27 },
+       {  264000000,  0x28 },
+       {  267000000,  0x29 },
+       {  269000000,  0x2A },
+       {  271000000,  0x2B },
+       {  273000000,  0x2C },
+       {  275000000,  0x2D },
+       {  277000000,  0x2E },
+       {  279000000,  0x2F },
+       {  282000000,  0x30 },
+       {  284000000,  0x31 },
+       {  286000000,  0x32 },
+       {  287000000,  0x33 },
+       {  290000000,  0x34 },
+       {  293000000,  0x35 },
+       {  295000000,  0x36 },
+       {  297000000,  0x37 },
+       {  300000000,  0x38 },
+       {  303000000,  0x39 },
+       {  305000000,  0x3A },
+       {  306000000,  0x3B },
+       {  307000000,  0x3C },
+       {  310000000,  0x3D },
+       {  312000000,  0x3E },
+       {  315000000,  0x3F },
+       {  318000000,  0x40 },
+       {  320000000,  0x41 },
+       {  323000000,  0x42 },
+       {  324000000,  0x43 },
+       {  325000000,  0x44 },
+       {  327000000,  0x45 },
+       {  331000000,  0x46 },
+       {  334000000,  0x47 },
+       {  337000000,  0x48 },
+       {  339000000,  0x49 },
+       {  340000000,  0x4A },
+       {  341000000,  0x4B },
+       {  343000000,  0x4C },
+       {  345000000,  0x4D },
+       {  349000000,  0x4E },
+       {  352000000,  0x4F },
+       {  353000000,  0x50 },
+       {  355000000,  0x51 },
+       {  357000000,  0x52 },
+       {  359000000,  0x53 },
+       {  361000000,  0x54 },
+       {  362000000,  0x55 },
+       {  364000000,  0x56 },
+       {  368000000,  0x57 },
+       {  370000000,  0x58 },
+       {  372000000,  0x59 },
+       {  375000000,  0x5A },
+       {  376000000,  0x5B },
+       {  377000000,  0x5C },
+       {  379000000,  0x5D },
+       {  382000000,  0x5E },
+       {  384000000,  0x5F },
+       {  385000000,  0x60 },
+       {  386000000,  0x61 },
+       {  388000000,  0x62 },
+       {  390000000,  0x63 },
+       {  393000000,  0x64 },
+       {  394000000,  0x65 },
+       {  396000000,  0x66 },
+       {  397000000,  0x67 },
+       {  398000000,  0x68 },
+       {  400000000,  0x69 },
+       {  402000000,  0x6A },
+       {  403000000,  0x6B },
+       {  407000000,  0x6C },
+       {  408000000,  0x6D },
+       {  409000000,  0x6E },
+       {  410000000,  0x6F },
+       {  411000000,  0x70 },
+       {  412000000,  0x71 },
+       {  413000000,  0x72 },
+       {  414000000,  0x73 },
+       {  417000000,  0x74 },
+       {  418000000,  0x75 },
+       {  420000000,  0x76 },
+       {  422000000,  0x77 },
+       {  423000000,  0x78 },
+       {  424000000,  0x79 },
+       {  427000000,  0x7A },
+       {  428000000,  0x7B },
+       {  429000000,  0x7D },
+       {  432000000,  0x7F },
+       {  434000000,  0x80 },
+       {  435000000,  0x81 },
+       {  436000000,  0x83 },
+       {  437000000,  0x84 },
+       {  438000000,  0x85 },
+       {  439000000,  0x86 },
+       {  440000000,  0x87 },
+       {  441000000,  0x88 },
+       {  442000000,  0x89 },
+       {  445000000,  0x8A },
+       {  446000000,  0x8B },
+       {  447000000,  0x8C },
+       {  448000000,  0x8E },
+       {  449000000,  0x8F },
+       {  450000000,  0x90 },
+       {  452000000,  0x91 },
+       {  453000000,  0x93 },
+       {  454000000,  0x94 },
+       {  456000000,  0x96 },
+       {  457800000,  0x98 },
+       {  461000000,  0x11 },
+       {  468000000,  0x12 },
+       {  472000000,  0x13 },
+       {  473000000,  0x14 },
+       {  474000000,  0x15 },
+       {  481000000,  0x16 },
+       {  486000000,  0x17 },
+       {  491000000,  0x18 },
+       {  498000000,  0x19 },
+       {  499000000,  0x1A },
+       {  501000000,  0x1B },
+       {  506000000,  0x1C },
+       {  511000000,  0x1D },
+       {  516000000,  0x1E },
+       {  520000000,  0x1F },
+       {  521000000,  0x20 },
+       {  525000000,  0x21 },
+       {  529000000,  0x22 },
+       {  533000000,  0x23 },
+       {  539000000,  0x24 },
+       {  541000000,  0x25 },
+       {  547000000,  0x26 },
+       {  549000000,  0x27 },
+       {  551000000,  0x28 },
+       {  556000000,  0x29 },
+       {  561000000,  0x2A },
+       {  563000000,  0x2B },
+       {  565000000,  0x2C },
+       {  569000000,  0x2D },
+       {  571000000,  0x2E },
+       {  577000000,  0x2F },
+       {  580000000,  0x30 },
+       {  582000000,  0x31 },
+       {  584000000,  0x32 },
+       {  588000000,  0x33 },
+       {  591000000,  0x34 },
+       {  596000000,  0x35 },
+       {  598000000,  0x36 },
+       {  603000000,  0x37 },
+       {  604000000,  0x38 },
+       {  606000000,  0x39 },
+       {  612000000,  0x3A },
+       {  615000000,  0x3B },
+       {  617000000,  0x3C },
+       {  621000000,  0x3D },
+       {  622000000,  0x3E },
+       {  625000000,  0x3F },
+       {  632000000,  0x40 },
+       {  633000000,  0x41 },
+       {  634000000,  0x42 },
+       {  642000000,  0x43 },
+       {  643000000,  0x44 },
+       {  647000000,  0x45 },
+       {  650000000,  0x46 },
+       {  652000000,  0x47 },
+       {  657000000,  0x48 },
+       {  661000000,  0x49 },
+       {  662000000,  0x4A },
+       {  665000000,  0x4B },
+       {  667000000,  0x4C },
+       {  670000000,  0x4D },
+       {  673000000,  0x4E },
+       {  676000000,  0x4F },
+       {  677000000,  0x50 },
+       {  681000000,  0x51 },
+       {  683000000,  0x52 },
+       {  686000000,  0x53 },
+       {  688000000,  0x54 },
+       {  689000000,  0x55 },
+       {  691000000,  0x56 },
+       {  695000000,  0x57 },
+       {  698000000,  0x58 },
+       {  703000000,  0x59 },
+       {  704000000,  0x5A },
+       {  705000000,  0x5B },
+       {  707000000,  0x5C },
+       {  710000000,  0x5D },
+       {  712000000,  0x5E },
+       {  717000000,  0x5F },
+       {  718000000,  0x60 },
+       {  721000000,  0x61 },
+       {  722000000,  0x62 },
+       {  723000000,  0x63 },
+       {  725000000,  0x64 },
+       {  727000000,  0x65 },
+       {  730000000,  0x66 },
+       {  732000000,  0x67 },
+       {  735000000,  0x68 },
+       {  740000000,  0x69 },
+       {  741000000,  0x6A },
+       {  742000000,  0x6B },
+       {  743000000,  0x6C },
+       {  745000000,  0x6D },
+       {  747000000,  0x6E },
+       {  748000000,  0x6F },
+       {  750000000,  0x70 },
+       {  752000000,  0x71 },
+       {  754000000,  0x72 },
+       {  757000000,  0x73 },
+       {  758000000,  0x74 },
+       {  760000000,  0x75 },
+       {  763000000,  0x76 },
+       {  764000000,  0x77 },
+       {  766000000,  0x78 },
+       {  767000000,  0x79 },
+       {  768000000,  0x7A },
+       {  773000000,  0x7B },
+       {  774000000,  0x7C },
+       {  776000000,  0x7D },
+       {  777000000,  0x7E },
+       {  778000000,  0x7F },
+       {  779000000,  0x80 },
+       {  781000000,  0x81 },
+       {  783000000,  0x82 },
+       {  784000000,  0x83 },
+       {  785000000,  0x84 },
+       {  786000000,  0x85 },
+       {  793000000,  0x86 },
+       {  794000000,  0x87 },
+       {  795000000,  0x88 },
+       {  797000000,  0x89 },
+       {  799000000,  0x8A },
+       {  801000000,  0x8B },
+       {  802000000,  0x8C },
+       {  803000000,  0x8D },
+       {  804000000,  0x8E },
+       {  810000000,  0x90 },
+       {  811000000,  0x91 },
+       {  812000000,  0x92 },
+       {  814000000,  0x93 },
+       {  816000000,  0x94 },
+       {  817000000,  0x96 },
+       {  818000000,  0x97 },
+       {  820000000,  0x98 },
+       {  821000000,  0x99 },
+       {  822000000,  0x9A },
+       {  828000000,  0x9B },
+       {  829000000,  0x9D },
+       {  830000000,  0x9F },
+       {  831000000,  0xA0 },
+       {  833000000,  0xA1 },
+       {  835000000,  0xA2 },
+       {  836000000,  0xA3 },
+       {  837000000,  0xA4 },
+       {  838000000,  0xA6 },
+       {  840000000,  0xA8 },
+       {  842000000,  0xA9 },
+       {  845000000,  0xAA },
+       {  846000000,  0xAB },
+       {  847000000,  0xAD },
+       {  848000000,  0xAE },
+       {  852000000,  0xAF },
+       {  853000000,  0xB0 },
+       {  858000000,  0xB1 },
+       {  860000000,  0xB2 },
+       {  861000000,  0xB3 },
+       {  862000000,  0xB4 },
+       {  863000000,  0xB6 },
+       {  864000000,  0xB8 },
+       {  865000000,  0xB9 },
+       {          0,  0x00 },    /* Table End */
+};
+
+
+static struct SMap2  m_KM_Map[] = {
+       {   47900000,  3, 2 },
+       {   61100000,  3, 1 },
+       {  350000000,  3, 0 },
+       {  720000000,  2, 1 },
+       {  865000000,  3, 3 },
+       {          0,  0x00 },    /* Table End */
+};
+
+static struct SMap2 m_Main_PLL_Map[] = {
+       {  33125000, 0x57, 0xF0 },
+       {  35500000, 0x56, 0xE0 },
+       {  38188000, 0x55, 0xD0 },
+       {  41375000, 0x54, 0xC0 },
+       {  45125000, 0x53, 0xB0 },
+       {  49688000, 0x52, 0xA0 },
+       {  55188000, 0x51, 0x90 },
+       {  62125000, 0x50, 0x80 },
+       {  66250000, 0x47, 0x78 },
+       {  71000000, 0x46, 0x70 },
+       {  76375000, 0x45, 0x68 },
+       {  82750000, 0x44, 0x60 },
+       {  90250000, 0x43, 0x58 },
+       {  99375000, 0x42, 0x50 },
+       { 110375000, 0x41, 0x48 },
+       { 124250000, 0x40, 0x40 },
+       { 132500000, 0x37, 0x3C },
+       { 142000000, 0x36, 0x38 },
+       { 152750000, 0x35, 0x34 },
+       { 165500000, 0x34, 0x30 },
+       { 180500000, 0x33, 0x2C },
+       { 198750000, 0x32, 0x28 },
+       { 220750000, 0x31, 0x24 },
+       { 248500000, 0x30, 0x20 },
+       { 265000000, 0x27, 0x1E },
+       { 284000000, 0x26, 0x1C },
+       { 305500000, 0x25, 0x1A },
+       { 331000000, 0x24, 0x18 },
+       { 361000000, 0x23, 0x16 },
+       { 397500000, 0x22, 0x14 },
+       { 441500000, 0x21, 0x12 },
+       { 497000000, 0x20, 0x10 },
+       { 530000000, 0x17, 0x0F },
+       { 568000000, 0x16, 0x0E },
+       { 611000000, 0x15, 0x0D },
+       { 662000000, 0x14, 0x0C },
+       { 722000000, 0x13, 0x0B },
+       { 795000000, 0x12, 0x0A },
+       { 883000000, 0x11, 0x09 },
+       { 994000000, 0x10, 0x08 },
+       {         0, 0x00, 0x00 },    /* Table End */
+};
+
+static struct SMap2 m_Cal_PLL_Map[] = {
+       {  33813000, 0xDD, 0xD0 },
+       {  36625000, 0xDC, 0xC0 },
+       {  39938000, 0xDB, 0xB0 },
+       {  43938000, 0xDA, 0xA0 },
+       {  48813000, 0xD9, 0x90 },
+       {  54938000, 0xD8, 0x80 },
+       {  62813000, 0xD3, 0x70 },
+       {  67625000, 0xCD, 0x68 },
+       {  73250000, 0xCC, 0x60 },
+       {  79875000, 0xCB, 0x58 },
+       {  87875000, 0xCA, 0x50 },
+       {  97625000, 0xC9, 0x48 },
+       { 109875000, 0xC8, 0x40 },
+       { 125625000, 0xC3, 0x38 },
+       { 135250000, 0xBD, 0x34 },
+       { 146500000, 0xBC, 0x30 },
+       { 159750000, 0xBB, 0x2C },
+       { 175750000, 0xBA, 0x28 },
+       { 195250000, 0xB9, 0x24 },
+       { 219750000, 0xB8, 0x20 },
+       { 251250000, 0xB3, 0x1C },
+       { 270500000, 0xAD, 0x1A },
+       { 293000000, 0xAC, 0x18 },
+       { 319500000, 0xAB, 0x16 },
+       { 351500000, 0xAA, 0x14 },
+       { 390500000, 0xA9, 0x12 },
+       { 439500000, 0xA8, 0x10 },
+       { 502500000, 0xA3, 0x0E },
+       { 541000000, 0x9D, 0x0D },
+       { 586000000, 0x9C, 0x0C },
+       { 639000000, 0x9B, 0x0B },
+       { 703000000, 0x9A, 0x0A },
+       { 781000000, 0x99, 0x09 },
+       { 879000000, 0x98, 0x08 },
+       {         0, 0x00, 0x00 },    /* Table End */
+};
+
+static struct SMap  m_GainTaper_Map[] = {
+       {  45400000, 0x1F },
+       {  45800000, 0x1E },
+       {  46200000, 0x1D },
+       {  46700000, 0x1C },
+       {  47100000, 0x1B },
+       {  47500000, 0x1A },
+       {  47900000, 0x19 },
+       {  49600000, 0x17 },
+       {  51200000, 0x16 },
+       {  52900000, 0x15 },
+       {  54500000, 0x14 },
+       {  56200000, 0x13 },
+       {  57800000, 0x12 },
+       {  59500000, 0x11 },
+       {  61100000, 0x10 },
+       {  67600000, 0x0D },
+       {  74200000, 0x0C },
+       {  80700000, 0x0B },
+       {  87200000, 0x0A },
+       {  93800000, 0x09 },
+       { 100300000, 0x08 },
+       { 106900000, 0x07 },
+       { 113400000, 0x06 },
+       { 119900000, 0x05 },
+       { 126500000, 0x04 },
+       { 133000000, 0x03 },
+       { 139500000, 0x02 },
+       { 146100000, 0x01 },
+       { 152600000, 0x00 },
+       { 154300000, 0x1F },
+       { 156100000, 0x1E },
+       { 157800000, 0x1D },
+       { 159500000, 0x1C },
+       { 161200000, 0x1B },
+       { 163000000, 0x1A },
+       { 164700000, 0x19 },
+       { 170200000, 0x17 },
+       { 175800000, 0x16 },
+       { 181300000, 0x15 },
+       { 186900000, 0x14 },
+       { 192400000, 0x13 },
+       { 198000000, 0x12 },
+       { 203500000, 0x11 },
+       { 216200000, 0x14 },
+       { 228900000, 0x13 },
+       { 241600000, 0x12 },
+       { 254400000, 0x11 },
+       { 267100000, 0x10 },
+       { 279800000, 0x0F },
+       { 292500000, 0x0E },
+       { 305200000, 0x0D },
+       { 317900000, 0x0C },
+       { 330700000, 0x0B },
+       { 343400000, 0x0A },
+       { 356100000, 0x09 },
+       { 368800000, 0x08 },
+       { 381500000, 0x07 },
+       { 394200000, 0x06 },
+       { 406900000, 0x05 },
+       { 419700000, 0x04 },
+       { 432400000, 0x03 },
+       { 445100000, 0x02 },
+       { 457800000, 0x01 },
+       { 476300000, 0x19 },
+       { 494800000, 0x18 },
+       { 513300000, 0x17 },
+       { 531800000, 0x16 },
+       { 550300000, 0x15 },
+       { 568900000, 0x14 },
+       { 587400000, 0x13 },
+       { 605900000, 0x12 },
+       { 624400000, 0x11 },
+       { 642900000, 0x10 },
+       { 661400000, 0x0F },
+       { 679900000, 0x0E },
+       { 698400000, 0x0D },
+       { 716900000, 0x0C },
+       { 735400000, 0x0B },
+       { 753900000, 0x0A },
+       { 772500000, 0x09 },
+       { 791000000, 0x08 },
+       { 809500000, 0x07 },
+       { 828000000, 0x06 },
+       { 846500000, 0x05 },
+       { 865000000, 0x04 },
+       {         0, 0x00 },    /* Table End */
+};
+
+static struct SMap m_RF_Cal_DC_Over_DT_Map[] = {
+       {  47900000, 0x00 },
+       {  55000000, 0x00 },
+       {  61100000, 0x0A },
+       {  64000000, 0x0A },
+       {  82000000, 0x14 },
+       {  84000000, 0x19 },
+       { 119000000, 0x1C },
+       { 124000000, 0x20 },
+       { 129000000, 0x2A },
+       { 134000000, 0x32 },
+       { 139000000, 0x39 },
+       { 144000000, 0x3E },
+       { 149000000, 0x3F },
+       { 152600000, 0x40 },
+       { 154000000, 0x40 },
+       { 164700000, 0x41 },
+       { 203500000, 0x32 },
+       { 353000000, 0x19 },
+       { 356000000, 0x1A },
+       { 359000000, 0x1B },
+       { 363000000, 0x1C },
+       { 366000000, 0x1D },
+       { 369000000, 0x1E },
+       { 373000000, 0x1F },
+       { 376000000, 0x20 },
+       { 379000000, 0x21 },
+       { 383000000, 0x22 },
+       { 386000000, 0x23 },
+       { 389000000, 0x24 },
+       { 393000000, 0x25 },
+       { 396000000, 0x26 },
+       { 399000000, 0x27 },
+       { 402000000, 0x28 },
+       { 404000000, 0x29 },
+       { 407000000, 0x2A },
+       { 409000000, 0x2B },
+       { 412000000, 0x2C },
+       { 414000000, 0x2D },
+       { 417000000, 0x2E },
+       { 419000000, 0x2F },
+       { 422000000, 0x30 },
+       { 424000000, 0x31 },
+       { 427000000, 0x32 },
+       { 429000000, 0x33 },
+       { 432000000, 0x34 },
+       { 434000000, 0x35 },
+       { 437000000, 0x36 },
+       { 439000000, 0x37 },
+       { 442000000, 0x38 },
+       { 444000000, 0x39 },
+       { 447000000, 0x3A },
+       { 449000000, 0x3B },
+       { 457800000, 0x3C },
+       { 465000000, 0x0F },
+       { 477000000, 0x12 },
+       { 483000000, 0x14 },
+       { 502000000, 0x19 },
+       { 508000000, 0x1B },
+       { 519000000, 0x1C },
+       { 522000000, 0x1D },
+       { 524000000, 0x1E },
+       { 534000000, 0x1F },
+       { 549000000, 0x20 },
+       { 554000000, 0x22 },
+       { 584000000, 0x24 },
+       { 589000000, 0x26 },
+       { 658000000, 0x27 },
+       { 664000000, 0x2C },
+       { 669000000, 0x2D },
+       { 699000000, 0x2E },
+       { 704000000, 0x30 },
+       { 709000000, 0x31 },
+       { 714000000, 0x32 },
+       { 724000000, 0x33 },
+       { 729000000, 0x36 },
+       { 739000000, 0x38 },
+       { 744000000, 0x39 },
+       { 749000000, 0x3B },
+       { 754000000, 0x3C },
+       { 759000000, 0x3D },
+       { 764000000, 0x3E },
+       { 769000000, 0x3F },
+       { 774000000, 0x40 },
+       { 779000000, 0x41 },
+       { 784000000, 0x43 },
+       { 789000000, 0x46 },
+       { 794000000, 0x48 },
+       { 799000000, 0x4B },
+       { 804000000, 0x4F },
+       { 809000000, 0x54 },
+       { 814000000, 0x59 },
+       { 819000000, 0x5D },
+       { 824000000, 0x61 },
+       { 829000000, 0x68 },
+       { 834000000, 0x6E },
+       { 839000000, 0x75 },
+       { 844000000, 0x7E },
+       { 849000000, 0x82 },
+       { 854000000, 0x84 },
+       { 859000000, 0x8F },
+       { 865000000, 0x9A },
+       {         0, 0x00 },    /* Table End */
+};
+
+
+static struct SMap  m_IR_Meas_Map[] = {
+       { 200000000, 0x05 },
+       { 400000000, 0x06 },
+       { 865000000, 0x07 },
+       {         0, 0x00 },    /* Table End */
+};
+
+static struct SMap2 m_CID_Target_Map[] = {
+       {  46000000, 0x04, 18 },
+       {  52200000, 0x0A, 15 },
+       {  70100000, 0x01, 40 },
+       { 136800000, 0x18, 40 },
+       { 156700000, 0x18, 40 },
+       { 186250000, 0x0A, 40 },
+       { 230000000, 0x0A, 40 },
+       { 345000000, 0x18, 40 },
+       { 426000000, 0x0E, 40 },
+       { 489500000, 0x1E, 40 },
+       { 697500000, 0x32, 40 },
+       { 842000000, 0x3A, 40 },
+       {         0, 0x00,  0 },    /* Table End */
+};
+
+static struct SRFBandMap  m_RF_Band_Map[7] = {
+       {   47900000,   46000000,           0,          0},
+       {   61100000,   52200000,           0,          0},
+       {  152600000,   70100000,   136800000,          0},
+       {  164700000,  156700000,           0,          0},
+       {  203500000,  186250000,           0,          0},
+       {  457800000,  230000000,   345000000,  426000000},
+       {  865000000,  489500000,   697500000,  842000000},
+};
+
+u8 m_Thermometer_Map_1[16] = {
+       60, 62, 66, 64,
+       74, 72, 68, 70,
+       90, 88, 84, 86,
+       76, 78, 82, 80,
+};
+
+u8 m_Thermometer_Map_2[16] = {
+       92, 94, 98, 96,
+       106, 104, 100, 102,
+       122, 120, 116, 118,
+       108, 110, 114, 112,
+};
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
new file mode 100644 (file)
index 0000000..2c1c759
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+       TDA665x tuner driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda665x.h"
+
+struct tda665x_state {
+       struct dvb_frontend             *fe;
+       struct i2c_adapter              *i2c;
+       const struct tda665x_config     *config;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+static int tda665x_read(struct tda665x_state *state, u8 *buf)
+{
+       const struct tda665x_config *config = state->config;
+       int err = 0;
+       struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
+
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1)
+               goto exit;
+
+       return err;
+exit:
+       printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
+       return err;
+}
+
+static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
+{
+       const struct tda665x_config *config = state->config;
+       int err = 0;
+       struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
+
+       err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1)
+               goto exit;
+
+       return err;
+exit:
+       printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
+       return err;
+}
+
+static int tda665x_get_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *tstate)
+{
+       struct tda665x_state *state = fe->tuner_priv;
+       int err = 0;
+
+       switch (param) {
+       case DVBFE_TUNER_FREQUENCY:
+               tstate->frequency = state->frequency;
+               break;
+       case DVBFE_TUNER_BANDWIDTH:
+               break;
+       default:
+               printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
+               err = -EINVAL;
+               break;
+       }
+
+       return err;
+}
+
+static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct tda665x_state *state = fe->tuner_priv;
+       u8 result = 0;
+       int err = 0;
+
+       *status = 0;
+
+       err = tda665x_read(state, &result);
+       if (err < 0)
+               goto exit;
+
+       if ((result >> 6) & 0x01) {
+               printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
+               *status = 1;
+       }
+
+       return err;
+exit:
+       printk(KERN_ERR "%s: I/O Error\n", __func__);
+       return err;
+}
+
+static int tda665x_set_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *tstate)
+{
+       struct tda665x_state *state = fe->tuner_priv;
+       const struct tda665x_config *config = state->config;
+       u32 frequency, status = 0;
+       u8 buf[4];
+       int err = 0;
+
+       if (param & DVBFE_TUNER_FREQUENCY) {
+
+               frequency = tstate->frequency;
+               if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
+                       printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
+                       return -EINVAL;
+               }
+
+               frequency += config->frequency_offst;
+               frequency *= config->ref_multiplier;
+               frequency += config->ref_divider >> 1;
+               frequency /= config->ref_divider;
+
+               buf[0] = (u8) ((frequency & 0x7f00) >> 8);
+               buf[1] = (u8) (frequency & 0x00ff) >> 0;
+               buf[2] = 0x80 | 0x40 | 0x02;
+               buf[3] = 0x00;
+
+               /* restore frequency */
+               frequency = tstate->frequency;
+
+               if (frequency < 153000000) {
+                       /* VHF-L */
+                       buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
+                       if (frequency < 68000000)
+                               buf[3] |= 0x40; /* 83uA */
+                       if (frequency < 1040000000)
+                               buf[3] |= 0x60; /* 122uA */
+                       if (frequency < 1250000000)
+                               buf[3] |= 0x80; /* 163uA */
+                       else
+                               buf[3] |= 0xa0; /* 254uA */
+               } else if (frequency < 438000000) {
+                       /* VHF-H */
+                       buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
+                       if (frequency < 230000000)
+                               buf[3] |= 0x40;
+                       if (frequency < 300000000)
+                               buf[3] |= 0x60;
+                       else
+                               buf[3] |= 0x80;
+               } else {
+                       /* UHF */
+                       buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
+                       if (frequency < 470000000)
+                               buf[3] |= 0x60;
+                       if (frequency < 526000000)
+                               buf[3] |= 0x80;
+                       else
+                               buf[3] |= 0xa0;
+               }
+
+               /* Set params */
+               err = tda665x_write(state, buf, 5);
+               if (err < 0)
+                       goto exit;
+
+               /* sleep for some time */
+               printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
+               msleep(20);
+               /* check status */
+               err = tda665x_get_status(fe, &status);
+               if (err < 0)
+                       goto exit;
+
+               if (status == 1) {
+                       printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
+                       state->frequency = frequency; /* cache successful state */
+               } else {
+                       printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
+               }
+       } else {
+               printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
+               return -EINVAL;
+       }
+
+       return 0;
+exit:
+       printk(KERN_ERR "%s: I/O Error\n", __func__);
+       return err;
+}
+
+static int tda665x_release(struct dvb_frontend *fe)
+{
+       struct tda665x_state *state = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+       return 0;
+}
+
+static struct dvb_tuner_ops tda665x_ops = {
+
+       .set_state      = tda665x_set_state,
+       .get_state      = tda665x_get_state,
+       .get_status     = tda665x_get_status,
+       .release        = tda665x_release
+};
+
+struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+                                   const struct tda665x_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct tda665x_state *state = NULL;
+       struct dvb_tuner_info *info;
+
+       state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
+       if (state == NULL)
+               goto exit;
+
+       state->config           = config;
+       state->i2c              = i2c;
+       state->fe               = fe;
+       fe->tuner_priv          = state;
+       fe->ops.tuner_ops       = tda665x_ops;
+       info                     = &fe->ops.tuner_ops.info;
+
+       memcpy(info->name, config->name, sizeof(config->name));
+       info->frequency_min     = config->frequency_min;
+       info->frequency_max     = config->frequency_max;
+       info->frequency_step    = config->frequency_offst;
+
+       printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
+
+       return fe;
+
+exit:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(tda665x_attach);
+
+MODULE_DESCRIPTION("TDA665x driver");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda665x.h b/drivers/media/dvb-frontends/tda665x.h
new file mode 100644 (file)
index 0000000..ec7927a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+       TDA665x tuner driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TDA665x_H
+#define __TDA665x_H
+
+struct tda665x_config {
+       char name[128];
+
+       u8      addr;
+       u32     frequency_min;
+       u32     frequency_max;
+       u32     frequency_offst;
+       u32     ref_multiplier;
+       u32     ref_divider;
+};
+
+#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+                                          const struct tda665x_config *config,
+                                          struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
+                                                 const struct tda665x_config *config,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif /* CONFIG_DVB_TDA665x */
+
+#endif /* __TDA665x_H */
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
new file mode 100644 (file)
index 0000000..15912c9
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+    Driver for Philips TDA8083 based QPSK Demodulator
+
+    Copyright (C) 2001 Convergence Integrated Media GmbH
+
+    written by Ralph Metzler <ralph@convergence.de>
+
+    adoption to the new DVB frontend API and diagnostic ioctl's
+    by Holger Waechtler <holger@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include "dvb_frontend.h"
+#include "tda8083.h"
+
+
+struct tda8083_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct tda8083_config* config;
+       struct dvb_frontend frontend;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "tda8083: " args); \
+       } while (0)
+
+
+static u8 tda8083_init_tab [] = {
+       0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
+       0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
+       0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
+       0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
+       0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00
+};
+
+
+static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf [] = { reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
+                       __func__, reg, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
+{
+       int ret;
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
+                       __func__, reg1, ret);
+
+       return ret == 2 ? 0 : -1;
+}
+
+static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
+{
+       u8 val;
+
+       tda8083_readregs (state, reg, &val, 1);
+
+       return val;
+}
+
+static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
+{
+       /*  XXX FIXME: implement other modes than FEC_AUTO */
+       if (inversion == INVERSION_AUTO)
+               return 0;
+
+       return -EINVAL;
+}
+
+static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
+{
+       if (fec == FEC_AUTO)
+               return tda8083_writereg (state, 0x07, 0xff);
+
+       if (fec >= FEC_1_2 && fec <= FEC_8_9)
+               return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
+
+       return -EINVAL;
+}
+
+static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
+{
+       u8 index;
+       static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
+                                      FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
+
+       index = tda8083_readreg(state, 0x0e) & 0x07;
+
+       return fec_tab [index];
+}
+
+static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
+{
+       u32 ratio;
+       u32 tmp;
+       u8 filter;
+
+       if (srate > 32000000)
+               srate = 32000000;
+       if (srate < 500000)
+               srate = 500000;
+
+       filter = 0;
+       if (srate < 24000000)
+               filter = 2;
+       if (srate < 16000000)
+               filter = 3;
+
+       tmp = 31250 << 16;
+       ratio = tmp / srate;
+
+       tmp = (tmp % srate) << 8;
+       ratio = (ratio << 8) + tmp / srate;
+
+       tmp = (tmp % srate) << 8;
+       ratio = (ratio << 8) + tmp / srate;
+
+       dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
+
+       tda8083_writereg (state, 0x05, filter);
+       tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
+       tda8083_writereg (state, 0x03, (ratio >>  8) & 0xff);
+       tda8083_writereg (state, 0x04, (ratio      ) & 0xff);
+
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 1;
+}
+
+static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
+{
+       unsigned long start = jiffies;
+
+       while (jiffies - start < timeout &&
+              !(tda8083_readreg(state, 0x02) & 0x80))
+       {
+               msleep(50);
+       };
+}
+
+static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
+{
+       tda8083_writereg (state, 0x26, 0xf1);
+
+       switch (tone) {
+       case SEC_TONE_OFF:
+               return tda8083_writereg (state, 0x29, 0x00);
+       case SEC_TONE_ON:
+               return tda8083_writereg (state, 0x29, 0x80);
+       default:
+               return -EINVAL;
+       };
+}
+
+static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
+{
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               return tda8083_writereg (state, 0x20, 0x00);
+       case SEC_VOLTAGE_18:
+               return tda8083_writereg (state, 0x20, 0x11);
+       default:
+               return -EINVAL;
+       };
+}
+
+static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
+{
+       switch (burst) {
+       case SEC_MINI_A:
+               tda8083_writereg (state, 0x29, (5 << 2));  /* send burst A */
+               break;
+       case SEC_MINI_B:
+               tda8083_writereg (state, 0x29, (7 << 2));  /* send B */
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       tda8083_wait_diseqc_fifo (state, 100);
+
+       return 0;
+}
+
+static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
+                                   struct dvb_diseqc_master_cmd *m)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+       int i;
+
+       tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
+
+       for (i=0; i<m->msg_len; i++)
+               tda8083_writereg (state, 0x23 + i, m->msg[i]);
+
+       tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
+
+       tda8083_wait_diseqc_fifo (state, 100);
+
+       return 0;
+}
+
+static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       u8 signal = ~tda8083_readreg (state, 0x01);
+       u8 sync = tda8083_readreg (state, 0x02);
+
+       *status = 0;
+
+       if (signal > 10)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 0x01)
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 0x02)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 0x10)
+               *status |= FE_HAS_SYNC;
+
+       if (sync & 0x20) /* frontend can not lock */
+               *status |= FE_TIMEDOUT;
+
+       if ((sync & 0x1f) == 0x1f)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+       int ret;
+       u8 buf[3];
+
+       if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf))))
+               return ret;
+
+       *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
+
+       return 0;
+}
+
+static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       u8 signal = ~tda8083_readreg (state, 0x01);
+       *strength = (signal << 8) | signal;
+
+       return 0;
+}
+
+static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       u8 _snr = tda8083_readreg (state, 0x08);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       *ucblocks = tda8083_readreg(state, 0x0f);
+       if (*ucblocks == 0xff)
+               *ucblocks = 0xffffffff;
+
+       return 0;
+}
+
+static int tda8083_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       tda8083_set_inversion (state, p->inversion);
+       tda8083_set_fec(state, p->fec_inner);
+       tda8083_set_symbolrate(state, p->symbol_rate);
+
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 0;
+}
+
+static int tda8083_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       /*  FIXME: get symbolrate & frequency offset...*/
+       /*p->frequency = ???;*/
+       p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
+                       INVERSION_ON : INVERSION_OFF;
+       p->fec_inner = tda8083_get_fec(state);
+       /*p->symbol_rate = tda8083_get_symbolrate (state);*/
+
+       return 0;
+}
+
+static int tda8083_sleep(struct dvb_frontend* fe)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       tda8083_writereg (state, 0x00, 0x02);
+       return 0;
+}
+
+static int tda8083_init(struct dvb_frontend* fe)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+       int i;
+
+       for (i=0; i<44; i++)
+               tda8083_writereg (state, i, tda8083_init_tab[i]);
+
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 0;
+}
+
+static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       tda8083_send_diseqc_burst (state, burst);
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 0;
+}
+
+static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       tda8083_set_tone (state, tone);
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 0;
+}
+
+static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+
+       tda8083_set_voltage (state, voltage);
+       tda8083_writereg (state, 0x00, 0x3c);
+       tda8083_writereg (state, 0x00, 0x04);
+
+       return 0;
+}
+
+static void tda8083_release(struct dvb_frontend* fe)
+{
+       struct tda8083_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops tda8083_ops;
+
+struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct tda8083_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+
+       /* check if the demod is there */
+       if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops tda8083_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "Philips TDA8083 DVB-S",
+               .frequency_min          = 920000,     /* TDA8060 */
+               .frequency_max          = 2200000,    /* TDA8060 */
+               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
+       /*      .frequency_tolerance    = ???,*/
+               .symbol_rate_min        = 12000000,
+               .symbol_rate_max        = 30000000,
+       /*      .symbol_rate_tolerance  = ???,*/
+               .caps = FE_CAN_INVERSION_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_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_MUTE_TS
+       },
+
+       .release = tda8083_release,
+
+       .init = tda8083_init,
+       .sleep = tda8083_sleep,
+
+       .set_frontend = tda8083_set_frontend,
+       .get_frontend = tda8083_get_frontend,
+
+       .read_status = tda8083_read_status,
+       .read_signal_strength = tda8083_read_signal_strength,
+       .read_snr = tda8083_read_snr,
+       .read_ber = tda8083_read_ber,
+       .read_ucblocks = tda8083_read_ucblocks,
+
+       .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
+       .diseqc_send_burst = tda8083_diseqc_send_burst,
+       .set_tone = tda8083_diseqc_set_tone,
+       .set_voltage = tda8083_diseqc_set_voltage,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
+MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb-frontends/tda8083.h b/drivers/media/dvb-frontends/tda8083.h
new file mode 100644 (file)
index 0000000..5a03c14
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
+
+    Copyright (C) 2001 Convergence Integrated Media GmbH
+
+    written by Ralph Metzler <ralph@convergence.de>
+
+    adoption to the new DVB frontend API and diagnostic ioctl's
+    by Holger Waechtler <holger@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef TDA8083_H
+#define TDA8083_H
+
+#include <linux/dvb/frontend.h>
+
+struct tda8083_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA8083
+
+#endif // TDA8083_H
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
new file mode 100644 (file)
index 0000000..53c7d8f
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+       TDA8261 8PSK/QPSK tuner driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "tda8261.h"
+
+struct tda8261_state {
+       struct dvb_frontend             *fe;
+       struct i2c_adapter              *i2c;
+       const struct tda8261_config     *config;
+
+       /* state cache */
+       u32 frequency;
+       u32 bandwidth;
+};
+
+static int tda8261_read(struct tda8261_state *state, u8 *buf)
+{
+       const struct tda8261_config *config = state->config;
+       int err = 0;
+       struct i2c_msg msg = { .addr    = config->addr, .flags = I2C_M_RD,.buf = buf,  .len = 1 };
+
+       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
+               printk("%s: read error, err=%d\n", __func__, err);
+
+       return err;
+}
+
+static int tda8261_write(struct tda8261_state *state, u8 *buf)
+{
+       const struct tda8261_config *config = state->config;
+       int err = 0;
+       struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
+
+       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
+               printk("%s: write error, err=%d\n", __func__, err);
+
+       return err;
+}
+
+static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct tda8261_state *state = fe->tuner_priv;
+       u8 result = 0;
+       int err = 0;
+
+       *status = 0;
+
+       if ((err = tda8261_read(state, &result)) < 0) {
+               printk("%s: I/O Error\n", __func__);
+               return err;
+       }
+       if ((result >> 6) & 0x01) {
+               printk("%s: Tuner Phase Locked\n", __func__);
+               *status = 1;
+       }
+
+       return err;
+}
+
+static const u32 div_tab[] = { 2000, 1000,  500,  250,  125 }; /* kHz */
+static const u8  ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
+
+static int tda8261_get_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *tstate)
+{
+       struct tda8261_state *state = fe->tuner_priv;
+       int err = 0;
+
+       switch (param) {
+       case DVBFE_TUNER_FREQUENCY:
+               tstate->frequency = state->frequency;
+               break;
+       case DVBFE_TUNER_BANDWIDTH:
+               tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
+               break;
+       default:
+               printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+               err = -EINVAL;
+               break;
+       }
+
+       return err;
+}
+
+static int tda8261_set_state(struct dvb_frontend *fe,
+                            enum tuner_param param,
+                            struct tuner_state *tstate)
+{
+       struct tda8261_state *state = fe->tuner_priv;
+       const struct tda8261_config *config = state->config;
+       u32 frequency, N, status = 0;
+       u8 buf[4];
+       int err = 0;
+
+       if (param & DVBFE_TUNER_FREQUENCY) {
+               /**
+                * N = Max VCO Frequency / Channel Spacing
+                * Max VCO Frequency = VCO frequency + (channel spacing - 1)
+                * (to account for half channel spacing on either side)
+                */
+               frequency = tstate->frequency;
+               if ((frequency < 950000) || (frequency > 2150000)) {
+                       printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
+                       return -EINVAL;
+               }
+               N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
+               printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
+                       __func__, config->step_size, div_tab[config->step_size], N, N);
+
+               buf[0] = (N >> 8) & 0xff;
+               buf[1] = N & 0xff;
+               buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
+
+               if (frequency < 1450000)
+                       buf[3] = 0x00;
+               else if (frequency < 2000000)
+                       buf[3] = 0x40;
+               else if (frequency < 2150000)
+                       buf[3] = 0x80;
+
+               /* Set params */
+               if ((err = tda8261_write(state, buf)) < 0) {
+                       printk("%s: I/O Error\n", __func__);
+                       return err;
+               }
+               /* sleep for some time */
+               printk("%s: Waiting to Phase LOCK\n", __func__);
+               msleep(20);
+               /* check status */
+               if ((err = tda8261_get_status(fe, &status)) < 0) {
+                       printk("%s: I/O Error\n", __func__);
+                       return err;
+               }
+               if (status == 1) {
+                       printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
+                       state->frequency = frequency; /* cache successful state */
+               } else {
+                       printk("%s: No Phase lock: status=%d\n", __func__, status);
+               }
+       } else {
+               printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int tda8261_release(struct dvb_frontend *fe)
+{
+       struct tda8261_state *state = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+       return 0;
+}
+
+static struct dvb_tuner_ops tda8261_ops = {
+
+       .info = {
+               .name           = "TDA8261",
+//             .tuner_name     = NULL,
+               .frequency_min  =  950000,
+               .frequency_max  = 2150000,
+               .frequency_step = 0
+       },
+
+       .set_state      = tda8261_set_state,
+       .get_state      = tda8261_get_state,
+       .get_status     = tda8261_get_status,
+       .release        = tda8261_release
+};
+
+struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+                                   const struct tda8261_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct tda8261_state *state = NULL;
+
+       if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL)
+               goto exit;
+
+       state->config           = config;
+       state->i2c              = i2c;
+       state->fe               = fe;
+       fe->tuner_priv          = state;
+       fe->ops.tuner_ops       = tda8261_ops;
+
+       fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
+//     fe->ops.tuner_ops.tuner_name     = &config->buf;
+
+//     printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
+//             __func__, fe->ops.tuner_ops.tuner_name);
+       printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
+
+       return fe;
+
+exit:
+       kfree(state);
+       return NULL;
+}
+
+EXPORT_SYMBOL(tda8261_attach);
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda8261.h b/drivers/media/dvb-frontends/tda8261.h
new file mode 100644 (file)
index 0000000..006e453
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+       TDA8261 8PSK/QPSK tuner driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TDA8261_H
+#define __TDA8261_H
+
+enum tda8261_step {
+       TDA8261_STEP_2000 = 0,  /* 2000 kHz */
+       TDA8261_STEP_1000,      /* 1000 kHz */
+       TDA8261_STEP_500,       /*  500 kHz */
+       TDA8261_STEP_250,       /*  250 kHz */
+       TDA8261_STEP_125        /*  125 kHz */
+};
+
+struct tda8261_config {
+//     u8                      buf[16];
+       u8                      addr;
+       enum tda8261_step       step_size;
+};
+
+#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+                                          const struct tda8261_config *config,
+                                          struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+                                                 const struct tda8261_config *config,
+                                                 struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+#endif //CONFIG_DVB_TDA8261
+
+#endif// __TDA8261_H
diff --git a/drivers/media/dvb-frontends/tda8261_cfg.h b/drivers/media/dvb-frontends/tda8261_cfg.h
new file mode 100644 (file)
index 0000000..1af1ee4
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+       TDA8261 8PSK/QPSK tuner driver
+       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+               *frequency = t_state.frequency;
+               printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+       }
+       return 0;
+}
+
+static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+       struct dvb_frontend_ops *frontend_ops = NULL;
+       struct dvb_tuner_ops    *tuner_ops = NULL;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       t_state.frequency = frequency;
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->set_state) {
+               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+       }
+       printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+       return 0;
+}
+
+static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct dvb_frontend_ops *frontend_ops = &fe->ops;
+       struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
+       struct tuner_state      t_state;
+       int err = 0;
+
+       if (&fe->ops)
+               frontend_ops = &fe->ops;
+       if (&frontend_ops->tuner_ops)
+               tuner_ops = &frontend_ops->tuner_ops;
+       if (tuner_ops->get_state) {
+               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+                       printk("%s: Invalid parameter\n", __func__);
+                       return err;
+               }
+               *bandwidth = t_state.bandwidth;
+       }
+       printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
+       return 0;
+}
diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c
new file mode 100644 (file)
index 0000000..04bbcc2
--- /dev/null
@@ -0,0 +1,188 @@
+  /*
+     Driver for Philips tda8262/tda8263 DVBS Silicon tuners
+
+     (c) 2006 Andrew de Quincey
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+  */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "tda826x.h"
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "tda826x: " args); \
+       } while (0)
+
+struct tda826x_priv {
+       /* i2c details */
+       int i2c_address;
+       struct i2c_adapter *i2c;
+       u8 has_loopthrough:1;
+       u32 frequency;
+};
+
+static int tda826x_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int tda826x_sleep(struct dvb_frontend *fe)
+{
+       struct tda826x_priv *priv = fe->tuner_priv;
+       int ret;
+       u8 buf [] = { 0x00, 0x8d };
+       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
+
+       dprintk("%s:\n", __func__);
+
+       if (!priv->has_loopthrough)
+               buf[1] = 0xad;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+               dprintk("%s: i2c error\n", __func__);
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return (ret == 1) ? 0 : ret;
+}
+
+static int tda826x_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct tda826x_priv *priv = fe->tuner_priv;
+       int ret;
+       u32 div;
+       u32 ksyms;
+       u32 bandwidth;
+       u8 buf [11];
+       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
+
+       dprintk("%s:\n", __func__);
+
+       div = (p->frequency + (1000-1)) / 1000;
+
+       /* BW = ((1 + RO) * SR/2 + 5) * 1.3      [SR in MSPS, BW in MHz] */
+       /* with R0 = 0.35 and some transformations: */
+       ksyms = p->symbol_rate / 1000;
+       bandwidth = (878 * ksyms + 6500000) / 1000000 + 1;
+       if (bandwidth < 5)
+               bandwidth = 5;
+       else if (bandwidth > 36)
+               bandwidth = 36;
+
+       buf[0] = 0x00; // subaddress
+       buf[1] = 0x09; // powerdown RSSI + the magic value 1
+       if (!priv->has_loopthrough)
+               buf[1] |= 0x20; // power down loopthrough if not needed
+       buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
+       buf[3] = div >> 7;
+       buf[4] = div << 1;
+       buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */
+       buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
+       buf[7] = 0x83; // charge pumps at high, tests off
+       buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
+       buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
+       buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+               dprintk("%s: i2c error\n", __func__);
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       priv->frequency = div * 1000;
+
+       return (ret == 1) ? 0 : ret;
+}
+
+static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda826x_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tda826x_tuner_ops = {
+       .info = {
+               .name = "Philips TDA826X",
+               .frequency_min = 950000,
+               .frequency_max = 2175000
+       },
+       .release = tda826x_release,
+       .sleep = tda826x_sleep,
+       .set_params = tda826x_set_params,
+       .get_frequency = tda826x_get_frequency,
+};
+
+struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
+{
+       struct tda826x_priv *priv = NULL;
+       u8 b1 [] = { 0, 0 };
+       struct i2c_msg msg[2] = {
+               { .addr = addr, .flags = 0,        .buf = NULL, .len = 0 },
+               { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 }
+       };
+       int ret;
+
+       dprintk("%s:\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer (i2c, msg, 2);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret != 2)
+               return NULL;
+       if (!(b1[1] & 0x80))
+               return NULL;
+
+       priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c_address = addr;
+       priv->i2c = i2c;
+       priv->has_loopthrough = has_loopthrough;
+
+       memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       return fe;
+}
+EXPORT_SYMBOL(tda826x_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("DVB TDA826x driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h
new file mode 100644 (file)
index 0000000..89e9792
--- /dev/null
@@ -0,0 +1,53 @@
+  /*
+     Driver for Philips tda8262/tda8263 DVBS Silicon tuners
+
+     (c) 2006 Andrew de Quincey
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+  */
+
+#ifndef __DVB_TDA826X_H__
+#define __DVB_TDA826X_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a tda826x tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param addr i2c address of the tuner.
+ * @param i2c i2c adapter to use.
+ * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
+ * @return FE pointer on success, NULL on failure.
+ */
+#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
+                                          struct i2c_adapter *i2c,
+                                          int has_loopthrough);
+#else
+static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe,
+                                                 int addr,
+                                                 struct i2c_adapter *i2c,
+                                                 int has_loopthrough)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA826X
+
+#endif // __DVB_TDA826X_H__
diff --git a/drivers/media/dvb-frontends/tdhd1.h b/drivers/media/dvb-frontends/tdhd1.h
new file mode 100644 (file)
index 0000000..1775098
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * tdhd1.h - ALPS TDHD1-204A tuner support
+ *
+ * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de>
+ *
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * The project's page is at http://www.linuxtv.org
+ */
+
+#ifndef TDHD1_H
+#define TDHD1_H
+
+#include "tda1004x.h"
+
+static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name);
+
+static struct tda1004x_config alps_tdhd1_204a_config = {
+       .demod_address = 0x8,
+       .invert = 1,
+       .invert_oclk = 0,
+       .xtal_freq = TDA10046_XTAL_4M,
+       .agc_config = TDA10046_AGC_DEFAULT,
+       .if_freq = TDA10046_FREQ_3617,
+       .request_firmware = alps_tdhd1_204_request_firmware
+};
+
+static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct i2c_adapter *i2c = fe->tuner_priv;
+       u8 data[4];
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+       u32 div;
+
+       div = (p->frequency + 36166666) / 166666;
+
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x85;
+
+       if (p->frequency >= 174000000 && p->frequency <= 230000000)
+               data[3] = 0x02;
+       else if (p->frequency >= 470000000 && p->frequency <= 823000000)
+               data[3] = 0x0C;
+       else if (p->frequency > 823000000 && p->frequency <= 862000000)
+               data[3] = 0x8C;
+       else
+               return -EINVAL;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(i2c, &msg, 1) != 1)
+               return -EIO;
+
+       return 0;
+}
+
+#endif /* TDHD1_H */
diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c
new file mode 100644 (file)
index 0000000..029384d
--- /dev/null
@@ -0,0 +1,206 @@
+/**
+ * Driver for Infineon tua6100 pll.
+ *
+ * (c) 2006 Andrew de Quincey
+ *
+ * Based on code found in budget-av.c, which has the following:
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
+ *                               Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "tua6100.h"
+
+struct tua6100_priv {
+       /* i2c details */
+       int i2c_address;
+       struct i2c_adapter *i2c;
+       u32 frequency;
+};
+
+static int tua6100_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int tua6100_sleep(struct dvb_frontend *fe)
+{
+       struct tua6100_priv *priv = fe->tuner_priv;
+       int ret;
+       u8 reg0[] = { 0x00, 0x00 };
+       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
+               printk("%s: i2c error\n", __func__);
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return (ret == 1) ? 0 : ret;
+}
+
+static int tua6100_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct tua6100_priv *priv = fe->tuner_priv;
+       u32 div;
+       u32 prediv;
+       u8 reg0[] = { 0x00, 0x00 };
+       u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 };
+       u8 reg2[] = { 0x02, 0x00, 0x00 };
+       struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
+       struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
+       struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
+
+#define _R 4
+#define _P 32
+#define _ri 4000000
+
+       // setup register 0
+       if (c->frequency < 2000000)
+               reg0[1] = 0x03;
+       else
+               reg0[1] = 0x07;
+
+       // setup register 1
+       if (c->frequency < 1630000)
+               reg1[1] = 0x2c;
+       else
+               reg1[1] = 0x0c;
+
+       if (_P == 64)
+               reg1[1] |= 0x40;
+       if (c->frequency >= 1525000)
+               reg1[1] |= 0x80;
+
+       // register 2
+       reg2[1] = (_R >> 8) & 0x03;
+       reg2[2] = _R;
+       if (c->frequency < 1455000)
+               reg2[1] |= 0x1c;
+       else if (c->frequency < 1630000)
+               reg2[1] |= 0x0c;
+       else
+               reg2[1] |= 0x1c;
+
+       /*
+        * The N divisor ratio (note: c->frequency is in kHz, but we
+        * need it in Hz)
+        */
+       prediv = (c->frequency * _R) / (_ri / 1000);
+       div = prediv / _P;
+       reg1[1] |= (div >> 9) & 0x03;
+       reg1[2] = div >> 1;
+       reg1[3] = (div << 7);
+       priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
+
+       // Finally, calculate and store the value for A
+       reg1[3] |= (prediv - (div*_P)) & 0x7f;
+
+#undef _R
+#undef _P
+#undef _ri
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(priv->i2c, &msg0, 1) != 1)
+               return -EIO;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(priv->i2c, &msg2, 1) != 1)
+               return -EIO;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (i2c_transfer(priv->i2c, &msg1, 1) != 1)
+               return -EIO;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tua6100_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tua6100_tuner_ops = {
+       .info = {
+               .name = "Infineon TUA6100",
+               .frequency_min = 950000,
+               .frequency_max = 2150000,
+               .frequency_step = 1000,
+       },
+       .release = tua6100_release,
+       .sleep = tua6100_sleep,
+       .set_params = tua6100_set_params,
+       .get_frequency = tua6100_get_frequency,
+};
+
+struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
+{
+       struct tua6100_priv *priv = NULL;
+       u8 b1 [] = { 0x80 };
+       u8 b2 [] = { 0x00 };
+       struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 },
+                                 { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } };
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer (i2c, msg, 2);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret != 2)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c_address = addr;
+       priv->i2c = i2c;
+
+       memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(tua6100_attach);
+
+MODULE_DESCRIPTION("DVB tua6100 driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h
new file mode 100644 (file)
index 0000000..f83dbd5
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * Driver for Infineon tua6100 PLL.
+ *
+ * (c) 2006 Andrew de Quincey
+ *
+ * Based on code found in budget-av.c, which has the following:
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
+ *                               Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph  Metzler
+ *                       & Marcus Metzler for convergence integrated media GmbH
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DVB_TUA6100_H__
+#define __DVB_TUA6100_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TUA6100
+
+#endif
diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c
new file mode 100644 (file)
index 0000000..bb42b56
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+    VES1820  - Single Chip Cable Channel Receiver driver module
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "ves1820.h"
+
+
+
+struct ves1820_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct ves1820_config* config;
+       struct dvb_frontend frontend;
+
+       /* private demodulator data */
+       u8 reg0;
+       u8 pwm;
+};
+
+
+static int verbose;
+
+static u8 ves1820_inittab[] = {
+       0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A,
+       0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
+       0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x40
+};
+
+static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
+{
+       u8 buf[] = { 0x00, reg, data };
+       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
+       int ret;
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk("ves1820: %s(): writereg error (reg == 0x%02x, "
+                       "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret);
+
+       return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
+{
+       u8 b0[] = { 0x00, reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
+               {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
+       };
+       int ret;
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk("ves1820: %s(): readreg error (reg == 0x%02x, "
+               "ret == %i)\n", __func__, reg, ret);
+
+       return b1[0];
+}
+
+static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
+{
+       reg0 |= state->reg0 & 0x62;
+
+       if (INVERSION_ON == inversion) {
+               if (!state->config->invert) reg0 |= 0x20;
+               else reg0 &= ~0x20;
+       } else if (INVERSION_OFF == inversion) {
+               if (!state->config->invert) reg0 &= ~0x20;
+               else reg0 |= 0x20;
+       }
+
+       ves1820_writereg(state, 0x00, reg0 & 0xfe);
+       ves1820_writereg(state, 0x00, reg0 | 0x01);
+
+       state->reg0 = reg0;
+
+       return 0;
+}
+
+static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
+{
+       s32 BDR;
+       s32 BDRI;
+       s16 SFIL = 0;
+       u16 NDEC = 0;
+       u32 ratio;
+       u32 fin;
+       u32 tmp;
+       u64 fptmp;
+       u64 fpxin;
+
+       if (symbolrate > state->config->xin / 2)
+               symbolrate = state->config->xin / 2;
+
+       if (symbolrate < 500000)
+               symbolrate = 500000;
+
+       if (symbolrate < state->config->xin / 16)
+               NDEC = 1;
+       if (symbolrate < state->config->xin / 32)
+               NDEC = 2;
+       if (symbolrate < state->config->xin / 64)
+               NDEC = 3;
+
+       /* yeuch! */
+       fpxin = state->config->xin * 10;
+       fptmp = fpxin; do_div(fptmp, 123);
+       if (symbolrate < fptmp)
+               SFIL = 1;
+       fptmp = fpxin; do_div(fptmp, 160);
+       if (symbolrate < fptmp)
+               SFIL = 0;
+       fptmp = fpxin; do_div(fptmp, 246);
+       if (symbolrate < fptmp)
+               SFIL = 1;
+       fptmp = fpxin; do_div(fptmp, 320);
+       if (symbolrate < fptmp)
+               SFIL = 0;
+       fptmp = fpxin; do_div(fptmp, 492);
+       if (symbolrate < fptmp)
+               SFIL = 1;
+       fptmp = fpxin; do_div(fptmp, 640);
+       if (symbolrate < fptmp)
+               SFIL = 0;
+       fptmp = fpxin; do_div(fptmp, 984);
+       if (symbolrate < fptmp)
+               SFIL = 1;
+
+       fin = state->config->xin >> 4;
+       symbolrate <<= NDEC;
+       ratio = (symbolrate << 4) / fin;
+       tmp = ((symbolrate << 4) % fin) << 8;
+       ratio = (ratio << 8) + tmp / fin;
+       tmp = (tmp % fin) << 8;
+       ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, fin);
+
+       BDR = ratio;
+       BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
+
+       if (BDRI > 0xFF)
+               BDRI = 0xFF;
+
+       SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
+
+       NDEC = (NDEC << 6) | ves1820_inittab[0x03];
+
+       ves1820_writereg(state, 0x03, NDEC);
+       ves1820_writereg(state, 0x0a, BDR & 0xff);
+       ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
+       ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
+
+       ves1820_writereg(state, 0x0d, BDRI);
+       ves1820_writereg(state, 0x0e, SFIL);
+
+       return 0;
+}
+
+static int ves1820_init(struct dvb_frontend* fe)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+       int i;
+
+       ves1820_writereg(state, 0, 0);
+
+       for (i = 0; i < sizeof(ves1820_inittab); i++)
+               ves1820_writereg(state, i, ves1820_inittab[i]);
+       if (state->config->selagc)
+               ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
+
+       ves1820_writereg(state, 0x34, state->pwm);
+
+       return 0;
+}
+
+static int ves1820_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ves1820_state* state = fe->demodulator_priv;
+       static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
+       static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
+       static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
+       static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
+       static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
+       int real_qam = p->modulation - QAM_16;
+
+       if (real_qam < 0 || real_qam > 4)
+               return -EINVAL;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       ves1820_set_symbolrate(state, p->symbol_rate);
+       ves1820_writereg(state, 0x34, state->pwm);
+
+       ves1820_writereg(state, 0x01, reg0x01[real_qam]);
+       ves1820_writereg(state, 0x05, reg0x05[real_qam]);
+       ves1820_writereg(state, 0x08, reg0x08[real_qam]);
+       ves1820_writereg(state, 0x09, reg0x09[real_qam]);
+
+       ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
+       ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
+       return 0;
+}
+
+static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+       int sync;
+
+       *status = 0;
+       sync = ves1820_readreg(state, 0x11);
+
+       if (sync & 1)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 2)
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 2)   /* XXX FIXME! */
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 4)
+               *status |= FE_HAS_SYNC;
+
+       if (sync & 8)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+
+       u32 _ber = ves1820_readreg(state, 0x14) |
+                       (ves1820_readreg(state, 0x15) << 8) |
+                       ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
+       *ber = 10 * _ber;
+
+       return 0;
+}
+
+static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+
+       u8 gain = ves1820_readreg(state, 0x17);
+       *strength = (gain << 8) | gain;
+
+       return 0;
+}
+
+static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+
+       u8 quality = ~ves1820_readreg(state, 0x18);
+       *snr = (quality << 8) | quality;
+
+       return 0;
+}
+
+static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+
+       *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
+       if (*ucblocks == 0x7f)
+               *ucblocks = 0xffffffff;
+
+       /* reset uncorrected block counter */
+       ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
+       ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
+
+       return 0;
+}
+
+static int ves1820_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ves1820_state* state = fe->demodulator_priv;
+       int sync;
+       s8 afc = 0;
+
+       sync = ves1820_readreg(state, 0x11);
+       afc = ves1820_readreg(state, 0x19);
+       if (verbose) {
+               /* AFC only valid when carrier has been recovered */
+               printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
+                       "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->symbol_rate * afc) >> 10);
+       }
+
+       if (!state->config->invert) {
+               p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
+       } else {
+               p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
+       }
+
+       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
+
+       p->fec_inner = FEC_NONE;
+
+       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+       if (sync & 2)
+               p->frequency -= ((s32) p->symbol_rate * afc) >> 10;
+
+       return 0;
+}
+
+static int ves1820_sleep(struct dvb_frontend* fe)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+
+       ves1820_writereg(state, 0x1b, 0x02);    /* pdown ADC */
+       ves1820_writereg(state, 0x00, 0x80);    /* standby */
+
+       return 0;
+}
+
+static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+
+       fesettings->min_delay_ms = 200;
+       fesettings->step_size = 0;
+       fesettings->max_drift = 0;
+       return 0;
+}
+
+static void ves1820_release(struct dvb_frontend* fe)
+{
+       struct ves1820_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops ves1820_ops;
+
+struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
+                                   struct i2c_adapter* i2c,
+                                   u8 pwm)
+{
+       struct ves1820_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->reg0 = ves1820_inittab[0];
+       state->config = config;
+       state->i2c = i2c;
+       state->pwm = pwm;
+
+       /* check if the demod is there */
+       if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
+               goto error;
+
+       if (verbose)
+               printk("ves1820: pwm=0x%02x\n", state->pwm);
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64;      /* SACLK/64 == (XIN/2)/64 */
+       state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4;       /* SACLK/4 */
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops ves1820_ops = {
+       .delsys = { SYS_DVBC_ANNEX_A },
+       .info = {
+               .name = "VLSI VES1820 DVB-C",
+               .frequency_stepsize = 62500,
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
+               .caps = FE_CAN_QAM_16 |
+                       FE_CAN_QAM_32 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_128 |
+                       FE_CAN_QAM_256 |
+                       FE_CAN_FEC_AUTO
+       },
+
+       .release = ves1820_release,
+
+       .init = ves1820_init,
+       .sleep = ves1820_sleep,
+
+       .set_frontend = ves1820_set_parameters,
+       .get_frontend = ves1820_get_frontend,
+       .get_tune_settings = ves1820_get_tune_settings,
+
+       .read_status = ves1820_read_status,
+       .read_ber = ves1820_read_ber,
+       .read_signal_strength = ves1820_read_signal_strength,
+       .read_snr = ves1820_read_snr,
+       .read_ucblocks = ves1820_read_ucblocks,
+};
+
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
+
+MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
+MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb-frontends/ves1820.h b/drivers/media/dvb-frontends/ves1820.h
new file mode 100644 (file)
index 0000000..e902ed6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    VES1820  - Single Chip Cable Channel Receiver driver module
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef VES1820_H
+#define VES1820_H
+
+#include <linux/dvb/frontend.h>
+
+#define VES1820_SELAGC_PWM 0
+#define VES1820_SELAGC_SIGNAMPERR 1
+
+struct ves1820_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* value of XIN to use */
+       u32 xin;
+
+       /* does inversion need inverted? */
+       u8 invert:1;
+
+       /* SELAGC control */
+       u8 selagc:1;
+};
+
+#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE))
+extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
+                                          struct i2c_adapter* i2c, u8 pwm);
+#else
+static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
+                                          struct i2c_adapter* i2c, u8 pwm)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_VES1820
+
+#endif // VES1820_H
diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c
new file mode 100644 (file)
index 0000000..9c17eac
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+    Driver for VES1893 and VES1993 QPSK Demodulators
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+    Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
+    Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
+    Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include "dvb_frontend.h"
+#include "ves1x93.h"
+
+
+struct ves1x93_state {
+       struct i2c_adapter* i2c;
+       /* configuration settings */
+       const struct ves1x93_config* config;
+       struct dvb_frontend frontend;
+
+       /* previous uncorrected block counter */
+       fe_spectral_inversion_t inversion;
+       u8 *init_1x93_tab;
+       u8 *init_1x93_wtab;
+       u8 tab_size;
+       u8 demod_type;
+       u32 frequency;
+};
+
+static int debug;
+#define dprintk        if (debug) printk
+
+#define DEMOD_VES1893          0
+#define DEMOD_VES1993          1
+
+static u8 init_1893_tab [] = {
+       0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
+       0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
+       0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
+       0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
+};
+
+static u8 init_1993_tab [] = {
+       0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
+       0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
+       0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
+       0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
+       0x00, 0x00, 0x0e, 0x80, 0x00
+};
+
+static u8 init_1893_wtab[] =
+{
+       1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
+       0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
+       1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
+       1,1,1,0,1,1
+};
+
+static u8 init_1993_wtab[] =
+{
+       1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
+       0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
+       1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
+       1,1,1,0,1,1,1,1, 1,1,1,1,1
+};
+
+static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
+{
+       u8 buf [] = { 0x00, reg, data };
+       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
+       int err;
+
+       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+               dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { 0x00, reg };
+       u8 b1 [] = { 0 };
+       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
+                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer (state->i2c, msg, 2);
+
+       if (ret != 2) return ret;
+
+       return b1[0];
+}
+
+static int ves1x93_clr_bit (struct ves1x93_state* state)
+{
+       msleep(10);
+       ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
+       ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
+       msleep(50);
+       return 0;
+}
+
+static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
+{
+       u8 val;
+
+       /*
+        * inversion on/off are interchanged because i and q seem to
+        * be swapped on the hardware
+        */
+
+       switch (inversion) {
+       case INVERSION_OFF:
+               val = 0xc0;
+               break;
+       case INVERSION_ON:
+               val = 0x80;
+               break;
+       case INVERSION_AUTO:
+               val = 0x00;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
+}
+
+static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
+{
+       if (fec == FEC_AUTO)
+               return ves1x93_writereg (state, 0x0d, 0x08);
+       else if (fec < FEC_1_2 || fec > FEC_8_9)
+               return -EINVAL;
+       else
+               return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
+}
+
+static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
+{
+       return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
+}
+
+static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
+{
+       u32 BDR;
+       u32 ratio;
+       u8  ADCONF, FCONF, FNR, AGCR;
+       u32 BDRI;
+       u32 tmp;
+       u32 FIN;
+
+       dprintk("%s: srate == %d\n", __func__, (unsigned int) srate);
+
+       if (srate > state->config->xin/2)
+               srate = state->config->xin/2;
+
+       if (srate < 500000)
+               srate = 500000;
+
+#define MUL (1UL<<26)
+
+       FIN = (state->config->xin + 6000) >> 4;
+
+       tmp = srate << 6;
+       ratio = tmp / FIN;
+
+       tmp = (tmp % FIN) << 8;
+       ratio = (ratio << 8) + tmp / FIN;
+
+       tmp = (tmp % FIN) << 8;
+       ratio = (ratio << 8) + tmp / FIN;
+
+       FNR = 0xff;
+
+       if (ratio < MUL/3)           FNR = 0;
+       if (ratio < (MUL*11)/50)     FNR = 1;
+       if (ratio < MUL/6)           FNR = 2;
+       if (ratio < MUL/9)           FNR = 3;
+       if (ratio < MUL/12)          FNR = 4;
+       if (ratio < (MUL*11)/200)    FNR = 5;
+       if (ratio < MUL/24)          FNR = 6;
+       if (ratio < (MUL*27)/1000)   FNR = 7;
+       if (ratio < MUL/48)          FNR = 8;
+       if (ratio < (MUL*137)/10000) FNR = 9;
+
+       if (FNR == 0xff) {
+               ADCONF = 0x89;
+               FCONF  = 0x80;
+               FNR     = 0;
+       } else {
+               ADCONF = 0x81;
+               FCONF  = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
+               /*FCONF  = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
+       }
+
+       BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
+       BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
+
+       dprintk("FNR= %d\n", FNR);
+       dprintk("ratio= %08x\n", (unsigned int) ratio);
+       dprintk("BDR= %08x\n", (unsigned int) BDR);
+       dprintk("BDRI= %02x\n", (unsigned int) BDRI);
+
+       if (BDRI > 0xff)
+               BDRI = 0xff;
+
+       ves1x93_writereg (state, 0x06, 0xff & BDR);
+       ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
+       ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
+
+       ves1x93_writereg (state, 0x09, BDRI);
+       ves1x93_writereg (state, 0x20, ADCONF);
+       ves1x93_writereg (state, 0x21, FCONF);
+
+       AGCR = state->init_1x93_tab[0x05];
+       if (state->config->invert_pwm)
+               AGCR |= 0x20;
+
+       if (srate < 6000000)
+               AGCR |= 0x80;
+       else
+               AGCR &= ~0x80;
+
+       ves1x93_writereg (state, 0x05, AGCR);
+
+       /* ves1993 hates this, will lose lock */
+       if (state->demod_type != DEMOD_VES1993)
+               ves1x93_clr_bit (state);
+
+       return 0;
+}
+
+static int ves1x93_init (struct dvb_frontend* fe)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+       int i;
+       int val;
+
+       dprintk("%s: init chip\n", __func__);
+
+       for (i = 0; i < state->tab_size; i++) {
+               if (state->init_1x93_wtab[i]) {
+                       val = state->init_1x93_tab[i];
+
+                       if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
+                       ves1x93_writereg (state, i, val);
+               }
+       }
+
+       return 0;
+}
+
+static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       switch (voltage) {
+       case SEC_VOLTAGE_13:
+               return ves1x93_writereg (state, 0x1f, 0x20);
+       case SEC_VOLTAGE_18:
+               return ves1x93_writereg (state, 0x1f, 0x30);
+       case SEC_VOLTAGE_OFF:
+               return ves1x93_writereg (state, 0x1f, 0x00);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       u8 sync = ves1x93_readreg (state, 0x0e);
+
+       /*
+        * The ves1893 sometimes returns sync values that make no sense,
+        * because, e.g., the SIGNAL bit is 0, while some of the higher
+        * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
+        * Tests showed that the VITERBI and SYNC bits are returned
+        * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
+        * If such a case occurs, we read the value again, until we get a
+        * valid value.
+        */
+       int maxtry = 10; /* just for safety - let's not get stuck here */
+       while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
+               msleep(10);
+               sync = ves1x93_readreg (state, 0x0e);
+       }
+
+       *status = 0;
+
+       if (sync & 1)
+               *status |= FE_HAS_SIGNAL;
+
+       if (sync & 2)
+               *status |= FE_HAS_CARRIER;
+
+       if (sync & 4)
+               *status |= FE_HAS_VITERBI;
+
+       if (sync & 8)
+               *status |= FE_HAS_SYNC;
+
+       if ((sync & 0x1f) == 0x1f)
+               *status |= FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       *ber = ves1x93_readreg (state, 0x15);
+       *ber |= (ves1x93_readreg (state, 0x16) << 8);
+       *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
+       *ber *= 10;
+
+       return 0;
+}
+
+static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       u8 signal = ~ves1x93_readreg (state, 0x0b);
+       *strength = (signal << 8) | signal;
+
+       return 0;
+}
+
+static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       u8 _snr = ~ves1x93_readreg (state, 0x1c);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
+
+       if (*ucblocks == 0x7f)
+               *ucblocks = 0xffffffff;   /* counter overflow... */
+
+       ves1x93_writereg (state, 0x18, 0x00);  /* reset the counter */
+       ves1x93_writereg (state, 0x18, 0x80);  /* dto. */
+
+       return 0;
+}
+
+static int ves1x93_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+       ves1x93_set_inversion (state, p->inversion);
+       ves1x93_set_fec(state, p->fec_inner);
+       ves1x93_set_symbolrate(state, p->symbol_rate);
+       state->inversion = p->inversion;
+       state->frequency = p->frequency;
+
+       return 0;
+}
+
+static int ves1x93_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct ves1x93_state* state = fe->demodulator_priv;
+       int afc;
+
+       afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
+       afc = (afc * (int)(p->symbol_rate/1000/8))/16;
+
+       p->frequency = state->frequency - afc;
+
+       /*
+        * inversion indicator is only valid
+        * if auto inversion was used
+        */
+       if (state->inversion == INVERSION_AUTO)
+               p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
+                               INVERSION_OFF : INVERSION_ON;
+       p->fec_inner = ves1x93_get_fec(state);
+       /*  XXX FIXME: timing offset !! */
+
+       return 0;
+}
+
+static int ves1x93_sleep(struct dvb_frontend* fe)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       return ves1x93_writereg (state, 0x00, 0x08);
+}
+
+static void ves1x93_release(struct dvb_frontend* fe)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct ves1x93_state* state = fe->demodulator_priv;
+
+       if (enable) {
+               return ves1x93_writereg(state, 0x00, 0x11);
+       } else {
+               return ves1x93_writereg(state, 0x00, 0x01);
+       }
+}
+
+static struct dvb_frontend_ops ves1x93_ops;
+
+struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct ves1x93_state* state = NULL;
+       u8 identity;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
+       if (state == NULL) goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->inversion = INVERSION_OFF;
+
+       /* check if the demod is there + identify it */
+       identity = ves1x93_readreg(state, 0x1e);
+       switch (identity) {
+       case 0xdc: /* VES1893A rev1 */
+               printk("ves1x93: Detected ves1893a rev1\n");
+               state->demod_type = DEMOD_VES1893;
+               state->init_1x93_tab = init_1893_tab;
+               state->init_1x93_wtab = init_1893_wtab;
+               state->tab_size = sizeof(init_1893_tab);
+               break;
+
+       case 0xdd: /* VES1893A rev2 */
+               printk("ves1x93: Detected ves1893a rev2\n");
+               state->demod_type = DEMOD_VES1893;
+               state->init_1x93_tab = init_1893_tab;
+               state->init_1x93_wtab = init_1893_wtab;
+               state->tab_size = sizeof(init_1893_tab);
+               break;
+
+       case 0xde: /* VES1993 */
+               printk("ves1x93: Detected ves1993\n");
+               state->demod_type = DEMOD_VES1993;
+               state->init_1x93_tab = init_1993_tab;
+               state->init_1x93_wtab = init_1993_wtab;
+               state->tab_size = sizeof(init_1993_tab);
+               break;
+
+       default:
+               goto error;
+       }
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops ves1x93_ops = {
+       .delsys = { SYS_DVBS },
+       .info = {
+               .name                   = "VLSI VES1x93 DVB-S",
+               .frequency_min          = 950000,
+               .frequency_max          = 2150000,
+               .frequency_stepsize     = 125,           /* kHz for QPSK frontends */
+               .frequency_tolerance    = 29500,
+               .symbol_rate_min        = 1000000,
+               .symbol_rate_max        = 45000000,
+       /*      .symbol_rate_tolerance  =       ???,*/
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK
+       },
+
+       .release = ves1x93_release,
+
+       .init = ves1x93_init,
+       .sleep = ves1x93_sleep,
+       .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,
+
+       .set_frontend = ves1x93_set_frontend,
+       .get_frontend = ves1x93_get_frontend,
+
+       .read_status = ves1x93_read_status,
+       .read_ber = ves1x93_read_ber,
+       .read_signal_strength = ves1x93_read_signal_strength,
+       .read_snr = ves1x93_read_snr,
+       .read_ucblocks = ves1x93_read_ucblocks,
+
+       .set_voltage = ves1x93_set_voltage,
+};
+
+module_param(debug, int, 0644);
+
+MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
+MODULE_AUTHOR("Ralph Metzler");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb-frontends/ves1x93.h b/drivers/media/dvb-frontends/ves1x93.h
new file mode 100644 (file)
index 0000000..8a5a49e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+    Driver for VES1893 and VES1993 QPSK Demodulators
+
+    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+    Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
+    Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
+    Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef VES1X93_H
+#define VES1X93_H
+
+#include <linux/dvb/frontend.h>
+
+struct ves1x93_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* value of XIN to use */
+       u32 xin;
+
+       /* should PWM be inverted? */
+       u8 invert_pwm:1;
+};
+
+#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE))
+extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
+                                          struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_VES1X93
+
+#endif // VES1X93_H
diff --git a/drivers/media/dvb-frontends/z0194a.h b/drivers/media/dvb-frontends/z0194a.h
new file mode 100644 (file)
index 0000000..96d86d6
--- /dev/null
@@ -0,0 +1,85 @@
+/* z0194a.h Sharp z0194a tuner support
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+*      This program is free software; you can redistribute it and/or modify it
+*      under the terms of the GNU General Public License as published by the
+*      Free Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#ifndef Z0194A
+#define Z0194A
+
+static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
+                                        u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) {
+               aclk = 0xb7; bclk = 0x47; }
+       else if (srate < 3000000) {
+               aclk = 0xb7; bclk = 0x4b; }
+       else if (srate < 7000000) {
+               aclk = 0xb7; bclk = 0x4f; }
+       else if (srate < 14000000) {
+               aclk = 0xb7; bclk = 0x53; }
+       else if (srate < 30000000) {
+               aclk = 0xb6; bclk = 0x53; }
+       else if (srate < 45000000) {
+               aclk = 0xb4; bclk = 0x51; }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+
+       return 0;
+}
+
+static u8 sharp_z0194a_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   /* AGC2  0x3d */
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,   /* lock detector threshold */
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  /* out imp: normal  out type: parallel FEC mode:0 */
+       0x29, 0x1e,  /* 1/2 threshold */
+       0x2a, 0x14,  /* 2/3 threshold */
+       0x2b, 0x0f,  /* 3/4 threshold */
+       0x2c, 0x09,  /* 5/6 threshold */
+       0x2d, 0x05,  /* 7/8 threshold */
+       0x2e, 0x01,
+       0x31, 0x1f,  /* test all FECs */
+       0x32, 0x19,  /* viterbi and synchro search */
+       0x33, 0xfc,  /* rs control */
+       0x34, 0x93,  /* error control */
+       0x0f, 0x52,
+       0xff, 0xff
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
new file mode 100644 (file)
index 0000000..0903d46
--- /dev/null
@@ -0,0 +1,520 @@
+/**
+ * Driver for Zarlink zl10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **
+ * The data sheet for this tuner can be found at:
+ *    http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
+ *
+ * This one is working: (at my Avermedia DVB-S Pro)
+ * - zl10036 (40pin, FTA)
+ *
+ * A driver for zl10038 should be very similar.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "zl10036.h"
+
+static int zl10036_debug;
+#define dprintk(level, args...) \
+       do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
+       } while (0)
+
+#define deb_info(args...)  dprintk(0x01, args)
+#define deb_i2c(args...)  dprintk(0x02, args)
+
+struct zl10036_state {
+       struct i2c_adapter *i2c;
+       const struct zl10036_config *config;
+       u32 frequency;
+       u8 br, bf;
+};
+
+
+/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
+#define _XTAL 10111
+
+/* Some of the possible dividers:
+ *   64, (write 0x05 to reg), freq step size   158kHz
+ *   10, (write 0x0a to reg), freq step size 1.011kHz (used here)
+ *    5, (write 0x09 to reg), freq step size 2.022kHz
+ */
+
+#define _RDIV 10
+#define _RDIV_REG 0x0a
+#define _FR   (_XTAL/_RDIV)
+
+#define STATUS_POR 0x80 /* Power on Reset */
+#define STATUS_FL  0x40 /* Frequency & Phase Lock */
+
+/* read/write for zl10036 and zl10038 */
+
+static int zl10036_read_status_reg(struct zl10036_state *state)
+{
+       u8 status;
+       struct i2c_msg msg[1] = {
+               { .addr = state->config->tuner_address, .flags = I2C_M_RD,
+                 .buf = &status, .len = sizeof(status) },
+       };
+
+       if (i2c_transfer(state->i2c, msg, 1) != 1) {
+               printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
+                       __func__, state->config->tuner_address);
+               return -EIO;
+       }
+
+       deb_i2c("R(status): %02x  [FL=%d]\n", status,
+               (status & STATUS_FL) ? 1 : 0);
+       if (status & STATUS_POR)
+               deb_info("%s: Power-On-Reset bit enabled - "
+                       "need to initialize the tuner\n", __func__);
+
+       return status;
+}
+
+static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
+{
+       struct i2c_msg msg[1] = {
+               { .addr = state->config->tuner_address, .flags = 0,
+                 .buf = buf, .len = count },
+       };
+       u8 reg = 0;
+       int ret;
+
+       if (zl10036_debug & 0x02) {
+               /* every 8bit-value satisifes this!
+                * so only check for debug log */
+               if ((buf[0] & 0x80) == 0x00)
+                       reg = 2;
+               else if ((buf[0] & 0xc0) == 0x80)
+                       reg = 4;
+               else if ((buf[0] & 0xf0) == 0xc0)
+                       reg = 6;
+               else if ((buf[0] & 0xf0) == 0xd0)
+                       reg = 8;
+               else if ((buf[0] & 0xf0) == 0xe0)
+                       reg = 10;
+               else if ((buf[0] & 0xf0) == 0xf0)
+                       reg = 12;
+
+               deb_i2c("W(%d):", reg);
+               {
+                       int i;
+                       for (i = 0; i < count; i++)
+                               printk(KERN_CONT " %02x", buf[i]);
+                       printk(KERN_CONT "\n");
+               }
+       }
+
+       ret = i2c_transfer(state->i2c, msg, 1);
+       if (ret != 1) {
+               printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int zl10036_release(struct dvb_frontend *fe)
+{
+       struct zl10036_state *state = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+
+       return 0;
+}
+
+static int zl10036_sleep(struct dvb_frontend *fe)
+{
+       struct zl10036_state *state = fe->tuner_priv;
+       u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
+       int ret;
+
+       deb_info("%s\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = zl10036_write(state, buf, sizeof(buf));
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+/**
+ * register map of the ZL10036/ZL10038
+ *
+ * reg[default] content
+ *  2[0x00]:   0 | N14 | N13 | N12 | N11 | N10 |  N9 |  N8
+ *  3[0x00]:  N7 |  N6 |  N5 |  N4 |  N3 |  N2 |  N1 |  N0
+ *  4[0x80]:   1 |   0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
+ *  5[0x00]:  P0 |  C1 |  C0 |  R4 |  R3 |  R2 |  R1 |  R0
+ *  6[0xc0]:   1 |   1 |   0 |   0 | RSD |   0 |   0 |   0
+ *  7[0x20]:  P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 |   0
+ *  8[0xdb]:   1 |   1 |   0 |   1 |   0 |  CC |   1 |   1
+ *  9[0x30]: VSD |  V2 |  V1 |  V0 |  S3 |  S2 |  S1 |  S0
+ * 10[0xe1]:   1 |   1 |   1 |   0 |   0 | LS2 | LS1 | LS0
+ * 11[0xf5]:  WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
+ * 12[0xf0]:   1 |   1 |   1 |   1 |   0 |   0 |   0 |   0
+ * 13[0x28]:  PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR |  TL
+ */
+
+static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
+{
+       u8 buf[2];
+       u32 div, foffset;
+
+       div = (frequency + _FR/2) / _FR;
+       state->frequency = div * _FR;
+
+       foffset = frequency - state->frequency;
+
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = (div >> 0) & 0xff;
+
+       deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
+               frequency, state->frequency, foffset, div);
+
+       return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
+{
+       /* fbw is measured in kHz */
+       u8 br, bf;
+       int ret;
+       u8 buf_bf[] = {
+               0xc0, 0x00, /*   6/7: rsd=0 bf=0 */
+       };
+       u8 buf_br[] = {
+               0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
+       };
+       u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
+
+       /* ensure correct values */
+       if (fbw > 35000)
+               fbw = 35000;
+       if (fbw <  8000)
+               fbw =  8000;
+
+#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
+
+       /* <= 28,82 MHz */
+       if (fbw <= 28820) {
+               br = _BR_MAXIMUM;
+       } else {
+               /**
+                *  f(bw)=34,6MHz f(xtal)=10.111MHz
+                *  br = (10111/34600) * 63 * 1/K = 14;
+                */
+               br = ((_XTAL * 21 * 1000) / (fbw * 419));
+       }
+
+       /* ensure correct values */
+       if (br < 4)
+               br = 4;
+       if (br > _BR_MAXIMUM)
+               br = _BR_MAXIMUM;
+
+       /*
+        * k = 1.257
+        * bf = fbw/_XTAL * br * k - 1 */
+
+       bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
+
+       /* ensure correct values */
+       if (bf > 62)
+               bf = 62;
+
+       buf_bf[1] = (bf << 1) & 0x7e;
+       buf_br[1] = (br << 2) & 0x7c;
+       deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
+
+       if (br != state->br) {
+               ret = zl10036_write(state, buf_br, sizeof(buf_br));
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (bf != state->bf) {
+               ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
+               if (ret < 0)
+                       return ret;
+
+               /* time = br/(32* fxtal) */
+               /* minimal sleep time to be calculated
+                * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
+               msleep(1);
+
+               ret = zl10036_write(state, zl10036_rsd_off,
+                       sizeof(zl10036_rsd_off));
+               if (ret < 0)
+                       return ret;
+       }
+
+       state->br = br;
+       state->bf = bf;
+
+       return 0;
+}
+
+static int zl10036_set_gain_params(struct zl10036_state *state,
+       int c)
+{
+       u8 buf[2];
+       u8 rfg, ba, bg;
+
+       /* default values */
+       rfg = 0; /* enable when using an lna */
+       ba = 1;
+       bg = 1;
+
+       /* reg 4 */
+       buf[0] = 0x80 | ((rfg << 5) & 0x20)
+               | ((ba  << 3) & 0x18) | ((bg  << 1) & 0x06);
+
+       if (!state->config->rf_loop_enable)
+               buf[0] |= 0x01;
+
+       /* P0=0 */
+       buf[1] = _RDIV_REG | ((c << 5) & 0x60);
+
+       deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
+       return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct zl10036_state *state = fe->tuner_priv;
+       int ret = 0;
+       u32 frequency = p->frequency;
+       u32 fbw;
+       int i;
+       u8 c;
+
+       /* ensure correct values
+        * maybe redundant as core already checks this */
+       if ((frequency < fe->ops.info.frequency_min)
+       ||  (frequency > fe->ops.info.frequency_max))
+               return -EINVAL;
+
+       /**
+        * alpha = 1.35 for dvb-s
+        * fBW = (alpha*symbolrate)/(2*0.8)
+        * 1.35 / (2*0.8) = 27 / 32
+        */
+       fbw = (27 * p->symbol_rate) / 32;
+
+       /* scale to kHz */
+       fbw /= 1000;
+
+       /* Add safe margin of 3MHz */
+       fbw += 3000;
+
+       /* setting the charge pump - guessed values */
+       if (frequency < 950000)
+               return -EINVAL;
+       else if (frequency < 1250000)
+               c = 0;
+       else if (frequency < 1750000)
+               c = 1;
+       else if (frequency < 2175000)
+               c = 2;
+       else
+               return -EINVAL;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = zl10036_set_gain_params(state, c);
+       if (ret < 0)
+               goto error;
+
+       ret = zl10036_set_frequency(state, p->frequency);
+       if (ret < 0)
+               goto error;
+
+       ret = zl10036_set_bandwidth(state, fbw);
+       if (ret < 0)
+               goto error;
+
+       /* wait for tuner lock - no idea if this is really needed */
+       for (i = 0; i < 20; i++) {
+               ret = zl10036_read_status_reg(state);
+               if (ret < 0)
+                       goto error;
+
+               /* check Frequency & Phase Lock Bit */
+               if (ret & STATUS_FL)
+                       break;
+
+               msleep(10);
+       }
+
+error:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct zl10036_state *state = fe->tuner_priv;
+
+       *frequency = state->frequency;
+
+       return 0;
+}
+
+static int zl10036_init_regs(struct zl10036_state *state)
+{
+       int ret;
+       int i;
+
+       /* could also be one block from reg 2 to 13 and additional 10/11 */
+       u8 zl10036_init_tab[][2] = {
+               { 0x04, 0x00 },         /*   2/3: div=0x400 - arbitrary value */
+               { 0x8b, _RDIV_REG },    /*   4/5: rfg=0 ba=1 bg=1 len=? */
+                                       /*        p0=0 c=0 r=_RDIV_REG */
+               { 0xc0, 0x20 },         /*   6/7: rsd=0 bf=0x10 */
+               { 0xd3, 0x40 },         /*   8/9: from datasheet */
+               { 0xe3, 0x5b },         /* 10/11: lock window level */
+               { 0xf0, 0x28 },         /* 12/13: br=0xa clr=0 tl=0*/
+               { 0xe3, 0xf9 },         /* 10/11: unlock window level */
+       };
+
+       /* invalid values to trigger writing */
+       state->br = 0xff;
+       state->bf = 0xff;
+
+       if (!state->config->rf_loop_enable)
+               zl10036_init_tab[1][0] |= 0x01;
+
+       deb_info("%s\n", __func__);
+
+       for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
+               ret = zl10036_write(state, zl10036_init_tab[i], 2);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int zl10036_init(struct dvb_frontend *fe)
+{
+       struct zl10036_state *state = fe->tuner_priv;
+       int ret = 0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = zl10036_read_status_reg(state);
+       if (ret < 0)
+               return ret;
+
+       /* Only init if Power-on-Reset bit is set? */
+       ret = zl10036_init_regs(state);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+static struct dvb_tuner_ops zl10036_tuner_ops = {
+       .info = {
+               .name = "Zarlink ZL10036",
+               .frequency_min = 950000,
+               .frequency_max = 2175000
+       },
+       .init = zl10036_init,
+       .release = zl10036_release,
+       .sleep = zl10036_sleep,
+       .set_params = zl10036_set_params,
+       .get_frequency = zl10036_get_frequency,
+};
+
+struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+                                   const struct zl10036_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct zl10036_state *state;
+       int ret;
+
+       if (!config) {
+               printk(KERN_ERR "%s: no config specified", __func__);
+               return NULL;
+       }
+
+       state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
+       if (!state)
+               return NULL;
+
+       state->config = config;
+       state->i2c = i2c;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = zl10036_read_status_reg(state);
+       if (ret < 0) {
+               printk(KERN_ERR "%s: No zl10036 found\n", __func__);
+               goto error;
+       }
+
+       ret = zl10036_init_regs(state);
+       if (ret < 0) {
+               printk(KERN_ERR "%s: tuner initialization failed\n",
+                       __func__);
+               goto error;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       fe->tuner_priv = state;
+
+       memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+       printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
+               __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+       return fe;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(zl10036_attach);
+
+module_param_named(debug, zl10036_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB ZL10036 driver");
+MODULE_AUTHOR("Tino Reichardt");
+MODULE_AUTHOR("Matthias Schwarzott");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
new file mode 100644 (file)
index 0000000..d84b8f8
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * Driver for Zarlink ZL10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_ZL10036_H
+#define DVB_ZL10036_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config zl10036_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct zl10036_config {
+       u8 tuner_address;
+       int rf_loop_enable;
+};
+
+#if defined(CONFIG_DVB_ZL10036) || \
+       (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
+extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+       const struct zl10036_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+       const struct zl10036_config *config, struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
new file mode 100644 (file)
index 0000000..eff9c5f
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ *  Driver for Zarlink ZL10039 DVB-S tuner
+ *
+ *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/dvb/frontend.h>
+
+#include "dvb_frontend.h"
+#include "zl10039.h"
+
+static int debug;
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG args); \
+       } while (0)
+
+enum zl10039_model_id {
+       ID_ZL10039 = 1
+};
+
+struct zl10039_state {
+       struct i2c_adapter *i2c;
+       u8 i2c_addr;
+       u8 id;
+};
+
+enum zl10039_reg_addr {
+       PLL0 = 0,
+       PLL1,
+       PLL2,
+       PLL3,
+       RFFE,
+       BASE0,
+       BASE1,
+       BASE2,
+       LO0,
+       LO1,
+       LO2,
+       LO3,
+       LO4,
+       LO5,
+       LO6,
+       GENERAL
+};
+
+static int zl10039_read(const struct zl10039_state *state,
+                       const enum zl10039_reg_addr reg, u8 *buf,
+                       const size_t count)
+{
+       u8 regbuf[] = { reg };
+       struct i2c_msg msg[] = {
+               {/* Write register address */
+                       .addr = state->i2c_addr,
+                       .flags = 0,
+                       .buf = regbuf,
+                       .len = 1,
+               }, {/* Read count bytes */
+                       .addr = state->i2c_addr,
+                       .flags = I2C_M_RD,
+                       .buf = buf,
+                       .len = count,
+               },
+       };
+
+       dprintk("%s\n", __func__);
+
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               dprintk("%s: i2c read error\n", __func__);
+               return -EREMOTEIO;
+       }
+
+       return 0; /* Success */
+}
+
+static int zl10039_write(struct zl10039_state *state,
+                       const enum zl10039_reg_addr reg, const u8 *src,
+                       const size_t count)
+{
+       u8 buf[count + 1];
+       struct i2c_msg msg = {
+               .addr = state->i2c_addr,
+               .flags = 0,
+               .buf = buf,
+               .len = count + 1,
+       };
+
+       dprintk("%s\n", __func__);
+       /* Write register address and data in one go */
+       buf[0] = reg;
+       memcpy(&buf[1], src, count);
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               dprintk("%s: i2c write error\n", __func__);
+               return -EREMOTEIO;
+       }
+
+       return 0; /* Success */
+}
+
+static inline int zl10039_readreg(struct zl10039_state *state,
+                               const enum zl10039_reg_addr reg, u8 *val)
+{
+       return zl10039_read(state, reg, val, 1);
+}
+
+static inline int zl10039_writereg(struct zl10039_state *state,
+                               const enum zl10039_reg_addr reg,
+                               const u8 val)
+{
+       return zl10039_write(state, reg, &val, 1);
+}
+
+static int zl10039_init(struct dvb_frontend *fe)
+{
+       struct zl10039_state *state = fe->tuner_priv;
+       int ret;
+
+       dprintk("%s\n", __func__);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       /* Reset logic */
+       ret = zl10039_writereg(state, GENERAL, 0x40);
+       if (ret < 0) {
+               dprintk("Note: i2c write error normal when resetting the "
+                       "tuner\n");
+       }
+       /* Wake up */
+       ret = zl10039_writereg(state, GENERAL, 0x01);
+       if (ret < 0) {
+               dprintk("Tuner power up failed\n");
+               return ret;
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int zl10039_sleep(struct dvb_frontend *fe)
+{
+       struct zl10039_state *state = fe->tuner_priv;
+       int ret;
+
+       dprintk("%s\n", __func__);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = zl10039_writereg(state, GENERAL, 0x80);
+       if (ret < 0) {
+               dprintk("Tuner sleep failed\n");
+               return ret;
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int zl10039_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct zl10039_state *state = fe->tuner_priv;
+       u8 buf[6];
+       u8 bf;
+       u32 fbw;
+       u32 div;
+       int ret;
+
+       dprintk("%s\n", __func__);
+       dprintk("Set frequency = %d, symbol rate = %d\n",
+                       c->frequency, c->symbol_rate);
+
+       /* Assumed 10.111 MHz crystal oscillator */
+       /* Cancelled num/den 80 to prevent overflow */
+       div = (c->frequency * 1000) / 126387;
+       fbw = (c->symbol_rate * 27) / 32000;
+       /* Cancelled num/den 10 to prevent overflow */
+       bf = ((fbw * 5088) / 1011100) - 1;
+
+       /*PLL divider*/
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = (div >> 0) & 0xff;
+       /*Reference divider*/
+       /* Select reference ratio of 80 */
+       buf[2] = 0x1D;
+       /*PLL test modes*/
+       buf[3] = 0x40;
+       /*RF Control register*/
+       buf[4] = 0x6E; /* Bypass enable */
+       /*Baseband filter cutoff */
+       buf[5] = bf;
+
+       /* Open i2c gate */
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       /* BR = 10, Enable filter adjustment */
+       ret = zl10039_writereg(state, BASE1, 0x0A);
+       if (ret < 0)
+               goto error;
+       /* Write new config values */
+       ret = zl10039_write(state, PLL0, buf, sizeof(buf));
+       if (ret < 0)
+               goto error;
+       /* BR = 10, Disable filter adjustment */
+       ret = zl10039_writereg(state, BASE1, 0x6A);
+       if (ret < 0)
+               goto error;
+
+       /* Close i2c gate */
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+       return 0;
+error:
+       dprintk("Error setting tuner\n");
+       return ret;
+}
+
+static int zl10039_release(struct dvb_frontend *fe)
+{
+       struct zl10039_state *state = fe->tuner_priv;
+
+       dprintk("%s\n", __func__);
+       kfree(state);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static struct dvb_tuner_ops zl10039_ops = {
+       .release = zl10039_release,
+       .init = zl10039_init,
+       .sleep = zl10039_sleep,
+       .set_params = zl10039_set_params,
+};
+
+struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+               u8 i2c_addr, struct i2c_adapter *i2c)
+{
+       struct zl10039_state *state = NULL;
+
+       dprintk("%s\n", __func__);
+       state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->i2c = i2c;
+       state->i2c_addr = i2c_addr;
+
+       /* Open i2c gate */
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       /* check if this is a valid tuner */
+       if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
+               /* Close i2c gate */
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+               goto error;
+       }
+       /* Close i2c gate */
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       state->id = state->id & 0x0f;
+       switch (state->id) {
+       case ID_ZL10039:
+               strcpy(fe->ops.tuner_ops.info.name,
+                       "Zarlink ZL10039 DVB-S tuner");
+               break;
+       default:
+               dprintk("Chip ID=%x does not match a known type\n", state->id);
+               goto error;
+       }
+
+       memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = state;
+       dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
+       return fe;
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL(zl10039_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
+MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/zl10039.h b/drivers/media/dvb-frontends/zl10039.h
new file mode 100644 (file)
index 0000000..5eee7ea
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+    Driver for Zarlink ZL10039 DVB-S tuner
+
+    Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef ZL10039_H
+#define ZL10039_H
+
+#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
+           && defined(MODULE))
+struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+                                       u8 i2c_addr,
+                                       struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+                                       u8 i2c_addr,
+                                       struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_ZL10039 */
+
+#endif /* ZL10039_H */
diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c
new file mode 100644 (file)
index 0000000..82946cd
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "zl10353_priv.h"
+#include "zl10353.h"
+
+struct zl10353_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend frontend;
+
+       struct zl10353_config config;
+
+       u32 bandwidth;
+       u32 ucblocks;
+       u32 frequency;
+};
+
+static int debug;
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "zl10353: " args); \
+       } while (0)
+
+static int debug_regs;
+
+static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+       int err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
+               return err;
+       }
+       return 0;
+}
+
+static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen)
+{
+       int err, i;
+       for (i = 0; i < ilen - 1; i++)
+               if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
+                       return err;
+
+       return 0;
+}
+
+static int zl10353_read_register(struct zl10353_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[1] = { reg };
+       u8 b1[1] = { 0 };
+       struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
+                                   .flags = 0,
+                                   .buf = b0, .len = 1 },
+                                 { .addr = state->config.demod_address,
+                                   .flags = I2C_M_RD,
+                                   .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk("%s: readreg error (reg=%d, ret==%i)\n",
+                      __func__, reg, ret);
+               return ret;
+       }
+
+       return b1[0];
+}
+
+static void zl10353_dump_regs(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       int ret;
+       u8 reg;
+
+       /* Dump all registers. */
+       for (reg = 0; ; reg++) {
+               if (reg % 16 == 0) {
+                       if (reg)
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
+               }
+               ret = zl10353_read_register(state, reg);
+               if (ret >= 0)
+                       printk(KERN_CONT " %02x", (u8)ret);
+               else
+                       printk(KERN_CONT " --");
+               if (reg == 0xff)
+                       break;
+       }
+       printk(KERN_CONT "\n");
+}
+
+static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
+                                     u32 bandwidth,
+                                     u16 *nominal_rate)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u32 adc_clock = 450560; /* 45.056 MHz */
+       u64 value;
+       u8 bw = bandwidth / 1000000;
+
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
+
+       value = (u64)10 * (1 << 23) / 7 * 125;
+       value = (bw * value) + adc_clock / 2;
+       do_div(value, adc_clock);
+       *nominal_rate = value;
+
+       dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
+               __func__, bw, adc_clock, *nominal_rate);
+}
+
+static void zl10353_calc_input_freq(struct dvb_frontend *fe,
+                                   u16 *input_freq)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u32 adc_clock = 450560; /* 45.056  MHz */
+       int if2 = 361667;       /* 36.1667 MHz */
+       int ife;
+       u64 value;
+
+       if (state->config.adc_clock)
+               adc_clock = state->config.adc_clock;
+       if (state->config.if2)
+               if2 = state->config.if2;
+
+       if (adc_clock >= if2 * 2)
+               ife = if2;
+       else {
+               ife = adc_clock - (if2 % adc_clock);
+               if (ife > adc_clock / 2)
+                       ife = adc_clock - ife;
+       }
+       value = (u64)65536 * ife + adc_clock / 2;
+       do_div(value, adc_clock);
+       *input_freq = -value;
+
+       dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
+               __func__, if2, ife, adc_clock, -(int)value, *input_freq);
+}
+
+static int zl10353_sleep(struct dvb_frontend *fe)
+{
+       static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
+
+       zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
+       return 0;
+}
+
+static int zl10353_set_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct zl10353_state *state = fe->demodulator_priv;
+       u16 nominal_rate, input_freq;
+       u8 pllbuf[6] = { 0x67 }, acq_ctl = 0;
+       u16 tps = 0;
+
+       state->frequency = c->frequency;
+
+       zl10353_single_write(fe, RESET, 0x80);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x01);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x00);
+
+       zl10353_single_write(fe, AGC_TARGET, 0x28);
+
+       if (c->transmission_mode != TRANSMISSION_MODE_AUTO)
+               acq_ctl |= (1 << 0);
+       if (c->guard_interval != GUARD_INTERVAL_AUTO)
+               acq_ctl |= (1 << 1);
+       zl10353_single_write(fe, ACQ_CTL, acq_ctl);
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               /* These are extrapolated from the 7 and 8MHz values */
+               zl10353_single_write(fe, MCLK_RATIO, 0x97);
+               zl10353_single_write(fe, 0x64, 0x34);
+               zl10353_single_write(fe, 0xcc, 0xdd);
+               break;
+       case 7000000:
+               zl10353_single_write(fe, MCLK_RATIO, 0x86);
+               zl10353_single_write(fe, 0x64, 0x35);
+               zl10353_single_write(fe, 0xcc, 0x73);
+               break;
+       default:
+               c->bandwidth_hz = 8000000;
+               /* fall though */
+       case 8000000:
+               zl10353_single_write(fe, MCLK_RATIO, 0x75);
+               zl10353_single_write(fe, 0x64, 0x36);
+               zl10353_single_write(fe, 0xcc, 0x73);
+       }
+
+       zl10353_calc_nominal_rate(fe, c->bandwidth_hz, &nominal_rate);
+       zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate));
+       zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate));
+       state->bandwidth = c->bandwidth_hz;
+
+       zl10353_calc_input_freq(fe, &input_freq);
+       zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq));
+       zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq));
+
+       /* Hint at TPS settings */
+       switch (c->code_rate_HP) {
+       case FEC_2_3:
+               tps |= (1 << 7);
+               break;
+       case FEC_3_4:
+               tps |= (2 << 7);
+               break;
+       case FEC_5_6:
+               tps |= (3 << 7);
+               break;
+       case FEC_7_8:
+               tps |= (4 << 7);
+               break;
+       case FEC_1_2:
+       case FEC_AUTO:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (c->code_rate_LP) {
+       case FEC_2_3:
+               tps |= (1 << 4);
+               break;
+       case FEC_3_4:
+               tps |= (2 << 4);
+               break;
+       case FEC_5_6:
+               tps |= (3 << 4);
+               break;
+       case FEC_7_8:
+               tps |= (4 << 4);
+               break;
+       case FEC_1_2:
+       case FEC_AUTO:
+               break;
+       case FEC_NONE:
+               if (c->hierarchy == HIERARCHY_AUTO ||
+                   c->hierarchy == HIERARCHY_NONE)
+                       break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (c->modulation) {
+       case QPSK:
+               break;
+       case QAM_AUTO:
+       case QAM_16:
+               tps |= (1 << 13);
+               break;
+       case QAM_64:
+               tps |= (2 << 13);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (c->transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+       case TRANSMISSION_MODE_AUTO:
+               break;
+       case TRANSMISSION_MODE_8K:
+               tps |= (1 << 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (c->guard_interval) {
+       case GUARD_INTERVAL_1_32:
+       case GUARD_INTERVAL_AUTO:
+               break;
+       case GUARD_INTERVAL_1_16:
+               tps |= (1 << 2);
+               break;
+       case GUARD_INTERVAL_1_8:
+               tps |= (2 << 2);
+               break;
+       case GUARD_INTERVAL_1_4:
+               tps |= (3 << 2);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (c->hierarchy) {
+       case HIERARCHY_AUTO:
+       case HIERARCHY_NONE:
+               break;
+       case HIERARCHY_1:
+               tps |= (1 << 10);
+               break;
+       case HIERARCHY_2:
+               tps |= (2 << 10);
+               break;
+       case HIERARCHY_4:
+               tps |= (3 << 10);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       zl10353_single_write(fe, TPS_GIVEN_1, msb(tps));
+       zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps));
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       /*
+        * If there is no tuner attached to the secondary I2C bus, we call
+        * set_params to program a potential tuner attached somewhere else.
+        * Otherwise, we update the PLL registers via calc_regs.
+        */
+       if (state->config.no_tuner) {
+               if (fe->ops.tuner_ops.set_params) {
+                       fe->ops.tuner_ops.set_params(fe);
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+       } else if (fe->ops.tuner_ops.calc_regs) {
+               fe->ops.tuner_ops.calc_regs(fe, pllbuf + 1, 5);
+               pllbuf[1] <<= 1;
+               zl10353_write(fe, pllbuf, sizeof(pllbuf));
+       }
+
+       zl10353_single_write(fe, 0x5F, 0x13);
+
+       /* If no attached tuner or invalid PLL registers, just start the FSM. */
+       if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL)
+               zl10353_single_write(fe, FSM_GO, 0x01);
+       else
+               zl10353_single_write(fe, TUNER_GO, 0x01);
+
+       return 0;
+}
+
+static int zl10353_get_parameters(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct zl10353_state *state = fe->demodulator_priv;
+       int s6, s9;
+       u16 tps;
+       static const u8 tps_fec_to_api[8] = {
+               FEC_1_2,
+               FEC_2_3,
+               FEC_3_4,
+               FEC_5_6,
+               FEC_7_8,
+               FEC_AUTO,
+               FEC_AUTO,
+               FEC_AUTO
+       };
+
+       s6 = zl10353_read_register(state, STATUS_6);
+       s9 = zl10353_read_register(state, STATUS_9);
+       if (s6 < 0 || s9 < 0)
+               return -EREMOTEIO;
+       if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0)
+               return -EINVAL; /* no FE or TPS lock */
+
+       tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 |
+             zl10353_read_register(state, TPS_RECEIVED_0);
+
+       c->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
+       c->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
+
+       switch ((tps >> 13) & 3) {
+       case 0:
+               c->modulation = QPSK;
+               break;
+       case 1:
+               c->modulation = QAM_16;
+               break;
+       case 2:
+               c->modulation = QAM_64;
+               break;
+       default:
+               c->modulation = QAM_AUTO;
+               break;
+       }
+
+       c->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K :
+                                              TRANSMISSION_MODE_2K;
+
+       switch ((tps >> 2) & 3) {
+       case 0:
+               c->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               c->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               c->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               c->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       default:
+               c->guard_interval = GUARD_INTERVAL_AUTO;
+               break;
+       }
+
+       switch ((tps >> 10) & 7) {
+       case 0:
+               c->hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               c->hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               c->hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               c->hierarchy = HIERARCHY_4;
+               break;
+       default:
+               c->hierarchy = HIERARCHY_AUTO;
+               break;
+       }
+
+       c->frequency = state->frequency;
+       c->bandwidth_hz = state->bandwidth;
+       c->inversion = INVERSION_AUTO;
+
+       return 0;
+}
+
+static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       int s6, s7, s8;
+
+       if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
+               return -EREMOTEIO;
+       if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
+               return -EREMOTEIO;
+       if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
+               return -EREMOTEIO;
+
+       *status = 0;
+       if (s6 & (1 << 2))
+               *status |= FE_HAS_CARRIER;
+       if (s6 & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if (s6 & (1 << 5))
+               *status |= FE_HAS_LOCK;
+       if (s7 & (1 << 4))
+               *status |= FE_HAS_SYNC;
+       if (s8 & (1 << 6))
+               *status |= FE_HAS_SIGNAL;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+           (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+
+       *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 |
+              zl10353_read_register(state, RS_ERR_CNT_1) << 8 |
+              zl10353_read_register(state, RS_ERR_CNT_0);
+
+       return 0;
+}
+
+static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+
+       u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 |
+                    zl10353_read_register(state, AGC_GAIN_0) << 2 | 3;
+
+       *strength = ~signal;
+
+       return 0;
+}
+
+static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 _snr;
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+
+       _snr = zl10353_read_register(state, SNR);
+       *snr = 10 * _snr / 8;
+
+       return 0;
+}
+
+static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u32 ubl = 0;
+
+       ubl = zl10353_read_register(state, RS_UBC_1) << 8 |
+            zl10353_read_register(state, RS_UBC_0);
+
+       state->ucblocks += ubl;
+       *ucblocks = state->ucblocks;
+
+       return 0;
+}
+
+static int zl10353_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings
+                                        *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 1000;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static int zl10353_init(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+       if (state->config.parallel_ts)
+               zl10353_reset_attach[2] &= ~0x20;
+       if (state->config.clock_ctl_1)
+               zl10353_reset_attach[3] = state->config.clock_ctl_1;
+       if (state->config.pll_0)
+               zl10353_reset_attach[4] = state->config.pll_0;
+
+       /* Do a "hard" reset if not already done */
+       if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
+           zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
+               zl10353_write(fe, zl10353_reset_attach,
+                                  sizeof(zl10353_reset_attach));
+               if (debug_regs)
+                       zl10353_dump_regs(fe);
+       }
+
+       return 0;
+}
+
+static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 val = 0x0a;
+
+       if (state->config.disable_i2c_gate_ctrl) {
+               /* No tuner attached to the internal I2C bus */
+               /* If set enable I2C bridge, the main I2C bus stopped hardly */
+               return 0;
+       }
+
+       if (enable)
+               val |= 0x10;
+
+       return zl10353_single_write(fe, 0x62, val);
+}
+
+static void zl10353_release(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops zl10353_ops;
+
+struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct zl10353_state *state = NULL;
+       int id;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config, config, sizeof(struct zl10353_config));
+
+       /* check if the demod is there */
+       id = zl10353_read_register(state, CHIP_ID);
+       if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops zl10353_ops = {
+       .delsys = { SYS_DVBT },
+       .info = {
+               .name                   = "Zarlink ZL10353 DVB-T",
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = zl10353_release,
+
+       .init = zl10353_init,
+       .sleep = zl10353_sleep,
+       .i2c_gate_ctrl = zl10353_i2c_gate_ctrl,
+       .write = zl10353_write,
+
+       .set_frontend = zl10353_set_parameters,
+       .get_frontend = zl10353_get_parameters,
+       .get_tune_settings = zl10353_get_tune_settings,
+
+       .read_status = zl10353_read_status,
+       .read_ber = zl10353_read_ber,
+       .read_signal_strength = zl10353_read_signal_strength,
+       .read_snr = zl10353_read_snr,
+       .read_ucblocks = zl10353_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+module_param(debug_regs, int, 0644);
+MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
+
+MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
+MODULE_AUTHOR("Chris Pascoe");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(zl10353_attach);
diff --git a/drivers/media/dvb-frontends/zl10353.h b/drivers/media/dvb-frontends/zl10353.h
new file mode 100644 (file)
index 0000000..6e3ca9e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef ZL10353_H
+#define ZL10353_H
+
+#include <linux/dvb/frontend.h>
+
+struct zl10353_config
+{
+       /* demodulator's I2C address */
+       u8 demod_address;
+
+       /* frequencies in units of 0.1kHz */
+       int adc_clock;  /* default: 450560 (45.056  MHz) */
+       int if2;        /* default: 361667 (36.1667 MHz) */
+
+       /* set if no pll is connected to the secondary i2c bus */
+       int no_tuner;
+
+       /* set if parallel ts output is required */
+       int parallel_ts;
+
+       /* set if i2c_gate_ctrl disable is required */
+       u8 disable_i2c_gate_ctrl:1;
+
+       /* clock control registers (0x51-0x54) */
+       u8 clock_ctl_1;  /* default: 0x46 */
+       u8 pll_0;        /* default: 0x15 */
+};
+
+#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
+extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
+                                          struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
+                                          struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_ZL10353 */
+
+#endif /* ZL10353_H */
diff --git a/drivers/media/dvb-frontends/zl10353_priv.h b/drivers/media/dvb-frontends/zl10353_priv.h
new file mode 100644 (file)
index 0000000..e0dd1d3
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _ZL10353_PRIV_
+#define _ZL10353_PRIV_
+
+#define ID_ZL10353     0x14 /* Zarlink ZL10353 */
+#define ID_CE6230      0x18 /* Intel CE6230 */
+#define ID_CE6231      0x19 /* Intel CE6231 */
+
+#define msb(x) (((x) >> 8) & 0xff)
+#define lsb(x) ((x) & 0xff)
+
+enum zl10353_reg_addr {
+       INTERRUPT_0        = 0x00,
+       INTERRUPT_1        = 0x01,
+       INTERRUPT_2        = 0x02,
+       INTERRUPT_3        = 0x03,
+       INTERRUPT_4        = 0x04,
+       INTERRUPT_5        = 0x05,
+       STATUS_6           = 0x06,
+       STATUS_7           = 0x07,
+       STATUS_8           = 0x08,
+       STATUS_9           = 0x09,
+       AGC_GAIN_1         = 0x0A,
+       AGC_GAIN_0         = 0x0B,
+       SNR                = 0x10,
+       RS_ERR_CNT_2       = 0x11,
+       RS_ERR_CNT_1       = 0x12,
+       RS_ERR_CNT_0       = 0x13,
+       RS_UBC_1           = 0x14,
+       RS_UBC_0           = 0x15,
+       TPS_RECEIVED_1     = 0x1D,
+       TPS_RECEIVED_0     = 0x1E,
+       TPS_CURRENT_1      = 0x1F,
+       TPS_CURRENT_0      = 0x20,
+       CLOCK_CTL_0        = 0x51,
+       CLOCK_CTL_1        = 0x52,
+       PLL_0              = 0x53,
+       PLL_1              = 0x54,
+       RESET              = 0x55,
+       AGC_TARGET         = 0x56,
+       MCLK_RATIO         = 0x5C,
+       ACQ_CTL            = 0x5E,
+       TRL_NOMINAL_RATE_1 = 0x65,
+       TRL_NOMINAL_RATE_0 = 0x66,
+       INPUT_FREQ_1       = 0x6C,
+       INPUT_FREQ_0       = 0x6D,
+       TPS_GIVEN_1        = 0x6E,
+       TPS_GIVEN_0        = 0x6F,
+       TUNER_GO           = 0x70,
+       FSM_GO             = 0x71,
+       CHIP_ID            = 0x7F,
+       CHAN_STEP_1        = 0xE4,
+       CHAN_STEP_0        = 0xE5,
+       OFDM_LOCK_TIME     = 0xE7,
+       FEC_LOCK_TIME      = 0xE8,
+       ACQ_DELAY          = 0xE9,
+};
+
+#endif                          /* _ZL10353_PRIV_ */
index 5a2c4bd75480199eff3d6cbf32b091f90edc4780..e610c361d185b0d15af13b1161ed049790e242c6 100644 (file)
@@ -59,8 +59,4 @@ comment "Supported ddbridge ('Octopus') Adapters"
        depends on DVB_CORE && PCI && I2C
        source "drivers/media/dvb/ddbridge/Kconfig"
 
-comment "Supported DVB Frontends"
-       depends on DVB_CORE
-source "drivers/media/dvb/frontends/Kconfig"
-
 endif # DVB_CAPTURE_DRIVERS
index b14aa9dd0156bc41aa58340d4fff0a70a8f01042..0cee8f82a5d43e51bc90c427a3a0f718ca2b7d28 100644 (file)
@@ -2,8 +2,7 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        :=        frontends/      \
-               ttpci/          \
+obj-y        :=        ttpci/          \
                ttusb-dec/      \
                ttusb-budget/   \
                b2c2/           \
index e4291e4aba2347bb24d60ddd8b9e2adc4767d69f..7a1f5ce6d3220268218896fc3459d37b84459b46 100644 (file)
@@ -12,5 +12,5 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
 b2c2-flexcop-usb-objs = flexcop-usb.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/common/tuners/
index 7c2dd04d37e47073730bb9e5d6be6e5eaf1dfeb2..36591ae505f48ec9896f803ac4302fe0e01dcfe0 100644 (file)
@@ -1,6 +1,6 @@
 obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/video/bt8xx
 ccflags-y += -Idrivers/media/common/tuners
index 9eca27dd732840045fac9dfe7c4f96a1c46f3b88..9d083c98ce587c701d1d20c16a0ca17818b746b8 100644 (file)
@@ -7,7 +7,7 @@ ddbridge-objs := ddbridge-core.o
 obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
 
 ccflags-y += -Idrivers/media/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/common/tuners/
 
 # For the staging CI driver cxd2099
index 0dc5963ee807e5d8ed99740ce04a15f353adf3c1..327585143c83ee00cea2365d4118a65b20e48a85 100644 (file)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_DM1105) += dm1105.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
index 9fef543dac21bc912547ed7650d567dbb465c5a5..24248b3acd4f19bca198947ec9f020d8c04dd24f 100644 (file)
@@ -43,6 +43,6 @@ dvb-usb-rtl28xxu-objs = rtl28xxu.o
 obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 
index cc95b116bbc25829aeae572dcaa1cddfeb01bee3..a5630e30eadcfe23739045ebf3fba5bb02fea108 100644 (file)
@@ -76,7 +76,7 @@ dvb-usb-technisat-usb2-objs = technisat-usb2.o
 obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
 # due to tuner-xc3028
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
deleted file mode 100644 (file)
index a08c215..0000000
+++ /dev/null
@@ -1,756 +0,0 @@
-config DVB_FE_CUSTOMISE
-       bool "Customise the frontend modules to build"
-       depends on DVB_CORE
-       depends on EXPERT
-       default y if EXPERT
-       help
-         This allows the user to select/deselect frontend drivers for their
-         hardware from the build.
-
-         Use this option with care as deselecting frontends which are in fact
-         necessary will result in DVB devices which cannot be tuned due to lack
-         of driver support.
-
-         If unsure say N.
-
-menu "Customise DVB Frontends"
-       visible if DVB_FE_CUSTOMISE
-
-comment "Multistandard (satellite) frontends"
-       depends on DVB_CORE
-
-config DVB_STB0899
-       tristate "STB0899 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
-         to support this demodulator based frontends
-
-config DVB_STB6100
-       tristate "STB6100 based tuners"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A Silicon tuner from ST used in conjunction with the STB0899
-         demodulator. Say Y when you want to support this tuner.
-
-config DVB_STV090x
-       tristate "STV0900/STV0903(A/B) based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
-         Say Y when you want to support these frontends.
-
-config DVB_STV6110x
-       tristate "STV6110/(A) based tuners"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A Silicon tuner that supports DVB-S and DVB-S2 modes
-
-comment "Multistandard (cable + terrestrial) frontends"
-       depends on DVB_CORE
-
-config DVB_DRXK
-       tristate "Micronas DRXK based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Micronas DRX-K DVB-C/T demodulator.
-
-         Say Y when you want to support this frontend.
-
-config DVB_TDA18271C2DD
-       tristate "NXP TDA18271C2 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         NXP TDA18271 silicon tuner.
-
-         Say Y when you want to support this tuner.
-
-comment "DVB-S (satellite) frontends"
-       depends on DVB_CORE
-
-config DVB_CX24110
-       tristate "Conexant CX24110 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_CX24123
-       tristate "Conexant CX24123 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_MT312
-       tristate "Zarlink VP310/MT312/ZL10313 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_ZL10036
-       tristate "Zarlink ZL10036 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_ZL10039
-       tristate "Zarlink ZL10039 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_S5H1420
-       tristate "Samsung S5H1420 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_STV0288
-       tristate "ST STV0288 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_STB6000
-       tristate "ST STB6000 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-         help
-         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
-
-config DVB_STV0299
-       tristate "ST STV0299 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_STV6110
-       tristate "ST STV6110 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-         help
-         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
-
-config DVB_STV0900
-       tristate "ST STV0900 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
-
-config DVB_TDA8083
-       tristate "Philips TDA8083 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA10086
-       tristate "Philips TDA10086 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA8261
-       tristate "Philips TDA8261 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_VES1X93
-       tristate "VLSI VES1893 or VES1993 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_TUNER_ITD1000
-       tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_TUNER_CX24113
-       tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-
-config DVB_TDA826X
-       tristate "Philips TDA826X silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S silicon tuner module. Say Y when you want to support this tuner.
-
-config DVB_TUA6100
-       tristate "Infineon TUA6100 PLL"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S PLL chip.
-
-config DVB_CX24116
-       tristate "Conexant CX24116 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
-
-config DVB_SI21XX
-       tristate "Silicon Labs SI21XX based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_DS3000
-       tristate "Montage Tehnology DS3000 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
-
-config DVB_MB86A16
-       tristate "Fujitsu MB86A16 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S/DSS Direct Conversion reveiver.
-         Say Y when you want to support this frontend.
-
-config DVB_TDA10071
-       tristate "NXP TDA10071"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-comment "DVB-T (terrestrial) frontends"
-       depends on DVB_CORE
-
-config DVB_SP8870
-       tristate "Spase sp8870 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the command
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
-         download/extract it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-config DVB_SP887X
-       tristate "Spase sp887x based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the command
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
-         download/extract it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-config DVB_CX22700
-       tristate "Conexant CX22700 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_CX22702
-       tristate "Conexant cx22702 demodulator (OFDM)"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_S5H1432
-       tristate "Samsung s5h1432 demodulator (OFDM)"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_DRXD
-       tristate "Micronas DRXD driver"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-         Note: this driver was based on vendor driver reference code (released
-         under the GPL) as opposed to the existing drx397xd driver, which
-         was written via reverse engineering.
-
-config DVB_L64781
-       tristate "LSI L64781"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA1004X
-       tristate "Philips TDA10045H/TDA10046H based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the commands
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
-         download/extract them, and then copy them to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-config DVB_NXT6000
-       tristate "NxtWave Communications NXT6000 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_MT352
-       tristate "Zarlink MT352 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_ZL10353
-       tristate "Zarlink ZL10353 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_DIB3000MB
-       tristate "DiBcom 3000M-B"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
-         to support this frontend.
-
-config DVB_DIB3000MC
-       tristate "DiBcom 3000P/M-C"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
-         to support this frontend.
-
-config DVB_DIB7000M
-       tristate "DiBcom 7000MA/MB/PA/PB/MC"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
-         to support this frontend.
-
-config DVB_DIB7000P
-       tristate "DiBcom 7000PC"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
-         to support this frontend.
-
-config DVB_DIB9000
-       tristate "DiBcom 9000"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Designed for mobile usage. Say Y when you want
-         to support this frontend.
-
-config DVB_TDA10048
-       tristate "Philips TDA10048HN based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module. Say Y when you want to support this frontend.
-
-config DVB_AF9013
-       tristate "Afatech AF9013 demodulator"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-config DVB_EC100
-       tristate "E3C EC100"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-config DVB_HD29L2
-       tristate "HDIC HD29L2"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-config DVB_STV0367
-       tristate "ST STV0367 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T/C tuner module. Say Y when you want to support this frontend.
-
-config DVB_CXD2820R
-       tristate "Sony CXD2820R"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-config DVB_RTL2830
-       tristate "Realtek RTL2830 DVB-T"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-config DVB_RTL2832
-       tristate "Realtek RTL2832 DVB-T"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Say Y when you want to support this frontend.
-
-comment "DVB-C (cable) frontends"
-       depends on DVB_CORE
-
-config DVB_VES1820
-       tristate "VLSI VES1820 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA10021
-       tristate "Philips TDA10021 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA10023
-       tristate "Philips TDA10023 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
-config DVB_STV0297
-       tristate "ST STV0297 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
-comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
-       depends on DVB_CORE
-
-config DVB_NXT200X
-       tristate "NxtWave Communications NXT2002/NXT2004 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-         This driver needs external firmware. Please use the commands
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
-         download/extract them, and then copy them to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-config DVB_OR51211
-       tristate "Oren OR51211 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the command
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
-         download it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
-config DVB_OR51132
-       tristate "Oren OR51132 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-         This driver needs external firmware. Please use the commands
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
-         download firmwares for 8VSB and QAM64/256, respectively. Copy them to
-         /usr/lib/hotplug/firmware or /lib/firmware (depending on
-         configuration of firmware hotplug).
-
-config DVB_BCM3510
-       tristate "Broadcom BCM3510"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
-         support this frontend.
-
-config DVB_LGDT330X
-       tristate "LG Electronics LGDT3302/LGDT3303 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-config DVB_LGDT3305
-       tristate "LG Electronics LGDT3304 and LGDT3305 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-config DVB_LG2160
-       tristate "LG Electronics LG216x based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC/MH demodulator module. Say Y when you want
-         to support this frontend.
-
-config DVB_S5H1409
-       tristate "Samsung S5H1409 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-config DVB_AU8522
-       depends on I2C
-       tristate
-
-config DVB_AU8522_DTV
-       tristate "Auvitek AU8522 based DTV demod"
-       depends on DVB_CORE && I2C
-       select DVB_AU8522
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
-         you want to enable DTV demodulation support for this frontend.
-
-config DVB_AU8522_V4L
-       tristate "Auvitek AU8522 based ATV demod"
-       depends on VIDEO_V4L2 && I2C
-       select DVB_AU8522
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
-         you want to enable ATV demodulation support for this frontend.
-
-config DVB_S5H1411
-       tristate "Samsung S5H1411 based"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
-         to support this frontend.
-
-comment "ISDB-T (terrestrial) frontends"
-       depends on DVB_CORE
-
-config DVB_S921
-       tristate "Sharp S921 frontend"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
-         Say Y when you want to support this frontend.
-
-config DVB_DIB8000
-       tristate "DiBcom 8000MB/MC"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
-         Say Y when you want to support this frontend.
-
-config DVB_MB86A20S
-       tristate "Fujitsu mb86a20s"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
-         Say Y when you want to support this frontend.
-
-comment "Digital terrestrial only tuners/PLL"
-       depends on DVB_CORE
-
-config DVB_PLL
-       tristate "Generic I2C PLL based tuners"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         This module drives a number of tuners based on PLL chips with a
-         common I2C interface. Say Y when you want to support these tuners.
-
-config DVB_TUNER_DIB0070
-       tristate "DiBcom DiB0070 silicon base-band tuner"
-       depends on I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner DiB0070 from DiBcom.
-         This device is only used inside a SiP called together with a
-         demodulator for now.
-
-config DVB_TUNER_DIB0090
-       tristate "DiBcom DiB0090 silicon base-band tuner"
-       depends on I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner DiB0090 from DiBcom.
-         This device is only used inside a SiP called together with a
-         demodulator for now.
-
-comment "SEC control devices for DVB-S"
-       depends on DVB_CORE
-
-config DVB_LNBP21
-       tristate "LNBP21/LNBH24 SEC controllers"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An SEC control chips.
-
-config DVB_LNBP22
-       tristate "LNBP22 SEC controllers"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         LNB power supply and control voltage
-         regulator chip with step-up converter
-         and I2C interface.
-         Say Y when you want to support this chip.
-
-config DVB_ISL6405
-       tristate "ISL6405 SEC controller"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An SEC control chip.
-
-config DVB_ISL6421
-       tristate "ISL6421 SEC controller"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         An SEC control chip.
-
-config DVB_ISL6423
-       tristate "ISL6423 SEC controller"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A SEC controller chip from Intersil
-
-config DVB_A8293
-       tristate "Allegro A8293"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-
-config DVB_LGS8GL5
-       tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DMB-TH tuner module. Say Y when you want to support this frontend.
-
-config DVB_LGS8GXX
-       tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
-       depends on DVB_CORE && I2C
-       select FW_LOADER
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DMB-TH tuner module. Say Y when you want to support this frontend.
-
-config DVB_ATBM8830
-       tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DMB-TH tuner module. Say Y when you want to support this frontend.
-
-config DVB_TDA665x
-       tristate "TDA665x tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         Support for tuner modules based on Philips TDA6650/TDA6651 chips.
-         Say Y when you want to support this chip.
-
-         Currently supported tuners:
-         * Panasonic ENV57H12D5 (ET-50DT)
-
-config DVB_IX2505V
-       tristate "Sharp IX2505V silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
-config DVB_IT913X_FE
-       tristate "it913x frontend and it9137 tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-T tuner module.
-         Say Y when you want to support this frontend.
-
-config DVB_M88RS2000
-       tristate "M88RS2000 DVB-S demodulator and tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A DVB-S tuner module.
-         Say Y when you want to support this frontend.
-
-config DVB_AF9033
-       tristate "Afatech AF9033 DVB-T demodulator"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-
-comment "Tools to develop new frontends"
-
-config DVB_DUMMY_FE
-       tristate "Dummy frontend driver"
-       default n
-endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
deleted file mode 100644 (file)
index a378c52..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# Makefile for the kernel DVB frontend device drivers.
-#
-
-ccflags-y += -I$(srctree)/drivers/media/dvb-core/
-ccflags-y += -I$(srctree)/drivers/media/common/tuners/
-
-stb0899-objs = stb0899_drv.o stb0899_algo.o
-stv0900-objs = stv0900_core.o stv0900_sw.o
-drxd-objs = drxd_firm.o drxd_hard.o
-cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
-drxk-objs := drxk_hard.o
-
-obj-$(CONFIG_DVB_PLL) += dvb-pll.o
-obj-$(CONFIG_DVB_STV0299) += stv0299.o
-obj-$(CONFIG_DVB_STB0899) += stb0899.o
-obj-$(CONFIG_DVB_STB6100) += stb6100.o
-obj-$(CONFIG_DVB_SP8870) += sp8870.o
-obj-$(CONFIG_DVB_CX22700) += cx22700.o
-obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
-obj-$(CONFIG_DVB_CX24110) += cx24110.o
-obj-$(CONFIG_DVB_TDA8083) += tda8083.o
-obj-$(CONFIG_DVB_L64781) += l64781.o
-obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
-obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
-obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
-obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
-obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
-obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
-obj-$(CONFIG_DVB_MT312) += mt312.o
-obj-$(CONFIG_DVB_VES1820) += ves1820.o
-obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
-obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
-obj-$(CONFIG_DVB_SP887X) += sp887x.o
-obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
-obj-$(CONFIG_DVB_MT352) += mt352.o
-obj-$(CONFIG_DVB_ZL10036) += zl10036.o
-obj-$(CONFIG_DVB_ZL10039) += zl10039.o
-obj-$(CONFIG_DVB_ZL10353) += zl10353.o
-obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_DRXD) += drxd.o
-obj-$(CONFIG_DVB_TDA10021) += tda10021.o
-obj-$(CONFIG_DVB_TDA10023) += tda10023.o
-obj-$(CONFIG_DVB_STV0297) += stv0297.o
-obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
-obj-$(CONFIG_DVB_OR51211) += or51211.o
-obj-$(CONFIG_DVB_OR51132) += or51132.o
-obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
-obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
-obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
-obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
-obj-$(CONFIG_DVB_LG2160) += lg2160.o
-obj-$(CONFIG_DVB_CX24123) += cx24123.o
-obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
-obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
-obj-$(CONFIG_DVB_ISL6405) += isl6405.o
-obj-$(CONFIG_DVB_ISL6421) += isl6421.o
-obj-$(CONFIG_DVB_TDA10086) += tda10086.o
-obj-$(CONFIG_DVB_TDA826X) += tda826x.o
-obj-$(CONFIG_DVB_TDA8261) += tda8261.o
-obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
-obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
-obj-$(CONFIG_DVB_TUA6100) += tua6100.o
-obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
-obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
-obj-$(CONFIG_DVB_AU8522) += au8522_common.o
-obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
-obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
-obj-$(CONFIG_DVB_TDA10048) += tda10048.o
-obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
-obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
-obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
-obj-$(CONFIG_DVB_TDA665x) += tda665x.o
-obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
-obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
-obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
-obj-$(CONFIG_DVB_AF9013) += af9013.o
-obj-$(CONFIG_DVB_CX24116) += cx24116.o
-obj-$(CONFIG_DVB_SI21XX) += si21xx.o
-obj-$(CONFIG_DVB_STV0288) += stv0288.o
-obj-$(CONFIG_DVB_STB6000) += stb6000.o
-obj-$(CONFIG_DVB_S921) += s921.o
-obj-$(CONFIG_DVB_STV6110) += stv6110.o
-obj-$(CONFIG_DVB_STV0900) += stv0900.o
-obj-$(CONFIG_DVB_STV090x) += stv090x.o
-obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
-obj-$(CONFIG_DVB_ISL6423) += isl6423.o
-obj-$(CONFIG_DVB_EC100) += ec100.o
-obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
-obj-$(CONFIG_DVB_DS3000) += ds3000.o
-obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
-obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
-obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
-obj-$(CONFIG_DVB_STV0367) += stv0367.o
-obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
-obj-$(CONFIG_DVB_DRXK) += drxk.o
-obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
-obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
-obj-$(CONFIG_DVB_A8293) += a8293.o
-obj-$(CONFIG_DVB_TDA10071) += tda10071.o
-obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
-obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
-obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
-obj-$(CONFIG_DVB_AF9033) += af9033.o
-
diff --git a/drivers/media/dvb/frontends/a8293.c b/drivers/media/dvb/frontends/a8293.c
deleted file mode 100644 (file)
index cff44a3..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Allegro A8293 SEC driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#include "dvb_frontend.h"
-#include "a8293.h"
-
-struct a8293_priv {
-       struct i2c_adapter *i2c;
-       const struct a8293_config *cfg;
-       u8 reg[2];
-};
-
-static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
-{
-       int ret;
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg->i2c_addr,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       if (rd)
-               msg[0].flags = I2C_M_RD;
-       else
-               msg[0].flags = 0;
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
-                               KBUILD_MODNAME, ret, rd);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
-{
-       return a8293_i2c(priv, val, len, 0);
-}
-
-static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
-{
-       return a8293_i2c(priv, val, len, 1);
-}
-
-static int a8293_set_voltage(struct dvb_frontend *fe,
-       fe_sec_voltage_t fe_sec_voltage)
-{
-       struct a8293_priv *priv = fe->sec_priv;
-       int ret;
-
-       dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
-                       fe_sec_voltage);
-
-       switch (fe_sec_voltage) {
-       case SEC_VOLTAGE_OFF:
-               /* ENB=0 */
-               priv->reg[0] = 0x10;
-               break;
-       case SEC_VOLTAGE_13:
-               /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
-               priv->reg[0] = 0x31;
-               break;
-       case SEC_VOLTAGE_18:
-               /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
-               priv->reg[0] = 0x38;
-               break;
-       default:
-               ret = -EINVAL;
-               goto err;
-       };
-
-       ret = a8293_wr(priv, &priv->reg[0], 1);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static void a8293_release_sec(struct dvb_frontend *fe)
-{
-       a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, const struct a8293_config *cfg)
-{
-       int ret;
-       struct a8293_priv *priv = NULL;
-       u8 buf[2];
-
-       /* allocate memory for the internal priv */
-       priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
-       if (priv == NULL) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       /* setup the priv */
-       priv->i2c = i2c;
-       priv->cfg = cfg;
-       fe->sec_priv = priv;
-
-       /* check if the SEC is there */
-       ret = a8293_rd(priv, buf, 2);
-       if (ret)
-               goto err;
-
-       /* ENB=0 */
-       priv->reg[0] = 0x10;
-       ret = a8293_wr(priv, &priv->reg[0], 1);
-       if (ret)
-               goto err;
-
-       /* TMODE=0, TGATE=1 */
-       priv->reg[1] = 0x82;
-       ret = a8293_wr(priv, &priv->reg[1], 1);
-       if (ret)
-               goto err;
-
-       fe->ops.release_sec = a8293_release_sec;
-
-       /* override frontend ops */
-       fe->ops.set_voltage = a8293_set_voltage;
-
-       dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
-                       KBUILD_MODNAME);
-
-       return fe;
-err:
-       dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(a8293_attach);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Allegro A8293 SEC driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/a8293.h b/drivers/media/dvb/frontends/a8293.h
deleted file mode 100644 (file)
index ed29e55..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Allegro A8293 SEC driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef A8293_H
-#define A8293_H
-
-struct a8293_config {
-       u8 i2c_addr;
-};
-
-#if defined(CONFIG_DVB_A8293) || \
-       (defined(CONFIG_DVB_A8293_MODULE) && defined(MODULE))
-extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, const struct a8293_config *cfg);
-#else
-static inline struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, const struct a8293_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* A8293_H */
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
deleted file mode 100644 (file)
index 5bc570d..0000000
+++ /dev/null
@@ -1,1524 +0,0 @@
-/*
- * Afatech AF9013 demodulator driver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "af9013_priv.h"
-
-int af9013_debug;
-module_param_named(debug, af9013_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-struct af9013_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct af9013_config config;
-
-       /* tuner/demod RF and IF AGC limits used for signal strength calc */
-       u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
-       u16 signal_strength;
-       u32 ber;
-       u32 ucblocks;
-       u16 snr;
-       u32 bandwidth_hz;
-       fe_status_t fe_status;
-       unsigned long set_frontend_jiffies;
-       unsigned long read_status_jiffies;
-       bool first_tune;
-       bool i2c_gate_state;
-       unsigned int statistics_step:3;
-       struct delayed_work statistics_work;
-};
-
-/* write multiple registers */
-static int af9013_wr_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
-       const u8 *val, int len)
-{
-       int ret;
-       u8 buf[3+len];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->config.i2c_addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = (reg >> 8) & 0xff;
-       buf[1] = (reg >> 0) & 0xff;
-       buf[2] = mbox;
-       memcpy(&buf[3], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed=%d reg=%04x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple registers */
-static int af9013_rd_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
-       u8 *val, int len)
-{
-       int ret;
-       u8 buf[3];
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->config.i2c_addr,
-                       .flags = 0,
-                       .len = 3,
-                       .buf = buf,
-               }, {
-                       .addr = priv->config.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       buf[0] = (reg >> 8) & 0xff;
-       buf[1] = (reg >> 0) & 0xff;
-       buf[2] = mbox;
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               warn("i2c rd failed=%d reg=%04x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* write multiple registers */
-static int af9013_wr_regs(struct af9013_state *priv, u16 reg, const u8 *val,
-       int len)
-{
-       int ret, i;
-       u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(1 << 0);
-
-       if ((priv->config.ts_mode == AF9013_TS_USB) &&
-               ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) {
-               mbox |= ((len - 1) << 2);
-               ret = af9013_wr_regs_i2c(priv, mbox, reg, val, len);
-       } else {
-               for (i = 0; i < len; i++) {
-                       ret = af9013_wr_regs_i2c(priv, mbox, reg+i, val+i, 1);
-                       if (ret)
-                               goto err;
-               }
-       }
-
-err:
-       return 0;
-}
-
-/* read multiple registers */
-static int af9013_rd_regs(struct af9013_state *priv, u16 reg, u8 *val, int len)
-{
-       int ret, i;
-       u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(0 << 0);
-
-       if ((priv->config.ts_mode == AF9013_TS_USB) &&
-               ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) {
-               mbox |= ((len - 1) << 2);
-               ret = af9013_rd_regs_i2c(priv, mbox, reg, val, len);
-       } else {
-               for (i = 0; i < len; i++) {
-                       ret = af9013_rd_regs_i2c(priv, mbox, reg+i, val+i, 1);
-                       if (ret)
-                               goto err;
-               }
-       }
-
-err:
-       return 0;
-}
-
-/* write single register */
-static int af9013_wr_reg(struct af9013_state *priv, u16 reg, u8 val)
-{
-       return af9013_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int af9013_rd_reg(struct af9013_state *priv, u16 reg, u8 *val)
-{
-       return af9013_rd_regs(priv, reg, val, 1);
-}
-
-static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val,
-       u8 len)
-{
-       u8 mbox = (1 << 7)|(1 << 6)|((len - 1) << 2)|(1 << 1)|(1 << 0);
-       return af9013_wr_regs_i2c(state, mbox, reg, val, len);
-}
-
-static int af9013_wr_reg_bits(struct af9013_state *state, u16 reg, int pos,
-       int len, u8 val)
-{
-       int ret;
-       u8 tmp, mask;
-
-       /* no need for read if whole reg is written */
-       if (len != 8) {
-               ret = af9013_rd_reg(state, reg, &tmp);
-               if (ret)
-                       return ret;
-
-               mask = (0xff >> (8 - len)) << pos;
-               val <<= pos;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return af9013_wr_reg(state, reg, val);
-}
-
-static int af9013_rd_reg_bits(struct af9013_state *state, u16 reg, int pos,
-       int len, u8 *val)
-{
-       int ret;
-       u8 tmp;
-
-       ret = af9013_rd_reg(state, reg, &tmp);
-       if (ret)
-               return ret;
-
-       *val = (tmp >> pos);
-       *val &= (0xff >> (8 - len));
-
-       return 0;
-}
-
-static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
-{
-       int ret;
-       u8 pos;
-       u16 addr;
-
-       dbg("%s: gpio=%d gpioval=%02x", __func__, gpio, gpioval);
-
-       /*
-        * GPIO0 & GPIO1 0xd735
-        * GPIO2 & GPIO3 0xd736
-        */
-
-       switch (gpio) {
-       case 0:
-       case 1:
-               addr = 0xd735;
-               break;
-       case 2:
-       case 3:
-               addr = 0xd736;
-               break;
-
-       default:
-               err("invalid gpio:%d\n", gpio);
-               ret = -EINVAL;
-               goto err;
-       };
-
-       switch (gpio) {
-       case 0:
-       case 2:
-               pos = 0;
-               break;
-       case 1:
-       case 3:
-       default:
-               pos = 4;
-               break;
-       };
-
-       ret = af9013_wr_reg_bits(state, addr, pos, 4, gpioval);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static u32 af913_div(u32 a, u32 b, u32 x)
-{
-       u32 r = 0, c = 0, i;
-
-       dbg("%s: a=%d b=%d x=%d", __func__, a, b, x);
-
-       if (a > b) {
-               c = a / b;
-               a = a - c * b;
-       }
-
-       for (i = 0; i < x; i++) {
-               if (a >= b) {
-                       r += 1;
-                       a -= b;
-               }
-               a <<= 1;
-               r <<= 1;
-       }
-       r = (c << (u32)x) + r;
-
-       dbg("%s: a=%d b=%d x=%d r=%x", __func__, a, b, x, r);
-       return r;
-}
-
-static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
-{
-       int ret, i;
-       u8 tmp;
-
-       dbg("%s: onoff=%d", __func__, onoff);
-
-       /* enable reset */
-       ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 1);
-       if (ret)
-               goto err;
-
-       /* start reset mechanism */
-       ret = af9013_wr_reg(state, 0xaeff, 1);
-       if (ret)
-               goto err;
-
-       /* wait reset performs */
-       for (i = 0; i < 150; i++) {
-               ret = af9013_rd_reg_bits(state, 0xd417, 1, 1, &tmp);
-               if (ret)
-                       goto err;
-
-               if (tmp)
-                       break; /* reset done */
-
-               usleep_range(5000, 25000);
-       }
-
-       if (!tmp)
-               return -ETIMEDOUT;
-
-       if (onoff) {
-               /* clear reset */
-               ret = af9013_wr_reg_bits(state, 0xd417, 1, 1, 0);
-               if (ret)
-                       goto err;
-
-               /* disable reset */
-               ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 0);
-
-               /* power on */
-               ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 0);
-       } else {
-               /* power off */
-               ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 1);
-       }
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-
-       dbg("%s", __func__);
-
-       /* reset and start BER counter */
-       ret = af9013_wr_reg_bits(state, 0xd391, 4, 1, 1);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[5];
-
-       dbg("%s", __func__);
-
-       /* check if error bit count is ready */
-       ret = af9013_rd_reg_bits(state, 0xd391, 4, 1, &buf[0]);
-       if (ret)
-               goto err;
-
-       if (!buf[0]) {
-               dbg("%s: not ready", __func__);
-               return 0;
-       }
-
-       ret = af9013_rd_regs(state, 0xd387, buf, 5);
-       if (ret)
-               goto err;
-
-       state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-       state->ucblocks += (buf[4] << 8) | buf[3];
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_statistics_snr_start(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-
-       dbg("%s", __func__);
-
-       /* start SNR meas */
-       ret = af9013_wr_reg_bits(state, 0xd2e1, 3, 1, 1);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_statistics_snr_result(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret, i, len;
-       u8 buf[3], tmp;
-       u32 snr_val;
-       const struct af9013_snr *uninitialized_var(snr_lut);
-
-       dbg("%s", __func__);
-
-       /* check if SNR ready */
-       ret = af9013_rd_reg_bits(state, 0xd2e1, 3, 1, &tmp);
-       if (ret)
-               goto err;
-
-       if (!tmp) {
-               dbg("%s: not ready", __func__);
-               return 0;
-       }
-
-       /* read value */
-       ret = af9013_rd_regs(state, 0xd2e3, buf, 3);
-       if (ret)
-               goto err;
-
-       snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
-       /* read current modulation */
-       ret = af9013_rd_reg(state, 0xd3c1, &tmp);
-       if (ret)
-               goto err;
-
-       switch ((tmp >> 6) & 3) {
-       case 0:
-               len = ARRAY_SIZE(qpsk_snr_lut);
-               snr_lut = qpsk_snr_lut;
-               break;
-       case 1:
-               len = ARRAY_SIZE(qam16_snr_lut);
-               snr_lut = qam16_snr_lut;
-               break;
-       case 2:
-               len = ARRAY_SIZE(qam64_snr_lut);
-               snr_lut = qam64_snr_lut;
-               break;
-       default:
-               goto err;
-               break;
-       }
-
-       for (i = 0; i < len; i++) {
-               tmp = snr_lut[i].snr;
-
-               if (snr_val < snr_lut[i].val)
-                       break;
-       }
-       state->snr = tmp * 10; /* dB/10 */
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_statistics_signal_strength(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret = 0;
-       u8 buf[2], rf_gain, if_gain;
-       int signal_strength;
-
-       dbg("%s", __func__);
-
-       if (!state->signal_strength_en)
-               return 0;
-
-       ret = af9013_rd_regs(state, 0xd07c, buf, 2);
-       if (ret)
-               goto err;
-
-       rf_gain = buf[0];
-       if_gain = buf[1];
-
-       signal_strength = (0xffff / \
-               (9 * (state->rf_50 + state->if_50) - \
-               11 * (state->rf_80 + state->if_80))) * \
-               (10 * (rf_gain + if_gain) - \
-               11 * (state->rf_80 + state->if_80));
-       if (signal_strength < 0)
-               signal_strength = 0;
-       else if (signal_strength > 0xffff)
-               signal_strength = 0xffff;
-
-       state->signal_strength = signal_strength;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static void af9013_statistics_work(struct work_struct *work)
-{
-       struct af9013_state *state = container_of(work,
-               struct af9013_state, statistics_work.work);
-       unsigned int next_msec;
-
-       /* update only signal strength when demod is not locked */
-       if (!(state->fe_status & FE_HAS_LOCK)) {
-               state->statistics_step = 0;
-               state->ber = 0;
-               state->snr = 0;
-       }
-
-       switch (state->statistics_step) {
-       default:
-               state->statistics_step = 0;
-       case 0:
-               af9013_statistics_signal_strength(&state->fe);
-               state->statistics_step++;
-               next_msec = 300;
-               break;
-       case 1:
-               af9013_statistics_snr_start(&state->fe);
-               state->statistics_step++;
-               next_msec = 200;
-               break;
-       case 2:
-               af9013_statistics_ber_unc_start(&state->fe);
-               state->statistics_step++;
-               next_msec = 1000;
-               break;
-       case 3:
-               af9013_statistics_snr_result(&state->fe);
-               state->statistics_step++;
-               next_msec = 400;
-               break;
-       case 4:
-               af9013_statistics_ber_unc_result(&state->fe);
-               state->statistics_step++;
-               next_msec = 100;
-               break;
-       }
-
-       schedule_delayed_work(&state->statistics_work,
-               msecs_to_jiffies(next_msec));
-}
-
-static int af9013_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 800;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-
-       return 0;
-}
-
-static int af9013_set_frontend(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, sampling_freq;
-       bool auto_mode, spec_inv;
-       u8 buf[6];
-       u32 if_frequency, freq_cw;
-
-       dbg("%s: frequency=%d bandwidth_hz=%d", __func__,
-               c->frequency, c->bandwidth_hz);
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* program CFOE coefficients */
-       if (c->bandwidth_hz != state->bandwidth_hz) {
-               for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
-                       if (coeff_lut[i].clock == state->config.clock &&
-                               coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
-                               break;
-                       }
-               }
-
-               ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val,
-                       sizeof(coeff_lut[i].val));
-       }
-
-       /* program frequency control */
-       if (c->bandwidth_hz != state->bandwidth_hz || state->first_tune) {
-               /* get used IF frequency */
-               if (fe->ops.tuner_ops.get_if_frequency)
-                       fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
-               else
-                       if_frequency = state->config.if_frequency;
-
-               sampling_freq = if_frequency;
-
-               while (sampling_freq > (state->config.clock / 2))
-                       sampling_freq -= state->config.clock;
-
-               if (sampling_freq < 0) {
-                       sampling_freq *= -1;
-                       spec_inv = state->config.spec_inv;
-               } else {
-                       spec_inv = !state->config.spec_inv;
-               }
-
-               freq_cw = af913_div(sampling_freq, state->config.clock, 23);
-
-               if (spec_inv)
-                       freq_cw = 0x800000 - freq_cw;
-
-               buf[0] = (freq_cw >>  0) & 0xff;
-               buf[1] = (freq_cw >>  8) & 0xff;
-               buf[2] = (freq_cw >> 16) & 0x7f;
-
-               freq_cw = 0x800000 - freq_cw;
-
-               buf[3] = (freq_cw >>  0) & 0xff;
-               buf[4] = (freq_cw >>  8) & 0xff;
-               buf[5] = (freq_cw >> 16) & 0x7f;
-
-               ret = af9013_wr_regs(state, 0xd140, buf, 3);
-               if (ret)
-                       goto err;
-
-               ret = af9013_wr_regs(state, 0x9be7, buf, 6);
-               if (ret)
-                       goto err;
-       }
-
-       /* clear TPS lock flag */
-       ret = af9013_wr_reg_bits(state, 0xd330, 3, 1, 1);
-       if (ret)
-               goto err;
-
-       /* clear MPEG2 lock flag */
-       ret = af9013_wr_reg_bits(state, 0xd507, 6, 1, 0);
-       if (ret)
-               goto err;
-
-       /* empty channel function */
-       ret = af9013_wr_reg_bits(state, 0x9bfe, 0, 1, 0);
-       if (ret)
-               goto err;
-
-       /* empty DVB-T channel function */
-       ret = af9013_wr_reg_bits(state, 0x9bc2, 0, 1, 0);
-       if (ret)
-               goto err;
-
-       /* transmission parameters */
-       auto_mode = false;
-       memset(buf, 0, 3);
-
-       switch (c->transmission_mode) {
-       case TRANSMISSION_MODE_AUTO:
-               auto_mode = 1;
-               break;
-       case TRANSMISSION_MODE_2K:
-               break;
-       case TRANSMISSION_MODE_8K:
-               buf[0] |= (1 << 0);
-               break;
-       default:
-               dbg("%s: invalid transmission_mode", __func__);
-               auto_mode = 1;
-       }
-
-       switch (c->guard_interval) {
-       case GUARD_INTERVAL_AUTO:
-               auto_mode = 1;
-               break;
-       case GUARD_INTERVAL_1_32:
-               break;
-       case GUARD_INTERVAL_1_16:
-               buf[0] |= (1 << 2);
-               break;
-       case GUARD_INTERVAL_1_8:
-               buf[0] |= (2 << 2);
-               break;
-       case GUARD_INTERVAL_1_4:
-               buf[0] |= (3 << 2);
-               break;
-       default:
-               dbg("%s: invalid guard_interval", __func__);
-               auto_mode = 1;
-       }
-
-       switch (c->hierarchy) {
-       case HIERARCHY_AUTO:
-               auto_mode = 1;
-               break;
-       case HIERARCHY_NONE:
-               break;
-       case HIERARCHY_1:
-               buf[0] |= (1 << 4);
-               break;
-       case HIERARCHY_2:
-               buf[0] |= (2 << 4);
-               break;
-       case HIERARCHY_4:
-               buf[0] |= (3 << 4);
-               break;
-       default:
-               dbg("%s: invalid hierarchy", __func__);
-               auto_mode = 1;
-       };
-
-       switch (c->modulation) {
-       case QAM_AUTO:
-               auto_mode = 1;
-               break;
-       case QPSK:
-               break;
-       case QAM_16:
-               buf[1] |= (1 << 6);
-               break;
-       case QAM_64:
-               buf[1] |= (2 << 6);
-               break;
-       default:
-               dbg("%s: invalid modulation", __func__);
-               auto_mode = 1;
-       }
-
-       /* Use HP. How and which case we can switch to LP? */
-       buf[1] |= (1 << 4);
-
-       switch (c->code_rate_HP) {
-       case FEC_AUTO:
-               auto_mode = 1;
-               break;
-       case FEC_1_2:
-               break;
-       case FEC_2_3:
-               buf[2] |= (1 << 0);
-               break;
-       case FEC_3_4:
-               buf[2] |= (2 << 0);
-               break;
-       case FEC_5_6:
-               buf[2] |= (3 << 0);
-               break;
-       case FEC_7_8:
-               buf[2] |= (4 << 0);
-               break;
-       default:
-               dbg("%s: invalid code_rate_HP", __func__);
-               auto_mode = 1;
-       }
-
-       switch (c->code_rate_LP) {
-       case FEC_AUTO:
-               auto_mode = 1;
-               break;
-       case FEC_1_2:
-               break;
-       case FEC_2_3:
-               buf[2] |= (1 << 3);
-               break;
-       case FEC_3_4:
-               buf[2] |= (2 << 3);
-               break;
-       case FEC_5_6:
-               buf[2] |= (3 << 3);
-               break;
-       case FEC_7_8:
-               buf[2] |= (4 << 3);
-               break;
-       case FEC_NONE:
-               break;
-       default:
-               dbg("%s: invalid code_rate_LP", __func__);
-               auto_mode = 1;
-       }
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               break;
-       case 7000000:
-               buf[1] |= (1 << 2);
-               break;
-       case 8000000:
-               buf[1] |= (2 << 2);
-               break;
-       default:
-               dbg("%s: invalid bandwidth_hz", __func__);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       ret = af9013_wr_regs(state, 0xd3c0, buf, 3);
-       if (ret)
-               goto err;
-
-       if (auto_mode) {
-               /* clear easy mode flag */
-               ret = af9013_wr_reg(state, 0xaefd, 0);
-               if (ret)
-                       goto err;
-
-               dbg("%s: auto params", __func__);
-       } else {
-               /* set easy mode flag */
-               ret = af9013_wr_reg(state, 0xaefd, 1);
-               if (ret)
-                       goto err;
-
-               ret = af9013_wr_reg(state, 0xaefe, 0);
-               if (ret)
-                       goto err;
-
-               dbg("%s: manual params", __func__);
-       }
-
-       /* tune */
-       ret = af9013_wr_reg(state, 0xffff, 0);
-       if (ret)
-               goto err;
-
-       state->bandwidth_hz = c->bandwidth_hz;
-       state->set_frontend_jiffies = jiffies;
-       state->first_tune = false;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-
-       dbg("%s", __func__);
-
-       ret = af9013_rd_regs(state, 0xd3c0, buf, 3);
-       if (ret)
-               goto err;
-
-       switch ((buf[1] >> 6) & 3) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       }
-
-       switch ((buf[0] >> 0) & 3) {
-       case 0:
-               c->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               c->transmission_mode = TRANSMISSION_MODE_8K;
-       }
-
-       switch ((buf[0] >> 2) & 3) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       switch ((buf[0] >> 4) & 7) {
-       case 0:
-               c->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               c->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               c->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               c->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-       switch ((buf[2] >> 0) & 7) {
-       case 0:
-               c->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_HP = FEC_7_8;
-               break;
-       }
-
-       switch ((buf[2] >> 3) & 7) {
-       case 0:
-               c->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       switch ((buf[1] >> 2) & 3) {
-       case 0:
-               c->bandwidth_hz = 6000000;
-               break;
-       case 1:
-               c->bandwidth_hz = 7000000;
-               break;
-       case 2:
-               c->bandwidth_hz = 8000000;
-               break;
-       }
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-
-       /*
-        * Return status from the cache if it is younger than 2000ms with the
-        * exception of last tune is done during 4000ms.
-        */
-       if (time_is_after_jiffies(
-               state->read_status_jiffies + msecs_to_jiffies(2000)) &&
-               time_is_before_jiffies(
-               state->set_frontend_jiffies + msecs_to_jiffies(4000))
-       ) {
-                       *status = state->fe_status;
-                       return 0;
-       } else {
-               *status = 0;
-       }
-
-       /* MPEG2 lock */
-       ret = af9013_rd_reg_bits(state, 0xd507, 6, 1, &tmp);
-       if (ret)
-               goto err;
-
-       if (tmp)
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-                       FE_HAS_SYNC | FE_HAS_LOCK;
-
-       if (!*status) {
-               /* TPS lock */
-               ret = af9013_rd_reg_bits(state, 0xd330, 3, 1, &tmp);
-               if (ret)
-                       goto err;
-
-               if (tmp)
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI;
-       }
-
-       state->fe_status = *status;
-       state->read_status_jiffies = jiffies;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       *snr = state->snr;
-       return 0;
-}
-
-static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       *strength = state->signal_strength;
-       return 0;
-}
-
-static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       *ber = state->ber;
-       return 0;
-}
-
-static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       *ucblocks = state->ucblocks;
-       return 0;
-}
-
-static int af9013_init(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret, i, len;
-       u8 buf[3], tmp;
-       u32 adc_cw;
-       const struct af9013_reg_bit *init;
-
-       dbg("%s", __func__);
-
-       /* power on */
-       ret = af9013_power_ctrl(state, 1);
-       if (ret)
-               goto err;
-
-       /* enable ADC */
-       ret = af9013_wr_reg(state, 0xd73a, 0xa4);
-       if (ret)
-               goto err;
-
-       /* write API version to firmware */
-       ret = af9013_wr_regs(state, 0x9bf2, state->config.api_version, 4);
-       if (ret)
-               goto err;
-
-       /* program ADC control */
-       switch (state->config.clock) {
-       case 28800000: /* 28.800 MHz */
-               tmp = 0;
-               break;
-       case 20480000: /* 20.480 MHz */
-               tmp = 1;
-               break;
-       case 28000000: /* 28.000 MHz */
-               tmp = 2;
-               break;
-       case 25000000: /* 25.000 MHz */
-               tmp = 3;
-               break;
-       default:
-               err("invalid clock");
-               return -EINVAL;
-       }
-
-       adc_cw = af913_div(state->config.clock, 1000000ul, 19);
-       buf[0] = (adc_cw >>  0) & 0xff;
-       buf[1] = (adc_cw >>  8) & 0xff;
-       buf[2] = (adc_cw >> 16) & 0xff;
-
-       ret = af9013_wr_regs(state, 0xd180, buf, 3);
-       if (ret)
-               goto err;
-
-       ret = af9013_wr_reg_bits(state, 0x9bd2, 0, 4, tmp);
-       if (ret)
-               goto err;
-
-       /* set I2C master clock */
-       ret = af9013_wr_reg(state, 0xd416, 0x14);
-       if (ret)
-               goto err;
-
-       /* set 16 embx */
-       ret = af9013_wr_reg_bits(state, 0xd700, 1, 1, 1);
-       if (ret)
-               goto err;
-
-       /* set no trigger */
-       ret = af9013_wr_reg_bits(state, 0xd700, 2, 1, 0);
-       if (ret)
-               goto err;
-
-       /* set read-update bit for constellation */
-       ret = af9013_wr_reg_bits(state, 0xd371, 1, 1, 1);
-       if (ret)
-               goto err;
-
-       /* settings for mp2if */
-       if (state->config.ts_mode == AF9013_TS_USB) {
-               /* AF9015 split PSB to 1.5k + 0.5k */
-               ret = af9013_wr_reg_bits(state, 0xd50b, 2, 1, 1);
-               if (ret)
-                       goto err;
-       } else {
-               /* AF9013 change the output bit to data7 */
-               ret = af9013_wr_reg_bits(state, 0xd500, 3, 1, 1);
-               if (ret)
-                       goto err;
-
-               /* AF9013 set mpeg to full speed */
-               ret = af9013_wr_reg_bits(state, 0xd502, 4, 1, 1);
-               if (ret)
-                       goto err;
-       }
-
-       ret = af9013_wr_reg_bits(state, 0xd520, 4, 1, 1);
-       if (ret)
-               goto err;
-
-       /* load OFSM settings */
-       dbg("%s: load ofsm settings", __func__);
-       len = ARRAY_SIZE(ofsm_init);
-       init = ofsm_init;
-       for (i = 0; i < len; i++) {
-               ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos,
-                       init[i].len, init[i].val);
-               if (ret)
-                       goto err;
-       }
-
-       /* load tuner specific settings */
-       dbg("%s: load tuner specific settings", __func__);
-       switch (state->config.tuner) {
-       case AF9013_TUNER_MXL5003D:
-               len = ARRAY_SIZE(tuner_init_mxl5003d);
-               init = tuner_init_mxl5003d;
-               break;
-       case AF9013_TUNER_MXL5005D:
-       case AF9013_TUNER_MXL5005R:
-       case AF9013_TUNER_MXL5007T:
-               len = ARRAY_SIZE(tuner_init_mxl5005);
-               init = tuner_init_mxl5005;
-               break;
-       case AF9013_TUNER_ENV77H11D5:
-               len = ARRAY_SIZE(tuner_init_env77h11d5);
-               init = tuner_init_env77h11d5;
-               break;
-       case AF9013_TUNER_MT2060:
-               len = ARRAY_SIZE(tuner_init_mt2060);
-               init = tuner_init_mt2060;
-               break;
-       case AF9013_TUNER_MC44S803:
-               len = ARRAY_SIZE(tuner_init_mc44s803);
-               init = tuner_init_mc44s803;
-               break;
-       case AF9013_TUNER_QT1010:
-       case AF9013_TUNER_QT1010A:
-               len = ARRAY_SIZE(tuner_init_qt1010);
-               init = tuner_init_qt1010;
-               break;
-       case AF9013_TUNER_MT2060_2:
-               len = ARRAY_SIZE(tuner_init_mt2060_2);
-               init = tuner_init_mt2060_2;
-               break;
-       case AF9013_TUNER_TDA18271:
-       case AF9013_TUNER_TDA18218:
-               len = ARRAY_SIZE(tuner_init_tda18271);
-               init = tuner_init_tda18271;
-               break;
-       case AF9013_TUNER_UNKNOWN:
-       default:
-               len = ARRAY_SIZE(tuner_init_unknown);
-               init = tuner_init_unknown;
-               break;
-       }
-
-       for (i = 0; i < len; i++) {
-               ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos,
-                       init[i].len, init[i].val);
-               if (ret)
-                       goto err;
-       }
-
-       /* TS mode */
-       ret = af9013_wr_reg_bits(state, 0xd500, 1, 2, state->config.ts_mode);
-       if (ret)
-               goto err;
-
-       /* enable lock led */
-       ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 1);
-       if (ret)
-               goto err;
-
-       /* check if we support signal strength */
-       if (!state->signal_strength_en) {
-               ret = af9013_rd_reg_bits(state, 0x9bee, 0, 1,
-                       &state->signal_strength_en);
-               if (ret)
-                       goto err;
-       }
-
-       /* read values needed for signal strength calculation */
-       if (state->signal_strength_en && !state->rf_50) {
-               ret = af9013_rd_reg(state, 0x9bbd, &state->rf_50);
-               if (ret)
-                       goto err;
-
-               ret = af9013_rd_reg(state, 0x9bd0, &state->rf_80);
-               if (ret)
-                       goto err;
-
-               ret = af9013_rd_reg(state, 0x9be2, &state->if_50);
-               if (ret)
-                       goto err;
-
-               ret = af9013_rd_reg(state, 0x9be4, &state->if_80);
-               if (ret)
-                       goto err;
-       }
-
-       /* SNR */
-       ret = af9013_wr_reg(state, 0xd2e2, 1);
-       if (ret)
-               goto err;
-
-       /* BER / UCB */
-       buf[0] = (10000 >> 0) & 0xff;
-       buf[1] = (10000 >> 8) & 0xff;
-       ret = af9013_wr_regs(state, 0xd385, buf, 2);
-       if (ret)
-               goto err;
-
-       /* enable FEC monitor */
-       ret = af9013_wr_reg_bits(state, 0xd392, 1, 1, 1);
-       if (ret)
-               goto err;
-
-       state->first_tune = true;
-       schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400));
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_sleep(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       int ret;
-
-       dbg("%s", __func__);
-
-       /* stop statistics polling */
-       cancel_delayed_work_sync(&state->statistics_work);
-
-       /* disable lock led */
-       ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 0);
-       if (ret)
-               goto err;
-
-       /* power off */
-       ret = af9013_power_ctrl(state, 0);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       int ret;
-       struct af9013_state *state = fe->demodulator_priv;
-
-       dbg("%s: enable=%d", __func__, enable);
-
-       /* gate already open or close */
-       if (state->i2c_gate_state == enable)
-               return 0;
-
-       if (state->config.ts_mode == AF9013_TS_USB)
-               ret = af9013_wr_reg_bits(state, 0xd417, 3, 1, enable);
-       else
-               ret = af9013_wr_reg_bits(state, 0xd607, 2, 1, enable);
-       if (ret)
-               goto err;
-
-       state->i2c_gate_state = enable;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static void af9013_release(struct dvb_frontend *fe)
-{
-       struct af9013_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops af9013_ops;
-
-static int af9013_download_firmware(struct af9013_state *state)
-{
-       int i, len, remaining, ret;
-       const struct firmware *fw;
-       u16 checksum = 0;
-       u8 val;
-       u8 fw_params[4];
-       u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
-
-       msleep(100);
-       /* check whether firmware is already running */
-       ret = af9013_rd_reg(state, 0x98be, &val);
-       if (ret)
-               goto err;
-       else
-               dbg("%s: firmware status=%02x", __func__, val);
-
-       if (val == 0x0c) /* fw is running, no need for download */
-               goto exit;
-
-       info("found a '%s' in cold state, will try to load a firmware",
-               af9013_ops.info.name);
-
-       /* request the firmware, this will block and timeout */
-       ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
-       if (ret) {
-               err("did not find the firmware file. (%s) "
-                       "Please see linux/Documentation/dvb/ for more details" \
-                       " on firmware-problems. (%d)",
-                       fw_file, ret);
-               goto err;
-       }
-
-       info("downloading firmware from file '%s'", fw_file);
-
-       /* calc checksum */
-       for (i = 0; i < fw->size; i++)
-               checksum += fw->data[i];
-
-       fw_params[0] = checksum >> 8;
-       fw_params[1] = checksum & 0xff;
-       fw_params[2] = fw->size >> 8;
-       fw_params[3] = fw->size & 0xff;
-
-       /* write fw checksum & size */
-       ret = af9013_write_ofsm_regs(state, 0x50fc,
-               fw_params, sizeof(fw_params));
-       if (ret)
-               goto err_release;
-
-       #define FW_ADDR 0x5100 /* firmware start address */
-       #define LEN_MAX 16 /* max packet size */
-       for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-               len = remaining;
-               if (len > LEN_MAX)
-                       len = LEN_MAX;
-
-               ret = af9013_write_ofsm_regs(state,
-                       FW_ADDR + fw->size - remaining,
-                       (u8 *) &fw->data[fw->size - remaining], len);
-               if (ret) {
-                       err("firmware download failed:%d", ret);
-                       goto err_release;
-               }
-       }
-
-       /* request boot firmware */
-       ret = af9013_wr_reg(state, 0xe205, 1);
-       if (ret)
-               goto err_release;
-
-       for (i = 0; i < 15; i++) {
-               msleep(100);
-
-               /* check firmware status */
-               ret = af9013_rd_reg(state, 0x98be, &val);
-               if (ret)
-                       goto err_release;
-
-               dbg("%s: firmware status=%02x", __func__, val);
-
-               if (val == 0x0c || val == 0x04) /* success or fail */
-                       break;
-       }
-
-       if (val == 0x04) {
-               err("firmware did not run");
-               ret = -ENODEV;
-       } else if (val != 0x0c) {
-               err("firmware boot timeout");
-               ret = -ENODEV;
-       }
-
-err_release:
-       release_firmware(fw);
-err:
-exit:
-       if (!ret)
-               info("found a '%s' in warm state.", af9013_ops.info.name);
-       return ret;
-}
-
-struct dvb_frontend *af9013_attach(const struct af9013_config *config,
-       struct i2c_adapter *i2c)
-{
-       int ret;
-       struct af9013_state *state = NULL;
-       u8 buf[4], i;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);
-       if (state == NULL)
-               goto err;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->config, config, sizeof(struct af9013_config));
-
-       /* download firmware */
-       if (state->config.ts_mode != AF9013_TS_USB) {
-               ret = af9013_download_firmware(state);
-               if (ret)
-                       goto err;
-       }
-
-       /* firmware version */
-       ret = af9013_rd_regs(state, 0x5103, buf, 4);
-       if (ret)
-               goto err;
-
-       info("firmware version %d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
-
-       /* set GPIOs */
-       for (i = 0; i < sizeof(state->config.gpio); i++) {
-               ret = af9013_set_gpio(state, i, state->config.gpio[i]);
-               if (ret)
-                       goto err;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->fe.ops, &af9013_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->fe.demodulator_priv = state;
-
-       INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work);
-
-       return &state->fe;
-err:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(af9013_attach);
-
-static struct dvb_frontend_ops af9013_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Afatech AF9013",
-               .frequency_min = 174000000,
-               .frequency_max = 862000000,
-               .frequency_stepsize = 250000,
-               .frequency_tolerance = 0,
-               .caps = FE_CAN_FEC_1_2 |
-                       FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 |
-                       FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = af9013_release,
-
-       .init = af9013_init,
-       .sleep = af9013_sleep,
-
-       .get_tune_settings = af9013_get_tune_settings,
-       .set_frontend = af9013_set_frontend,
-       .get_frontend = af9013_get_frontend,
-
-       .read_status = af9013_read_status,
-       .read_snr = af9013_read_snr,
-       .read_signal_strength = af9013_read_signal_strength,
-       .read_ber = af9013_read_ber,
-       .read_ucblocks = af9013_read_ucblocks,
-
-       .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
deleted file mode 100644 (file)
index b973fc5..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Afatech AF9013 demodulator driver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef AF9013_H
-#define AF9013_H
-
-#include <linux/dvb/frontend.h>
-
-/* AF9013/5 GPIOs (mostly guessed)
-   demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
-   demod#1-gpio#1 - xtal setting (?)
-   demod#1-gpio#3 - tuner#1
-   demod#2-gpio#0 - tuner#2
-   demod#2-gpio#1 - xtal setting (?)
-*/
-
-struct af9013_config {
-       /*
-        * I2C address
-        */
-       u8 i2c_addr;
-
-       /*
-        * clock
-        * 20480000, 25000000, 28000000, 28800000
-        */
-       u32 clock;
-
-       /*
-        * tuner
-        */
-#define AF9013_TUNER_MXL5003D      3 /* MaxLinear */
-#define AF9013_TUNER_MXL5005D     13 /* MaxLinear */
-#define AF9013_TUNER_MXL5005R     30 /* MaxLinear */
-#define AF9013_TUNER_ENV77H11D5  129 /* Panasonic */
-#define AF9013_TUNER_MT2060      130 /* Microtune */
-#define AF9013_TUNER_MC44S803    133 /* Freescale */
-#define AF9013_TUNER_QT1010      134 /* Quantek */
-#define AF9013_TUNER_UNKNOWN     140 /* for can tuners ? */
-#define AF9013_TUNER_MT2060_2    147 /* Microtune */
-#define AF9013_TUNER_TDA18271    156 /* NXP */
-#define AF9013_TUNER_QT1010A     162 /* Quantek */
-#define AF9013_TUNER_MXL5007T    177 /* MaxLinear */
-#define AF9013_TUNER_TDA18218    179 /* NXP */
-       u8 tuner;
-
-       /*
-        * IF frequency
-        */
-       u32 if_frequency;
-
-       /*
-        * TS settings
-        */
-#define AF9013_TS_USB       0
-#define AF9013_TS_PARALLEL  1
-#define AF9013_TS_SERIAL    2
-       u8 ts_mode:2;
-
-       /*
-        * input spectrum inversion
-        */
-       bool spec_inv;
-
-       /*
-        * firmware API version
-        */
-       u8 api_version[4];
-
-       /*
-        * GPIOs
-        */
-#define AF9013_GPIO_ON (1 << 0)
-#define AF9013_GPIO_EN (1 << 1)
-#define AF9013_GPIO_O  (1 << 2)
-#define AF9013_GPIO_I  (1 << 3)
-#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN)
-#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
-#define AF9013_GPIO_TUNER_ON  (AF9013_GPIO_ON|AF9013_GPIO_EN)
-#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
-       u8 gpio[4];
-};
-
-#if defined(CONFIG_DVB_AF9013) || \
-       (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
-extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *af9013_attach(
-const struct af9013_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_AF9013 */
-
-#endif /* AF9013_H */
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h
deleted file mode 100644 (file)
index fa848af..0000000
+++ /dev/null
@@ -1,922 +0,0 @@
-/*
- * Afatech AF9013 demodulator driver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef AF9013_PRIV_H
-#define AF9013_PRIV_H
-
-#include "dvb_frontend.h"
-#include "af9013.h"
-#include <linux/firmware.h>
-
-#define LOG_PREFIX "af9013"
-
-#undef dbg
-#define dbg(f, arg...) \
-       if (af9013_debug) \
-               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#define AF9013_DEFAULT_FIRMWARE     "dvb-fe-af9013.fw"
-
-struct af9013_reg_bit {
-       u16 addr;
-       u8  pos:4;
-       u8  len:4;
-       u8  val;
-};
-
-struct af9013_snr {
-       u32 val;
-       u8 snr;
-};
-
-struct af9013_coeff {
-       u32 clock;
-       u32 bandwidth_hz;
-       u8 val[24];
-};
-
-/* pre-calculated coeff lookup table */
-static const struct af9013_coeff coeff_lut[] = {
-       /* 28.800 MHz */
-       { 28800000, 8000000, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14,
-               0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a,
-               0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } },
-       { 28800000, 7000000, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71,
-               0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38,
-               0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } },
-       { 28800000, 6000000, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf,
-               0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7,
-               0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } },
-       /* 20.480 MHz */
-       { 20480000, 8000000, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24,
-               0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92,
-               0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } },
-       { 20480000, 7000000, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40,
-               0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00,
-               0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } },
-       { 20480000, 6000000, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b,
-               0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d,
-               0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } },
-       /* 28.000 MHz */
-       { 28000000, 8000000, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39,
-               0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f,
-               0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } },
-       { 28000000, 7000000, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92,
-               0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49,
-               0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } },
-       { 28000000, 6000000, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb,
-               0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63,
-               0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } },
-       /* 25.000 MHz */
-       { 25000000, 8000000, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9,
-               0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e,
-               0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } },
-       { 25000000, 7000000, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e,
-               0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7,
-               0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } },
-       { 25000000, 6000000, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63,
-               0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f,
-               0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } },
-};
-
-/* QPSK SNR lookup table */
-static const struct af9013_snr qpsk_snr_lut[] = {
-       { 0x000000,  0 },
-       { 0x0b4771,  0 },
-       { 0x0c1aed,  1 },
-       { 0x0d0d27,  2 },
-       { 0x0e4d19,  3 },
-       { 0x0e5da8,  4 },
-       { 0x107097,  5 },
-       { 0x116975,  6 },
-       { 0x1252d9,  7 },
-       { 0x131fa4,  8 },
-       { 0x13d5e1,  9 },
-       { 0x148e53, 10 },
-       { 0x15358b, 11 },
-       { 0x15dd29, 12 },
-       { 0x168112, 13 },
-       { 0x170b61, 14 },
-       { 0xffffff, 15 },
-};
-
-/* QAM16 SNR lookup table */
-static const struct af9013_snr qam16_snr_lut[] = {
-       { 0x000000,  0 },
-       { 0x05eb62,  5 },
-       { 0x05fecf,  6 },
-       { 0x060b80,  7 },
-       { 0x062501,  8 },
-       { 0x064865,  9 },
-       { 0x069604, 10 },
-       { 0x06f356, 11 },
-       { 0x07706a, 12 },
-       { 0x0804d3, 13 },
-       { 0x089d1a, 14 },
-       { 0x093e3d, 15 },
-       { 0x09e35d, 16 },
-       { 0x0a7c3c, 17 },
-       { 0x0afaf8, 18 },
-       { 0x0b719d, 19 },
-       { 0xffffff, 20 },
-};
-
-/* QAM64 SNR lookup table */
-static const struct af9013_snr qam64_snr_lut[] = {
-       { 0x000000,  0 },
-       { 0x03109b, 12 },
-       { 0x0310d4, 13 },
-       { 0x031920, 14 },
-       { 0x0322d0, 15 },
-       { 0x0339fc, 16 },
-       { 0x0364a1, 17 },
-       { 0x038bcc, 18 },
-       { 0x03c7d3, 19 },
-       { 0x0408cc, 20 },
-       { 0x043bed, 21 },
-       { 0x048061, 22 },
-       { 0x04be95, 23 },
-       { 0x04fa7d, 24 },
-       { 0x052405, 25 },
-       { 0x05570d, 26 },
-       { 0xffffff, 27 },
-};
-
-static const struct af9013_reg_bit ofsm_init[] = {
-       { 0xd73a, 0, 8, 0xa1 },
-       { 0xd73b, 0, 8, 0x1f },
-       { 0xd73c, 4, 4, 0x0a },
-       { 0xd732, 3, 1, 0x00 },
-       { 0xd731, 4, 2, 0x03 },
-       { 0xd73d, 7, 1, 0x01 },
-       { 0xd740, 0, 1, 0x00 },
-       { 0xd740, 1, 1, 0x00 },
-       { 0xd740, 2, 1, 0x00 },
-       { 0xd740, 3, 1, 0x01 },
-       { 0xd3c1, 4, 1, 0x01 },
-       { 0x9124, 0, 8, 0x58 },
-       { 0x9125, 0, 2, 0x02 },
-       { 0xd3a2, 0, 8, 0x00 },
-       { 0xd3a3, 0, 8, 0x04 },
-       { 0xd305, 0, 8, 0x32 },
-       { 0xd306, 0, 8, 0x10 },
-       { 0xd304, 0, 8, 0x04 },
-       { 0x9112, 0, 1, 0x01 },
-       { 0x911d, 0, 1, 0x01 },
-       { 0x911a, 0, 1, 0x01 },
-       { 0x911b, 0, 1, 0x01 },
-       { 0x9bce, 0, 4, 0x02 },
-       { 0x9116, 0, 1, 0x01 },
-       { 0x9122, 0, 8, 0xd0 },
-       { 0xd2e0, 0, 8, 0xd0 },
-       { 0xd2e9, 0, 4, 0x0d },
-       { 0xd38c, 0, 8, 0xfc },
-       { 0xd38d, 0, 8, 0x00 },
-       { 0xd38e, 0, 8, 0x7e },
-       { 0xd38f, 0, 8, 0x00 },
-       { 0xd390, 0, 8, 0x2f },
-       { 0xd145, 4, 1, 0x01 },
-       { 0xd1a9, 4, 1, 0x01 },
-       { 0xd158, 5, 3, 0x01 },
-       { 0xd159, 0, 6, 0x06 },
-       { 0xd167, 0, 8, 0x00 },
-       { 0xd168, 0, 4, 0x07 },
-       { 0xd1c3, 5, 3, 0x00 },
-       { 0xd1c4, 0, 6, 0x00 },
-       { 0xd1c5, 0, 7, 0x10 },
-       { 0xd1c6, 0, 3, 0x02 },
-       { 0xd080, 2, 5, 0x03 },
-       { 0xd081, 4, 4, 0x09 },
-       { 0xd098, 4, 4, 0x0f },
-       { 0xd098, 0, 4, 0x03 },
-       { 0xdbc0, 4, 1, 0x01 },
-       { 0xdbc7, 0, 8, 0x08 },
-       { 0xdbc8, 4, 4, 0x00 },
-       { 0xdbc9, 0, 5, 0x01 },
-       { 0xd280, 0, 8, 0xe0 },
-       { 0xd281, 0, 8, 0xff },
-       { 0xd282, 0, 8, 0xff },
-       { 0xd283, 0, 8, 0xc3 },
-       { 0xd284, 0, 8, 0xff },
-       { 0xd285, 0, 4, 0x01 },
-       { 0xd0f0, 0, 7, 0x1a },
-       { 0xd0f1, 4, 1, 0x01 },
-       { 0xd0f2, 0, 8, 0x0c },
-       { 0xd101, 5, 3, 0x06 },
-       { 0xd103, 0, 4, 0x08 },
-       { 0xd0f8, 0, 7, 0x20 },
-       { 0xd111, 5, 1, 0x00 },
-       { 0xd111, 6, 1, 0x00 },
-       { 0x910b, 0, 8, 0x0a },
-       { 0x9115, 0, 8, 0x02 },
-       { 0x910c, 0, 8, 0x02 },
-       { 0x910d, 0, 8, 0x08 },
-       { 0x910e, 0, 8, 0x0a },
-       { 0x9bf6, 0, 8, 0x06 },
-       { 0x9bf8, 0, 8, 0x02 },
-       { 0x9bf7, 0, 8, 0x05 },
-       { 0x9bf9, 0, 8, 0x0f },
-       { 0x9bfc, 0, 8, 0x13 },
-       { 0x9bd3, 0, 8, 0xff },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-};
-
-/* Panasonic ENV77H11D5 tuner init
-   AF9013_TUNER_ENV77H11D5 = 129 */
-static const struct af9013_reg_bit tuner_init_env77h11d5[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x03 },
-       { 0x9bbe, 0, 8, 0x01 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x00 },
-       { 0x9be3, 0, 8, 0x00 },
-       { 0xd015, 0, 8, 0x50 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0xdf },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x44 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0xeb },
-       { 0xd00d, 0, 2, 0x02 },
-       { 0xd00a, 0, 8, 0xf4 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bba, 0, 8, 0xf9 },
-       { 0x9bc3, 0, 8, 0xdf },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0xeb },
-       { 0x9bc6, 0, 8, 0x02 },
-       { 0x9bc9, 0, 8, 0x52 },
-       { 0xd011, 0, 8, 0x3c },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0xf7 },
-       { 0xd014, 0, 2, 0x02 },
-       { 0xd040, 0, 8, 0x0b },
-       { 0xd041, 0, 2, 0x02 },
-       { 0xd042, 0, 8, 0x4d },
-       { 0xd043, 0, 2, 0x00 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-};
-
-/* Microtune MT2060 tuner init
-   AF9013_TUNER_MT2060     = 130 */
-static const struct af9013_reg_bit tuner_init_mt2060[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x07 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x00 },
-       { 0x9be3, 0, 8, 0x00 },
-       { 0x9bbe, 0, 1, 0x00 },
-       { 0x9bcc, 0, 1, 0x00 },
-       { 0x9bb9, 0, 8, 0x75 },
-       { 0x9bcd, 0, 8, 0x24 },
-       { 0x9bff, 0, 8, 0x30 },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0x0f },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x32 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0x36 },
-       { 0xd00d, 0, 2, 0x03 },
-       { 0xd00a, 0, 8, 0x35 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x07 },
-       { 0x9bc8, 0, 8, 0x90 },
-       { 0x9bc3, 0, 8, 0x0f },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x36 },
-       { 0x9bc6, 0, 8, 0x03 },
-       { 0x9bba, 0, 8, 0xc9 },
-       { 0x9bc9, 0, 8, 0x79 },
-       { 0xd011, 0, 8, 0x10 },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0x45 },
-       { 0xd014, 0, 2, 0x03 },
-       { 0xd040, 0, 8, 0x98 },
-       { 0xd041, 0, 2, 0x00 },
-       { 0xd042, 0, 8, 0xcf },
-       { 0xd043, 0, 2, 0x03 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-       { 0x9bd0, 0, 8, 0xcc },
-       { 0x9be4, 0, 8, 0xa0 },
-       { 0x9bbd, 0, 8, 0x8e },
-       { 0x9be2, 0, 8, 0x4d },
-       { 0x9bee, 0, 1, 0x01 },
-};
-
-/* Microtune MT2060 tuner init
-   AF9013_TUNER_MT2060_2   = 147 */
-static const struct af9013_reg_bit tuner_init_mt2060_2[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x06 },
-       { 0x9bbe, 0, 8, 0x01 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0x0f },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x32 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0x36 },
-       { 0xd00d, 0, 2, 0x03 },
-       { 0xd00a, 0, 8, 0x35 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x07 },
-       { 0x9bc8, 0, 8, 0x90 },
-       { 0x9bc3, 0, 8, 0x0f },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x36 },
-       { 0x9bc6, 0, 8, 0x03 },
-       { 0x9bba, 0, 8, 0xc9 },
-       { 0x9bc9, 0, 8, 0x79 },
-       { 0xd011, 0, 8, 0x10 },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0x45 },
-       { 0xd014, 0, 2, 0x03 },
-       { 0xd040, 0, 8, 0x98 },
-       { 0xd041, 0, 2, 0x00 },
-       { 0xd042, 0, 8, 0xcf },
-       { 0xd043, 0, 2, 0x03 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 8, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x96 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0xd045, 7, 1, 0x00 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-};
-
-/* MaxLinear MXL5003 tuner init
-   AF9013_TUNER_MXL5003D   =   3 */
-static const struct af9013_reg_bit tuner_init_mxl5003d[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x09 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x00 },
-       { 0x9be3, 0, 8, 0x00 },
-       { 0x9bfc, 0, 8, 0x0f },
-       { 0x9bf6, 0, 8, 0x01 },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0xd015, 0, 8, 0x33 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x40 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0x0f },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x6c },
-       { 0xd007, 0, 2, 0x00 },
-       { 0xd00c, 0, 8, 0x3d },
-       { 0xd00d, 0, 2, 0x00 },
-       { 0xd00a, 0, 8, 0x45 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x07 },
-       { 0x9bc8, 0, 8, 0x52 },
-       { 0x9bc3, 0, 8, 0x0f },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x3d },
-       { 0x9bc6, 0, 8, 0x00 },
-       { 0x9bba, 0, 8, 0xa2 },
-       { 0x9bc9, 0, 8, 0xa0 },
-       { 0xd011, 0, 8, 0x56 },
-       { 0xd012, 0, 2, 0x00 },
-       { 0xd013, 0, 8, 0x50 },
-       { 0xd014, 0, 2, 0x00 },
-       { 0xd040, 0, 8, 0x56 },
-       { 0xd041, 0, 2, 0x00 },
-       { 0xd042, 0, 8, 0x50 },
-       { 0xd043, 0, 2, 0x00 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 8, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-};
-
-/* MaxLinear MXL5005S & MXL5007T tuner init
-   AF9013_TUNER_MXL5005D   =  13
-   AF9013_TUNER_MXL5005R   =  30
-   AF9013_TUNER_MXL5007T   = 177 */
-static const struct af9013_reg_bit tuner_init_mxl5005[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x07 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x01 },
-       { 0x9be3, 0, 8, 0x01 },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-       { 0x9bb9, 0, 8, 0x00 },
-       { 0x9bcd, 0, 8, 0x28 },
-       { 0x9bff, 0, 8, 0x24 },
-       { 0xd015, 0, 8, 0x40 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x40 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0x0f },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x73 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0xfa },
-       { 0xd00d, 0, 2, 0x01 },
-       { 0xd00a, 0, 8, 0xff },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x23 },
-       { 0x9bc8, 0, 8, 0x55 },
-       { 0x9bc3, 0, 8, 0x01 },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0xfa },
-       { 0x9bc6, 0, 8, 0x01 },
-       { 0x9bba, 0, 8, 0xff },
-       { 0x9bc9, 0, 8, 0xff },
-       { 0x9bd3, 0, 8, 0x95 },
-       { 0xd011, 0, 8, 0x70 },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0xfb },
-       { 0xd014, 0, 2, 0x01 },
-       { 0xd040, 0, 8, 0x70 },
-       { 0xd041, 0, 2, 0x01 },
-       { 0xd042, 0, 8, 0xfb },
-       { 0xd043, 0, 2, 0x01 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-       { 0x9bd0, 0, 8, 0x93 },
-       { 0x9be4, 0, 8, 0xfe },
-       { 0x9bbd, 0, 8, 0x63 },
-       { 0x9be2, 0, 8, 0xfe },
-       { 0x9bee, 0, 1, 0x01 },
-};
-
-/* Quantek QT1010 tuner init
-   AF9013_TUNER_QT1010     = 134
-   AF9013_TUNER_QT1010A    = 162 */
-static const struct af9013_reg_bit tuner_init_qt1010[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x09 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x01 },
-       { 0x9be3, 0, 8, 0x01 },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-       { 0x9bb9, 0, 8, 0x00 },
-       { 0x9bcd, 0, 8, 0x28 },
-       { 0x9bff, 0, 8, 0x20 },
-       { 0xd008, 0, 8, 0x0f },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x99 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0x0f },
-       { 0xd00d, 0, 2, 0x02 },
-       { 0xd00a, 0, 8, 0x50 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x00 },
-       { 0x9bc8, 0, 8, 0x00 },
-       { 0x9bc3, 0, 8, 0x0f },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x0f },
-       { 0x9bc6, 0, 8, 0x02 },
-       { 0x9bba, 0, 8, 0xc5 },
-       { 0x9bc9, 0, 8, 0xff },
-       { 0xd011, 0, 8, 0x58 },
-       { 0xd012, 0, 2, 0x02 },
-       { 0xd013, 0, 8, 0x89 },
-       { 0xd014, 0, 2, 0x01 },
-       { 0xd040, 0, 8, 0x58 },
-       { 0xd041, 0, 2, 0x02 },
-       { 0xd042, 0, 8, 0x89 },
-       { 0xd043, 0, 2, 0x01 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-       { 0x9bd0, 0, 8, 0xcd },
-       { 0x9be4, 0, 8, 0xbb },
-       { 0x9bbd, 0, 8, 0x93 },
-       { 0x9be2, 0, 8, 0x80 },
-       { 0x9bee, 0, 1, 0x01 },
-};
-
-/* Freescale MC44S803 tuner init
-   AF9013_TUNER_MC44S803   = 133 */
-static const struct af9013_reg_bit tuner_init_mc44s803[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x06 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x00 },
-       { 0x9be3, 0, 8, 0x00 },
-       { 0x9bf6, 0, 8, 0x01 },
-       { 0x9bf8, 0, 8, 0x02 },
-       { 0x9bf9, 0, 8, 0x02 },
-       { 0x9bfc, 0, 8, 0x1f },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-       { 0x9bb9, 0, 8, 0x00 },
-       { 0x9bcd, 0, 8, 0x24 },
-       { 0x9bff, 0, 8, 0x24 },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0x01 },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x7b },
-       { 0xd007, 0, 2, 0x00 },
-       { 0xd00c, 0, 8, 0x7c },
-       { 0xd00d, 0, 2, 0x02 },
-       { 0xd00a, 0, 8, 0xfe },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bc7, 0, 8, 0x08 },
-       { 0x9bc8, 0, 8, 0x9a },
-       { 0x9bc3, 0, 8, 0x01 },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x7c },
-       { 0x9bc6, 0, 8, 0x02 },
-       { 0x9bba, 0, 8, 0xfc },
-       { 0x9bc9, 0, 8, 0xaa },
-       { 0xd011, 0, 8, 0x6b },
-       { 0xd012, 0, 2, 0x00 },
-       { 0xd013, 0, 8, 0x88 },
-       { 0xd014, 0, 2, 0x02 },
-       { 0xd040, 0, 8, 0x6b },
-       { 0xd041, 0, 2, 0x00 },
-       { 0xd042, 0, 8, 0x7c },
-       { 0xd043, 0, 2, 0x02 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-       { 0x9bd0, 0, 8, 0x9e },
-       { 0x9be4, 0, 8, 0xff },
-       { 0x9bbd, 0, 8, 0x9e },
-       { 0x9be2, 0, 8, 0x25 },
-       { 0x9bee, 0, 1, 0x01 },
-       { 0xd73b, 3, 1, 0x00 },
-};
-
-/* unknown, probably for tin can tuner, tuner init
-   AF9013_TUNER_UNKNOWN   = 140 */
-static const struct af9013_reg_bit tuner_init_unknown[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x02 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x01 },
-       { 0x9be3, 0, 8, 0x01 },
-       { 0xd1a0, 1, 1, 0x00 },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-       { 0x9bb9, 0, 8, 0x00 },
-       { 0x9bcd, 0, 8, 0x18 },
-       { 0x9bff, 0, 8, 0x2c },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0xdf },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x44 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0x00 },
-       { 0xd00d, 0, 2, 0x02 },
-       { 0xd00a, 0, 8, 0xf6 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bba, 0, 8, 0xf9 },
-       { 0x9bc8, 0, 8, 0xaa },
-       { 0x9bc3, 0, 8, 0xdf },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x00 },
-       { 0x9bc6, 0, 8, 0x02 },
-       { 0x9bc9, 0, 8, 0xf0 },
-       { 0xd011, 0, 8, 0x3c },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0xf7 },
-       { 0xd014, 0, 2, 0x02 },
-       { 0xd040, 0, 8, 0x0b },
-       { 0xd041, 0, 2, 0x02 },
-       { 0xd042, 0, 8, 0x4d },
-       { 0xd043, 0, 2, 0x00 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-};
-
-/* NXP TDA18271 & TDA18218 tuner init
-   AF9013_TUNER_TDA18271   = 156
-   AF9013_TUNER_TDA18218   = 179 */
-static const struct af9013_reg_bit tuner_init_tda18271[] = {
-       { 0x9bd5, 0, 8, 0x01 },
-       { 0x9bd6, 0, 8, 0x04 },
-       { 0xd1a0, 1, 1, 0x01 },
-       { 0xd000, 0, 1, 0x01 },
-       { 0xd000, 1, 1, 0x00 },
-       { 0xd001, 1, 1, 0x01 },
-       { 0xd001, 0, 1, 0x00 },
-       { 0xd001, 5, 1, 0x00 },
-       { 0xd002, 0, 5, 0x19 },
-       { 0xd003, 0, 5, 0x1a },
-       { 0xd004, 0, 5, 0x19 },
-       { 0xd005, 0, 5, 0x1a },
-       { 0xd00e, 0, 5, 0x10 },
-       { 0xd00f, 0, 3, 0x04 },
-       { 0xd00f, 3, 3, 0x05 },
-       { 0xd010, 0, 3, 0x04 },
-       { 0xd010, 3, 3, 0x05 },
-       { 0xd016, 4, 4, 0x03 },
-       { 0xd01f, 0, 6, 0x0a },
-       { 0xd020, 0, 6, 0x0a },
-       { 0x9bda, 0, 8, 0x01 },
-       { 0x9be3, 0, 8, 0x01 },
-       { 0xd1a0, 1, 1, 0x00 },
-       { 0x9bbe, 0, 1, 0x01 },
-       { 0x9bcc, 0, 1, 0x01 },
-       { 0x9bb9, 0, 8, 0x00 },
-       { 0x9bcd, 0, 8, 0x18 },
-       { 0x9bff, 0, 8, 0x2c },
-       { 0xd015, 0, 8, 0x46 },
-       { 0xd016, 0, 1, 0x00 },
-       { 0xd044, 0, 8, 0x46 },
-       { 0xd045, 0, 1, 0x00 },
-       { 0xd008, 0, 8, 0xdf },
-       { 0xd009, 0, 2, 0x02 },
-       { 0xd006, 0, 8, 0x44 },
-       { 0xd007, 0, 2, 0x01 },
-       { 0xd00c, 0, 8, 0x00 },
-       { 0xd00d, 0, 2, 0x02 },
-       { 0xd00a, 0, 8, 0xf6 },
-       { 0xd00b, 0, 2, 0x01 },
-       { 0x9bba, 0, 8, 0xf9 },
-       { 0x9bc8, 0, 8, 0xaa },
-       { 0x9bc3, 0, 8, 0xdf },
-       { 0x9bc4, 0, 8, 0x02 },
-       { 0x9bc5, 0, 8, 0x00 },
-       { 0x9bc6, 0, 8, 0x02 },
-       { 0x9bc9, 0, 8, 0xf0 },
-       { 0xd011, 0, 8, 0x3c },
-       { 0xd012, 0, 2, 0x01 },
-       { 0xd013, 0, 8, 0xf7 },
-       { 0xd014, 0, 2, 0x02 },
-       { 0xd040, 0, 8, 0x0b },
-       { 0xd041, 0, 2, 0x02 },
-       { 0xd042, 0, 8, 0x4d },
-       { 0xd043, 0, 2, 0x00 },
-       { 0xd045, 1, 1, 0x00 },
-       { 0x9bcf, 0, 1, 0x01 },
-       { 0xd045, 2, 1, 0x01 },
-       { 0xd04f, 0, 8, 0x9a },
-       { 0xd050, 0, 1, 0x01 },
-       { 0xd051, 0, 8, 0x5a },
-       { 0xd052, 0, 1, 0x01 },
-       { 0xd053, 0, 8, 0x50 },
-       { 0xd054, 0, 8, 0x46 },
-       { 0x9bd7, 0, 8, 0x0a },
-       { 0x9bd8, 0, 8, 0x14 },
-       { 0x9bd9, 0, 8, 0x08 },
-       { 0x9bd0, 0, 8, 0xa8 },
-       { 0x9be4, 0, 8, 0x7f },
-       { 0x9bbd, 0, 8, 0xa8 },
-       { 0x9be2, 0, 8, 0x20 },
-       { 0x9bee, 0, 1, 0x01 },
-};
-
-#endif /* AF9013_PRIV_H */
diff --git a/drivers/media/dvb/frontends/af9033.c b/drivers/media/dvb/frontends/af9033.c
deleted file mode 100644 (file)
index a389982..0000000
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Afatech AF9033 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#include "af9033_priv.h"
-
-struct af9033_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct af9033_config cfg;
-
-       u32 bandwidth_hz;
-       bool ts_mode_parallel;
-       bool ts_mode_serial;
-
-       u32 ber;
-       u32 ucb;
-       unsigned long last_stat_check;
-};
-
-/* write multiple registers */
-static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
-               int len)
-{
-       int ret;
-       u8 buf[3 + len];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = state->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = (reg >> 16) & 0xff;
-       buf[1] = (reg >>  8) & 0xff;
-       buf[2] = (reg >>  0) & 0xff;
-       memcpy(&buf[3], val, len);
-
-       ret = i2c_transfer(state->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n",
-                               __func__, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* read multiple registers */
-static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
-                       (reg >> 0) & 0xff };
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = state->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf
-               }, {
-                       .addr = state->cfg.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n",
-                               __func__, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-
-/* write single register */
-static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
-{
-       return af9033_wr_regs(state, reg, &val, 1);
-}
-
-/* read single register */
-static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
-{
-       return af9033_rd_regs(state, reg, val, 1);
-}
-
-/* write single register with mask */
-static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
-               u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = af9033_rd_regs(state, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return af9033_wr_regs(state, reg, &val, 1);
-}
-
-/* read single register with mask */
-static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
-               u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = af9033_rd_regs(state, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static u32 af9033_div(u32 a, u32 b, u32 x)
-{
-       u32 r = 0, c = 0, i;
-
-       pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x);
-
-       if (a > b) {
-               c = a / b;
-               a = a - c * b;
-       }
-
-       for (i = 0; i < x; i++) {
-               if (a >= b) {
-                       r += 1;
-                       a -= b;
-               }
-               a <<= 1;
-               r <<= 1;
-       }
-       r = (c << (u32)x) + r;
-
-       pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r);
-
-       return r;
-}
-
-static void af9033_release(struct dvb_frontend *fe)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-
-       kfree(state);
-}
-
-static int af9033_init(struct dvb_frontend *fe)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret, i, len;
-       const struct reg_val *init;
-       u8 buf[4];
-       u32 adc_cw, clock_cw;
-       struct reg_val_mask tab[] = {
-               { 0x80fb24, 0x00, 0x08 },
-               { 0x80004c, 0x00, 0xff },
-               { 0x00f641, state->cfg.tuner, 0xff },
-               { 0x80f5ca, 0x01, 0x01 },
-               { 0x80f715, 0x01, 0x01 },
-               { 0x00f41f, 0x04, 0x04 },
-               { 0x00f41a, 0x01, 0x01 },
-               { 0x80f731, 0x00, 0x01 },
-               { 0x00d91e, 0x00, 0x01 },
-               { 0x00d919, 0x00, 0x01 },
-               { 0x80f732, 0x00, 0x01 },
-               { 0x00d91f, 0x00, 0x01 },
-               { 0x00d91a, 0x00, 0x01 },
-               { 0x80f730, 0x00, 0x01 },
-               { 0x80f778, 0x00, 0xff },
-               { 0x80f73c, 0x01, 0x01 },
-               { 0x80f776, 0x00, 0x01 },
-               { 0x00d8fd, 0x01, 0xff },
-               { 0x00d830, 0x01, 0xff },
-               { 0x00d831, 0x00, 0xff },
-               { 0x00d832, 0x00, 0xff },
-               { 0x80f985, state->ts_mode_serial, 0x01 },
-               { 0x80f986, state->ts_mode_parallel, 0x01 },
-               { 0x00d827, 0x00, 0xff },
-               { 0x00d829, 0x00, 0xff },
-       };
-
-       /* program clock control */
-       clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul);
-       buf[0] = (clock_cw >>  0) & 0xff;
-       buf[1] = (clock_cw >>  8) & 0xff;
-       buf[2] = (clock_cw >> 16) & 0xff;
-       buf[3] = (clock_cw >> 24) & 0xff;
-
-       pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock,
-                       clock_cw);
-
-       ret = af9033_wr_regs(state, 0x800025, buf, 4);
-       if (ret < 0)
-               goto err;
-
-       /* program ADC control */
-       for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
-               if (clock_adc_lut[i].clock == state->cfg.clock)
-                       break;
-       }
-
-       adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul);
-       buf[0] = (adc_cw >>  0) & 0xff;
-       buf[1] = (adc_cw >>  8) & 0xff;
-       buf[2] = (adc_cw >> 16) & 0xff;
-
-       pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc,
-                       adc_cw);
-
-       ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
-       if (ret < 0)
-               goto err;
-
-       /* program register table */
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
-                               tab[i].mask);
-               if (ret < 0)
-                       goto err;
-       }
-
-       /* settings for TS interface */
-       if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
-               ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-       } else {
-               ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-       }
-
-       /* load OFSM settings */
-       pr_debug("%s: load ofsm settings\n", __func__);
-       len = ARRAY_SIZE(ofsm_init);
-       init = ofsm_init;
-       for (i = 0; i < len; i++) {
-               ret = af9033_wr_reg(state, init[i].reg, init[i].val);
-               if (ret < 0)
-                       goto err;
-       }
-
-       /* load tuner specific settings */
-       pr_debug("%s: load tuner specific settings\n",
-                       __func__);
-       switch (state->cfg.tuner) {
-       case AF9033_TUNER_TUA9001:
-               len = ARRAY_SIZE(tuner_init_tua9001);
-               init = tuner_init_tua9001;
-               break;
-       case AF9033_TUNER_FC0011:
-               len = ARRAY_SIZE(tuner_init_fc0011);
-               init = tuner_init_fc0011;
-               break;
-       case AF9033_TUNER_MXL5007T:
-               len = ARRAY_SIZE(tuner_init_mxl5007t);
-               init = tuner_init_mxl5007t;
-               break;
-       case AF9033_TUNER_TDA18218:
-               len = ARRAY_SIZE(tuner_init_tda18218);
-               init = tuner_init_tda18218;
-               break;
-       default:
-               pr_debug("%s: unsupported tuner ID=%d\n", __func__,
-                               state->cfg.tuner);
-               ret = -ENODEV;
-               goto err;
-       }
-
-       for (i = 0; i < len; i++) {
-               ret = af9033_wr_reg(state, init[i].reg, init[i].val);
-               if (ret < 0)
-                       goto err;
-       }
-
-       state->bandwidth_hz = 0; /* force to program all parameters */
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_sleep(struct dvb_frontend *fe)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret, i;
-       u8 tmp;
-
-       ret = af9033_wr_reg(state, 0x80004c, 1);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_wr_reg(state, 0x800000, 0);
-       if (ret < 0)
-               goto err;
-
-       for (i = 100, tmp = 1; i && tmp; i--) {
-               ret = af9033_rd_reg(state, 0x80004c, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(200, 10000);
-       }
-
-       pr_debug("%s: loop=%d\n", __func__, i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
-               goto err;
-       }
-
-       ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
-       if (ret < 0)
-               goto err;
-
-       /* prevent current leak (?) */
-       if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
-               /* enable parallel TS */
-               ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
-               if (ret < 0)
-                       goto err;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_get_tune_settings(struct dvb_frontend *fe,
-               struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 800;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-
-       return 0;
-}
-
-static int af9033_set_frontend(struct dvb_frontend *fe)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, spec_inv;
-       u8 tmp, buf[3], bandwidth_reg_val;
-       u32 if_frequency, freq_cw, adc_freq;
-
-       pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency,
-                       c->bandwidth_hz);
-
-       /* check bandwidth */
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               bandwidth_reg_val = 0x00;
-               break;
-       case 7000000:
-               bandwidth_reg_val = 0x01;
-               break;
-       case 8000000:
-               bandwidth_reg_val = 0x02;
-               break;
-       default:
-               pr_debug("%s: invalid bandwidth_hz\n", __func__);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* program CFOE coefficients */
-       if (c->bandwidth_hz != state->bandwidth_hz) {
-               for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
-                       if (coeff_lut[i].clock == state->cfg.clock &&
-                               coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
-                               break;
-                       }
-               }
-               ret =  af9033_wr_regs(state, 0x800001,
-                               coeff_lut[i].val, sizeof(coeff_lut[i].val));
-       }
-
-       /* program frequency control */
-       if (c->bandwidth_hz != state->bandwidth_hz) {
-               spec_inv = state->cfg.spec_inv ? -1 : 1;
-
-               for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
-                       if (clock_adc_lut[i].clock == state->cfg.clock)
-                               break;
-               }
-               adc_freq = clock_adc_lut[i].adc;
-
-               /* get used IF frequency */
-               if (fe->ops.tuner_ops.get_if_frequency)
-                       fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
-               else
-                       if_frequency = 0;
-
-               while (if_frequency > (adc_freq / 2))
-                       if_frequency -= adc_freq;
-
-               if (if_frequency >= 0)
-                       spec_inv *= -1;
-               else
-                       if_frequency *= -1;
-
-               freq_cw = af9033_div(if_frequency, adc_freq, 23ul);
-
-               if (spec_inv == -1)
-                       freq_cw *= -1;
-
-               /* get adc multiplies */
-               ret = af9033_rd_reg(state, 0x800045, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               if (tmp == 1)
-                       freq_cw /= 2;
-
-               buf[0] = (freq_cw >>  0) & 0xff;
-               buf[1] = (freq_cw >>  8) & 0xff;
-               buf[2] = (freq_cw >> 16) & 0x7f;
-               ret = af9033_wr_regs(state, 0x800029, buf, 3);
-               if (ret < 0)
-                       goto err;
-
-               state->bandwidth_hz = c->bandwidth_hz;
-       }
-
-       ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_wr_reg(state, 0x800040, 0x00);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_wr_reg(state, 0x800047, 0x00);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
-       if (ret < 0)
-               goto err;
-
-       if (c->frequency <= 230000000)
-               tmp = 0x00; /* VHF */
-       else
-               tmp = 0x01; /* UHF */
-
-       ret = af9033_wr_reg(state, 0x80004b, tmp);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_wr_reg(state, 0x800000, 0x00);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_get_frontend(struct dvb_frontend *fe)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-       u8 buf[8];
-
-       pr_debug("%s\n", __func__);
-
-       /* read all needed registers */
-       ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
-       if (ret < 0)
-               goto err;
-
-       switch ((buf[0] >> 0) & 3) {
-       case 0:
-               c->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               c->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       }
-
-       switch ((buf[1] >> 0) & 3) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       switch ((buf[2] >> 0) & 7) {
-       case 0:
-               c->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               c->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               c->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               c->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-       switch ((buf[3] >> 0) & 3) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       }
-
-       switch ((buf[4] >> 0) & 3) {
-       case 0:
-               c->bandwidth_hz = 6000000;
-               break;
-       case 1:
-               c->bandwidth_hz = 7000000;
-               break;
-       case 2:
-               c->bandwidth_hz = 8000000;
-               break;
-       }
-
-       switch ((buf[6] >> 0) & 7) {
-       case 0:
-               c->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_HP = FEC_7_8;
-               break;
-       case 5:
-               c->code_rate_HP = FEC_NONE;
-               break;
-       }
-
-       switch ((buf[7] >> 0) & 7) {
-       case 0:
-               c->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_LP = FEC_7_8;
-               break;
-       case 5:
-               c->code_rate_LP = FEC_NONE;
-               break;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-
-       *status = 0;
-
-       /* radio channel status, 0=no result, 1=has signal, 2=no signal */
-       ret = af9033_rd_reg(state, 0x800047, &tmp);
-       if (ret < 0)
-               goto err;
-
-       /* has signal */
-       if (tmp == 0x01)
-               *status |= FE_HAS_SIGNAL;
-
-       if (tmp != 0x02) {
-               /* TPS lock */
-               ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               if (tmp)
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                                       FE_HAS_VITERBI;
-
-               /* full lock */
-               ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
-               if (ret < 0)
-                       goto err;
-
-               if (tmp)
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                                       FE_HAS_VITERBI | FE_HAS_SYNC |
-                                       FE_HAS_LOCK;
-       }
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret, i, len;
-       u8 buf[3], tmp;
-       u32 snr_val;
-       const struct val_snr *uninitialized_var(snr_lut);
-
-       /* read value */
-       ret = af9033_rd_regs(state, 0x80002c, buf, 3);
-       if (ret < 0)
-               goto err;
-
-       snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
-       /* read current modulation */
-       ret = af9033_rd_reg(state, 0x80f903, &tmp);
-       if (ret < 0)
-               goto err;
-
-       switch ((tmp >> 0) & 3) {
-       case 0:
-               len = ARRAY_SIZE(qpsk_snr_lut);
-               snr_lut = qpsk_snr_lut;
-               break;
-       case 1:
-               len = ARRAY_SIZE(qam16_snr_lut);
-               snr_lut = qam16_snr_lut;
-               break;
-       case 2:
-               len = ARRAY_SIZE(qam64_snr_lut);
-               snr_lut = qam64_snr_lut;
-               break;
-       default:
-               goto err;
-       }
-
-       for (i = 0; i < len; i++) {
-               tmp = snr_lut[i].snr;
-
-               if (snr_val < snr_lut[i].val)
-                       break;
-       }
-
-       *snr = tmp * 10; /* dB/10 */
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret;
-       u8 strength2;
-
-       /* read signal strength of 0-100 scale */
-       ret = af9033_rd_reg(state, 0x800048, &strength2);
-       if (ret < 0)
-               goto err;
-
-       /* scale value to 0x0000-0xffff */
-       *strength = strength2 * 0xffff / 100;
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int af9033_update_ch_stat(struct af9033_state *state)
-{
-       int ret = 0;
-       u32 err_cnt, bit_cnt;
-       u16 abort_cnt;
-       u8 buf[7];
-
-       /* only update data every half second */
-       if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
-               ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
-               if (ret < 0)
-                       goto err;
-               /* in 8 byte packets? */
-               abort_cnt = (buf[1] << 8) + buf[0];
-               /* in bits */
-               err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
-               /* in 8 byte packets? always(?) 0x2710 = 10000 */
-               bit_cnt = (buf[6] << 8) + buf[5];
-
-               if (bit_cnt < abort_cnt) {
-                       abort_cnt = 1000;
-                       state->ber = 0xffffffff;
-               } else {
-                       /* 8 byte packets, that have not been rejected already */
-                       bit_cnt -= (u32)abort_cnt;
-                       if (bit_cnt == 0) {
-                               state->ber = 0xffffffff;
-                       } else {
-                               err_cnt -= (u32)abort_cnt * 8 * 8;
-                               bit_cnt *= 8 * 8;
-                               state->ber = err_cnt * (0xffffffff / bit_cnt);
-                       }
-               }
-               state->ucb += abort_cnt;
-               state->last_stat_check = jiffies;
-       }
-
-       return 0;
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret;
-
-       ret = af9033_update_ch_stat(state);
-       if (ret < 0)
-               return ret;
-
-       *ber = state->ber;
-
-       return 0;
-}
-
-static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret;
-
-       ret = af9033_update_ch_stat(state);
-       if (ret < 0)
-               return ret;
-
-       *ucblocks = state->ucb;
-
-       return 0;
-}
-
-static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct af9033_state *state = fe->demodulator_priv;
-       int ret;
-
-       pr_debug("%s: enable=%d\n", __func__, enable);
-
-       ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
-       if (ret < 0)
-               goto err;
-
-       return 0;
-
-err:
-       pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static struct dvb_frontend_ops af9033_ops;
-
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-               struct i2c_adapter *i2c)
-{
-       int ret;
-       struct af9033_state *state;
-       u8 buf[8];
-
-       pr_debug("%s:\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
-       if (state == NULL)
-               goto err;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->cfg, config, sizeof(struct af9033_config));
-
-       if (state->cfg.clock != 12000000) {
-               printk(KERN_INFO "af9033: unsupported clock=%d, only " \
-                               "12000000 Hz is supported currently\n",
-                               state->cfg.clock);
-               goto err;
-       }
-
-       /* firmware version */
-       ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
-       if (ret < 0)
-               goto err;
-
-       ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
-       if (ret < 0)
-               goto err;
-
-       printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \
-                       "OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3],
-                       buf[4], buf[5], buf[6], buf[7]);
-
-       /* configure internal TS mode */
-       switch (state->cfg.ts_mode) {
-       case AF9033_TS_MODE_PARALLEL:
-               state->ts_mode_parallel = true;
-               break;
-       case AF9033_TS_MODE_SERIAL:
-               state->ts_mode_serial = true;
-               break;
-       case AF9033_TS_MODE_USB:
-               /* usb mode for AF9035 */
-       default:
-               break;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
-       state->fe.demodulator_priv = state;
-
-       return &state->fe;
-
-err:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(af9033_attach);
-
-static struct dvb_frontend_ops af9033_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Afatech AF9033 (DVB-T)",
-               .frequency_min = 174000000,
-               .frequency_max = 862000000,
-               .frequency_stepsize = 250000,
-               .frequency_tolerance = 0,
-               .caps = FE_CAN_FEC_1_2 |
-                       FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 |
-                       FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = af9033_release,
-
-       .init = af9033_init,
-       .sleep = af9033_sleep,
-
-       .get_tune_settings = af9033_get_tune_settings,
-       .set_frontend = af9033_set_frontend,
-       .get_frontend = af9033_get_frontend,
-
-       .read_status = af9033_read_status,
-       .read_snr = af9033_read_snr,
-       .read_signal_strength = af9033_read_signal_strength,
-       .read_ber = af9033_read_ber,
-       .read_ucblocks = af9033_read_ucblocks,
-
-       .i2c_gate_ctrl = af9033_i2c_gate_ctrl,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9033.h b/drivers/media/dvb/frontends/af9033.h
deleted file mode 100644 (file)
index 9e302c3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Afatech AF9033 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef AF9033_H
-#define AF9033_H
-
-struct af9033_config {
-       /*
-        * I2C address
-        */
-       u8 i2c_addr;
-
-       /*
-        * clock Hz
-        * 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
-        * 30000000, 36000000, 20480000, 16384000
-        */
-       u32 clock;
-
-       /*
-        * tuner
-        */
-#define AF9033_TUNER_TUA9001     0x27 /* Infineon TUA 9001 */
-#define AF9033_TUNER_FC0011      0x28 /* Fitipower FC0011 */
-#define AF9033_TUNER_MXL5007T    0xa0 /* MaxLinear MxL5007T */
-#define AF9033_TUNER_TDA18218    0xa1 /* NXP TDA 18218HN */
-       u8 tuner;
-
-       /*
-        * TS settings
-        */
-#define AF9033_TS_MODE_USB       0
-#define AF9033_TS_MODE_PARALLEL  1
-#define AF9033_TS_MODE_SERIAL    2
-       u8 ts_mode:2;
-
-       /*
-        * input spectrum inversion
-        */
-       bool spec_inv;
-};
-
-
-#if defined(CONFIG_DVB_AF9033) || \
-       (defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE))
-extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *af9033_attach(
-       const struct af9033_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* AF9033_H */
diff --git a/drivers/media/dvb/frontends/af9033_priv.h b/drivers/media/dvb/frontends/af9033_priv.h
deleted file mode 100644 (file)
index 0b783b9..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Afatech AF9033 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef AF9033_PRIV_H
-#define AF9033_PRIV_H
-
-#include "dvb_frontend.h"
-#include "af9033.h"
-
-struct reg_val {
-       u32 reg;
-       u8  val;
-};
-
-struct reg_val_mask {
-       u32 reg;
-       u8  val;
-       u8  mask;
-};
-
-struct coeff {
-       u32 clock;
-       u32 bandwidth_hz;
-       u8 val[36];
-};
-
-struct clock_adc {
-       u32 clock;
-       u32 adc;
-};
-
-struct val_snr {
-       u32 val;
-       u8 snr;
-};
-
-/* Xtal clock vs. ADC clock lookup table */
-static const struct clock_adc clock_adc_lut[] = {
-       { 16384000, 20480000 },
-       { 20480000, 20480000 },
-       { 36000000, 20250000 },
-       { 30000000, 20156250 },
-       { 26000000, 20583333 },
-       { 28000000, 20416667 },
-       { 32000000, 20500000 },
-       { 34000000, 20187500 },
-       { 24000000, 20500000 },
-       { 22000000, 20625000 },
-       { 12000000, 20250000 },
-};
-
-/* pre-calculated coeff lookup table */
-static const struct coeff coeff_lut[] = {
-       /* 12.000 MHz */
-       { 12000000, 8000000, {
-               0x01, 0xce, 0x55, 0xc9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
-               0x99, 0x0f, 0x00, 0x73, 0x95, 0x72, 0x00, 0x73, 0x91, 0xd5,
-               0x00, 0x39, 0xca, 0xb9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
-               0x95, 0x72, 0x37, 0x02, 0xce, 0x01 }
-       },
-       { 12000000, 7000000, {
-               0x01, 0x94, 0x8b, 0x10, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
-               0x25, 0xed, 0x00, 0x65, 0x22, 0xc4, 0x00, 0x65, 0x1f, 0x9b,
-               0x00, 0x32, 0x91, 0x62, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
-               0x22, 0xc4, 0x88, 0x02, 0x95, 0x01 }
-       },
-       { 12000000, 6000000, {
-               0x01, 0x5a, 0xc0, 0x56, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
-               0xb2, 0xcb, 0x00, 0x56, 0xb0, 0x15, 0x00, 0x56, 0xad, 0x60,
-               0x00, 0x2b, 0x58, 0x0b, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
-               0xb0, 0x15, 0xf4, 0x02, 0x5b, 0x01 }
-       },
-};
-
-/* QPSK SNR lookup table */
-static const struct val_snr qpsk_snr_lut[] = {
-       { 0x0b4771,  0 },
-       { 0x0c1aed,  1 },
-       { 0x0d0d27,  2 },
-       { 0x0e4d19,  3 },
-       { 0x0e5da8,  4 },
-       { 0x107097,  5 },
-       { 0x116975,  6 },
-       { 0x1252d9,  7 },
-       { 0x131fa4,  8 },
-       { 0x13d5e1,  9 },
-       { 0x148e53, 10 },
-       { 0x15358b, 11 },
-       { 0x15dd29, 12 },
-       { 0x168112, 13 },
-       { 0x170b61, 14 },
-       { 0x17a532, 15 },
-       { 0x180f94, 16 },
-       { 0x186ed2, 17 },
-       { 0x18b271, 18 },
-       { 0x18e118, 19 },
-       { 0x18ff4b, 20 },
-       { 0x190af1, 21 },
-       { 0x191451, 22 },
-       { 0xffffff, 23 },
-};
-
-/* QAM16 SNR lookup table */
-static const struct val_snr qam16_snr_lut[] = {
-       { 0x04f0d5,  0 },
-       { 0x05387a,  1 },
-       { 0x0573a4,  2 },
-       { 0x05a99e,  3 },
-       { 0x05cc80,  4 },
-       { 0x05eb62,  5 },
-       { 0x05fecf,  6 },
-       { 0x060b80,  7 },
-       { 0x062501,  8 },
-       { 0x064865,  9 },
-       { 0x069604, 10 },
-       { 0x06f356, 11 },
-       { 0x07706a, 12 },
-       { 0x0804d3, 13 },
-       { 0x089d1a, 14 },
-       { 0x093e3d, 15 },
-       { 0x09e35d, 16 },
-       { 0x0a7c3c, 17 },
-       { 0x0afaf8, 18 },
-       { 0x0b719d, 19 },
-       { 0x0bda6a, 20 },
-       { 0x0c0c75, 21 },
-       { 0x0c3f7d, 22 },
-       { 0x0c5e62, 23 },
-       { 0x0c6c31, 24 },
-       { 0x0c7925, 25 },
-       { 0xffffff, 26 },
-};
-
-/* QAM64 SNR lookup table */
-static const struct val_snr qam64_snr_lut[] = {
-       { 0x0256d0,  0 },
-       { 0x027a65,  1 },
-       { 0x029873,  2 },
-       { 0x02b7fe,  3 },
-       { 0x02cf1e,  4 },
-       { 0x02e234,  5 },
-       { 0x02f409,  6 },
-       { 0x030046,  7 },
-       { 0x030844,  8 },
-       { 0x030a02,  9 },
-       { 0x030cde, 10 },
-       { 0x031031, 11 },
-       { 0x03144c, 12 },
-       { 0x0315dd, 13 },
-       { 0x031920, 14 },
-       { 0x0322d0, 15 },
-       { 0x0339fc, 16 },
-       { 0x0364a1, 17 },
-       { 0x038bcc, 18 },
-       { 0x03c7d3, 19 },
-       { 0x0408cc, 20 },
-       { 0x043bed, 21 },
-       { 0x048061, 22 },
-       { 0x04be95, 23 },
-       { 0x04fa7d, 24 },
-       { 0x052405, 25 },
-       { 0x05570d, 26 },
-       { 0x059feb, 27 },
-       { 0x05bf38, 28 },
-       { 0xffffff, 29 },
-};
-
-static const struct reg_val ofsm_init[] = {
-       { 0x800051, 0x01 },
-       { 0x800070, 0x0a },
-       { 0x80007e, 0x04 },
-       { 0x800081, 0x0a },
-       { 0x80008a, 0x01 },
-       { 0x80008e, 0x01 },
-       { 0x800092, 0x06 },
-       { 0x800099, 0x01 },
-       { 0x80009f, 0xe1 },
-       { 0x8000a0, 0xcf },
-       { 0x8000a3, 0x01 },
-       { 0x8000a5, 0x01 },
-       { 0x8000a6, 0x01 },
-       { 0x8000a9, 0x00 },
-       { 0x8000aa, 0x01 },
-       { 0x8000ab, 0x01 },
-       { 0x8000b0, 0x01 },
-       { 0x8000c0, 0x05 },
-       { 0x8000c4, 0x19 },
-       { 0x80f000, 0x0f },
-       { 0x80f016, 0x10 },
-       { 0x80f017, 0x04 },
-       { 0x80f018, 0x05 },
-       { 0x80f019, 0x04 },
-       { 0x80f01a, 0x05 },
-       { 0x80f021, 0x03 },
-       { 0x80f022, 0x0a },
-       { 0x80f023, 0x0a },
-       { 0x80f02b, 0x00 },
-       { 0x80f02c, 0x01 },
-       { 0x80f064, 0x03 },
-       { 0x80f065, 0xf9 },
-       { 0x80f066, 0x03 },
-       { 0x80f067, 0x01 },
-       { 0x80f06f, 0xe0 },
-       { 0x80f070, 0x03 },
-       { 0x80f072, 0x0f },
-       { 0x80f073, 0x03 },
-       { 0x80f078, 0x00 },
-       { 0x80f087, 0x00 },
-       { 0x80f09b, 0x3f },
-       { 0x80f09c, 0x00 },
-       { 0x80f09d, 0x20 },
-       { 0x80f09e, 0x00 },
-       { 0x80f09f, 0x0c },
-       { 0x80f0a0, 0x00 },
-       { 0x80f130, 0x04 },
-       { 0x80f132, 0x04 },
-       { 0x80f144, 0x1a },
-       { 0x80f146, 0x00 },
-       { 0x80f14a, 0x01 },
-       { 0x80f14c, 0x00 },
-       { 0x80f14d, 0x00 },
-       { 0x80f14f, 0x04 },
-       { 0x80f158, 0x7f },
-       { 0x80f15a, 0x00 },
-       { 0x80f15b, 0x08 },
-       { 0x80f15d, 0x03 },
-       { 0x80f15e, 0x05 },
-       { 0x80f163, 0x05 },
-       { 0x80f166, 0x01 },
-       { 0x80f167, 0x40 },
-       { 0x80f168, 0x0f },
-       { 0x80f17a, 0x00 },
-       { 0x80f17b, 0x00 },
-       { 0x80f183, 0x01 },
-       { 0x80f19d, 0x40 },
-       { 0x80f1bc, 0x36 },
-       { 0x80f1bd, 0x00 },
-       { 0x80f1cb, 0xa0 },
-       { 0x80f1cc, 0x01 },
-       { 0x80f204, 0x10 },
-       { 0x80f214, 0x00 },
-       { 0x80f40e, 0x0a },
-       { 0x80f40f, 0x40 },
-       { 0x80f410, 0x08 },
-       { 0x80f55f, 0x0a },
-       { 0x80f561, 0x15 },
-       { 0x80f562, 0x20 },
-       { 0x80f5df, 0xfb },
-       { 0x80f5e0, 0x00 },
-       { 0x80f5e3, 0x09 },
-       { 0x80f5e4, 0x01 },
-       { 0x80f5e5, 0x01 },
-       { 0x80f5f8, 0x01 },
-       { 0x80f5fd, 0x01 },
-       { 0x80f600, 0x05 },
-       { 0x80f601, 0x08 },
-       { 0x80f602, 0x0b },
-       { 0x80f603, 0x0e },
-       { 0x80f604, 0x11 },
-       { 0x80f605, 0x14 },
-       { 0x80f606, 0x17 },
-       { 0x80f607, 0x1f },
-       { 0x80f60e, 0x00 },
-       { 0x80f60f, 0x04 },
-       { 0x80f610, 0x32 },
-       { 0x80f611, 0x10 },
-       { 0x80f707, 0xfc },
-       { 0x80f708, 0x00 },
-       { 0x80f709, 0x37 },
-       { 0x80f70a, 0x00 },
-       { 0x80f78b, 0x01 },
-       { 0x80f80f, 0x40 },
-       { 0x80f810, 0x54 },
-       { 0x80f811, 0x5a },
-       { 0x80f905, 0x01 },
-       { 0x80fb06, 0x03 },
-       { 0x80fd8b, 0x00 },
-};
-
-/* Infineon TUA 9001 tuner init
-   AF9033_TUNER_TUA9001    = 0x27 */
-static const struct reg_val tuner_init_tua9001[] = {
-       { 0x800046, 0x27 },
-       { 0x800057, 0x00 },
-       { 0x800058, 0x01 },
-       { 0x80005f, 0x00 },
-       { 0x800060, 0x00 },
-       { 0x80006d, 0x00 },
-       { 0x800071, 0x05 },
-       { 0x800072, 0x02 },
-       { 0x800074, 0x01 },
-       { 0x800075, 0x03 },
-       { 0x800076, 0x02 },
-       { 0x800077, 0x00 },
-       { 0x800078, 0x01 },
-       { 0x800079, 0x00 },
-       { 0x80007a, 0x7e },
-       { 0x80007b, 0x3e },
-       { 0x800093, 0x00 },
-       { 0x800094, 0x01 },
-       { 0x800095, 0x02 },
-       { 0x800096, 0x01 },
-       { 0x800098, 0x0a },
-       { 0x80009b, 0x05 },
-       { 0x80009c, 0x80 },
-       { 0x8000b3, 0x00 },
-       { 0x8000c1, 0x01 },
-       { 0x8000c2, 0x00 },
-       { 0x80f007, 0x00 },
-       { 0x80f01f, 0x82 },
-       { 0x80f020, 0x00 },
-       { 0x80f029, 0x82 },
-       { 0x80f02a, 0x00 },
-       { 0x80f047, 0x00 },
-       { 0x80f054, 0x00 },
-       { 0x80f055, 0x00 },
-       { 0x80f077, 0x01 },
-       { 0x80f1e6, 0x00 },
-};
-
-/* Fitipower fc0011 tuner init
-   AF9033_TUNER_FC0011    = 0x28 */
-static const struct reg_val tuner_init_fc0011[] = {
-       { 0x800046, AF9033_TUNER_FC0011 },
-       { 0x800057, 0x00 },
-       { 0x800058, 0x01 },
-       { 0x80005f, 0x00 },
-       { 0x800060, 0x00 },
-       { 0x800068, 0xa5 },
-       { 0x80006e, 0x01 },
-       { 0x800071, 0x0A },
-       { 0x800072, 0x02 },
-       { 0x800074, 0x01 },
-       { 0x800079, 0x01 },
-       { 0x800093, 0x00 },
-       { 0x800094, 0x00 },
-       { 0x800095, 0x00 },
-       { 0x800096, 0x00 },
-       { 0x80009b, 0x2D },
-       { 0x80009c, 0x60 },
-       { 0x80009d, 0x23 },
-       { 0x8000a4, 0x50 },
-       { 0x8000ad, 0x50 },
-       { 0x8000b3, 0x01 },
-       { 0x8000b7, 0x88 },
-       { 0x8000b8, 0xa6 },
-       { 0x8000c3, 0x01 },
-       { 0x8000c4, 0x01 },
-       { 0x8000c7, 0x69 },
-       { 0x80F007, 0x00 },
-       { 0x80F00A, 0x1B },
-       { 0x80F00B, 0x1B },
-       { 0x80F00C, 0x1B },
-       { 0x80F00D, 0x1B },
-       { 0x80F00E, 0xFF },
-       { 0x80F00F, 0x01 },
-       { 0x80F010, 0x00 },
-       { 0x80F011, 0x02 },
-       { 0x80F012, 0xFF },
-       { 0x80F013, 0x01 },
-       { 0x80F014, 0x00 },
-       { 0x80F015, 0x02 },
-       { 0x80F01B, 0xEF },
-       { 0x80F01C, 0x01 },
-       { 0x80F01D, 0x0f },
-       { 0x80F01E, 0x02 },
-       { 0x80F01F, 0x6E },
-       { 0x80F020, 0x00 },
-       { 0x80F025, 0xDE },
-       { 0x80F026, 0x00 },
-       { 0x80F027, 0x0A },
-       { 0x80F028, 0x03 },
-       { 0x80F029, 0x6E },
-       { 0x80F02A, 0x00 },
-       { 0x80F047, 0x00 },
-       { 0x80F054, 0x00 },
-       { 0x80F055, 0x00 },
-       { 0x80F077, 0x01 },
-       { 0x80F1E6, 0x00 },
-};
-
-/* MaxLinear MxL5007T tuner init
-   AF9033_TUNER_MXL5007T    = 0xa0 */
-static const struct reg_val tuner_init_mxl5007t[] = {
-       { 0x800046, 0x1b },
-       { 0x800057, 0x01 },
-       { 0x800058, 0x01 },
-       { 0x80005f, 0x00 },
-       { 0x800060, 0x00 },
-       { 0x800068, 0x96 },
-       { 0x800071, 0x05 },
-       { 0x800072, 0x02 },
-       { 0x800074, 0x01 },
-       { 0x800079, 0x01 },
-       { 0x800093, 0x00 },
-       { 0x800094, 0x00 },
-       { 0x800095, 0x00 },
-       { 0x800096, 0x00 },
-       { 0x8000b3, 0x01 },
-       { 0x8000c1, 0x01 },
-       { 0x8000c2, 0x00 },
-       { 0x80f007, 0x00 },
-       { 0x80f00c, 0x19 },
-       { 0x80f00d, 0x1a },
-       { 0x80f012, 0xda },
-       { 0x80f013, 0x00 },
-       { 0x80f014, 0x00 },
-       { 0x80f015, 0x02 },
-       { 0x80f01f, 0x82 },
-       { 0x80f020, 0x00 },
-       { 0x80f029, 0x82 },
-       { 0x80f02a, 0x00 },
-       { 0x80f077, 0x02 },
-       { 0x80f1e6, 0x00 },
-};
-
-/* NXP TDA 18218HN tuner init
-   AF9033_TUNER_TDA18218    = 0xa1 */
-static const struct reg_val tuner_init_tda18218[] = {
-       {0x800046, 0xa1},
-       {0x800057, 0x01},
-       {0x800058, 0x01},
-       {0x80005f, 0x00},
-       {0x800060, 0x00},
-       {0x800071, 0x05},
-       {0x800072, 0x02},
-       {0x800074, 0x01},
-       {0x800079, 0x01},
-       {0x800093, 0x00},
-       {0x800094, 0x00},
-       {0x800095, 0x00},
-       {0x800096, 0x00},
-       {0x8000b3, 0x01},
-       {0x8000c3, 0x01},
-       {0x8000c4, 0x00},
-       {0x80f007, 0x00},
-       {0x80f00c, 0x19},
-       {0x80f00d, 0x1a},
-       {0x80f012, 0xda},
-       {0x80f013, 0x00},
-       {0x80f014, 0x00},
-       {0x80f015, 0x02},
-       {0x80f01f, 0x82},
-       {0x80f020, 0x00},
-       {0x80f029, 0x82},
-       {0x80f02a, 0x00},
-       {0x80f077, 0x02},
-       {0x80f1e6, 0x00},
-};
-
-#endif /* AF9033_PRIV_H */
-
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
deleted file mode 100644 (file)
index 4e11dc4..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
- *    ATBM8830, ATBM8831
- *
- *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/div64.h>
-#include "dvb_frontend.h"
-
-#include "atbm8830.h"
-#include "atbm8830_priv.h"
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "atbm8830: " args); \
-       } while (0)
-
-static int debug;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
-{
-       int ret = 0;
-       u8 dev_addr;
-       u8 buf1[] = { reg >> 8, reg & 0xFF };
-       u8 buf2[] = { data };
-       struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
-       struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
-
-       dev_addr = priv->config->demod_address;
-       msg1.addr = dev_addr;
-       msg2.addr = dev_addr;
-
-       if (debug >= 2)
-               dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
-
-       ret = i2c_transfer(priv->i2c, &msg1, 1);
-       if (ret != 1)
-               return -EIO;
-
-       ret = i2c_transfer(priv->i2c, &msg2, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
-{
-       int ret;
-       u8 dev_addr;
-
-       u8 buf1[] = { reg >> 8, reg & 0xFF };
-       u8 buf2[] = { 0 };
-       struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
-       struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
-
-       dev_addr = priv->config->demod_address;
-       msg1.addr = dev_addr;
-       msg2.addr = dev_addr;
-
-       ret = i2c_transfer(priv->i2c, &msg1, 1);
-       if (ret != 1) {
-               dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
-               return -EIO;
-       }
-
-       ret = i2c_transfer(priv->i2c, &msg2, 1);
-       if (ret != 1)
-               return -EIO;
-
-       *p_data = buf2[0];
-       if (debug >= 2)
-               dprintk("%s: reg=0x%04X, data=0x%02X\n",
-                       __func__, reg, buf2[0]);
-
-       return 0;
-}
-
-/* Lock register latch so that multi-register read is atomic */
-static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
-{
-       return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
-}
-
-static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
-{
-       u32 val;
-       u64 t;
-
-       /* 0x100000 * freq / 30.4MHz */
-       t = (u64)0x100000 * freq;
-       do_div(t, 30400);
-       val = t;
-
-       atbm8830_write_reg(priv, REG_OSC_CLK, val);
-       atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
-       atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
-
-       return 0;
-}
-
-static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
-{
-
-       u32 fs = priv->config->osc_clk_freq;
-       u64 t;
-       u32 val;
-       u8 dat;
-
-       if (freq != 0) {
-               /* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
-               t = (u64) 2 * 31416 * (freq - fs);
-               t <<= 22;
-               do_div(t, fs);
-               do_div(t, 1000);
-               val = t;
-
-               atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
-               atbm8830_write_reg(priv, REG_IF_FREQ, val);
-               atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
-               atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
-
-               atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
-               dat &= 0xFC;
-               atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
-       } else {
-               /* Zero IF */
-               atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
-
-               atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
-               dat &= 0xFC;
-               dat |= 0x02;
-               atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
-
-               if (priv->config->zif_swap_iq)
-                       atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
-               else
-                       atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
-       }
-
-       return 0;
-}
-
-static int is_locked(struct atbm_state *priv, u8 *locked)
-{
-       u8 status;
-
-       atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
-
-       if (locked != NULL)
-               *locked = (status == 1);
-       return 0;
-}
-
-static int set_agc_config(struct atbm_state *priv,
-       u8 min, u8 max, u8 hold_loop)
-{
-       /* no effect if both min and max are zero */
-       if (!min && !max)
-           return 0;
-
-       atbm8830_write_reg(priv, REG_AGC_MIN, min);
-       atbm8830_write_reg(priv, REG_AGC_MAX, max);
-       atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
-
-       return 0;
-}
-
-static int set_static_channel_mode(struct atbm_state *priv)
-{
-       int i;
-
-       for (i = 0; i < 5; i++)
-               atbm8830_write_reg(priv, 0x099B + i, 0x08);
-
-       atbm8830_write_reg(priv, 0x095B, 0x7F);
-       atbm8830_write_reg(priv, 0x09CB, 0x01);
-       atbm8830_write_reg(priv, 0x09CC, 0x7F);
-       atbm8830_write_reg(priv, 0x09CD, 0x7F);
-       atbm8830_write_reg(priv, 0x0E01, 0x20);
-
-       /* For single carrier */
-       atbm8830_write_reg(priv, 0x0B03, 0x0A);
-       atbm8830_write_reg(priv, 0x0935, 0x10);
-       atbm8830_write_reg(priv, 0x0936, 0x08);
-       atbm8830_write_reg(priv, 0x093E, 0x08);
-       atbm8830_write_reg(priv, 0x096E, 0x06);
-
-       /* frame_count_max0 */
-       atbm8830_write_reg(priv, 0x0B09, 0x00);
-       /* frame_count_max1 */
-       atbm8830_write_reg(priv, 0x0B0A, 0x08);
-
-       return 0;
-}
-
-static int set_ts_config(struct atbm_state *priv)
-{
-       const struct atbm8830_config *cfg = priv->config;
-
-       /*Set parallel/serial ts mode*/
-       atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
-       atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
-       /*Set ts sampling edge*/
-       atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
-               cfg->ts_sampling_edge ? 1 : 0);
-       /*Set ts clock freerun*/
-       atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
-               cfg->ts_clk_gated ? 0 : 1);
-
-       return 0;
-}
-
-static int atbm8830_init(struct dvb_frontend *fe)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-       const struct atbm8830_config *cfg = priv->config;
-
-       /*Set oscillator frequency*/
-       set_osc_freq(priv, cfg->osc_clk_freq);
-
-       /*Set IF frequency*/
-       set_if_freq(priv, cfg->if_freq);
-
-       /*Set AGC Config*/
-       set_agc_config(priv, cfg->agc_min, cfg->agc_max,
-               cfg->agc_hold_loop);
-
-       /*Set static channel mode*/
-       set_static_channel_mode(priv);
-
-       set_ts_config(priv);
-       /*Turn off DSP reset*/
-       atbm8830_write_reg(priv, 0x000A, 0);
-
-       /*SW version test*/
-       atbm8830_write_reg(priv, 0x020C, 11);
-
-       /* Run */
-       atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
-
-       return 0;
-}
-
-
-static void atbm8830_release(struct dvb_frontend *fe)
-{
-       struct atbm_state *state = fe->demodulator_priv;
-       dprintk("%s\n", __func__);
-
-       kfree(state);
-}
-
-static int atbm8830_set_fe(struct dvb_frontend *fe)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-       int i;
-       u8 locked = 0;
-       dprintk("%s\n", __func__);
-
-       /* set frequency */
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* start auto lock */
-       for (i = 0; i < 10; i++) {
-               mdelay(100);
-               dprintk("Try %d\n", i);
-               is_locked(priv, &locked);
-               if (locked != 0) {
-                       dprintk("ATBM8830 locked!\n");
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int atbm8830_get_fe(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       dprintk("%s\n", __func__);
-
-       /* TODO: get real readings from device */
-       /* inversion status */
-       c->inversion = INVERSION_OFF;
-
-       /* bandwidth */
-       c->bandwidth_hz = 8000000;
-
-       c->code_rate_HP = FEC_AUTO;
-       c->code_rate_LP = FEC_AUTO;
-
-       c->modulation = QAM_AUTO;
-
-       /* transmission mode */
-       c->transmission_mode = TRANSMISSION_MODE_AUTO;
-
-       /* guard interval */
-       c->guard_interval = GUARD_INTERVAL_AUTO;
-
-       /* hierarchy */
-       c->hierarchy = HIERARCHY_NONE;
-
-       return 0;
-}
-
-static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 0;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-       u8 locked = 0;
-       u8 agc_locked = 0;
-
-       dprintk("%s\n", __func__);
-       *fe_status = 0;
-
-       is_locked(priv, &locked);
-       if (locked) {
-               *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                       FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-       }
-       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
-
-       atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
-       dprintk("AGC Lock: %d\n", agc_locked);
-
-       return 0;
-}
-
-static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-       u32 frame_err;
-       u8 t;
-
-       dprintk("%s\n", __func__);
-
-       atbm8830_reglatch_lock(priv, 1);
-
-       atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
-       frame_err = t & 0x7F;
-       frame_err <<= 8;
-       atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
-       frame_err |= t;
-
-       atbm8830_reglatch_lock(priv, 0);
-
-       *ber = frame_err * 100 / 32767;
-
-       dprintk("%s: ber=0x%x\n", __func__, *ber);
-       return 0;
-}
-
-static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-       u32 pwm;
-       u8 t;
-
-       dprintk("%s\n", __func__);
-       atbm8830_reglatch_lock(priv, 1);
-
-       atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
-       pwm = t & 0x03;
-       pwm <<= 8;
-       atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
-       pwm |= t;
-
-       atbm8830_reglatch_lock(priv, 0);
-
-       dprintk("AGC PWM = 0x%02X\n", pwm);
-       pwm = 0x400 - pwm;
-
-       *signal = pwm * 0x10000 / 0x400;
-
-       return 0;
-}
-
-static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       dprintk("%s\n", __func__);
-       *snr = 0;
-       return 0;
-}
-
-static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       dprintk("%s\n", __func__);
-       *ucblocks = 0;
-       return 0;
-}
-
-static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct atbm_state *priv = fe->demodulator_priv;
-
-       return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
-}
-
-static struct dvb_frontend_ops atbm8830_ops = {
-       .delsys = { SYS_DTMB },
-       .info = {
-               .name = "AltoBeam ATBM8830/8831 DMB-TH",
-               .frequency_min = 474000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 10000,
-               .caps =
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO
-       },
-
-       .release = atbm8830_release,
-
-       .init = atbm8830_init,
-       .sleep = NULL,
-       .write = NULL,
-       .i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
-
-       .set_frontend = atbm8830_set_fe,
-       .get_frontend = atbm8830_get_fe,
-       .get_tune_settings = atbm8830_get_tune_settings,
-
-       .read_status = atbm8830_read_status,
-       .read_ber = atbm8830_read_ber,
-       .read_signal_strength = atbm8830_read_signal_strength,
-       .read_snr = atbm8830_read_snr,
-       .read_ucblocks = atbm8830_read_ucblocks,
-};
-
-struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
-       struct i2c_adapter *i2c)
-{
-       struct atbm_state *priv = NULL;
-       u8 data = 0;
-
-       dprintk("%s()\n", __func__);
-
-       if (config == NULL || i2c == NULL)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
-       if (priv == NULL)
-               goto error_out;
-
-       priv->config = config;
-       priv->i2c = i2c;
-
-       /* check if the demod is there */
-       if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
-               dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
-                       __func__, priv->config->demod_address);
-               goto error_out;
-       }
-       dprintk("atbm8830 chip id: 0x%02X\n", data);
-
-       memcpy(&priv->frontend.ops, &atbm8830_ops,
-              sizeof(struct dvb_frontend_ops));
-       priv->frontend.demodulator_priv = priv;
-
-       atbm8830_init(&priv->frontend);
-
-       atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
-
-       return &priv->frontend;
-
-error_out:
-       dprintk("%s() error_out\n", __func__);
-       kfree(priv);
-       return NULL;
-
-}
-EXPORT_SYMBOL(atbm8830_attach);
-
-MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
-MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h
deleted file mode 100644 (file)
index 0242733..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
- *    ATBM8830, ATBM8831
- *
- *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ATBM8830_H__
-#define __ATBM8830_H__
-
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#define ATBM8830_PROD_8830 0
-#define ATBM8830_PROD_8831 1
-
-struct atbm8830_config {
-
-       /* product type */
-       u8 prod;
-
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* parallel or serial transport stream */
-       u8 serial_ts;
-
-       /* transport stream clock output only when receiving valid stream */
-       u8 ts_clk_gated;
-
-       /* Decoder sample TS data at rising edge of clock */
-       u8 ts_sampling_edge;
-
-       /* Oscillator clock frequency */
-       u32 osc_clk_freq; /* in kHz */
-
-       /* IF frequency */
-       u32 if_freq; /* in kHz */
-
-       /* Swap I/Q for zero IF */
-       u8 zif_swap_iq;
-
-       /* Tuner AGC settings */
-       u8 agc_min;
-       u8 agc_max;
-       u8 agc_hold_loop;
-};
-
-#if defined(CONFIG_DVB_ATBM8830) || \
-       (defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
-extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
-               struct i2c_adapter *i2c);
-#else
-static inline
-struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
-               struct i2c_adapter *i2c) {
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_ATBM8830 */
-
-#endif /* __ATBM8830_H__ */
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h
deleted file mode 100644 (file)
index d460058..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *    Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
- *    ATBM8830, ATBM8831
- *
- *    Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ATBM8830_PRIV_H
-#define __ATBM8830_PRIV_H
-
-struct atbm_state {
-       struct i2c_adapter *i2c;
-       /* configuration settings */
-       const struct atbm8830_config *config;
-       struct dvb_frontend frontend;
-};
-
-#define REG_CHIP_ID    0x0000
-#define REG_TUNER_BASEBAND     0x0001
-#define REG_DEMOD_RUN  0x0004
-#define REG_DSP_RESET  0x0005
-#define REG_RAM_RESET  0x0006
-#define REG_ADC_RESET  0x0007
-#define REG_TSPORT_RESET       0x0008
-#define REG_BLKERR_POL 0x000C
-#define REG_I2C_GATE   0x0103
-#define REG_TS_SAMPLE_EDGE     0x0301
-#define REG_TS_PKT_LEN_204     0x0302
-#define REG_TS_PKT_LEN_AUTO    0x0303
-#define REG_TS_SERIAL  0x0305
-#define REG_TS_CLK_FREERUN     0x0306
-#define REG_TS_VALID_MODE      0x0307
-#define REG_TS_CLK_MODE        0x030B /* 1 for serial, 0 for parallel */
-
-#define REG_TS_ERRBIT_USE      0x030C
-#define REG_LOCK_STATUS        0x030D
-#define REG_ADC_CONFIG 0x0602
-#define REG_CARRIER_OFFSET     0x0827 /* 0x0827-0x0829 little endian */
-#define REG_DETECTED_PN_MODE   0x082D
-#define REG_READ_LATCH 0x084D
-#define REG_IF_FREQ    0x0A00 /* 0x0A00-0x0A02 little endian */
-#define REG_OSC_CLK    0x0A03 /* 0x0A03-0x0A05 little endian */
-#define REG_BYPASS_CCI 0x0A06
-#define REG_ANALOG_LUMA_DETECTED       0x0A25
-#define REG_ANALOG_AUDIO_DETECTED      0x0A26
-#define REG_ANALOG_CHROMA_DETECTED     0x0A39
-#define REG_FRAME_ERR_CNT      0x0B04
-#define REG_USE_EXT_ADC        0x0C00
-#define REG_SWAP_I_Q   0x0C01
-#define REG_TPS_MANUAL 0x0D01
-#define REG_TPS_CONFIG 0x0D02
-#define REG_BYPASS_DEINTERLEAVER       0x0E00
-#define REG_AGC_TARGET 0x1003 /* 0x1003-0x1005 little endian */
-#define REG_AGC_MIN    0x1020
-#define REG_AGC_MAX    0x1023
-#define REG_AGC_LOCK   0x1027
-#define REG_AGC_PWM_VAL        0x1028 /* 0x1028-0x1029 little endian */
-#define REG_AGC_HOLD_LOOP      0x1031
-
-#endif
-
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
deleted file mode 100644 (file)
index 565dcf3..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-    Auvitek AU8522 QAM/8VSB demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef __AU8522_H__
-#define __AU8522_H__
-
-#include <linux/dvb/frontend.h>
-
-enum au8522_if_freq {
-       AU8522_IF_6MHZ = 0,
-       AU8522_IF_4MHZ,
-       AU8522_IF_3_25MHZ,
-};
-
-struct au8522_led_config {
-       u16 vsb8_strong;
-       u16 qam64_strong;
-       u16 qam256_strong;
-
-       u16 gpio_output;
-       /* unset hi bits, set low bits */
-       u16 gpio_output_enable;
-       u16 gpio_output_disable;
-
-       u16 gpio_leds;
-       u8 *led_states;
-       unsigned int num_led_states;
-};
-
-struct au8522_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* Return lock status based on tuner lock, or demod lock */
-#define AU8522_TUNERLOCKING 0
-#define AU8522_DEMODLOCKING 1
-       u8 status_mode;
-
-       struct au8522_led_config *led_cfg;
-
-       enum au8522_if_freq vsb_if;
-       enum au8522_if_freq qam_if;
-};
-
-#if defined(CONFIG_DVB_AU8522) ||                              \
-           (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
-extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
-                                         struct i2c_adapter *i2c);
-#else
-static inline
-struct dvb_frontend *au8522_attach(const struct au8522_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_AU8522 */
-
-/* Other modes may need to be added later */
-enum au8522_video_input {
-       AU8522_COMPOSITE_CH1 = 1,
-       AU8522_COMPOSITE_CH2,
-       AU8522_COMPOSITE_CH3,
-       AU8522_COMPOSITE_CH4,
-       AU8522_COMPOSITE_CH4_SIF,
-       AU8522_SVIDEO_CH13,
-       AU8522_SVIDEO_CH24,
-};
-
-enum au8522_audio_input {
-       AU8522_AUDIO_NONE,
-       AU8522_AUDIO_SIF,
-};
-
-#endif /* __AU8522_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/frontends/au8522_common.c b/drivers/media/dvb/frontends/au8522_common.c
deleted file mode 100644 (file)
index 3559ff2..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-    Auvitek AU8522 QAM/8VSB demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-    Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
-    Copyright (C) 2005-2008 Auvitek International, Ltd.
-    Copyright (C) 2012 Michael Krufky <mkrufky@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "au8522_priv.h"
-
-static int debug;
-
-#define dprintk(arg...)\
-  do { if (debug)\
-        printk(arg);\
-  } while (0)
-
-/* Despite the name "hybrid_tuner", the framework works just as well for
-   hybrid demodulators as well... */
-static LIST_HEAD(hybrid_tuner_instance_list);
-static DEFINE_MUTEX(au8522_list_mutex);
-
-/* 16 bit registers, 8 bit values */
-int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
-
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-                              .flags = 0, .buf = buf, .len = 3 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
-                      "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-EXPORT_SYMBOL(au8522_writereg);
-
-u8 au8522_readreg(struct au8522_state *state, u16 reg)
-{
-       int ret;
-       u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
-       u8 b1[] = { 0 };
-
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0,
-                 .buf = b0, .len = 2 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD,
-                 .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
-                      __func__, ret);
-       return b1[0];
-}
-EXPORT_SYMBOL(au8522_readreg);
-
-int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (state->operational_mode == AU8522_ANALOG_MODE) {
-               /* We're being asked to manage the gate even though we're
-                  not in digital mode.  This can occur if we get switched
-                  over to analog mode before the dvb_frontend kernel thread
-                  has completely shutdown */
-               return 0;
-       }
-
-       if (enable)
-               return au8522_writereg(state, 0x106, 1);
-       else
-               return au8522_writereg(state, 0x106, 0);
-}
-EXPORT_SYMBOL(au8522_i2c_gate_ctrl);
-
-int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (enable)
-               return au8522_writereg(state, 0x106, 1);
-       else
-               return au8522_writereg(state, 0x106, 0);
-}
-EXPORT_SYMBOL(au8522_analog_i2c_gate_ctrl);
-
-/* Reset the demod hardware and reset all of the configuration registers
-   to a default state. */
-int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
-                    u8 client_address)
-{
-       int ret;
-
-       mutex_lock(&au8522_list_mutex);
-       ret = hybrid_tuner_request_state(struct au8522_state, (*state),
-                                        hybrid_tuner_instance_list,
-                                        i2c, client_address, "au8522");
-       mutex_unlock(&au8522_list_mutex);
-
-       return ret;
-}
-EXPORT_SYMBOL(au8522_get_state);
-
-void au8522_release_state(struct au8522_state *state)
-{
-       mutex_lock(&au8522_list_mutex);
-       if (state != NULL)
-               hybrid_tuner_release_state(state);
-       mutex_unlock(&au8522_list_mutex);
-}
-EXPORT_SYMBOL(au8522_release_state);
-
-static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
-{
-       struct au8522_led_config *led_config = state->config->led_cfg;
-       u8 val;
-
-       /* bail out if we can't control an LED */
-       if (!led_config || !led_config->gpio_output ||
-           !led_config->gpio_output_enable || !led_config->gpio_output_disable)
-               return 0;
-
-       val = au8522_readreg(state, 0x4000 |
-                            (led_config->gpio_output & ~0xc000));
-       if (onoff) {
-               /* enable GPIO output */
-               val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
-               val |=  (led_config->gpio_output_enable & 0xff);
-       } else {
-               /* disable GPIO output */
-               val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
-               val |=  (led_config->gpio_output_disable & 0xff);
-       }
-       return au8522_writereg(state, 0x8000 |
-                              (led_config->gpio_output & ~0xc000), val);
-}
-
-/* led = 0 | off
- * led = 1 | signal ok
- * led = 2 | signal strong
- * led < 0 | only light led if leds are currently off
- */
-int au8522_led_ctrl(struct au8522_state *state, int led)
-{
-       struct au8522_led_config *led_config = state->config->led_cfg;
-       int i, ret = 0;
-
-       /* bail out if we can't control an LED */
-       if (!led_config || !led_config->gpio_leds ||
-           !led_config->num_led_states || !led_config->led_states)
-               return 0;
-
-       if (led < 0) {
-               /* if LED is already lit, then leave it as-is */
-               if (state->led_state)
-                       return 0;
-               else
-                       led *= -1;
-       }
-
-       /* toggle LED if changing state */
-       if (state->led_state != led) {
-               u8 val;
-
-               dprintk("%s: %d\n", __func__, led);
-
-               au8522_led_gpio_enable(state, 1);
-
-               val = au8522_readreg(state, 0x4000 |
-                                    (led_config->gpio_leds & ~0xc000));
-
-               /* start with all leds off */
-               for (i = 0; i < led_config->num_led_states; i++)
-                       val &= ~led_config->led_states[i];
-
-               /* set selected LED state */
-               if (led < led_config->num_led_states)
-                       val |= led_config->led_states[led];
-               else if (led_config->num_led_states)
-                       val |=
-                       led_config->led_states[led_config->num_led_states - 1];
-
-               ret = au8522_writereg(state, 0x8000 |
-                                     (led_config->gpio_leds & ~0xc000), val);
-               if (ret < 0)
-                       return ret;
-
-               state->led_state = led;
-
-               if (led == 0)
-                       au8522_led_gpio_enable(state, 0);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(au8522_led_ctrl);
-
-int au8522_init(struct dvb_frontend *fe)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       dprintk("%s()\n", __func__);
-
-       state->operational_mode = AU8522_DIGITAL_MODE;
-
-       /* Clear out any state associated with the digital side of the
-          chip, so that when it gets powered back up it won't think
-          that it is already tuned */
-       state->current_frequency = 0;
-
-       au8522_writereg(state, 0xa4, 1 << 5);
-
-       au8522_i2c_gate_ctrl(fe, 1);
-
-       return 0;
-}
-EXPORT_SYMBOL(au8522_init);
-
-int au8522_sleep(struct dvb_frontend *fe)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       dprintk("%s()\n", __func__);
-
-       /* Only power down if the digital side is currently using the chip */
-       if (state->operational_mode == AU8522_ANALOG_MODE) {
-               /* We're not in one of the expected power modes, which means
-                  that the DVB thread is probably telling us to go to sleep
-                  even though the analog frontend has already started using
-                  the chip.  So ignore the request */
-               return 0;
-       }
-
-       /* turn off led */
-       au8522_led_ctrl(state, 0);
-
-       /* Power down the chip */
-       au8522_writereg(state, 0xa4, 1 << 5);
-
-       state->current_frequency = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL(au8522_sleep);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
deleted file mode 100644 (file)
index 5243ba6..0000000
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
- *
- * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
- * Copyright (C) 2005-2008 Auvitek International, Ltd.
- *
- * 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.
- */
-
-/* Developer notes:
- *
- * VBI support is not yet working
- * Enough is implemented here for CVBS and S-Video inputs, but the actual
- *  analog demodulator code isn't implemented (not needed for xc5000 since it
- *  has its own demodulator and outputs CVBS)
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-device.h>
-#include "au8522.h"
-#include "au8522_priv.h"
-
-MODULE_AUTHOR("Devin Heitmueller");
-MODULE_LICENSE("GPL");
-
-static int au8522_analog_debug;
-
-
-module_param_named(analog_debug, au8522_analog_debug, int, 0644);
-
-MODULE_PARM_DESC(analog_debug,
-                "Analog debugging messages [0=Off (default) 1=On]");
-
-struct au8522_register_config {
-       u16 reg_name;
-       u8 reg_val[8];
-};
-
-
-/* Video Decoder Filter Coefficients
-   The values are as follows from left to right
-   0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
-*/
-static const struct au8522_register_config filter_coef[] = {
-       {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
-       {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
-       {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
-       {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
-       {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
-       {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
-       {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
-       {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
-       {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
-       {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
-       {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
-       {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
-       {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
-       {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
-       {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
-       {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
-       {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
-       {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
-       {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
-       {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
-       {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
-       {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
-
-};
-#define NUM_FILTER_COEF (sizeof(filter_coef)\
-                        / sizeof(struct au8522_register_config))
-
-
-/* Registers 0x060b through 0x0652 are the LP Filter coefficients
-   The values are as follows from left to right
-   0="SIF" 1="ATVRF/ATVRF13"
-   Note: the "ATVRF/ATVRF13" mode has never been tested
-*/
-static const struct au8522_register_config lpfilter_coef[] = {
-       {0x060b, {0x21, 0x0b} },
-       {0x060c, {0xad, 0xad} },
-       {0x060d, {0x70, 0xf0} },
-       {0x060e, {0xea, 0xe9} },
-       {0x060f, {0xdd, 0xdd} },
-       {0x0610, {0x08, 0x64} },
-       {0x0611, {0x60, 0x60} },
-       {0x0612, {0xf8, 0xb2} },
-       {0x0613, {0x01, 0x02} },
-       {0x0614, {0xe4, 0xb4} },
-       {0x0615, {0x19, 0x02} },
-       {0x0616, {0xae, 0x2e} },
-       {0x0617, {0xee, 0xc5} },
-       {0x0618, {0x56, 0x56} },
-       {0x0619, {0x30, 0x58} },
-       {0x061a, {0xf9, 0xf8} },
-       {0x061b, {0x24, 0x64} },
-       {0x061c, {0x07, 0x07} },
-       {0x061d, {0x30, 0x30} },
-       {0x061e, {0xa9, 0xed} },
-       {0x061f, {0x09, 0x0b} },
-       {0x0620, {0x42, 0xc2} },
-       {0x0621, {0x1d, 0x2a} },
-       {0x0622, {0xd6, 0x56} },
-       {0x0623, {0x95, 0x8b} },
-       {0x0624, {0x2b, 0x2b} },
-       {0x0625, {0x30, 0x24} },
-       {0x0626, {0x3e, 0x3e} },
-       {0x0627, {0x62, 0xe2} },
-       {0x0628, {0xe9, 0xf5} },
-       {0x0629, {0x99, 0x19} },
-       {0x062a, {0xd4, 0x11} },
-       {0x062b, {0x03, 0x04} },
-       {0x062c, {0xb5, 0x85} },
-       {0x062d, {0x1e, 0x20} },
-       {0x062e, {0x2a, 0xea} },
-       {0x062f, {0xd7, 0xd2} },
-       {0x0630, {0x15, 0x15} },
-       {0x0631, {0xa3, 0xa9} },
-       {0x0632, {0x1f, 0x1f} },
-       {0x0633, {0xf9, 0xd1} },
-       {0x0634, {0xc0, 0xc3} },
-       {0x0635, {0x4d, 0x8d} },
-       {0x0636, {0x21, 0x31} },
-       {0x0637, {0x83, 0x83} },
-       {0x0638, {0x08, 0x8c} },
-       {0x0639, {0x19, 0x19} },
-       {0x063a, {0x45, 0xa5} },
-       {0x063b, {0xef, 0xec} },
-       {0x063c, {0x8a, 0x8a} },
-       {0x063d, {0xf4, 0xf6} },
-       {0x063e, {0x8f, 0x8f} },
-       {0x063f, {0x44, 0x0c} },
-       {0x0640, {0xef, 0xf0} },
-       {0x0641, {0x66, 0x66} },
-       {0x0642, {0xcc, 0xd2} },
-       {0x0643, {0x41, 0x41} },
-       {0x0644, {0x63, 0x93} },
-       {0x0645, {0x8e, 0x8e} },
-       {0x0646, {0xa2, 0x42} },
-       {0x0647, {0x7b, 0x7b} },
-       {0x0648, {0x04, 0x04} },
-       {0x0649, {0x00, 0x00} },
-       {0x064a, {0x40, 0x40} },
-       {0x064b, {0x8c, 0x98} },
-       {0x064c, {0x00, 0x00} },
-       {0x064d, {0x63, 0xc3} },
-       {0x064e, {0x04, 0x04} },
-       {0x064f, {0x20, 0x20} },
-       {0x0650, {0x00, 0x00} },
-       {0x0651, {0x40, 0x40} },
-       {0x0652, {0x01, 0x01} },
-};
-#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
-                          / sizeof(struct au8522_register_config))
-
-static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
-{
-       return container_of(sd, struct au8522_state, sd);
-}
-
-static void setup_vbi(struct au8522_state *state, int aud_input)
-{
-       int i;
-
-       /* These are set to zero regardless of what mode we're in */
-       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
-                       0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
-                       0x00);
-       au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
-                       0x00);
-
-       /* Setup the VBI registers */
-       for (i = 0x30; i < 0x60; i++)
-               au8522_writereg(state, i, 0x40);
-
-       /* For some reason, every register is 0x40 except register 0x44
-          (confirmed via the HVR-950q USB capture) */
-       au8522_writereg(state, 0x44, 0x60);
-
-       /* Enable VBI (we always do this regardless of whether the user is
-          viewing closed caption info) */
-       au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
-                       AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
-
-}
-
-static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
-{
-       int i;
-       int filter_coef_type;
-
-       /* Provide reasonable defaults for picture tuning values */
-       au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
-       au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
-       state->brightness = 0xed - 128;
-       au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
-       state->contrast = 0x79;
-       au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
-       au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
-       state->saturation = 0x80;
-       au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
-       au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
-       state->hue = 0x00;
-
-       /* Other decoder registers */
-       au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
-
-       if (input_mode == 0x23) {
-               /* S-Video input mapping */
-               au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
-       } else {
-               /* All other modes (CVBS/ATVRF etc.) */
-               au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
-       }
-
-       au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
-                       AU8522_TVDEC_PGA_REG012H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
-                       AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
-       au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
-                       AU8522_TVDED_DBG_MODE_REG060H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
-                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
-                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
-                       AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
-       au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
-                       AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
-       au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
-                       AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
-                       AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
-                       AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
-                       AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
-                       AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
-                       AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
-                       AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
-                       AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
-                       AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
-       if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
-           input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
-               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
-                               AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
-               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
-                               AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
-       } else {
-               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
-                               AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
-               au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
-                               AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
-       }
-       au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
-                       AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
-                       AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
-                       AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
-       au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
-       au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
-                       AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
-       au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
-       au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
-                       AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
-                       AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
-                       AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
-                       AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
-                       AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
-       au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
-                       AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
-       au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
-                       AU8522_TOREGAAGC_REG0E5H_CVBS);
-       au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
-
-       setup_vbi(state, 0);
-
-       if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
-           input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
-               /* Despite what the table says, for the HVR-950q we still need
-                  to be in CVBS mode for the S-Video input (reason unknown). */
-               /* filter_coef_type = 3; */
-               filter_coef_type = 5;
-       } else {
-               filter_coef_type = 5;
-       }
-
-       /* Load the Video Decoder Filter Coefficients */
-       for (i = 0; i < NUM_FILTER_COEF; i++) {
-               au8522_writereg(state, filter_coef[i].reg_name,
-                               filter_coef[i].reg_val[filter_coef_type]);
-       }
-
-       /* It's not clear what these registers are for, but they are always
-          set to the same value regardless of what mode we're in */
-       au8522_writereg(state, AU8522_REG42EH, 0x87);
-       au8522_writereg(state, AU8522_REG42FH, 0xa2);
-       au8522_writereg(state, AU8522_REG430H, 0xbf);
-       au8522_writereg(state, AU8522_REG431H, 0xcb);
-       au8522_writereg(state, AU8522_REG432H, 0xa1);
-       au8522_writereg(state, AU8522_REG433H, 0x41);
-       au8522_writereg(state, AU8522_REG434H, 0x88);
-       au8522_writereg(state, AU8522_REG435H, 0xc2);
-       au8522_writereg(state, AU8522_REG436H, 0x3c);
-}
-
-static void au8522_setup_cvbs_mode(struct au8522_state *state)
-{
-       /* here we're going to try the pre-programmed route */
-       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
-                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
-
-       /* PGA in automatic mode */
-       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
-
-       /* Enable clamping control */
-       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
-
-       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
-                       AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
-
-       setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
-
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
-}
-
-static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
-{
-       /* here we're going to try the pre-programmed route */
-       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
-                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
-
-       /* It's not clear why we have to have the PGA in automatic mode while
-          enabling clamp control, but it's what Windows does */
-       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
-
-       /* Enable clamping control */
-       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
-
-       /* Disable automatic PGA (since the CVBS is coming from the tuner) */
-       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
-
-       /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
-       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
-                       AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
-
-       setup_decoder_defaults(state,
-                              AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
-
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
-}
-
-static void au8522_setup_svideo_mode(struct au8522_state *state)
-{
-       au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
-                       AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
-
-       /* Set input to Y on Channe1, C on Channel 3 */
-       au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
-                       AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
-
-       /* PGA in automatic mode */
-       au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
-
-       /* Enable clamping control */
-       au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
-
-       setup_decoder_defaults(state,
-                              AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
-
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void disable_audio_input(struct au8522_state *state)
-{
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
-
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
-       au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
-
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                       AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
-}
-
-/* 0=disable, 1=SIF */
-static void set_audio_input(struct au8522_state *state, int aud_input)
-{
-       int i;
-
-       /* Note that this function needs to be used in conjunction with setting
-          the input routing via register 0x81 */
-
-       if (aud_input == AU8522_AUDIO_NONE) {
-               disable_audio_input(state);
-               return;
-       }
-
-       if (aud_input != AU8522_AUDIO_SIF) {
-               /* The caller asked for a mode we don't currently support */
-               printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
-                      aud_input);
-               return;
-       }
-
-       /* Load the Audio Decoder Filter Coefficients */
-       for (i = 0; i < NUM_LPFILTER_COEF; i++) {
-               au8522_writereg(state, lpfilter_coef[i].reg_name,
-                               lpfilter_coef[i].reg_val[0]);
-       }
-
-       /* Setup audio */
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
-       au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
-       au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
-       msleep(150);
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
-       msleep(1);
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
-       msleep(50);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
-       msleep(80);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
-       au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
-       au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
-       au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
-       msleep(70);
-       au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
-       au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
-       au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct au8522_state *state = to_state(sd);
-
-       switch (ctrl->id) {
-       case V4L2_CID_BRIGHTNESS:
-               state->brightness = ctrl->value;
-               au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
-                               ctrl->value - 128);
-               break;
-       case V4L2_CID_CONTRAST:
-               state->contrast = ctrl->value;
-               au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
-                               ctrl->value);
-               break;
-       case V4L2_CID_SATURATION:
-               state->saturation = ctrl->value;
-               au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
-                               ctrl->value);
-               au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
-                               ctrl->value);
-               break;
-       case V4L2_CID_HUE:
-               state->hue = ctrl->value;
-               au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
-                               ctrl->value >> 8);
-               au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
-                               ctrl->value & 0xFF);
-               break;
-       case V4L2_CID_AUDIO_VOLUME:
-       case V4L2_CID_AUDIO_BASS:
-       case V4L2_CID_AUDIO_TREBLE:
-       case V4L2_CID_AUDIO_BALANCE:
-       case V4L2_CID_AUDIO_MUTE:
-               /* Not yet implemented */
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct au8522_state *state = to_state(sd);
-
-       /* Note that we are using values cached in the state structure instead
-          of reading the registers due to issues with i2c reads not working
-          properly/consistently yet on the HVR-950q */
-
-       switch (ctrl->id) {
-       case V4L2_CID_BRIGHTNESS:
-               ctrl->value = state->brightness;
-               break;
-       case V4L2_CID_CONTRAST:
-               ctrl->value = state->contrast;
-               break;
-       case V4L2_CID_SATURATION:
-               ctrl->value = state->saturation;
-               break;
-       case V4L2_CID_HUE:
-               ctrl->value = state->hue;
-               break;
-       case V4L2_CID_AUDIO_VOLUME:
-       case V4L2_CID_AUDIO_BASS:
-       case V4L2_CID_AUDIO_TREBLE:
-       case V4L2_CID_AUDIO_BALANCE:
-       case V4L2_CID_AUDIO_MUTE:
-               /* Not yet supported */
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int au8522_g_register(struct v4l2_subdev *sd,
-                            struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct au8522_state *state = to_state(sd);
-
-       if (!v4l2_chip_match_i2c_client(client, &reg->match))
-               return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       reg->val = au8522_readreg(state, reg->reg & 0xffff);
-       return 0;
-}
-
-static int au8522_s_register(struct v4l2_subdev *sd,
-                            struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct au8522_state *state = to_state(sd);
-
-       if (!v4l2_chip_match_i2c_client(client, &reg->match))
-               return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       au8522_writereg(state, reg->reg, reg->val & 0xff);
-       return 0;
-}
-#endif
-
-static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct au8522_state *state = to_state(sd);
-
-       if (enable) {
-               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                               0x01);
-               msleep(1);
-               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                               AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
-       } else {
-               /* This does not completely power down the device
-                  (it only reduces it from around 140ma to 80ma) */
-               au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
-                               1 << 5);
-       }
-       return 0;
-}
-
-static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-       switch (qc->id) {
-       case V4L2_CID_CONTRAST:
-               return v4l2_ctrl_query_fill(qc, 0, 255, 1,
-                                           AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
-       case V4L2_CID_BRIGHTNESS:
-               return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
-       case V4L2_CID_SATURATION:
-               return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
-       case V4L2_CID_HUE:
-               return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
-       default:
-               break;
-       }
-
-       qc->type = 0;
-       return -EINVAL;
-}
-
-static int au8522_reset(struct v4l2_subdev *sd, u32 val)
-{
-       struct au8522_state *state = to_state(sd);
-
-       state->operational_mode = AU8522_ANALOG_MODE;
-
-       /* Clear out any state associated with the digital side of the
-          chip, so that when it gets powered back up it won't think
-          that it is already tuned */
-       state->current_frequency = 0;
-
-       au8522_writereg(state, 0xa4, 1 << 5);
-
-       return 0;
-}
-
-static int au8522_s_video_routing(struct v4l2_subdev *sd,
-                                       u32 input, u32 output, u32 config)
-{
-       struct au8522_state *state = to_state(sd);
-
-       au8522_reset(sd, 0);
-
-       if (input == AU8522_COMPOSITE_CH1) {
-               au8522_setup_cvbs_mode(state);
-       } else if (input == AU8522_SVIDEO_CH13) {
-               au8522_setup_svideo_mode(state);
-       } else if (input == AU8522_COMPOSITE_CH4_SIF) {
-               au8522_setup_cvbs_tuner_mode(state);
-       } else {
-               printk(KERN_ERR "au8522 mode not currently supported\n");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int au8522_s_audio_routing(struct v4l2_subdev *sd,
-                                       u32 input, u32 output, u32 config)
-{
-       struct au8522_state *state = to_state(sd);
-       set_audio_input(state, input);
-       return 0;
-}
-
-static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
-       int val = 0;
-       struct au8522_state *state = to_state(sd);
-       u8 lock_status;
-
-       /* Interrogate the decoder to see if we are getting a real signal */
-       lock_status = au8522_readreg(state, 0x00);
-       if (lock_status == 0xa2)
-               vt->signal = 0xffff;
-       else
-               vt->signal = 0x00;
-
-       vt->capability |=
-               V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
-               V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
-       val = V4L2_TUNER_SUB_MONO;
-       vt->rxsubchans = val;
-       vt->audmode = V4L2_TUNER_MODE_STEREO;
-       return 0;
-}
-
-static int au8522_g_chip_ident(struct v4l2_subdev *sd,
-                              struct v4l2_dbg_chip_ident *chip)
-{
-       struct au8522_state *state = to_state(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
-static int au8522_log_status(struct v4l2_subdev *sd)
-{
-       /* FIXME: Add some status info here */
-       return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops au8522_core_ops = {
-       .log_status = au8522_log_status,
-       .g_chip_ident = au8522_g_chip_ident,
-       .g_ctrl = au8522_g_ctrl,
-       .s_ctrl = au8522_s_ctrl,
-       .queryctrl = au8522_queryctrl,
-       .reset = au8522_reset,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register = au8522_g_register,
-       .s_register = au8522_s_register,
-#endif
-};
-
-static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
-       .g_tuner = au8522_g_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
-       .s_routing = au8522_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops au8522_video_ops = {
-       .s_routing = au8522_s_video_routing,
-       .s_stream = au8522_s_stream,
-};
-
-static const struct v4l2_subdev_ops au8522_ops = {
-       .core = &au8522_core_ops,
-       .tuner = &au8522_tuner_ops,
-       .audio = &au8522_audio_ops,
-       .video = &au8522_video_ops,
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int au8522_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct au8522_state *state;
-       struct v4l2_subdev *sd;
-       int instance;
-       struct au8522_config *demod_config;
-
-       /* Check if the adapter supports the needed features */
-       if (!i2c_check_functionality(client->adapter,
-                                    I2C_FUNC_SMBUS_BYTE_DATA)) {
-               return -EIO;
-       }
-
-       /* allocate memory for the internal state */
-       instance = au8522_get_state(&state, client->adapter, client->addr);
-       switch (instance) {
-       case 0:
-               printk(KERN_ERR "au8522_decoder allocation failed\n");
-               return -EIO;
-       case 1:
-               /* new demod instance */
-               printk(KERN_INFO "au8522_decoder creating new instance...\n");
-               break;
-       default:
-               /* existing demod instance */
-               printk(KERN_INFO "au8522_decoder attach existing instance.\n");
-               break;
-       }
-
-       demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
-       if (demod_config == NULL) {
-               if (instance == 1)
-                       kfree(state);
-               return -ENOMEM;
-       }
-       demod_config->demod_address = 0x8e >> 1;
-
-       state->config = demod_config;
-       state->i2c = client->adapter;
-
-       sd = &state->sd;
-       v4l2_i2c_subdev_init(sd, client, &au8522_ops);
-
-       state->c = client;
-       state->vid_input = AU8522_COMPOSITE_CH1;
-       state->aud_input = AU8522_AUDIO_NONE;
-       state->id = 8522;
-       state->rev = 0;
-
-       /* Jam open the i2c gate to the tuner */
-       au8522_writereg(state, 0x106, 1);
-
-       return 0;
-}
-
-static int au8522_remove(struct i2c_client *client)
-{
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
-       v4l2_device_unregister_subdev(sd);
-       au8522_release_state(to_state(sd));
-       return 0;
-}
-
-static const struct i2c_device_id au8522_id[] = {
-       {"au8522", 0},
-       {}
-};
-
-MODULE_DEVICE_TABLE(i2c, au8522_id);
-
-static struct i2c_driver au8522_driver = {
-       .driver = {
-               .owner  = THIS_MODULE,
-               .name   = "au8522",
-       },
-       .probe          = au8522_probe,
-       .remove         = au8522_remove,
-       .id_table       = au8522_id,
-};
-
-module_i2c_driver(au8522_driver);
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
deleted file mode 100644 (file)
index a68974f..0000000
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
-    Auvitek AU8522 QAM/8VSB demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "au8522.h"
-#include "au8522_priv.h"
-
-static int debug;
-
-#define dprintk(arg...)\
-       do { if (debug)\
-               printk(arg);\
-       } while (0)
-
-struct mse2snr_tab {
-       u16 val;
-       u16 data;
-};
-
-/* VSB SNR lookup table */
-static struct mse2snr_tab vsb_mse2snr_tab[] = {
-       {   0, 270 },
-       {   2, 250 },
-       {   3, 240 },
-       {   5, 230 },
-       {   7, 220 },
-       {   9, 210 },
-       {  12, 200 },
-       {  13, 195 },
-       {  15, 190 },
-       {  17, 185 },
-       {  19, 180 },
-       {  21, 175 },
-       {  24, 170 },
-       {  27, 165 },
-       {  31, 160 },
-       {  32, 158 },
-       {  33, 156 },
-       {  36, 152 },
-       {  37, 150 },
-       {  39, 148 },
-       {  40, 146 },
-       {  41, 144 },
-       {  43, 142 },
-       {  44, 140 },
-       {  48, 135 },
-       {  50, 130 },
-       {  43, 142 },
-       {  53, 125 },
-       {  56, 120 },
-       { 256, 115 },
-};
-
-/* QAM64 SNR lookup table */
-static struct mse2snr_tab qam64_mse2snr_tab[] = {
-       {  15,   0 },
-       {  16, 290 },
-       {  17, 288 },
-       {  18, 286 },
-       {  19, 284 },
-       {  20, 282 },
-       {  21, 281 },
-       {  22, 279 },
-       {  23, 277 },
-       {  24, 275 },
-       {  25, 273 },
-       {  26, 271 },
-       {  27, 269 },
-       {  28, 268 },
-       {  29, 266 },
-       {  30, 264 },
-       {  31, 262 },
-       {  32, 260 },
-       {  33, 259 },
-       {  34, 258 },
-       {  35, 256 },
-       {  36, 255 },
-       {  37, 254 },
-       {  38, 252 },
-       {  39, 251 },
-       {  40, 250 },
-       {  41, 249 },
-       {  42, 248 },
-       {  43, 246 },
-       {  44, 245 },
-       {  45, 244 },
-       {  46, 242 },
-       {  47, 241 },
-       {  48, 240 },
-       {  50, 239 },
-       {  51, 238 },
-       {  53, 237 },
-       {  54, 236 },
-       {  56, 235 },
-       {  57, 234 },
-       {  59, 233 },
-       {  60, 232 },
-       {  62, 231 },
-       {  63, 230 },
-       {  65, 229 },
-       {  67, 228 },
-       {  68, 227 },
-       {  70, 226 },
-       {  71, 225 },
-       {  73, 224 },
-       {  74, 223 },
-       {  76, 222 },
-       {  78, 221 },
-       {  80, 220 },
-       {  82, 219 },
-       {  85, 218 },
-       {  88, 217 },
-       {  90, 216 },
-       {  92, 215 },
-       {  93, 214 },
-       {  94, 212 },
-       {  95, 211 },
-       {  97, 210 },
-       {  99, 209 },
-       { 101, 208 },
-       { 102, 207 },
-       { 104, 206 },
-       { 107, 205 },
-       { 111, 204 },
-       { 114, 203 },
-       { 118, 202 },
-       { 122, 201 },
-       { 125, 200 },
-       { 128, 199 },
-       { 130, 198 },
-       { 132, 197 },
-       { 256, 190 },
-};
-
-/* QAM256 SNR lookup table */
-static struct mse2snr_tab qam256_mse2snr_tab[] = {
-       {  15,   0 },
-       {  16, 400 },
-       {  17, 398 },
-       {  18, 396 },
-       {  19, 394 },
-       {  20, 392 },
-       {  21, 390 },
-       {  22, 388 },
-       {  23, 386 },
-       {  24, 384 },
-       {  25, 382 },
-       {  26, 380 },
-       {  27, 379 },
-       {  28, 378 },
-       {  29, 377 },
-       {  30, 376 },
-       {  31, 375 },
-       {  32, 374 },
-       {  33, 373 },
-       {  34, 372 },
-       {  35, 371 },
-       {  36, 370 },
-       {  37, 362 },
-       {  38, 354 },
-       {  39, 346 },
-       {  40, 338 },
-       {  41, 330 },
-       {  42, 328 },
-       {  43, 326 },
-       {  44, 324 },
-       {  45, 322 },
-       {  46, 320 },
-       {  47, 319 },
-       {  48, 318 },
-       {  49, 317 },
-       {  50, 316 },
-       {  51, 315 },
-       {  52, 314 },
-       {  53, 313 },
-       {  54, 312 },
-       {  55, 311 },
-       {  56, 310 },
-       {  57, 308 },
-       {  58, 306 },
-       {  59, 304 },
-       {  60, 302 },
-       {  61, 300 },
-       {  62, 298 },
-       {  65, 295 },
-       {  68, 294 },
-       {  70, 293 },
-       {  73, 292 },
-       {  76, 291 },
-       {  78, 290 },
-       {  79, 289 },
-       {  81, 288 },
-       {  82, 287 },
-       {  83, 286 },
-       {  84, 285 },
-       {  85, 284 },
-       {  86, 283 },
-       {  88, 282 },
-       {  89, 281 },
-       { 256, 280 },
-};
-
-static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
-                                u16 *snr)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < sz; i++) {
-               if (mse < tab[i].val) {
-                       *snr = tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       dprintk("%s() snr=%d\n", __func__, *snr);
-       return ret;
-}
-
-static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       u8 r0b5, r0b6, r0b7;
-       char *ifmhz;
-
-       switch (if_freq) {
-       case AU8522_IF_3_25MHZ:
-               ifmhz = "3.25";
-               r0b5 = 0x00;
-               r0b6 = 0x3d;
-               r0b7 = 0xa0;
-               break;
-       case AU8522_IF_4MHZ:
-               ifmhz = "4.00";
-               r0b5 = 0x00;
-               r0b6 = 0x4b;
-               r0b7 = 0xd9;
-               break;
-       case AU8522_IF_6MHZ:
-               ifmhz = "6.00";
-               r0b5 = 0xfb;
-               r0b6 = 0x8e;
-               r0b7 = 0x39;
-               break;
-       default:
-               dprintk("%s() IF Frequency not supported\n", __func__);
-               return -EINVAL;
-       }
-       dprintk("%s() %s MHz\n", __func__, ifmhz);
-       au8522_writereg(state, 0x80b5, r0b5);
-       au8522_writereg(state, 0x80b6, r0b6);
-       au8522_writereg(state, 0x80b7, r0b7);
-
-       return 0;
-}
-
-/* VSB Modulation table */
-static struct {
-       u16 reg;
-       u16 data;
-} VSB_mod_tab[] = {
-       { 0x8090, 0x84 },
-       { 0x4092, 0x11 },
-       { 0x2005, 0x00 },
-       { 0x8091, 0x80 },
-       { 0x80a3, 0x0c },
-       { 0x80a4, 0xe8 },
-       { 0x8081, 0xc4 },
-       { 0x80a5, 0x40 },
-       { 0x80a7, 0x40 },
-       { 0x80a6, 0x67 },
-       { 0x8262, 0x20 },
-       { 0x821c, 0x30 },
-       { 0x80d8, 0x1a },
-       { 0x8227, 0xa0 },
-       { 0x8121, 0xff },
-       { 0x80a8, 0xf0 },
-       { 0x80a9, 0x05 },
-       { 0x80aa, 0x77 },
-       { 0x80ab, 0xf0 },
-       { 0x80ac, 0x05 },
-       { 0x80ad, 0x77 },
-       { 0x80ae, 0x41 },
-       { 0x80af, 0x66 },
-       { 0x821b, 0xcc },
-       { 0x821d, 0x80 },
-       { 0x80a4, 0xe8 },
-       { 0x8231, 0x13 },
-};
-
-/* QAM64 Modulation table */
-static struct {
-       u16 reg;
-       u16 data;
-} QAM64_mod_tab[] = {
-       { 0x00a3, 0x09 },
-       { 0x00a4, 0x00 },
-       { 0x0081, 0xc4 },
-       { 0x00a5, 0x40 },
-       { 0x00aa, 0x77 },
-       { 0x00ad, 0x77 },
-       { 0x00a6, 0x67 },
-       { 0x0262, 0x20 },
-       { 0x021c, 0x30 },
-       { 0x00b8, 0x3e },
-       { 0x00b9, 0xf0 },
-       { 0x00ba, 0x01 },
-       { 0x00bb, 0x18 },
-       { 0x00bc, 0x50 },
-       { 0x00bd, 0x00 },
-       { 0x00be, 0xea },
-       { 0x00bf, 0xef },
-       { 0x00c0, 0xfc },
-       { 0x00c1, 0xbd },
-       { 0x00c2, 0x1f },
-       { 0x00c3, 0xfc },
-       { 0x00c4, 0xdd },
-       { 0x00c5, 0xaf },
-       { 0x00c6, 0x00 },
-       { 0x00c7, 0x38 },
-       { 0x00c8, 0x30 },
-       { 0x00c9, 0x05 },
-       { 0x00ca, 0x4a },
-       { 0x00cb, 0xd0 },
-       { 0x00cc, 0x01 },
-       { 0x00cd, 0xd9 },
-       { 0x00ce, 0x6f },
-       { 0x00cf, 0xf9 },
-       { 0x00d0, 0x70 },
-       { 0x00d1, 0xdf },
-       { 0x00d2, 0xf7 },
-       { 0x00d3, 0xc2 },
-       { 0x00d4, 0xdf },
-       { 0x00d5, 0x02 },
-       { 0x00d6, 0x9a },
-       { 0x00d7, 0xd0 },
-       { 0x0250, 0x0d },
-       { 0x0251, 0xcd },
-       { 0x0252, 0xe0 },
-       { 0x0253, 0x05 },
-       { 0x0254, 0xa7 },
-       { 0x0255, 0xff },
-       { 0x0256, 0xed },
-       { 0x0257, 0x5b },
-       { 0x0258, 0xae },
-       { 0x0259, 0xe6 },
-       { 0x025a, 0x3d },
-       { 0x025b, 0x0f },
-       { 0x025c, 0x0d },
-       { 0x025d, 0xea },
-       { 0x025e, 0xf2 },
-       { 0x025f, 0x51 },
-       { 0x0260, 0xf5 },
-       { 0x0261, 0x06 },
-       { 0x021a, 0x00 },
-       { 0x0546, 0x40 },
-       { 0x0210, 0xc7 },
-       { 0x0211, 0xaa },
-       { 0x0212, 0xab },
-       { 0x0213, 0x02 },
-       { 0x0502, 0x00 },
-       { 0x0121, 0x04 },
-       { 0x0122, 0x04 },
-       { 0x052e, 0x10 },
-       { 0x00a4, 0xca },
-       { 0x00a7, 0x40 },
-       { 0x0526, 0x01 },
-};
-
-/* QAM256 Modulation table */
-static struct {
-       u16 reg;
-       u16 data;
-} QAM256_mod_tab[] = {
-       { 0x80a3, 0x09 },
-       { 0x80a4, 0x00 },
-       { 0x8081, 0xc4 },
-       { 0x80a5, 0x40 },
-       { 0x80aa, 0x77 },
-       { 0x80ad, 0x77 },
-       { 0x80a6, 0x67 },
-       { 0x8262, 0x20 },
-       { 0x821c, 0x30 },
-       { 0x80b8, 0x3e },
-       { 0x80b9, 0xf0 },
-       { 0x80ba, 0x01 },
-       { 0x80bb, 0x18 },
-       { 0x80bc, 0x50 },
-       { 0x80bd, 0x00 },
-       { 0x80be, 0xea },
-       { 0x80bf, 0xef },
-       { 0x80c0, 0xfc },
-       { 0x80c1, 0xbd },
-       { 0x80c2, 0x1f },
-       { 0x80c3, 0xfc },
-       { 0x80c4, 0xdd },
-       { 0x80c5, 0xaf },
-       { 0x80c6, 0x00 },
-       { 0x80c7, 0x38 },
-       { 0x80c8, 0x30 },
-       { 0x80c9, 0x05 },
-       { 0x80ca, 0x4a },
-       { 0x80cb, 0xd0 },
-       { 0x80cc, 0x01 },
-       { 0x80cd, 0xd9 },
-       { 0x80ce, 0x6f },
-       { 0x80cf, 0xf9 },
-       { 0x80d0, 0x70 },
-       { 0x80d1, 0xdf },
-       { 0x80d2, 0xf7 },
-       { 0x80d3, 0xc2 },
-       { 0x80d4, 0xdf },
-       { 0x80d5, 0x02 },
-       { 0x80d6, 0x9a },
-       { 0x80d7, 0xd0 },
-       { 0x8250, 0x0d },
-       { 0x8251, 0xcd },
-       { 0x8252, 0xe0 },
-       { 0x8253, 0x05 },
-       { 0x8254, 0xa7 },
-       { 0x8255, 0xff },
-       { 0x8256, 0xed },
-       { 0x8257, 0x5b },
-       { 0x8258, 0xae },
-       { 0x8259, 0xe6 },
-       { 0x825a, 0x3d },
-       { 0x825b, 0x0f },
-       { 0x825c, 0x0d },
-       { 0x825d, 0xea },
-       { 0x825e, 0xf2 },
-       { 0x825f, 0x51 },
-       { 0x8260, 0xf5 },
-       { 0x8261, 0x06 },
-       { 0x821a, 0x00 },
-       { 0x8546, 0x40 },
-       { 0x8210, 0x26 },
-       { 0x8211, 0xf6 },
-       { 0x8212, 0x84 },
-       { 0x8213, 0x02 },
-       { 0x8502, 0x01 },
-       { 0x8121, 0x04 },
-       { 0x8122, 0x04 },
-       { 0x852e, 0x10 },
-       { 0x80a4, 0xca },
-       { 0x80a7, 0x40 },
-       { 0x8526, 0x01 },
-};
-
-static int au8522_enable_modulation(struct dvb_frontend *fe,
-                                   fe_modulation_t m)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       int i;
-
-       dprintk("%s(0x%08x)\n", __func__, m);
-
-       switch (m) {
-       case VSB_8:
-               dprintk("%s() VSB_8\n", __func__);
-               for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
-                       au8522_writereg(state,
-                               VSB_mod_tab[i].reg,
-                               VSB_mod_tab[i].data);
-               au8522_set_if(fe, state->config->vsb_if);
-               break;
-       case QAM_64:
-               dprintk("%s() QAM 64\n", __func__);
-               for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++)
-                       au8522_writereg(state,
-                               QAM64_mod_tab[i].reg,
-                               QAM64_mod_tab[i].data);
-               au8522_set_if(fe, state->config->qam_if);
-               break;
-       case QAM_256:
-               dprintk("%s() QAM 256\n", __func__);
-               for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
-                       au8522_writereg(state,
-                               QAM256_mod_tab[i].reg,
-                               QAM256_mod_tab[i].data);
-               au8522_set_if(fe, state->config->qam_if);
-               break;
-       default:
-               dprintk("%s() Invalid modulation\n", __func__);
-               return -EINVAL;
-       }
-
-       state->current_modulation = m;
-
-       return 0;
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int au8522_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct au8522_state *state = fe->demodulator_priv;
-       int ret = -EINVAL;
-
-       dprintk("%s(frequency=%d)\n", __func__, c->frequency);
-
-       if ((state->current_frequency == c->frequency) &&
-           (state->current_modulation == c->modulation))
-               return 0;
-
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       if (ret < 0)
-               return ret;
-
-       /* Allow the tuner to settle */
-       msleep(100);
-
-       au8522_enable_modulation(fe, c->modulation);
-
-       state->current_frequency = c->frequency;
-
-       return 0;
-}
-
-static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       u8 reg;
-       u32 tuner_status = 0;
-
-       *status = 0;
-
-       if (state->current_modulation == VSB_8) {
-               dprintk("%s() Checking VSB_8\n", __func__);
-               reg = au8522_readreg(state, 0x4088);
-               if ((reg & 0x03) == 0x03)
-                       *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
-       } else {
-               dprintk("%s() Checking QAM\n", __func__);
-               reg = au8522_readreg(state, 0x4541);
-               if (reg & 0x80)
-                       *status |= FE_HAS_VITERBI;
-               if (reg & 0x20)
-                       *status |= FE_HAS_LOCK | FE_HAS_SYNC;
-       }
-
-       switch (state->config->status_mode) {
-       case AU8522_DEMODLOCKING:
-               dprintk("%s() DEMODLOCKING\n", __func__);
-               if (*status & FE_HAS_VITERBI)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       case AU8522_TUNERLOCKING:
-               /* Get the tuner status */
-               dprintk("%s() TUNERLOCKING\n", __func__);
-               if (fe->ops.tuner_ops.get_status) {
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 1);
-
-                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
-
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               if (tuner_status)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       }
-       state->fe_status = *status;
-
-       if (*status & FE_HAS_LOCK)
-               /* turn on LED, if it isn't on already */
-               au8522_led_ctrl(state, -1);
-       else
-               /* turn off LED */
-               au8522_led_ctrl(state, 0);
-
-       dprintk("%s() status 0x%08x\n", __func__, *status);
-
-       return 0;
-}
-
-static int au8522_led_status(struct au8522_state *state, const u16 *snr)
-{
-       struct au8522_led_config *led_config = state->config->led_cfg;
-       int led;
-       u16 strong;
-
-       /* bail out if we can't control an LED */
-       if (!led_config)
-               return 0;
-
-       if (0 == (state->fe_status & FE_HAS_LOCK))
-               return au8522_led_ctrl(state, 0);
-       else if (state->current_modulation == QAM_256)
-               strong = led_config->qam256_strong;
-       else if (state->current_modulation == QAM_64)
-               strong = led_config->qam64_strong;
-       else /* (state->current_modulation == VSB_8) */
-               strong = led_config->vsb8_strong;
-
-       if (*snr >= strong)
-               led = 2;
-       else
-               led = 1;
-
-       if ((state->led_state) &&
-           (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
-               /* snr didn't change enough to bother
-                * changing the color of the led */
-               return 0;
-
-       return au8522_led_ctrl(state, led);
-}
-
-static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       int ret = -EINVAL;
-
-       dprintk("%s()\n", __func__);
-
-       if (state->current_modulation == QAM_256)
-               ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
-                                           ARRAY_SIZE(qam256_mse2snr_tab),
-                                           au8522_readreg(state, 0x4522),
-                                           snr);
-       else if (state->current_modulation == QAM_64)
-               ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
-                                           ARRAY_SIZE(qam64_mse2snr_tab),
-                                           au8522_readreg(state, 0x4522),
-                                           snr);
-       else /* VSB_8 */
-               ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
-                                           ARRAY_SIZE(vsb_mse2snr_tab),
-                                           au8522_readreg(state, 0x4311),
-                                           snr);
-
-       if (state->config->led_cfg)
-               au8522_led_status(state, snr);
-
-       return ret;
-}
-
-static int au8522_read_signal_strength(struct dvb_frontend *fe,
-                                      u16 *signal_strength)
-{
-       /* borrowed from lgdt330x.c
-        *
-        * Calculate strength from SNR up to 35dB
-        * Even though the SNR can go higher than 35dB,
-        * there is some comfort factor in having a range of
-        * strong signals that can show at 100%
-        */
-       u16 snr;
-       u32 tmp;
-       int ret = au8522_read_snr(fe, &snr);
-
-       *signal_strength = 0;
-
-       if (0 == ret) {
-               /* The following calculation method was chosen
-                * purely for the sake of code re-use from the
-                * other demod drivers that use this method */
-
-               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
-               tmp = (snr * ((1 << 24) / 10));
-
-               /* Convert from 8.24 fixed-point to
-                * scale the range 0 - 35*2^24 into 0 - 65535*/
-               if (tmp >= 8960 * 0x10000)
-                       *signal_strength = 0xffff;
-               else
-                       *signal_strength = tmp / 8960;
-       }
-
-       return ret;
-}
-
-static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-
-       if (state->current_modulation == VSB_8)
-               *ucblocks = au8522_readreg(state, 0x4087);
-       else
-               *ucblocks = au8522_readreg(state, 0x4543);
-
-       return 0;
-}
-
-static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       return au8522_read_ucblocks(fe, ber);
-}
-
-static int au8522_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct au8522_state *state = fe->demodulator_priv;
-
-       c->frequency = state->current_frequency;
-       c->modulation = state->current_modulation;
-
-       return 0;
-}
-
-static int au8522_get_tune_settings(struct dvb_frontend *fe,
-                                   struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static struct dvb_frontend_ops au8522_ops;
-
-
-static void au8522_release(struct dvb_frontend *fe)
-{
-       struct au8522_state *state = fe->demodulator_priv;
-       au8522_release_state(state);
-}
-
-struct dvb_frontend *au8522_attach(const struct au8522_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       struct au8522_state *state = NULL;
-       int instance;
-
-       /* allocate memory for the internal state */
-       instance = au8522_get_state(&state, i2c, config->demod_address);
-       switch (instance) {
-       case 0:
-               dprintk("%s state allocation failed\n", __func__);
-               break;
-       case 1:
-               /* new demod instance */
-               dprintk("%s using new instance\n", __func__);
-               break;
-       default:
-               /* existing demod instance */
-               dprintk("%s using existing instance\n", __func__);
-               break;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->operational_mode = AU8522_DIGITAL_MODE;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &au8522_ops,
-              sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       state->frontend.ops.analog_ops.i2c_gate_ctrl = au8522_analog_i2c_gate_ctrl;
-
-       if (au8522_init(&state->frontend) != 0) {
-               printk(KERN_ERR "%s: Failed to initialize correctly\n",
-                       __func__);
-               goto error;
-       }
-
-       /* Note: Leaving the I2C gate open here. */
-       au8522_i2c_gate_ctrl(&state->frontend, 1);
-
-       return &state->frontend;
-
-error:
-       au8522_release_state(state);
-       return NULL;
-}
-EXPORT_SYMBOL(au8522_attach);
-
-static struct dvb_frontend_ops au8522_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name                   = "Auvitek AU8522 QAM/8VSB Frontend",
-               .frequency_min          = 54000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-
-       .init                 = au8522_init,
-       .sleep                = au8522_sleep,
-       .i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
-       .set_frontend         = au8522_set_frontend,
-       .get_frontend         = au8522_get_frontend,
-       .get_tune_settings    = au8522_get_tune_settings,
-       .read_status          = au8522_read_status,
-       .read_ber             = au8522_read_ber,
-       .read_signal_strength = au8522_read_signal_strength,
-       .read_snr             = au8522_read_snr,
-       .read_ucblocks        = au8522_read_ucblocks,
-       .release              = au8522_release,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
deleted file mode 100644 (file)
index 0529699..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
-    Auvitek AU8522 QAM/8VSB demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-    Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
-    Copyright (C) 2005-2008 Auvitek International, Ltd.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "au8522.h"
-#include "tuner-i2c.h"
-
-#define AU8522_ANALOG_MODE 0
-#define AU8522_DIGITAL_MODE 1
-
-struct au8522_state {
-       struct i2c_client *c;
-       struct i2c_adapter *i2c;
-
-       u8 operational_mode;
-
-       /* Used for sharing of the state between analog and digital mode */
-       struct tuner_i2c_props i2c_props;
-       struct list_head hybrid_tuner_instance_list;
-
-       /* configuration settings */
-       const struct au8522_config *config;
-
-       struct dvb_frontend frontend;
-
-       u32 current_frequency;
-       fe_modulation_t current_modulation;
-
-       u32 fe_status;
-       unsigned int led_state;
-
-       /* Analog settings */
-       struct v4l2_subdev sd;
-       v4l2_std_id std;
-       int vid_input;
-       int aud_input;
-       u32 id;
-       u32 rev;
-       u8 brightness;
-       u8 contrast;
-       u8 saturation;
-       s16 hue;
-};
-
-/* These are routines shared by both the VSB/QAM demodulator and the analog
-   decoder */
-int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
-u8 au8522_readreg(struct au8522_state *state, u16 reg);
-int au8522_init(struct dvb_frontend *fe);
-int au8522_sleep(struct dvb_frontend *fe);
-
-int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
-                    u8 client_address);
-void au8522_release_state(struct au8522_state *state);
-int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
-int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
-int au8522_led_ctrl(struct au8522_state *state, int led);
-
-/* REGISTERS */
-#define AU8522_INPUT_CONTROL_REG081H                   0x081
-#define AU8522_PGA_CONTROL_REG082H                     0x082
-#define AU8522_CLAMPING_CONTROL_REG083H                        0x083
-
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H            0x0A3
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H         0x0A4
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H         0x0A5
-#define AU8522_AGC_CONTROL_RANGE_REG0A6H               0x0A6
-#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H             0x0A7
-#define AU8522_TUNER_AGC_RF_STOP_REG0A8H               0x0A8
-#define AU8522_TUNER_AGC_RF_START_REG0A9H              0x0A9
-#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH            0x0AA
-#define AU8522_TUNER_AGC_IF_STOP_REG0ABH               0x0AB
-#define AU8522_TUNER_AGC_IF_START_REG0ACH              0x0AC
-#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH            0x0AD
-#define AU8522_TUNER_AGC_STEP_REG0AEH                  0x0AE
-#define AU8522_TUNER_GAIN_STEP_REG0AFH                 0x0AF
-
-/* Receiver registers */
-#define AU8522_FRMREGTHRD1_REG0B0H                     0x0B0
-#define AU8522_FRMREGAGC1H_REG0B1H                     0x0B1
-#define AU8522_FRMREGSHIFT1_REG0B2H                    0x0B2
-#define AU8522_TOREGAGC1_REG0B3H                       0x0B3
-#define AU8522_TOREGASHIFT1_REG0B4H                    0x0B4
-#define AU8522_FRMREGBBH_REG0B5H                       0x0B5
-#define AU8522_FRMREGBBM_REG0B6H                       0x0B6
-#define AU8522_FRMREGBBL_REG0B7H                       0x0B7
-/* 0xB8 TO 0xD7 are the filter coefficients */
-#define AU8522_FRMREGTHRD2_REG0D8H                     0x0D8
-#define AU8522_FRMREGAGC2H_REG0D9H                     0x0D9
-#define AU8522_TOREGAGC2_REG0DAH                       0x0DA
-#define AU8522_TOREGSHIFT2_REG0DBH                     0x0DB
-#define AU8522_FRMREGPILOTH_REG0DCH                    0x0DC
-#define AU8522_FRMREGPILOTM_REG0DDH                    0x0DD
-#define AU8522_FRMREGPILOTL_REG0DEH                    0x0DE
-#define AU8522_TOREGFREQ_REG0DFH                       0x0DF
-
-#define AU8522_RX_PGA_RFOUT_REG0EBH                    0x0EB
-#define AU8522_RX_PGA_IFOUT_REG0ECH                    0x0EC
-#define AU8522_RX_PGA_PGAOUT_REG0EDH                   0x0ED
-
-#define AU8522_CHIP_MODE_REG0FEH                       0x0FE
-
-/* I2C bus control registers */
-#define AU8522_I2C_CONTROL_REG0_REG090H                0x090
-#define AU8522_I2C_CONTROL_REG1_REG091H                0x091
-#define AU8522_I2C_STATUS_REG092H                      0x092
-#define AU8522_I2C_WR_DATA0_REG093H                    0x093
-#define AU8522_I2C_WR_DATA1_REG094H                    0x094
-#define AU8522_I2C_WR_DATA2_REG095H                    0x095
-#define AU8522_I2C_WR_DATA3_REG096H                    0x096
-#define AU8522_I2C_WR_DATA4_REG097H                    0x097
-#define AU8522_I2C_WR_DATA5_REG098H                    0x098
-#define AU8522_I2C_WR_DATA6_REG099H                    0x099
-#define AU8522_I2C_WR_DATA7_REG09AH                    0x09A
-#define AU8522_I2C_RD_DATA0_REG09BH                    0x09B
-#define AU8522_I2C_RD_DATA1_REG09CH                    0x09C
-#define AU8522_I2C_RD_DATA2_REG09DH                    0x09D
-#define AU8522_I2C_RD_DATA3_REG09EH                    0x09E
-#define AU8522_I2C_RD_DATA4_REG09FH                    0x09F
-#define AU8522_I2C_RD_DATA5_REG0A0H                    0x0A0
-#define AU8522_I2C_RD_DATA6_REG0A1H                    0x0A1
-#define AU8522_I2C_RD_DATA7_REG0A2H                    0x0A2
-
-#define AU8522_ENA_USB_REG101H                         0x101
-
-#define AU8522_I2S_CTRL_0_REG110H                      0x110
-#define AU8522_I2S_CTRL_1_REG111H                      0x111
-#define AU8522_I2S_CTRL_2_REG112H                      0x112
-
-#define AU8522_FRMREGFFECONTROL_REG121H                0x121
-#define AU8522_FRMREGDFECONTROL_REG122H                0x122
-
-#define AU8522_CARRFREQOFFSET0_REG201H                         0x201
-#define AU8522_CARRFREQOFFSET1_REG202H                 0x202
-
-#define AU8522_DECIMATION_GAIN_REG21AH                 0x21A
-#define AU8522_FRMREGIFSLP_REG21BH                     0x21B
-#define AU8522_FRMREGTHRDL2_REG21CH                    0x21C
-#define AU8522_FRMREGSTEP3DB_REG21DH                   0x21D
-#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH            0x21E
-#define AU8522_FRMREGPLLMODE_REG21FH                   0x21F
-#define AU8522_FRMREGCSTHRD_REG220H                    0x220
-#define AU8522_FRMREGCRLOCKDMAX_REG221H                0x221
-#define AU8522_FRMREGCRPERIODMASK_REG222H              0x222
-#define AU8522_FRMREGCRLOCK0THH_REG223H                0x223
-#define AU8522_FRMREGCRLOCK1THH_REG224H                0x224
-#define AU8522_FRMREGCRLOCK0THL_REG225H                0x225
-#define AU8522_FRMREGCRLOCK1THL_REG226H                0x226
-#define AU_FRMREGPLLACQPHASESCL_REG227H                        0x227
-#define AU8522_FRMREGFREQFBCTRL_REG228H                0x228
-
-/* Analog TV Decoder */
-#define AU8522_TVDEC_STATUS_REG000H                    0x000
-#define AU8522_TVDEC_INT_STATUS_REG001H                        0x001
-#define AU8522_TVDEC_MACROVISION_STATUS_REG002H        0x002
-#define AU8522_TVDEC_SHARPNESSREG009H                  0x009
-#define AU8522_TVDEC_BRIGHTNESS_REG00AH                        0x00A
-#define AU8522_TVDEC_CONTRAST_REG00BH                  0x00B
-#define AU8522_TVDEC_SATURATION_CB_REG00CH             0x00C
-#define AU8522_TVDEC_SATURATION_CR_REG00DH             0x00D
-#define AU8522_TVDEC_HUE_H_REG00EH                     0x00E
-#define AU8522_TVDEC_HUE_L_REG00FH                     0x00F
-#define AU8522_TVDEC_INT_MASK_REG010H                  0x010
-#define AU8522_VIDEO_MODE_REG011H                      0x011
-#define AU8522_TVDEC_PGA_REG012H                       0x012
-#define AU8522_TVDEC_COMB_MODE_REG015H                 0x015
-#define AU8522_REG016H                                 0x016
-#define AU8522_TVDED_DBG_MODE_REG060H                  0x060
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H              0x061
-#define AU8522_TVDEC_FORMAT_CTRL2_REG062H              0x062
-#define AU8522_TVDEC_VCR_DET_LLIM_REG063H              0x063
-#define AU8522_TVDEC_VCR_DET_HLIM_REG064H              0x064
-#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H            0x065
-#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H            0x066
-#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H            0x067
-#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H            0x068
-#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H            0x069
-#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH            0x06A
-#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH            0x06B
-#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH           0x06C
-#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH           0x06D
-#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH           0x06E
-#define AU8522_TVDEC_UV_SEP_THR_REG06FH                0x06F
-#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H         0x070
-#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H         0x073
-#define AU8522_TVDEC_DCAGC_CTRL_REG077H                        0x077
-#define AU8522_TVDEC_PIC_START_ADJ_REG078H             0x078
-#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H            0x079
-#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH      0x07A
-#define AU8522_TVDEC_INTRP_CTRL_REG07BH                        0x07B
-#define AU8522_TVDEC_PLL_STATUS_REG07EH                        0x07E
-#define AU8522_TVDEC_FSC_FREQ_REG07FH                  0x07F
-
-#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H             0x0E4
-#define AU8522_TOREGAAGC_REG0E5H                       0x0E5
-
-#define AU8522_TVDEC_CHROMA_AGC_REG401H                0x401
-#define AU8522_TVDEC_CHROMA_SFT_REG402H                0x402
-#define AU8522_FILTER_COEF_R410                0x410
-#define AU8522_FILTER_COEF_R411                0x411
-#define AU8522_FILTER_COEF_R412                0x412
-#define AU8522_FILTER_COEF_R413                0x413
-#define AU8522_FILTER_COEF_R414                0x414
-#define AU8522_FILTER_COEF_R415                0x415
-#define AU8522_FILTER_COEF_R416                0x416
-#define AU8522_FILTER_COEF_R417                0x417
-#define AU8522_FILTER_COEF_R418                0x418
-#define AU8522_FILTER_COEF_R419                0x419
-#define AU8522_FILTER_COEF_R41A                0x41A
-#define AU8522_FILTER_COEF_R41B                0x41B
-#define AU8522_FILTER_COEF_R41C                0x41C
-#define AU8522_FILTER_COEF_R41D                0x41D
-#define AU8522_FILTER_COEF_R41E                0x41E
-#define AU8522_FILTER_COEF_R41F                0x41F
-#define AU8522_FILTER_COEF_R420                0x420
-#define AU8522_FILTER_COEF_R421                0x421
-#define AU8522_FILTER_COEF_R422                0x422
-#define AU8522_FILTER_COEF_R423                0x423
-#define AU8522_FILTER_COEF_R424                0x424
-#define AU8522_FILTER_COEF_R425                0x425
-#define AU8522_FILTER_COEF_R426                0x426
-#define AU8522_FILTER_COEF_R427                0x427
-#define AU8522_FILTER_COEF_R428                0x428
-#define AU8522_FILTER_COEF_R429                0x429
-#define AU8522_FILTER_COEF_R42A                0x42A
-#define AU8522_FILTER_COEF_R42B                0x42B
-#define AU8522_FILTER_COEF_R42C                0x42C
-#define AU8522_FILTER_COEF_R42D                0x42D
-
-/* VBI Control Registers */
-#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H       0x004
-#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H       0x005
-#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H          0x006
-#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H           0x007
-#define AU8522_TVDEC_VBI_CTRL_H_REG017H                        0x017
-#define AU8522_TVDEC_VBI_CTRL_L_REG018H                        0x018
-#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H       0x019
-#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH          0x01A
-#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH          0x01B
-#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH          0x01C
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH       0x01E
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH       0x01F
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H       0x020
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H      0x021
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H      0x022
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H      0x023
-
-#define AU8522_REG071H                                 0x071
-#define AU8522_REG072H                                 0x072
-#define AU8522_REG074H                                 0x074
-#define AU8522_REG075H                                 0x075
-
-/* Digital Demodulator Registers */
-#define AU8522_FRAME_COUNT0_REG084H                    0x084
-#define AU8522_RS_STATUS_G0_REG085H                    0x085
-#define AU8522_RS_STATUS_B0_REG086H                    0x086
-#define AU8522_RS_STATUS_E_REG087H                     0x087
-#define AU8522_DEMODULATION_STATUS_REG088H             0x088
-#define AU8522_TOREGTRESTATUS_REG0E6H                  0x0E6
-#define AU8522_TSPORT_CONTROL_REG10BH                  0x10B
-#define AU8522_TSTHES_REG10CH                          0x10C
-#define AU8522_FRMREGDFEKEEP_REG301H                   0x301
-#define AU8522_DFE_AVERAGE_REG302H                     0x302
-#define AU8522_FRMREGEQLERRWIN_REG303H                 0x303
-#define AU8522_FRMREGFFEKEEP_REG304H                   0x304
-#define AU8522_FRMREGDFECONTROL1_REG305H               0x305
-#define AU8522_FRMREGEQLERRLOW_REG306H                 0x306
-
-#define AU8522_REG42EH                         0x42E
-#define AU8522_REG42FH                         0x42F
-#define AU8522_REG430H                         0x430
-#define AU8522_REG431H                         0x431
-#define AU8522_REG432H                         0x432
-#define AU8522_REG433H                         0x433
-#define AU8522_REG434H                         0x434
-#define AU8522_REG435H                         0x435
-#define AU8522_REG436H                         0x436
-
-/* GPIO Registers */
-#define AU8522_GPIO_CONTROL_REG0E0H                    0x0E0
-#define AU8522_GPIO_STATUS_REG0E1H                     0x0E1
-#define AU8522_GPIO_DATA_REG0E2H                       0x0E2
-
-/* Audio Control Registers */
-#define AU8522_AUDIOAGC_REG0EEH                        0x0EE
-#define AU8522_AUDIO_STATUS_REG0F0H                    0x0F0
-#define AU8522_AUDIO_MODE_REG0F1H                      0x0F1
-#define AU8522_AUDIO_VOLUME_L_REG0F2H                  0x0F2
-#define AU8522_AUDIO_VOLUME_R_REG0F3H                  0x0F3
-#define AU8522_AUDIO_VOLUME_REG0F4H                    0x0F4
-#define AU8522_FRMREGAUPHASE_REG0F7H                   0x0F7
-#define AU8522_REG0F9H                                 0x0F9
-
-#define AU8522_AUDIOAGC2_REG605H                       0x605
-#define AU8522_AUDIOFREQ_REG606H                       0x606
-
-
-/**************************************************************/
-
-/* Format control 1 */
-
-/* VCR Mode 7-6 */
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_YES         0x80
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_NO          0x40
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_AUTO                0x00
-/* Field len 5-4 */
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_625                0x20
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525                0x10
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_AUTO       0x00
-/* Line len (us) 3-2 */
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_64_000      0x0b
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492      0x08
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_556      0x04
-/* Subcarrier freq 1-0 */
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO 0x03
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_443  0x02
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN   0x01
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_50   0x00
-
-/* Format control 2 */
-#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT       0x00
-#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC             0x01
-
-
-#define AU8522_INPUT_CONTROL_REG081H_ATSC                      0xC4
-#define AU8522_INPUT_CONTROL_REG081H_ATVRF                     0xC4
-#define AU8522_INPUT_CONTROL_REG081H_ATVRF13                   0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B64                    0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B256                   0xC4
-#define AU8522_INPUT_CONTROL_REG081H_CVBS                      0x20
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1                  0xA2
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2                  0xA0
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3                  0x69
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4                  0x68
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF              0x28
-/* CH1 AS Y,CH3 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13               0x23
-/* CH2 AS Y,CH4 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24               0x20
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC               0x0C
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64             0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256                    0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS               0x12
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF              0x1A
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13            0x1A
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO             0x02
-
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR           0x00
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO          0x9C
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS            0x9D
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC            0xE8
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256                 0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64                  0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF                   0xDD
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13         0xDD
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL             0xDD
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM              0xDD
-
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC            0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256                 0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64                  0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC     0x40
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256  0x40
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64   0x40
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR    0x00
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF           0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13         0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO                  0x04
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS            0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM                     0x03
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS             0x09
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL             0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM              0x01
-
-/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
-#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS                     0x79
-#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS                        0x80
-#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS                        0x80
-#define AU8522_TVDEC_HUE_H_REG00EH_CVBS                                0x00
-#define AU8522_TVDEC_HUE_L_REG00FH_CVBS                                0x00
-#define AU8522_TVDEC_PGA_REG012H_CVBS                          0x0F
-#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS                    0x00
-#define AU8522_REG016H_CVBS                                    0x00
-#define AU8522_TVDED_DBG_MODE_REG060H_CVBS                     0x00
-#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS                 0x19
-#define AU8522_REG0F9H_AUDIO                                   0x20
-#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS                 0xA7
-#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS               0x0A
-#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS               0x32
-#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS               0x19
-#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS               0x23
-#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS               0x41
-#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS               0x0A
-#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS               0x32
-#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS              0x34
-#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO            0x2a
-#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS              0x05
-#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO            0x15
-#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS              0x6E
-#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS                   0x0F
-#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS            0x80
-#define AU8522_REG071H_CVBS                                    0x18
-#define AU8522_REG072H_CVBS                                    0x30
-#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS            0xF0
-#define AU8522_REG074H_CVBS                                    0x80
-#define AU8522_REG075H_CVBS                                    0xF0
-#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS                   0xFB
-#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS                        0x04
-#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS               0x00
-#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS         0x00
-#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS                   0xEE
-#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS                        0xFE
-#define AU8522_TOREGAAGC_REG0E5H_CVBS                          0x00
-#define AU8522_TVDEC_VBI6A_REG035H_CVBS                                0x40
-
-/* Enables Closed captioning */
-#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON                   0x21
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
deleted file mode 100644 (file)
index 033cd7a..0000000
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
- *
- *  Copyright (C) 2001-5, B2C2 inc.
- *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
- *
- *  This driver is "hard-coded" to be used with the 1st generation of
- *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
- *  (Panasonic CT10S) is located here, which is actually wrong. Unless there is
- *  another device with a BCM3510, this is no problem.
- *
- *  The driver works also with QAM64 DVB-C, but had an unreasonable high
- *  UNC. (Tested with the Air2PC ATSC 1st generation)
- *
- *  You'll need a firmware for this driver in order to get it running. It is
- *  called "dvb-fe-bcm3510-01.fw".
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
- * Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/jiffies.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include "dvb_frontend.h"
-#include "bcm3510.h"
-#include "bcm3510_priv.h"
-
-struct bcm3510_state {
-
-       struct i2c_adapter* i2c;
-       const struct bcm3510_config* config;
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       struct mutex hab_mutex;
-       u8 firmware_loaded:1;
-
-       unsigned long next_status_check;
-       unsigned long status_check_interval;
-       struct bcm3510_hab_cmd_status1 status1;
-       struct bcm3510_hab_cmd_status2 status2;
-};
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
-
-#define dprintk(level,x...) if (level & debug) printk(x)
-#define dbufout(b,l,m) {\
-           int i; \
-           for (i = 0; i < l; i++) \
-               m("%02x ",b[i]); \
-}
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_i2c(args...)  dprintk(0x02,args)
-#define deb_hab(args...)  dprintk(0x04,args)
-
-/* transfer functions */
-static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
-{
-       u8 b[256];
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
-
-       b[0] = reg;
-       memcpy(&b[1],buf,len);
-
-       deb_i2c("i2c wr %02x: ",reg);
-       dbufout(buf,len,deb_i2c);
-       deb_i2c("\n");
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-
-               deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
-                       __func__, state->config->demod_address, reg,  err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
-{
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0,        .buf = &reg, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf,  .len = len }
-       };
-       int err;
-
-       memset(buf,0,len);
-
-       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
-               deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
-                       __func__, state->config->demod_address, reg,  err);
-               return -EREMOTEIO;
-       }
-       deb_i2c("i2c rd %02x: ",reg);
-       dbufout(buf,len,deb_i2c);
-       deb_i2c("\n");
-
-       return 0;
-}
-
-static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
-{
-       return bcm3510_writebytes(state,reg,&v.raw,1);
-}
-
-static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
-{
-       return bcm3510_readbytes(state,reg,&v->raw,1);
-}
-
-/* Host Access Buffer transfers */
-static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
-{
-       bcm3510_register_value v;
-       int ret,i;
-
-       v.HABADR_a6.HABADR = 0;
-       if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
-               return ret;
-
-       for (i = 0; i < len; i++) {
-               if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
-                       return ret;
-               buf[i] = v.HABDATA_a7;
-       }
-       return 0;
-}
-
-static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
-{
-       bcm3510_register_value v,hab;
-       int ret,i;
-       unsigned long t;
-
-/* Check if any previous HAB request still needs to be serviced by the
- * Acquisition Processor before sending new request */
-       if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
-               return ret;
-       if (v.HABSTAT_a8.HABR) {
-               deb_info("HAB is running already - clearing it.\n");
-               v.HABSTAT_a8.HABR = 0;
-               bcm3510_writeB(st,0xa8,v);
-//             return -EBUSY;
-       }
-
-/* Send the start HAB Address (automatically incremented after write of
- * HABDATA) and write the HAB Data */
-       hab.HABADR_a6.HABADR = 0;
-       if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
-               return ret;
-
-       for (i = 0; i < len; i++) {
-               hab.HABDATA_a7 = buf[i];
-               if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
-                       return ret;
-       }
-
-/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
- * be written) */
-       v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
-       if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
-               return ret;
-
-/* Polling method: Wait until the AP finishes processing the HAB request */
-       t = jiffies + 1*HZ;
-       while (time_before(jiffies, t)) {
-               deb_info("waiting for HAB to complete\n");
-               msleep(10);
-               if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
-                       return ret;
-
-               if (!v.HABSTAT_a8.HABR)
-                       return 0;
-       }
-
-       deb_info("send_request execution timed out.\n");
-       return -ETIMEDOUT;
-}
-
-static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
-{
-       u8 ob[olen+2],ib[ilen+2];
-       int ret = 0;
-
-       ob[0] = cmd;
-       ob[1] = msgid;
-       memcpy(&ob[2],obuf,olen);
-
-       deb_hab("hab snd: ");
-       dbufout(ob,olen+2,deb_hab);
-       deb_hab("\n");
-
-       if (mutex_lock_interruptible(&st->hab_mutex) < 0)
-               return -EAGAIN;
-
-       if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
-               (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
-               goto error;
-
-       deb_hab("hab get: ");
-       dbufout(ib,ilen+2,deb_hab);
-       deb_hab("\n");
-
-       memcpy(ibuf,&ib[2],ilen);
-error:
-       mutex_unlock(&st->hab_mutex);
-       return ret;
-}
-
-#if 0
-/* not needed, we use a semaphore to prevent HAB races */
-static int bcm3510_is_ap_ready(struct bcm3510_state *st)
-{
-       bcm3510_register_value ap,hab;
-       int ret;
-
-       if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
-               (ret = bcm3510_readB(st,0xa2,&ap) < 0))
-               return ret;
-
-       if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
-               deb_info("AP is busy\n");
-               return -EBUSY;
-       }
-
-       return 0;
-}
-#endif
-
-static int bcm3510_bert_reset(struct bcm3510_state *st)
-{
-       bcm3510_register_value b;
-       int ret;
-
-       if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
-               return ret;
-
-       b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
-       b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
-       b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
-       b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
-
-       /* clear residual bit counter TODO  */
-       return 0;
-}
-
-static int bcm3510_refresh_state(struct bcm3510_state *st)
-{
-       if (time_after(jiffies,st->next_status_check)) {
-               bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
-               bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
-               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
-       }
-       return 0;
-}
-
-static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       bcm3510_refresh_state(st);
-
-       *status = 0;
-       if (st->status1.STATUS1.RECEIVER_LOCK)
-               *status |= FE_HAS_LOCK | FE_HAS_SYNC;
-
-       if (st->status1.STATUS1.FEC_LOCK)
-               *status |= FE_HAS_VITERBI;
-
-       if (st->status1.STATUS1.OUT_PLL_LOCK)
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
-
-       if (*status & FE_HAS_LOCK)
-               st->status_check_interval = 1500;
-       else /* more frequently checks if no lock has been achieved yet */
-               st->status_check_interval = 500;
-
-       deb_info("real_status: %02x\n",*status);
-       return 0;
-}
-
-static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       bcm3510_refresh_state(st);
-
-       *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
-       return 0;
-}
-
-static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       bcm3510_refresh_state(st);
-       *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
-       return 0;
-}
-
-static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       s32 t;
-
-       bcm3510_refresh_state(st);
-       t = st->status2.SIGNAL;
-
-       if (t > 190)
-               t = 190;
-       if (t < 90)
-               t = 90;
-
-       t -= 90;
-       t = t * 0xff / 100;
-       /* normalize if necessary */
-       *strength = (t << 8) | t;
-       return 0;
-}
-
-static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       bcm3510_refresh_state(st);
-
-       *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
-       return 0;
-}
-
-/* tuner frontend programming */
-static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
-{
-       struct bcm3510_hab_cmd_tune c;
-       memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
-
-/* I2C Mode disabled,  set 16 control / Data pairs */
-       c.length = 0x10;
-       c.clock_width = 0;
-/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
- * logic high (as Configuration) */
-       c.misc = 0x10;
-/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
-       c.TUNCTL_state = 0x40;
-
-/* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
-       c.ctl_dat[0].ctrl.size = BITS_8;
-       c.ctl_dat[0].data      = 0x80 | bc;
-
-/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
-       c.ctl_dat[1].ctrl.size = BITS_8;
-       c.ctl_dat[1].data      = 4;
-
-/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
-       c.ctl_dat[2].ctrl.size = BITS_3;
-       c.ctl_dat[2].data      = 0x20;
-
-/* control CS0 pin, pulse byte ? */
-       c.ctl_dat[3].ctrl.size = BITS_3;
-       c.ctl_dat[3].ctrl.clk_off = 1;
-       c.ctl_dat[3].ctrl.cs0  = 1;
-       c.ctl_dat[3].data      = 0x40;
-
-/* PGM_S18 to PGM_S11 */
-       c.ctl_dat[4].ctrl.size = BITS_8;
-       c.ctl_dat[4].data      = n >> 3;
-
-/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
-       c.ctl_dat[5].ctrl.size = BITS_8;
-       c.ctl_dat[5].data      = ((n & 0x7) << 5) | (a >> 2);
-
-/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
-       c.ctl_dat[6].ctrl.size = BITS_3;
-       c.ctl_dat[6].data      = (a << 6) & 0xdf;
-
-/* control CS0 pin, pulse byte ? */
-       c.ctl_dat[7].ctrl.size = BITS_3;
-       c.ctl_dat[7].ctrl.clk_off = 1;
-       c.ctl_dat[7].ctrl.cs0  = 1;
-       c.ctl_dat[7].data      = 0x40;
-
-/* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
-       c.ctl_dat[8].ctrl.size = BITS_8;
-       c.ctl_dat[8].data      = 0x80;
-
-/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
-       c.ctl_dat[9].ctrl.size = BITS_8;
-       c.ctl_dat[9].data      = 0x10;
-
-/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
-       c.ctl_dat[10].ctrl.size = BITS_3;
-       c.ctl_dat[10].data      = 0x20;
-
-/* pulse byte */
-       c.ctl_dat[11].ctrl.size = BITS_3;
-       c.ctl_dat[11].ctrl.clk_off = 1;
-       c.ctl_dat[11].ctrl.cs1  = 1;
-       c.ctl_dat[11].data      = 0x40;
-
-/* PGM_S18 to PGM_S11 */
-       c.ctl_dat[12].ctrl.size = BITS_8;
-       c.ctl_dat[12].data      = 0x2a;
-
-/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
-       c.ctl_dat[13].ctrl.size = BITS_8;
-       c.ctl_dat[13].data      = 0x8e;
-
-/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
-       c.ctl_dat[14].ctrl.size = BITS_3;
-       c.ctl_dat[14].data      = 0;
-
-/* Pulse Byte */
-       c.ctl_dat[15].ctrl.size = BITS_3;
-       c.ctl_dat[15].ctrl.clk_off = 1;
-       c.ctl_dat[15].ctrl.cs1  = 1;
-       c.ctl_dat[15].data      = 0x40;
-
-       return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
-}
-
-static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
-{
-       u8 bc,a;
-       u16 n;
-       s32 YIntercept,Tfvco1;
-
-       freq /= 1000;
-
-       deb_info("%dkHz:",freq);
-       /* set Band Switch */
-       if (freq <= 168000)
-               bc = 0x1c;
-       else if (freq <= 378000)
-               bc = 0x2c;
-       else
-               bc = 0x30;
-
-       if (freq >= 470000) {
-               freq -= 470001;
-               YIntercept = 18805;
-       } else if (freq >= 90000) {
-               freq -= 90001;
-               YIntercept = 15005;
-       } else if (freq >= 76000){
-               freq -= 76001;
-               YIntercept = 14865;
-       } else {
-               freq -= 54001;
-               YIntercept = 14645;
-       }
-
-       Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
-
-       n = Tfvco1 >> 6;
-       a = Tfvco1 & 0x3f;
-
-       deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
-       if (n >= 16 && n <= 2047)
-               return bcm3510_tuner_cmd(st,bc,n,a);
-
-       return -EINVAL;
-}
-
-static int bcm3510_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct bcm3510_state* st = fe->demodulator_priv;
-       struct bcm3510_hab_cmd_ext_acquire cmd;
-       struct bcm3510_hab_cmd_bert_control bert;
-       int ret;
-
-       memset(&cmd,0,sizeof(cmd));
-       switch (c->modulation) {
-               case QAM_256:
-                       cmd.ACQUIRE0.MODE = 0x1;
-                       cmd.ACQUIRE1.SYM_RATE = 0x1;
-                       cmd.ACQUIRE1.IF_FREQ = 0x1;
-                       break;
-               case QAM_64:
-                       cmd.ACQUIRE0.MODE = 0x2;
-                       cmd.ACQUIRE1.SYM_RATE = 0x2;
-                       cmd.ACQUIRE1.IF_FREQ = 0x1;
-                       break;
-#if 0
-               case QAM_256:
-                       cmd.ACQUIRE0.MODE = 0x3;
-                       break;
-               case QAM_128:
-                       cmd.ACQUIRE0.MODE = 0x4;
-                       break;
-               case QAM_64:
-                       cmd.ACQUIRE0.MODE = 0x5;
-                       break;
-               case QAM_32:
-                       cmd.ACQUIRE0.MODE = 0x6;
-                       break;
-               case QAM_16:
-                       cmd.ACQUIRE0.MODE = 0x7;
-                       break;
-#endif
-               case VSB_8:
-                       cmd.ACQUIRE0.MODE = 0x8;
-                       cmd.ACQUIRE1.SYM_RATE = 0x0;
-                       cmd.ACQUIRE1.IF_FREQ = 0x0;
-                       break;
-               case VSB_16:
-                       cmd.ACQUIRE0.MODE = 0x9;
-                       cmd.ACQUIRE1.SYM_RATE = 0x0;
-                       cmd.ACQUIRE1.IF_FREQ = 0x0;
-               default:
-                       return -EINVAL;
-       };
-       cmd.ACQUIRE0.OFFSET = 0;
-       cmd.ACQUIRE0.NTSCSWEEP = 1;
-       cmd.ACQUIRE0.FA = 1;
-       cmd.ACQUIRE0.BW = 0;
-
-/*     if (enableOffset) {
-               cmd.IF_OFFSET0 = xx;
-               cmd.IF_OFFSET1 = xx;
-
-               cmd.SYM_OFFSET0 = xx;
-               cmd.SYM_OFFSET1 = xx;
-               if (enableNtscSweep) {
-                       cmd.NTSC_OFFSET0;
-                       cmd.NTSC_OFFSET1;
-               }
-       } */
-       bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
-
-/* doing it with different MSGIDs, data book and source differs */
-       bert.BE = 0;
-       bert.unused = 0;
-       bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
-       bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
-
-       bcm3510_bert_reset(st);
-
-       ret = bcm3510_set_freq(st, c->frequency);
-       if (ret < 0)
-               return ret;
-
-       memset(&st->status1,0,sizeof(st->status1));
-       memset(&st->status2,0,sizeof(st->status2));
-       st->status_check_interval = 500;
-
-/* Give the AP some time */
-       msleep(200);
-
-       return 0;
-}
-
-static int bcm3510_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 1000;
-       s->step_size = 0;
-       s->max_drift = 0;
-       return 0;
-}
-
-static void bcm3510_release(struct dvb_frontend* fe)
-{
-       struct bcm3510_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-/* firmware download:
- * firmware file is build up like this:
- * 16bit addr, 16bit length, 8byte of length
- */
-#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
-
-static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
-                            u16 len)
-{
-       int ret = 0,i;
-       bcm3510_register_value vH, vL,vD;
-
-       vH.MADRH_a9 = addr >> 8;
-       vL.MADRL_aa = addr;
-       if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
-       if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
-
-       for (i = 0; i < len; i++) {
-               vD.MDATA_ab = b[i];
-               if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int bcm3510_download_firmware(struct dvb_frontend* fe)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       const struct firmware *fw;
-       u16 addr,len;
-       const u8 *b;
-       int ret,i;
-
-       deb_info("requesting firmware\n");
-       if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
-               err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
-               return ret;
-       }
-       deb_info("got firmware: %zd\n",fw->size);
-
-       b = fw->data;
-       for (i = 0; i < fw->size;) {
-               addr = le16_to_cpu( *( (u16 *)&b[i] ) );
-               len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );
-               deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
-               if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
-                       err("firmware download failed: %d\n",ret);
-                       return ret;
-               }
-               i += 4 + len;
-       }
-       release_firmware(fw);
-       deb_info("firmware download successfully completed\n");
-       return 0;
-}
-
-static int bcm3510_check_firmware_version(struct bcm3510_state *st)
-{
-       struct bcm3510_hab_cmd_get_version_info ver;
-       bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
-
-       deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
-               ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
-
-       if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
-               ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
-               ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
-               return 0;
-
-       deb_info("version check failed\n");
-       return -ENODEV;
-}
-
-/* (un)resetting the AP */
-static int bcm3510_reset(struct bcm3510_state *st)
-{
-       int ret;
-       unsigned long  t;
-       bcm3510_register_value v;
-
-       bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
-       if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
-               return ret;
-
-    t = jiffies + 3*HZ;
-       while (time_before(jiffies, t)) {
-               msleep(10);
-               if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
-                       return ret;
-
-               if (v.APSTAT1_a2.RESET)
-                       return 0;
-       }
-       deb_info("reset timed out\n");
-       return -ETIMEDOUT;
-}
-
-static int bcm3510_clear_reset(struct bcm3510_state *st)
-{
-       bcm3510_register_value v;
-       int ret;
-       unsigned long t;
-
-       v.raw = 0;
-       if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
-               return ret;
-
-    t = jiffies + 3*HZ;
-       while (time_before(jiffies, t)) {
-               msleep(10);
-               if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
-                       return ret;
-
-               /* verify that reset is cleared */
-               if (!v.APSTAT1_a2.RESET)
-                       return 0;
-       }
-       deb_info("reset clear timed out\n");
-       return -ETIMEDOUT;
-}
-
-static int bcm3510_init_cold(struct bcm3510_state *st)
-{
-       int ret;
-       bcm3510_register_value v;
-
-       /* read Acquisation Processor status register and check it is not in RUN mode */
-       if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
-               return ret;
-       if (v.APSTAT1_a2.RUN) {
-               deb_info("AP is already running - firmware already loaded.\n");
-               return 0;
-       }
-
-       deb_info("reset?\n");
-       if ((ret = bcm3510_reset(st)) < 0)
-               return ret;
-
-       deb_info("tristate?\n");
-       /* tri-state */
-       v.TSTCTL_2e.CTL = 0;
-       if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
-               return ret;
-
-       deb_info("firmware?\n");
-       if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
-               (ret = bcm3510_clear_reset(st)) < 0)
-               return ret;
-
-       /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
-
-       return 0;
-}
-
-static int bcm3510_init(struct dvb_frontend* fe)
-{
-       struct bcm3510_state* st = fe->demodulator_priv;
-       bcm3510_register_value j;
-       struct bcm3510_hab_cmd_set_agc c;
-       int ret;
-
-       if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
-               return ret;
-
-       deb_info("JDEC: %02x\n",j.raw);
-
-       switch (j.JDEC_ca.JDEC) {
-               case JDEC_WAIT_AT_RAM:
-                       deb_info("attempting to download firmware\n");
-                       if ((ret = bcm3510_init_cold(st)) < 0)
-                               return ret;
-               case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
-                       deb_info("firmware is loaded\n");
-                       bcm3510_check_firmware_version(st);
-                       break;
-               default:
-                       return -ENODEV;
-       }
-
-       memset(&c,0,1);
-       c.SEL = 1;
-       bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
-
-       return 0;
-}
-
-
-static struct dvb_frontend_ops bcm3510_ops;
-
-struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       struct bcm3510_state* state = NULL;
-       int ret;
-       bcm3510_register_value v;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-
-       state->config = config;
-       state->i2c = i2c;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       mutex_init(&state->hab_mutex);
-
-       if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
-               goto error;
-
-       deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
-
-       if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
-               (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
-               goto error;
-
-       info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
-
-       bcm3510_reset(state);
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(bcm3510_attach);
-
-static struct dvb_frontend_ops bcm3510_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name = "Broadcom BCM3510 VSB/QAM frontend",
-               .frequency_min =  54000000,
-               .frequency_max = 803000000,
-               /* stepsize is just a guess */
-               .frequency_stepsize = 0,
-               .caps =
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_8VSB | FE_CAN_16VSB |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
-       },
-
-       .release = bcm3510_release,
-
-       .init = bcm3510_init,
-       .sleep = bcm3510_sleep,
-
-       .set_frontend = bcm3510_set_frontend,
-       .get_tune_settings = bcm3510_get_tune_settings,
-
-       .read_status = bcm3510_read_status,
-       .read_ber = bcm3510_read_ber,
-       .read_signal_strength = bcm3510_read_signal_strength,
-       .read_snr = bcm3510_read_snr,
-       .read_ucblocks = bcm3510_read_unc,
-};
-
-MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
deleted file mode 100644 (file)
index f4575c0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
- *
- *  Copyright (C) 2001-5, B2C2 inc.
- *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef BCM3510_H
-#define BCM3510_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct bcm3510_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE))
-extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
-                                                 struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_BCM3510
-
-#endif
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h
deleted file mode 100644 (file)
index 3bb1bc2..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
- *
- *  Copyright (C) 2001-5, B2C2 inc.
- *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef __BCM3510_PRIV_H__
-#define __BCM3510_PRIV_H__
-
-#define PACKED __attribute__((packed))
-
-#undef err
-#define err(format, arg...)  printk(KERN_ERR     "bcm3510: " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) printk(KERN_INFO    "bcm3510: " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
-
-
-#define PANASONIC_FIRST_IF_BASE_IN_KHz  1407500
-#define BCM3510_SYMBOL_RATE             5381000
-
-typedef union {
-       u8 raw;
-
-       struct {
-               u8 CTL   :8;
-       } TSTCTL_2e;
-
-       u8 LDCERC_4e;
-       u8 LDUERC_4f;
-       u8 LD_BER0_65;
-       u8 LD_BER1_66;
-       u8 LD_BER2_67;
-       u8 LD_BER3_68;
-
-       struct {
-               u8 RESET :1;
-               u8 IDLE  :1;
-               u8 STOP  :1;
-               u8 HIRQ0 :1;
-               u8 HIRQ1 :1;
-               u8 na0   :1;
-               u8 HABAV :1;
-               u8 na1   :1;
-       } HCTL1_a0;
-
-       struct {
-               u8 na0    :1;
-               u8 IDLMSK :1;
-               u8 STMSK  :1;
-               u8 I0MSK  :1;
-               u8 I1MSK  :1;
-               u8 na1    :1;
-               u8 HABMSK :1;
-               u8 na2    :1;
-       } HCTLMSK_a1;
-
-       struct {
-               u8 RESET  :1;
-               u8 IDLE   :1;
-               u8 STOP   :1;
-               u8 RUN    :1;
-               u8 HABAV  :1;
-               u8 MEMAV  :1;
-               u8 ALDONE :1;
-               u8 REIRQ  :1;
-       } APSTAT1_a2;
-
-       struct {
-               u8 RSTMSK :1;
-               u8 IMSK   :1;
-               u8 SMSK   :1;
-               u8 RMSK   :1;
-               u8 HABMSK :1;
-               u8 MAVMSK :1;
-               u8 ALDMSK :1;
-               u8 REMSK  :1;
-       } APMSK1_a3;
-
-       u8 APSTAT2_a4;
-       u8 APMSK2_a5;
-
-       struct {
-               u8 HABADR :7;
-               u8 na     :1;
-       } HABADR_a6;
-
-       u8 HABDATA_a7;
-
-       struct {
-               u8 HABR   :1;
-               u8 LDHABR :1;
-               u8 APMSK  :1;
-               u8 HMSK   :1;
-               u8 LDMSK  :1;
-               u8 na     :3;
-       } HABSTAT_a8;
-
-       u8 MADRH_a9;
-       u8 MADRL_aa;
-       u8 MDATA_ab;
-
-       struct {
-#define JDEC_WAIT_AT_RAM      0x7
-#define JDEC_EEPROM_LOAD_WAIT 0x4
-               u8 JDEC   :3;
-               u8 na     :5;
-       } JDEC_ca;
-
-       struct {
-               u8 REV   :4;
-               u8 LAYER :4;
-       } REVID_e0;
-
-       struct {
-               u8 unk0   :1;
-               u8 CNTCTL :1;
-               u8 BITCNT :1;
-               u8 unk1   :1;
-               u8 RESYNC :1;
-               u8 unk2   :3;
-       } BERCTL_fa;
-
-       struct {
-               u8 CSEL0  :1;
-               u8 CLKED0 :1;
-               u8 CSEL1  :1;
-               u8 CLKED1 :1;
-               u8 CLKLEV :1;
-               u8 SPIVAR :1;
-               u8 na     :2;
-       } TUNSET_fc;
-
-       struct {
-               u8 CLK    :1;
-               u8 DATA   :1;
-               u8 CS0    :1;
-               u8 CS1    :1;
-               u8 AGCSEL :1;
-               u8 na0    :1;
-               u8 TUNSEL :1;
-               u8 na1    :1;
-       } TUNCTL_fd;
-
-       u8 TUNSEL0_fe;
-       u8 TUNSEL1_ff;
-
-} bcm3510_register_value;
-
-/* HAB commands */
-
-/* version */
-#define CMD_GET_VERSION_INFO   0x3D
-#define MSGID_GET_VERSION_INFO 0x15
-struct bcm3510_hab_cmd_get_version_info {
-       u8 microcode_version;
-       u8 script_version;
-       u8 config_version;
-       u8 demod_version;
-} PACKED;
-
-#define BCM3510_DEF_MICROCODE_VERSION 0x0E
-#define BCM3510_DEF_SCRIPT_VERSION    0x06
-#define BCM3510_DEF_CONFIG_VERSION    0x01
-#define BCM3510_DEF_DEMOD_VERSION     0xB1
-
-/* acquire */
-#define CMD_ACQUIRE            0x38
-
-#define MSGID_EXT_TUNER_ACQUIRE 0x0A
-struct bcm3510_hab_cmd_ext_acquire {
-       struct {
-               u8 MODE      :4;
-               u8 BW        :1;
-               u8 FA        :1;
-               u8 NTSCSWEEP :1;
-               u8 OFFSET    :1;
-       } PACKED ACQUIRE0; /* control_byte */
-
-       struct {
-               u8 IF_FREQ  :3;
-               u8 zero0    :1;
-               u8 SYM_RATE :3;
-               u8 zero1    :1;
-       } PACKED ACQUIRE1; /* sym_if */
-
-       u8 IF_OFFSET0;   /* IF_Offset_10hz */
-       u8 IF_OFFSET1;
-       u8 SYM_OFFSET0;  /* SymbolRateOffset */
-       u8 SYM_OFFSET1;
-       u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
-       u8 NTSC_OFFSET1;
-} PACKED;
-
-#define MSGID_INT_TUNER_ACQUIRE 0x0B
-struct bcm3510_hab_cmd_int_acquire {
-       struct {
-               u8 MODE      :4;
-               u8 BW        :1;
-               u8 FA        :1;
-               u8 NTSCSWEEP :1;
-               u8 OFFSET    :1;
-       } PACKED ACQUIRE0; /* control_byte */
-
-       struct {
-               u8 IF_FREQ  :3;
-               u8 zero0    :1;
-               u8 SYM_RATE :3;
-               u8 zero1    :1;
-       } PACKED ACQUIRE1; /* sym_if */
-
-       u8 TUNER_FREQ0;
-       u8 TUNER_FREQ1;
-       u8 TUNER_FREQ2;
-       u8 TUNER_FREQ3;
-       u8 IF_OFFSET0;   /* IF_Offset_10hz */
-       u8 IF_OFFSET1;
-       u8 SYM_OFFSET0;  /* SymbolRateOffset */
-       u8 SYM_OFFSET1;
-       u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
-       u8 NTSC_OFFSET1;
-} PACKED;
-
-/* modes */
-#define BCM3510_QAM16           =   0x01
-#define BCM3510_QAM32           =   0x02
-#define BCM3510_QAM64           =   0x03
-#define BCM3510_QAM128          =   0x04
-#define BCM3510_QAM256          =   0x05
-#define BCM3510_8VSB            =   0x0B
-#define BCM3510_16VSB           =   0x0D
-
-/* IF_FREQS */
-#define BCM3510_IF_TERRESTRIAL 0x0
-#define BCM3510_IF_CABLE       0x1
-#define BCM3510_IF_USE_CMD     0x7
-
-/* SYM_RATE */
-#define BCM3510_SR_8VSB        0x0 /* 5381119 s/sec */
-#define BCM3510_SR_256QAM      0x1 /* 5360537 s/sec */
-#define BCM3510_SR_16QAM       0x2 /* 5056971 s/sec */
-#define BCM3510_SR_MISC        0x3 /* 5000000 s/sec */
-#define BCM3510_SR_USE_CMD     0x7
-
-/* special symbol rate */
-#define CMD_SET_VALUE_NOT_LISTED  0x2d
-#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
-struct bcm3510_hab_cmd_set_sr_not_listed {
-       u8 HOST_SYM_RATE0;
-       u8 HOST_SYM_RATE1;
-       u8 HOST_SYM_RATE2;
-       u8 HOST_SYM_RATE3;
-} PACKED;
-
-/* special IF */
-#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
-struct bcm3510_hab_cmd_set_if_freq_not_listed {
-       u8 HOST_IF_FREQ0;
-       u8 HOST_IF_FREQ1;
-       u8 HOST_IF_FREQ2;
-       u8 HOST_IF_FREQ3;
-} PACKED;
-
-/* auto reacquire */
-#define CMD_AUTO_PARAM       0x2a
-#define MSGID_AUTO_REACQUIRE 0x0e
-struct bcm3510_hab_cmd_auto_reacquire {
-       u8 ACQ    :1; /* on/off*/
-       u8 unused :7;
-} PACKED;
-
-#define MSGID_SET_RF_AGC_SEL 0x12
-struct bcm3510_hab_cmd_set_agc {
-       u8 LVL    :1;
-       u8 unused :6;
-       u8 SEL    :1;
-} PACKED;
-
-#define MSGID_SET_AUTO_INVERSION 0x14
-struct bcm3510_hab_cmd_auto_inversion {
-       u8 AI     :1;
-       u8 unused :7;
-} PACKED;
-
-
-/* bert control */
-#define CMD_STATE_CONTROL  0x12
-#define MSGID_BERT_CONTROL 0x0e
-#define MSGID_BERT_SET     0xfa
-struct bcm3510_hab_cmd_bert_control {
-       u8 BE     :1;
-       u8 unused :7;
-} PACKED;
-
-#define MSGID_TRI_STATE 0x2e
-struct bcm3510_hab_cmd_tri_state {
-       u8 RE :1; /* a/d ram port pins */
-       u8 PE :1; /* baud clock pin */
-       u8 AC :1; /* a/d clock pin */
-       u8 BE :1; /* baud clock pin */
-       u8 unused :4;
-} PACKED;
-
-
-/* tune */
-#define CMD_TUNE   0x38
-#define MSGID_TUNE 0x16
-struct bcm3510_hab_cmd_tune_ctrl_data_pair {
-       struct {
-#define BITS_8 0x07
-#define BITS_7 0x06
-#define BITS_6 0x05
-#define BITS_5 0x04
-#define BITS_4 0x03
-#define BITS_3 0x02
-#define BITS_2 0x01
-#define BITS_1 0x00
-               u8 size    :3;
-               u8 unk     :2;
-               u8 clk_off :1;
-               u8 cs0     :1;
-               u8 cs1     :1;
-
-       } PACKED ctrl;
-
-       u8 data;
-} PACKED;
-
-struct bcm3510_hab_cmd_tune {
-       u8 length;
-       u8 clock_width;
-       u8 misc;
-       u8 TUNCTL_state;
-
-       struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
-} PACKED;
-
-#define CMD_STATUS    0x38
-#define MSGID_STATUS1 0x08
-struct bcm3510_hab_cmd_status1 {
-       struct {
-               u8 EQ_MODE       :4;
-               u8 reserved      :2;
-               u8 QRE           :1; /* if QSE and the spectrum is inversed */
-               u8 QSE           :1; /* automatic spectral inversion */
-       } PACKED STATUS0;
-
-       struct {
-               u8 RECEIVER_LOCK :1;
-               u8 FEC_LOCK      :1;
-               u8 OUT_PLL_LOCK  :1;
-               u8 reserved      :5;
-       } PACKED STATUS1;
-
-       struct {
-               u8 reserved      :2;
-               u8 BW            :1;
-               u8 NTE           :1; /* NTSC filter sweep enabled */
-               u8 AQI           :1; /* currently acquiring */
-               u8 FA            :1; /* fast acquisition */
-               u8 ARI           :1; /* auto reacquire */
-               u8 TI            :1; /* programming the tuner */
-       } PACKED STATUS2;
-       u8 STATUS3;
-       u8 SNR_EST0;
-       u8 SNR_EST1;
-       u8 TUNER_FREQ0;
-       u8 TUNER_FREQ1;
-       u8 TUNER_FREQ2;
-       u8 TUNER_FREQ3;
-       u8 SYM_RATE0;
-       u8 SYM_RATE1;
-       u8 SYM_RATE2;
-       u8 SYM_RATE3;
-       u8 SYM_OFFSET0;
-       u8 SYM_OFFSET1;
-       u8 SYM_ERROR0;
-       u8 SYM_ERROR1;
-       u8 IF_FREQ0;
-       u8 IF_FREQ1;
-       u8 IF_FREQ2;
-       u8 IF_FREQ3;
-       u8 IF_OFFSET0;
-       u8 IF_OFFSET1;
-       u8 IF_ERROR0;
-       u8 IF_ERROR1;
-       u8 NTSC_FILTER0;
-       u8 NTSC_FILTER1;
-       u8 NTSC_FILTER2;
-       u8 NTSC_FILTER3;
-       u8 NTSC_OFFSET0;
-       u8 NTSC_OFFSET1;
-       u8 NTSC_ERROR0;
-       u8 NTSC_ERROR1;
-       u8 INT_AGC_LEVEL0;
-       u8 INT_AGC_LEVEL1;
-       u8 EXT_AGC_LEVEL0;
-       u8 EXT_AGC_LEVEL1;
-} PACKED;
-
-#define MSGID_STATUS2 0x14
-struct bcm3510_hab_cmd_status2 {
-       struct {
-               u8 EQ_MODE  :4;
-               u8 reserved :2;
-               u8 QRE      :1;
-               u8 QSR      :1;
-       } PACKED STATUS0;
-       struct {
-               u8 RL       :1;
-               u8 FL       :1;
-               u8 OL       :1;
-               u8 reserved :5;
-       } PACKED STATUS1;
-       u8 SYMBOL_RATE0;
-       u8 SYMBOL_RATE1;
-       u8 SYMBOL_RATE2;
-       u8 SYMBOL_RATE3;
-       u8 LDCERC0;
-       u8 LDCERC1;
-       u8 LDCERC2;
-       u8 LDCERC3;
-       u8 LDUERC0;
-       u8 LDUERC1;
-       u8 LDUERC2;
-       u8 LDUERC3;
-       u8 LDBER0;
-       u8 LDBER1;
-       u8 LDBER2;
-       u8 LDBER3;
-       struct {
-               u8 MODE_TYPE :4; /* acquire mode 0 */
-               u8 reservd   :4;
-       } MODE_TYPE;
-       u8 SNR_EST0;
-       u8 SNR_EST1;
-       u8 SIGNAL;
-} PACKED;
-
-#define CMD_SET_RF_BW_NOT_LISTED   0x3f
-#define MSGID_SET_RF_BW_NOT_LISTED 0x11
-/* TODO */
-
-#endif
diff --git a/drivers/media/dvb/frontends/bsbe1-d01a.h b/drivers/media/dvb/frontends/bsbe1-d01a.h
deleted file mode 100644 (file)
index 7ed3c42..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * bsbe1-d01a.h - ALPS BSBE1-D01A tuner support
- *
- * Copyright (C) 2011 Oliver Endriss <o.endriss@gmx.de>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef BSBE1_D01A_H
-#define BSBE1_D01A_H
-
-#include "stb6000.h"
-#include "stv0288.h"
-
-static u8 stv0288_bsbe1_d01a_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x20,
-       0x09, 0x0,
-       0x0a, 0x4,
-       0x0b, 0x0,
-       0x0c, 0x0,
-       0x0d, 0x0,
-       0x0e, 0xd4,
-       0x0f, 0x30,
-       0x11, 0x80,
-       0x12, 0x03,
-       0x13, 0x48,
-       0x14, 0x84,
-       0x15, 0x45,
-       0x16, 0xb7,
-       0x17, 0x9c,
-       0x18, 0x0,
-       0x19, 0xa6,
-       0x1a, 0x88,
-       0x1b, 0x8f,
-       0x1c, 0xf0,
-       0x20, 0x0b,
-       0x21, 0x54,
-       0x22, 0x0,
-       0x23, 0x0,
-       0x2b, 0xff,
-       0x2c, 0xf7,
-       0x30, 0x0,
-       0x31, 0x1e,
-       0x32, 0x14,
-       0x33, 0x0f,
-       0x34, 0x09,
-       0x35, 0x0c,
-       0x36, 0x05,
-       0x37, 0x2f,
-       0x38, 0x16,
-       0x39, 0xbd,
-       0x3a, 0x03,
-       0x3b, 0x13,
-       0x3c, 0x11,
-       0x3d, 0x30,
-       0x40, 0x63,
-       0x41, 0x04,
-       0x42, 0x60,
-       0x43, 0x00,
-       0x44, 0x00,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x47, 0x00,
-       0x4a, 0x00,
-       0x50, 0x10,
-       0x51, 0x36,
-       0x52, 0x09,
-       0x53, 0x94,
-       0x54, 0x62,
-       0x55, 0x29,
-       0x56, 0x64,
-       0x57, 0x2b,
-       0x58, 0x54,
-       0x59, 0x86,
-       0x5a, 0x0,
-       0x5b, 0x9b,
-       0x5c, 0x08,
-       0x5d, 0x7f,
-       0x5e, 0x0,
-       0x5f, 0xff,
-       0x70, 0x0,
-       0x71, 0x0,
-       0x72, 0x0,
-       0x74, 0x0,
-       0x75, 0x0,
-       0x76, 0x0,
-       0x81, 0x0,
-       0x82, 0x3f,
-       0x83, 0x3f,
-       0x84, 0x0,
-       0x85, 0x0,
-       0x88, 0x0,
-       0x89, 0x0,
-       0x8a, 0x0,
-       0x8b, 0x0,
-       0x8c, 0x0,
-       0x90, 0x0,
-       0x91, 0x0,
-       0x92, 0x0,
-       0x93, 0x0,
-       0x94, 0x1c,
-       0x97, 0x0,
-       0xa0, 0x48,
-       0xa1, 0x0,
-       0xb0, 0xb8,
-       0xb1, 0x3a,
-       0xb2, 0x10,
-       0xb3, 0x82,
-       0xb4, 0x80,
-       0xb5, 0x82,
-       0xb6, 0x82,
-       0xb7, 0x82,
-       0xb8, 0x20,
-       0xb9, 0x0,
-       0xf0, 0x0,
-       0xf1, 0x0,
-       0xf2, 0xc0,
-       0xff, 0xff,
-};
-
-static struct stv0288_config stv0288_bsbe1_d01a_config = {
-       .demod_address = 0x68,
-       .min_delay_ms = 100,
-       .inittab = stv0288_bsbe1_d01a_inittab,
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
deleted file mode 100644 (file)
index 53e4d0d..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * bsbe1.h - ALPS BSBE1 tuner support
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef BSBE1_H
-#define BSBE1_H
-
-static u8 alps_bsbe1_inittab[] = {
-       0x01, 0x15,   /* XTAL = 4MHz, VCO = 352 MHz */
-       0x02, 0x30,   /* MCLK = 88 MHz */
-       0x03, 0x00,   /* ACR output 0 */
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x05,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x00,   /* DAC output 0 */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1/OP0 normal, val = 1 (LNB power on) */
-       0x0d, 0x82,   /* DC offset compensation = on, beta_agc1 = 2 */
-       0x0f, 0x92,   /* AGC1R */
-       0x10, 0x34,   /* AGC2O */
-       0x11, 0x84,   /* TLSR */
-       0x12, 0xb9,   /* CFD */
-       0x15, 0xc9,   /* lock detector threshold */
-       0x28, 0x00,   /* out imp: normal, type: parallel, FEC mode: QPSK */
-       0x33, 0xfc,   /* RS control */
-       0x34, 0x93,   /* count viterbi bit errors per 2E18 bytes */
-       0xff, 0xff
-};
-
-
-static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio      ) & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsbe1_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-       struct i2c_adapter *i2c = fe->tuner_priv;
-
-       if ((p->frequency < 950000) || (p->frequency > 2150000))
-               return -EINVAL;
-
-       div = p->frequency / 1000;
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1;
-       data[3] = 0xe0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer(i2c, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static struct stv0299_config alps_bsbe1_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
deleted file mode 100644 (file)
index c2a578e..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c)
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef BSRU6_H
-#define BSRU6_H
-
-static u8 alps_bsru6_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) {
-               aclk = 0xb7;
-               bclk = 0x47;
-       } else if (srate < 3000000) {
-               aclk = 0xb7;
-               bclk = 0x4b;
-       } else if (srate < 7000000) {
-               aclk = 0xb7;
-               bclk = 0x4f;
-       } else if (srate < 14000000) {
-               aclk = 0xb7;
-               bclk = 0x53;
-       } else if (srate < 30000000) {
-               aclk = 0xb6;
-               bclk = 0x53;
-       } else if (srate < 45000000) {
-               aclk = 0xb4;
-               bclk = 0x51;
-       }
-
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, 0x21, ratio & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-       struct i2c_adapter *i2c = fe->tuner_priv;
-
-       if ((p->frequency < 950000) || (p->frequency > 2150000))
-               return -EINVAL;
-
-       div = (p->frequency + (125 - 1)) / 125; /* round correctly */
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       buf[3] = 0xC4;
-
-       if (p->frequency > 1530000)
-               buf[3] = 0xc0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(i2c, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct stv0299_config alps_bsru6_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0299_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
deleted file mode 100644 (file)
index f2a90f9..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
-    Conexant cx22700 DVB OFDM demodulator driver
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-       Holger Waechtler <holger@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "dvb_frontend.h"
-#include "cx22700.h"
-
-
-struct cx22700_state {
-
-       struct i2c_adapter* i2c;
-
-       const struct cx22700_config* config;
-
-       struct dvb_frontend frontend;
-};
-
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "cx22700: " args); \
-       } while (0)
-
-static u8 init_tab [] = {
-       0x04, 0x10,
-       0x05, 0x09,
-       0x06, 0x00,
-       0x08, 0x04,
-       0x09, 0x00,
-       0x0a, 0x01,
-       0x15, 0x40,
-       0x16, 0x10,
-       0x17, 0x87,
-       0x18, 0x17,
-       0x1a, 0x10,
-       0x25, 0x04,
-       0x2e, 0x00,
-       0x39, 0x00,
-       0x3a, 0x04,
-       0x45, 0x08,
-       0x46, 0x02,
-       0x47, 0x05,
-};
-
-
-static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf [] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       dprintk ("%s\n", __func__);
-
-       ret = i2c_transfer (state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       __func__, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static int cx22700_readreg (struct cx22700_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       dprintk ("%s\n", __func__);
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-
-       if (ret != 2) return -EIO;
-
-       return b1[0];
-}
-
-static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
-{
-       u8 val;
-
-       dprintk ("%s\n", __func__);
-
-       switch (inversion) {
-       case INVERSION_AUTO:
-               return -EOPNOTSUPP;
-       case INVERSION_ON:
-               val = cx22700_readreg (state, 0x09);
-               return cx22700_writereg (state, 0x09, val | 0x01);
-       case INVERSION_OFF:
-               val = cx22700_readreg (state, 0x09);
-               return cx22700_writereg (state, 0x09, val & 0xfe);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int cx22700_set_tps(struct cx22700_state *state,
-                          struct dtv_frontend_properties *p)
-{
-       static const u8 qam_tab [4] = { 0, 1, 0, 2 };
-       static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
-       u8 val;
-
-       dprintk ("%s\n", __func__);
-
-       if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
-               return -EINVAL;
-
-       if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
-               return -EINVAL;
-
-       if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
-               return -EINVAL;
-
-       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
-           p->guard_interval > GUARD_INTERVAL_1_4)
-               return -EINVAL;
-
-       if (p->transmission_mode != TRANSMISSION_MODE_2K &&
-           p->transmission_mode != TRANSMISSION_MODE_8K)
-               return -EINVAL;
-
-       if (p->modulation != QPSK &&
-           p->modulation != QAM_16 &&
-           p->modulation != QAM_64)
-               return -EINVAL;
-
-       if (p->hierarchy < HIERARCHY_NONE ||
-           p->hierarchy > HIERARCHY_4)
-               return -EINVAL;
-
-       if (p->bandwidth_hz > 8000000 || p->bandwidth_hz < 6000000)
-               return -EINVAL;
-
-       if (p->bandwidth_hz == 7000000)
-               cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
-       else
-               cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
-
-       val = qam_tab[p->modulation - QPSK];
-       val |= p->hierarchy - HIERARCHY_NONE;
-
-       cx22700_writereg (state, 0x04, val);
-
-       val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
-       val |= fec_tab[p->code_rate_LP - FEC_1_2];
-
-       cx22700_writereg (state, 0x05, val);
-
-       val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
-       val |= p->transmission_mode - TRANSMISSION_MODE_2K;
-
-       cx22700_writereg (state, 0x06, val);
-
-       cx22700_writereg (state, 0x08, 0x04 | 0x02);  /* use user tps parameters */
-       cx22700_writereg (state, 0x08, 0x04);         /* restart acquisition */
-
-       return 0;
-}
-
-static int cx22700_get_tps(struct cx22700_state *state,
-                          struct dtv_frontend_properties *p)
-{
-       static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
-       static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
-                                                   FEC_5_6, FEC_7_8 };
-       u8 val;
-
-       dprintk ("%s\n", __func__);
-
-       if (!(cx22700_readreg(state, 0x07) & 0x20))  /*  tps valid? */
-               return -EAGAIN;
-
-       val = cx22700_readreg (state, 0x01);
-
-       if ((val & 0x7) > 4)
-               p->hierarchy = HIERARCHY_AUTO;
-       else
-               p->hierarchy = HIERARCHY_NONE + (val & 0x7);
-
-       if (((val >> 3) & 0x3) > 2)
-               p->modulation = QAM_AUTO;
-       else
-               p->modulation = qam_tab[(val >> 3) & 0x3];
-
-       val = cx22700_readreg (state, 0x02);
-
-       if (((val >> 3) & 0x07) > 4)
-               p->code_rate_HP = FEC_AUTO;
-       else
-               p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
-
-       if ((val & 0x07) > 4)
-               p->code_rate_LP = FEC_AUTO;
-       else
-               p->code_rate_LP = fec_tab[val & 0x07];
-
-       val = cx22700_readreg (state, 0x03);
-
-       p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
-       p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
-
-       return 0;
-}
-
-static int cx22700_init (struct dvb_frontend* fe)
-
-{      struct cx22700_state* state = fe->demodulator_priv;
-       int i;
-
-       dprintk("cx22700_init: init chip\n");
-
-       cx22700_writereg (state, 0x00, 0x02);   /*  soft reset */
-       cx22700_writereg (state, 0x00, 0x00);
-
-       msleep(10);
-
-       for (i=0; i<sizeof(init_tab); i+=2)
-               cx22700_writereg (state, init_tab[i], init_tab[i+1]);
-
-       cx22700_writereg (state, 0x00, 0x01);
-
-       return 0;
-}
-
-static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
-                  | (cx22700_readreg (state, 0x0e) << 1);
-       u8 sync = cx22700_readreg (state, 0x07);
-
-       *status = 0;
-
-       if (rs_ber < 0xff00)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 0x20)
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 0x10)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 0x10)
-               *status |= FE_HAS_SYNC;
-
-       if (*status == 0x0f)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       *ber = cx22700_readreg (state, 0x0c) & 0x7f;
-       cx22700_writereg (state, 0x0c, 0x00);
-
-       return 0;
-}
-
-static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
-                  | (cx22700_readreg (state, 0x0e) << 1);
-       *signal_strength = ~rs_ber;
-
-       return 0;
-}
-
-static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
-                  | (cx22700_readreg (state, 0x0e) << 1);
-       *snr = ~rs_ber;
-
-       return 0;
-}
-
-static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       *ucblocks = cx22700_readreg (state, 0x0f);
-       cx22700_writereg (state, 0x0f, 0x00);
-
-       return 0;
-}
-
-static int cx22700_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
-       cx22700_writereg (state, 0x00, 0x00);
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       cx22700_set_inversion(state, c->inversion);
-       cx22700_set_tps(state, c);
-       cx22700_writereg (state, 0x37, 0x01);  /* PAL loop filter off */
-       cx22700_writereg (state, 0x00, 0x01);  /* restart acquire */
-
-       return 0;
-}
-
-static int cx22700_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct cx22700_state* state = fe->demodulator_priv;
-       u8 reg09 = cx22700_readreg (state, 0x09);
-
-       c->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
-       return cx22700_get_tps(state, c);
-}
-
-static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return cx22700_writereg(state, 0x0a, 0x00);
-       } else {
-               return cx22700_writereg(state, 0x0a, 0x01);
-       }
-}
-
-static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 150;
-       fesettings->step_size = 166667;
-       fesettings->max_drift = 166667*2;
-       return 0;
-}
-
-static void cx22700_release(struct dvb_frontend* fe)
-{
-       struct cx22700_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops cx22700_ops;
-
-struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct cx22700_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if (cx22700_readreg(state, 0x07) < 0) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops cx22700_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Conexant CX22700 DVB-T",
-               .frequency_min          = 470000000,
-               .frequency_max          = 860000000,
-               .frequency_stepsize     = 166667,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                     FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                     FE_CAN_RECOVER
-       },
-
-       .release = cx22700_release,
-
-       .init = cx22700_init,
-       .i2c_gate_ctrl = cx22700_i2c_gate_ctrl,
-
-       .set_frontend = cx22700_set_frontend,
-       .get_frontend = cx22700_get_frontend,
-       .get_tune_settings = cx22700_get_tune_settings,
-
-       .read_status = cx22700_read_status,
-       .read_ber = cx22700_read_ber,
-       .read_signal_strength = cx22700_read_signal_strength,
-       .read_snr = cx22700_read_snr,
-       .read_ucblocks = cx22700_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
-MODULE_AUTHOR("Holger Waechtler");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
deleted file mode 100644 (file)
index 4757a93..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-    Conexant CX22700 DVB OFDM demodulator driver
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-       Holger Waechtler <holger@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef CX22700_H
-#define CX22700_H
-
-#include <linux/dvb/frontend.h>
-
-struct cx22700_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE))
-extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_CX22700
-
-#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
deleted file mode 100644 (file)
index edc8eaf..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
-    Conexant 22702 DVB OFDM demodulator driver
-
-    based on:
-       Alps TDMB7 DVB OFDM demodulator driver
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-         Holger Waechtler <holger@convergence.de>
-
-    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "cx22702.h"
-
-struct cx22702_state {
-
-       struct i2c_adapter *i2c;
-
-       /* configuration settings */
-       const struct cx22702_config *config;
-
-       struct dvb_frontend frontend;
-
-       /* previous uncorrected block counter */
-       u8 prevUCBlocks;
-};
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-#define dprintk        if (debug) printk
-
-/* Register values to initialise the demod */
-static const u8 init_tab[] = {
-       0x00, 0x00, /* Stop acquisition */
-       0x0B, 0x06,
-       0x09, 0x01,
-       0x0D, 0x41,
-       0x16, 0x32,
-       0x20, 0x0A,
-       0x21, 0x17,
-       0x24, 0x3e,
-       0x26, 0xff,
-       0x27, 0x10,
-       0x28, 0x00,
-       0x29, 0x00,
-       0x2a, 0x10,
-       0x2b, 0x00,
-       0x2c, 0x10,
-       0x2d, 0x00,
-       0x48, 0xd4,
-       0x49, 0x56,
-       0x6b, 0x1e,
-       0xc8, 0x02,
-       0xf9, 0x00,
-       0xfa, 0x00,
-       0xfb, 0x00,
-       0xfc, 0x00,
-       0xfd, 0x00,
-};
-
-static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address, .flags = 0,
-                       .buf = buf, .len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (unlikely(ret != 1)) {
-               printk(KERN_ERR
-                       "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       __func__, reg, data, ret);
-               return -1;
-       }
-
-       return 0;
-}
-
-static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
-{
-       int ret;
-       u8 data;
-
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0,
-                       .buf = &reg, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD,
-                       .buf = &data, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (unlikely(ret != 2)) {
-               printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n",
-                       __func__, reg, ret);
-               return 0;
-       }
-
-       return data;
-}
-
-static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
-{
-       u8 val;
-
-       val = cx22702_readreg(state, 0x0C);
-       switch (inversion) {
-       case INVERSION_AUTO:
-               return -EOPNOTSUPP;
-       case INVERSION_ON:
-               val |= 0x01;
-               break;
-       case INVERSION_OFF:
-               val &= 0xfe;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return cx22702_writereg(state, 0x0C, val);
-}
-
-/* Retrieve the demod settings */
-static int cx22702_get_tps(struct cx22702_state *state,
-                          struct dtv_frontend_properties *p)
-{
-       u8 val;
-
-       /* Make sure the TPS regs are valid */
-       if (!(cx22702_readreg(state, 0x0A) & 0x20))
-               return -EAGAIN;
-
-       val = cx22702_readreg(state, 0x01);
-       switch ((val & 0x18) >> 3) {
-       case 0:
-               p->modulation = QPSK;
-               break;
-       case 1:
-               p->modulation = QAM_16;
-               break;
-       case 2:
-               p->modulation = QAM_64;
-               break;
-       }
-       switch (val & 0x07) {
-       case 0:
-               p->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               p->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               p->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               p->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-
-       val = cx22702_readreg(state, 0x02);
-       switch ((val & 0x38) >> 3) {
-       case 0:
-               p->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_HP = FEC_7_8;
-               break;
-       }
-       switch (val & 0x07) {
-       case 0:
-               p->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       val = cx22702_readreg(state, 0x03);
-       switch ((val & 0x0c) >> 2) {
-       case 0:
-               p->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               p->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               p->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               p->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-       switch (val & 0x03) {
-       case 0:
-               p->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               p->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       }
-
-       return 0;
-}
-
-static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("%s(%d)\n", __func__, enable);
-       val = cx22702_readreg(state, 0x0D);
-       if (enable)
-               val &= 0xfe;
-       else
-               val |= 0x01;
-       return cx22702_writereg(state, 0x0D, val);
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int cx22702_set_tps(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u8 val;
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* set inversion */
-       cx22702_set_inversion(state, p->inversion);
-
-       /* set bandwidth */
-       val = cx22702_readreg(state, 0x0C) & 0xcf;
-       switch (p->bandwidth_hz) {
-       case 6000000:
-               val |= 0x20;
-               break;
-       case 7000000:
-               val |= 0x10;
-               break;
-       case 8000000:
-               break;
-       default:
-               dprintk("%s: invalid bandwidth\n", __func__);
-               return -EINVAL;
-       }
-       cx22702_writereg(state, 0x0C, val);
-
-       p->code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
-
-       /* use auto configuration? */
-       if ((p->hierarchy == HIERARCHY_AUTO) ||
-          (p->modulation == QAM_AUTO) ||
-          (p->code_rate_HP == FEC_AUTO) ||
-          (p->code_rate_LP == FEC_AUTO) ||
-          (p->guard_interval == GUARD_INTERVAL_AUTO) ||
-          (p->transmission_mode == TRANSMISSION_MODE_AUTO)) {
-
-               /* TPS Source - use hardware driven values */
-               cx22702_writereg(state, 0x06, 0x10);
-               cx22702_writereg(state, 0x07, 0x9);
-               cx22702_writereg(state, 0x08, 0xC1);
-               cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
-                       & 0xfc);
-               cx22702_writereg(state, 0x0C,
-                       (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
-               cx22702_writereg(state, 0x00, 0x01); /* Begin acquisition */
-               dprintk("%s: Autodetecting\n", __func__);
-               return 0;
-       }
-
-       /* manually programmed values */
-       switch (p->modulation) {                /* mask 0x18 */
-       case QPSK:
-               val = 0x00;
-               break;
-       case QAM_16:
-               val = 0x08;
-               break;
-       case QAM_64:
-               val = 0x10;
-               break;
-       default:
-               dprintk("%s: invalid modulation\n", __func__);
-               return -EINVAL;
-       }
-       switch (p->hierarchy) { /* mask 0x07 */
-       case HIERARCHY_NONE:
-               break;
-       case HIERARCHY_1:
-               val |= 0x01;
-               break;
-       case HIERARCHY_2:
-               val |= 0x02;
-               break;
-       case HIERARCHY_4:
-               val |= 0x03;
-               break;
-       default:
-               dprintk("%s: invalid hierarchy\n", __func__);
-               return -EINVAL;
-       }
-       cx22702_writereg(state, 0x06, val);
-
-       switch (p->code_rate_HP) {              /* mask 0x38 */
-       case FEC_NONE:
-       case FEC_1_2:
-               val = 0x00;
-               break;
-       case FEC_2_3:
-               val = 0x08;
-               break;
-       case FEC_3_4:
-               val = 0x10;
-               break;
-       case FEC_5_6:
-               val = 0x18;
-               break;
-       case FEC_7_8:
-               val = 0x20;
-               break;
-       default:
-               dprintk("%s: invalid code_rate_HP\n", __func__);
-               return -EINVAL;
-       }
-       switch (p->code_rate_LP) {              /* mask 0x07 */
-       case FEC_NONE:
-       case FEC_1_2:
-               break;
-       case FEC_2_3:
-               val |= 0x01;
-               break;
-       case FEC_3_4:
-               val |= 0x02;
-               break;
-       case FEC_5_6:
-               val |= 0x03;
-               break;
-       case FEC_7_8:
-               val |= 0x04;
-               break;
-       default:
-               dprintk("%s: invalid code_rate_LP\n", __func__);
-               return -EINVAL;
-       }
-       cx22702_writereg(state, 0x07, val);
-
-       switch (p->guard_interval) {            /* mask 0x0c */
-       case GUARD_INTERVAL_1_32:
-               val = 0x00;
-               break;
-       case GUARD_INTERVAL_1_16:
-               val = 0x04;
-               break;
-       case GUARD_INTERVAL_1_8:
-               val = 0x08;
-               break;
-       case GUARD_INTERVAL_1_4:
-               val = 0x0c;
-               break;
-       default:
-               dprintk("%s: invalid guard_interval\n", __func__);
-               return -EINVAL;
-       }
-       switch (p->transmission_mode) {         /* mask 0x03 */
-       case TRANSMISSION_MODE_2K:
-               break;
-       case TRANSMISSION_MODE_8K:
-               val |= 0x1;
-               break;
-       default:
-               dprintk("%s: invalid transmission_mode\n", __func__);
-               return -EINVAL;
-       }
-       cx22702_writereg(state, 0x08, val);
-       cx22702_writereg(state, 0x0B,
-               (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
-       cx22702_writereg(state, 0x0C,
-               (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
-
-       /* Begin channel acquisition */
-       cx22702_writereg(state, 0x00, 0x01);
-
-       return 0;
-}
-
-/* Reset the demod hardware and reset all of the configuration registers
-   to a default state. */
-static int cx22702_init(struct dvb_frontend *fe)
-{
-       int i;
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       cx22702_writereg(state, 0x00, 0x02);
-
-       msleep(10);
-
-       for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
-               cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
-
-       cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
-               & 0x02);
-
-       cx22702_i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-       u8 reg0A;
-       u8 reg23;
-
-       *status = 0;
-
-       reg0A = cx22702_readreg(state, 0x0A);
-       reg23 = cx22702_readreg(state, 0x23);
-
-       dprintk("%s: status demod=0x%02x agc=0x%02x\n"
-               , __func__, reg0A, reg23);
-
-       if (reg0A & 0x10) {
-               *status |= FE_HAS_LOCK;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-       }
-
-       if (reg0A & 0x20)
-               *status |= FE_HAS_CARRIER;
-
-       if (reg23 < 0xf0)
-               *status |= FE_HAS_SIGNAL;
-
-       return 0;
-}
-
-static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       if (cx22702_readreg(state, 0xE4) & 0x02) {
-               /* Realtime statistics */
-               *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
-                       | (cx22702_readreg(state, 0xDF) & 0x7F);
-       } else {
-               /* Averagtine statistics */
-               *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
-                       | cx22702_readreg(state, 0xDF);
-       }
-
-       return 0;
-}
-
-static int cx22702_read_signal_strength(struct dvb_frontend *fe,
-       u16 *signal_strength)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-       u8 reg23;
-
-       /*
-        * Experience suggests that the strength signal register works as
-        * follows:
-        * - In the absence of signal, value is 0xff.
-        * - In the presence of a weak signal, bit 7 is set, not sure what
-        *   the lower 7 bits mean.
-        * - In the presence of a strong signal, the register holds a 7-bit
-        *   value (bit 7 is cleared), with greater values standing for
-        *   weaker signals.
-        */
-       reg23 = cx22702_readreg(state, 0x23);
-       if (reg23 & 0x80) {
-               *signal_strength = 0;
-       } else {
-               reg23 = ~reg23 & 0x7f;
-               /* Scale to 16 bit */
-               *signal_strength = (reg23 << 9) | (reg23 << 2) | (reg23 >> 5);
-       }
-
-       return 0;
-}
-
-static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       u16 rs_ber;
-       if (cx22702_readreg(state, 0xE4) & 0x02) {
-               /* Realtime statistics */
-               rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
-                       | (cx22702_readreg(state, 0xDF) & 0x7F);
-       } else {
-               /* Averagine statistics */
-               rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
-                       | cx22702_readreg(state, 0xDF);
-       }
-       *snr = ~rs_ber;
-
-       return 0;
-}
-
-static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       u8 _ucblocks;
-
-       /* RS Uncorrectable Packet Count then reset */
-       _ucblocks = cx22702_readreg(state, 0xE3);
-       if (state->prevUCBlocks < _ucblocks)
-               *ucblocks = (_ucblocks - state->prevUCBlocks);
-       else
-               *ucblocks = state->prevUCBlocks - _ucblocks;
-       state->prevUCBlocks = _ucblocks;
-
-       return 0;
-}
-
-static int cx22702_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct cx22702_state *state = fe->demodulator_priv;
-
-       u8 reg0C = cx22702_readreg(state, 0x0C);
-
-       c->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
-       return cx22702_get_tps(state, c);
-}
-
-static int cx22702_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void cx22702_release(struct dvb_frontend *fe)
-{
-       struct cx22702_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static const struct dvb_frontend_ops cx22702_ops;
-
-struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
-       struct i2c_adapter *i2c)
-{
-       struct cx22702_state *state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if (cx22702_readreg(state, 0x1f) != 0x3)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &cx22702_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(cx22702_attach);
-
-static const struct dvb_frontend_ops cx22702_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Conexant CX22702 DVB-T",
-               .frequency_min          = 177000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-               FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-               FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
-       },
-
-       .release = cx22702_release,
-
-       .init = cx22702_init,
-       .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
-
-       .set_frontend = cx22702_set_tps,
-       .get_frontend = cx22702_get_frontend,
-       .get_tune_settings = cx22702_get_tune_settings,
-
-       .read_status = cx22702_read_status,
-       .read_ber = cx22702_read_ber,
-       .read_signal_strength = cx22702_read_signal_strength,
-       .read_snr = cx22702_read_snr,
-       .read_ucblocks = cx22702_read_ucblocks,
-};
-
-MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
deleted file mode 100644 (file)
index f154e1f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-    Conexant 22702 DVB OFDM demodulator driver
-
-    based on:
-       Alps TDMB7 DVB OFDM demodulator driver
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-         Holger Waechtler <holger@convergence.de>
-
-    Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef CX22702_H
-#define CX22702_H
-
-#include <linux/dvb/frontend.h>
-
-struct cx22702_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* serial/parallel output */
-#define CX22702_PARALLEL_OUTPUT 0
-#define CX22702_SERIAL_OUTPUT   1
-       u8 output_mode;
-};
-
-#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
-       && defined(MODULE))
-extern struct dvb_frontend *cx22702_attach(
-       const struct cx22702_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *cx22702_attach(
-       const struct cx22702_config *config,
-       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
deleted file mode 100644 (file)
index 3180f5b..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
-    cx24110 - Single Chip Satellite Channel Receiver driver module
-
-    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
-    work
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "dvb_frontend.h"
-#include "cx24110.h"
-
-
-struct cx24110_state {
-
-       struct i2c_adapter* i2c;
-
-       const struct cx24110_config* config;
-
-       struct dvb_frontend frontend;
-
-       u32 lastber;
-       u32 lastbler;
-       u32 lastesn0;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "cx24110: " args); \
-       } while (0)
-
-static struct {u8 reg; u8 data;} cx24110_regdata[]=
-                     /* Comments beginning with @ denote this value should
-                        be the default */
-       {{0x09,0x01}, /* SoftResetAll */
-        {0x09,0x00}, /* release reset */
-        {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
-        {0x02,0x17}, /* middle byte " */
-        {0x03,0x29}, /* LSB         " */
-        {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
-        {0x06,0xa5}, /* @ PLL 60MHz */
-        {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
-        {0x0a,0x00}, /* @ partial chip disables, do not set */
-        {0x0b,0x01}, /* set output clock in gapped mode, start signal low
-                        active for first byte */
-        {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
-        {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
-        {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
-                        to avoid starting the BER counter. Reset the
-                        CRC test bit. Finite counting selected */
-        {0x15,0xff}, /* @ size of the limited time window for RS BER
-                        estimation. It is <value>*256 RS blocks, this
-                        gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
-        {0x16,0x00}, /* @ enable all RS output ports */
-        {0x17,0x04}, /* @ time window allowed for the RS to sync */
-        {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
-                        for automatically */
-                     /* leave the current code rate and normalization
-                        registers as they are after reset... */
-        {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
-                        only once */
-        {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
-                        estimation. It is <value>*65536 channel bits, i.e.
-                        approx. 38ms at 27.5MS/s, rate 3/4 */
-        {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
-                     /* leave front-end AGC parameters at default values */
-                     /* leave decimation AGC parameters at default values */
-        {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
-        {0x36,0xff}, /* clear all interrupt pending flags */
-        {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
-        {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
-                     /* leave the equalizer parameters on their default values */
-                     /* leave the final AGC parameters on their default values */
-        {0x41,0x00}, /* @ MSB of front-end derotator frequency */
-        {0x42,0x00}, /* @ middle bytes " */
-        {0x43,0x00}, /* @ LSB          " */
-                     /* leave the carrier tracking loop parameters on default */
-                     /* leave the bit timing loop parameters at default */
-        {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
-                     /* the cx24108 data sheet for symbol rates above 15MS/s */
-        {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
-        {0x61,0x95}, /* GPIO pins 1-4 have special function */
-        {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
-        {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
-        {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
-        {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
-        {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
-        {0x73,0x00}, /* @ disable several demod bypasses */
-        {0x74,0x00}, /* @  " */
-        {0x75,0x00}  /* @  " */
-                     /* the remaining registers are for SEC */
-       };
-
-
-static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
-{
-       u8 buf [] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-       int err;
-
-       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-               dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
-                        " data == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int cx24110_readreg (struct cx24110_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) return ret;
-
-       return b1[0];
-}
-
-static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
-{
-/* fixme (low): error handling */
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
-               /* AcqSpectrInvDis on. No idea why someone should want this */
-               cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
-               /* Initial value 0 at start of acq */
-               cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
-               /* current value 0 */
-               /* The cx24110 manual tells us this reg is read-only.
-                  But what the heck... set it ayways */
-               break;
-       case INVERSION_ON:
-               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
-               /* AcqSpectrInvDis on. No idea why someone should want this */
-               cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
-               /* Initial value 1 at start of acq */
-               cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
-               /* current value 1 */
-               break;
-       case INVERSION_AUTO:
-               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
-               /* AcqSpectrInvDis off. Leave initial & current states as is */
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
-{
-/* fixme (low): error handling */
-
-       static const int rate[]={-1,1,2,3,5,7,-1};
-       static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
-       static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
-
-       /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
-          searches all enabled viterbi rates, and can handle non-standard
-          rates as well. */
-
-       if (fec>FEC_AUTO)
-               fec=FEC_AUTO;
-
-       if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
-               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
-               /* clear AcqVitDis bit */
-               cx24110_writereg(state,0x18,0xae);
-               /* allow all DVB standard code rates */
-               cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
-               /* set nominal Viterbi rate 3/4 */
-               cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
-               /* set current Viterbi rate 3/4 */
-               cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
-               /* set the puncture registers for code rate 3/4 */
-               return 0;
-       } else {
-               cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
-               /* set AcqVitDis bit */
-               if(rate[fec]>0) {
-                       cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
-                       /* set nominal Viterbi rate */
-                       cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
-                       /* set current Viterbi rate */
-                       cx24110_writereg(state,0x1a,g1[fec]);
-                       cx24110_writereg(state,0x1b,g2[fec]);
-                       /* not sure if this is the right way: I always used AutoAcq mode */
-          } else
-                  return -EOPNOTSUPP;
-/* fixme (low): which is the correct return code? */
-       };
-       return 0;
-}
-
-static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
-{
-       int i;
-
-       i=cx24110_readreg(state,0x22)&0x0f;
-       if(!(i&0x08)) {
-               return FEC_1_2 + i - 1;
-       } else {
-/* fixme (low): a special code rate has been selected. In theory, we need to
-   return a denominator value, a numerator value, and a pair of puncture
-   maps to correctly describe this mode. But this should never happen in
-   practice, because it cannot be set by cx24110_get_fec. */
-          return FEC_NONE;
-       }
-}
-
-static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
-{
-/* fixme (low): add error handling */
-       u32 ratio;
-       u32 tmp, fclk, BDRI;
-
-       static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
-       int i;
-
-       dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
-       if (srate>90999000UL/2)
-               srate=90999000UL/2;
-       if (srate<500000)
-               srate=500000;
-
-       for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++)
-               ;
-       /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
-          and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
-          R06[3:0] PLLphaseDetGain */
-       tmp=cx24110_readreg(state,0x07)&0xfc;
-       if(srate<90999000UL/4) { /* sample rate 45MHz*/
-               cx24110_writereg(state,0x07,tmp);
-               cx24110_writereg(state,0x06,0x78);
-               fclk=90999000UL/2;
-       } else if(srate<60666000UL/2) { /* sample rate 60MHz */
-               cx24110_writereg(state,0x07,tmp|0x1);
-               cx24110_writereg(state,0x06,0xa5);
-               fclk=60666000UL;
-       } else if(srate<80888000UL/2) { /* sample rate 80MHz */
-               cx24110_writereg(state,0x07,tmp|0x2);
-               cx24110_writereg(state,0x06,0x87);
-               fclk=80888000UL;
-       } else { /* sample rate 90MHz */
-               cx24110_writereg(state,0x07,tmp|0x3);
-               cx24110_writereg(state,0x06,0x78);
-               fclk=90999000UL;
-       };
-       dprintk("cx24110 debug: fclk %d Hz\n",fclk);
-       /* we need to divide two integers with approx. 27 bits in 32 bit
-          arithmetic giving a 25 bit result */
-       /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
-          also the most complex divisor. Hence, the dividend has,
-          assuming 32bit unsigned arithmetic, 6 clear bits on top, the
-          divisor 2 unused bits at the bottom. Also, the quotient is
-          always less than 1/2. Borrowed from VES1893.c, of course */
-
-       tmp=srate<<6;
-       BDRI=fclk>>2;
-       ratio=(tmp/BDRI);
-
-       tmp=(tmp%BDRI)<<8;
-       ratio=(ratio<<8)+(tmp/BDRI);
-
-       tmp=(tmp%BDRI)<<8;
-       ratio=(ratio<<8)+(tmp/BDRI);
-
-       tmp=(tmp%BDRI)<<1;
-       ratio=(ratio<<1)+(tmp/BDRI);
-
-       dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
-       dprintk("fclk = %d\n", fclk);
-       dprintk("ratio= %08x\n", ratio);
-
-       cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
-       cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
-       cx24110_writereg(state, 0x3, (ratio)&0xff);
-
-       return 0;
-
-}
-
-static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       if (len != 3)
-               return -EINVAL;
-
-/* tuner data is 21 bits long, must be left-aligned in data */
-/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
-/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
-
-       cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
-       cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
-
-       /* if the auto tuner writer is still busy, clear it out */
-       while (cx24110_readreg(state,0x6d)&0x80)
-               cx24110_writereg(state,0x72,0);
-
-       /* write the topmost 8 bits */
-       cx24110_writereg(state,0x72,buf[0]);
-
-       /* wait for the send to be completed */
-       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
-               ;
-
-       /* send another 8 bytes */
-       cx24110_writereg(state,0x72,buf[1]);
-       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
-               ;
-
-       /* and the topmost 5 bits of this byte */
-       cx24110_writereg(state,0x72,buf[2]);
-       while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
-               ;
-
-       /* now strobe the enable line once */
-       cx24110_writereg(state,0x6d,0x32);
-       cx24110_writereg(state,0x6d,0x30);
-
-       return 0;
-}
-
-static int cx24110_initfe(struct dvb_frontend* fe)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-/* fixme (low): error handling */
-       int i;
-
-       dprintk("%s: init chip\n", __func__);
-
-       for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
-               cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
-       };
-
-       return 0;
-}
-
-static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
-       case SEC_VOLTAGE_18:
-               return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
-       default:
-               return -EINVAL;
-       };
-}
-
-static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
-{
-       int rv, bit;
-       struct cx24110_state *state = fe->demodulator_priv;
-       unsigned long timeout;
-
-       if (burst == SEC_MINI_A)
-               bit = 0x00;
-       else if (burst == SEC_MINI_B)
-               bit = 0x08;
-       else
-               return -EINVAL;
-
-       rv = cx24110_readreg(state, 0x77);
-       if (!(rv & 0x04))
-               cx24110_writereg(state, 0x77, rv | 0x04);
-
-       rv = cx24110_readreg(state, 0x76);
-       cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
-       timeout = jiffies + msecs_to_jiffies(100);
-       while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
-               ; /* wait for LNB ready */
-
-       return 0;
-}
-
-static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
-                                  struct dvb_diseqc_master_cmd *cmd)
-{
-       int i, rv;
-       struct cx24110_state *state = fe->demodulator_priv;
-       unsigned long timeout;
-
-       if (cmd->msg_len < 3 || cmd->msg_len > 6)
-               return -EINVAL;  /* not implemented */
-
-       for (i = 0; i < cmd->msg_len; i++)
-               cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
-
-       rv = cx24110_readreg(state, 0x77);
-       if (rv & 0x04) {
-               cx24110_writereg(state, 0x77, rv & ~0x04);
-               msleep(30); /* reportedly fixes switching problems */
-       }
-
-       rv = cx24110_readreg(state, 0x76);
-
-       cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
-       timeout = jiffies + msecs_to_jiffies(100);
-       while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
-               ; /* wait for LNB ready */
-
-       return 0;
-}
-
-static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       int sync = cx24110_readreg (state, 0x55);
-
-       *status = 0;
-
-       if (sync & 0x10)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 0x08)
-               *status |= FE_HAS_CARRIER;
-
-       sync = cx24110_readreg (state, 0x08);
-
-       if (sync & 0x40)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 0x20)
-               *status |= FE_HAS_SYNC;
-
-       if ((sync & 0x60) == 0x60)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       /* fixme (maybe): value range is 16 bit. Scale? */
-       if(cx24110_readreg(state,0x24)&0x10) {
-               /* the Viterbi error counter has finished one counting window */
-               cx24110_writereg(state,0x24,0x04); /* select the ber reg */
-               state->lastber=cx24110_readreg(state,0x25)|
-                       (cx24110_readreg(state,0x26)<<8);
-               cx24110_writereg(state,0x24,0x04); /* start new count window */
-               cx24110_writereg(state,0x24,0x14);
-       }
-       *ber = state->lastber;
-
-       return 0;
-}
-
-static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
-       u8 signal = cx24110_readreg (state, 0x27)+128;
-       *signal_strength = (signal << 8) | signal;
-
-       return 0;
-}
-
-static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
-       if(cx24110_readreg(state,0x6a)&0x80) {
-               /* the Es/N0 error counter has finished one counting window */
-               state->lastesn0=cx24110_readreg(state,0x69)|
-                       (cx24110_readreg(state,0x68)<<8);
-               cx24110_writereg(state,0x6a,0x84); /* start new count window */
-       }
-       *snr = state->lastesn0;
-
-       return 0;
-}
-
-static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       if(cx24110_readreg(state,0x10)&0x40) {
-               /* the RS error counter has finished one counting window */
-               cx24110_writereg(state,0x10,0x60); /* select the byer reg */
-               (void)(cx24110_readreg(state, 0x12) |
-                       (cx24110_readreg(state, 0x13) << 8) |
-                       (cx24110_readreg(state, 0x14) << 16));
-               cx24110_writereg(state,0x10,0x70); /* select the bler reg */
-               state->lastbler=cx24110_readreg(state,0x12)|
-                       (cx24110_readreg(state,0x13)<<8)|
-                       (cx24110_readreg(state,0x14)<<16);
-               cx24110_writereg(state,0x10,0x20); /* start new count window */
-       }
-       *ucblocks = state->lastbler;
-
-       return 0;
-}
-
-static int cx24110_set_frontend(struct dvb_frontend *fe)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       cx24110_set_inversion(state, p->inversion);
-       cx24110_set_fec(state, p->fec_inner);
-       cx24110_set_symbolrate(state, p->symbol_rate);
-       cx24110_writereg(state,0x04,0x05); /* start acquisition */
-
-       return 0;
-}
-
-static int cx24110_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct cx24110_state *state = fe->demodulator_priv;
-       s32 afc; unsigned sclk;
-
-/* cannot read back tuner settings (freq). Need to have some private storage */
-
-       sclk = cx24110_readreg (state, 0x07) & 0x03;
-/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
- * Need 64 bit arithmetic. Is thiss possible in the kernel? */
-       if (sclk==0) sclk=90999000L/2L;
-       else if (sclk==1) sclk=60666000L;
-       else if (sclk==2) sclk=80888000L;
-       else sclk=90999000L;
-       sclk>>=8;
-       afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
-             ((sclk*cx24110_readreg (state, 0x45))>>8)+
-             ((sclk*cx24110_readreg (state, 0x46))>>16);
-
-       p->frequency += afc;
-       p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
-                               INVERSION_ON : INVERSION_OFF;
-       p->fec_inner = cx24110_get_fec(state);
-
-       return 0;
-}
-
-static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct cx24110_state *state = fe->demodulator_priv;
-
-       return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
-}
-
-static void cx24110_release(struct dvb_frontend* fe)
-{
-       struct cx24110_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops cx24110_ops;
-
-struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct cx24110_state* state = NULL;
-       int ret;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->lastber = 0;
-       state->lastbler = 0;
-       state->lastesn0 = 0;
-
-       /* check if the demod is there */
-       ret = cx24110_readreg(state, 0x00);
-       if ((ret != 0x5a) && (ret != 0x69)) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops cx24110_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name = "Conexant CX24110 DVB-S",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1011,  /* kHz for QPSK frontends */
-               .frequency_tolerance = 29500,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_RECOVER
-       },
-
-       .release = cx24110_release,
-
-       .init = cx24110_initfe,
-       .write = _cx24110_pll_write,
-       .set_frontend = cx24110_set_frontend,
-       .get_frontend = cx24110_get_frontend,
-       .read_status = cx24110_read_status,
-       .read_ber = cx24110_read_ber,
-       .read_signal_strength = cx24110_read_signal_strength,
-       .read_snr = cx24110_read_snr,
-       .read_ucblocks = cx24110_read_ucblocks,
-
-       .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
-       .set_tone = cx24110_set_tone,
-       .set_voltage = cx24110_set_voltage,
-       .diseqc_send_burst = cx24110_diseqc_send_burst,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
-MODULE_AUTHOR("Peter Hettkamp");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(cx24110_attach);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
deleted file mode 100644 (file)
index fdcceee..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-    cx24110 - Single Chip Satellite Channel Receiver driver module
-
-    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
-    work
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef CX24110_H
-#define CX24110_H
-
-#include <linux/dvb/frontend.h>
-
-struct cx24110_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
-{
-       u8 buf[] = {
-               (u8)((val >> 24) & 0xff),
-               (u8)((val >> 16) & 0xff),
-               (u8)((val >> 8) & 0xff)
-       };
-
-       if (fe->ops.write)
-               return fe->ops.write(fe, buf, 3);
-       return 0;
-}
-
-#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
-extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
-                                                 struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_CX24110
-
-#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
deleted file mode 100644 (file)
index 3883c3b..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- *  Driver for Conexant CX24113/CX24128 Tuner (Satellite)
- *
- *  Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
- *
- *  Developed for BBTI / Technisat
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "dvb_frontend.h"
-#include "cx24113.h"
-
-static int debug;
-
-#define cx_info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0)
-#define cx_err(args...)  do { printk(KERN_ERR  "CX24113: " args); } while (0)
-
-#define dprintk(args...) \
-       do { \
-               if (debug) { \
-                       printk(KERN_DEBUG "CX24113: %s: ", __func__); \
-                       printk(args); \
-               } \
-       } while (0)
-
-struct cx24113_state {
-       struct i2c_adapter *i2c;
-       const struct cx24113_config *config;
-
-#define REV_CX24113 0x23
-       u8 rev;
-       u8 ver;
-
-       u8 icp_mode:1;
-
-#define ICP_LEVEL1 0
-#define ICP_LEVEL2 1
-#define ICP_LEVEL3 2
-#define ICP_LEVEL4 3
-       u8 icp_man:2;
-       u8 icp_auto_low:2;
-       u8 icp_auto_mlow:2;
-       u8 icp_auto_mhi:2;
-       u8 icp_auto_hi:2;
-       u8 icp_dig;
-
-#define LNA_MIN_GAIN 0
-#define LNA_MID_GAIN 1
-#define LNA_MAX_GAIN 2
-       u8 lna_gain:2;
-
-       u8 acp_on:1;
-
-       u8 vco_mode:2;
-       u8 vco_shift:1;
-#define VCOBANDSEL_6 0x80
-#define VCOBANDSEL_5 0x01
-#define VCOBANDSEL_4 0x02
-#define VCOBANDSEL_3 0x04
-#define VCOBANDSEL_2 0x08
-#define VCOBANDSEL_1 0x10
-       u8 vco_band;
-
-#define VCODIV4 4
-#define VCODIV2 2
-       u8 vcodiv;
-
-       u8 bs_delay:4;
-       u16 bs_freqcnt:13;
-       u16 bs_rdiv;
-       u8 prescaler_mode:1;
-
-       u8 rfvga_bias_ctrl;
-
-       s16 tuner_gain_thres;
-       u8  gain_level;
-
-       u32 frequency;
-
-       u8 refdiv;
-
-       u8 Fwindow_enabled;
-};
-
-static int cx24113_writereg(struct cx24113_state *state, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->i2c_addr,
-               .flags = 0, .buf = buf, .len = 2 };
-       int err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x,"
-                        " data == 0x%02x)\n", __func__, err, reg, data);
-               return err;
-       }
-
-       return 0;
-}
-
-static int cx24113_readreg(struct cx24113_state *state, u8 reg)
-{
-       int ret;
-       u8 b;
-       struct i2c_msg msg[] = {
-               { .addr = state->config->i2c_addr,
-                       .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = state->config->i2c_addr,
-                       .flags = I2C_M_RD, .buf = &b, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n",
-                       __func__, reg, ret);
-               return ret;
-       }
-
-       return b;
-}
-
-static void cx24113_set_parameters(struct cx24113_state *state)
-{
-       u8 r;
-
-       r = cx24113_readreg(state, 0x10) & 0x82;
-       r |= state->icp_mode;
-       r |= state->icp_man << 4;
-       r |= state->icp_dig << 2;
-       r |= state->prescaler_mode << 5;
-       cx24113_writereg(state, 0x10, r);
-
-       r = (state->icp_auto_low  << 0) | (state->icp_auto_mlow << 2)
-               | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6);
-       cx24113_writereg(state, 0x11, r);
-
-       if (state->rev == REV_CX24113) {
-               r = cx24113_readreg(state, 0x20) & 0xec;
-               r |= state->lna_gain;
-               r |= state->rfvga_bias_ctrl << 4;
-               cx24113_writereg(state, 0x20, r);
-       }
-
-       r = cx24113_readreg(state, 0x12) & 0x03;
-       r |= state->acp_on << 2;
-       r |= state->bs_delay << 4;
-       cx24113_writereg(state, 0x12, r);
-
-       r = cx24113_readreg(state, 0x18) & 0x40;
-       r |= state->vco_shift;
-       if (state->vco_band == VCOBANDSEL_6)
-               r |= (1 << 7);
-       else
-               r |= (state->vco_band << 1);
-       cx24113_writereg(state, 0x18, r);
-
-       r  = cx24113_readreg(state, 0x14) & 0x20;
-       r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f);
-       cx24113_writereg(state, 0x14, r);
-       cx24113_writereg(state, 0x15, (state->bs_freqcnt        & 0xff));
-
-       cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff);
-       r = (cx24113_readreg(state, 0x17) & 0x0f) |
-               ((state->bs_rdiv & 0x0f) << 4);
-       cx24113_writereg(state, 0x17, r);
-}
-
-#define VGA_0 0x00
-#define VGA_1 0x04
-#define VGA_2 0x02
-#define VGA_3 0x06
-#define VGA_4 0x01
-#define VGA_5 0x05
-#define VGA_6 0x03
-#define VGA_7 0x07
-
-#define RFVGA_0 0x00
-#define RFVGA_1 0x01
-#define RFVGA_2 0x02
-#define RFVGA_3 0x03
-
-static int cx24113_set_gain_settings(struct cx24113_state *state,
-               s16 power_estimation)
-{
-       u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0,
-          vga    = cx24113_readreg(state, 0x1f) & 0x3f,
-          rfvga  = cx24113_readreg(state, 0x20) & 0xf3;
-       u8 gain_level = power_estimation >= state->tuner_gain_thres;
-
-       dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n",
-                       power_estimation, state->tuner_gain_thres,
-                       state->gain_level, gain_level);
-
-       if (gain_level == state->gain_level)
-               return 0; /* nothing to be done */
-
-       ampout |= 0xf;
-
-       if (gain_level) {
-               rfvga |= RFVGA_0 << 2;
-               vga   |= (VGA_7 << 3) | VGA_7;
-       } else {
-               rfvga |= RFVGA_2 << 2;
-               vga  |= (VGA_6 << 3) | VGA_2;
-       }
-       state->gain_level = gain_level;
-
-       cx24113_writereg(state, 0x1d, ampout);
-       cx24113_writereg(state, 0x1f, vga);
-       cx24113_writereg(state, 0x20, rfvga);
-
-       return 1; /* did something */
-}
-
-static int cx24113_set_Fref(struct cx24113_state *state, u8 high)
-{
-       u8 xtal = cx24113_readreg(state, 0x02);
-       if (state->rev == 0x43 && state->vcodiv == VCODIV4)
-               high = 1;
-
-       xtal &= ~0x2;
-       if (high)
-               xtal |= high << 1;
-       return cx24113_writereg(state, 0x02, xtal);
-}
-
-static int cx24113_enable(struct cx24113_state *state, u8 enable)
-{
-       u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable;
-       if (state->rev == REV_CX24113)
-               r21 |= (1 << 1);
-       return cx24113_writereg(state, 0x21, r21);
-}
-
-static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz)
-{
-       u8 r;
-
-       if (bandwidth_khz <= 19000)
-               r = 0x03 << 6;
-       else if (bandwidth_khz <= 25000)
-               r = 0x02 << 6;
-       else
-               r = 0x01 << 6;
-
-       dprintk("bandwidth to be set: %d\n", bandwidth_khz);
-       bandwidth_khz *= 10;
-       bandwidth_khz -= 10000;
-       bandwidth_khz /= 1000;
-       bandwidth_khz += 5;
-       bandwidth_khz /= 10;
-
-       dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz);
-
-       r |= bandwidth_khz & 0x3f;
-
-       return cx24113_writereg(state, 0x1e, r);
-}
-
-static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on)
-{
-       u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7);
-       return cx24113_writereg(state, 0x10, r);
-}
-
-static int cx24113_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct cx24113_state *state = fe->tuner_priv;
-       u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1;
-       if (r)
-               *status |= TUNER_STATUS_LOCKED;
-       dprintk("PLL locked: %d\n", r);
-       return 0;
-}
-
-static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv)
-{
-       if (state->rev == 0x43 && state->vcodiv == VCODIV4)
-               refdiv = 2;
-       return state->refdiv = refdiv;
-}
-
-static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
-{
-       s32 N;
-       s64 F;
-       u64 dividend;
-       u8 R, r;
-       u8 vcodiv;
-       u8 factor;
-       s32 freq_hz = state->frequency * 1000;
-
-       if (state->config->xtal_khz < 20000)
-               factor = 1;
-       else
-               factor = 2;
-
-       if (state->rev == REV_CX24113) {
-               if (state->frequency >= 1100000)
-                       vcodiv = VCODIV2;
-               else
-                       vcodiv = VCODIV4;
-       } else {
-               if (state->frequency >= 1165000)
-                       vcodiv = VCODIV2;
-               else
-                       vcodiv = VCODIV4;
-       }
-       state->vcodiv = vcodiv;
-
-       dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv);
-       R = 0;
-       do {
-               R = cx24113_set_ref_div(state, R + 1);
-
-               /* calculate tuner PLL settings: */
-               N =  (freq_hz / 100 * vcodiv) * R;
-               N /= (state->config->xtal_khz) * factor * 2;
-               N += 5;     /* For round up. */
-               N /= 10;
-               N -= 32;
-       } while (N < 6 && R < 3);
-
-       if (N < 6) {
-               cx_err("strange frequency: N < 6\n");
-               return;
-       }
-       F = freq_hz;
-       F *= (u64) (R * vcodiv * 262144);
-       dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
-       /* do_div needs an u64 as first argument */
-       dividend = F;
-       do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
-       F = dividend;
-       dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
-       F -= (N + 32) * 262144;
-
-       dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
-
-       if (state->Fwindow_enabled) {
-               if (F > (262144 / 2 - 1638))
-                       F = 262144 / 2 - 1638;
-               if (F < (-262144 / 2 + 1638))
-                       F = -262144 / 2 + 1638;
-               if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) {
-                       F = 0;
-                       r = cx24113_readreg(state, 0x10);
-                       cx24113_writereg(state, 0x10, r | (1 << 6));
-               }
-       }
-       dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
-
-       *n = (u16) N;
-       *f = (s32) F;
-}
-
-
-static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r)
-{
-       u8 reg;
-       cx24113_writereg(state, 0x19, (n >> 1) & 0xff);
-
-       reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f);
-       cx24113_writereg(state, 0x1a, reg);
-
-       cx24113_writereg(state, 0x1b, (f >> 3) & 0xff);
-
-       reg = cx24113_readreg(state, 0x1c) & 0x1f;
-       cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5));
-
-       cx24113_set_Fref(state, r - 1);
-}
-
-static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency)
-{
-       u8 r = 1; /* or 2 */
-       u16 n = 6;
-       s32 f = 0;
-
-       r = cx24113_readreg(state, 0x14);
-       cx24113_writereg(state, 0x14, r & 0x3f);
-
-       r = cx24113_readreg(state, 0x10);
-       cx24113_writereg(state, 0x10, r & 0xbf);
-
-       state->frequency = frequency;
-
-       dprintk("tuning to frequency: %d\n", frequency);
-
-       cx24113_calc_pll_nf(state, &n, &f);
-       cx24113_set_nfr(state, n, f, state->refdiv);
-
-       r = cx24113_readreg(state, 0x18) & 0xbf;
-       if (state->vcodiv != VCODIV2)
-               r |= 1 << 6;
-       cx24113_writereg(state, 0x18, r);
-
-       /* The need for this sleep is not clear. But helps in some cases */
-       msleep(5);
-
-       r = cx24113_readreg(state, 0x1c) & 0xef;
-       cx24113_writereg(state, 0x1c, r | (1 << 4));
-       return 0;
-}
-
-static int cx24113_init(struct dvb_frontend *fe)
-{
-       struct cx24113_state *state = fe->tuner_priv;
-       int ret;
-
-       state->tuner_gain_thres = -50;
-       state->gain_level = 255; /* to force a gain-setting initialization */
-       state->icp_mode = 0;
-
-       if (state->config->xtal_khz < 11000) {
-               state->icp_auto_hi  = ICP_LEVEL4;
-               state->icp_auto_mhi  = ICP_LEVEL4;
-               state->icp_auto_mlow = ICP_LEVEL3;
-               state->icp_auto_low = ICP_LEVEL3;
-       } else {
-               state->icp_auto_hi  = ICP_LEVEL4;
-               state->icp_auto_mhi  = ICP_LEVEL4;
-               state->icp_auto_mlow = ICP_LEVEL3;
-               state->icp_auto_low = ICP_LEVEL2;
-       }
-
-       state->icp_dig = ICP_LEVEL3;
-       state->icp_man = ICP_LEVEL1;
-       state->acp_on  = 1;
-       state->vco_mode = 0;
-       state->vco_shift = 0;
-       state->vco_band = VCOBANDSEL_1;
-       state->bs_delay = 8;
-       state->bs_freqcnt = 0x0fff;
-       state->bs_rdiv = 0x0fff;
-       state->prescaler_mode = 0;
-       state->lna_gain = LNA_MAX_GAIN;
-       state->rfvga_bias_ctrl = 1;
-       state->Fwindow_enabled = 1;
-
-       cx24113_set_Fref(state, 0);
-       cx24113_enable(state, 0x3d);
-       cx24113_set_parameters(state);
-
-       cx24113_set_gain_settings(state, -30);
-
-       cx24113_set_bandwidth(state, 18025);
-       cx24113_set_clk_inversion(state, 1);
-
-       if (state->config->xtal_khz >= 40000)
-               ret = cx24113_writereg(state, 0x02,
-                       (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2));
-       else
-               ret = cx24113_writereg(state, 0x02,
-                       (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2));
-
-       return ret;
-}
-
-static int cx24113_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct cx24113_state *state = fe->tuner_priv;
-       /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */
-       u32 roll_off = 675;
-       u32 bw;
-
-       bw  = ((c->symbol_rate/100) * roll_off) / 1000;
-       bw += (10000000/100) + 5;
-       bw /= 10;
-       bw += 1000;
-       cx24113_set_bandwidth(state, bw);
-
-       cx24113_set_frequency(state, c->frequency);
-       msleep(5);
-       return cx24113_get_status(fe, &bw);
-}
-
-static s8 cx24113_agc_table[2][10] = {
-       {-54, -41, -35, -30, -25, -21, -16, -10,  -6,  -2},
-       {-39, -35, -30, -25, -19, -15, -11,  -5,   1,   9},
-};
-
-void cx24113_agc_callback(struct dvb_frontend *fe)
-{
-       struct cx24113_state *state = fe->tuner_priv;
-       s16 s, i;
-       if (!fe->ops.read_signal_strength)
-               return;
-
-       do {
-               /* this only works with the current CX24123 implementation */
-               fe->ops.read_signal_strength(fe, (u16 *) &s);
-               s >>= 8;
-               dprintk("signal strength: %d\n", s);
-               for (i = 0; i < sizeof(cx24113_agc_table[0]); i++)
-                       if (cx24113_agc_table[state->gain_level][i] > s)
-                               break;
-               s = -25 - i*5;
-       } while (cx24113_set_gain_settings(state, s));
-}
-EXPORT_SYMBOL(cx24113_agc_callback);
-
-static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct cx24113_state *state = fe->tuner_priv;
-       *frequency = state->frequency;
-       return 0;
-}
-
-static int cx24113_release(struct dvb_frontend *fe)
-{
-       struct cx24113_state *state = fe->tuner_priv;
-       dprintk("\n");
-       fe->tuner_priv = NULL;
-       kfree(state);
-       return 0;
-}
-
-static const struct dvb_tuner_ops cx24113_tuner_ops = {
-       .info = {
-               .name           = "Conexant CX24113",
-               .frequency_min  = 950000,
-               .frequency_max  = 2150000,
-               .frequency_step = 125,
-       },
-
-       .release       = cx24113_release,
-
-       .init          = cx24113_init,
-
-       .set_params    = cx24113_set_params,
-       .get_frequency = cx24113_get_frequency,
-       .get_status    = cx24113_get_status,
-};
-
-struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
-               const struct cx24113_config *config, struct i2c_adapter *i2c)
-{
-       /* allocate memory for the internal state */
-       struct cx24113_state *state =
-               kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
-       int rc;
-       if (state == NULL) {
-               cx_err("Unable to kzalloc\n");
-               goto error;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       cx_info("trying to detect myself\n");
-
-       /* making a dummy read, because of some expected troubles
-        * after power on */
-       cx24113_readreg(state, 0x00);
-
-       rc = cx24113_readreg(state, 0x00);
-       if (rc < 0) {
-               cx_info("CX24113 not found.\n");
-               goto error;
-       }
-       state->rev = rc;
-
-       switch (rc) {
-       case 0x43:
-               cx_info("detected CX24113 variant\n");
-               break;
-       case REV_CX24113:
-               cx_info("successfully detected\n");
-               break;
-       default:
-               cx_err("unsupported device id: %x\n", state->rev);
-               goto error;
-       }
-       state->ver = cx24113_readreg(state, 0x01);
-       cx_info("version: %x\n", state->ver);
-
-       /* create dvb_frontend */
-       memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops,
-                       sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = state;
-       return fe;
-
-error:
-       kfree(state);
-
-       return NULL;
-}
-EXPORT_SYMBOL(cx24113_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
-MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h
deleted file mode 100644 (file)
index 01eb7b9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Driver for Conexant CX24113/CX24128 Tuner (Satellite)
- *
- *  Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef CX24113_H
-#define CX24113_H
-
-struct dvb_frontend;
-
-struct cx24113_config {
-       u8 i2c_addr; /* 0x14 or 0x54 */
-
-       u32 xtal_khz;
-};
-
-#if defined(CONFIG_DVB_TUNER_CX24113) || \
-       (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
-extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
-       const struct cx24113_config *config, struct i2c_adapter *i2c);
-
-extern void cx24113_agc_callback(struct dvb_frontend *fe);
-#else
-static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
-       const struct cx24113_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline void cx24113_agc_callback(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-#endif
-
-#endif /* CX24113_H */
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
deleted file mode 100644 (file)
index b488791..0000000
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
-    Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
-
-    Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
-    Copyright (C) 2006-2007 Georg Acher
-    Copyright (C) 2007-2008 Darron Broad
-       March 2007
-           Fixed some bugs.
-           Added diseqc support.
-           Added corrected signal strength support.
-       August 2007
-           Sync with legacy version.
-           Some clean ups.
-    Copyright (C) 2008 Igor Liplianin
-       September, 9th 2008
-           Fixed locking on high symbol rates (>30000).
-           Implement MPEG initialization parameter.
-       January, 17th 2009
-           Fill set_voltage with actually control voltage code.
-           Correct set tone to not affect voltage.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/firmware.h>
-
-#include "dvb_frontend.h"
-#include "cx24116.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_INFO "cx24116: " args); \
-       } while (0)
-
-#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
-#define CX24116_SEARCH_RANGE_KHZ 5000
-
-/* known registers */
-#define CX24116_REG_COMMAND (0x00)      /* command args 0x00..0x1e */
-#define CX24116_REG_EXECUTE (0x1f)      /* execute command */
-#define CX24116_REG_MAILBOX (0x96)      /* FW or multipurpose mailbox? */
-#define CX24116_REG_RESET   (0x20)      /* reset status > 0     */
-#define CX24116_REG_SIGNAL  (0x9e)      /* signal low           */
-#define CX24116_REG_SSTATUS (0x9d)      /* signal high / status */
-#define CX24116_REG_QUALITY8 (0xa3)
-#define CX24116_REG_QSTATUS (0xbc)
-#define CX24116_REG_QUALITY0 (0xd5)
-#define CX24116_REG_BER0    (0xc9)
-#define CX24116_REG_BER8    (0xc8)
-#define CX24116_REG_BER16   (0xc7)
-#define CX24116_REG_BER24   (0xc6)
-#define CX24116_REG_UCB0    (0xcb)
-#define CX24116_REG_UCB8    (0xca)
-#define CX24116_REG_CLKDIV  (0xf3)
-#define CX24116_REG_RATEDIV (0xf9)
-
-/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
-#define CX24116_REG_FECSTATUS (0x9c)
-
-/* FECSTATUS bits */
-/* mask to determine configured fec (not tuned) or actual fec (tuned) */
-#define CX24116_FEC_FECMASK   (0x1f)
-
-/* Select DVB-S demodulator, else DVB-S2 */
-#define CX24116_FEC_DVBS      (0x20)
-#define CX24116_FEC_UNKNOWN   (0x40)    /* Unknown/unused */
-
-/* Pilot mode requested when tuning else always reset when tuned */
-#define CX24116_FEC_PILOT     (0x80)
-
-/* arg buffer size */
-#define CX24116_ARGLEN (0x1e)
-
-/* rolloff */
-#define CX24116_ROLLOFF_020 (0x00)
-#define CX24116_ROLLOFF_025 (0x01)
-#define CX24116_ROLLOFF_035 (0x02)
-
-/* pilot bit */
-#define CX24116_PILOT_OFF (0x00)
-#define CX24116_PILOT_ON (0x40)
-
-/* signal status */
-#define CX24116_HAS_SIGNAL   (0x01)
-#define CX24116_HAS_CARRIER  (0x02)
-#define CX24116_HAS_VITERBI  (0x04)
-#define CX24116_HAS_SYNCLOCK (0x08)
-#define CX24116_HAS_UNKNOWN1 (0x10)
-#define CX24116_HAS_UNKNOWN2 (0x20)
-#define CX24116_STATUS_MASK  (0x0f)
-#define CX24116_SIGNAL_MASK  (0xc0)
-
-#define CX24116_DISEQC_TONEOFF   (0)    /* toneburst never sent */
-#define CX24116_DISEQC_TONECACHE (1)    /* toneburst cached     */
-#define CX24116_DISEQC_MESGCACHE (2)    /* message cached       */
-
-/* arg offset for DiSEqC */
-#define CX24116_DISEQC_BURST  (1)
-#define CX24116_DISEQC_ARG2_2 (2)   /* unknown value=2 */
-#define CX24116_DISEQC_ARG3_0 (3)   /* unknown value=0 */
-#define CX24116_DISEQC_ARG4_0 (4)   /* unknown value=0 */
-#define CX24116_DISEQC_MSGLEN (5)
-#define CX24116_DISEQC_MSGOFS (6)
-
-/* DiSEqC burst */
-#define CX24116_DISEQC_MINI_A (0)
-#define CX24116_DISEQC_MINI_B (1)
-
-/* DiSEqC tone burst */
-static int toneburst = 1;
-module_param(toneburst, int, 0644);
-MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
-       "2=MESSAGE CACHE (default:1)");
-
-/* SNR measurements */
-static int esno_snr;
-module_param(esno_snr, int, 0644);
-MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
-       "1=ESNO(db * 10) (default:0)");
-
-enum cmds {
-       CMD_SET_VCO     = 0x10,
-       CMD_TUNEREQUEST = 0x11,
-       CMD_MPEGCONFIG  = 0x13,
-       CMD_TUNERINIT   = 0x14,
-       CMD_BANDWIDTH   = 0x15,
-       CMD_GETAGC      = 0x19,
-       CMD_LNBCONFIG   = 0x20,
-       CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
-       CMD_LNBDCLEVEL  = 0x22,
-       CMD_SET_TONE    = 0x23,
-       CMD_UPDFWVERS   = 0x35,
-       CMD_TUNERSLEEP  = 0x36,
-       CMD_AGCCONTROL  = 0x3b, /* Unknown */
-};
-
-/* The Demod/Tuner can't easily provide these, we cache them */
-struct cx24116_tuning {
-       u32 frequency;
-       u32 symbol_rate;
-       fe_spectral_inversion_t inversion;
-       fe_code_rate_t fec;
-
-       fe_delivery_system_t delsys;
-       fe_modulation_t modulation;
-       fe_pilot_t pilot;
-       fe_rolloff_t rolloff;
-
-       /* Demod values */
-       u8 fec_val;
-       u8 fec_mask;
-       u8 inversion_val;
-       u8 pilot_val;
-       u8 rolloff_val;
-};
-
-/* Basic commands that are sent to the firmware */
-struct cx24116_cmd {
-       u8 len;
-       u8 args[CX24116_ARGLEN];
-};
-
-struct cx24116_state {
-       struct i2c_adapter *i2c;
-       const struct cx24116_config *config;
-
-       struct dvb_frontend frontend;
-
-       struct cx24116_tuning dcur;
-       struct cx24116_tuning dnxt;
-
-       u8 skip_fw_load;
-       u8 burst;
-       struct cx24116_cmd dsec_cmd;
-};
-
-static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-               .flags = 0, .buf = buf, .len = 2 };
-       int err;
-
-       if (debug > 1)
-               printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
-                       __func__, reg, data);
-
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
-                        " value == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-/* Bulk byte writes to a single I2C address, for 32k firmware load */
-static int cx24116_writeregN(struct cx24116_state *state, int reg,
-                            const u8 *data, u16 len)
-{
-       int ret = -EREMOTEIO;
-       struct i2c_msg msg;
-       u8 *buf;
-
-       buf = kmalloc(len + 1, GFP_KERNEL);
-       if (buf == NULL) {
-               printk("Unable to kmalloc\n");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       *(buf) = reg;
-       memcpy(buf + 1, data, len);
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.buf = buf;
-       msg.len = len + 1;
-
-       if (debug > 1)
-               printk(KERN_INFO "cx24116: %s:  write regN 0x%02x, len = %d\n",
-                       __func__, reg, len);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-       if (ret != 1) {
-               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
-                        __func__, ret, reg);
-               ret = -EREMOTEIO;
-       }
-
-error:
-       kfree(buf);
-
-       return ret;
-}
-
-static int cx24116_readreg(struct cx24116_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0,
-                       .buf = b0, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD,
-                       .buf = b1, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
-                       __func__, reg, ret);
-               return ret;
-       }
-
-       if (debug > 1)
-               printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
-                       reg, b1[0]);
-
-       return b1[0];
-}
-
-static int cx24116_set_inversion(struct cx24116_state *state,
-       fe_spectral_inversion_t inversion)
-{
-       dprintk("%s(%d)\n", __func__, inversion);
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               state->dnxt.inversion_val = 0x00;
-               break;
-       case INVERSION_ON:
-               state->dnxt.inversion_val = 0x04;
-               break;
-       case INVERSION_AUTO:
-               state->dnxt.inversion_val = 0x0C;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       state->dnxt.inversion = inversion;
-
-       return 0;
-}
-
-/*
- * modfec (modulation and FEC)
- * ===========================
- *
- * MOD          FEC             mask/val    standard
- * ----         --------        ----------- --------
- * QPSK         FEC_1_2         0x02 0x02+X DVB-S
- * QPSK         FEC_2_3         0x04 0x02+X DVB-S
- * QPSK         FEC_3_4         0x08 0x02+X DVB-S
- * QPSK         FEC_4_5         0x10 0x02+X DVB-S (?)
- * QPSK         FEC_5_6         0x20 0x02+X DVB-S
- * QPSK         FEC_6_7         0x40 0x02+X DVB-S
- * QPSK         FEC_7_8         0x80 0x02+X DVB-S
- * QPSK         FEC_8_9         0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
- * QPSK         AUTO            0xff 0x02+X DVB-S
- *
- * For DVB-S high byte probably represents FEC
- * and low byte selects the modulator. The high
- * byte is search range mask. Bit 5 may turn
- * on DVB-S and remaining bits represent some
- * kind of calibration (how/what i do not know).
- *
- * Eg.(2/3) szap "Zone Horror"
- *
- * mask/val = 0x04, 0x20
- * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
- *
- * mask/val = 0x04, 0x30
- * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
- *
- * After tuning FECSTATUS contains actual FEC
- * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
- *
- * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
- *
- * NBC-QPSK     FEC_1_2         0x00, 0x04      DVB-S2
- * NBC-QPSK     FEC_3_5         0x00, 0x05      DVB-S2
- * NBC-QPSK     FEC_2_3         0x00, 0x06      DVB-S2
- * NBC-QPSK     FEC_3_4         0x00, 0x07      DVB-S2
- * NBC-QPSK     FEC_4_5         0x00, 0x08      DVB-S2
- * NBC-QPSK     FEC_5_6         0x00, 0x09      DVB-S2
- * NBC-QPSK     FEC_8_9         0x00, 0x0a      DVB-S2
- * NBC-QPSK     FEC_9_10        0x00, 0x0b      DVB-S2
- *
- * NBC-8PSK     FEC_3_5         0x00, 0x0c      DVB-S2
- * NBC-8PSK     FEC_2_3         0x00, 0x0d      DVB-S2
- * NBC-8PSK     FEC_3_4         0x00, 0x0e      DVB-S2
- * NBC-8PSK     FEC_5_6         0x00, 0x0f      DVB-S2
- * NBC-8PSK     FEC_8_9         0x00, 0x10      DVB-S2
- * NBC-8PSK     FEC_9_10        0x00, 0x11      DVB-S2
- *
- * For DVB-S2 low bytes selects both modulator
- * and FEC. High byte is meaningless here. To
- * set pilot, bit 6 (0x40) is set. When inspecting
- * FECSTATUS bit 7 (0x80) represents the pilot
- * selection whilst not tuned. When tuned, actual FEC
- * in use is found in FECSTATUS as per above. Pilot
- * value is reset.
- */
-
-/* A table of modulation, fec and configuration bytes for the demod.
- * Not all S2 mmodulation schemes are support and not all rates with
- * a scheme are support. Especially, no auto detect when in S2 mode.
- */
-static struct cx24116_modfec {
-       fe_delivery_system_t delivery_system;
-       fe_modulation_t modulation;
-       fe_code_rate_t fec;
-       u8 mask;        /* In DVBS mode this is used to autodetect */
-       u8 val;         /* Passed to the firmware to indicate mode selection */
-} CX24116_MODFEC_MODES[] = {
- /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
-
- /*mod   fec       mask  val */
- { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
- { SYS_DVBS, QPSK, FEC_1_2,  0x02, 0x2e }, /* 00000010 00101110 */
- { SYS_DVBS, QPSK, FEC_2_3,  0x04, 0x2f }, /* 00000100 00101111 */
- { SYS_DVBS, QPSK, FEC_3_4,  0x08, 0x30 }, /* 00001000 00110000 */
- { SYS_DVBS, QPSK, FEC_4_5,  0xfe, 0x30 }, /* 000?0000 ?        */
- { SYS_DVBS, QPSK, FEC_5_6,  0x20, 0x31 }, /* 00100000 00110001 */
- { SYS_DVBS, QPSK, FEC_6_7,  0xfe, 0x30 }, /* 0?000000 ?        */
- { SYS_DVBS, QPSK, FEC_7_8,  0x80, 0x32 }, /* 10000000 00110010 */
- { SYS_DVBS, QPSK, FEC_8_9,  0xfe, 0x30 }, /* 0000000? ?        */
- { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
- /* NBC-QPSK */
- { SYS_DVBS2, QPSK, FEC_1_2,  0x00, 0x04 },
- { SYS_DVBS2, QPSK, FEC_3_5,  0x00, 0x05 },
- { SYS_DVBS2, QPSK, FEC_2_3,  0x00, 0x06 },
- { SYS_DVBS2, QPSK, FEC_3_4,  0x00, 0x07 },
- { SYS_DVBS2, QPSK, FEC_4_5,  0x00, 0x08 },
- { SYS_DVBS2, QPSK, FEC_5_6,  0x00, 0x09 },
- { SYS_DVBS2, QPSK, FEC_8_9,  0x00, 0x0a },
- { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
- /* 8PSK */
- { SYS_DVBS2, PSK_8, FEC_3_5,  0x00, 0x0c },
- { SYS_DVBS2, PSK_8, FEC_2_3,  0x00, 0x0d },
- { SYS_DVBS2, PSK_8, FEC_3_4,  0x00, 0x0e },
- { SYS_DVBS2, PSK_8, FEC_5_6,  0x00, 0x0f },
- { SYS_DVBS2, PSK_8, FEC_8_9,  0x00, 0x10 },
- { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
- /*
-  * `val' can be found in the FECSTATUS register when tuning.
-  * FECSTATUS will give the actual FEC in use if tuning was successful.
-  */
-};
-
-static int cx24116_lookup_fecmod(struct cx24116_state *state,
-       fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
-{
-       int i, ret = -EOPNOTSUPP;
-
-       dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
-
-       for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
-               if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
-                       (m == CX24116_MODFEC_MODES[i].modulation) &&
-                       (f == CX24116_MODFEC_MODES[i].fec)) {
-                               ret = i;
-                               break;
-                       }
-       }
-
-       return ret;
-}
-
-static int cx24116_set_fec(struct cx24116_state *state,
-       fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
-{
-       int ret = 0;
-
-       dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
-
-       ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
-
-       if (ret < 0)
-               return ret;
-
-       state->dnxt.fec = fec;
-       state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
-       state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
-       dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
-               state->dnxt.fec_mask, state->dnxt.fec_val);
-
-       return 0;
-}
-
-static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
-{
-       dprintk("%s(%d)\n", __func__, rate);
-
-       /*  check if symbol rate is within limits */
-       if ((rate > state->frontend.ops.info.symbol_rate_max) ||
-           (rate < state->frontend.ops.info.symbol_rate_min)) {
-               dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
-               return -EOPNOTSUPP;
-       }
-
-       state->dnxt.symbol_rate = rate;
-       dprintk("%s() symbol_rate = %d\n", __func__, rate);
-
-       return 0;
-}
-
-static int cx24116_load_firmware(struct dvb_frontend *fe,
-       const struct firmware *fw);
-
-static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret = 0;
-
-       dprintk("%s()\n", __func__);
-
-       if (cx24116_readreg(state, 0x20) > 0) {
-
-               if (state->skip_fw_load)
-                       return 0;
-
-               /* Load firmware */
-               /* request the firmware, this will block until loaded */
-               printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
-                       __func__, CX24116_DEFAULT_FIRMWARE);
-               ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
-                       state->i2c->dev.parent);
-               printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
-                       __func__);
-               if (ret) {
-                       printk(KERN_ERR "%s: No firmware uploaded "
-                               "(timeout or file not found?)\n", __func__);
-                       return ret;
-               }
-
-               /* Make sure we don't recurse back through here
-                * during loading */
-               state->skip_fw_load = 1;
-
-               ret = cx24116_load_firmware(fe, fw);
-               if (ret)
-                       printk(KERN_ERR "%s: Writing firmware to device failed\n",
-                               __func__);
-
-               release_firmware(fw);
-
-               printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
-                       ret == 0 ? "complete" : "failed");
-
-               /* Ensure firmware is always loaded if required */
-               state->skip_fw_load = 0;
-       }
-
-       return ret;
-}
-
-/* Take a basic firmware command structure, format it
- * and forward it for processing
- */
-static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       int i, ret;
-
-       dprintk("%s()\n", __func__);
-
-       /* Load the firmware if required */
-       ret = cx24116_firmware_ondemand(fe);
-       if (ret != 0) {
-               printk(KERN_ERR "%s(): Unable initialise the firmware\n",
-                       __func__);
-               return ret;
-       }
-
-       /* Write the command */
-       for (i = 0; i < cmd->len ; i++) {
-               dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
-               cx24116_writereg(state, i, cmd->args[i]);
-       }
-
-       /* Start execution and wait for cmd to terminate */
-       cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
-       while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
-               msleep(10);
-               if (i++ > 64) {
-                       /* Avoid looping forever if the firmware does
-                               not respond */
-                       printk(KERN_WARNING "%s() Firmware not responding\n",
-                               __func__);
-                       return -EREMOTEIO;
-               }
-       }
-       return 0;
-}
-
-static int cx24116_load_firmware(struct dvb_frontend *fe,
-       const struct firmware *fw)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct cx24116_cmd cmd;
-       int i, ret, len, max, remaining;
-       unsigned char vers[4];
-
-       dprintk("%s\n", __func__);
-       dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
-                       fw->size,
-                       fw->data[0],
-                       fw->data[1],
-                       fw->data[fw->size-2],
-                       fw->data[fw->size-1]);
-
-       /* Toggle 88x SRST pin to reset demod */
-       if (state->config->reset_device)
-               state->config->reset_device(fe);
-
-       /* Begin the firmware load process */
-       /* Prepare the demod, load the firmware, cleanup after load */
-
-       /* Init PLL */
-       cx24116_writereg(state, 0xE5, 0x00);
-       cx24116_writereg(state, 0xF1, 0x08);
-       cx24116_writereg(state, 0xF2, 0x13);
-
-       /* Start PLL */
-       cx24116_writereg(state, 0xe0, 0x03);
-       cx24116_writereg(state, 0xe0, 0x00);
-
-       /* Unknown */
-       cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
-       cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
-
-       /* Unknown */
-       cx24116_writereg(state, 0xF0, 0x03);
-       cx24116_writereg(state, 0xF4, 0x81);
-       cx24116_writereg(state, 0xF5, 0x00);
-       cx24116_writereg(state, 0xF6, 0x00);
-
-       /* Split firmware to the max I2C write len and write.
-        * Writes whole firmware as one write when i2c_wr_max is set to 0. */
-       if (state->config->i2c_wr_max)
-               max = state->config->i2c_wr_max;
-       else
-               max = INT_MAX; /* enough for 32k firmware */
-
-       for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
-               len = remaining;
-               if (len > max - 1)
-                       len = max - 1;
-
-               cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
-                       len);
-       }
-
-       cx24116_writereg(state, 0xF4, 0x10);
-       cx24116_writereg(state, 0xF0, 0x00);
-       cx24116_writereg(state, 0xF8, 0x06);
-
-       /* Firmware CMD 10: VCO config */
-       cmd.args[0x00] = CMD_SET_VCO;
-       cmd.args[0x01] = 0x05;
-       cmd.args[0x02] = 0xdc;
-       cmd.args[0x03] = 0xda;
-       cmd.args[0x04] = 0xae;
-       cmd.args[0x05] = 0xaa;
-       cmd.args[0x06] = 0x04;
-       cmd.args[0x07] = 0x9d;
-       cmd.args[0x08] = 0xfc;
-       cmd.args[0x09] = 0x06;
-       cmd.len = 0x0a;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
-
-       /* Firmware CMD 14: Tuner config */
-       cmd.args[0x00] = CMD_TUNERINIT;
-       cmd.args[0x01] = 0x00;
-       cmd.args[0x02] = 0x00;
-       cmd.len = 0x03;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       cx24116_writereg(state, 0xe5, 0x00);
-
-       /* Firmware CMD 13: MPEG config */
-       cmd.args[0x00] = CMD_MPEGCONFIG;
-       cmd.args[0x01] = 0x01;
-       cmd.args[0x02] = 0x75;
-       cmd.args[0x03] = 0x00;
-       if (state->config->mpg_clk_pos_pol)
-               cmd.args[0x04] = state->config->mpg_clk_pos_pol;
-       else
-               cmd.args[0x04] = 0x02;
-       cmd.args[0x05] = 0x00;
-       cmd.len = 0x06;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       /* Firmware CMD 35: Get firmware version */
-       cmd.args[0x00] = CMD_UPDFWVERS;
-       cmd.len = 0x02;
-       for (i = 0; i < 4; i++) {
-               cmd.args[0x01] = i;
-               ret = cx24116_cmd_execute(fe, &cmd);
-               if (ret != 0)
-                       return ret;
-               vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
-       }
-       printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
-               vers[0], vers[1], vers[2], vers[3]);
-
-       return 0;
-}
-
-static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-
-       int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
-               CX24116_STATUS_MASK;
-
-       dprintk("%s: status = 0x%02x\n", __func__, lock);
-
-       *status = 0;
-
-       if (lock & CX24116_HAS_SIGNAL)
-               *status |= FE_HAS_SIGNAL;
-       if (lock & CX24116_HAS_CARRIER)
-               *status |= FE_HAS_CARRIER;
-       if (lock & CX24116_HAS_VITERBI)
-               *status |= FE_HAS_VITERBI;
-       if (lock & CX24116_HAS_SYNCLOCK)
-               *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       *ber =  (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
-               (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
-               (cx24116_readreg(state, CX24116_REG_BER8)  << 8)  |
-                cx24116_readreg(state, CX24116_REG_BER0);
-
-       return 0;
-}
-
-/* TODO Determine function and scale appropriately */
-static int cx24116_read_signal_strength(struct dvb_frontend *fe,
-       u16 *signal_strength)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct cx24116_cmd cmd;
-       int ret;
-       u16 sig_reading;
-
-       dprintk("%s()\n", __func__);
-
-       /* Firmware CMD 19: Get AGC */
-       cmd.args[0x00] = CMD_GETAGC;
-       cmd.len = 0x01;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       sig_reading =
-               (cx24116_readreg(state,
-                       CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
-               (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
-       *signal_strength = 0 - sig_reading;
-
-       dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
-               __func__, sig_reading, *signal_strength);
-
-       return 0;
-}
-
-/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
-static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       u8 snr_reading;
-       static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
-               0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
-               0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
-               0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
-               0x18000 };
-
-       dprintk("%s()\n", __func__);
-
-       snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
-
-       if (snr_reading >= 0xa0 /* 100% */)
-               *snr = 0xffff;
-       else
-               *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
-                       (snr_tab[(snr_reading & 0x0f)] >> 4);
-
-       dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
-               snr_reading, *snr);
-
-       return 0;
-}
-
-/* The reelbox patches show the value in the registers represents
- * ESNO, from 0->30db (values 0->300). We provide this value by
- * default.
- */
-static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
-               cx24116_readreg(state, CX24116_REG_QUALITY0);
-
-       dprintk("%s: raw 0x%04x\n", __func__, *snr);
-
-       return 0;
-}
-
-static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       if (esno_snr == 1)
-               return cx24116_read_snr_esno(fe, snr);
-       else
-               return cx24116_read_snr_pct(fe, snr);
-}
-
-static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
-               cx24116_readreg(state, CX24116_REG_UCB0);
-
-       return 0;
-}
-
-/* Overwrite the current tuning params, we are about to tune */
-static void cx24116_clone_params(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
-}
-
-/* Wait for LNB */
-static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       int i;
-
-       dprintk("%s() qstatus = 0x%02x\n", __func__,
-               cx24116_readreg(state, CX24116_REG_QSTATUS));
-
-       /* Wait for up to 300 ms */
-       for (i = 0; i < 30 ; i++) {
-               if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
-                       return 0;
-               msleep(10);
-       }
-
-       dprintk("%s(): LNB not ready\n", __func__);
-
-       return -ETIMEDOUT; /* -EBUSY ? */
-}
-
-static int cx24116_set_voltage(struct dvb_frontend *fe,
-       fe_sec_voltage_t voltage)
-{
-       struct cx24116_cmd cmd;
-       int ret;
-
-       dprintk("%s: %s\n", __func__,
-               voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
-               voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
-
-       /* Wait for LNB ready */
-       ret = cx24116_wait_for_lnb(fe);
-       if (ret != 0)
-               return ret;
-
-       /* Wait for voltage/min repeat delay */
-       msleep(100);
-
-       cmd.args[0x00] = CMD_LNBDCLEVEL;
-       cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
-       cmd.len = 0x02;
-
-       /* Min delay time before DiSEqC send */
-       msleep(15);
-
-       return cx24116_cmd_execute(fe, &cmd);
-}
-
-static int cx24116_set_tone(struct dvb_frontend *fe,
-       fe_sec_tone_mode_t tone)
-{
-       struct cx24116_cmd cmd;
-       int ret;
-
-       dprintk("%s(%d)\n", __func__, tone);
-       if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
-               printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
-               return -EINVAL;
-       }
-
-       /* Wait for LNB ready */
-       ret = cx24116_wait_for_lnb(fe);
-       if (ret != 0)
-               return ret;
-
-       /* Min delay time after DiSEqC send */
-       msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
-
-       /* Now we set the tone */
-       cmd.args[0x00] = CMD_SET_TONE;
-       cmd.args[0x01] = 0x00;
-       cmd.args[0x02] = 0x00;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               dprintk("%s: setting tone on\n", __func__);
-               cmd.args[0x03] = 0x01;
-               break;
-       case SEC_TONE_OFF:
-               dprintk("%s: setting tone off\n", __func__);
-               cmd.args[0x03] = 0x00;
-               break;
-       }
-       cmd.len = 0x04;
-
-       /* Min delay time before DiSEqC send */
-       msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
-
-       return cx24116_cmd_execute(fe, &cmd);
-}
-
-/* Initialise DiSEqC */
-static int cx24116_diseqc_init(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct cx24116_cmd cmd;
-       int ret;
-
-       /* Firmware CMD 20: LNB/DiSEqC config */
-       cmd.args[0x00] = CMD_LNBCONFIG;
-       cmd.args[0x01] = 0x00;
-       cmd.args[0x02] = 0x10;
-       cmd.args[0x03] = 0x00;
-       cmd.args[0x04] = 0x8f;
-       cmd.args[0x05] = 0x28;
-       cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
-       cmd.args[0x07] = 0x01;
-       cmd.len = 0x08;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       /* Prepare a DiSEqC command */
-       state->dsec_cmd.args[0x00] = CMD_LNBSEND;
-
-       /* DiSEqC burst */
-       state->dsec_cmd.args[CX24116_DISEQC_BURST]  = CX24116_DISEQC_MINI_A;
-
-       /* Unknown */
-       state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
-       state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
-       /* Continuation flag? */
-       state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
-
-       /* DiSEqC message length */
-       state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
-
-       /* Command length */
-       state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
-
-       return 0;
-}
-
-/* Send DiSEqC message with derived burst (hack) || previous burst */
-static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
-       struct dvb_diseqc_master_cmd *d)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       int i, ret;
-
-       /* Dump DiSEqC message */
-       if (debug) {
-               printk(KERN_INFO "cx24116: %s(", __func__);
-               for (i = 0 ; i < d->msg_len ;) {
-                       printk(KERN_INFO "0x%02x", d->msg[i]);
-                       if (++i < d->msg_len)
-                               printk(KERN_INFO ", ");
-               }
-               printk(") toneburst=%d\n", toneburst);
-       }
-
-       /* Validate length */
-       if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
-               return -EINVAL;
-
-       /* DiSEqC message */
-       for (i = 0; i < d->msg_len; i++)
-               state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
-
-       /* DiSEqC message length */
-       state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
-
-       /* Command length */
-       state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
-               state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
-
-       /* DiSEqC toneburst */
-       if (toneburst == CX24116_DISEQC_MESGCACHE)
-               /* Message is cached */
-               return 0;
-
-       else if (toneburst == CX24116_DISEQC_TONEOFF)
-               /* Message is sent without burst */
-               state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
-
-       else if (toneburst == CX24116_DISEQC_TONECACHE) {
-               /*
-                * Message is sent with derived else cached burst
-                *
-                * WRITE PORT GROUP COMMAND 38
-                *
-                * 0/A/A: E0 10 38 F0..F3
-                * 1/B/B: E0 10 38 F4..F7
-                * 2/C/A: E0 10 38 F8..FB
-                * 3/D/B: E0 10 38 FC..FF
-                *
-                * databyte[3]= 8421:8421
-                *              ABCD:WXYZ
-                *              CLR :SET
-                *
-                *              WX= PORT SELECT 0..3    (X=TONEBURST)
-                *              Y = VOLTAGE             (0=13V, 1=18V)
-                *              Z = BAND                (0=LOW, 1=HIGH(22K))
-                */
-               if (d->msg_len >= 4 && d->msg[2] == 0x38)
-                       state->dsec_cmd.args[CX24116_DISEQC_BURST] =
-                               ((d->msg[3] & 4) >> 2);
-               if (debug)
-                       dprintk("%s burst=%d\n", __func__,
-                               state->dsec_cmd.args[CX24116_DISEQC_BURST]);
-       }
-
-       /* Wait for LNB ready */
-       ret = cx24116_wait_for_lnb(fe);
-       if (ret != 0)
-               return ret;
-
-       /* Wait for voltage/min repeat delay */
-       msleep(100);
-
-       /* Command */
-       ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
-       if (ret != 0)
-               return ret;
-       /*
-        * Wait for send
-        *
-        * Eutelsat spec:
-        * >15ms delay          + (XXX determine if FW does this, see set_tone)
-        *  13.5ms per byte     +
-        * >15ms delay          +
-        *  12.5ms burst        +
-        * >15ms delay            (XXX determine if FW does this, see set_tone)
-        */
-       msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
-               ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
-
-       return 0;
-}
-
-/* Send DiSEqC burst */
-static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
-       fe_sec_mini_cmd_t burst)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       int ret;
-
-       dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
-
-       /* DiSEqC burst */
-       if (burst == SEC_MINI_A)
-               state->dsec_cmd.args[CX24116_DISEQC_BURST] =
-                       CX24116_DISEQC_MINI_A;
-       else if (burst == SEC_MINI_B)
-               state->dsec_cmd.args[CX24116_DISEQC_BURST] =
-                       CX24116_DISEQC_MINI_B;
-       else
-               return -EINVAL;
-
-       /* DiSEqC toneburst */
-       if (toneburst != CX24116_DISEQC_MESGCACHE)
-               /* Burst is cached */
-               return 0;
-
-       /* Burst is to be sent with cached message */
-
-       /* Wait for LNB ready */
-       ret = cx24116_wait_for_lnb(fe);
-       if (ret != 0)
-               return ret;
-
-       /* Wait for voltage/min repeat delay */
-       msleep(100);
-
-       /* Command */
-       ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
-       if (ret != 0)
-               return ret;
-
-       /*
-        * Wait for send
-        *
-        * Eutelsat spec:
-        * >15ms delay          + (XXX determine if FW does this, see set_tone)
-        *  13.5ms per byte     +
-        * >15ms delay          +
-        *  12.5ms burst        +
-        * >15ms delay            (XXX determine if FW does this, see set_tone)
-        */
-       msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
-
-       return 0;
-}
-
-static void cx24116_release(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       dprintk("%s\n", __func__);
-       kfree(state);
-}
-
-static struct dvb_frontend_ops cx24116_ops;
-
-struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
-       struct i2c_adapter *i2c)
-{
-       struct cx24116_state *state = NULL;
-       int ret;
-
-       dprintk("%s\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error1;
-
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is present */
-       ret = (cx24116_readreg(state, 0xFF) << 8) |
-               cx24116_readreg(state, 0xFE);
-       if (ret != 0x0501) {
-               printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
-               goto error2;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &cx24116_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error2: kfree(state);
-error1: return NULL;
-}
-EXPORT_SYMBOL(cx24116_attach);
-
-/*
- * Initialise or wake up device
- *
- * Power config will reset and load initial firmware if required
- */
-static int cx24116_initfe(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct cx24116_cmd cmd;
-       int ret;
-
-       dprintk("%s()\n", __func__);
-
-       /* Power on */
-       cx24116_writereg(state, 0xe0, 0);
-       cx24116_writereg(state, 0xe1, 0);
-       cx24116_writereg(state, 0xea, 0);
-
-       /* Firmware CMD 36: Power config */
-       cmd.args[0x00] = CMD_TUNERSLEEP;
-       cmd.args[0x01] = 0;
-       cmd.len = 0x02;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       ret = cx24116_diseqc_init(fe);
-       if (ret != 0)
-               return ret;
-
-       /* HVR-4000 needs this */
-       return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
-}
-
-/*
- * Put device to sleep
- */
-static int cx24116_sleep(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct cx24116_cmd cmd;
-       int ret;
-
-       dprintk("%s()\n", __func__);
-
-       /* Firmware CMD 36: Power config */
-       cmd.args[0x00] = CMD_TUNERSLEEP;
-       cmd.args[0x01] = 1;
-       cmd.len = 0x02;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       /* Power off (Shutdown clocks) */
-       cx24116_writereg(state, 0xea, 0xff);
-       cx24116_writereg(state, 0xe1, 1);
-       cx24116_writereg(state, 0xe0, 1);
-
-       return 0;
-}
-
-/* dvb-core told us to tune, the tv property cache will be complete,
- * it's safe for is to pull values and use them for tuning purposes.
- */
-static int cx24116_set_frontend(struct dvb_frontend *fe)
-{
-       struct cx24116_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct cx24116_cmd cmd;
-       fe_status_t tunerstat;
-       int i, status, ret, retune = 1;
-
-       dprintk("%s()\n", __func__);
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               dprintk("%s: DVB-S delivery system selected\n", __func__);
-
-               /* Only QPSK is supported for DVB-S */
-               if (c->modulation != QPSK) {
-                       dprintk("%s: unsupported modulation selected (%d)\n",
-                               __func__, c->modulation);
-                       return -EOPNOTSUPP;
-               }
-
-               /* Pilot doesn't exist in DVB-S, turn bit off */
-               state->dnxt.pilot_val = CX24116_PILOT_OFF;
-
-               /* DVB-S only supports 0.35 */
-               if (c->rolloff != ROLLOFF_35) {
-                       dprintk("%s: unsupported rolloff selected (%d)\n",
-                               __func__, c->rolloff);
-                       return -EOPNOTSUPP;
-               }
-               state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
-               break;
-
-       case SYS_DVBS2:
-               dprintk("%s: DVB-S2 delivery system selected\n", __func__);
-
-               /*
-                * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
-                * but not hardware auto detection
-                */
-               if (c->modulation != PSK_8 && c->modulation != QPSK) {
-                       dprintk("%s: unsupported modulation selected (%d)\n",
-                               __func__, c->modulation);
-                       return -EOPNOTSUPP;
-               }
-
-               switch (c->pilot) {
-               case PILOT_AUTO:        /* Not supported but emulated */
-                       state->dnxt.pilot_val = (c->modulation == QPSK)
-                               ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
-                       retune++;
-                       break;
-               case PILOT_OFF:
-                       state->dnxt.pilot_val = CX24116_PILOT_OFF;
-                       break;
-               case PILOT_ON:
-                       state->dnxt.pilot_val = CX24116_PILOT_ON;
-                       break;
-               default:
-                       dprintk("%s: unsupported pilot mode selected (%d)\n",
-                               __func__, c->pilot);
-                       return -EOPNOTSUPP;
-               }
-
-               switch (c->rolloff) {
-               case ROLLOFF_20:
-                       state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
-                       break;
-               case ROLLOFF_25:
-                       state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
-                       break;
-               case ROLLOFF_35:
-                       state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
-                       break;
-               case ROLLOFF_AUTO:      /* Rolloff must be explicit */
-               default:
-                       dprintk("%s: unsupported rolloff selected (%d)\n",
-                               __func__, c->rolloff);
-                       return -EOPNOTSUPP;
-               }
-               break;
-
-       default:
-               dprintk("%s: unsupported delivery system selected (%d)\n",
-                       __func__, c->delivery_system);
-               return -EOPNOTSUPP;
-       }
-       state->dnxt.delsys = c->delivery_system;
-       state->dnxt.modulation = c->modulation;
-       state->dnxt.frequency = c->frequency;
-       state->dnxt.pilot = c->pilot;
-       state->dnxt.rolloff = c->rolloff;
-
-       ret = cx24116_set_inversion(state, c->inversion);
-       if (ret !=  0)
-               return ret;
-
-       /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
-       ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
-       if (ret !=  0)
-               return ret;
-
-       ret = cx24116_set_symbolrate(state, c->symbol_rate);
-       if (ret !=  0)
-               return ret;
-
-       /* discard the 'current' tuning parameters and prepare to tune */
-       cx24116_clone_params(fe);
-
-       dprintk("%s:   delsys      = %d\n", __func__, state->dcur.delsys);
-       dprintk("%s:   modulation  = %d\n", __func__, state->dcur.modulation);
-       dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
-       dprintk("%s:   pilot       = %d (val = 0x%02x)\n", __func__,
-               state->dcur.pilot, state->dcur.pilot_val);
-       dprintk("%s:   retune      = %d\n", __func__, retune);
-       dprintk("%s:   rolloff     = %d (val = 0x%02x)\n", __func__,
-               state->dcur.rolloff, state->dcur.rolloff_val);
-       dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
-       dprintk("%s:   FEC         = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
-               state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
-       dprintk("%s:   Inversion   = %d (val = 0x%02x)\n", __func__,
-               state->dcur.inversion, state->dcur.inversion_val);
-
-       /* This is also done in advise/acquire on HVR4000 but not on LITE */
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-
-       /* Set/Reset B/W */
-       cmd.args[0x00] = CMD_BANDWIDTH;
-       cmd.args[0x01] = 0x01;
-       cmd.len = 0x02;
-       ret = cx24116_cmd_execute(fe, &cmd);
-       if (ret != 0)
-               return ret;
-
-       /* Prepare a tune request */
-       cmd.args[0x00] = CMD_TUNEREQUEST;
-
-       /* Frequency */
-       cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
-       cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
-       cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
-
-       /* Symbol Rate */
-       cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
-       cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
-
-       /* Automatic Inversion */
-       cmd.args[0x06] = state->dcur.inversion_val;
-
-       /* Modulation / FEC / Pilot */
-       cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
-
-       cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
-       cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
-       cmd.args[0x0a] = 0x00;
-       cmd.args[0x0b] = 0x00;
-       cmd.args[0x0c] = state->dcur.rolloff_val;
-       cmd.args[0x0d] = state->dcur.fec_mask;
-
-       if (state->dcur.symbol_rate > 30000000) {
-               cmd.args[0x0e] = 0x04;
-               cmd.args[0x0f] = 0x00;
-               cmd.args[0x10] = 0x01;
-               cmd.args[0x11] = 0x77;
-               cmd.args[0x12] = 0x36;
-               cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
-               cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
-       } else {
-               cmd.args[0x0e] = 0x06;
-               cmd.args[0x0f] = 0x00;
-               cmd.args[0x10] = 0x00;
-               cmd.args[0x11] = 0xFA;
-               cmd.args[0x12] = 0x24;
-               cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
-               cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
-       }
-
-       cmd.len = 0x13;
-
-       /* We need to support pilot and non-pilot tuning in the
-        * driver automatically. This is a workaround for because
-        * the demod does not support autodetect.
-        */
-       do {
-               /* Reset status register */
-               status = cx24116_readreg(state, CX24116_REG_SSTATUS)
-                       & CX24116_SIGNAL_MASK;
-               cx24116_writereg(state, CX24116_REG_SSTATUS, status);
-
-               /* Tune */
-               ret = cx24116_cmd_execute(fe, &cmd);
-               if (ret != 0)
-                       break;
-
-               /*
-                * Wait for up to 500 ms before retrying
-                *
-                * If we are able to tune then generally it occurs within 100ms.
-                * If it takes longer, try a different toneburst setting.
-                */
-               for (i = 0; i < 50 ; i++) {
-                       cx24116_read_status(fe, &tunerstat);
-                       status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
-                       if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
-                               dprintk("%s: Tuned\n", __func__);
-                               goto tuned;
-                       }
-                       msleep(10);
-               }
-
-               dprintk("%s: Not tuned\n", __func__);
-
-               /* Toggle pilot bit when in auto-pilot */
-               if (state->dcur.pilot == PILOT_AUTO)
-                       cmd.args[0x07] ^= CX24116_PILOT_ON;
-       } while (--retune);
-
-tuned:  /* Set/Reset B/W */
-       cmd.args[0x00] = CMD_BANDWIDTH;
-       cmd.args[0x01] = 0x00;
-       cmd.len = 0x02;
-       return cx24116_cmd_execute(fe, &cmd);
-}
-
-static int cx24116_tune(struct dvb_frontend *fe, bool re_tune,
-       unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
-{
-       /*
-        * It is safe to discard "params" here, as the DVB core will sync
-        * fe->dtv_property_cache with fepriv->parameters_in, where the
-        * DVBv3 params are stored. The only practical usage for it indicate
-        * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is
-        * true.
-        */
-
-       *delay = HZ / 5;
-       if (re_tune) {
-               int ret = cx24116_set_frontend(fe);
-               if (ret)
-                       return ret;
-       }
-       return cx24116_read_status(fe, status);
-}
-
-static int cx24116_get_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_HW;
-}
-
-static struct dvb_frontend_ops cx24116_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2 },
-       .info = {
-               .name = "Conexant CX24116/CX24118",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
-               .frequency_tolerance = 5000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_2G_MODULATION |
-                       FE_CAN_QPSK | FE_CAN_RECOVER
-       },
-
-       .release = cx24116_release,
-
-       .init = cx24116_initfe,
-       .sleep = cx24116_sleep,
-       .read_status = cx24116_read_status,
-       .read_ber = cx24116_read_ber,
-       .read_signal_strength = cx24116_read_signal_strength,
-       .read_snr = cx24116_read_snr,
-       .read_ucblocks = cx24116_read_ucblocks,
-       .set_tone = cx24116_set_tone,
-       .set_voltage = cx24116_set_voltage,
-       .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
-       .diseqc_send_burst = cx24116_diseqc_send_burst,
-       .get_frontend_algo = cx24116_get_algo,
-       .tune = cx24116_tune,
-
-       .set_frontend = cx24116_set_frontend,
-};
-
-MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
deleted file mode 100644 (file)
index 7d90ab9..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-    Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
-
-    Copyright (C) 2006 Steven Toth <stoth@linuxtv.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef CX24116_H
-#define CX24116_H
-
-#include <linux/dvb/frontend.h>
-
-struct cx24116_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* Need to set device param for start_dma */
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-
-       /* Need to reset device during firmware loading */
-       int (*reset_device)(struct dvb_frontend *fe);
-
-       /* Need to set MPEG parameters */
-       u8 mpg_clk_pos_pol:0x02;
-
-       /* max bytes I2C provider can write at once */
-       u16 i2c_wr_max;
-};
-
-#if defined(CONFIG_DVB_CX24116) || \
-       (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE))
-extern struct dvb_frontend *cx24116_attach(
-       const struct cx24116_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *cx24116_attach(
-       const struct cx24116_config *config,
-       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* CX24116_H */
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
deleted file mode 100644 (file)
index 7e28b4e..0000000
+++ /dev/null
@@ -1,1165 +0,0 @@
-/*
- *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
- *
- *   Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
- *
- *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
- *
- *   Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License as
- *   published by the Free Software Foundation; either version 2 of
- *   the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *   General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "dvb_frontend.h"
-#include "cx24123.h"
-
-#define XTAL 10111000
-
-static int force_band;
-module_param(force_band, int, 0644);
-MODULE_PARM_DESC(force_band, "Force a specific band select "\
-       "(1-9, default:off).");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
-#define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
-
-#define dprintk(args...) \
-       do { \
-               if (debug) { \
-                       printk(KERN_DEBUG "CX24123: %s: ", __func__); \
-                       printk(args); \
-               } \
-       } while (0)
-
-struct cx24123_state {
-       struct i2c_adapter *i2c;
-       const struct cx24123_config *config;
-
-       struct dvb_frontend frontend;
-
-       /* Some PLL specifics for tuning */
-       u32 VCAarg;
-       u32 VGAarg;
-       u32 bandselectarg;
-       u32 pllarg;
-       u32 FILTune;
-
-       struct i2c_adapter tuner_i2c_adapter;
-
-       u8 demod_rev;
-
-       /* The Demod/Tuner can't easily provide these, we cache them */
-       u32 currentfreq;
-       u32 currentsymbolrate;
-};
-
-/* Various tuner defaults need to be established for a given symbol rate Sps */
-static struct cx24123_AGC_val {
-       u32 symbolrate_low;
-       u32 symbolrate_high;
-       u32 VCAprogdata;
-       u32 VGAprogdata;
-       u32 FILTune;
-} cx24123_AGC_vals[] =
-{
-       {
-               .symbolrate_low         = 1000000,
-               .symbolrate_high        = 4999999,
-               /* the specs recommend other values for VGA offsets,
-                  but tests show they are wrong */
-               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
-               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x07,
-               .FILTune                = 0x27f /* 0.41 V */
-       },
-       {
-               .symbolrate_low         =  5000000,
-               .symbolrate_high        = 14999999,
-               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
-               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x1f,
-               .FILTune                = 0x317 /* 0.90 V */
-       },
-       {
-               .symbolrate_low         = 15000000,
-               .symbolrate_high        = 45000000,
-               .VGAprogdata            = (1 << 19) | (0x100 << 9) | 0x180,
-               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x3f,
-               .FILTune                = 0x145 /* 2.70 V */
-       },
-};
-
-/*
- * Various tuner defaults need to be established for a given frequency kHz.
- * fixme: The bounds on the bands do not match the doc in real life.
- * fixme: Some of them have been moved, other might need adjustment.
- */
-static struct cx24123_bandselect_val {
-       u32 freq_low;
-       u32 freq_high;
-       u32 VCOdivider;
-       u32 progdata;
-} cx24123_bandselect_vals[] =
-{
-       /* band 1 */
-       {
-               .freq_low       = 950000,
-               .freq_high      = 1074999,
-               .VCOdivider     = 4,
-               .progdata       = (0 << 19) | (0 << 9) | 0x40,
-       },
-
-       /* band 2 */
-       {
-               .freq_low       = 1075000,
-               .freq_high      = 1177999,
-               .VCOdivider     = 4,
-               .progdata       = (0 << 19) | (0 << 9) | 0x80,
-       },
-
-       /* band 3 */
-       {
-               .freq_low       = 1178000,
-               .freq_high      = 1295999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x01,
-       },
-
-       /* band 4 */
-       {
-               .freq_low       = 1296000,
-               .freq_high      = 1431999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x02,
-       },
-
-       /* band 5 */
-       {
-               .freq_low       = 1432000,
-               .freq_high      = 1575999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x04,
-       },
-
-       /* band 6 */
-       {
-               .freq_low       = 1576000,
-               .freq_high      = 1717999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x08,
-       },
-
-       /* band 7 */
-       {
-               .freq_low       = 1718000,
-               .freq_high      = 1855999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x10,
-       },
-
-       /* band 8 */
-       {
-               .freq_low       = 1856000,
-               .freq_high      = 2035999,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x20,
-       },
-
-       /* band 9 */
-       {
-               .freq_low       = 2036000,
-               .freq_high      = 2150000,
-               .VCOdivider     = 2,
-               .progdata       = (0 << 19) | (1 << 9) | 0x40,
-       },
-};
-
-static struct {
-       u8 reg;
-       u8 data;
-} cx24123_regdata[] =
-{
-       {0x00, 0x03}, /* Reset system */
-       {0x00, 0x00}, /* Clear reset */
-       {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
-       {0x04, 0x10}, /* MPEG */
-       {0x05, 0x04}, /* MPEG */
-       {0x06, 0x31}, /* MPEG (default) */
-       {0x0b, 0x00}, /* Freq search start point (default) */
-       {0x0c, 0x00}, /* Demodulator sample gain (default) */
-       {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
-       {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
-       {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
-       {0x10, 0x01}, /* Default search inversion, no repeat (default) */
-       {0x16, 0x00}, /* Enable reading of frequency */
-       {0x17, 0x01}, /* Enable EsNO Ready Counter */
-       {0x1c, 0x80}, /* Enable error counter */
-       {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
-       {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
-       {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
-       {0x29, 0x00}, /* DiSEqC LNB_DC off */
-       {0x2a, 0xb0}, /* DiSEqC Parameters (default) */
-       {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
-       {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
-       {0x2d, 0x00},
-       {0x2e, 0x00},
-       {0x2f, 0x00},
-       {0x30, 0x00},
-       {0x31, 0x00},
-       {0x32, 0x8c}, /* DiSEqC Parameters (default) */
-       {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
-       {0x34, 0x00},
-       {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
-       {0x36, 0x02}, /* DiSEqC Parameters (default) */
-       {0x37, 0x3a}, /* DiSEqC Parameters (default) */
-       {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
-       {0x44, 0x00}, /* Constellation (default) */
-       {0x45, 0x00}, /* Symbol count (default) */
-       {0x46, 0x0d}, /* Symbol rate estimator on (default) */
-       {0x56, 0xc1}, /* Error Counter = Viterbi BER */
-       {0x57, 0xff}, /* Error Counter Window (default) */
-       {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
-       {0x67, 0x83}, /* Non-DCII symbol clock */
-};
-
-static int cx24123_i2c_writereg(struct cx24123_state *state,
-       u8 i2c_addr, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
-       };
-       int err;
-
-       /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
-
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk("%s: writereg error(err == %i, reg == 0x%02x,"
-                        " data == 0x%02x)\n", __func__, err, reg, data);
-               return err;
-       }
-
-       return 0;
-}
-
-static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
-{
-       int ret;
-       u8 b = 0;
-       struct i2c_msg msg[] = {
-               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
-               return ret;
-       }
-
-       /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
-
-       return b;
-}
-
-#define cx24123_readreg(state, reg) \
-       cx24123_i2c_readreg(state, state->config->demod_address, reg)
-#define cx24123_writereg(state, reg, val) \
-       cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
-
-static int cx24123_set_inversion(struct cx24123_state *state,
-       fe_spectral_inversion_t inversion)
-{
-       u8 nom_reg = cx24123_readreg(state, 0x0e);
-       u8 auto_reg = cx24123_readreg(state, 0x10);
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               dprintk("inversion off\n");
-               cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
-               cx24123_writereg(state, 0x10, auto_reg | 0x80);
-               break;
-       case INVERSION_ON:
-               dprintk("inversion on\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x80);
-               cx24123_writereg(state, 0x10, auto_reg | 0x80);
-               break;
-       case INVERSION_AUTO:
-               dprintk("inversion auto\n");
-               cx24123_writereg(state, 0x10, auto_reg & ~0x80);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int cx24123_get_inversion(struct cx24123_state *state,
-       fe_spectral_inversion_t *inversion)
-{
-       u8 val;
-
-       val = cx24123_readreg(state, 0x1b) >> 7;
-
-       if (val == 0) {
-               dprintk("read inversion off\n");
-               *inversion = INVERSION_OFF;
-       } else {
-               dprintk("read inversion on\n");
-               *inversion = INVERSION_ON;
-       }
-
-       return 0;
-}
-
-static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
-{
-       u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
-
-       if ((fec < FEC_NONE) || (fec > FEC_AUTO))
-               fec = FEC_AUTO;
-
-       /* Set the soft decision threshold */
-       if (fec == FEC_1_2)
-               cx24123_writereg(state, 0x43,
-                       cx24123_readreg(state, 0x43) | 0x01);
-       else
-               cx24123_writereg(state, 0x43,
-                       cx24123_readreg(state, 0x43) & ~0x01);
-
-       switch (fec) {
-       case FEC_1_2:
-               dprintk("set FEC to 1/2\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x01);
-               cx24123_writereg(state, 0x0f, 0x02);
-               break;
-       case FEC_2_3:
-               dprintk("set FEC to 2/3\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x02);
-               cx24123_writereg(state, 0x0f, 0x04);
-               break;
-       case FEC_3_4:
-               dprintk("set FEC to 3/4\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x03);
-               cx24123_writereg(state, 0x0f, 0x08);
-               break;
-       case FEC_4_5:
-               dprintk("set FEC to 4/5\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x04);
-               cx24123_writereg(state, 0x0f, 0x10);
-               break;
-       case FEC_5_6:
-               dprintk("set FEC to 5/6\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x05);
-               cx24123_writereg(state, 0x0f, 0x20);
-               break;
-       case FEC_6_7:
-               dprintk("set FEC to 6/7\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x06);
-               cx24123_writereg(state, 0x0f, 0x40);
-               break;
-       case FEC_7_8:
-               dprintk("set FEC to 7/8\n");
-               cx24123_writereg(state, 0x0e, nom_reg | 0x07);
-               cx24123_writereg(state, 0x0f, 0x80);
-               break;
-       case FEC_AUTO:
-               dprintk("set FEC to auto\n");
-               cx24123_writereg(state, 0x0f, 0xfe);
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       return 0;
-}
-
-static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec)
-{
-       int ret;
-
-       ret = cx24123_readreg(state, 0x1b);
-       if (ret < 0)
-               return ret;
-       ret = ret & 0x07;
-
-       switch (ret) {
-       case 1:
-               *fec = FEC_1_2;
-               break;
-       case 2:
-               *fec = FEC_2_3;
-               break;
-       case 3:
-               *fec = FEC_3_4;
-               break;
-       case 4:
-               *fec = FEC_4_5;
-               break;
-       case 5:
-               *fec = FEC_5_6;
-               break;
-       case 6:
-               *fec = FEC_6_7;
-               break;
-       case 7:
-               *fec = FEC_7_8;
-               break;
-       default:
-               /* this can happen when there's no lock */
-               *fec = FEC_NONE;
-       }
-
-       return 0;
-}
-
-/* Approximation of closest integer of log2(a/b). It actually gives the
-   lowest integer i such that 2^i >= round(a/b) */
-static u32 cx24123_int_log2(u32 a, u32 b)
-{
-       u32 exp, nearest = 0;
-       u32 div = a / b;
-       if (a % b >= b / 2)
-               ++div;
-       if (div < (1 << 31)) {
-               for (exp = 1; div > exp; nearest++)
-                       exp += exp;
-       }
-       return nearest;
-}
-
-static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
-{
-       u32 tmp, sample_rate, ratio, sample_gain;
-       u8 pll_mult;
-
-       /*  check if symbol rate is within limits */
-       if ((srate > state->frontend.ops.info.symbol_rate_max) ||
-           (srate < state->frontend.ops.info.symbol_rate_min))
-               return -EOPNOTSUPP;
-
-       /* choose the sampling rate high enough for the required operation,
-          while optimizing the power consumed by the demodulator */
-       if (srate < (XTAL*2)/2)
-               pll_mult = 2;
-       else if (srate < (XTAL*3)/2)
-               pll_mult = 3;
-       else if (srate < (XTAL*4)/2)
-               pll_mult = 4;
-       else if (srate < (XTAL*5)/2)
-               pll_mult = 5;
-       else if (srate < (XTAL*6)/2)
-               pll_mult = 6;
-       else if (srate < (XTAL*7)/2)
-               pll_mult = 7;
-       else if (srate < (XTAL*8)/2)
-               pll_mult = 8;
-       else
-               pll_mult = 9;
-
-
-       sample_rate = pll_mult * XTAL;
-
-       /*
-           SYSSymbolRate[21:0] = (srate << 23) / sample_rate
-
-           We have to use 32 bit unsigned arithmetic without precision loss.
-           The maximum srate is 45000000 or 0x02AEA540. This number has
-           only 6 clear bits on top, hence we can shift it left only 6 bits
-           at a time. Borrowed from cx24110.c
-       */
-
-       tmp = srate << 6;
-       ratio = tmp / sample_rate;
-
-       tmp = (tmp % sample_rate) << 6;
-       ratio = (ratio << 6) + (tmp / sample_rate);
-
-       tmp = (tmp % sample_rate) << 6;
-       ratio = (ratio << 6) + (tmp / sample_rate);
-
-       tmp = (tmp % sample_rate) << 5;
-       ratio = (ratio << 5) + (tmp / sample_rate);
-
-
-       cx24123_writereg(state, 0x01, pll_mult * 6);
-
-       cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
-       cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
-       cx24123_writereg(state, 0x0a, ratio & 0xff);
-
-       /* also set the demodulator sample gain */
-       sample_gain = cx24123_int_log2(sample_rate, srate);
-       tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
-       cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
-
-       dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
-               srate, ratio, sample_rate, sample_gain);
-
-       return 0;
-}
-
-/*
- * Based on the required frequency and symbolrate, the tuner AGC has
- * to be configured and the correct band selected.
- * Calculate those values.
- */
-static int cx24123_pll_calculate(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct cx24123_state *state = fe->demodulator_priv;
-       u32 ndiv = 0, adiv = 0, vco_div = 0;
-       int i = 0;
-       int pump = 2;
-       int band = 0;
-       int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
-       struct cx24123_bandselect_val *bsv = NULL;
-       struct cx24123_AGC_val *agcv = NULL;
-
-       /* Defaults for low freq, low rate */
-       state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
-       state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
-       state->bandselectarg = cx24123_bandselect_vals[0].progdata;
-       vco_div = cx24123_bandselect_vals[0].VCOdivider;
-
-       /* For the given symbol rate, determine the VCA, VGA and
-        * FILTUNE programming bits */
-       for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
-               agcv = &cx24123_AGC_vals[i];
-               if ((agcv->symbolrate_low <= p->symbol_rate) &&
-                   (agcv->symbolrate_high >= p->symbol_rate)) {
-                       state->VCAarg = agcv->VCAprogdata;
-                       state->VGAarg = agcv->VGAprogdata;
-                       state->FILTune = agcv->FILTune;
-               }
-       }
-
-       /* determine the band to use */
-       if (force_band < 1 || force_band > num_bands) {
-               for (i = 0; i < num_bands; i++) {
-                       bsv = &cx24123_bandselect_vals[i];
-                       if ((bsv->freq_low <= p->frequency) &&
-                               (bsv->freq_high >= p->frequency))
-                               band = i;
-               }
-       } else
-               band = force_band - 1;
-
-       state->bandselectarg = cx24123_bandselect_vals[band].progdata;
-       vco_div = cx24123_bandselect_vals[band].VCOdivider;
-
-       /* determine the charge pump current */
-       if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
-               cx24123_bandselect_vals[band].freq_high) / 2)
-               pump = 0x01;
-       else
-               pump = 0x02;
-
-       /* Determine the N/A dividers for the requested lband freq (in kHz). */
-       /* Note: the reference divider R=10, frequency is in KHz,
-        * XTAL is in Hz */
-       ndiv = (((p->frequency * vco_div * 10) /
-               (2 * XTAL / 1000)) / 32) & 0x1ff;
-       adiv = (((p->frequency * vco_div * 10) /
-               (2 * XTAL / 1000)) % 32) & 0x1f;
-
-       if (adiv == 0 && ndiv > 0)
-               ndiv--;
-
-       /* control bits 11, refdiv 11, charge pump polarity 1,
-        * charge pump current, ndiv, adiv */
-       state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
-               (pump << 14) | (ndiv << 5) | adiv;
-
-       return 0;
-}
-
-/*
- * Tuner data is 21 bits long, must be left-aligned in data.
- * Tuner cx24109 is written through a dedicated 3wire interface
- * on the demod chip.
- */
-static int cx24123_pll_writereg(struct dvb_frontend *fe, u32 data)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       unsigned long timeout;
-
-       dprintk("pll writereg called, data=0x%08x\n", data);
-
-       /* align the 21 bytes into to bit23 boundary */
-       data = data << 3;
-
-       /* Reset the demod pll word length to 0x15 bits */
-       cx24123_writereg(state, 0x21, 0x15);
-
-       /* write the msb 8 bits, wait for the send to be completed */
-       timeout = jiffies + msecs_to_jiffies(40);
-       cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
-       while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
-               if (time_after(jiffies, timeout)) {
-                       err("%s:  demodulator is not responding, "\
-                               "possibly hung, aborting.\n", __func__);
-                       return -EREMOTEIO;
-               }
-               msleep(10);
-       }
-
-       /* send another 8 bytes, wait for the send to be completed */
-       timeout = jiffies + msecs_to_jiffies(40);
-       cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
-       while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
-               if (time_after(jiffies, timeout)) {
-                       err("%s:  demodulator is not responding, "\
-                               "possibly hung, aborting.\n", __func__);
-                       return -EREMOTEIO;
-               }
-               msleep(10);
-       }
-
-       /* send the lower 5 bits of this byte, padded with 3 LBB,
-        * wait for the send to be completed */
-       timeout = jiffies + msecs_to_jiffies(40);
-       cx24123_writereg(state, 0x22, (data) & 0xff);
-       while ((cx24123_readreg(state, 0x20) & 0x80)) {
-               if (time_after(jiffies, timeout)) {
-                       err("%s:  demodulator is not responding," \
-                               "possibly hung, aborting.\n", __func__);
-                       return -EREMOTEIO;
-               }
-               msleep(10);
-       }
-
-       /* Trigger the demod to configure the tuner */
-       cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
-       cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
-
-       return 0;
-}
-
-static int cx24123_pll_tune(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct cx24123_state *state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("frequency=%i\n", p->frequency);
-
-       if (cx24123_pll_calculate(fe) != 0) {
-               err("%s: cx24123_pll_calcutate failed\n", __func__);
-               return -EINVAL;
-       }
-
-       /* Write the new VCO/VGA */
-       cx24123_pll_writereg(fe, state->VCAarg);
-       cx24123_pll_writereg(fe, state->VGAarg);
-
-       /* Write the new bandselect and pll args */
-       cx24123_pll_writereg(fe, state->bandselectarg);
-       cx24123_pll_writereg(fe, state->pllarg);
-
-       /* set the FILTUNE voltage */
-       val = cx24123_readreg(state, 0x28) & ~0x3;
-       cx24123_writereg(state, 0x27, state->FILTune >> 2);
-       cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
-
-       dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
-                       state->bandselectarg, state->pllarg);
-
-       return 0;
-}
-
-
-/*
- * 0x23:
- *    [7:7] = BTI enabled
- *    [6:6] = I2C repeater enabled
- *    [5:5] = I2C repeater start
- *    [0:0] = BTI start
- */
-
-/* mode == 1 -> i2c-repeater, 0 -> bti */
-static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
-{
-       u8 r = cx24123_readreg(state, 0x23) & 0x1e;
-       if (mode)
-               r |= (1 << 6) | (start << 5);
-       else
-               r |= (1 << 7) | (start);
-       return cx24123_writereg(state, 0x23, r);
-}
-
-static int cx24123_initfe(struct dvb_frontend *fe)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       int i;
-
-       dprintk("init frontend\n");
-
-       /* Configure the demod to a good set of defaults */
-       for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
-               cx24123_writereg(state, cx24123_regdata[i].reg,
-                       cx24123_regdata[i].data);
-
-       /* Set the LNB polarity */
-       if (state->config->lnb_polarity)
-               cx24123_writereg(state, 0x32,
-                       cx24123_readreg(state, 0x32) | 0x02);
-
-       if (state->config->dont_use_pll)
-               cx24123_repeater_mode(state, 1, 0);
-
-       return 0;
-}
-
-static int cx24123_set_voltage(struct dvb_frontend *fe,
-       fe_sec_voltage_t voltage)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       u8 val;
-
-       val = cx24123_readreg(state, 0x29) & ~0x40;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               dprintk("setting voltage 13V\n");
-               return cx24123_writereg(state, 0x29, val & 0x7f);
-       case SEC_VOLTAGE_18:
-               dprintk("setting voltage 18V\n");
-               return cx24123_writereg(state, 0x29, val | 0x80);
-       case SEC_VOLTAGE_OFF:
-               /* already handled in cx88-dvb */
-               return 0;
-       default:
-               return -EINVAL;
-       };
-
-       return 0;
-}
-
-/* wait for diseqc queue to become ready (or timeout) */
-static void cx24123_wait_for_diseqc(struct cx24123_state *state)
-{
-       unsigned long timeout = jiffies + msecs_to_jiffies(200);
-       while (!(cx24123_readreg(state, 0x29) & 0x40)) {
-               if (time_after(jiffies, timeout)) {
-                       err("%s: diseqc queue not ready, " \
-                               "command may be lost.\n", __func__);
-                       break;
-               }
-               msleep(10);
-       }
-}
-
-static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
-       struct dvb_diseqc_master_cmd *cmd)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       int i, val, tone;
-
-       dprintk("\n");
-
-       /* stop continuous tone if enabled */
-       tone = cx24123_readreg(state, 0x29);
-       if (tone & 0x10)
-               cx24123_writereg(state, 0x29, tone & ~0x50);
-
-       /* wait for diseqc queue ready */
-       cx24123_wait_for_diseqc(state);
-
-       /* select tone mode */
-       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
-
-       for (i = 0; i < cmd->msg_len; i++)
-               cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
-
-       val = cx24123_readreg(state, 0x29);
-       cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
-               ((cmd->msg_len-3) & 3));
-
-       /* wait for diseqc message to finish sending */
-       cx24123_wait_for_diseqc(state);
-
-       /* restart continuous tone if enabled */
-       if (tone & 0x10)
-               cx24123_writereg(state, 0x29, tone & ~0x40);
-
-       return 0;
-}
-
-static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
-       fe_sec_mini_cmd_t burst)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       int val, tone;
-
-       dprintk("\n");
-
-       /* stop continuous tone if enabled */
-       tone = cx24123_readreg(state, 0x29);
-       if (tone & 0x10)
-               cx24123_writereg(state, 0x29, tone & ~0x50);
-
-       /* wait for diseqc queue ready */
-       cx24123_wait_for_diseqc(state);
-
-       /* select tone mode */
-       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
-       msleep(30);
-       val = cx24123_readreg(state, 0x29);
-       if (burst == SEC_MINI_A)
-               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
-       else if (burst == SEC_MINI_B)
-               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
-       else
-               return -EINVAL;
-
-       cx24123_wait_for_diseqc(state);
-       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
-
-       /* restart continuous tone if enabled */
-       if (tone & 0x10)
-               cx24123_writereg(state, 0x29, tone & ~0x40);
-
-       return 0;
-}
-
-static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       int sync = cx24123_readreg(state, 0x14);
-
-       *status = 0;
-       if (state->config->dont_use_pll) {
-               u32 tun_status = 0;
-               if (fe->ops.tuner_ops.get_status)
-                       fe->ops.tuner_ops.get_status(fe, &tun_status);
-               if (tun_status & TUNER_STATUS_LOCKED)
-                       *status |= FE_HAS_SIGNAL;
-       } else {
-               int lock = cx24123_readreg(state, 0x20);
-               if (lock & 0x01)
-                       *status |= FE_HAS_SIGNAL;
-       }
-
-       if (sync & 0x02)
-               *status |= FE_HAS_CARRIER;      /* Phase locked */
-       if (sync & 0x04)
-               *status |= FE_HAS_VITERBI;
-
-       /* Reed-Solomon Status */
-       if (sync & 0x08)
-               *status |= FE_HAS_SYNC;
-       if (sync & 0x80)
-               *status |= FE_HAS_LOCK;         /*Full Sync */
-
-       return 0;
-}
-
-/*
- * Configured to return the measurement of errors in blocks,
- * because no UCBLOCKS value is available, so this value doubles up
- * to satisfy both measurements.
- */
-static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-
-       /* The true bit error rate is this value divided by
-          the window size (set as 256 * 255) */
-       *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
-               (cx24123_readreg(state, 0x1d) << 8 |
-                cx24123_readreg(state, 0x1e));
-
-       dprintk("BER = %d\n", *ber);
-
-       return 0;
-}
-
-static int cx24123_read_signal_strength(struct dvb_frontend *fe,
-       u16 *signal_strength)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-
-       /* larger = better */
-       *signal_strength = cx24123_readreg(state, 0x3b) << 8;
-
-       dprintk("Signal strength = %d\n", *signal_strength);
-
-       return 0;
-}
-
-static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-
-       /* Inverted raw Es/N0 count, totally bogus but better than the
-          BER threshold. */
-       *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
-                        (u16)cx24123_readreg(state, 0x19));
-
-       dprintk("read S/N index = %d\n", *snr);
-
-       return 0;
-}
-
-static int cx24123_set_frontend(struct dvb_frontend *fe)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       dprintk("\n");
-
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-
-       state->currentfreq = p->frequency;
-       state->currentsymbolrate = p->symbol_rate;
-
-       cx24123_set_inversion(state, p->inversion);
-       cx24123_set_fec(state, p->fec_inner);
-       cx24123_set_symbolrate(state, p->symbol_rate);
-
-       if (!state->config->dont_use_pll)
-               cx24123_pll_tune(fe);
-       else if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-       else
-               err("it seems I don't have a tuner...");
-
-       /* Enable automatic acquisition and reset cycle */
-       cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
-       cx24123_writereg(state, 0x00, 0x10);
-       cx24123_writereg(state, 0x00, 0);
-
-       if (state->config->agc_callback)
-               state->config->agc_callback(fe);
-
-       return 0;
-}
-
-static int cx24123_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct cx24123_state *state = fe->demodulator_priv;
-
-       dprintk("\n");
-
-       if (cx24123_get_inversion(state, &p->inversion) != 0) {
-               err("%s: Failed to get inversion status\n", __func__);
-               return -EREMOTEIO;
-       }
-       if (cx24123_get_fec(state, &p->fec_inner) != 0) {
-               err("%s: Failed to get fec status\n", __func__);
-               return -EREMOTEIO;
-       }
-       p->frequency = state->currentfreq;
-       p->symbol_rate = state->currentsymbolrate;
-
-       return 0;
-}
-
-static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       u8 val;
-
-       /* wait for diseqc queue ready */
-       cx24123_wait_for_diseqc(state);
-
-       val = cx24123_readreg(state, 0x29) & ~0x40;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               dprintk("setting tone on\n");
-               return cx24123_writereg(state, 0x29, val | 0x10);
-       case SEC_TONE_OFF:
-               dprintk("setting tone off\n");
-               return cx24123_writereg(state, 0x29, val & 0xef);
-       default:
-               err("CASE reached default with tone=%d\n", tone);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int cx24123_tune(struct dvb_frontend *fe,
-                       bool re_tune,
-                       unsigned int mode_flags,
-                       unsigned int *delay,
-                       fe_status_t *status)
-{
-       int retval = 0;
-
-       if (re_tune)
-               retval = cx24123_set_frontend(fe);
-
-       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
-               cx24123_read_status(fe, status);
-       *delay = HZ/10;
-
-       return retval;
-}
-
-static int cx24123_get_algo(struct dvb_frontend *fe)
-{
-       return 1; /* FE_ALGO_HW */
-}
-
-static void cx24123_release(struct dvb_frontend *fe)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       dprintk("\n");
-       i2c_del_adapter(&state->tuner_i2c_adapter);
-       kfree(state);
-}
-
-static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
-       struct i2c_msg msg[], int num)
-{
-       struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
-       /* this repeater closes after the first stop */
-       cx24123_repeater_mode(state, 1, 1);
-       return i2c_transfer(state->i2c, msg, num);
-}
-
-static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm cx24123_tuner_i2c_algo = {
-       .master_xfer   = cx24123_tuner_i2c_tuner_xfer,
-       .functionality = cx24123_tuner_i2c_func,
-};
-
-struct i2c_adapter *
-       cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       struct cx24123_state *state = fe->demodulator_priv;
-       return &state->tuner_i2c_adapter;
-}
-EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
-
-static struct dvb_frontend_ops cx24123_ops;
-
-struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       /* allocate memory for the internal state */
-       struct cx24123_state *state =
-               kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
-
-       dprintk("\n");
-       if (state == NULL) {
-               err("Unable to kzalloc\n");
-               goto error;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       state->demod_rev = cx24123_readreg(state, 0x00);
-       switch (state->demod_rev) {
-       case 0xe1:
-               info("detected CX24123C\n");
-               break;
-       case 0xd1:
-               info("detected CX24123\n");
-               break;
-       default:
-               err("wrong demod revision: %x\n", state->demod_rev);
-               goto error;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &cx24123_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       /* create tuner i2c adapter */
-       if (config->dont_use_pll)
-               cx24123_repeater_mode(state, 1, 0);
-
-       strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
-               sizeof(state->tuner_i2c_adapter.name));
-       state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
-       state->tuner_i2c_adapter.algo_data = NULL;
-       i2c_set_adapdata(&state->tuner_i2c_adapter, state);
-       if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
-               err("tuner i2c bus could not be initialized\n");
-               goto error;
-       }
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-
-       return NULL;
-}
-EXPORT_SYMBOL(cx24123_attach);
-
-static struct dvb_frontend_ops cx24123_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name = "Conexant CX24123/CX24109",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
-               .frequency_tolerance = 5000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_RECOVER
-       },
-
-       .release = cx24123_release,
-
-       .init = cx24123_initfe,
-       .set_frontend = cx24123_set_frontend,
-       .get_frontend = cx24123_get_frontend,
-       .read_status = cx24123_read_status,
-       .read_ber = cx24123_read_ber,
-       .read_signal_strength = cx24123_read_signal_strength,
-       .read_snr = cx24123_read_snr,
-       .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
-       .diseqc_send_burst = cx24123_diseqc_send_burst,
-       .set_tone = cx24123_set_tone,
-       .set_voltage = cx24123_set_voltage,
-       .tune = cx24123_tune,
-       .get_frontend_algo = cx24123_get_algo,
-};
-
-MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
-       "CX24123/CX24109/CX24113 hardware");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
deleted file mode 100644 (file)
index 51ae866..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
-
-    Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef CX24123_H
-#define CX24123_H
-
-#include <linux/dvb/frontend.h>
-
-struct cx24123_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* Need to set device param for start_dma */
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-
-       /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
-       int lnb_polarity;
-
-       /* this device has another tuner */
-       u8 dont_use_pll;
-       void (*agc_callback) (struct dvb_frontend *);
-};
-
-#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
-       && defined(MODULE))
-extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
-                                          struct i2c_adapter *i2c);
-extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
-#else
-static inline struct dvb_frontend *cx24123_attach(
-       const struct cx24123_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static struct i2c_adapter *
-       cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
deleted file mode 100644 (file)
index 5aa306e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#ifndef CXD2820R_H
-#define CXD2820R_H
-
-#include <linux/dvb/frontend.h>
-
-#define CXD2820R_GPIO_D (0 << 0) /* disable */
-#define CXD2820R_GPIO_E (1 << 0) /* enable */
-#define CXD2820R_GPIO_O (0 << 1) /* output */
-#define CXD2820R_GPIO_I (1 << 1) /* input */
-#define CXD2820R_GPIO_L (0 << 2) /* output low */
-#define CXD2820R_GPIO_H (1 << 2) /* output high */
-
-#define CXD2820R_TS_SERIAL        0x08
-#define CXD2820R_TS_SERIAL_MSB    0x28
-#define CXD2820R_TS_PARALLEL      0x30
-#define CXD2820R_TS_PARALLEL_MSB  0x70
-
-struct cxd2820r_config {
-       /* Demodulator I2C address.
-        * Driver determines DVB-C slave I2C address automatically from master
-        * address.
-        * Default: none, must set
-        * Values: 0x6c, 0x6d
-        */
-       u8 i2c_address;
-
-       /* TS output mode.
-        * Default: none, must set.
-        * Values:
-        */
-       u8 ts_mode;
-
-       /* IF AGC polarity.
-        * Default: 0
-        * Values: 0, 1
-        */
-       bool if_agc_polarity;
-
-       /* Spectrum inversion.
-        * Default: 0
-        * Values: 0, 1
-        */
-       bool spec_inv;
-
-       /* GPIOs for all used modes.
-        * Default: none, disabled
-        * Values: <see above>
-        */
-       u8 gpio_dvbt[3];
-       u8 gpio_dvbt2[3];
-       u8 gpio_dvbc[3];
-};
-
-
-#if defined(CONFIG_DVB_CXD2820R) || \
-       (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
-extern struct dvb_frontend *cxd2820r_attach(
-       const struct cxd2820r_config *config,
-       struct i2c_adapter *i2c
-);
-#else
-static inline struct dvb_frontend *cxd2820r_attach(
-       const struct cxd2820r_config *config,
-       struct i2c_adapter *i2c
-)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif
-
-#endif /* CXD2820R_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
deleted file mode 100644 (file)
index ed3b0ba..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#include "cxd2820r_priv.h"
-
-int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       u8 buf[2];
-       u32 if_freq;
-       u16 if_ctl;
-       u64 num;
-       struct reg_val_mask tab[] = {
-               { 0x00080, 0x01, 0xff },
-               { 0x00081, 0x05, 0xff },
-               { 0x00085, 0x07, 0xff },
-               { 0x00088, 0x01, 0xff },
-
-               { 0x00082, 0x20, 0x60 },
-               { 0x1016a, 0x48, 0xff },
-               { 0x100a5, 0x00, 0x01 },
-               { 0x10020, 0x06, 0x07 },
-               { 0x10059, 0x50, 0xff },
-               { 0x10087, 0x0c, 0x3c },
-               { 0x1008b, 0x07, 0xff },
-               { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
-               { 0x10070, priv->cfg.ts_mode, 0xff },
-       };
-
-       dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
-
-       /* update GPIOs */
-       ret = cxd2820r_gpio(fe);
-       if (ret)
-               goto error;
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       if (priv->delivery_system !=  SYS_DVBC_ANNEX_A) {
-               for (i = 0; i < ARRAY_SIZE(tab); i++) {
-                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
-                               tab[i].val, tab[i].mask);
-                       if (ret)
-                               goto error;
-               }
-       }
-
-       priv->delivery_system = SYS_DVBC_ANNEX_A;
-       priv->ber_running = 0; /* tune stops BER counter */
-
-       /* program IF frequency */
-       if (fe->ops.tuner_ops.get_if_frequency) {
-               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
-               if (ret)
-                       goto error;
-       } else
-               if_freq = 0;
-
-       dbg("%s: if_freq=%d", __func__, if_freq);
-
-       num = if_freq / 1000; /* Hz => kHz */
-       num *= 0x4000;
-       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
-       buf[0] = (if_ctl >> 8) & 0x3f;
-       buf[1] = (if_ctl >> 0) & 0xff;
-
-       ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_get_frontend_c(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-       u8 buf[2];
-
-       ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
-       if (ret)
-               goto error;
-
-       c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
-
-       ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0:
-               c->modulation = QAM_16;
-               break;
-       case 1:
-               c->modulation = QAM_32;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       case 3:
-               c->modulation = QAM_128;
-               break;
-       case 4:
-               c->modulation = QAM_256;
-               break;
-       }
-
-       switch ((buf[0] >> 7) & 0x01) {
-       case 0:
-               c->inversion = INVERSION_OFF;
-               break;
-       case 1:
-               c->inversion = INVERSION_ON;
-               break;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[3], start_ber = 0;
-       *ber = 0;
-
-       if (priv->ber_running) {
-               ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
-               if (ret)
-                       goto error;
-
-               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
-                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
-                       start_ber = 1;
-               }
-       } else {
-               priv->ber_running = 1;
-               start_ber = 1;
-       }
-
-       if (start_ber) {
-               /* (re)start BER */
-               ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 tmp;
-
-       ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       tmp = (buf[0] & 0x03) << 8 | buf[1];
-       tmp = (~tmp & 0x03ff);
-
-       if (tmp == 512)
-               /* ~no signal */
-               tmp = 0;
-       else if (tmp > 350)
-               tmp = 350;
-
-       /* scale value to 0x0000-0xffff */
-       *strength = tmp * 0xffff / (350-0);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-       unsigned int A, B;
-       /* report SNR in dB * 10 */
-
-       ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
-       if (ret)
-               goto error;
-
-       if (((tmp >> 0) & 0x03) % 2) {
-               A = 875;
-               B = 650;
-       } else {
-               A = 950;
-               B = 760;
-       }
-
-       ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
-       if (ret)
-               goto error;
-
-       #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
-       if (tmp)
-               *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
-                       / 10;
-       else
-               *snr = 0;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       /* no way to read ? */
-       return 0;
-}
-
-int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       *status = 0;
-
-       ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       if (((buf[0] >> 0) & 0x01) == 1) {
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                       FE_HAS_VITERBI | FE_HAS_SYNC;
-
-               if (((buf[1] >> 3) & 0x01) == 1) {
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-               }
-       }
-
-       dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_init_c(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-
-       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_sleep_c(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret, i;
-       struct reg_val_mask tab[] = {
-               { 0x000ff, 0x1f, 0xff },
-               { 0x00085, 0x00, 0xff },
-               { 0x00088, 0x01, 0xff },
-               { 0x00081, 0x00, 0xff },
-               { 0x00080, 0x00, 0xff },
-       };
-
-       dbg("%s", __func__);
-
-       priv->delivery_system = SYS_UNDEFINED;
-
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
-                       tab[i].mask);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 500;
-       s->step_size = 0; /* no zigzag */
-       s->max_drift = 0;
-
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
deleted file mode 100644 (file)
index 3bba37d..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#include "cxd2820r_priv.h"
-
-int cxd2820r_debug;
-module_param_named(debug, cxd2820r_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-/* write multiple registers */
-static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
-       u8 *val, int len)
-{
-       int ret;
-       u8 buf[len+1];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = i2c,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple registers */
-static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
-       u8 *val, int len)
-{
-       int ret;
-       u8 buf[len];
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = i2c,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = i2c,
-                       .flags = I2C_M_RD,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               memcpy(val, buf, len);
-               ret = 0;
-       } else {
-               warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write multiple registers */
-int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
-       int len)
-{
-       int ret;
-       u8 i2c_addr;
-       u8 reg = (reginfo >> 0) & 0xff;
-       u8 bank = (reginfo >> 8) & 0xff;
-       u8 i2c = (reginfo >> 16) & 0x01;
-
-       /* select I2C */
-       if (i2c)
-               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
-       else
-               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
-
-       /* switch bank if needed */
-       if (bank != priv->bank[i2c]) {
-               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
-               if (ret)
-                       return ret;
-               priv->bank[i2c] = bank;
-       }
-       return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
-}
-
-/* read multiple registers */
-int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
-       int len)
-{
-       int ret;
-       u8 i2c_addr;
-       u8 reg = (reginfo >> 0) & 0xff;
-       u8 bank = (reginfo >> 8) & 0xff;
-       u8 i2c = (reginfo >> 16) & 0x01;
-
-       /* select I2C */
-       if (i2c)
-               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
-       else
-               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
-
-       /* switch bank if needed */
-       if (bank != priv->bank[i2c]) {
-               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
-               if (ret)
-                       return ret;
-               priv->bank[i2c] = bank;
-       }
-       return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
-}
-
-/* write single register */
-int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
-{
-       return cxd2820r_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
-{
-       return cxd2820r_rd_regs(priv, reg, val, 1);
-}
-
-/* write single register with mask */
-int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
-       u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = cxd2820r_rd_reg(priv, reg, &tmp);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return cxd2820r_wr_reg(priv, reg, val);
-}
-
-int cxd2820r_gpio(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret, i;
-       u8 *gpio, tmp0, tmp1;
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               gpio = priv->cfg.gpio_dvbt;
-               break;
-       case SYS_DVBT2:
-               gpio = priv->cfg.gpio_dvbt2;
-               break;
-       case SYS_DVBC_ANNEX_AC:
-               gpio = priv->cfg.gpio_dvbc;
-               break;
-       default:
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* update GPIOs only when needed */
-       if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
-               return 0;
-
-       tmp0 = 0x00;
-       tmp1 = 0x00;
-       for (i = 0; i < sizeof(priv->gpio); i++) {
-               /* enable / disable */
-               if (gpio[i] & CXD2820R_GPIO_E)
-                       tmp0 |= (2 << 6) >> (2 * i);
-               else
-                       tmp0 |= (1 << 6) >> (2 * i);
-
-               /* input / output */
-               if (gpio[i] & CXD2820R_GPIO_I)
-                       tmp1 |= (1 << (3 + i));
-               else
-                       tmp1 |= (0 << (3 + i));
-
-               /* high / low */
-               if (gpio[i] & CXD2820R_GPIO_H)
-                       tmp1 |= (1 << (0 + i));
-               else
-                       tmp1 |= (0 << (0 + i));
-
-               dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
-       }
-
-       dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
-
-       /* write bits [7:2] */
-       ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
-       if (ret)
-               goto error;
-
-       /* write bits [5:0] */
-       ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
-       if (ret)
-               goto error;
-
-       memcpy(priv->gpio, gpio, sizeof(priv->gpio));
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
-u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
-{
-       return div_u64(dividend + (divisor / 2), divisor);
-}
-
-static int cxd2820r_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (c->delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_init_t(fe);
-               if (ret < 0)
-                       goto err;
-               ret = cxd2820r_set_frontend_t(fe);
-               if (ret < 0)
-                       goto err;
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_init_t(fe);
-               if (ret < 0)
-                       goto err;
-               ret = cxd2820r_set_frontend_t2(fe);
-               if (ret < 0)
-                       goto err;
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_init_c(fe);
-               if (ret < 0)
-                       goto err;
-               ret = cxd2820r_set_frontend_c(fe);
-               if (ret < 0)
-                       goto err;
-               break;
-       default:
-               dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system);
-               ret = -EINVAL;
-               break;
-       }
-err:
-       return ret;
-}
-static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_read_status_t(fe, status);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_read_status_t2(fe, status);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_read_status_c(fe, status);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_get_frontend(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-
-       if (priv->delivery_system == SYS_UNDEFINED)
-               return 0;
-
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_get_frontend_t(fe);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_get_frontend_t2(fe);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_get_frontend_c(fe);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_read_ber_t(fe, ber);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_read_ber_t2(fe, ber);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_read_ber_c(fe, ber);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_read_signal_strength_t(fe, strength);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_read_signal_strength_t2(fe, strength);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_read_signal_strength_c(fe, strength);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_read_snr_t(fe, snr);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_read_snr_t2(fe, snr);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_read_snr_c(fe, snr);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_init(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int cxd2820r_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_sleep_t(fe);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_sleep_t2(fe);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_sleep_c(fe);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
-                                     struct dvb_frontend_tune_settings *s)
-{
-       int ret;
-
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-       switch (fe->dtv_property_cache.delivery_system) {
-       case SYS_DVBT:
-               ret = cxd2820r_get_tune_settings_t(fe, s);
-               break;
-       case SYS_DVBT2:
-               ret = cxd2820r_get_tune_settings_t2(fe, s);
-               break;
-       case SYS_DVBC_ANNEX_A:
-               ret = cxd2820r_get_tune_settings_c(fe, s);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       fe_status_t status = 0;
-       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
-
-       /* switch between DVB-T and DVB-T2 when tune fails */
-       if (priv->last_tune_failed) {
-               if (priv->delivery_system == SYS_DVBT) {
-                       ret = cxd2820r_sleep_t(fe);
-                       if (ret)
-                               goto error;
-
-                       c->delivery_system = SYS_DVBT2;
-               } else if (priv->delivery_system == SYS_DVBT2) {
-                       ret = cxd2820r_sleep_t2(fe);
-                       if (ret)
-                               goto error;
-
-                       c->delivery_system = SYS_DVBT;
-               }
-       }
-
-       /* set frontend */
-       ret = cxd2820r_set_frontend(fe);
-       if (ret)
-               goto error;
-
-
-       /* frontend lock wait loop count */
-       switch (priv->delivery_system) {
-       case SYS_DVBT:
-       case SYS_DVBC_ANNEX_A:
-               i = 20;
-               break;
-       case SYS_DVBT2:
-               i = 40;
-               break;
-       case SYS_UNDEFINED:
-       default:
-               i = 0;
-               break;
-       }
-
-       /* wait frontend lock */
-       for (; i > 0; i--) {
-               dbg("%s: LOOP=%d", __func__, i);
-               msleep(50);
-               ret = cxd2820r_read_status(fe, &status);
-               if (ret)
-                       goto error;
-
-               if (status & FE_HAS_LOCK)
-                       break;
-       }
-
-       /* check if we have a valid signal */
-       if (status & FE_HAS_LOCK) {
-               priv->last_tune_failed = 0;
-               return DVBFE_ALGO_SEARCH_SUCCESS;
-       } else {
-               priv->last_tune_failed = 1;
-               return DVBFE_ALGO_SEARCH_AGAIN;
-       }
-
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return DVBFE_ALGO_SEARCH_ERROR;
-}
-
-static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static void cxd2820r_release(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       dbg("%s", __func__);
-
-       kfree(priv);
-       return;
-}
-
-static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       dbg("%s: %d", __func__, enable);
-
-       /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
-       return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
-}
-
-static const struct dvb_frontend_ops cxd2820r_ops = {
-       .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
-       /* default: DVB-T/T2 */
-       .info = {
-               .name = "Sony CXD2820R",
-
-               .caps = FE_CAN_FEC_1_2                  |
-                       FE_CAN_FEC_2_3                  |
-                       FE_CAN_FEC_3_4                  |
-                       FE_CAN_FEC_5_6                  |
-                       FE_CAN_FEC_7_8                  |
-                       FE_CAN_FEC_AUTO                 |
-                       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_TRANSMISSION_MODE_AUTO   |
-                       FE_CAN_GUARD_INTERVAL_AUTO      |
-                       FE_CAN_HIERARCHY_AUTO           |
-                       FE_CAN_MUTE_TS                  |
-                       FE_CAN_2G_MODULATION
-               },
-
-       .release                = cxd2820r_release,
-       .init                   = cxd2820r_init,
-       .sleep                  = cxd2820r_sleep,
-
-       .get_tune_settings      = cxd2820r_get_tune_settings,
-       .i2c_gate_ctrl          = cxd2820r_i2c_gate_ctrl,
-
-       .get_frontend           = cxd2820r_get_frontend,
-
-       .get_frontend_algo      = cxd2820r_get_frontend_algo,
-       .search                 = cxd2820r_search,
-
-       .read_status            = cxd2820r_read_status,
-       .read_snr               = cxd2820r_read_snr,
-       .read_ber               = cxd2820r_read_ber,
-       .read_ucblocks          = cxd2820r_read_ucblocks,
-       .read_signal_strength   = cxd2820r_read_signal_strength,
-};
-
-struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
-               struct i2c_adapter *i2c)
-{
-       struct cxd2820r_priv *priv = NULL;
-       int ret;
-       u8 tmp;
-
-       priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL);
-       if (!priv)
-               goto error;
-
-       priv->i2c = i2c;
-       memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config));
-
-       priv->bank[0] = priv->bank[1] = 0xff;
-       ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
-       dbg("%s: chip id=%02x", __func__, tmp);
-       if (ret || tmp != 0xe1)
-               goto error;
-
-       memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-       return &priv->fe;
-error:
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(cxd2820r_attach);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
deleted file mode 100644 (file)
index 9a9822c..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#ifndef CXD2820R_PRIV_H
-#define CXD2820R_PRIV_H
-
-#include <linux/dvb/version.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "cxd2820r.h"
-
-#define LOG_PREFIX "cxd2820r"
-
-#undef dbg
-#define dbg(f, arg...) \
-       if (cxd2820r_debug) \
-               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-struct reg_val_mask {
-       u32 reg;
-       u8  val;
-       u8  mask;
-};
-
-struct cxd2820r_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct cxd2820r_config cfg;
-
-       bool ber_running;
-
-       u8 bank[2];
-       u8 gpio[3];
-
-       fe_delivery_system_t delivery_system;
-       bool last_tune_failed; /* for switch between T and T2 tune */
-};
-
-/* cxd2820r_core.c */
-
-extern int cxd2820r_debug;
-
-int cxd2820r_gpio(struct dvb_frontend *fe);
-
-int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
-       u8 mask);
-
-int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
-       int len);
-
-u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
-
-int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
-       int len);
-
-int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
-       int len);
-
-int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
-
-int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
-
-/* cxd2820r_c.c */
-
-int cxd2820r_get_frontend_c(struct dvb_frontend *fe);
-
-int cxd2820r_set_frontend_c(struct dvb_frontend *fe);
-
-int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
-
-int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
-
-int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
-
-int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
-
-int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
-
-int cxd2820r_init_c(struct dvb_frontend *fe);
-
-int cxd2820r_sleep_c(struct dvb_frontend *fe);
-
-int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s);
-
-/* cxd2820r_t.c */
-
-int cxd2820r_get_frontend_t(struct dvb_frontend *fe);
-
-int cxd2820r_set_frontend_t(struct dvb_frontend *fe);
-
-int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
-
-int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
-
-int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
-
-int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
-
-int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
-
-int cxd2820r_init_t(struct dvb_frontend *fe);
-
-int cxd2820r_sleep_t(struct dvb_frontend *fe);
-
-int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s);
-
-/* cxd2820r_t2.c */
-
-int cxd2820r_get_frontend_t2(struct dvb_frontend *fe);
-
-int cxd2820r_set_frontend_t2(struct dvb_frontend *fe);
-
-int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
-
-int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
-
-int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
-
-int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
-
-int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
-
-int cxd2820r_init_t2(struct dvb_frontend *fe);
-
-int cxd2820r_sleep_t2(struct dvb_frontend *fe);
-
-int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s);
-
-#endif /* CXD2820R_PRIV_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
deleted file mode 100644 (file)
index e5dd22b..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#include "cxd2820r_priv.h"
-
-int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, bw_i;
-       u32 if_freq, if_ctl;
-       u64 num;
-       u8 buf[3], bw_param;
-       u8 bw_params1[][5] = {
-               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
-               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
-               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
-       };
-       u8 bw_params2[][2] = {
-               { 0x1f, 0xdc }, /* 6 MHz */
-               { 0x12, 0xf8 }, /* 7 MHz */
-               { 0x01, 0xe0 }, /* 8 MHz */
-       };
-       struct reg_val_mask tab[] = {
-               { 0x00080, 0x00, 0xff },
-               { 0x00081, 0x03, 0xff },
-               { 0x00085, 0x07, 0xff },
-               { 0x00088, 0x01, 0xff },
-
-               { 0x00070, priv->cfg.ts_mode, 0xff },
-               { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
-               { 0x000a5, 0x00, 0x01 },
-               { 0x00082, 0x20, 0x60 },
-               { 0x000c2, 0xc3, 0xff },
-               { 0x0016a, 0x50, 0xff },
-               { 0x00427, 0x41, 0xff },
-       };
-
-       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               bw_i = 0;
-               bw_param = 2;
-               break;
-       case 7000000:
-               bw_i = 1;
-               bw_param = 1;
-               break;
-       case 8000000:
-               bw_i = 2;
-               bw_param = 0;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* update GPIOs */
-       ret = cxd2820r_gpio(fe);
-       if (ret)
-               goto error;
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       if (priv->delivery_system != SYS_DVBT) {
-               for (i = 0; i < ARRAY_SIZE(tab); i++) {
-                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
-                               tab[i].val, tab[i].mask);
-                       if (ret)
-                               goto error;
-               }
-       }
-
-       priv->delivery_system = SYS_DVBT;
-       priv->ber_running = 0; /* tune stops BER counter */
-
-       /* program IF frequency */
-       if (fe->ops.tuner_ops.get_if_frequency) {
-               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
-               if (ret)
-                       goto error;
-       } else
-               if_freq = 0;
-
-       dbg("%s: if_freq=%d", __func__, if_freq);
-
-       num = if_freq / 1000; /* Hz => kHz */
-       num *= 0x1000000;
-       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
-       buf[0] = ((if_ctl >> 16) & 0xff);
-       buf[1] = ((if_ctl >>  8) & 0xff);
-       buf[2] = ((if_ctl >>  0) & 0xff);
-
-       ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_get_frontend_t(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-       u8 buf[2];
-
-       ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 6) & 0x03) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       }
-
-       switch ((buf[1] >> 1) & 0x03) {
-       case 0:
-               c->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               c->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       }
-
-       switch ((buf[1] >> 3) & 0x03) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       switch ((buf[0] >> 3) & 0x07) {
-       case 0:
-               c->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               c->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               c->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               c->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0:
-               c->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_HP = FEC_7_8;
-               break;
-       }
-
-       switch ((buf[1] >> 5) & 0x07) {
-       case 0:
-               c->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 0) & 0x01) {
-       case 0:
-               c->inversion = INVERSION_OFF;
-               break;
-       case 1:
-               c->inversion = INVERSION_ON;
-               break;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[3], start_ber = 0;
-       *ber = 0;
-
-       if (priv->ber_running) {
-               ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
-               if (ret)
-                       goto error;
-
-               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
-                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
-                       start_ber = 1;
-               }
-       } else {
-               priv->ber_running = 1;
-               start_ber = 1;
-       }
-
-       if (start_ber) {
-               /* (re)start BER */
-               ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 tmp;
-
-       ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       tmp = (buf[0] & 0x0f) << 8 | buf[1];
-       tmp = ~tmp & 0x0fff;
-
-       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
-       *strength = tmp * 0xffff / 0x0fff;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 tmp;
-       /* report SNR in dB * 10 */
-
-       ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       tmp = (buf[0] & 0x1f) << 8 | buf[1];
-       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
-       if (tmp)
-               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
-                       / 100);
-       else
-               *snr = 0;
-
-       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       /* no way to read ? */
-       return 0;
-}
-
-int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[4];
-       *status = 0;
-
-       ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
-       if (ret)
-               goto error;
-
-       if ((buf[0] & 0x07) == 6) {
-               ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
-               if (ret)
-                       goto error;
-
-               if (((buf[1] >> 3) & 0x01) == 1) {
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-               } else {
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC;
-               }
-       } else {
-               ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
-               if (ret)
-                       goto error;
-
-               if ((buf[2] & 0x0f) >= 4) {
-                       ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
-                       if (ret)
-                               goto error;
-
-                       if (((buf[3] >> 4) & 0x01) == 1)
-                               *status |= FE_HAS_SIGNAL;
-               }
-       }
-
-       dbg("%s: lock=%*ph", __func__, 4, buf);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_init_t(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-
-       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_sleep_t(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret, i;
-       struct reg_val_mask tab[] = {
-               { 0x000ff, 0x1f, 0xff },
-               { 0x00085, 0x00, 0xff },
-               { 0x00088, 0x01, 0xff },
-               { 0x00081, 0x00, 0xff },
-               { 0x00080, 0x00, 0xff },
-       };
-
-       dbg("%s", __func__);
-
-       priv->delivery_system = SYS_UNDEFINED;
-
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
-                       tab[i].mask);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 500;
-       s->step_size = fe->ops.info.frequency_stepsize * 2;
-       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
-
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
deleted file mode 100644 (file)
index 3a5759e..0000000
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Sony CXD2820R demodulator driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-#include "cxd2820r_priv.h"
-
-int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, bw_i;
-       u32 if_freq, if_ctl;
-       u64 num;
-       u8 buf[3], bw_param;
-       u8 bw_params1[][5] = {
-               { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
-               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
-               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
-               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
-       };
-       struct reg_val_mask tab[] = {
-               { 0x00080, 0x02, 0xff },
-               { 0x00081, 0x20, 0xff },
-               { 0x00085, 0x07, 0xff },
-               { 0x00088, 0x01, 0xff },
-               { 0x02069, 0x01, 0xff },
-
-               { 0x0207f, 0x2a, 0xff },
-               { 0x02082, 0x0a, 0xff },
-               { 0x02083, 0x0a, 0xff },
-               { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
-               { 0x02070, priv->cfg.ts_mode, 0xff },
-               { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
-               { 0x02567, 0x07, 0x0f },
-               { 0x02569, 0x03, 0x03 },
-               { 0x02595, 0x1a, 0xff },
-               { 0x02596, 0x50, 0xff },
-               { 0x02a8c, 0x00, 0xff },
-               { 0x02a8d, 0x34, 0xff },
-               { 0x02a45, 0x06, 0x07 },
-               { 0x03f10, 0x0d, 0xff },
-               { 0x03f11, 0x02, 0xff },
-               { 0x03f12, 0x01, 0xff },
-               { 0x03f23, 0x2c, 0xff },
-               { 0x03f51, 0x13, 0xff },
-               { 0x03f52, 0x01, 0xff },
-               { 0x03f53, 0x00, 0xff },
-               { 0x027e6, 0x14, 0xff },
-               { 0x02786, 0x02, 0x07 },
-               { 0x02787, 0x40, 0xe0 },
-               { 0x027ef, 0x10, 0x18 },
-       };
-
-       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
-
-       switch (c->bandwidth_hz) {
-       case 5000000:
-               bw_i = 0;
-               bw_param = 3;
-               break;
-       case 6000000:
-               bw_i = 1;
-               bw_param = 2;
-               break;
-       case 7000000:
-               bw_i = 2;
-               bw_param = 1;
-               break;
-       case 8000000:
-               bw_i = 3;
-               bw_param = 0;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* update GPIOs */
-       ret = cxd2820r_gpio(fe);
-       if (ret)
-               goto error;
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       if (priv->delivery_system != SYS_DVBT2) {
-               for (i = 0; i < ARRAY_SIZE(tab); i++) {
-                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
-                               tab[i].val, tab[i].mask);
-                       if (ret)
-                               goto error;
-               }
-       }
-
-       priv->delivery_system = SYS_DVBT2;
-
-       /* program IF frequency */
-       if (fe->ops.tuner_ops.get_if_frequency) {
-               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
-               if (ret)
-                       goto error;
-       } else
-               if_freq = 0;
-
-       dbg("%s: if_freq=%d", __func__, if_freq);
-
-       num = if_freq / 1000; /* Hz => kHz */
-       num *= 0x1000000;
-       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
-       buf[0] = ((if_ctl >> 16) & 0xff);
-       buf[1] = ((if_ctl >>  8) & 0xff);
-       buf[2] = ((if_ctl >>  0) & 0xff);
-
-       ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
-       if (ret)
-               goto error;
-
-       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-
-}
-
-int cxd2820r_get_frontend_t2(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-       u8 buf[2];
-
-       ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0:
-               c->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               c->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       case 2:
-               c->transmission_mode = TRANSMISSION_MODE_4K;
-               break;
-       case 3:
-               c->transmission_mode = TRANSMISSION_MODE_1K;
-               break;
-       case 4:
-               c->transmission_mode = TRANSMISSION_MODE_16K;
-               break;
-       case 5:
-               c->transmission_mode = TRANSMISSION_MODE_32K;
-               break;
-       }
-
-       switch ((buf[1] >> 4) & 0x07) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       case 4:
-               c->guard_interval = GUARD_INTERVAL_1_128;
-               break;
-       case 5:
-               c->guard_interval = GUARD_INTERVAL_19_128;
-               break;
-       case 6:
-               c->guard_interval = GUARD_INTERVAL_19_256;
-               break;
-       }
-
-       ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0:
-               c->fec_inner = FEC_1_2;
-               break;
-       case 1:
-               c->fec_inner = FEC_3_5;
-               break;
-       case 2:
-               c->fec_inner = FEC_2_3;
-               break;
-       case 3:
-               c->fec_inner = FEC_3_4;
-               break;
-       case 4:
-               c->fec_inner = FEC_4_5;
-               break;
-       case 5:
-               c->fec_inner = FEC_5_6;
-               break;
-       }
-
-       switch ((buf[1] >> 0) & 0x07) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       case 3:
-               c->modulation = QAM_256;
-               break;
-       }
-
-       ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
-       if (ret)
-               goto error;
-
-       switch ((buf[0] >> 4) & 0x01) {
-       case 0:
-               c->inversion = INVERSION_OFF;
-               break;
-       case 1:
-               c->inversion = INVERSION_ON;
-               break;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[1];
-       *status = 0;
-
-       ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
-       if (ret)
-               goto error;
-
-       if ((buf[0] & 0x07) == 6) {
-               if (((buf[0] >> 5) & 0x01) == 1) {
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-               } else {
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC;
-               }
-       }
-
-       dbg("%s: lock=%02x", __func__, buf[0]);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[4];
-       unsigned int errbits;
-       *ber = 0;
-       /* FIXME: correct calculation */
-
-       ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       if ((buf[0] >> 4) & 0x01) {
-               errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
-                       buf[2] << 8 | buf[3];
-
-               if (errbits)
-                       *ber = errbits * 64 / 16588800;
-       }
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 tmp;
-
-       ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       tmp = (buf[0] & 0x0f) << 8 | buf[1];
-       tmp = ~tmp & 0x0fff;
-
-       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
-       *strength = tmp * 0xffff / 0x0fff;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 tmp;
-       /* report SNR in dB * 10 */
-
-       ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       tmp = (buf[0] & 0x0f) << 8 | buf[1];
-       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
-       if (tmp)
-               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
-                       / 100);
-       else
-               *snr = 0;
-
-       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       /* no way to read ? */
-       return 0;
-}
-
-int cxd2820r_sleep_t2(struct dvb_frontend *fe)
-{
-       struct cxd2820r_priv *priv = fe->demodulator_priv;
-       int ret, i;
-       struct reg_val_mask tab[] = {
-               { 0x000ff, 0x1f, 0xff },
-               { 0x00085, 0x00, 0xff },
-               { 0x00088, 0x01, 0xff },
-               { 0x02069, 0x00, 0xff },
-               { 0x00081, 0x00, 0xff },
-               { 0x00080, 0x00, 0xff },
-       };
-
-       dbg("%s", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
-                       tab[i].mask);
-               if (ret)
-                       goto error;
-       }
-
-       priv->delivery_system = SYS_UNDEFINED;
-
-       return ret;
-error:
-       dbg("%s: failed:%d", __func__, ret);
-       return ret;
-}
-
-int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 1500;
-       s->step_size = fe->ops.info.frequency_stepsize * 2;
-       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
-
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
deleted file mode 100644 (file)
index 3b024bf..0000000
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
- *
- * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * This code is more or less generated from another driver, please
- * excuse some codingstyle oddities.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_frontend.h"
-
-#include "dib0070.h"
-#include "dibx000_common.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { \
-       if (debug) { \
-               printk(KERN_DEBUG "DiB0070: "); \
-               printk(args); \
-               printk("\n"); \
-       } \
-} while (0)
-
-#define DIB0070_P1D  0x00
-#define DIB0070_P1F  0x01
-#define DIB0070_P1G  0x03
-#define DIB0070S_P1A 0x02
-
-struct dib0070_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe;
-       const struct dib0070_config *cfg;
-       u16 wbd_ff_offset;
-       u8 revision;
-
-    enum frontend_tune_state tune_state;
-    u32 current_rf;
-
-    /* for the captrim binary search */
-       s8 step;
-       u16 adc_diff;
-
-       s8 captrim;
-       s8 fcaptrim;
-       u16 lo4;
-
-       const struct dib0070_tuning *current_tune_table_index;
-       const struct dib0070_lna_match *lna_match;
-
-    u8  wbd_gain_current;
-       u16 wbd_offset_3_3[2];
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[3];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-};
-
-static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = reg;
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->cfg->i2c_address;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 1;
-       state->msg[1].addr = state->cfg->i2c_address;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = state->i2c_read_buffer;
-       state->msg[1].len = 2;
-
-       if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
-               printk(KERN_WARNING "DiB0070 I2C read failed\n");
-               ret = 0;
-       } else
-               ret = (state->i2c_read_buffer[0] << 8)
-                       | state->i2c_read_buffer[1];
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-       state->i2c_write_buffer[0] = reg;
-       state->i2c_write_buffer[1] = val >> 8;
-       state->i2c_write_buffer[2] = val & 0xff;
-
-       memset(state->msg, 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->cfg->i2c_address;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 3;
-
-       if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
-               printk(KERN_WARNING "DiB0070 I2C write failed\n");
-               ret = -EREMOTEIO;
-       } else
-               ret = 0;
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-#define HARD_RESET(state) do { \
-    state->cfg->sleep(state->fe, 0); \
-    if (state->cfg->reset) { \
-       state->cfg->reset(state->fe,1); msleep(10); \
-       state->cfg->reset(state->fe,0); msleep(10); \
-    } \
-} while (0)
-
-static int dib0070_set_bandwidth(struct dvb_frontend *fe)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-    u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
-
-    if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
-       tmp |= (0 << 14);
-    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
-       tmp |= (1 << 14);
-    else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
-       tmp |= (2 << 14);
-    else
-       tmp |= (3 << 14);
-
-    dib0070_write_reg(state, 0x02, tmp);
-
-    /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
-    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
-       u16 value = dib0070_read_reg(state, 0x17);
-
-       dib0070_write_reg(state, 0x17, value & 0xfffc);
-       tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
-       dib0070_write_reg(state, 0x01, tmp | (60 << 9));
-
-       dib0070_write_reg(state, 0x17, value);
-    }
-       return 0;
-}
-
-static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
-{
-       int8_t step_sign;
-       u16 adc;
-       int ret = 0;
-
-       if (*tune_state == CT_TUNER_STEP_0) {
-
-               dib0070_write_reg(state, 0x0f, 0xed10);
-               dib0070_write_reg(state, 0x17,    0x0034);
-
-               dib0070_write_reg(state, 0x18, 0x0032);
-               state->step = state->captrim = state->fcaptrim = 64;
-               state->adc_diff = 3000;
-               ret = 20;
-
-       *tune_state = CT_TUNER_STEP_1;
-       } else if (*tune_state == CT_TUNER_STEP_1) {
-               state->step /= 2;
-               dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
-               ret = 15;
-
-               *tune_state = CT_TUNER_STEP_2;
-       } else if (*tune_state == CT_TUNER_STEP_2) {
-
-               adc = dib0070_read_reg(state, 0x19);
-
-               dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
-
-               if (adc >= 400) {
-                       adc -= 400;
-                       step_sign = -1;
-               } else {
-                       adc = 400 - adc;
-                       step_sign = 1;
-               }
-
-               if (adc < state->adc_diff) {
-                       dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
-                       state->adc_diff = adc;
-                       state->fcaptrim = state->captrim;
-
-
-
-               }
-               state->captrim += (step_sign * state->step);
-
-               if (state->step >= 1)
-                       *tune_state = CT_TUNER_STEP_1;
-               else
-                       *tune_state = CT_TUNER_STEP_3;
-
-       } else if (*tune_state == CT_TUNER_STEP_3) {
-               dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
-               dib0070_write_reg(state, 0x18, 0x07ff);
-               *tune_state = CT_TUNER_STEP_4;
-       }
-
-       return ret;
-}
-
-static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
-       dprintk("CTRL_LO5: 0x%x", lo5);
-       return dib0070_write_reg(state, 0x15, lo5);
-}
-
-void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-
-       if (open) {
-               dib0070_write_reg(state, 0x1b, 0xff00);
-               dib0070_write_reg(state, 0x1a, 0x0000);
-       } else {
-               dib0070_write_reg(state, 0x1b, 0x4112);
-       if (state->cfg->vga_filter != 0) {
-               dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
-               dprintk("vga filter register is set to %x", state->cfg->vga_filter);
-       } else
-               dib0070_write_reg(state, 0x1a, 0x0009);
-       }
-}
-
-EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
-struct dib0070_tuning {
-    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
-    u8 switch_trim;
-    u8 vco_band;
-    u8 hfdiv;
-    u8 vco_multi;
-    u8 presc;
-    u8 wbdmux;
-    u16 tuner_enable;
-};
-
-struct dib0070_lna_match {
-    u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
-    u8 lna_band;
-};
-
-static const struct dib0070_tuning dib0070s_tuning_table[] = {
-    {     570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
-    {     700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
-    {     863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
-    {    1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
-    {    1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
-    {    2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
-    { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
-};
-
-static const struct dib0070_tuning dib0070_tuning_table[] = {
-    {     115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
-    {     179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
-    {     189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
-    {     250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
-    {     569999, 2, 1, 5,  6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
-    {     699999, 2, 0, 1,  4, 2, 2, 0x4000 | 0x0800 },
-    {     863999, 2, 1, 1,  4, 2, 2, 0x4000 | 0x0800 },
-    { 0xffffffff, 0, 1, 0,  2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
-};
-
-static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
-    {     180000, 0 }, /* VHF */
-    {     188000, 1 },
-    {     196400, 2 },
-    {     250000, 3 },
-    {     550000, 0 }, /* UHF */
-    {     590000, 1 },
-    {     666000, 3 },
-    {     864000, 5 },
-    {    1500000, 0 }, /* LBAND or everything higher than UHF */
-    {    1600000, 1 },
-    {    2000000, 3 },
-    { 0xffffffff, 7 },
-};
-
-static const struct dib0070_lna_match dib0070_lna[] = {
-    {     180000, 0 }, /* VHF */
-    {     188000, 1 },
-    {     196400, 2 },
-    {     250000, 3 },
-    {     550000, 2 }, /* UHF */
-    {     650000, 3 },
-    {     750000, 5 },
-    {     850000, 6 },
-    {     864000, 7 },
-    {    1500000, 0 }, /* LBAND or everything higher than UHF */
-    {    1600000, 1 },
-    {    2000000, 3 },
-    { 0xffffffff, 7 },
-};
-
-#define LPF    100
-static int dib0070_tune_digital(struct dvb_frontend *fe)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-
-    const struct dib0070_tuning *tune;
-    const struct dib0070_lna_match *lna_match;
-
-    enum frontend_tune_state *tune_state = &state->tune_state;
-    int ret = 10; /* 1ms is the default delay most of the time */
-
-    u8  band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
-    u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
-
-#ifdef CONFIG_SYS_ISDBT
-    if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
-               if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
-                    && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
-                   || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
-                       && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
-                   || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
-                       && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
-                       freq += 850;
-#endif
-    if (state->current_rf != freq) {
-
-       switch (state->revision) {
-       case DIB0070S_P1A:
-           tune = dib0070s_tuning_table;
-           lna_match = dib0070_lna;
-           break;
-       default:
-           tune = dib0070_tuning_table;
-           if (state->cfg->flip_chip)
-               lna_match = dib0070_lna_flip_chip;
-           else
-               lna_match = dib0070_lna;
-           break;
-       }
-       while (freq > tune->max_freq) /* find the right one */
-           tune++;
-       while (freq > lna_match->max_freq) /* find the right one */
-           lna_match++;
-
-       state->current_tune_table_index = tune;
-       state->lna_match = lna_match;
-    }
-
-    if (*tune_state == CT_TUNER_START) {
-       dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
-       if (state->current_rf != freq) {
-               u8 REFDIV;
-               u32 FBDiv, Rest, FREF, VCOF_kHz;
-               u8 Den;
-
-               state->current_rf = freq;
-               state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
-
-
-               dib0070_write_reg(state, 0x17, 0x30);
-
-
-               VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
-
-               switch (band) {
-               case BAND_VHF:
-                       REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
-                       break;
-               case BAND_FM:
-                       REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
-                       break;
-               default:
-                       REFDIV = (u8) (state->cfg->clock_khz  / 10000);
-                       break;
-               }
-               FREF = state->cfg->clock_khz / REFDIV;
-
-
-
-               switch (state->revision) {
-               case DIB0070S_P1A:
-                       FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
-                       Rest  = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
-                       break;
-
-               case DIB0070_P1G:
-               case DIB0070_P1F:
-               default:
-                       FBDiv = (freq / (FREF / 2));
-                       Rest  = 2 * freq - FBDiv * FREF;
-                       break;
-               }
-
-               if (Rest < LPF)
-                       Rest = 0;
-               else if (Rest < 2 * LPF)
-                       Rest = 2 * LPF;
-               else if (Rest > (FREF - LPF)) {
-                       Rest = 0;
-                       FBDiv += 1;
-               } else if (Rest > (FREF - 2 * LPF))
-                       Rest = FREF - 2 * LPF;
-               Rest = (Rest * 6528) / (FREF / 10);
-
-               Den = 1;
-               if (Rest > 0) {
-                       state->lo4 |= (1 << 14) | (1 << 12);
-                       Den = 255;
-               }
-
-
-               dib0070_write_reg(state, 0x11, (u16)FBDiv);
-               dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
-               dib0070_write_reg(state, 0x13, (u16) Rest);
-
-               if (state->revision == DIB0070S_P1A) {
-
-                       if (band == BAND_SBAND) {
-                               dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-                               dib0070_write_reg(state, 0x1d, 0xFFFF);
-                       } else
-                               dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
-               }
-
-               dib0070_write_reg(state, 0x20,
-                       0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
-
-               dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
-               dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
-               dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
-               dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
-               dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
-               dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
-
-               *tune_state = CT_TUNER_STEP_0;
-       } else { /* we are already tuned to this frequency - the configuration is correct  */
-               ret = 50; /* wakeup time */
-               *tune_state = CT_TUNER_STEP_5;
-       }
-    } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
-
-       ret = dib0070_captrim(state, tune_state);
-
-    } else if (*tune_state == CT_TUNER_STEP_4) {
-       const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-       if (tmp != NULL) {
-               while (freq/1000 > tmp->freq) /* find the right one */
-                       tmp++;
-               dib0070_write_reg(state, 0x0f,
-                       (0 << 15) | (1 << 14) | (3 << 12)
-                       | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
-                       | (state->current_tune_table_index->wbdmux << 0));
-               state->wbd_gain_current = tmp->wbd_gain_val;
-       } else {
-                       dib0070_write_reg(state, 0x0f,
-                                         (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
-                                                                                                               wbdmux << 0));
-           state->wbd_gain_current = 6;
-       }
-
-       dib0070_write_reg(state, 0x06, 0x3fff);
-               dib0070_write_reg(state, 0x07,
-                                 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
-       dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
-       dib0070_write_reg(state, 0x0d, 0x0d80);
-
-
-       dib0070_write_reg(state, 0x18,   0x07ff);
-       dib0070_write_reg(state, 0x17, 0x0033);
-
-
-       *tune_state = CT_TUNER_STEP_5;
-    } else if (*tune_state == CT_TUNER_STEP_5) {
-       dib0070_set_bandwidth(fe);
-       *tune_state = CT_TUNER_STOP;
-    } else {
-       ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
-    }
-    return ret;
-}
-
-
-static int dib0070_tune(struct dvb_frontend *fe)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-    uint32_t ret;
-
-    state->tune_state = CT_TUNER_START;
-
-    do {
-       ret = dib0070_tune_digital(fe);
-       if (ret != FE_CALLBACK_TIME_NEVER)
-               msleep(ret/10);
-       else
-           break;
-    } while (state->tune_state != CT_TUNER_STOP);
-
-    return 0;
-}
-
-static int dib0070_wakeup(struct dvb_frontend *fe)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-       if (state->cfg->sleep)
-               state->cfg->sleep(fe, 0);
-       return 0;
-}
-
-static int dib0070_sleep(struct dvb_frontend *fe)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-       if (state->cfg->sleep)
-               state->cfg->sleep(fe, 1);
-       return 0;
-}
-
-u8 dib0070_get_rf_output(struct dvb_frontend *fe)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-       return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
-}
-EXPORT_SYMBOL(dib0070_get_rf_output);
-
-int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
-{
-       struct dib0070_state *state = fe->tuner_priv;
-       u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
-       if (no > 3)
-               no = 3;
-       if (no < 1)
-               no = 1;
-       return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
-}
-EXPORT_SYMBOL(dib0070_set_rf_output);
-
-static const u16 dib0070_p1f_defaults[] =
-
-{
-       7, 0x02,
-               0x0008,
-               0x0000,
-               0x0000,
-               0x0000,
-               0x0000,
-               0x0002,
-               0x0100,
-
-       3, 0x0d,
-               0x0d80,
-               0x0001,
-               0x0000,
-
-       4, 0x11,
-               0x0000,
-               0x0103,
-               0x0000,
-               0x0000,
-
-       3, 0x16,
-               0x0004 | 0x0040,
-               0x0030,
-               0x07ff,
-
-       6, 0x1b,
-               0x4112,
-               0xff00,
-               0xc07f,
-               0x0000,
-               0x0180,
-               0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
-
-       0,
-};
-
-static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
-{
-    u16 tuner_en = dib0070_read_reg(state, 0x20);
-    u16 offset;
-
-    dib0070_write_reg(state, 0x18, 0x07ff);
-    dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
-    dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
-    msleep(9);
-    offset = dib0070_read_reg(state, 0x19);
-    dib0070_write_reg(state, 0x20, tuner_en);
-    return offset;
-}
-
-static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
-{
-    u8 gain;
-    for (gain = 6; gain < 8; gain++) {
-       state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
-       dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
-    }
-}
-
-u16 dib0070_wbd_offset(struct dvb_frontend *fe)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-    const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
-    u32 freq = fe->dtv_property_cache.frequency/1000;
-
-    if (tmp != NULL) {
-       while (freq/1000 > tmp->freq) /* find the right one */
-           tmp++;
-       state->wbd_gain_current = tmp->wbd_gain_val;
-       } else
-       state->wbd_gain_current = 6;
-
-    return state->wbd_offset_3_3[state->wbd_gain_current - 6];
-}
-EXPORT_SYMBOL(dib0070_wbd_offset);
-
-#define pgm_read_word(w) (*w)
-static int dib0070_reset(struct dvb_frontend *fe)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-       u16 l, r, *n;
-
-       HARD_RESET(state);
-
-
-#ifndef FORCE_SBAND_TUNER
-       if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
-               state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
-       else
-#else
-#warning forcing SBAND
-#endif
-               state->revision = DIB0070S_P1A;
-
-       /* P1F or not */
-       dprintk("Revision: %x", state->revision);
-
-       if (state->revision == DIB0070_P1D) {
-               dprintk("Error: this driver is not to be used meant for P1D or earlier");
-               return -EINVAL;
-       }
-
-       n = (u16 *) dib0070_p1f_defaults;
-       l = pgm_read_word(n++);
-       while (l) {
-               r = pgm_read_word(n++);
-               do {
-                       dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
-                       r++;
-               } while (--l);
-               l = pgm_read_word(n++);
-       }
-
-       if (state->cfg->force_crystal_mode != 0)
-               r = state->cfg->force_crystal_mode;
-       else if (state->cfg->clock_khz >= 24000)
-               r = 1;
-       else
-               r = 2;
-
-
-       r |= state->cfg->osc_buffer_state << 3;
-
-       dib0070_write_reg(state, 0x10, r);
-       dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
-
-       if (state->cfg->invert_iq) {
-               r = dib0070_read_reg(state, 0x02) & 0xffdf;
-               dib0070_write_reg(state, 0x02, r | (1 << 5));
-       }
-
-    if (state->revision == DIB0070S_P1A)
-       dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
-    else
-               dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
-
-       dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
-
-    dib0070_wbd_offset_calibration(state);
-
-    return 0;
-}
-
-static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-    struct dib0070_state *state = fe->tuner_priv;
-
-    *frequency = 1000 * state->current_rf;
-    return 0;
-}
-
-static int dib0070_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops dib0070_ops = {
-       .info = {
-               .name           = "DiBcom DiB0070",
-               .frequency_min  =  45000000,
-               .frequency_max  = 860000000,
-               .frequency_step =      1000,
-       },
-       .release       = dib0070_release,
-
-       .init          = dib0070_wakeup,
-       .sleep         = dib0070_sleep,
-       .set_params    = dib0070_tune,
-
-       .get_frequency = dib0070_get_frequency,
-//      .get_bandwidth = dib0070_get_bandwidth
-};
-
-struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
-{
-       struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->cfg = cfg;
-       state->i2c = i2c;
-       state->fe  = fe;
-       mutex_init(&state->i2c_buffer_lock);
-       fe->tuner_priv = state;
-
-       if (dib0070_reset(fe) != 0)
-               goto free_mem;
-
-       printk(KERN_INFO "DiB0070: successfully identified\n");
-       memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = state;
-       return fe;
-
-free_mem:
-       kfree(state);
-       fe->tuner_priv = NULL;
-       return NULL;
-}
-EXPORT_SYMBOL(dib0070_attach);
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
deleted file mode 100644 (file)
index 45c31fa..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
- *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#ifndef DIB0070_H
-#define DIB0070_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
-
-struct dib0070_wbd_gain_cfg {
-       u16 freq;
-       u16 wbd_gain_val;
-};
-
-struct dib0070_config {
-       u8 i2c_address;
-
-       /* tuner pins controlled externally */
-       int (*reset) (struct dvb_frontend *, int);
-       int (*sleep) (struct dvb_frontend *, int);
-
-       /*  offset in kHz */
-       int freq_offset_khz_uhf;
-       int freq_offset_khz_vhf;
-
-       u8 osc_buffer_state;    /* 0= normal, 1= tri-state */
-       u32 clock_khz;
-       u8 clock_pad_drive;     /* (Drive + 1) * 2mA */
-
-       u8 invert_iq;           /* invert Q - in case I or Q is inverted on the board */
-
-       u8 force_crystal_mode;  /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
-
-       u8 flip_chip;
-       u8 enable_third_order_filter;
-       u8 charge_pump;
-
-       const struct dib0070_wbd_gain_cfg *wbd_gain;
-
-       u8 vga_filter;
-};
-
-#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
-extern u16 dib0070_wbd_offset(struct dvb_frontend *);
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
-extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
-extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
-#else
-static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-
-static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
deleted file mode 100644 (file)
index d9fe60b..0000000
+++ /dev/null
@@ -1,2686 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
- *
- * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * This code is more or less generated from another driver, please
- * excuse some codingstyle oddities.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_frontend.h"
-
-#include "dib0090.h"
-#include "dibx000_common.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { \
-       if (debug) { \
-               printk(KERN_DEBUG "DiB0090: "); \
-               printk(args); \
-               printk("\n"); \
-       } \
-} while (0)
-
-#define CONFIG_SYS_DVBT
-#define CONFIG_SYS_ISDBT
-#define CONFIG_BAND_CBAND
-#define CONFIG_BAND_VHF
-#define CONFIG_BAND_UHF
-#define CONFIG_DIB0090_USE_PWM_AGC
-
-#define EN_LNA0      0x8000
-#define EN_LNA1      0x4000
-#define EN_LNA2      0x2000
-#define EN_LNA3      0x1000
-#define EN_MIX0      0x0800
-#define EN_MIX1      0x0400
-#define EN_MIX2      0x0200
-#define EN_MIX3      0x0100
-#define EN_IQADC     0x0040
-#define EN_PLL       0x0020
-#define EN_TX        0x0010
-#define EN_BB        0x0008
-#define EN_LO        0x0004
-#define EN_BIAS      0x0001
-
-#define EN_IQANA     0x0002
-#define EN_DIGCLK    0x0080    /* not in the 0x24 reg, only in 0x1b */
-#define EN_CRYSTAL   0x0002
-
-#define EN_UHF          0x22E9
-#define EN_VHF          0x44E9
-#define EN_LBD          0x11E9
-#define EN_SBD          0x44E9
-#define EN_CAB          0x88E9
-
-/* Calibration defines */
-#define      DC_CAL 0x1
-#define     WBD_CAL 0x2
-#define    TEMP_CAL 0x4
-#define CAPTRIM_CAL 0x8
-
-#define KROSUS_PLL_LOCKED   0x800
-#define KROSUS              0x2
-
-/* Use those defines to identify SOC version */
-#define SOC               0x02
-#define SOC_7090_P1G_11R1 0x82
-#define SOC_7090_P1G_21R1 0x8a
-#define SOC_8090_P1G_11R1 0x86
-#define SOC_8090_P1G_21R1 0x8e
-
-/* else use thos ones to check */
-#define P1A_B      0x0
-#define P1C       0x1
-#define P1D_E_F    0x3
-#define P1G       0x7
-#define P1G_21R2   0xf
-
-#define MP001 0x1              /* Single 9090/8096 */
-#define MP005 0x4              /* Single Sband */
-#define MP008 0x6              /* Dual diversity VHF-UHF-LBAND */
-#define MP009 0x7              /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
-
-#define pgm_read_word(w) (*w)
-
-struct dc_calibration;
-
-struct dib0090_tuning {
-       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
-       u8 switch_trim;
-       u8 lna_tune;
-       u16 lna_bias;
-       u16 v2i;
-       u16 mix;
-       u16 load;
-       u16 tuner_enable;
-};
-
-struct dib0090_pll {
-       u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
-       u8 vco_band;
-       u8 hfdiv_code;
-       u8 hfdiv;
-       u8 topresc;
-};
-
-struct dib0090_identity {
-       u8 version;
-       u8 product;
-       u8 p1g;
-       u8 in_soc;
-};
-
-struct dib0090_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe;
-       const struct dib0090_config *config;
-
-       u8 current_band;
-       enum frontend_tune_state tune_state;
-       u32 current_rf;
-
-       u16 wbd_offset;
-       s16 wbd_target;         /* in dB */
-
-       s16 rf_gain_limit;      /* take-over-point: where to split between bb and rf gain */
-       s16 current_gain;       /* keeps the currently programmed gain */
-       u8 agc_step;            /* new binary search */
-
-       u16 gain[2];            /* for channel monitoring */
-
-       const u16 *rf_ramp;
-       const u16 *bb_ramp;
-
-       /* for the software AGC ramps */
-       u16 bb_1_def;
-       u16 rf_lt_def;
-       u16 gain_reg[4];
-
-       /* for the captrim/dc-offset search */
-       s8 step;
-       s16 adc_diff;
-       s16 min_adc_diff;
-
-       s8 captrim;
-       s8 fcaptrim;
-
-       const struct dc_calibration *dc;
-       u16 bb6, bb7;
-
-       const struct dib0090_tuning *current_tune_table_index;
-       const struct dib0090_pll *current_pll_table_index;
-
-       u8 tuner_is_tuned;
-       u8 agc_freeze;
-
-       struct dib0090_identity identity;
-
-       u32 rf_request;
-       u8 current_standard;
-
-       u8 calibrate;
-       u32 rest;
-       u16 bias;
-       s16 temperature;
-
-       u8 wbd_calibration_gain;
-       const struct dib0090_wbd_slope *current_wbd_table;
-       u16 wbdmux;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[3];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-};
-
-struct dib0090_fw_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe;
-       struct dib0090_identity identity;
-       const struct dib0090_config *config;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg;
-       u8 i2c_write_buffer[2];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-};
-
-static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = reg;
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->config->i2c_address;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 1;
-       state->msg[1].addr = state->config->i2c_address;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = state->i2c_read_buffer;
-       state->msg[1].len = 2;
-
-       if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
-               printk(KERN_WARNING "DiB0090 I2C read failed\n");
-               ret = 0;
-       } else
-               ret = (state->i2c_read_buffer[0] << 8)
-                       | state->i2c_read_buffer[1];
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       state->i2c_write_buffer[0] = reg & 0xff;
-       state->i2c_write_buffer[1] = val >> 8;
-       state->i2c_write_buffer[2] = val & 0xff;
-
-       memset(state->msg, 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->config->i2c_address;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 3;
-
-       if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
-               printk(KERN_WARNING "DiB0090 I2C write failed\n");
-               ret = -EREMOTEIO;
-       } else
-               ret = 0;
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = reg;
-
-       memset(&state->msg, 0, sizeof(struct i2c_msg));
-       state->msg.addr = reg;
-       state->msg.flags = I2C_M_RD;
-       state->msg.buf = state->i2c_read_buffer;
-       state->msg.len = 2;
-       if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
-               printk(KERN_WARNING "DiB0090 I2C read failed\n");
-               ret = 0;
-       } else
-               ret = (state->i2c_read_buffer[0] << 8)
-                       | state->i2c_read_buffer[1];
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       state->i2c_write_buffer[0] = val >> 8;
-       state->i2c_write_buffer[1] = val & 0xff;
-
-       memset(&state->msg, 0, sizeof(struct i2c_msg));
-       state->msg.addr = reg;
-       state->msg.flags = 0;
-       state->msg.buf = state->i2c_write_buffer;
-       state->msg.len = 2;
-       if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
-               printk(KERN_WARNING "DiB0090 I2C write failed\n");
-               ret = -EREMOTEIO;
-       } else
-               ret = 0;
-
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-#define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
-#define ADC_TARGET -220
-#define GAIN_ALPHA 5
-#define WBD_ALPHA 6
-#define LPF    100
-static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
-{
-       do {
-               dib0090_write_reg(state, r++, *b++);
-       } while (--c);
-}
-
-static int dib0090_identify(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       u16 v;
-       struct dib0090_identity *identity = &state->identity;
-
-       v = dib0090_read_reg(state, 0x1a);
-
-       identity->p1g = 0;
-       identity->in_soc = 0;
-
-       dprintk("Tuner identification (Version = 0x%04x)", v);
-
-       /* without PLL lock info */
-       v &= ~KROSUS_PLL_LOCKED;
-
-       identity->version = v & 0xff;
-       identity->product = (v >> 8) & 0xf;
-
-       if (identity->product != KROSUS)
-               goto identification_error;
-
-       if ((identity->version & 0x3) == SOC) {
-               identity->in_soc = 1;
-               switch (identity->version) {
-               case SOC_8090_P1G_11R1:
-                       dprintk("SOC 8090 P1-G11R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_8090_P1G_21R1:
-                       dprintk("SOC 8090 P1-G21R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_7090_P1G_11R1:
-                       dprintk("SOC 7090 P1-G11R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_7090_P1G_21R1:
-                       dprintk("SOC 7090 P1-G21R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               default:
-                       goto identification_error;
-               }
-       } else {
-               switch ((identity->version >> 5) & 0x7) {
-               case MP001:
-                       dprintk("MP001 : 9090/8096");
-                       break;
-               case MP005:
-                       dprintk("MP005 : Single Sband");
-                       break;
-               case MP008:
-                       dprintk("MP008 : diversity VHF-UHF-LBAND");
-                       break;
-               case MP009:
-                       dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
-                       break;
-               default:
-                       goto identification_error;
-               }
-
-               switch (identity->version & 0x1f) {
-               case P1G_21R2:
-                       dprintk("P1G_21R2 detected");
-                       identity->p1g = 1;
-                       break;
-               case P1G:
-                       dprintk("P1G detected");
-                       identity->p1g = 1;
-                       break;
-               case P1D_E_F:
-                       dprintk("P1D/E/F detected");
-                       break;
-               case P1C:
-                       dprintk("P1C detected");
-                       break;
-               case P1A_B:
-                       dprintk("P1-A/B detected: driver is deactivated - not available");
-                       goto identification_error;
-                       break;
-               default:
-                       goto identification_error;
-               }
-       }
-
-       return 0;
-
-identification_error:
-       return -EIO;
-}
-
-static int dib0090_fw_identify(struct dvb_frontend *fe)
-{
-       struct dib0090_fw_state *state = fe->tuner_priv;
-       struct dib0090_identity *identity = &state->identity;
-
-       u16 v = dib0090_fw_read_reg(state, 0x1a);
-       identity->p1g = 0;
-       identity->in_soc = 0;
-
-       dprintk("FE: Tuner identification (Version = 0x%04x)", v);
-
-       /* without PLL lock info */
-       v &= ~KROSUS_PLL_LOCKED;
-
-       identity->version = v & 0xff;
-       identity->product = (v >> 8) & 0xf;
-
-       if (identity->product != KROSUS)
-               goto identification_error;
-
-       if ((identity->version & 0x3) == SOC) {
-               identity->in_soc = 1;
-               switch (identity->version) {
-               case SOC_8090_P1G_11R1:
-                       dprintk("SOC 8090 P1-G11R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_8090_P1G_21R1:
-                       dprintk("SOC 8090 P1-G21R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_7090_P1G_11R1:
-                       dprintk("SOC 7090 P1-G11R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               case SOC_7090_P1G_21R1:
-                       dprintk("SOC 7090 P1-G21R1 Has been detected");
-                       identity->p1g = 1;
-                       break;
-               default:
-                       goto identification_error;
-               }
-       } else {
-               switch ((identity->version >> 5) & 0x7) {
-               case MP001:
-                       dprintk("MP001 : 9090/8096");
-                       break;
-               case MP005:
-                       dprintk("MP005 : Single Sband");
-                       break;
-               case MP008:
-                       dprintk("MP008 : diversity VHF-UHF-LBAND");
-                       break;
-               case MP009:
-                       dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
-                       break;
-               default:
-                       goto identification_error;
-               }
-
-               switch (identity->version & 0x1f) {
-               case P1G_21R2:
-                       dprintk("P1G_21R2 detected");
-                       identity->p1g = 1;
-                       break;
-               case P1G:
-                       dprintk("P1G detected");
-                       identity->p1g = 1;
-                       break;
-               case P1D_E_F:
-                       dprintk("P1D/E/F detected");
-                       break;
-               case P1C:
-                       dprintk("P1C detected");
-                       break;
-               case P1A_B:
-                       dprintk("P1-A/B detected: driver is deactivated - not available");
-                       goto identification_error;
-                       break;
-               default:
-                       goto identification_error;
-               }
-       }
-
-       return 0;
-
-identification_error:
-       return -EIO;
-}
-
-static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       u16 PllCfg, i, v;
-
-       HARD_RESET(state);
-
-       dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
-       dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);        /* PLL, DIG_CLK and CRYSTAL remain */
-
-       if (!cfg->in_soc) {
-               /* adcClkOutRatio=8->7, release reset */
-               dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
-               if (cfg->clkoutdrive != 0)
-                       dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
-                                         | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
-               else
-                       dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
-                                         | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
-       }
-
-       /* Read Pll current config * */
-       PllCfg = dib0090_read_reg(state, 0x21);
-
-       /** Reconfigure PLL if current setting is different from default setting **/
-       if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
-                       && !cfg->io.pll_bypass) {
-
-               /* Set Bypass mode */
-               PllCfg |= (1 << 15);
-               dib0090_write_reg(state, 0x21, PllCfg);
-
-               /* Set Reset Pll */
-               PllCfg &= ~(1 << 13);
-               dib0090_write_reg(state, 0x21, PllCfg);
-
-       /*** Set new Pll configuration in bypass and reset state ***/
-               PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
-               dib0090_write_reg(state, 0x21, PllCfg);
-
-               /* Remove Reset Pll */
-               PllCfg |= (1 << 13);
-               dib0090_write_reg(state, 0x21, PllCfg);
-
-       /*** Wait for PLL lock ***/
-               i = 100;
-               do {
-                       v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
-                       if (v)
-                               break;
-               } while (--i);
-
-               if (i == 0) {
-                       dprintk("Pll: Unable to lock Pll");
-                       return;
-               }
-
-               /* Finally Remove Bypass mode */
-               PllCfg &= ~(1 << 15);
-               dib0090_write_reg(state, 0x21, PllCfg);
-       }
-
-       if (cfg->io.pll_bypass) {
-               PllCfg |= (cfg->io.pll_bypass << 15);
-               dib0090_write_reg(state, 0x21, PllCfg);
-       }
-}
-
-static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
-{
-       struct dib0090_fw_state *state = fe->tuner_priv;
-       u16 PllCfg;
-       u16 v;
-       int i;
-
-       dprintk("fw reset digital");
-       HARD_RESET(state);
-
-       dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
-       dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);     /* PLL, DIG_CLK and CRYSTAL remain */
-
-       dib0090_fw_write_reg(state, 0x20,
-                       ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
-
-       v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
-       if (cfg->clkoutdrive != 0)
-               v |= cfg->clkoutdrive << 5;
-       else
-               v |= 7 << 5;
-
-       v |= 2 << 10;
-       dib0090_fw_write_reg(state, 0x23, v);
-
-       /* Read Pll current config * */
-       PllCfg = dib0090_fw_read_reg(state, 0x21);
-
-       /** Reconfigure PLL if current setting is different from default setting **/
-       if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
-
-               /* Set Bypass mode */
-               PllCfg |= (1 << 15);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-
-               /* Set Reset Pll */
-               PllCfg &= ~(1 << 13);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-
-       /*** Set new Pll configuration in bypass and reset state ***/
-               PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-
-               /* Remove Reset Pll */
-               PllCfg |= (1 << 13);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-
-       /*** Wait for PLL lock ***/
-               i = 100;
-               do {
-                       v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
-                       if (v)
-                               break;
-               } while (--i);
-
-               if (i == 0) {
-                       dprintk("Pll: Unable to lock Pll");
-                       return -EIO;
-               }
-
-               /* Finally Remove Bypass mode */
-               PllCfg &= ~(1 << 15);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-       }
-
-       if (cfg->io.pll_bypass) {
-               PllCfg |= (cfg->io.pll_bypass << 15);
-               dib0090_fw_write_reg(state, 0x21, PllCfg);
-       }
-
-       return dib0090_fw_identify(fe);
-}
-
-static int dib0090_wakeup(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       if (state->config->sleep)
-               state->config->sleep(fe, 0);
-
-       /* enable dataTX in case we have been restarted in the wrong moment */
-       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
-       return 0;
-}
-
-static int dib0090_sleep(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       if (state->config->sleep)
-               state->config->sleep(fe, 1);
-       return 0;
-}
-
-void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       if (fast)
-               dib0090_write_reg(state, 0x04, 0);
-       else
-               dib0090_write_reg(state, 0x04, 1);
-}
-
-EXPORT_SYMBOL(dib0090_dcc_freq);
-
-static const u16 bb_ramp_pwm_normal_socs[] = {
-       550,                    /* max BB gain in 10th of dB */
-       (1 << 9) | 8,           /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
-       440,
-       (4 << 9) | 0,           /* BB_RAMP3 = 26dB */
-       (0 << 9) | 208,         /* BB_RAMP4 */
-       (4 << 9) | 208,         /* BB_RAMP5 = 29dB */
-       (0 << 9) | 440,         /* BB_RAMP6 */
-};
-
-static const u16 rf_ramp_pwm_cband_7090[] = {
-       280,                    /* max RF gain in 10th of dB */
-       18,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
-       504,                    /* ramp_max = maximum X used on the ramp */
-       (29 << 10) | 364,       /* RF_RAMP5, LNA 1 = 8dB */
-       (0 << 10) | 504,        /* RF_RAMP6, LNA 1 */
-       (60 << 10) | 228,       /* RF_RAMP7, LNA 2 = 7.7dB */
-       (0 << 10) | 364,        /* RF_RAMP8, LNA 2 */
-       (34 << 10) | 109,       /* GAIN_4_1, LNA 3 = 6.8dB */
-       (0 << 10) | 228,        /* GAIN_4_2, LNA 3 */
-       (37 << 10) | 0,         /* RF_RAMP3, LNA 4 = 6.2dB */
-       (0 << 10) | 109,        /* RF_RAMP4, LNA 4 */
-};
-
-static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
-       186,
-       40,
-       746,
-       (10 << 10) | 345,
-       (0  << 10) | 746,
-       (0 << 10) | 0,
-       (0  << 10) | 0,
-       (28 << 10) | 200,
-       (0  << 10) | 345,
-       (20 << 10) | 0,
-       (0  << 10) | 200,
-};
-
-static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
-       86,
-       40,
-       345,
-       (0 << 10) | 0,
-       (0 << 10) | 0,
-       (0 << 10) | 0,
-       (0 << 10) | 0,
-       (28 << 10) | 200,
-       (0  << 10) | 345,
-       (20 << 10) | 0,
-       (0  << 10) | 200,
-};
-
-static const u16 rf_ramp_pwm_cband_8090[] = {
-       345,                    /* max RF gain in 10th of dB */
-       29,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
-       1000,                   /* ramp_max = maximum X used on the ramp */
-       (35 << 10) | 772,       /* RF_RAMP3, LNA 1 = 8dB */
-       (0 << 10) | 1000,       /* RF_RAMP4, LNA 1 */
-       (58 << 10) | 496,       /* RF_RAMP5, LNA 2 = 9.5dB */
-       (0 << 10) | 772,        /* RF_RAMP6, LNA 2 */
-       (27 << 10) | 200,       /* RF_RAMP7, LNA 3 = 10.5dB */
-       (0 << 10) | 496,        /* RF_RAMP8, LNA 3 */
-       (40 << 10) | 0,         /* GAIN_4_1, LNA 4 = 7dB */
-       (0 << 10) | 200,        /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_pwm_uhf_7090[] = {
-       407,                    /* max RF gain in 10th of dB */
-       13,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
-       529,                    /* ramp_max = maximum X used on the ramp */
-       (23 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
-       (0 << 10) | 176,        /* RF_RAMP4, LNA 1 */
-       (63 << 10) | 400,       /* RF_RAMP5, LNA 2 = 8dB */
-       (0 << 10) | 529,        /* RF_RAMP6, LNA 2 */
-       (48 << 10) | 316,       /* RF_RAMP7, LNA 3 = 6.8dB */
-       (0 << 10) | 400,        /* RF_RAMP8, LNA 3 */
-       (29 << 10) | 176,       /* GAIN_4_1, LNA 4 = 11.5dB */
-       (0 << 10) | 316,        /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_pwm_uhf_8090[] = {
-       388,                    /* max RF gain in 10th of dB */
-       26,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
-       1008,                   /* ramp_max = maximum X used on the ramp */
-       (11 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
-       (0 << 10) | 369,        /* RF_RAMP4, LNA 1 */
-       (41 << 10) | 809,       /* RF_RAMP5, LNA 2 = 8dB */
-       (0 << 10) | 1008,       /* RF_RAMP6, LNA 2 */
-       (27 << 10) | 659,       /* RF_RAMP7, LNA 3 = 6dB */
-       (0 << 10) | 809,        /* RF_RAMP8, LNA 3 */
-       (14 << 10) | 369,       /* GAIN_4_1, LNA 4 = 11.5dB */
-       (0 << 10) | 659,        /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_pwm_cband[] = {
-       0,                      /* max RF gain in 10th of dB */
-       0,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
-       0,                      /* ramp_max = maximum X used on the ramp */
-       (0 << 10) | 0,          /* 0x2c, LNA 1 = 0dB */
-       (0 << 10) | 0,          /* 0x2d, LNA 1 */
-       (0 << 10) | 0,          /* 0x2e, LNA 2 = 0dB */
-       (0 << 10) | 0,          /* 0x2f, LNA 2 */
-       (0 << 10) | 0,          /* 0x30, LNA 3 = 0dB */
-       (0 << 10) | 0,          /* 0x31, LNA 3 */
-       (0 << 10) | 0,          /* GAIN_4_1, LNA 4 = 0dB */
-       (0 << 10) | 0,          /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_vhf[] = {
-       412,                    /* max RF gain in 10th of dB */
-       132, 307, 127,          /* LNA1,  13.2dB */
-       105, 412, 255,          /* LNA2,  10.5dB */
-       50, 50, 127,            /* LNA3,  5dB */
-       125, 175, 127,          /* LNA4,  12.5dB */
-       0, 0, 127,              /* CBAND, 0dB */
-};
-
-static const u16 rf_ramp_uhf[] = {
-       412,                    /* max RF gain in 10th of dB */
-       132, 307, 127,          /* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
-       105, 412, 255,          /* LNA2  : 10.5 dB */
-       50, 50, 127,            /* LNA3  :  5.0 dB */
-       125, 175, 127,          /* LNA4  : 12.5 dB */
-       0, 0, 127,              /* CBAND :  0.0 dB */
-};
-
-static const u16 rf_ramp_cband_broadmatching[] =       /* for p1G only */
-{
-       314,                    /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
-       84, 314, 127,           /* LNA1 */
-       80, 230, 255,           /* LNA2 */
-       80, 150, 127,           /* LNA3  It was measured 12dB, do not lock if 120 */
-       70, 70, 127,            /* LNA4 */
-       0, 0, 127,              /* CBAND */
-};
-
-static const u16 rf_ramp_cband[] = {
-       332,                    /* max RF gain in 10th of dB */
-       132, 252, 127,          /* LNA1,  dB */
-       80, 332, 255,           /* LNA2,  dB */
-       0, 0, 127,              /* LNA3,  dB */
-       0, 0, 127,              /* LNA4,  dB */
-       120, 120, 127,          /* LT1 CBAND */
-};
-
-static const u16 rf_ramp_pwm_vhf[] = {
-       404,                    /* max RF gain in 10th of dB */
-       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
-       1011,                   /* ramp_max = maximum X used on the ramp */
-       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
-       (0 << 10) | 756,        /* 0x2d, LNA 1 */
-       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
-       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
-       (16 << 10) | 290,       /* 0x30, LNA 3 = 5dB */
-       (0 << 10) | 417,        /* 0x31, LNA 3 */
-       (7 << 10) | 0,          /* GAIN_4_1, LNA 4 = 12.5dB */
-       (0 << 10) | 290,        /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 rf_ramp_pwm_uhf[] = {
-       404,                    /* max RF gain in 10th of dB */
-       25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
-       1011,                   /* ramp_max = maximum X used on the ramp */
-       (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
-       (0 << 10) | 756,        /* 0x2d, LNA 1 */
-       (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
-       (0 << 10) | 1011,       /* 0x2f, LNA 2 */
-       (16 << 10) | 0,         /* 0x30, LNA 3 = 5dB */
-       (0 << 10) | 127,        /* 0x31, LNA 3 */
-       (7 << 10) | 127,        /* GAIN_4_1, LNA 4 = 12.5dB */
-       (0 << 10) | 417,        /* GAIN_4_2, LNA 4 */
-};
-
-static const u16 bb_ramp_boost[] = {
-       550,                    /* max BB gain in 10th of dB */
-       260, 260, 26,           /* BB1, 26dB */
-       290, 550, 29,           /* BB2, 29dB */
-};
-
-static const u16 bb_ramp_pwm_normal[] = {
-       500,                    /* max RF gain in 10th of dB */
-       8,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
-       400,
-       (2 << 9) | 0,           /* 0x35 = 21dB */
-       (0 << 9) | 168,         /* 0x36 */
-       (2 << 9) | 168,         /* 0x37 = 29dB */
-       (0 << 9) | 400,         /* 0x38 */
-};
-
-struct slope {
-       s16 range;
-       s16 slope;
-};
-static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
-{
-       u8 i;
-       u16 rest;
-       u16 ret = 0;
-       for (i = 0; i < num; i++) {
-               if (val > slopes[i].range)
-                       rest = slopes[i].range;
-               else
-                       rest = val;
-               ret += (rest * slopes[i].slope) / slopes[i].range;
-               val -= rest;
-       }
-       return ret;
-}
-
-static const struct slope dib0090_wbd_slopes[3] = {
-       {66, 120},              /* -64,-52: offset -   65 */
-       {600, 170},             /* -52,-35: 65     -  665 */
-       {170, 250},             /* -45,-10: 665    - 835 */
-};
-
-static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
-{
-       wbd &= 0x3ff;
-       if (wbd < state->wbd_offset)
-               wbd = 0;
-       else
-               wbd -= state->wbd_offset;
-       /* -64dB is the floor */
-       return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
-}
-
-static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
-{
-       u16 offset = 250;
-
-       /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
-
-       if (state->current_band == BAND_VHF)
-               offset = 650;
-#ifndef FIRMWARE_FIREFLY
-       if (state->current_band == BAND_VHF)
-               offset = state->config->wbd_vhf_offset;
-       if (state->current_band == BAND_CBAND)
-               offset = state->config->wbd_cband_offset;
-#endif
-
-       state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
-       dprintk("wbd-target: %d dB", (u32) state->wbd_target);
-}
-
-static const int gain_reg_addr[4] = {
-       0x08, 0x0a, 0x0f, 0x01
-};
-
-static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
-{
-       u16 rf, bb, ref;
-       u16 i, v, gain_reg[4] = { 0 }, gain;
-       const u16 *g;
-
-       if (top_delta < -511)
-               top_delta = -511;
-       if (top_delta > 511)
-               top_delta = 511;
-
-       if (force) {
-               top_delta *= (1 << WBD_ALPHA);
-               gain_delta *= (1 << GAIN_ALPHA);
-       }
-
-       if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))       /* overflow */
-               state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
-       else
-               state->rf_gain_limit += top_delta;
-
-       if (state->rf_gain_limit < 0)   /*underflow */
-               state->rf_gain_limit = 0;
-
-       /* use gain as a temporary variable and correct current_gain */
-       gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
-       if (gain_delta >= ((s16) gain - state->current_gain))   /* overflow */
-               state->current_gain = gain;
-       else
-               state->current_gain += gain_delta;
-       /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
-       if (state->current_gain < 0)
-               state->current_gain = 0;
-
-       /* now split total gain to rf and bb gain */
-       gain = state->current_gain >> GAIN_ALPHA;
-
-       /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
-       if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
-               rf = state->rf_gain_limit >> WBD_ALPHA;
-               bb = gain - rf;
-               if (bb > state->bb_ramp[0])
-                       bb = state->bb_ramp[0];
-       } else {                /* high signal level -> all gains put on RF */
-               rf = gain;
-               bb = 0;
-       }
-
-       state->gain[0] = rf;
-       state->gain[1] = bb;
-
-       /* software ramp */
-       /* Start with RF gains */
-       g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
-       ref = rf;
-       for (i = 0; i < 7; i++) {       /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
-               if (g[0] == 0 || ref < (g[1] - g[0]))   /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
-                       v = 0;  /* force the gain to write for the current amp to be null */
-               else if (ref >= g[1])   /* Gain to set is higher than the high working point of this amp */
-                       v = g[2];       /* force this amp to be full gain */
-               else            /* compute the value to set to this amp because we are somewhere in his range */
-                       v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
-
-               if (i == 0)     /* LNA 1 reg mapping */
-                       gain_reg[0] = v;
-               else if (i == 1)        /* LNA 2 reg mapping */
-                       gain_reg[0] |= v << 7;
-               else if (i == 2)        /* LNA 3 reg mapping */
-                       gain_reg[1] = v;
-               else if (i == 3)        /* LNA 4 reg mapping */
-                       gain_reg[1] |= v << 7;
-               else if (i == 4)        /* CBAND LNA reg mapping */
-                       gain_reg[2] = v | state->rf_lt_def;
-               else if (i == 5)        /* BB gain 1 reg mapping */
-                       gain_reg[3] = v << 3;
-               else if (i == 6)        /* BB gain 2 reg mapping */
-                       gain_reg[3] |= v << 8;
-
-               g += 3;         /* go to next gain bloc */
-
-               /* When RF is finished, start with BB */
-               if (i == 4) {
-                       g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
-                       ref = bb;
-               }
-       }
-       gain_reg[3] |= state->bb_1_def;
-       gain_reg[3] |= ((bb % 10) * 100) / 125;
-
-#ifdef DEBUG_AGC
-       dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
-               gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
-#endif
-
-       /* Write the amplifier regs */
-       for (i = 0; i < 4; i++) {
-               v = gain_reg[i];
-               if (force || state->gain_reg[i] != v) {
-                       state->gain_reg[i] = v;
-                       dib0090_write_reg(state, gain_reg_addr[i], v);
-               }
-       }
-}
-
-static void dib0090_set_boost(struct dib0090_state *state, int onoff)
-{
-       state->bb_1_def &= 0xdfff;
-       state->bb_1_def |= onoff << 13;
-}
-
-static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
-{
-       state->rf_ramp = cfg;
-}
-
-static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
-{
-       state->rf_ramp = cfg;
-
-       dib0090_write_reg(state, 0x2a, 0xffff);
-
-       dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
-
-       dib0090_write_regs(state, 0x2c, cfg + 3, 6);
-       dib0090_write_regs(state, 0x3e, cfg + 9, 2);
-}
-
-static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
-{
-       state->bb_ramp = cfg;
-       dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
-}
-
-static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
-{
-       state->bb_ramp = cfg;
-
-       dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
-
-       dib0090_write_reg(state, 0x33, 0xffff);
-       dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
-       dib0090_write_regs(state, 0x35, cfg + 3, 4);
-}
-
-void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       /* reset the AGC */
-
-       if (state->config->use_pwm_agc) {
-#ifdef CONFIG_BAND_SBAND
-               if (state->current_band == BAND_SBAND) {
-                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
-                       dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
-               } else
-#endif
-#ifdef CONFIG_BAND_CBAND
-               if (state->current_band == BAND_CBAND) {
-                       if (state->identity.in_soc) {
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
-                               if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
-                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
-                               else if (state->identity.version == SOC_7090_P1G_11R1
-                                               || state->identity.version == SOC_7090_P1G_21R1) {
-                                       if (state->config->is_dib7090e) {
-                                               if (state->rf_ramp == NULL)
-                                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
-                                               else
-                                                       dib0090_set_rframp_pwm(state, state->rf_ramp);
-                                       } else
-                                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
-                               }
-                       } else {
-                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
-                       }
-               } else
-#endif
-#ifdef CONFIG_BAND_VHF
-               if (state->current_band == BAND_VHF) {
-                       if (state->identity.in_soc) {
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
-                       } else {
-                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
-                       }
-               } else
-#endif
-               {
-                       if (state->identity.in_soc) {
-                               if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
-                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
-                               else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
-                                       dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
-                       } else {
-                               dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
-                               dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
-                       }
-               }
-
-               if (state->rf_ramp[0] != 0)
-                       dib0090_write_reg(state, 0x32, (3 << 11));
-               else
-                       dib0090_write_reg(state, 0x32, (0 << 11));
-
-               dib0090_write_reg(state, 0x04, 0x03);
-               dib0090_write_reg(state, 0x39, (1 << 10));
-       }
-}
-
-EXPORT_SYMBOL(dib0090_pwm_gain_reset);
-
-void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       if (DC_servo_cutoff < 4)
-               dib0090_write_reg(state, 0x04, DC_servo_cutoff);
-}
-EXPORT_SYMBOL(dib0090_set_dc_servo);
-
-static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
-{
-       u16 adc_val = dib0090_read_reg(state, 0x1d);
-       if (state->identity.in_soc)
-               adc_val >>= 2;
-       return adc_val;
-}
-
-int dib0090_gain_control(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       enum frontend_tune_state *tune_state = &state->tune_state;
-       int ret = 10;
-
-       u16 wbd_val = 0;
-       u8 apply_gain_immediatly = 1;
-       s16 wbd_error = 0, adc_error = 0;
-
-       if (*tune_state == CT_AGC_START) {
-               state->agc_freeze = 0;
-               dib0090_write_reg(state, 0x04, 0x0);
-
-#ifdef CONFIG_BAND_SBAND
-               if (state->current_band == BAND_SBAND) {
-                       dib0090_set_rframp(state, rf_ramp_sband);
-                       dib0090_set_bbramp(state, bb_ramp_boost);
-               } else
-#endif
-#ifdef CONFIG_BAND_VHF
-               if (state->current_band == BAND_VHF && !state->identity.p1g) {
-                       dib0090_set_rframp(state, rf_ramp_vhf);
-                       dib0090_set_bbramp(state, bb_ramp_boost);
-               } else
-#endif
-#ifdef CONFIG_BAND_CBAND
-               if (state->current_band == BAND_CBAND && !state->identity.p1g) {
-                       dib0090_set_rframp(state, rf_ramp_cband);
-                       dib0090_set_bbramp(state, bb_ramp_boost);
-               } else
-#endif
-               if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
-                       dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
-                       dib0090_set_bbramp(state, bb_ramp_boost);
-               } else {
-                       dib0090_set_rframp(state, rf_ramp_uhf);
-                       dib0090_set_bbramp(state, bb_ramp_boost);
-               }
-
-               dib0090_write_reg(state, 0x32, 0);
-               dib0090_write_reg(state, 0x39, 0);
-
-               dib0090_wbd_target(state, state->current_rf);
-
-               state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
-               state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
-
-               *tune_state = CT_AGC_STEP_0;
-       } else if (!state->agc_freeze) {
-               s16 wbd = 0, i, cnt;
-
-               int adc;
-               wbd_val = dib0090_get_slow_adc_val(state);
-
-               if (*tune_state == CT_AGC_STEP_0)
-                       cnt = 5;
-               else
-                       cnt = 1;
-
-               for (i = 0; i < cnt; i++) {
-                       wbd_val = dib0090_get_slow_adc_val(state);
-                       wbd += dib0090_wbd_to_db(state, wbd_val);
-               }
-               wbd /= cnt;
-               wbd_error = state->wbd_target - wbd;
-
-               if (*tune_state == CT_AGC_STEP_0) {
-                       if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
-#ifdef CONFIG_BAND_CBAND
-                               /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
-                               u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
-                               if (state->current_band == BAND_CBAND && ltg2) {
-                                       ltg2 >>= 1;
-                                       state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
-                               }
-#endif
-                       } else {
-                               state->agc_step = 0;
-                               *tune_state = CT_AGC_STEP_1;
-                       }
-               } else {
-                       /* calc the adc power */
-                       adc = state->config->get_adc_power(fe);
-                       adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
-
-                       adc_error = (s16) (((s32) ADC_TARGET) - adc);
-#ifdef CONFIG_STANDARD_DAB
-                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
-                               adc_error -= 10;
-#endif
-#ifdef CONFIG_STANDARD_DVBT
-                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
-                                       (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
-                               adc_error += 60;
-#endif
-#ifdef CONFIG_SYS_ISDBT
-                       if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
-                                                               0)
-                                                       &&
-                                                       ((state->fe->dtv_property_cache.layer[0].modulation ==
-                                                         QAM_64)
-                                                        || (state->fe->dtv_property_cache.
-                                                                layer[0].modulation == QAM_16)))
-                                               ||
-                                               ((state->fe->dtv_property_cache.layer[1].segment_count >
-                                                 0)
-                                                &&
-                                                ((state->fe->dtv_property_cache.layer[1].modulation ==
-                                                  QAM_64)
-                                                 || (state->fe->dtv_property_cache.
-                                                         layer[1].modulation == QAM_16)))
-                                               ||
-                                               ((state->fe->dtv_property_cache.layer[2].segment_count >
-                                                 0)
-                                                &&
-                                                ((state->fe->dtv_property_cache.layer[2].modulation ==
-                                                  QAM_64)
-                                                 || (state->fe->dtv_property_cache.
-                                                         layer[2].modulation == QAM_16)))
-                                               )
-                               )
-                               adc_error += 60;
-#endif
-
-                       if (*tune_state == CT_AGC_STEP_1) {     /* quickly go to the correct range of the ADC power */
-                               if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
-
-#ifdef CONFIG_STANDARD_DAB
-                                       if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
-                                               dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));      /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
-                                               dib0090_write_reg(state, 0x04, 0x0);
-                                       } else
-#endif
-                                       {
-                                               dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
-                                               dib0090_write_reg(state, 0x04, 0x01);   /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
-                                       }
-
-                                       *tune_state = CT_AGC_STOP;
-                               }
-                       } else {
-                               /* everything higher than or equal to CT_AGC_STOP means tracking */
-                               ret = 100;      /* 10ms interval */
-                               apply_gain_immediatly = 0;
-                       }
-               }
-#ifdef DEBUG_AGC
-               dprintk
-                       ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
-                        (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
-                        (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
-#endif
-       }
-
-       /* apply gain */
-       if (!state->agc_freeze)
-               dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
-       return ret;
-}
-
-EXPORT_SYMBOL(dib0090_gain_control);
-
-void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       if (rf)
-               *rf = state->gain[0];
-       if (bb)
-               *bb = state->gain[1];
-       if (rf_gain_limit)
-               *rf_gain_limit = state->rf_gain_limit;
-       if (rflt)
-               *rflt = (state->rf_lt_def >> 10) & 0x7;
-}
-
-EXPORT_SYMBOL(dib0090_get_current_gain);
-
-u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
-       s32 current_temp = state->temperature;
-       s32 wbd_thot, wbd_tcold;
-       const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
-
-       while (f_MHz > wbd->max_freq)
-               wbd++;
-
-       dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
-
-       if (current_temp < 0)
-               current_temp = 0;
-       if (current_temp > 128)
-               current_temp = 128;
-
-       state->wbdmux &= ~(7 << 13);
-       if (wbd->wbd_gain != 0)
-               state->wbdmux |= (wbd->wbd_gain << 13);
-       else
-               state->wbdmux |= (4 << 13);
-
-       dib0090_write_reg(state, 0x10, state->wbdmux);
-
-       wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
-       wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
-
-       wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
-
-       state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
-       dprintk("wbd-target: %d dB", (u32) state->wbd_target);
-       dprintk("wbd offset applied is %d", wbd_tcold);
-
-       return state->wbd_offset + wbd_tcold;
-}
-EXPORT_SYMBOL(dib0090_get_wbd_target);
-
-u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       return state->wbd_offset;
-}
-EXPORT_SYMBOL(dib0090_get_wbd_offset);
-
-int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
-                       | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
-
-       return 0;
-}
-EXPORT_SYMBOL(dib0090_set_switch);
-
-int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
-                       | ((onoff & 1) << 15));
-       return 0;
-}
-EXPORT_SYMBOL(dib0090_set_vga);
-
-int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       if ((!state->identity.p1g) || (!state->identity.in_soc)
-                       || ((state->identity.version != SOC_7090_P1G_21R1)
-                               && (state->identity.version != SOC_7090_P1G_11R1))) {
-               dprintk("%s() function can only be used for dib7090P", __func__);
-               return -ENODEV;
-       }
-
-       if (cfg_sensitivity)
-               state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
-       else
-               state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
-       dib0090_pwm_gain_reset(fe);
-
-       return 0;
-}
-EXPORT_SYMBOL(dib0090_update_rframp_7090);
-
-static const u16 dib0090_defaults[] = {
-
-       25, 0x01,
-       0x0000,
-       0x99a0,
-       0x6008,
-       0x0000,
-       0x8bcb,
-       0x0000,
-       0x0405,
-       0x0000,
-       0x0000,
-       0x0000,
-       0xb802,
-       0x0300,
-       0x2d12,
-       0xbac0,
-       0x7c00,
-       0xdbb9,
-       0x0954,
-       0x0743,
-       0x8000,
-       0x0001,
-       0x0040,
-       0x0100,
-       0x0000,
-       0xe910,
-       0x149e,
-
-       1, 0x1c,
-       0xff2d,
-
-       1, 0x39,
-       0x0000,
-
-       2, 0x1e,
-       0x07FF,
-       0x0007,
-
-       1, 0x24,
-       EN_UHF | EN_CRYSTAL,
-
-       2, 0x3c,
-       0x3ff,
-       0x111,
-       0
-};
-
-static const u16 dib0090_p1g_additionnal_defaults[] = {
-       1, 0x05,
-       0xabcd,
-
-       1, 0x11,
-       0x00b4,
-
-       1, 0x1c,
-       0xfffd,
-
-       1, 0x40,
-       0x108,
-       0
-};
-
-static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
-{
-       u16 l, r;
-
-       l = pgm_read_word(n++);
-       while (l) {
-               r = pgm_read_word(n++);
-               do {
-                       dib0090_write_reg(state, r, pgm_read_word(n++));
-                       r++;
-               } while (--l);
-               l = pgm_read_word(n++);
-       }
-}
-
-#define CAP_VALUE_MIN (u8)  9
-#define CAP_VALUE_MAX (u8) 40
-#define HR_MIN       (u8) 25
-#define HR_MAX       (u8) 40
-#define POLY_MIN      (u8)  0
-#define POLY_MAX      (u8)  8
-
-static void dib0090_set_EFUSE(struct dib0090_state *state)
-{
-       u8 c, h, n;
-       u16 e2, e4;
-       u16 cal;
-
-       e2 = dib0090_read_reg(state, 0x26);
-       e4 = dib0090_read_reg(state, 0x28);
-
-       if ((state->identity.version == P1D_E_F) ||
-                       (state->identity.version == P1G) || (e2 == 0xffff)) {
-
-               dib0090_write_reg(state, 0x22, 0x10);
-               cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
-
-               if ((cal < 670) || (cal == 1023))
-                       cal = 850;
-               n = 165 - ((cal * 10)>>6) ;
-               e2 = e4 = (3<<12) | (34<<6) | (n);
-       }
-
-       if (e2 != e4)
-               e2 &= e4; /* Remove the redundancy  */
-
-       if (e2 != 0xffff) {
-               c = e2 & 0x3f;
-               n = (e2 >> 12) & 0xf;
-               h = (e2 >> 6) & 0x3f;
-
-               if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
-                       c = 32;
-               if ((h >= HR_MAX) || (h <= HR_MIN))
-                       h = 34;
-               if ((n >= POLY_MAX) || (n <= POLY_MIN))
-                       n = 3;
-
-               dib0090_write_reg(state, 0x13, (h << 10)) ;
-               e2 = (n<<11) | ((h>>2)<<6) | (c);
-               dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
-       }
-}
-
-static int dib0090_reset(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       dib0090_reset_digital(fe, state->config);
-       if (dib0090_identify(fe) < 0)
-               return -EIO;
-
-#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
-       if (!(state->identity.version & 0x1))   /* it is P1B - reset is already done */
-               return 0;
-#endif
-
-       if (!state->identity.in_soc) {
-               if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
-                       dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
-               else
-                       dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
-       }
-
-       dib0090_set_default_config(state, dib0090_defaults);
-
-       if (state->identity.in_soc)
-               dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
-
-       if (state->identity.p1g)
-               dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
-
-       /* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
-       if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
-               dib0090_set_EFUSE(state);
-
-       /* Congigure in function of the crystal */
-       if (state->config->force_crystal_mode != 0)
-               dib0090_write_reg(state, 0x14,
-                               state->config->force_crystal_mode & 3);
-       else if (state->config->io.clock_khz >= 24000)
-               dib0090_write_reg(state, 0x14, 1);
-       else
-               dib0090_write_reg(state, 0x14, 2);
-       dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
-
-       state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
-
-       return 0;
-}
-
-#define steps(u) (((u) > 15) ? ((u)-16) : (u))
-#define INTERN_WAIT 10
-static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
-       int ret = INTERN_WAIT * 10;
-
-       switch (*tune_state) {
-       case CT_TUNER_STEP_2:
-               /* Turns to positive */
-               dib0090_write_reg(state, 0x1f, 0x7);
-               *tune_state = CT_TUNER_STEP_3;
-               break;
-
-       case CT_TUNER_STEP_3:
-               state->adc_diff = dib0090_read_reg(state, 0x1d);
-
-               /* Turns to negative */
-               dib0090_write_reg(state, 0x1f, 0x4);
-               *tune_state = CT_TUNER_STEP_4;
-               break;
-
-       case CT_TUNER_STEP_4:
-               state->adc_diff -= dib0090_read_reg(state, 0x1d);
-               *tune_state = CT_TUNER_STEP_5;
-               ret = 0;
-               break;
-
-       default:
-               break;
-       }
-
-       return ret;
-}
-
-struct dc_calibration {
-       u8 addr;
-       u8 offset;
-       u8 pga:1;
-       u16 bb1;
-       u8 i:1;
-};
-
-static const struct dc_calibration dc_table[] = {
-       /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
-       {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
-       {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
-       /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
-       {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
-       {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
-       {0},
-};
-
-static const struct dc_calibration dc_p1g_table[] = {
-       /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
-       /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
-       {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
-       {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
-       /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
-       {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
-       {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
-       {0},
-};
-
-static void dib0090_set_trim(struct dib0090_state *state)
-{
-       u16 *val;
-
-       if (state->dc->addr == 0x07)
-               val = &state->bb7;
-       else
-               val = &state->bb6;
-
-       *val &= ~(0x1f << state->dc->offset);
-       *val |= state->step << state->dc->offset;
-
-       dib0090_write_reg(state, state->dc->addr, *val);
-}
-
-static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
-       int ret = 0;
-       u16 reg;
-
-       switch (*tune_state) {
-       case CT_TUNER_START:
-               dprintk("Start DC offset calibration");
-
-               /* force vcm2 = 0.8V */
-               state->bb6 = 0;
-               state->bb7 = 0x040d;
-
-               /* the LNA AND LO are off */
-               reg = dib0090_read_reg(state, 0x24) & 0x0ffb;   /* shutdown lna and lo */
-               dib0090_write_reg(state, 0x24, reg);
-
-               state->wbdmux = dib0090_read_reg(state, 0x10);
-               dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
-               dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
-
-               state->dc = dc_table;
-
-               if (state->identity.p1g)
-                       state->dc = dc_p1g_table;
-               *tune_state = CT_TUNER_STEP_0;
-
-               /* fall through */
-
-       case CT_TUNER_STEP_0:
-               dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
-               dib0090_write_reg(state, 0x01, state->dc->bb1);
-               dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
-
-               state->step = 0;
-               state->min_adc_diff = 1023;
-               *tune_state = CT_TUNER_STEP_1;
-               ret = 50;
-               break;
-
-       case CT_TUNER_STEP_1:
-               dib0090_set_trim(state);
-               *tune_state = CT_TUNER_STEP_2;
-               break;
-
-       case CT_TUNER_STEP_2:
-       case CT_TUNER_STEP_3:
-       case CT_TUNER_STEP_4:
-               ret = dib0090_get_offset(state, tune_state);
-               break;
-
-       case CT_TUNER_STEP_5:   /* found an offset */
-               dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
-               if (state->step == 0 && state->adc_diff < 0) {
-                       state->min_adc_diff = -1023;
-                       dprintk("Change of sign of the minimum adc diff");
-               }
-
-               dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
-
-               /* first turn for this frequency */
-               if (state->step == 0) {
-                       if (state->dc->pga && state->adc_diff < 0)
-                               state->step = 0x10;
-                       if (state->dc->pga == 0 && state->adc_diff > 0)
-                               state->step = 0x10;
-               }
-
-               /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
-               if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
-                       /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
-                       state->step++;
-                       state->min_adc_diff = state->adc_diff;
-                       *tune_state = CT_TUNER_STEP_1;
-               } else {
-                       /* the minimum was what we have seen in the step before */
-                       if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
-                               dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
-                               state->step--;
-                       }
-
-                       dib0090_set_trim(state);
-                       dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
-
-                       state->dc++;
-                       if (state->dc->addr == 0)       /* done */
-                               *tune_state = CT_TUNER_STEP_6;
-                       else
-                               *tune_state = CT_TUNER_STEP_0;
-
-               }
-               break;
-
-       case CT_TUNER_STEP_6:
-               dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
-               dib0090_write_reg(state, 0x1f, 0x7);
-               *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
-               state->calibrate &= ~DC_CAL;
-       default:
-               break;
-       }
-       return ret;
-}
-
-static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
-       u8 wbd_gain;
-       const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
-
-       switch (*tune_state) {
-       case CT_TUNER_START:
-               while (state->current_rf / 1000 > wbd->max_freq)
-                       wbd++;
-               if (wbd->wbd_gain != 0)
-                       wbd_gain = wbd->wbd_gain;
-               else {
-                       wbd_gain = 4;
-#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
-                       if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
-                               wbd_gain = 2;
-#endif
-               }
-
-               if (wbd_gain == state->wbd_calibration_gain) {  /* the WBD calibration has already been done */
-                       *tune_state = CT_TUNER_START;
-                       state->calibrate &= ~WBD_CAL;
-                       return 0;
-               }
-
-               dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
-
-               dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
-               *tune_state = CT_TUNER_STEP_0;
-               state->wbd_calibration_gain = wbd_gain;
-               return 90;      /* wait for the WBDMUX to switch and for the ADC to sample */
-
-       case CT_TUNER_STEP_0:
-               state->wbd_offset = dib0090_get_slow_adc_val(state);
-               dprintk("WBD calibration offset = %d", state->wbd_offset);
-               *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
-               state->calibrate &= ~WBD_CAL;
-               break;
-
-       default:
-               break;
-       }
-       return 0;
-}
-
-static void dib0090_set_bandwidth(struct dib0090_state *state)
-{
-       u16 tmp;
-
-       if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
-               tmp = (3 << 14);
-       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
-               tmp = (2 << 14);
-       else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
-               tmp = (1 << 14);
-       else
-               tmp = (0 << 14);
-
-       state->bb_1_def &= 0x3fff;
-       state->bb_1_def |= tmp;
-
-       dib0090_write_reg(state, 0x01, state->bb_1_def);        /* be sure that we have the right bb-filter */
-
-       dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
-       dib0090_write_reg(state, 0x04, 0x1);    /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
-       if (state->identity.in_soc) {
-               dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
-       } else {
-               dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));     /* 22 = cap_value */
-               dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
-       }
-}
-
-static const struct dib0090_pll dib0090_pll_table[] = {
-#ifdef CONFIG_BAND_CBAND
-       {56000, 0, 9, 48, 6},
-       {70000, 1, 9, 48, 6},
-       {87000, 0, 8, 32, 4},
-       {105000, 1, 8, 32, 4},
-       {115000, 0, 7, 24, 6},
-       {140000, 1, 7, 24, 6},
-       {170000, 0, 6, 16, 4},
-#endif
-#ifdef CONFIG_BAND_VHF
-       {200000, 1, 6, 16, 4},
-       {230000, 0, 5, 12, 6},
-       {280000, 1, 5, 12, 6},
-       {340000, 0, 4, 8, 4},
-       {380000, 1, 4, 8, 4},
-       {450000, 0, 3, 6, 6},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {580000, 1, 3, 6, 6},
-       {700000, 0, 2, 4, 4},
-       {860000, 1, 2, 4, 4},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1800000, 1, 0, 2, 4},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2900000, 0, 14, 1, 4},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
-
-#ifdef CONFIG_BAND_CBAND
-       {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-       {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-       {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
-       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table[] = {
-
-#ifdef CONFIG_BAND_CBAND
-       {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_VHF
-       {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-       {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-       {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
-       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
-#ifdef CONFIG_BAND_CBAND
-       {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_VHF
-       {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-       {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-       {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
-       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-static const struct dib0090_pll dib0090_p1g_pll_table[] = {
-#ifdef CONFIG_BAND_CBAND
-       {57000, 0, 11, 48, 6},
-       {70000, 1, 11, 48, 6},
-       {86000, 0, 10, 32, 4},
-       {105000, 1, 10, 32, 4},
-       {115000, 0, 9, 24, 6},
-       {140000, 1, 9, 24, 6},
-       {170000, 0, 8, 16, 4},
-#endif
-#ifdef CONFIG_BAND_VHF
-       {200000, 1, 8, 16, 4},
-       {230000, 0, 7, 12, 6},
-       {280000, 1, 7, 12, 6},
-       {340000, 0, 6, 8, 4},
-       {380000, 1, 6, 8, 4},
-       {455000, 0, 5, 6, 6},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {580000, 1, 5, 6, 6},
-       {680000, 0, 4, 4, 4},
-       {860000, 1, 4, 4, 4},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1800000, 1, 2, 2, 4},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2900000, 0, 1, 1, 6},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
-#ifdef CONFIG_BAND_CBAND
-       {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
-       {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
-       {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
-#endif
-#ifdef CONFIG_BAND_UHF
-       {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-       {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
-#endif
-#ifdef CONFIG_BAND_LBAND
-       {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-       {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
-#endif
-#ifdef CONFIG_BAND_SBAND
-       {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
-       {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
-#ifdef CONFIG_BAND_CBAND
-       {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
-       {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
-       {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
-       {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
-#endif
-};
-
-static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
-#ifdef CONFIG_BAND_CBAND
-       { 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
-       { 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
-       { 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
-       { 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
-       { 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
-       { 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
-#endif
-};
-
-int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
-               u8 cfg_sensitivity)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       const struct dib0090_tuning *tune =
-               dib0090_tuning_table_cband_7090e_sensitivity;
-       const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
-               { 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
-               { 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
-               { 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
-       };
-
-       if ((!state->identity.p1g) || (!state->identity.in_soc)
-                       || ((state->identity.version != SOC_7090_P1G_21R1)
-                               && (state->identity.version != SOC_7090_P1G_11R1))) {
-               dprintk("%s() function can only be used for dib7090", __func__);
-               return -ENODEV;
-       }
-
-       if (cfg_sensitivity)
-               tune = dib0090_tuning_table_cband_7090e_sensitivity;
-       else
-               tune = dib0090_tuning_table_cband_7090e_aci;
-
-       while (state->rf_request > tune->max_freq)
-               tune++;
-
-       dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
-                       | (tune->lna_bias & 0x7fff));
-       dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
-                       | ((tune->lna_tune << 6) & 0x07c0));
-       return 0;
-}
-EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
-
-static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
-       int ret = 0;
-       u16 lo4 = 0xe900;
-
-       s16 adc_target;
-       u16 adc;
-       s8 step_sign;
-       u8 force_soft_search = 0;
-
-       if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
-               force_soft_search = 1;
-
-       if (*tune_state == CT_TUNER_START) {
-               dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
-               dib0090_write_reg(state, 0x10, 0x2B1);
-               dib0090_write_reg(state, 0x1e, 0x0032);
-
-               if (!state->tuner_is_tuned) {
-                       /* prepare a complete captrim */
-                       if (!state->identity.p1g || force_soft_search)
-                               state->step = state->captrim = state->fcaptrim = 64;
-
-                       state->current_rf = state->rf_request;
-               } else {        /* we are already tuned to this frequency - the configuration is correct  */
-                       if (!state->identity.p1g || force_soft_search) {
-                               /* do a minimal captrim even if the frequency has not changed */
-                               state->step = 4;
-                               state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
-                       }
-               }
-               state->adc_diff = 3000;
-               *tune_state = CT_TUNER_STEP_0;
-
-       } else if (*tune_state == CT_TUNER_STEP_0) {
-               if (state->identity.p1g && !force_soft_search) {
-                       u8 ratio = 31;
-
-                       dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
-                       dib0090_read_reg(state, 0x40);
-                       ret = 50;
-               } else {
-                       state->step /= 2;
-                       dib0090_write_reg(state, 0x18, lo4 | state->captrim);
-
-                       if (state->identity.in_soc)
-                               ret = 25;
-               }
-               *tune_state = CT_TUNER_STEP_1;
-
-       } else if (*tune_state == CT_TUNER_STEP_1) {
-               if (state->identity.p1g && !force_soft_search) {
-                       dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
-                       dib0090_read_reg(state, 0x40);
-
-                       state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
-                       dprintk("***Final Captrim= 0x%x", state->fcaptrim);
-                       *tune_state = CT_TUNER_STEP_3;
-
-               } else {
-                       /* MERGE for all krosus before P1G */
-                       adc = dib0090_get_slow_adc_val(state);
-                       dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
-
-                       if (state->rest == 0 || state->identity.in_soc) {       /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
-                               adc_target = 200;
-                       } else
-                               adc_target = 400;
-
-                       if (adc >= adc_target) {
-                               adc -= adc_target;
-                               step_sign = -1;
-                       } else {
-                               adc = adc_target - adc;
-                               step_sign = 1;
-                       }
-
-                       if (adc < state->adc_diff) {
-                               dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
-                               state->adc_diff = adc;
-                               state->fcaptrim = state->captrim;
-                       }
-
-                       state->captrim += step_sign * state->step;
-                       if (state->step >= 1)
-                               *tune_state = CT_TUNER_STEP_0;
-                       else
-                               *tune_state = CT_TUNER_STEP_2;
-
-                       ret = 25;
-               }
-       } else if (*tune_state == CT_TUNER_STEP_2) {    /* this step is only used by krosus < P1G */
-               /*write the final cptrim config */
-               dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
-
-               *tune_state = CT_TUNER_STEP_3;
-
-       } else if (*tune_state == CT_TUNER_STEP_3) {
-               state->calibrate &= ~CAPTRIM_CAL;
-               *tune_state = CT_TUNER_STEP_0;
-       }
-
-       return ret;
-}
-
-static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
-{
-       int ret = 15;
-       s16 val;
-
-       switch (*tune_state) {
-       case CT_TUNER_START:
-               state->wbdmux = dib0090_read_reg(state, 0x10);
-               dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
-
-               state->bias = dib0090_read_reg(state, 0x13);
-               dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
-
-               *tune_state = CT_TUNER_STEP_0;
-               /* wait for the WBDMUX to switch and for the ADC to sample */
-               break;
-
-       case CT_TUNER_STEP_0:
-               state->adc_diff = dib0090_get_slow_adc_val(state);
-               dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
-               *tune_state = CT_TUNER_STEP_1;
-               break;
-
-       case CT_TUNER_STEP_1:
-               val = dib0090_get_slow_adc_val(state);
-               state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
-
-               dprintk("temperature: %d C", state->temperature - 30);
-
-               *tune_state = CT_TUNER_STEP_2;
-               break;
-
-       case CT_TUNER_STEP_2:
-               dib0090_write_reg(state, 0x13, state->bias);
-               dib0090_write_reg(state, 0x10, state->wbdmux);  /* write back original WBDMUX */
-
-               *tune_state = CT_TUNER_START;
-               state->calibrate &= ~TEMP_CAL;
-               if (state->config->analog_output == 0)
-                       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
-
-               break;
-
-       default:
-               ret = 0;
-               break;
-       }
-       return ret;
-}
-
-#define WBD     0x781          /* 1 1 1 1 0000 0 0 1 */
-static int dib0090_tune(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       const struct dib0090_tuning *tune = state->current_tune_table_index;
-       const struct dib0090_pll *pll = state->current_pll_table_index;
-       enum frontend_tune_state *tune_state = &state->tune_state;
-
-       u16 lo5, lo6, Den, tmp;
-       u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
-       int ret = 10;           /* 1ms is the default delay most of the time */
-       u8 c, i;
-
-       /************************* VCO ***************************/
-       /* Default values for FG                                 */
-       /* from these are needed :                               */
-       /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
-
-       /* in any case we first need to do a calibration if needed */
-       if (*tune_state == CT_TUNER_START) {
-               /* deactivate DataTX before some calibrations */
-               if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
-                       dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
-               else
-                       /* Activate DataTX in case a calibration has been done before */
-                       if (state->config->analog_output == 0)
-                               dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
-       }
-
-       if (state->calibrate & DC_CAL)
-               return dib0090_dc_offset_calibration(state, tune_state);
-       else if (state->calibrate & WBD_CAL) {
-               if (state->current_rf == 0)
-                       state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
-               return dib0090_wbd_calibration(state, tune_state);
-       } else if (state->calibrate & TEMP_CAL)
-               return dib0090_get_temperature(state, tune_state);
-       else if (state->calibrate & CAPTRIM_CAL)
-               return dib0090_captrim_search(state, tune_state);
-
-       if (*tune_state == CT_TUNER_START) {
-               /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
-               if (state->config->use_pwm_agc && state->identity.in_soc) {
-                       tmp = dib0090_read_reg(state, 0x39);
-                       if ((tmp >> 10) & 0x1)
-                               dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
-               }
-
-               state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
-               state->rf_request =
-                       state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
-                                       BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
-                                       freq_offset_khz_vhf);
-
-               /* in ISDB-T 1seg we shift tuning frequency */
-               if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
-                                       && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
-                       const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
-                       u8 found_offset = 0;
-                       u32 margin_khz = 100;
-
-                       if (LUT_offset != NULL) {
-                               while (LUT_offset->RF_freq != 0xffff) {
-                                       if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
-                                                               && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
-                                                       && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
-                                               state->rf_request += LUT_offset->offset_khz;
-                                               found_offset = 1;
-                                               break;
-                                       }
-                                       LUT_offset++;
-                               }
-                       }
-
-                       if (found_offset == 0)
-                               state->rf_request += 400;
-               }
-               if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
-                       state->tuner_is_tuned = 0;
-                       state->current_rf = 0;
-                       state->current_standard = 0;
-
-                       tune = dib0090_tuning_table;
-                       if (state->identity.p1g)
-                               tune = dib0090_p1g_tuning_table;
-
-                       tmp = (state->identity.version >> 5) & 0x7;
-
-                       if (state->identity.in_soc) {
-                               if (state->config->force_cband_input) { /* Use the CBAND input for all band */
-                                       if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
-                                                       || state->current_band & BAND_UHF) {
-                                               state->current_band = BAND_CBAND;
-                                               if (state->config->is_dib7090e)
-                                                       tune = dib0090_tuning_table_cband_7090e_sensitivity;
-                                               else
-                                                       tune = dib0090_tuning_table_cband_7090;
-                                       }
-                               } else {        /* Use the CBAND input for all band under UHF */
-                                       if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
-                                               state->current_band = BAND_CBAND;
-                                               if (state->config->is_dib7090e)
-                                                       tune = dib0090_tuning_table_cband_7090e_sensitivity;
-                                               else
-                                                       tune = dib0090_tuning_table_cband_7090;
-                                       }
-                               }
-                       } else
-                        if (tmp == 0x4 || tmp == 0x7) {
-                               /* CBAND tuner version for VHF */
-                               if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
-                                       state->current_band = BAND_CBAND;       /* Force CBAND */
-
-                                       tune = dib0090_tuning_table_fm_vhf_on_cband;
-                                       if (state->identity.p1g)
-                                               tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
-                               }
-                       }
-
-                       pll = dib0090_pll_table;
-                       if (state->identity.p1g)
-                               pll = dib0090_p1g_pll_table;
-
-                       /* Look for the interval */
-                       while (state->rf_request > tune->max_freq)
-                               tune++;
-                       while (state->rf_request > pll->max_freq)
-                               pll++;
-
-                       state->current_tune_table_index = tune;
-                       state->current_pll_table_index = pll;
-
-                       dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
-
-                       VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
-
-                       FREF = state->config->io.clock_khz;
-                       if (state->config->fref_clock_ratio != 0)
-                               FREF /= state->config->fref_clock_ratio;
-
-                       FBDiv = (VCOF_kHz / pll->topresc / FREF);
-                       Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
-
-                       if (Rest < LPF)
-                               Rest = 0;
-                       else if (Rest < 2 * LPF)
-                               Rest = 2 * LPF;
-                       else if (Rest > (FREF - LPF)) {
-                               Rest = 0;
-                               FBDiv += 1;
-                       } else if (Rest > (FREF - 2 * LPF))
-                               Rest = FREF - 2 * LPF;
-                       Rest = (Rest * 6528) / (FREF / 10);
-                       state->rest = Rest;
-
-                       /* external loop filter, otherwise:
-                        * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
-                        * lo6 = 0x0e34 */
-
-                       if (Rest == 0) {
-                               if (pll->vco_band)
-                                       lo5 = 0x049f;
-                               else
-                                       lo5 = 0x041f;
-                       } else {
-                               if (pll->vco_band)
-                                       lo5 = 0x049e;
-                               else if (state->config->analog_output)
-                                       lo5 = 0x041d;
-                               else
-                                       lo5 = 0x041c;
-                       }
-
-                       if (state->identity.p1g) {      /* Bias is done automatically in P1G */
-                               if (state->identity.in_soc) {
-                                       if (state->identity.version == SOC_8090_P1G_11R1)
-                                               lo5 = 0x46f;
-                                       else
-                                               lo5 = 0x42f;
-                               } else
-                                       lo5 = 0x42c;
-                       }
-
-                       lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);  /* bit 15 is the split to the slave, we do not do it here */
-
-                       if (!state->config->io.pll_int_loop_filt) {
-                               if (state->identity.in_soc)
-                                       lo6 = 0xff98;
-                               else if (state->identity.p1g || (Rest == 0))
-                                       lo6 = 0xfff8;
-                               else
-                                       lo6 = 0xff28;
-                       } else
-                               lo6 = (state->config->io.pll_int_loop_filt << 3);
-
-                       Den = 1;
-
-                       if (Rest > 0) {
-                               if (state->config->analog_output)
-                                       lo6 |= (1 << 2) | 2;
-                               else {
-                                       if (state->identity.in_soc)
-                                               lo6 |= (1 << 2) | 2;
-                                       else
-                                               lo6 |= (1 << 2) | 2;
-                               }
-                               Den = 255;
-                       }
-                       dib0090_write_reg(state, 0x15, (u16) FBDiv);
-                       if (state->config->fref_clock_ratio != 0)
-                               dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
-                       else
-                               dib0090_write_reg(state, 0x16, (Den << 8) | 1);
-                       dib0090_write_reg(state, 0x17, (u16) Rest);
-                       dib0090_write_reg(state, 0x19, lo5);
-                       dib0090_write_reg(state, 0x1c, lo6);
-
-                       lo6 = tune->tuner_enable;
-                       if (state->config->analog_output)
-                               lo6 = (lo6 & 0xff9f) | 0x2;
-
-                       dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
-
-               }
-
-               state->current_rf = state->rf_request;
-               state->current_standard = state->fe->dtv_property_cache.delivery_system;
-
-               ret = 20;
-               state->calibrate = CAPTRIM_CAL; /* captrim serach now */
-       }
-
-       else if (*tune_state == CT_TUNER_STEP_0) {      /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
-               const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
-
-               while (state->current_rf / 1000 > wbd->max_freq)
-                       wbd++;
-
-               dib0090_write_reg(state, 0x1e, 0x07ff);
-               dprintk("Final Captrim: %d", (u32) state->fcaptrim);
-               dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
-               dprintk("VCO = %d", (u32) pll->vco_band);
-               dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
-               dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
-               dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
-               dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
-                       (u32) dib0090_read_reg(state, 0x1c) & 0x3);
-
-#define WBD     0x781          /* 1 1 1 1 0000 0 0 1 */
-               c = 4;
-               i = 3;
-
-               if (wbd->wbd_gain != 0)
-                       c = wbd->wbd_gain;
-
-               state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
-               dib0090_write_reg(state, 0x10, state->wbdmux);
-
-               if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
-                       dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
-                       dib0090_write_reg(state, 0x09, tune->lna_bias);
-                       dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
-               } else
-                       dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
-
-               dib0090_write_reg(state, 0x0c, tune->v2i);
-               dib0090_write_reg(state, 0x0d, tune->mix);
-               dib0090_write_reg(state, 0x0e, tune->load);
-               *tune_state = CT_TUNER_STEP_1;
-
-       } else if (*tune_state == CT_TUNER_STEP_1) {
-               /* initialize the lt gain register */
-               state->rf_lt_def = 0x7c00;
-
-               dib0090_set_bandwidth(state);
-               state->tuner_is_tuned = 1;
-
-               state->calibrate |= WBD_CAL;
-               state->calibrate |= TEMP_CAL;
-               *tune_state = CT_TUNER_STOP;
-       } else
-               ret = FE_CALLBACK_TIME_NEVER;
-       return ret;
-}
-
-static int dib0090_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       return state->tune_state;
-}
-
-EXPORT_SYMBOL(dib0090_get_tune_state);
-
-int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       state->tune_state = tune_state;
-       return 0;
-}
-
-EXPORT_SYMBOL(dib0090_set_tune_state);
-
-static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-
-       *frequency = 1000 * state->current_rf;
-       return 0;
-}
-
-static int dib0090_set_params(struct dvb_frontend *fe)
-{
-       struct dib0090_state *state = fe->tuner_priv;
-       u32 ret;
-
-       state->tune_state = CT_TUNER_START;
-
-       do {
-               ret = dib0090_tune(fe);
-               if (ret != FE_CALLBACK_TIME_NEVER)
-                       msleep(ret / 10);
-               else
-                       break;
-       } while (state->tune_state != CT_TUNER_STOP);
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops dib0090_ops = {
-       .info = {
-                .name = "DiBcom DiB0090",
-                .frequency_min = 45000000,
-                .frequency_max = 860000000,
-                .frequency_step = 1000,
-                },
-       .release = dib0090_release,
-
-       .init = dib0090_wakeup,
-       .sleep = dib0090_sleep,
-       .set_params = dib0090_set_params,
-       .get_frequency = dib0090_get_frequency,
-};
-
-static const struct dvb_tuner_ops dib0090_fw_ops = {
-       .info = {
-                .name = "DiBcom DiB0090",
-                .frequency_min = 45000000,
-                .frequency_max = 860000000,
-                .frequency_step = 1000,
-                },
-       .release = dib0090_release,
-
-       .init = NULL,
-       .sleep = NULL,
-       .set_params = NULL,
-       .get_frequency = NULL,
-};
-
-static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
-       {470, 0, 250, 0, 100, 4},
-       {860, 51, 866, 21, 375, 4},
-       {1700, 0, 800, 0, 850, 4},
-       {2900, 0, 250, 0, 100, 6},
-       {0xFFFF, 0, 0, 0, 0, 0},
-};
-
-struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
-{
-       struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-
-       st->config = config;
-       st->i2c = i2c;
-       st->fe = fe;
-       mutex_init(&st->i2c_buffer_lock);
-       fe->tuner_priv = st;
-
-       if (config->wbd == NULL)
-               st->current_wbd_table = dib0090_wbd_table_default;
-       else
-               st->current_wbd_table = config->wbd;
-
-       if (dib0090_reset(fe) != 0)
-               goto free_mem;
-
-       printk(KERN_INFO "DiB0090: successfully identified\n");
-       memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
-
-       return fe;
- free_mem:
-       kfree(st);
-       fe->tuner_priv = NULL;
-       return NULL;
-}
-
-EXPORT_SYMBOL(dib0090_register);
-
-struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
-{
-       struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-
-       st->config = config;
-       st->i2c = i2c;
-       st->fe = fe;
-       mutex_init(&st->i2c_buffer_lock);
-       fe->tuner_priv = st;
-
-       if (dib0090_fw_reset_digital(fe, st->config) != 0)
-               goto free_mem;
-
-       dprintk("DiB0090 FW: successfully identified");
-       memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
-
-       return fe;
-free_mem:
-       kfree(st);
-       fe->tuner_priv = NULL;
-       return NULL;
-}
-EXPORT_SYMBOL(dib0090_fw_register);
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h
deleted file mode 100644 (file)
index 781dc49..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
- *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#ifndef DIB0090_H
-#define DIB0090_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
-
-struct dib0090_io_config {
-       u32 clock_khz;
-
-       u8 pll_bypass:1;
-       u8 pll_range:1;
-       u8 pll_prediv:6;
-       u8 pll_loopdiv:6;
-
-       u8 adc_clock_ratio;     /* valid is 8, 7 ,6 */
-       u16 pll_int_loop_filt;
-};
-
-struct dib0090_wbd_slope {
-       u16 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
-       u16 slope_cold;
-       u16 offset_cold;
-       u16 slope_hot;
-       u16 offset_hot;
-       u8 wbd_gain;
-};
-
-struct dib0090_low_if_offset_table {
-       int std;
-       u32 RF_freq;
-       s32 offset_khz;
-};
-
-struct dib0090_config {
-       struct dib0090_io_config io;
-       int (*reset) (struct dvb_frontend *, int);
-       int (*sleep) (struct dvb_frontend *, int);
-
-       /*  offset in kHz */
-       int freq_offset_khz_uhf;
-       int freq_offset_khz_vhf;
-
-       int (*get_adc_power) (struct dvb_frontend *);
-
-       u8 clkouttobamse:1;     /* activate or deactivate clock output */
-       u8 analog_output;
-
-       u8 i2c_address;
-       /* add drives and other things if necessary */
-       u16 wbd_vhf_offset;
-       u16 wbd_cband_offset;
-       u8 use_pwm_agc;
-       u8 clkoutdrive;
-
-       u8 ls_cfg_pad_drv;
-       u8 data_tx_drv;
-
-       u8 in_soc;
-       const struct dib0090_low_if_offset_table *low_if;
-       u8 fref_clock_ratio;
-       u16 force_cband_input;
-       struct dib0090_wbd_slope *wbd;
-       u8 is_dib7090e;
-       u8 force_crystal_mode;
-};
-
-#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
-extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
-extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
-extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
-extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner);
-extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe);
-extern int dib0090_gain_control(struct dvb_frontend *fe);
-extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
-extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
-extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
-extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff);
-extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3);
-extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff);
-extern int dib0090_update_rframp_7090(struct dvb_frontend *fe,
-               u8 cfg_sensitivity);
-extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
-               u8 cfg_sensitivity);
-#else
-static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-
-static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-
-static inline int dib0090_gain_control(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return CT_DONE;
-}
-
-static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-
-static inline int dib0090_set_switch(struct dvb_frontend *fe,
-               u8 sw1, u8 sw2, u8 sw3)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe,
-               u8 cfg_sensitivity)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
-               u8 cfg_sensitivity)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
deleted file mode 100644 (file)
index 404f63a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * public header file of the frontend drivers for mobile DVB-T demodulators
- * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DibCom, which has
- *
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- * Acknowledgements
- *
- *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- *  sources, on which this driver (and the dvb-dibusb) are based.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- */
-
-#ifndef DIB3000_H
-#define DIB3000_H
-
-#include <linux/dvb/frontend.h>
-
-struct dib3000_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-struct dib_fe_xfer_ops
-{
-       /* pid and transfer handling is done in the demodulator */
-       int (*pid_parse)(struct dvb_frontend *fe, int onoff);
-       int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
-       int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
-       int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
-};
-
-#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE))
-extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-                                            struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
-#else
-static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-                                            struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_DIB3000MB
-
-#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
deleted file mode 100644 (file)
index af91e0c..0000000
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
- * DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DibCom, which has
- *
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- * Acknowledgements
- *
- *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- *  sources, on which this driver (and the dvb-dibusb) are based.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "dib3000.h"
-#include "dib3000mb_priv.h"
-
-/* Version information */
-#define DRIVER_VERSION "0.1"
-#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
-
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_i2c(args...)  dprintk(0x02,args)
-#define deb_srch(args...) dprintk(0x04,args)
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_xfer(args...) dprintk(0x02,args)
-#define deb_setf(args...) dprintk(0x04,args)
-#define deb_getf(args...) dprintk(0x08,args)
-
-static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
-{
-       u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
-       u8 rb[2];
-       struct i2c_msg msg[] = {
-               { .addr = state->config.demod_address, .flags = 0,        .buf = wb, .len = 2 },
-               { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
-       };
-
-       if (i2c_transfer(state->i2c, msg, 2) != 2)
-               deb_i2c("i2c read error\n");
-
-       deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
-                       (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
-
-       return (rb[0] << 8) | rb[1];
-}
-
-static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
-{
-       u8 b[] = {
-               (reg >> 8) & 0xff, reg & 0xff,
-               (val >> 8) & 0xff, val & 0xff,
-       };
-       struct i2c_msg msg[] = {
-               { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
-       };
-       deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
-
-       return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
-}
-
-static int dib3000_search_status(u16 irq,u16 lock)
-{
-       if (irq & 0x02) {
-               if (lock & 0x01) {
-                       deb_srch("auto search succeeded\n");
-                       return 1; // auto search succeeded
-               } else {
-                       deb_srch("auto search not successful\n");
-                       return 0; // auto search failed
-               }
-       } else if (irq & 0x01)  {
-               deb_srch("auto search failed\n");
-               return 0; // auto search failed
-       }
-       return -1; // try again
-}
-
-/* for auto search */
-static u16 dib3000_seq[2][2][2] =     /* fft,gua,   inv   */
-       { /* fft */
-               { /* gua */
-                       { 0, 1 },                   /*  0   0   { 0,1 } */
-                       { 3, 9 },                   /*  0   1   { 0,1 } */
-               },
-               {
-                       { 2, 5 },                   /*  1   0   { 0,1 } */
-                       { 6, 11 },                  /*  1   1   { 0,1 } */
-               }
-       };
-
-static int dib3000mb_get_frontend(struct dvb_frontend* fe);
-
-static int dib3000mb_set_frontend(struct dvb_frontend *fe, int tuner)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       fe_code_rate_t fe_cr = FEC_NONE;
-       int search_state, seq;
-
-       if (tuner && fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-
-               deb_setf("bandwidth: ");
-               switch (c->bandwidth_hz) {
-                       case 8000000:
-                               deb_setf("8 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
-                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
-                               break;
-                       case 7000000:
-                               deb_setf("7 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
-                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
-                               break;
-                       case 6000000:
-                               deb_setf("6 MHz\n");
-                               wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
-                               wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
-                               break;
-                       case 0:
-                               return -EOPNOTSUPP;
-                       default:
-                               err("unknown bandwidth value.");
-                               return -EINVAL;
-               }
-       }
-       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
-
-       deb_setf("transmission mode: ");
-       switch (c->transmission_mode) {
-               case TRANSMISSION_MODE_2K:
-                       deb_setf("2k\n");
-                       wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
-                       break;
-               case TRANSMISSION_MODE_8K:
-                       deb_setf("8k\n");
-                       wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
-                       break;
-               case TRANSMISSION_MODE_AUTO:
-                       deb_setf("auto\n");
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       deb_setf("guard: ");
-       switch (c->guard_interval) {
-               case GUARD_INTERVAL_1_32:
-                       deb_setf("1_32\n");
-                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
-                       break;
-               case GUARD_INTERVAL_1_16:
-                       deb_setf("1_16\n");
-                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
-                       break;
-               case GUARD_INTERVAL_1_8:
-                       deb_setf("1_8\n");
-                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
-                       break;
-               case GUARD_INTERVAL_1_4:
-                       deb_setf("1_4\n");
-                       wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
-                       break;
-               case GUARD_INTERVAL_AUTO:
-                       deb_setf("auto\n");
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       deb_setf("inversion: ");
-       switch (c->inversion) {
-               case INVERSION_OFF:
-                       deb_setf("off\n");
-                       wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
-                       break;
-               case INVERSION_AUTO:
-                       deb_setf("auto ");
-                       break;
-               case INVERSION_ON:
-                       deb_setf("on\n");
-                       wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       deb_setf("modulation: ");
-       switch (c->modulation) {
-               case QPSK:
-                       deb_setf("qpsk\n");
-                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
-                       break;
-               case QAM_16:
-                       deb_setf("qam16\n");
-                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
-                       break;
-               case QAM_64:
-                       deb_setf("qam64\n");
-                       wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
-                       break;
-               case QAM_AUTO:
-                       break;
-               default:
-                       return -EINVAL;
-       }
-       deb_setf("hierarchy: ");
-       switch (c->hierarchy) {
-               case HIERARCHY_NONE:
-                       deb_setf("none ");
-                       /* fall through */
-               case HIERARCHY_1:
-                       deb_setf("alpha=1\n");
-                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
-                       break;
-               case HIERARCHY_2:
-                       deb_setf("alpha=2\n");
-                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
-                       break;
-               case HIERARCHY_4:
-                       deb_setf("alpha=4\n");
-                       wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
-                       break;
-               case HIERARCHY_AUTO:
-                       deb_setf("alpha=auto\n");
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       deb_setf("hierarchy: ");
-       if (c->hierarchy == HIERARCHY_NONE) {
-               deb_setf("none\n");
-               wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
-               wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
-               fe_cr = c->code_rate_HP;
-       } else if (c->hierarchy != HIERARCHY_AUTO) {
-               deb_setf("on\n");
-               wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
-               wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
-               fe_cr = c->code_rate_LP;
-       }
-       deb_setf("fec: ");
-       switch (fe_cr) {
-               case FEC_1_2:
-                       deb_setf("1_2\n");
-                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
-                       break;
-               case FEC_2_3:
-                       deb_setf("2_3\n");
-                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
-                       break;
-               case FEC_3_4:
-                       deb_setf("3_4\n");
-                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
-                       break;
-               case FEC_5_6:
-                       deb_setf("5_6\n");
-                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
-                       break;
-               case FEC_7_8:
-                       deb_setf("7_8\n");
-                       wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
-                       break;
-               case FEC_NONE:
-                       deb_setf("none ");
-                       break;
-               case FEC_AUTO:
-                       deb_setf("auto\n");
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       seq = dib3000_seq
-               [c->transmission_mode == TRANSMISSION_MODE_AUTO]
-               [c->guard_interval == GUARD_INTERVAL_AUTO]
-               [c->inversion == INVERSION_AUTO];
-
-       deb_setf("seq? %d\n", seq);
-
-       wr(DIB3000MB_REG_SEQ, seq);
-
-       wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
-
-       if (c->transmission_mode == TRANSMISSION_MODE_2K) {
-               if (c->guard_interval == GUARD_INTERVAL_1_8) {
-                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
-               } else {
-                       wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
-               }
-
-               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
-       } else {
-               wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
-       }
-
-       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
-       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
-       wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
-
-       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
-
-       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
-
-       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
-       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
-
-       /* wait for AGC lock */
-       msleep(70);
-
-       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
-
-       /* something has to be auto searched */
-       if (c->modulation == QAM_AUTO ||
-               c->hierarchy == HIERARCHY_AUTO ||
-               fe_cr == FEC_AUTO ||
-               c->inversion == INVERSION_AUTO) {
-               int as_count=0;
-
-               deb_setf("autosearch enabled.\n");
-
-               wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
-
-               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
-               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
-
-               while ((search_state =
-                               dib3000_search_status(
-                                       rd(DIB3000MB_REG_AS_IRQ_PENDING),
-                                       rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
-                       msleep(1);
-
-               deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
-
-               if (search_state == 1) {
-                       if (dib3000mb_get_frontend(fe) == 0) {
-                               deb_setf("reading tuning data from frontend succeeded.\n");
-                               return dib3000mb_set_frontend(fe, 0);
-                       }
-               }
-
-       } else {
-               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
-               wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
-       }
-
-       return 0;
-}
-
-static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-
-       deb_info("dib3000mb is getting up.\n");
-       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
-
-       wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
-
-       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
-       wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
-
-       wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
-
-       wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
-
-       wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
-       wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
-
-       wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
-
-       wr_foreach(dib3000mb_reg_impulse_noise,
-                       dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
-
-       wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
-
-       wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
-
-       wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
-
-       wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
-
-       wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
-
-       wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
-       wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
-       wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
-       wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
-
-       wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
-
-       wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
-       wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
-       wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
-       wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
-       wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
-       wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
-       wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
-       wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
-       wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
-       wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
-       wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
-       wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
-       wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
-       wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
-       wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
-
-       wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
-
-       wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
-       wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
-       wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
-
-       wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
-
-       wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
-       wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
-       wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
-       wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
-       wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
-       wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
-
-       wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
-
-       return 0;
-}
-
-static int dib3000mb_get_frontend(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dib3000_state* state = fe->demodulator_priv;
-       fe_code_rate_t *cr;
-       u16 tps_val;
-       int inv_test1,inv_test2;
-       u32 dds_val, threshold = 0x800000;
-
-       if (!rd(DIB3000MB_REG_TPS_LOCK))
-               return 0;
-
-       dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
-       deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
-       if (dds_val < threshold)
-               inv_test1 = 0;
-       else if (dds_val == threshold)
-               inv_test1 = 1;
-       else
-               inv_test1 = 2;
-
-       dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
-       deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
-       if (dds_val < threshold)
-               inv_test2 = 0;
-       else if (dds_val == threshold)
-               inv_test2 = 1;
-       else
-               inv_test2 = 2;
-
-       c->inversion =
-               ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
-               ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
-               INVERSION_ON : INVERSION_OFF;
-
-       deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, c->inversion);
-
-       switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
-               case DIB3000_CONSTELLATION_QPSK:
-                       deb_getf("QPSK ");
-                       c->modulation = QPSK;
-                       break;
-               case DIB3000_CONSTELLATION_16QAM:
-                       deb_getf("QAM16 ");
-                       c->modulation = QAM_16;
-                       break;
-               case DIB3000_CONSTELLATION_64QAM:
-                       deb_getf("QAM64 ");
-                       c->modulation = QAM_64;
-                       break;
-               default:
-                       err("Unexpected constellation returned by TPS (%d)", tps_val);
-                       break;
-       }
-       deb_getf("TPS: %d\n", tps_val);
-
-       if (rd(DIB3000MB_REG_TPS_HRCH)) {
-               deb_getf("HRCH ON\n");
-               cr = &c->code_rate_LP;
-               c->code_rate_HP = FEC_NONE;
-               switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
-                       case DIB3000_ALPHA_0:
-                               deb_getf("HIERARCHY_NONE ");
-                               c->hierarchy = HIERARCHY_NONE;
-                               break;
-                       case DIB3000_ALPHA_1:
-                               deb_getf("HIERARCHY_1 ");
-                               c->hierarchy = HIERARCHY_1;
-                               break;
-                       case DIB3000_ALPHA_2:
-                               deb_getf("HIERARCHY_2 ");
-                               c->hierarchy = HIERARCHY_2;
-                               break;
-                       case DIB3000_ALPHA_4:
-                               deb_getf("HIERARCHY_4 ");
-                               c->hierarchy = HIERARCHY_4;
-                               break;
-                       default:
-                               err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
-                               break;
-               }
-               deb_getf("TPS: %d\n", tps_val);
-
-               tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
-       } else {
-               deb_getf("HRCH OFF\n");
-               cr = &c->code_rate_HP;
-               c->code_rate_LP = FEC_NONE;
-               c->hierarchy = HIERARCHY_NONE;
-
-               tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
-       }
-
-       switch (tps_val) {
-               case DIB3000_FEC_1_2:
-                       deb_getf("FEC_1_2 ");
-                       *cr = FEC_1_2;
-                       break;
-               case DIB3000_FEC_2_3:
-                       deb_getf("FEC_2_3 ");
-                       *cr = FEC_2_3;
-                       break;
-               case DIB3000_FEC_3_4:
-                       deb_getf("FEC_3_4 ");
-                       *cr = FEC_3_4;
-                       break;
-               case DIB3000_FEC_5_6:
-                       deb_getf("FEC_5_6 ");
-                       *cr = FEC_4_5;
-                       break;
-               case DIB3000_FEC_7_8:
-                       deb_getf("FEC_7_8 ");
-                       *cr = FEC_7_8;
-                       break;
-               default:
-                       err("Unexpected FEC returned by TPS (%d)", tps_val);
-                       break;
-       }
-       deb_getf("TPS: %d\n",tps_val);
-
-       switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
-               case DIB3000_GUARD_TIME_1_32:
-                       deb_getf("GUARD_INTERVAL_1_32 ");
-                       c->guard_interval = GUARD_INTERVAL_1_32;
-                       break;
-               case DIB3000_GUARD_TIME_1_16:
-                       deb_getf("GUARD_INTERVAL_1_16 ");
-                       c->guard_interval = GUARD_INTERVAL_1_16;
-                       break;
-               case DIB3000_GUARD_TIME_1_8:
-                       deb_getf("GUARD_INTERVAL_1_8 ");
-                       c->guard_interval = GUARD_INTERVAL_1_8;
-                       break;
-               case DIB3000_GUARD_TIME_1_4:
-                       deb_getf("GUARD_INTERVAL_1_4 ");
-                       c->guard_interval = GUARD_INTERVAL_1_4;
-                       break;
-               default:
-                       err("Unexpected Guard Time returned by TPS (%d)", tps_val);
-                       break;
-       }
-       deb_getf("TPS: %d\n", tps_val);
-
-       switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
-               case DIB3000_TRANSMISSION_MODE_2K:
-                       deb_getf("TRANSMISSION_MODE_2K ");
-                       c->transmission_mode = TRANSMISSION_MODE_2K;
-                       break;
-               case DIB3000_TRANSMISSION_MODE_8K:
-                       deb_getf("TRANSMISSION_MODE_8K ");
-                       c->transmission_mode = TRANSMISSION_MODE_8K;
-                       break;
-               default:
-                       err("unexpected transmission mode return by TPS (%d)", tps_val);
-                       break;
-       }
-       deb_getf("TPS: %d\n", tps_val);
-
-       return 0;
-}
-
-static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-
-       *stat = 0;
-
-       if (rd(DIB3000MB_REG_AGC_LOCK))
-               *stat |= FE_HAS_SIGNAL;
-       if (rd(DIB3000MB_REG_CARRIER_LOCK))
-               *stat |= FE_HAS_CARRIER;
-       if (rd(DIB3000MB_REG_VIT_LCK))
-               *stat |= FE_HAS_VITERBI;
-       if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
-               *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
-
-       deb_getf("actual status is %2x\n",*stat);
-
-       deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
-                       rd(DIB3000MB_REG_TPS_LOCK),
-                       rd(DIB3000MB_REG_TPS_QAM),
-                       rd(DIB3000MB_REG_TPS_HRCH),
-                       rd(DIB3000MB_REG_TPS_VIT_ALPHA),
-                       rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
-                       rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
-                       rd(DIB3000MB_REG_TPS_GUARD_TIME),
-                       rd(DIB3000MB_REG_TPS_FFT),
-                       rd(DIB3000MB_REG_TPS_CELL_ID));
-
-       //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-       return 0;
-}
-
-static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-
-       *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
-       return 0;
-}
-
-/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
-static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-
-       *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
-       return 0;
-}
-
-static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-       short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
-       int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
-               rd(DIB3000MB_REG_NOISE_POWER_LSB);
-       *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
-       return 0;
-}
-
-static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-
-       *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
-       return 0;
-}
-
-static int dib3000mb_sleep(struct dvb_frontend* fe)
-{
-       struct dib3000_state* state = fe->demodulator_priv;
-       deb_info("dib3000mb is going to bed.\n");
-       wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
-       return 0;
-}
-
-static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 800;
-       return 0;
-}
-
-static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
-{
-       return dib3000mb_fe_init(fe, 0);
-}
-
-static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend *fe)
-{
-       return dib3000mb_set_frontend(fe, 1);
-}
-
-static void dib3000mb_release(struct dvb_frontend* fe)
-{
-       struct dib3000_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-/* pid filter and transfer stuff */
-static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
-{
-       struct dib3000_state *state = fe->demodulator_priv;
-       pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
-       wr(index+DIB3000MB_REG_FIRST_PID,pid);
-       return 0;
-}
-
-static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
-{
-       struct dib3000_state *state = fe->demodulator_priv;
-
-       deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
-       if (onoff) {
-               wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
-       } else {
-               wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
-       }
-       return 0;
-}
-
-static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
-{
-       struct dib3000_state *state = fe->demodulator_priv;
-       deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
-       wr(DIB3000MB_REG_PID_PARSE,onoff);
-       return 0;
-}
-
-static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
-{
-       struct dib3000_state *state = fe->demodulator_priv;
-       if (onoff) {
-               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
-       } else {
-               wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
-       }
-       return 0;
-}
-
-static struct dvb_frontend_ops dib3000mb_ops;
-
-struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
-                                     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
-{
-       struct dib3000_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->config,config,sizeof(struct dib3000_config));
-
-       /* check for the correct demod */
-       if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
-               goto error;
-
-       if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       /* set the xfer operations */
-       xfer_ops->pid_parse = dib3000mb_pid_parse;
-       xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
-       xfer_ops->pid_ctrl = dib3000mb_pid_control;
-       xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops dib3000mb_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "DiBcom 3000M-B DVB-T",
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_INVERSION_AUTO |
-                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                               FE_CAN_TRANSMISSION_MODE_AUTO |
-                               FE_CAN_GUARD_INTERVAL_AUTO |
-                               FE_CAN_RECOVER |
-                               FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = dib3000mb_release,
-
-       .init = dib3000mb_fe_init_nonmobile,
-       .sleep = dib3000mb_sleep,
-
-       .set_frontend = dib3000mb_set_frontend_and_tuner,
-       .get_frontend = dib3000mb_get_frontend,
-       .get_tune_settings = dib3000mb_fe_get_tune_settings,
-
-       .read_status = dib3000mb_read_status,
-       .read_ber = dib3000mb_read_ber,
-       .read_signal_strength = dib3000mb_read_signal_strength,
-       .read_snr = dib3000mb_read_snr,
-       .read_ucblocks = dib3000mb_read_unc_blocks,
-};
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
deleted file mode 100644 (file)
index 9dc235a..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * dib3000mb_priv.h
- *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- *
- * for more information see dib3000mb.c .
- */
-
-#ifndef __DIB3000MB_PRIV_H_INCLUDED__
-#define __DIB3000MB_PRIV_H_INCLUDED__
-
-/* info and err, taken from usb.h, if there is anything available like by default. */
-#define err(format, arg...)  printk(KERN_ERR     "dib3000: " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO    "dib3000: " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
-
-/* handy shortcuts */
-#define rd(reg) dib3000_read_reg(state,reg)
-
-#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
-       { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
-
-#define wr_foreach(a,v) { int i; \
-       if (sizeof(a) != sizeof(v)) \
-               err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
-       for (i=0; i < sizeof(a)/sizeof(u16); i++) \
-               wr(a[i],v[i]); \
-       }
-
-#define set_or(reg,val) wr(reg,rd(reg) | val)
-
-#define set_and(reg,val) wr(reg,rd(reg) & val)
-
-/* debug */
-
-#define dprintk(level,args...) \
-    do { if ((debug & level)) { printk(args); } } while (0)
-
-/* mask for enabling a specific pid for the pid_filter */
-#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
-
-/* common values for tuning */
-#define DIB3000_ALPHA_0                                        (     0)
-#define DIB3000_ALPHA_1                                        (     1)
-#define DIB3000_ALPHA_2                                        (     2)
-#define DIB3000_ALPHA_4                                        (     4)
-
-#define DIB3000_CONSTELLATION_QPSK             (     0)
-#define DIB3000_CONSTELLATION_16QAM            (     1)
-#define DIB3000_CONSTELLATION_64QAM            (     2)
-
-#define DIB3000_GUARD_TIME_1_32                        (     0)
-#define DIB3000_GUARD_TIME_1_16                        (     1)
-#define DIB3000_GUARD_TIME_1_8                 (     2)
-#define DIB3000_GUARD_TIME_1_4                 (     3)
-
-#define DIB3000_TRANSMISSION_MODE_2K   (     0)
-#define DIB3000_TRANSMISSION_MODE_8K   (     1)
-
-#define DIB3000_SELECT_LP                              (     0)
-#define DIB3000_SELECT_HP                              (     1)
-
-#define DIB3000_FEC_1_2                                        (     1)
-#define DIB3000_FEC_2_3                                        (     2)
-#define DIB3000_FEC_3_4                                        (     3)
-#define DIB3000_FEC_5_6                                        (     5)
-#define DIB3000_FEC_7_8                                        (     7)
-
-#define DIB3000_HRCH_OFF                               (     0)
-#define DIB3000_HRCH_ON                                        (     1)
-
-#define DIB3000_DDS_INVERSION_OFF              (     0)
-#define DIB3000_DDS_INVERSION_ON               (     1)
-
-#define DIB3000_TUNER_WRITE_ENABLE(a)  (0xffff & (a << 8))
-#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
-
-#define DIB3000_REG_MANUFACTOR_ID              (  1025)
-#define DIB3000_I2C_ID_DIBCOM                  (0x01b3)
-
-#define DIB3000_REG_DEVICE_ID                  (  1026)
-#define DIB3000MB_DEVICE_ID                            (0x3000)
-#define DIB3000MC_DEVICE_ID                            (0x3001)
-#define DIB3000P_DEVICE_ID                             (0x3002)
-
-/* frontend state */
-struct dib3000_state {
-       struct i2c_adapter* i2c;
-
-/* configuration settings */
-       struct dib3000_config config;
-
-       struct dvb_frontend frontend;
-       int timing_offset;
-       int timing_offset_comp_done;
-
-       u32 last_tuned_bw;
-       u32 last_tuned_freq;
-};
-
-/* register addresses and some of their default values */
-
-/* restart subsystems */
-#define DIB3000MB_REG_RESTART                  (     0)
-
-#define DIB3000MB_RESTART_OFF                  (     0)
-#define DIB3000MB_RESTART_AUTO_SEARCH          (1 << 1)
-#define DIB3000MB_RESTART_CTRL                         (1 << 2)
-#define DIB3000MB_RESTART_AGC                          (1 << 3)
-
-/* FFT size */
-#define DIB3000MB_REG_FFT                              (     1)
-
-/* Guard time */
-#define DIB3000MB_REG_GUARD_TIME               (     2)
-
-/* QAM */
-#define DIB3000MB_REG_QAM                              (     3)
-
-/* Alpha coefficient high priority Viterbi algorithm */
-#define DIB3000MB_REG_VIT_ALPHA                        (     4)
-
-/* spectrum inversion */
-#define DIB3000MB_REG_DDS_INV                  (     5)
-
-/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
-#define DIB3000MB_REG_DDS_FREQ_MSB             (     6)
-#define DIB3000MB_REG_DDS_FREQ_LSB             (     7)
-#define DIB3000MB_DDS_FREQ_MSB                         (   178)
-#define DIB3000MB_DDS_FREQ_LSB                         (  8990)
-
-/* timing frequency (carrier spacing) */
-static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
-static u16 dib3000mb_timing_freq[][2] = {
-       { 126 , 48873 }, /* 6 MHz */
-       { 147 , 57019 }, /* 7 MHz */
-       { 168 , 65164 }, /* 8 MHz */
-};
-
-/* impulse noise parameter */
-/* 36 ??? */
-
-static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
-
-enum dib3000mb_impulse_noise_type {
-       DIB3000MB_IMPNOISE_OFF,
-       DIB3000MB_IMPNOISE_MOBILE,
-       DIB3000MB_IMPNOISE_FIXED,
-       DIB3000MB_IMPNOISE_DEFAULT
-};
-
-static u16 dib3000mb_impulse_noise_values[][5] = {
-       { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
-       { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
-       { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
-       { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
-};
-
-/*
- * Dual Automatic-Gain-Control
- * - gains RF in tuner (AGC1)
- * - gains IF after filtering (AGC2)
- */
-
-/* also from 16 to 18 */
-static u16 dib3000mb_reg_agc_gain[] = {
-       19,20,21,22,23,24,25,26,27,28,29,30,31,32
-};
-
-static u16 dib3000mb_default_agc_gain[] =
-       { 0x0001, 52429,   623, 128, 166, 195, 61,   /* RF ??? */
-         0x0001, 53766, 38011,   0,  90,  33, 23 }; /* IF ??? */
-
-/* phase noise */
-/* 36 is set when setting the impulse noise */
-static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
-
-static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
-
-/* lock duration */
-static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
-static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
-
-/* AGC loop bandwidth */
-static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
-
-static u16 dib3000mb_agc_bandwidth_low[]  =
-       { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
-static u16 dib3000mb_agc_bandwidth_high[] =
-       { 2349,  5, 2349,  5, 2586, 2, 2586, 2 };
-
-/*
- * lock0 definition (coff_lock)
- */
-#define DIB3000MB_REG_LOCK0_MASK               (    51)
-#define DIB3000MB_LOCK0_DEFAULT                                (     4)
-
-/*
- * lock1 definition (cpil_lock)
- * for auto search
- * which values hide behind the lock masks
- */
-#define DIB3000MB_REG_LOCK1_MASK               (    52)
-#define DIB3000MB_LOCK1_SEARCH_4                       (0x0004)
-#define DIB3000MB_LOCK1_SEARCH_2048                    (0x0800)
-#define DIB3000MB_LOCK1_DEFAULT                                (0x0001)
-
-/*
- * lock2 definition (fec_lock) */
-#define DIB3000MB_REG_LOCK2_MASK               (    53)
-#define DIB3000MB_LOCK2_DEFAULT                                (0x0080)
-
-/*
- * SEQ ? what was that again ... :)
- * changes when, inversion, guard time and fft is
- * either automatically detected or not
- */
-#define DIB3000MB_REG_SEQ                              (    54)
-
-/* bandwidth */
-static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
-static u16 dib3000mb_bandwidth_6mhz[] =
-       { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
-
-static u16 dib3000mb_bandwidth_7mhz[] =
-       { 0, 28, 64421,  96, 39973, 483,  3255, 0, 1000, 0, 1010, 1, 45264 };
-
-static u16 dib3000mb_bandwidth_8mhz[] =
-       { 0, 25, 23600,  84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
-
-#define DIB3000MB_REG_UNK_68                           (    68)
-#define DIB3000MB_UNK_68                                               (     0)
-
-#define DIB3000MB_REG_UNK_69                           (    69)
-#define DIB3000MB_UNK_69                                               (     0)
-
-#define DIB3000MB_REG_UNK_71                           (    71)
-#define DIB3000MB_UNK_71                                               (     0)
-
-#define DIB3000MB_REG_UNK_77                           (    77)
-#define DIB3000MB_UNK_77                                               (     6)
-
-#define DIB3000MB_REG_UNK_78                           (    78)
-#define DIB3000MB_UNK_78                                               (0x0080)
-
-/* isi */
-#define DIB3000MB_REG_ISI                              (    79)
-#define DIB3000MB_ISI_ACTIVATE                         (     0)
-#define DIB3000MB_ISI_INHIBIT                          (     1)
-
-/* sync impovement */
-#define DIB3000MB_REG_SYNC_IMPROVEMENT (    84)
-#define DIB3000MB_SYNC_IMPROVE_2K_1_8          (     3)
-#define DIB3000MB_SYNC_IMPROVE_DEFAULT         (     0)
-
-/* phase noise compensation inhibition */
-#define DIB3000MB_REG_PHASE_NOISE              (    87)
-#define DIB3000MB_PHASE_NOISE_DEFAULT  (     0)
-
-#define DIB3000MB_REG_UNK_92                           (    92)
-#define DIB3000MB_UNK_92                                               (0x0080)
-
-#define DIB3000MB_REG_UNK_96                           (    96)
-#define DIB3000MB_UNK_96                                               (0x0010)
-
-#define DIB3000MB_REG_UNK_97                           (    97)
-#define DIB3000MB_UNK_97                                               (0x0009)
-
-/* mobile mode ??? */
-#define DIB3000MB_REG_MOBILE_MODE              (   101)
-#define DIB3000MB_MOBILE_MODE_ON                       (     1)
-#define DIB3000MB_MOBILE_MODE_OFF                      (     0)
-
-#define DIB3000MB_REG_UNK_106                  (   106)
-#define DIB3000MB_UNK_106                                      (0x0080)
-
-#define DIB3000MB_REG_UNK_107                  (   107)
-#define DIB3000MB_UNK_107                                      (0x0080)
-
-#define DIB3000MB_REG_UNK_108                  (   108)
-#define DIB3000MB_UNK_108                                      (0x0080)
-
-/* fft */
-#define DIB3000MB_REG_UNK_121                  (   121)
-#define DIB3000MB_UNK_121_2K                           (     7)
-#define DIB3000MB_UNK_121_DEFAULT                      (     5)
-
-#define DIB3000MB_REG_UNK_122                  (   122)
-#define DIB3000MB_UNK_122                                      (  2867)
-
-/* QAM for mobile mode */
-#define DIB3000MB_REG_MOBILE_MODE_QAM  (   126)
-#define DIB3000MB_MOBILE_MODE_QAM_64           (     3)
-#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16      (     1)
-#define DIB3000MB_MOBILE_MODE_QAM_OFF          (     0)
-
-/*
- * data diversity when having more than one chip on-board
- * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
- */
-#define DIB3000MB_REG_DATA_IN_DIVERSITY                (   127)
-#define DIB3000MB_DATA_DIVERSITY_IN_OFF                        (     0)
-#define DIB3000MB_DATA_DIVERSITY_IN_ON                 (     2)
-
-/* vit hrch */
-#define DIB3000MB_REG_VIT_HRCH                 (   128)
-
-/* vit code rate */
-#define DIB3000MB_REG_VIT_CODE_RATE            (   129)
-
-/* vit select hp */
-#define DIB3000MB_REG_VIT_HP                   (   130)
-
-/* time frame for Bit-Error-Rate calculation */
-#define DIB3000MB_REG_BERLEN                   (   135)
-#define DIB3000MB_BERLEN_LONG                          (     0)
-#define DIB3000MB_BERLEN_DEFAULT                       (     1)
-#define DIB3000MB_BERLEN_MEDIUM                                (     2)
-#define DIB3000MB_BERLEN_SHORT                         (     3)
-
-/* 142 - 152 FIFO parameters
- * which is what ?
- */
-
-#define DIB3000MB_REG_FIFO_142                 (   142)
-#define DIB3000MB_FIFO_142                                     (     0)
-
-/* MPEG2 TS output mode */
-#define DIB3000MB_REG_MPEG2_OUT_MODE   (   143)
-#define DIB3000MB_MPEG2_OUT_MODE_204           (     0)
-#define DIB3000MB_MPEG2_OUT_MODE_188           (     1)
-
-#define DIB3000MB_REG_PID_PARSE                        (   144)
-#define DIB3000MB_PID_PARSE_INHIBIT            (     0)
-#define DIB3000MB_PID_PARSE_ACTIVATE   (     1)
-
-#define DIB3000MB_REG_FIFO                             (   145)
-#define DIB3000MB_FIFO_INHIBIT                         (     1)
-#define DIB3000MB_FIFO_ACTIVATE                                (     0)
-
-#define DIB3000MB_REG_FIFO_146                 (   146)
-#define DIB3000MB_FIFO_146                                     (     3)
-
-#define DIB3000MB_REG_FIFO_147                 (   147)
-#define DIB3000MB_FIFO_147                                     (0x0100)
-
-/*
- * pidfilter
- * it is not a hardware pidfilter but a filter which drops all pids
- * except the ones set. Necessary because of the limited USB1.1 bandwidth.
- * regs 153-168
- */
-
-#define DIB3000MB_REG_FIRST_PID                        (   153)
-#define DIB3000MB_NUM_PIDS                             (    16)
-
-/*
- * output mode
- * USB devices have to use 'slave'-mode
- * see also DIB3000MB_REG_ELECT_OUT_MODE
- */
-#define DIB3000MB_REG_OUTPUT_MODE              (   169)
-#define DIB3000MB_OUTPUT_MODE_GATED_CLK                (     0)
-#define DIB3000MB_OUTPUT_MODE_CONT_CLK         (     1)
-#define DIB3000MB_OUTPUT_MODE_SERIAL           (     2)
-#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY   (     5)
-#define DIB3000MB_OUTPUT_MODE_SLAVE                    (     6)
-
-/* irq event mask */
-#define DIB3000MB_REG_IRQ_EVENT_MASK           (   170)
-#define DIB3000MB_IRQ_EVENT_MASK                               (     0)
-
-/* filter coefficients */
-static u16 dib3000mb_reg_filter_coeffs[] = {
-       171, 172, 173, 174, 175, 176, 177, 178,
-       179, 180, 181, 182, 183, 184, 185, 186,
-       188, 189, 190, 191, 192, 194
-};
-
-static u16 dib3000mb_filter_coeffs[] = {
-        226,  160,   29,
-        979,  998,   19,
-         22, 1019, 1006,
-       1022,   12,    6,
-       1017, 1017,    3,
-          6,       1019,
-       1021,    2,    3,
-          1,          0,
-};
-
-/*
- * mobile algorithm (when you are moving with your device)
- * but not faster than 90 km/h
- */
-#define DIB3000MB_REG_MOBILE_ALGO              (   195)
-#define DIB3000MB_MOBILE_ALGO_ON                       (     0)
-#define DIB3000MB_MOBILE_ALGO_OFF                      (     1)
-
-/* multiple demodulators algorithm */
-#define DIB3000MB_REG_MULTI_DEMOD_MSB  (   206)
-#define DIB3000MB_REG_MULTI_DEMOD_LSB  (   207)
-
-/* terminator, no more demods */
-#define DIB3000MB_MULTI_DEMOD_MSB                      ( 32767)
-#define DIB3000MB_MULTI_DEMOD_LSB                      (  4095)
-
-/* bring the device into a known  */
-#define DIB3000MB_REG_RESET_DEVICE             (  1024)
-#define DIB3000MB_RESET_DEVICE                         (0x812c)
-#define DIB3000MB_RESET_DEVICE_RST                     (     0)
-
-/* hardware clock configuration */
-#define DIB3000MB_REG_CLOCK                            (  1027)
-#define DIB3000MB_CLOCK_DEFAULT                                (0x9000)
-#define DIB3000MB_CLOCK_DIVERSITY                      (0x92b0)
-
-/* power down config */
-#define DIB3000MB_REG_POWER_CONTROL            (  1028)
-#define DIB3000MB_POWER_DOWN                           (     1)
-#define DIB3000MB_POWER_UP                                     (     0)
-
-/* electrical output mode */
-#define DIB3000MB_REG_ELECT_OUT_MODE   (  1029)
-#define DIB3000MB_ELECT_OUT_MODE_OFF           (     0)
-#define DIB3000MB_ELECT_OUT_MODE_ON                    (     1)
-
-/* set the tuner i2c address */
-#define DIB3000MB_REG_TUNER                            (  1089)
-
-/* monitoring registers (read only) */
-
-/* agc loop locked (size: 1) */
-#define DIB3000MB_REG_AGC_LOCK                 (   324)
-
-/* agc power (size: 16) */
-#define DIB3000MB_REG_AGC_POWER                        (   325)
-
-/* agc1 value (16) */
-#define DIB3000MB_REG_AGC1_VALUE               (   326)
-
-/* agc2 value (16) */
-#define DIB3000MB_REG_AGC2_VALUE               (   327)
-
-/* total RF power (16), can be used for signal strength */
-#define DIB3000MB_REG_RF_POWER                 (   328)
-
-/* dds_frequency with offset (24) */
-#define DIB3000MB_REG_DDS_VALUE_MSB            (   339)
-#define DIB3000MB_REG_DDS_VALUE_LSB            (   340)
-
-/* timing offset signed (24) */
-#define DIB3000MB_REG_TIMING_OFFSET_MSB        (   341)
-#define DIB3000MB_REG_TIMING_OFFSET_LSB        (   342)
-
-/* fft start position (13) */
-#define DIB3000MB_REG_FFT_WINDOW_POS   (   353)
-
-/* carriers locked (1) */
-#define DIB3000MB_REG_CARRIER_LOCK             (   355)
-
-/* noise power (24) */
-#define DIB3000MB_REG_NOISE_POWER_MSB  (   372)
-#define DIB3000MB_REG_NOISE_POWER_LSB  (   373)
-
-#define DIB3000MB_REG_MOBILE_NOISE_MSB (   374)
-#define DIB3000MB_REG_MOBILE_NOISE_LSB (   375)
-
-/*
- * signal power (16), this and the above can be
- * used to calculate the signal/noise - ratio
- */
-#define DIB3000MB_REG_SIGNAL_POWER             (   380)
-
-/* mer (24) */
-#define DIB3000MB_REG_MER_MSB                  (   381)
-#define DIB3000MB_REG_MER_LSB                  (   382)
-
-/*
- * Transmission Parameter Signalling (TPS)
- * the following registers can be used to get TPS-information.
- * The values are according to the DVB-T standard.
- */
-
-/* TPS locked (1) */
-#define DIB3000MB_REG_TPS_LOCK                 (   394)
-
-/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
-#define DIB3000MB_REG_TPS_QAM                  (   398)
-
-/* hierarchy from TPS (1) */
-#define DIB3000MB_REG_TPS_HRCH                 (   399)
-
-/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
-#define DIB3000MB_REG_TPS_VIT_ALPHA            (   400)
-
-/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
-#define DIB3000MB_REG_TPS_CODE_RATE_HP (   401)
-
-/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
-#define DIB3000MB_REG_TPS_CODE_RATE_LP (   402)
-
-/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
-#define DIB3000MB_REG_TPS_GUARD_TIME   (   403)
-
-/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
-#define DIB3000MB_REG_TPS_FFT                  (   404)
-
-/* cell id from TPS (16) */
-#define DIB3000MB_REG_TPS_CELL_ID              (   406)
-
-/* TPS (68) */
-#define DIB3000MB_REG_TPS_1                            (   408)
-#define DIB3000MB_REG_TPS_2                            (   409)
-#define DIB3000MB_REG_TPS_3                            (   410)
-#define DIB3000MB_REG_TPS_4                            (   411)
-#define DIB3000MB_REG_TPS_5                            (   412)
-
-/* bit error rate (before RS correction) (21) */
-#define DIB3000MB_REG_BER_MSB                  (   414)
-#define DIB3000MB_REG_BER_LSB                  (   415)
-
-/* packet error rate (uncorrected TS packets) (16) */
-#define DIB3000MB_REG_PACKET_ERROR_RATE        (   417)
-
-/* uncorrected packet count (16) */
-#define DIB3000MB_REG_UNC                              (   420)
-
-/* viterbi locked (1) */
-#define DIB3000MB_REG_VIT_LCK                  (   421)
-
-/* viterbi inidcator (16) */
-#define DIB3000MB_REG_VIT_INDICATOR            (   422)
-
-/* transport stream sync lock (1) */
-#define DIB3000MB_REG_TS_SYNC_LOCK             (   423)
-
-/* transport stream RS lock (1) */
-#define DIB3000MB_REG_TS_RS_LOCK               (   424)
-
-/* lock mask 0 value (1) */
-#define DIB3000MB_REG_LOCK0_VALUE              (   425)
-
-/* lock mask 1 value (1) */
-#define DIB3000MB_REG_LOCK1_VALUE              (   426)
-
-/* lock mask 2 value (1) */
-#define DIB3000MB_REG_LOCK2_VALUE              (   427)
-
-/* interrupt pending for auto search */
-#define DIB3000MB_REG_AS_IRQ_PENDING   (   434)
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
deleted file mode 100644 (file)
index ffad181..0000000
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- * Driver for DiBcom DiB3000MC/P-demodulator.
- *
- * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * This code is partially based on the previous dib3000mc.c .
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-
-#include "dib3000mc.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-static int buggy_sfn_workaround;
-module_param(buggy_sfn_workaround, int, 0644);
-MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
-
-struct dib3000mc_state {
-       struct dvb_frontend demod;
-       struct dib3000mc_config *cfg;
-
-       u8 i2c_addr;
-       struct i2c_adapter *i2c_adap;
-
-       struct dibx000_i2c_master i2c_master;
-
-       u32 timf;
-
-       u32 current_bandwidth;
-
-       u16 dev_id;
-
-       u8 sfn_workaround_active :1;
-};
-
-static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
-{
-       u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
-       u8 rb[2];
-       struct i2c_msg msg[2] = {
-               { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
-               { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
-       };
-
-       if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
-               dprintk("i2c read error on %d\n",reg);
-
-       return (rb[0] << 8) | rb[1];
-}
-
-static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
-{
-       u8 b[4] = {
-               (reg >> 8) & 0xff, reg & 0xff,
-               (val >> 8) & 0xff, val & 0xff,
-       };
-       struct i2c_msg msg = {
-               .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
-       };
-       return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
-}
-
-static int dib3000mc_identify(struct dib3000mc_state *state)
-{
-       u16 value;
-       if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
-               dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
-               return -EREMOTEIO;
-       }
-
-       value = dib3000mc_read_word(state, 1026);
-       if (value != 0x3001 && value != 0x3002) {
-               dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
-               return -EREMOTEIO;
-       }
-       state->dev_id = value;
-
-       dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);
-
-       return 0;
-}
-
-static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
-{
-       u32 timf;
-
-       if (state->timf == 0) {
-               timf = 1384402; // default value for 8MHz
-               if (update_offset)
-                       msleep(200); // first time we do an update
-       } else
-               timf = state->timf;
-
-       timf *= (bw / 1000);
-
-       if (update_offset) {
-               s16 tim_offs = dib3000mc_read_word(state, 416);
-
-               if (tim_offs &  0x2000)
-                       tim_offs -= 0x4000;
-
-               if (nfft == TRANSMISSION_MODE_2K)
-                       tim_offs *= 4;
-
-               timf += tim_offs;
-               state->timf = timf / (bw / 1000);
-       }
-
-       dprintk("timf: %d\n", timf);
-
-       dib3000mc_write_word(state, 23, (u16) (timf >> 16));
-       dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
-
-       return 0;
-}
-
-static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
-{
-       u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
-    if (state->cfg->pwm3_inversion) {
-               reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
-               reg_52 |= (1 << 2);
-       } else {
-               reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
-               reg_52 |= (1 << 8);
-       }
-       dib3000mc_write_word(state, 51, reg_51);
-       dib3000mc_write_word(state, 52, reg_52);
-
-    if (state->cfg->use_pwm3)
-               dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
-       else
-               dib3000mc_write_word(state, 245, 0);
-
-    dib3000mc_write_word(state, 1040, 0x3);
-       return 0;
-}
-
-static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
-{
-       int    ret = 0;
-       u16 fifo_threshold = 1792;
-       u16 outreg = 0;
-       u16 outmode = 0;
-       u16 elecout = 1;
-       u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
-
-       dprintk("-I-  Setting output mode for demod %p to %d\n",
-                       &state->demod, mode);
-
-       switch (mode) {
-               case OUTMODE_HIGH_Z:  // disable
-                       elecout = 0;
-                       break;
-               case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
-                       outmode = 0;
-                       break;
-               case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
-                       outmode = 1;
-                       break;
-               case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
-                       outmode = 2;
-                       break;
-               case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
-                       elecout = 3;
-                       /*ADDR @ 206 :
-                       P_smo_error_discard  [1;6:6] = 0
-                       P_smo_rs_discard     [1;5:5] = 0
-                       P_smo_pid_parse      [1;4:4] = 0
-                       P_smo_fifo_flush     [1;3:3] = 0
-                       P_smo_mode           [2;2:1] = 11
-                       P_smo_ovf_prot       [1;0:0] = 0
-                       */
-                       smo_reg |= 3 << 1;
-                       fifo_threshold = 512;
-                       outmode = 5;
-                       break;
-               case OUTMODE_DIVERSITY:
-                       outmode = 4;
-                       elecout = 1;
-                       break;
-               default:
-                       dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
-                       outmode = 0;
-                       break;
-       }
-
-       if ((state->cfg->output_mpeg2_in_188_bytes))
-               smo_reg |= (1 << 5); // P_smo_rs_discard     [1;5:5] = 1
-
-       outreg = dib3000mc_read_word(state, 244) & 0x07FF;
-       outreg |= (outmode << 11);
-       ret |= dib3000mc_write_word(state,  244, outreg);
-       ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
-       ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
-       ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
-       return ret;
-}
-
-static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
-{
-       u16 bw_cfg[6] = { 0 };
-       u16 imp_bw_cfg[3] = { 0 };
-       u16 reg;
-
-/* settings here are for 27.7MHz */
-       switch (bw) {
-               case 8000:
-                       bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
-                       imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
-                       break;
-
-               case 7000:
-                       bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
-                       imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
-                       break;
-
-               case 6000:
-                       bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
-                       imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
-                       break;
-
-               case 5000:
-                       bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
-                       imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
-                       break;
-
-               default: return -EINVAL;
-       }
-
-       for (reg = 6; reg < 12; reg++)
-               dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
-       dib3000mc_write_word(state, 12, 0x0000);
-       dib3000mc_write_word(state, 13, 0x03e8);
-       dib3000mc_write_word(state, 14, 0x0000);
-       dib3000mc_write_word(state, 15, 0x03f2);
-       dib3000mc_write_word(state, 16, 0x0001);
-       dib3000mc_write_word(state, 17, 0xb0d0);
-       // P_sec_len
-       dib3000mc_write_word(state, 18, 0x0393);
-       dib3000mc_write_word(state, 19, 0x8700);
-
-       for (reg = 55; reg < 58; reg++)
-               dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
-
-       // Timing configuration
-       dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
-
-       return 0;
-}
-
-static u16 impulse_noise_val[29] =
-
-{
-       0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
-       0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
-       0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
-};
-
-static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
-{
-       u16 i;
-       for (i = 58; i < 87; i++)
-               dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
-
-       if (nfft == TRANSMISSION_MODE_8K) {
-               dib3000mc_write_word(state, 58, 0x3b);
-               dib3000mc_write_word(state, 84, 0x00);
-               dib3000mc_write_word(state, 85, 0x8200);
-       }
-
-       dib3000mc_write_word(state, 34, 0x1294);
-       dib3000mc_write_word(state, 35, 0x1ff8);
-       if (mode == 1)
-               dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
-}
-
-static int dib3000mc_init(struct dvb_frontend *demod)
-{
-       struct dib3000mc_state *state = demod->demodulator_priv;
-       struct dibx000_agc_config *agc = state->cfg->agc;
-
-       // Restart Configuration
-       dib3000mc_write_word(state, 1027, 0x8000);
-       dib3000mc_write_word(state, 1027, 0x0000);
-
-       // power up the demod + mobility configuration
-       dib3000mc_write_word(state, 140, 0x0000);
-       dib3000mc_write_word(state, 1031, 0);
-
-       if (state->cfg->mobile_mode) {
-               dib3000mc_write_word(state, 139,  0x0000);
-               dib3000mc_write_word(state, 141,  0x0000);
-               dib3000mc_write_word(state, 175,  0x0002);
-               dib3000mc_write_word(state, 1032, 0x0000);
-       } else {
-               dib3000mc_write_word(state, 139,  0x0001);
-               dib3000mc_write_word(state, 141,  0x0000);
-               dib3000mc_write_word(state, 175,  0x0000);
-               dib3000mc_write_word(state, 1032, 0x012C);
-       }
-       dib3000mc_write_word(state, 1033, 0x0000);
-
-       // P_clk_cfg
-       dib3000mc_write_word(state, 1037, 0x3130);
-
-       // other configurations
-
-       // P_ctrl_sfreq
-       dib3000mc_write_word(state, 33, (5 << 0));
-       dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
-
-       // Phase noise control
-       // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
-       dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
-
-       if (state->cfg->phase_noise_mode == 0)
-               dib3000mc_write_word(state, 111, 0x00);
-       else
-               dib3000mc_write_word(state, 111, 0x02);
-
-       // P_agc_global
-       dib3000mc_write_word(state, 50, 0x8000);
-
-       // agc setup misc
-       dib3000mc_setup_pwm_state(state);
-
-       // P_agc_counter_lock
-       dib3000mc_write_word(state, 53, 0x87);
-       // P_agc_counter_unlock
-       dib3000mc_write_word(state, 54, 0x87);
-
-       /* agc */
-       dib3000mc_write_word(state, 36, state->cfg->max_time);
-       dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
-       dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
-       dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
-
-       // set_agc_loop_Bw
-       dib3000mc_write_word(state, 40, 0x0179);
-       dib3000mc_write_word(state, 41, 0x03f0);
-
-       dib3000mc_write_word(state, 42, agc->agc1_max);
-       dib3000mc_write_word(state, 43, agc->agc1_min);
-       dib3000mc_write_word(state, 44, agc->agc2_max);
-       dib3000mc_write_word(state, 45, agc->agc2_min);
-       dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
-       dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
-       dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
-       dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
-
-// Begin: TimeOut registers
-       // P_pha3_thres
-       dib3000mc_write_word(state, 110, 3277);
-       // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
-       dib3000mc_write_word(state,  26, 0x6680);
-       // lock_mask0
-       dib3000mc_write_word(state, 1, 4);
-       // lock_mask1
-       dib3000mc_write_word(state, 2, 4);
-       // lock_mask2
-       dib3000mc_write_word(state, 3, 0x1000);
-       // P_search_maxtrial=1
-       dib3000mc_write_word(state, 5, 1);
-
-       dib3000mc_set_bandwidth(state, 8000);
-
-       // div_lock_mask
-       dib3000mc_write_word(state,  4, 0x814);
-
-       dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
-       dib3000mc_write_word(state, 22, 0x463d);
-
-       // Spurious rm cfg
-       // P_cspu_regul, P_cspu_win_cut
-       dib3000mc_write_word(state, 120, 0x200f);
-       // P_adp_selec_monit
-       dib3000mc_write_word(state, 134, 0);
-
-       // Fec cfg
-       dib3000mc_write_word(state, 195, 0x10);
-
-       // diversity register: P_dvsy_sync_wait..
-       dib3000mc_write_word(state, 180, 0x2FF0);
-
-       // Impulse noise configuration
-       dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
-
-       // output mode set-up
-       dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
-
-       /* close the i2c-gate */
-       dib3000mc_write_word(state, 769, (1 << 7) );
-
-       return 0;
-}
-
-static int dib3000mc_sleep(struct dvb_frontend *demod)
-{
-       struct dib3000mc_state *state = demod->demodulator_priv;
-
-       dib3000mc_write_word(state, 1031, 0xFFFF);
-       dib3000mc_write_word(state, 1032, 0xFFFF);
-       dib3000mc_write_word(state, 1033, 0xFFF0);
-
-    return 0;
-}
-
-static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
-{
-       u16 cfg[4] = { 0 },reg;
-       switch (qam) {
-               case QPSK:
-                       cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
-                       break;
-               case QAM_16:
-                       cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
-                       break;
-               case QAM_64:
-                       cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
-                       break;
-       }
-       for (reg = 129; reg < 133; reg++)
-               dib3000mc_write_word(state, reg, cfg[reg - 129]);
-}
-
-static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
-                                     struct dtv_frontend_properties *ch, u16 seq)
-{
-       u16 value;
-       u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
-
-       dib3000mc_set_bandwidth(state, bw);
-       dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
-
-//     if (boost)
-//             dib3000mc_write_word(state, 100, (11 << 6) + 6);
-//     else
-               dib3000mc_write_word(state, 100, (16 << 6) + 9);
-
-       dib3000mc_write_word(state, 1027, 0x0800);
-       dib3000mc_write_word(state, 1027, 0x0000);
-
-       //Default cfg isi offset adp
-       dib3000mc_write_word(state, 26,  0x6680);
-       dib3000mc_write_word(state, 29,  0x1273);
-       dib3000mc_write_word(state, 33,       5);
-       dib3000mc_set_adp_cfg(state, QAM_16);
-       dib3000mc_write_word(state, 133,  15564);
-
-       dib3000mc_write_word(state, 12 , 0x0);
-       dib3000mc_write_word(state, 13 , 0x3e8);
-       dib3000mc_write_word(state, 14 , 0x0);
-       dib3000mc_write_word(state, 15 , 0x3f2);
-
-       dib3000mc_write_word(state, 93,0);
-       dib3000mc_write_word(state, 94,0);
-       dib3000mc_write_word(state, 95,0);
-       dib3000mc_write_word(state, 96,0);
-       dib3000mc_write_word(state, 97,0);
-       dib3000mc_write_word(state, 98,0);
-
-       dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
-
-       value = 0;
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
-               default:
-               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
-       }
-       switch (ch->guard_interval) {
-               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
-               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
-               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
-               default:
-               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
-       }
-       switch (ch->modulation) {
-               case QPSK:  value |= (0 << 3); break;
-               case QAM_16: value |= (1 << 3); break;
-               default:
-               case QAM_64: value |= (2 << 3); break;
-       }
-       switch (HIERARCHY_1) {
-               case HIERARCHY_2: value |= 2; break;
-               case HIERARCHY_4: value |= 4; break;
-               default:
-               case HIERARCHY_1: value |= 1; break;
-       }
-       dib3000mc_write_word(state, 0, value);
-       dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
-
-       value = 0;
-       if (ch->hierarchy == 1)
-               value |= (1 << 4);
-       if (1 == 1)
-               value |= 1;
-       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
-               case FEC_2_3: value |= (2 << 1); break;
-               case FEC_3_4: value |= (3 << 1); break;
-               case FEC_5_6: value |= (5 << 1); break;
-               case FEC_7_8: value |= (7 << 1); break;
-               default:
-               case FEC_1_2: value |= (1 << 1); break;
-       }
-       dib3000mc_write_word(state, 181, value);
-
-       // diversity synchro delay add 50% SFN margin
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_8K: value = 256; break;
-               case TRANSMISSION_MODE_2K:
-               default: value = 64; break;
-       }
-       switch (ch->guard_interval) {
-               case GUARD_INTERVAL_1_16: value *= 2; break;
-               case GUARD_INTERVAL_1_8:  value *= 4; break;
-               case GUARD_INTERVAL_1_4:  value *= 8; break;
-               default:
-               case GUARD_INTERVAL_1_32: value *= 1; break;
-       }
-       value <<= 4;
-       value |= dib3000mc_read_word(state, 180) & 0x000f;
-       dib3000mc_write_word(state, 180, value);
-
-       // restart demod
-       value = dib3000mc_read_word(state, 0);
-       dib3000mc_write_word(state, 0, value | (1 << 9));
-       dib3000mc_write_word(state, 0, value);
-
-       msleep(30);
-
-       dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
-}
-
-static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
-       struct dib3000mc_state *state = demod->demodulator_priv;
-       u16 reg;
-//     u32 val;
-       struct dtv_frontend_properties schan;
-
-       schan = *chan;
-
-       /* TODO what is that ? */
-
-       /* a channel for autosearch */
-       schan.transmission_mode = TRANSMISSION_MODE_8K;
-       schan.guard_interval = GUARD_INTERVAL_1_32;
-       schan.modulation = QAM_64;
-       schan.code_rate_HP = FEC_2_3;
-       schan.code_rate_LP = FEC_2_3;
-       schan.hierarchy = 0;
-
-       dib3000mc_set_channel_cfg(state, &schan, 11);
-
-       reg = dib3000mc_read_word(state, 0);
-       dib3000mc_write_word(state, 0, reg | (1 << 8));
-       dib3000mc_read_word(state, 511);
-       dib3000mc_write_word(state, 0, reg);
-
-       return 0;
-}
-
-static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
-{
-       struct dib3000mc_state *state = demod->demodulator_priv;
-       u16 irq_pending = dib3000mc_read_word(state, 511);
-
-       if (irq_pending & 0x1) // failed
-               return 1;
-
-       if (irq_pending & 0x2) // succeeded
-               return 2;
-
-       return 0; // still pending
-}
-
-static int dib3000mc_tune(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib3000mc_state *state = demod->demodulator_priv;
-
-       // ** configure demod **
-       dib3000mc_set_channel_cfg(state, ch, 0);
-
-       // activates isi
-       if (state->sfn_workaround_active) {
-               dprintk("SFN workaround is active\n");
-               dib3000mc_write_word(state, 29, 0x1273);
-               dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
-       } else {
-               dib3000mc_write_word(state, 29, 0x1073);
-               dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
-       }
-
-       dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
-       if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
-               dib3000mc_write_word(state, 26, 38528);
-               dib3000mc_write_word(state, 33, 8);
-       } else {
-               dib3000mc_write_word(state, 26, 30336);
-               dib3000mc_write_word(state, 33, 6);
-       }
-
-       if (dib3000mc_read_word(state, 509) & 0x80)
-               dib3000mc_set_timing(state, ch->transmission_mode,
-                                    BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
-
-       return 0;
-}
-
-struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
-{
-       struct dib3000mc_state *st = demod->demodulator_priv;
-       return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
-}
-
-EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
-
-static int dib3000mc_get_frontend(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       u16 tps = dib3000mc_read_word(state,458);
-
-       fep->inversion = INVERSION_AUTO;
-
-       fep->bandwidth_hz = state->current_bandwidth;
-
-       switch ((tps >> 8) & 0x1) {
-               case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
-               case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
-       }
-
-       switch (tps & 0x3) {
-               case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
-               case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
-               case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
-               case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
-       }
-
-       switch ((tps >> 13) & 0x3) {
-               case 0: fep->modulation = QPSK; break;
-               case 1: fep->modulation = QAM_16; break;
-               case 2:
-               default: fep->modulation = QAM_64; break;
-       }
-
-       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
-       /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
-
-       fep->hierarchy = HIERARCHY_NONE;
-       switch ((tps >> 5) & 0x7) {
-               case 1: fep->code_rate_HP = FEC_1_2; break;
-               case 2: fep->code_rate_HP = FEC_2_3; break;
-               case 3: fep->code_rate_HP = FEC_3_4; break;
-               case 5: fep->code_rate_HP = FEC_5_6; break;
-               case 7:
-               default: fep->code_rate_HP = FEC_7_8; break;
-
-       }
-
-       switch ((tps >> 2) & 0x7) {
-               case 1: fep->code_rate_LP = FEC_1_2; break;
-               case 2: fep->code_rate_LP = FEC_2_3; break;
-               case 3: fep->code_rate_LP = FEC_3_4; break;
-               case 5: fep->code_rate_LP = FEC_5_6; break;
-               case 7:
-               default: fep->code_rate_LP = FEC_7_8; break;
-       }
-
-       return 0;
-}
-
-static int dib3000mc_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       int ret;
-
-       dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
-
-       state->current_bandwidth = fep->bandwidth_hz;
-       dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
-
-       /* maybe the parameter has been changed */
-       state->sfn_workaround_active = buggy_sfn_workaround;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               msleep(100);
-       }
-
-       if (fep->transmission_mode  == TRANSMISSION_MODE_AUTO ||
-           fep->guard_interval == GUARD_INTERVAL_AUTO ||
-           fep->modulation     == QAM_AUTO ||
-           fep->code_rate_HP   == FEC_AUTO) {
-               int i = 1000, found;
-
-               dib3000mc_autosearch_start(fe);
-               do {
-                       msleep(1);
-                       found = dib3000mc_autosearch_is_irq(fe);
-               } while (found == 0 && i--);
-
-               dprintk("autosearch returns: %d\n",found);
-               if (found == 0 || found == 1)
-                       return 0; // no channel found
-
-               dib3000mc_get_frontend(fe);
-       }
-
-       ret = dib3000mc_tune(fe);
-
-       /* make this a config parameter */
-       dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
-       return ret;
-}
-
-static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       u16 lock = dib3000mc_read_word(state, 509);
-
-       *stat = 0;
-
-       if (lock & 0x8000)
-               *stat |= FE_HAS_SIGNAL;
-       if (lock & 0x3000)
-               *stat |= FE_HAS_CARRIER;
-       if (lock & 0x0100)
-               *stat |= FE_HAS_VITERBI;
-       if (lock & 0x0010)
-               *stat |= FE_HAS_SYNC;
-       if (lock & 0x0008)
-               *stat |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
-       return 0;
-}
-
-static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       *unc = dib3000mc_read_word(state, 508);
-       return 0;
-}
-
-static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       u16 val = dib3000mc_read_word(state, 392);
-       *strength = 65535 - val;
-       return 0;
-}
-
-static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       *snr = 0x0000;
-       return 0;
-}
-
-static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void dib3000mc_release(struct dvb_frontend *fe)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       dibx000_exit_i2c_master(&state->i2c_master);
-       kfree(state);
-}
-
-int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
-       return 0;
-}
-EXPORT_SYMBOL(dib3000mc_pid_control);
-
-int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
-       tmp |= (onoff << 4);
-       return dib3000mc_write_word(state, 206, tmp);
-}
-EXPORT_SYMBOL(dib3000mc_pid_parse);
-
-void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
-{
-       struct dib3000mc_state *state = fe->demodulator_priv;
-       state->cfg = cfg;
-}
-EXPORT_SYMBOL(dib3000mc_set_config);
-
-int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
-{
-       struct dib3000mc_state *dmcst;
-       int k;
-       u8 new_addr;
-
-       static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
-
-       dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
-       if (dmcst == NULL)
-               return -ENOMEM;
-
-       dmcst->i2c_adap = i2c;
-
-       for (k = no_of_demods-1; k >= 0; k--) {
-               dmcst->cfg = &cfg[k];
-
-               /* designated i2c address */
-               new_addr          = DIB3000MC_I2C_ADDRESS[k];
-               dmcst->i2c_addr = new_addr;
-               if (dib3000mc_identify(dmcst) != 0) {
-                       dmcst->i2c_addr = default_addr;
-                       if (dib3000mc_identify(dmcst) != 0) {
-                               dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
-                               kfree(dmcst);
-                               return -ENODEV;
-                       }
-               }
-
-               dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
-
-               // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
-               dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
-               dmcst->i2c_addr = new_addr;
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               dmcst->cfg = &cfg[k];
-               dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
-
-               dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
-
-               /* turn off data output */
-               dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
-       }
-
-       kfree(dmcst);
-       return 0;
-}
-EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
-
-static struct dvb_frontend_ops dib3000mc_ops;
-
-struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
-{
-       struct dvb_frontend *demod;
-       struct dib3000mc_state *st;
-       st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-
-       st->cfg = cfg;
-       st->i2c_adap = i2c_adap;
-       st->i2c_addr = i2c_addr;
-
-       demod                   = &st->demod;
-       demod->demodulator_priv = st;
-       memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
-
-       if (dib3000mc_identify(st) != 0)
-               goto error;
-
-       dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
-
-       dib3000mc_write_word(st, 1037, 0x3130);
-
-       return demod;
-
-error:
-       kfree(st);
-       return NULL;
-}
-EXPORT_SYMBOL(dib3000mc_attach);
-
-static struct dvb_frontend_ops dib3000mc_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "DiBcom 3000MC/P",
-               .frequency_min      = 44250000,
-               .frequency_max      = 867250000,
-               .frequency_stepsize = 62500,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release              = dib3000mc_release,
-
-       .init                 = dib3000mc_init,
-       .sleep                = dib3000mc_sleep,
-
-       .set_frontend         = dib3000mc_set_frontend,
-       .get_tune_settings    = dib3000mc_fe_get_tune_settings,
-       .get_frontend         = dib3000mc_get_frontend,
-
-       .read_status          = dib3000mc_read_status,
-       .read_ber             = dib3000mc_read_ber,
-       .read_signal_strength = dib3000mc_read_signal_strength,
-       .read_snr             = dib3000mc_read_snr,
-       .read_ucblocks        = dib3000mc_read_unc_blocks,
-};
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
deleted file mode 100644 (file)
index d75ffad..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Driver for DiBcom DiB3000MC/P-demodulator.
- *
- * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
- *
- * This code is partially based on the previous dib3000mc.c .
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#ifndef DIB3000MC_H
-#define DIB3000MC_H
-
-#include "dibx000_common.h"
-
-struct dib3000mc_config {
-       struct dibx000_agc_config *agc;
-
-       u8 phase_noise_mode;
-       u8 impulse_noise_mode;
-
-       u8  pwm3_inversion;
-       u8  use_pwm3;
-       u16 pwm3_value;
-
-       u16 max_time;
-       u16 ln_adc_level;
-
-       u8 agc_command1 :1;
-       u8 agc_command2 :1;
-
-       u8 mobile_mode;
-
-       u8 output_mpeg2_in_188_bytes;
-};
-
-#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
-#define DEFAULT_DIB3000P_I2C_ADDRESS  24
-
-#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
-                                     defined(MODULE))
-extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
-                                            u8 i2c_addr,
-                                            struct dib3000mc_config *cfg);
-extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
-                                    int no_of_demods, u8 default_addr,
-                                    struct dib3000mc_config cfg[]);
-extern
-struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
-                                                  int gating);
-#else
-static inline
-struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
-                                     struct dib3000mc_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline
-int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
-                             int no_of_demods, u8 default_addr,
-                             struct dib3000mc_config cfg[])
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline
-struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
-                                                  int gating)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_DIB3000MC
-
-extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
-extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
-
-extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
deleted file mode 100644 (file)
index 148bf79..0000000
+++ /dev/null
@@ -1,1473 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB7000M and
- *              first generation DiB7000P-demodulator-family.
- *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_frontend.h"
-
-#include "dib7000m.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
-
-struct dib7000m_state {
-       struct dvb_frontend demod;
-    struct dib7000m_config cfg;
-
-       u8 i2c_addr;
-       struct i2c_adapter   *i2c_adap;
-
-       struct dibx000_i2c_master i2c_master;
-
-/* offset is 1 in case of the 7000MC */
-       u8 reg_offs;
-
-       u16 wbd_ref;
-
-       u8 current_band;
-       u32 current_bandwidth;
-       struct dibx000_agc_config *current_agc;
-       u32 timf;
-       u32 timf_default;
-       u32 internal_clk;
-
-       u8 div_force_off : 1;
-       u8 div_state : 1;
-       u16 div_sync_wait;
-
-       u16 revision;
-
-       u8 agc_state;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[4];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-};
-
-enum dib7000m_power_mode {
-       DIB7000M_POWER_ALL = 0,
-
-       DIB7000M_POWER_NO,
-       DIB7000M_POWER_INTERF_ANALOG_AGC,
-       DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
-       DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
-       DIB7000M_POWER_INTERFACE_ONLY,
-};
-
-static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
-       state->i2c_write_buffer[1] = reg & 0xff;
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 2;
-       state->msg[1].addr = state->i2c_addr >> 1;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = state->i2c_read_buffer;
-       state->msg[1].len = 2;
-
-       if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
-               dprintk("i2c read error on %d",reg);
-
-       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
-       mutex_unlock(&state->i2c_buffer_lock);
-
-       return ret;
-}
-
-static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       state->i2c_write_buffer[1] = reg & 0xff;
-       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-       state->i2c_write_buffer[3] = val & 0xff;
-
-       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 4;
-
-       ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
-                       -EREMOTEIO : 0);
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
-{
-       u16 l = 0, r, *n;
-       n = buf;
-       l = *n++;
-       while (l) {
-               r = *n++;
-
-               if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
-                       r++;
-
-               do {
-                       dib7000m_write_word(state, r, *n++);
-                       r++;
-               } while (--l);
-               l = *n++;
-       }
-}
-
-static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
-{
-       int    ret = 0;
-       u16 outreg, fifo_threshold, smo_mode,
-               sram = 0x0005; /* by default SRAM output is disabled */
-
-       outreg = 0;
-       fifo_threshold = 1792;
-       smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
-
-       dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
-
-       switch (mode) {
-               case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
-                       outreg = (1 << 10);  /* 0x0400 */
-                       break;
-               case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
-                       outreg = (1 << 10) | (1 << 6); /* 0x0440 */
-                       break;
-               case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
-                       outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
-                       break;
-               case OUTMODE_DIVERSITY:
-                       if (state->cfg.hostbus_diversity)
-                               outreg = (1 << 10) | (4 << 6); /* 0x0500 */
-                       else
-                               sram   |= 0x0c00;
-                       break;
-               case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
-                       smo_mode |= (3 << 1);
-                       fifo_threshold = 512;
-                       outreg = (1 << 10) | (5 << 6);
-                       break;
-               case OUTMODE_HIGH_Z:  // disable
-                       outreg = 0;
-                       break;
-               default:
-                       dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
-                       break;
-       }
-
-       if (state->cfg.output_mpeg2_in_188_bytes)
-               smo_mode |= (1 << 5) ;
-
-       ret |= dib7000m_write_word(state,  294 + state->reg_offs, smo_mode);
-       ret |= dib7000m_write_word(state,  295 + state->reg_offs, fifo_threshold); /* synchronous fread */
-       ret |= dib7000m_write_word(state, 1795, outreg);
-       ret |= dib7000m_write_word(state, 1805, sram);
-
-       if (state->revision == 0x4003) {
-               u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
-               if (mode == OUTMODE_DIVERSITY)
-                       clk_cfg1 |= (1 << 1); // P_O_CLK_en
-               dib7000m_write_word(state, 909, clk_cfg1);
-       }
-       return ret;
-}
-
-static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
-{
-       /* by default everything is going to be powered off */
-       u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
-       u8  offset = 0;
-
-       /* now, depending on the requested mode, we power on */
-       switch (mode) {
-               /* power up everything in the demod */
-               case DIB7000M_POWER_ALL:
-                       reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
-                       break;
-
-               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
-               case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
-                       reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
-                       break;
-
-               case DIB7000M_POWER_INTERF_ANALOG_AGC:
-                       reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
-                       reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
-                       reg_906 &= ~((1 << 0));
-                       break;
-
-               case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
-                       reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
-                       break;
-
-               case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
-                       reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
-                       break;
-               case DIB7000M_POWER_NO:
-                       break;
-       }
-
-       /* always power down unused parts */
-       if (!state->cfg.mobile_mode)
-               reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
-
-       /* P_sdio_select_clk = 0 on MC and after*/
-       if (state->revision != 0x4000)
-               reg_906 <<= 1;
-
-       if (state->revision == 0x4003)
-               offset = 1;
-
-       dib7000m_write_word(state, 903 + offset, reg_903);
-       dib7000m_write_word(state, 904 + offset, reg_904);
-       dib7000m_write_word(state, 905 + offset, reg_905);
-       dib7000m_write_word(state, 906 + offset, reg_906);
-}
-
-static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
-{
-       int ret = 0;
-       u16 reg_913 = dib7000m_read_word(state, 913),
-              reg_914 = dib7000m_read_word(state, 914);
-
-       switch (no) {
-               case DIBX000_SLOW_ADC_ON:
-                       reg_914 |= (1 << 1) | (1 << 0);
-                       ret |= dib7000m_write_word(state, 914, reg_914);
-                       reg_914 &= ~(1 << 1);
-                       break;
-
-               case DIBX000_SLOW_ADC_OFF:
-                       reg_914 |=  (1 << 1) | (1 << 0);
-                       break;
-
-               case DIBX000_ADC_ON:
-                       if (state->revision == 0x4000) { // workaround for PA/MA
-                               // power-up ADC
-                               dib7000m_write_word(state, 913, 0);
-                               dib7000m_write_word(state, 914, reg_914 & 0x3);
-                               // power-down bandgag
-                               dib7000m_write_word(state, 913, (1 << 15));
-                               dib7000m_write_word(state, 914, reg_914 & 0x3);
-                       }
-
-                       reg_913 &= 0x0fff;
-                       reg_914 &= 0x0003;
-                       break;
-
-               case DIBX000_ADC_OFF: // leave the VBG voltage on
-                       reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
-                       reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
-                       break;
-
-               case DIBX000_VBG_ENABLE:
-                       reg_913 &= ~(1 << 15);
-                       break;
-
-               case DIBX000_VBG_DISABLE:
-                       reg_913 |= (1 << 15);
-                       break;
-
-               default:
-                       break;
-       }
-
-//     dprintk( "913: %x, 914: %x", reg_913, reg_914);
-       ret |= dib7000m_write_word(state, 913, reg_913);
-       ret |= dib7000m_write_word(state, 914, reg_914);
-
-       return ret;
-}
-
-static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
-{
-       u32 timf;
-
-       if (!bw)
-               bw = 8000;
-
-       // store the current bandwidth for later use
-       state->current_bandwidth = bw;
-
-       if (state->timf == 0) {
-               dprintk( "using default timf");
-               timf = state->timf_default;
-       } else {
-               dprintk( "using updated timf");
-               timf = state->timf;
-       }
-
-       timf = timf * (bw / 50) / 160;
-
-       dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
-       dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
-
-       return 0;
-}
-
-static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
-{
-       struct dib7000m_state *state = demod->demodulator_priv;
-
-       if (state->div_force_off) {
-               dprintk( "diversity combination deactivated - forced by COFDM parameters");
-               onoff = 0;
-       }
-       state->div_state = (u8)onoff;
-
-       if (onoff) {
-               dib7000m_write_word(state, 263 + state->reg_offs, 6);
-               dib7000m_write_word(state, 264 + state->reg_offs, 6);
-               dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
-       } else {
-               dib7000m_write_word(state, 263 + state->reg_offs, 1);
-               dib7000m_write_word(state, 264 + state->reg_offs, 0);
-               dib7000m_write_word(state, 266 + state->reg_offs, 0);
-       }
-
-       return 0;
-}
-
-static int dib7000m_sad_calib(struct dib7000m_state *state)
-{
-
-/* internal */
-//     dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
-       dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
-       dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
-
-       /* do the calibration */
-       dib7000m_write_word(state, 929, (1 << 0));
-       dib7000m_write_word(state, 929, (0 << 0));
-
-       msleep(1);
-
-       return 0;
-}
-
-static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
-{
-       dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
-       dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
-       dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
-       dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
-
-       dib7000m_write_word(state, 928, bw->sad_cfg);
-}
-
-static void dib7000m_reset_pll(struct dib7000m_state *state)
-{
-       const struct dibx000_bandwidth_config *bw = state->cfg.bw;
-       u16 reg_907,reg_910;
-
-       /* default */
-       reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
-               (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
-               (bw->enable_refdiv << 1) | (0 << 0);
-       reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
-
-       // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
-       // this is only working only for 30 MHz crystals
-       if (!state->cfg.quartz_direct) {
-               reg_910 |= (1 << 5);  // forcing the predivider to 1
-
-               // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
-               if(state->cfg.input_clk_is_div_2)
-                       reg_907 |= (16 << 9);
-               else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
-                       reg_907 |= (8 << 9);
-       } else {
-               reg_907 |= (bw->pll_ratio & 0x3f) << 9;
-               reg_910 |= (bw->pll_prediv << 5);
-       }
-
-       dib7000m_write_word(state, 910, reg_910); // pll cfg
-       dib7000m_write_word(state, 907, reg_907); // clk cfg0
-       dib7000m_write_word(state, 908, 0x0006);  // clk_cfg1
-
-       dib7000m_reset_pll_common(state, bw);
-}
-
-static void dib7000mc_reset_pll(struct dib7000m_state *state)
-{
-       const struct dibx000_bandwidth_config *bw = state->cfg.bw;
-       u16 clk_cfg1;
-
-       // clk_cfg0
-       dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
-
-       // clk_cfg1
-       //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
-       clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
-                       (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
-                       (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
-       dib7000m_write_word(state, 908, clk_cfg1);
-       clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
-       dib7000m_write_word(state, 908, clk_cfg1);
-
-       // smpl_cfg
-       dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
-
-       dib7000m_reset_pll_common(state, bw);
-}
-
-static int dib7000m_reset_gpio(struct dib7000m_state *st)
-{
-       /* reset the GPIOs */
-       dib7000m_write_word(st, 773, st->cfg.gpio_dir);
-       dib7000m_write_word(st, 774, st->cfg.gpio_val);
-
-       /* TODO 782 is P_gpio_od */
-
-       dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
-
-       dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
-       return 0;
-}
-
-static u16 dib7000m_defaults_common[] =
-
-{
-       // auto search configuration
-       3, 2,
-               0x0004,
-               0x1000,
-               0x0814,
-
-       12, 6,
-               0x001b,
-               0x7740,
-               0x005b,
-               0x8d80,
-               0x01c9,
-               0xc380,
-               0x0000,
-               0x0080,
-               0x0000,
-               0x0090,
-               0x0001,
-               0xd4c0,
-
-       1, 26,
-               0x6680, // P_corm_thres Lock algorithms configuration
-
-       1, 170,
-               0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
-
-       8, 173,
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-
-       1, 182,
-               8192, // P_fft_nb_to_cut
-
-       2, 195,
-               0x0ccd, // P_pha3_thres
-               0,      // P_cti_use_cpe, P_cti_use_prog
-
-       1, 205,
-               0x200f, // P_cspu_regul, P_cspu_win_cut
-
-       5, 214,
-               0x023d, // P_adp_regul_cnt
-               0x00a4, // P_adp_noise_cnt
-               0x00a4, // P_adp_regul_ext
-               0x7ff0, // P_adp_noise_ext
-               0x3ccc, // P_adp_fil
-
-       1, 226,
-               0, // P_2d_byp_ti_num
-
-       1, 255,
-               0x800, // P_equal_thres_wgn
-
-       1, 263,
-               0x0001,
-
-       1, 281,
-               0x0010, // P_fec_*
-
-       1, 294,
-               0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
-
-       0
-};
-
-static u16 dib7000m_defaults[] =
-
-{
-       /* set ADC level to -16 */
-       11, 76,
-               (1 << 13) - 825 - 117,
-               (1 << 13) - 837 - 117,
-               (1 << 13) - 811 - 117,
-               (1 << 13) - 766 - 117,
-               (1 << 13) - 737 - 117,
-               (1 << 13) - 693 - 117,
-               (1 << 13) - 648 - 117,
-               (1 << 13) - 619 - 117,
-               (1 << 13) - 575 - 117,
-               (1 << 13) - 531 - 117,
-               (1 << 13) - 501 - 117,
-
-       // Tuner IO bank: max drive (14mA)
-       1, 912,
-               0x2c8a,
-
-       1, 1817,
-               1,
-
-       0,
-};
-
-static int dib7000m_demod_reset(struct dib7000m_state *state)
-{
-       dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
-
-       /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
-       dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
-
-       /* restart all parts */
-       dib7000m_write_word(state,  898, 0xffff);
-       dib7000m_write_word(state,  899, 0xffff);
-       dib7000m_write_word(state,  900, 0xff0f);
-       dib7000m_write_word(state,  901, 0xfffc);
-
-       dib7000m_write_word(state,  898, 0);
-       dib7000m_write_word(state,  899, 0);
-       dib7000m_write_word(state,  900, 0);
-       dib7000m_write_word(state,  901, 0);
-
-       if (state->revision == 0x4000)
-               dib7000m_reset_pll(state);
-       else
-               dib7000mc_reset_pll(state);
-
-       if (dib7000m_reset_gpio(state) != 0)
-               dprintk( "GPIO reset was not successful.");
-
-       if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
-               dprintk( "OUTPUT_MODE could not be reset.");
-
-       /* unforce divstr regardless whether i2c enumeration was done or not */
-       dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
-
-       dib7000m_set_bandwidth(state, 8000);
-
-       dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-       dib7000m_sad_calib(state);
-       dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
-
-       if (state->cfg.dvbt_mode)
-               dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
-
-       if (state->cfg.mobile_mode)
-               dib7000m_write_word(state, 261 + state->reg_offs, 2);
-       else
-               dib7000m_write_word(state, 224 + state->reg_offs, 1);
-
-       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
-       if(state->cfg.tuner_is_baseband)
-               dib7000m_write_word(state, 36, 0x0755);
-       else
-               dib7000m_write_word(state, 36, 0x1f55);
-
-       // P_divclksel=3 P_divbitsel=1
-       if (state->revision == 0x4000)
-               dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
-       else
-               dib7000m_write_word(state, 909, (3 << 4) | 1);
-
-       dib7000m_write_tab(state, dib7000m_defaults_common);
-       dib7000m_write_tab(state, dib7000m_defaults);
-
-       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
-
-       state->internal_clk = state->cfg.bw->internal;
-
-       return 0;
-}
-
-static void dib7000m_restart_agc(struct dib7000m_state *state)
-{
-       // P_restart_iqc & P_restart_agc
-       dib7000m_write_word(state, 898, 0x0c00);
-       dib7000m_write_word(state, 898, 0x0000);
-}
-
-static int dib7000m_agc_soft_split(struct dib7000m_state *state)
-{
-       u16 agc,split_offset;
-
-       if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
-               return 0;
-
-       // n_agc_global
-       agc = dib7000m_read_word(state, 390);
-
-       if (agc > state->current_agc->split.min_thres)
-               split_offset = state->current_agc->split.min;
-       else if (agc < state->current_agc->split.max_thres)
-               split_offset = state->current_agc->split.max;
-       else
-               split_offset = state->current_agc->split.max *
-                       (agc - state->current_agc->split.min_thres) /
-                       (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
-
-       dprintk( "AGC split_offset: %d",split_offset);
-
-       // P_agc_force_split and P_agc_split_offset
-       return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
-}
-
-static int dib7000m_update_lna(struct dib7000m_state *state)
-{
-       u16 dyn_gain;
-
-       if (state->cfg.update_lna) {
-               // read dyn_gain here (because it is demod-dependent and not fe)
-               dyn_gain = dib7000m_read_word(state, 390);
-
-               if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
-                       dib7000m_restart_agc(state);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
-{
-       struct dibx000_agc_config *agc = NULL;
-       int i;
-       if (state->current_band == band && state->current_agc != NULL)
-               return 0;
-       state->current_band = band;
-
-       for (i = 0; i < state->cfg.agc_config_count; i++)
-               if (state->cfg.agc[i].band_caps & band) {
-                       agc = &state->cfg.agc[i];
-                       break;
-               }
-
-       if (agc == NULL) {
-               dprintk( "no valid AGC configuration found for band 0x%02x",band);
-               return -EINVAL;
-       }
-
-       state->current_agc = agc;
-
-       /* AGC */
-       dib7000m_write_word(state, 72 ,  agc->setup);
-       dib7000m_write_word(state, 73 ,  agc->inv_gain);
-       dib7000m_write_word(state, 74 ,  agc->time_stabiliz);
-       dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
-
-       // Demod AGC loop configuration
-       dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
-       dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
-
-       dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
-               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
-
-       /* AGC continued */
-       if (state->wbd_ref != 0)
-               dib7000m_write_word(state, 102, state->wbd_ref);
-       else // use default
-               dib7000m_write_word(state, 102, agc->wbd_ref);
-
-       dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
-       dib7000m_write_word(state, 104,  agc->agc1_max);
-       dib7000m_write_word(state, 105,  agc->agc1_min);
-       dib7000m_write_word(state, 106,  agc->agc2_max);
-       dib7000m_write_word(state, 107,  agc->agc2_min);
-       dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
-       dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
-       dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
-       dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
-
-       if (state->revision > 0x4000) { // settings for the MC
-               dib7000m_write_word(state, 71,   agc->agc1_pt3);
-//             dprintk( "929: %x %d %d",
-//                     (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
-               dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
-       } else {
-               // wrong default values
-               u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
-               for (i = 0; i < 9; i++)
-                       dib7000m_write_word(state, 88 + i, b[i]);
-       }
-       return 0;
-}
-
-static void dib7000m_update_timf(struct dib7000m_state *state)
-{
-       u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
-       state->timf = timf * 160 / (state->current_bandwidth / 50);
-       dib7000m_write_word(state, 23, (u16) (timf >> 16));
-       dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
-       dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
-}
-
-static int dib7000m_agc_startup(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000m_state *state = demod->demodulator_priv;
-       u16 cfg_72 = dib7000m_read_word(state, 72);
-       int ret = -1;
-       u8 *agc_state = &state->agc_state;
-       u8 agc_split;
-
-       switch (state->agc_state) {
-               case 0:
-                       // set power-up level: interf+analog+AGC
-                       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
-                       dib7000m_set_adc_state(state, DIBX000_ADC_ON);
-
-                       if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
-                               return -1;
-
-                       ret = 7; /* ADC power up */
-                       (*agc_state)++;
-                       break;
-
-               case 1:
-                       /* AGC initialization */
-                       if (state->cfg.agc_control)
-                               state->cfg.agc_control(&state->demod, 1);
-
-                       dib7000m_write_word(state, 75, 32768);
-                       if (!state->current_agc->perform_agc_softsplit) {
-                               /* we are using the wbd - so slow AGC startup */
-                               dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
-                               (*agc_state)++;
-                               ret = 5;
-                       } else {
-                               /* default AGC startup */
-                               (*agc_state) = 4;
-                               /* wait AGC rough lock time */
-                               ret = 7;
-                       }
-
-                       dib7000m_restart_agc(state);
-                       break;
-
-               case 2: /* fast split search path after 5sec */
-                       dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
-                       dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
-                       (*agc_state)++;
-                       ret = 14;
-                       break;
-
-       case 3: /* split search ended */
-                       agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
-                       dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
-
-                       dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
-                       dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
-
-                       dib7000m_restart_agc(state);
-
-                       dprintk( "SPLIT %p: %hd", demod, agc_split);
-
-                       (*agc_state)++;
-                       ret = 5;
-                       break;
-
-               case 4: /* LNA startup */
-                       /* wait AGC accurate lock time */
-                       ret = 7;
-
-                       if (dib7000m_update_lna(state))
-                               // wait only AGC rough lock time
-                               ret = 5;
-                       else
-                               (*agc_state)++;
-                       break;
-
-               case 5:
-                       dib7000m_agc_soft_split(state);
-
-                       if (state->cfg.agc_control)
-                               state->cfg.agc_control(&state->demod, 0);
-
-                       (*agc_state)++;
-                       break;
-
-               default:
-                       break;
-       }
-       return ret;
-}
-
-static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
-                                u8 seq)
-{
-       u16 value, est[4];
-
-       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
-
-       /* nfft, guard, qam, alpha */
-       value = 0;
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
-               case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
-               default:
-               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
-       }
-       switch (ch->guard_interval) {
-               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
-               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
-               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
-               default:
-               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
-       }
-       switch (ch->modulation) {
-               case QPSK:  value |= (0 << 3); break;
-               case QAM_16: value |= (1 << 3); break;
-               default:
-               case QAM_64: value |= (2 << 3); break;
-       }
-       switch (HIERARCHY_1) {
-               case HIERARCHY_2: value |= 2; break;
-               case HIERARCHY_4: value |= 4; break;
-               default:
-               case HIERARCHY_1: value |= 1; break;
-       }
-       dib7000m_write_word(state, 0, value);
-       dib7000m_write_word(state, 5, (seq << 4));
-
-       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
-       value = 0;
-       if (1 != 0)
-               value |= (1 << 6);
-       if (ch->hierarchy == 1)
-               value |= (1 << 4);
-       if (1 == 1)
-               value |= 1;
-       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
-               case FEC_2_3: value |= (2 << 1); break;
-               case FEC_3_4: value |= (3 << 1); break;
-               case FEC_5_6: value |= (5 << 1); break;
-               case FEC_7_8: value |= (7 << 1); break;
-               default:
-               case FEC_1_2: value |= (1 << 1); break;
-       }
-       dib7000m_write_word(state, 267 + state->reg_offs, value);
-
-       /* offset loop parameters */
-
-       /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
-       dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
-
-       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
-       dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
-
-       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
-       dib7000m_write_word(state, 32, (0 << 4) | 0x3);
-
-       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
-       dib7000m_write_word(state, 33, (0 << 4) | 0x5);
-
-       /* P_dvsy_sync_wait */
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_8K: value = 256; break;
-               case TRANSMISSION_MODE_4K: value = 128; break;
-               case TRANSMISSION_MODE_2K:
-               default: value = 64; break;
-       }
-       switch (ch->guard_interval) {
-               case GUARD_INTERVAL_1_16: value *= 2; break;
-               case GUARD_INTERVAL_1_8:  value *= 4; break;
-               case GUARD_INTERVAL_1_4:  value *= 8; break;
-               default:
-               case GUARD_INTERVAL_1_32: value *= 1; break;
-       }
-       state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
-
-       /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
-       /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-       if (1 == 1 || state->revision > 0x4000)
-               state->div_force_off = 0;
-       else
-               state->div_force_off = 1;
-       dib7000m_set_diversity_in(&state->demod, state->div_state);
-
-       /* channel estimation fine configuration */
-       switch (ch->modulation) {
-               case QAM_64:
-                       est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
-                       est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
-                       est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
-                       est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
-                       break;
-               case QAM_16:
-                       est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
-                       est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
-                       est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
-                       est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
-                       break;
-               default:
-                       est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
-                       est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
-                       est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
-                       est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
-                       break;
-       }
-       for (value = 0; value < 4; value++)
-               dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
-
-       // set power-up level: autosearch
-       dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
-}
-
-static int dib7000m_autosearch_start(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000m_state *state = demod->demodulator_priv;
-       struct dtv_frontend_properties schan;
-       int ret = 0;
-       u32 value, factor;
-
-       schan = *ch;
-
-       schan.modulation = QAM_64;
-       schan.guard_interval        = GUARD_INTERVAL_1_32;
-       schan.transmission_mode         = TRANSMISSION_MODE_8K;
-       schan.code_rate_HP = FEC_2_3;
-       schan.code_rate_LP = FEC_3_4;
-       schan.hierarchy    = 0;
-
-       dib7000m_set_channel(state, &schan, 7);
-
-       factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
-       if (factor >= 5000)
-               factor = 1;
-       else
-               factor = 6;
-
-       // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
-       value = 30 * state->internal_clk * factor;
-       ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
-       ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
-       value = 100 * state->internal_clk * factor;
-       ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
-       ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
-       value = 500 * state->internal_clk * factor;
-       ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
-       ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
-
-       // start search
-       value = dib7000m_read_word(state, 0);
-       ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
-
-       /* clear n_irq_pending */
-       if (state->revision == 0x4000)
-               dib7000m_write_word(state, 1793, 0);
-       else
-               dib7000m_read_word(state, 537);
-
-       ret |= dib7000m_write_word(state, 0, (u16) value);
-
-       return ret;
-}
-
-static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
-{
-       u16 irq_pending = dib7000m_read_word(state, reg);
-
-       if (irq_pending & 0x1) { // failed
-               dprintk( "autosearch failed");
-               return 1;
-       }
-
-       if (irq_pending & 0x2) { // succeeded
-               dprintk( "autosearch succeeded");
-               return 2;
-       }
-       return 0; // still pending
-}
-
-static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
-{
-       struct dib7000m_state *state = demod->demodulator_priv;
-       if (state->revision == 0x4000)
-               return dib7000m_autosearch_irq(state, 1793);
-       else
-               return dib7000m_autosearch_irq(state, 537);
-}
-
-static int dib7000m_tune(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000m_state *state = demod->demodulator_priv;
-       int ret = 0;
-       u16 value;
-
-       // we are already tuned - just resuming from suspend
-       if (ch != NULL)
-               dib7000m_set_channel(state, ch, 0);
-       else
-               return -EINVAL;
-
-       // restart demod
-       ret |= dib7000m_write_word(state, 898, 0x4000);
-       ret |= dib7000m_write_word(state, 898, 0x0000);
-       msleep(45);
-
-       dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
-       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
-       ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
-
-       // never achieved a lock before - wait for timfreq to update
-       if (state->timf == 0)
-               msleep(200);
-
-       //dump_reg(state);
-       /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
-       value = (6 << 8) | 0x80;
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
-               case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
-               default:
-               case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
-       }
-       ret |= dib7000m_write_word(state, 26, value);
-
-       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
-       value = (0 << 4);
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_2K: value |= 0x6; break;
-               case TRANSMISSION_MODE_4K: value |= 0x7; break;
-               default:
-               case TRANSMISSION_MODE_8K: value |= 0x8; break;
-       }
-       ret |= dib7000m_write_word(state, 32, value);
-
-       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
-       value = (0 << 4);
-       switch (ch->transmission_mode) {
-               case TRANSMISSION_MODE_2K: value |= 0x6; break;
-               case TRANSMISSION_MODE_4K: value |= 0x7; break;
-               default:
-               case TRANSMISSION_MODE_8K: value |= 0x8; break;
-       }
-       ret |= dib7000m_write_word(state, 33,  value);
-
-       // we achieved a lock - it's time to update the timf freq
-       if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
-               dib7000m_update_timf(state);
-
-       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
-       return ret;
-}
-
-static int dib7000m_wakeup(struct dvb_frontend *demod)
-{
-       struct dib7000m_state *state = demod->demodulator_priv;
-
-       dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
-
-       if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
-               dprintk( "could not start Slow ADC");
-
-       return 0;
-}
-
-static int dib7000m_sleep(struct dvb_frontend *demod)
-{
-       struct dib7000m_state *st = demod->demodulator_priv;
-       dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
-       dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
-       return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
-               dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
-}
-
-static int dib7000m_identify(struct dib7000m_state *state)
-{
-       u16 value;
-
-       if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
-               dprintk( "wrong Vendor ID (0x%x)",value);
-               return -EREMOTEIO;
-       }
-
-       state->revision = dib7000m_read_word(state, 897);
-       if (state->revision != 0x4000 &&
-               state->revision != 0x4001 &&
-               state->revision != 0x4002 &&
-               state->revision != 0x4003) {
-               dprintk( "wrong Device ID (0x%x)",value);
-               return -EREMOTEIO;
-       }
-
-       /* protect this driver to be used with 7000PC */
-       if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
-               dprintk( "this driver does not work with DiB7000PC");
-               return -EREMOTEIO;
-       }
-
-       switch (state->revision) {
-               case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
-               case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
-               case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
-               case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
-       }
-
-       return 0;
-}
-
-
-static int dib7000m_get_frontend(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib7000m_state *state = fe->demodulator_priv;
-       u16 tps = dib7000m_read_word(state,480);
-
-       fep->inversion = INVERSION_AUTO;
-
-       fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
-
-       switch ((tps >> 8) & 0x3) {
-               case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
-               case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
-               /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
-       }
-
-       switch (tps & 0x3) {
-               case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
-               case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
-               case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
-               case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
-       }
-
-       switch ((tps >> 14) & 0x3) {
-               case 0: fep->modulation = QPSK; break;
-               case 1: fep->modulation = QAM_16; break;
-               case 2:
-               default: fep->modulation = QAM_64; break;
-       }
-
-       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
-       /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
-
-       fep->hierarchy = HIERARCHY_NONE;
-       switch ((tps >> 5) & 0x7) {
-               case 1: fep->code_rate_HP = FEC_1_2; break;
-               case 2: fep->code_rate_HP = FEC_2_3; break;
-               case 3: fep->code_rate_HP = FEC_3_4; break;
-               case 5: fep->code_rate_HP = FEC_5_6; break;
-               case 7:
-               default: fep->code_rate_HP = FEC_7_8; break;
-
-       }
-
-       switch ((tps >> 2) & 0x7) {
-               case 1: fep->code_rate_LP = FEC_1_2; break;
-               case 2: fep->code_rate_LP = FEC_2_3; break;
-               case 3: fep->code_rate_LP = FEC_3_4; break;
-               case 5: fep->code_rate_LP = FEC_5_6; break;
-               case 7:
-               default: fep->code_rate_LP = FEC_7_8; break;
-       }
-
-       /* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
-
-       return 0;
-}
-
-static int dib7000m_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib7000m_state *state = fe->demodulator_priv;
-       int time, ret;
-
-       dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
-
-       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
-
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* start up the AGC */
-       state->agc_state = 0;
-       do {
-               time = dib7000m_agc_startup(fe);
-               if (time != -1)
-                       msleep(time);
-       } while (time != -1);
-
-       if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
-               fep->guard_interval    == GUARD_INTERVAL_AUTO ||
-               fep->modulation        == QAM_AUTO ||
-               fep->code_rate_HP      == FEC_AUTO) {
-               int i = 800, found;
-
-               dib7000m_autosearch_start(fe);
-               do {
-                       msleep(1);
-                       found = dib7000m_autosearch_is_irq(fe);
-               } while (found == 0 && i--);
-
-               dprintk("autosearch returns: %d",found);
-               if (found == 0 || found == 1)
-                       return 0; // no channel found
-
-               dib7000m_get_frontend(fe);
-       }
-
-       ret = dib7000m_tune(fe);
-
-       /* make this a config parameter */
-       dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
-       return ret;
-}
-
-static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       u16 lock = dib7000m_read_word(state, 535);
-
-       *stat = 0;
-
-       if (lock & 0x8000)
-               *stat |= FE_HAS_SIGNAL;
-       if (lock & 0x3000)
-               *stat |= FE_HAS_CARRIER;
-       if (lock & 0x0100)
-               *stat |= FE_HAS_VITERBI;
-       if (lock & 0x0010)
-               *stat |= FE_HAS_SYNC;
-       if (lock & 0x0008)
-               *stat |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
-       return 0;
-}
-
-static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       *unc = dib7000m_read_word(state, 534);
-       return 0;
-}
-
-static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       u16 val = dib7000m_read_word(state, 390);
-       *strength = 65535 - val;
-       return 0;
-}
-
-static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-       *snr = 0x0000;
-       return 0;
-}
-
-static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void dib7000m_release(struct dvb_frontend *demod)
-{
-       struct dib7000m_state *st = demod->demodulator_priv;
-       dibx000_exit_i2c_master(&st->i2c_master);
-       kfree(st);
-}
-
-struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
-{
-       struct dib7000m_state *st = demod->demodulator_priv;
-       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
-}
-EXPORT_SYMBOL(dib7000m_get_i2c_master);
-
-int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
-       val |= (onoff & 0x1) << 4;
-       dprintk("PID filter enabled %d", onoff);
-       return dib7000m_write_word(state, 294 + state->reg_offs, val);
-}
-EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
-
-int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       struct dib7000m_state *state = fe->demodulator_priv;
-       dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
-       return dib7000m_write_word(state, 300 + state->reg_offs + id,
-                       onoff ? (1 << 13) | pid : 0);
-}
-EXPORT_SYMBOL(dib7000m_pid_filter);
-
-#if 0
-/* used with some prototype boards */
-int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
-               u8 default_addr, struct dib7000m_config cfg[])
-{
-       struct dib7000m_state st = { .i2c_adap = i2c };
-       int k = 0;
-       u8 new_addr = 0;
-
-       for (k = no_of_demods-1; k >= 0; k--) {
-               st.cfg = cfg[k];
-
-               /* designated i2c address */
-               new_addr          = (0x40 + k) << 1;
-               st.i2c_addr = new_addr;
-               if (dib7000m_identify(&st) != 0) {
-                       st.i2c_addr = default_addr;
-                       if (dib7000m_identify(&st) != 0) {
-                               dprintk("DiB7000M #%d: not identified", k);
-                               return -EIO;
-                       }
-               }
-
-               /* start diversity to pull_down div_str - just for i2c-enumeration */
-               dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
-
-               dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
-
-               /* set new i2c address and force divstart */
-               dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
-
-               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               st.cfg = cfg[k];
-               st.i2c_addr = (0x40 + k) << 1;
-
-               // unforce divstr
-               dib7000m_write_word(&st,1794, st.i2c_addr << 2);
-
-               /* deactivate div - it was just for i2c-enumeration */
-               dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(dib7000m_i2c_enumeration);
-#endif
-
-static struct dvb_frontend_ops dib7000m_ops;
-struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
-{
-       struct dvb_frontend *demod;
-       struct dib7000m_state *st;
-       st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-
-       memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
-       st->i2c_adap = i2c_adap;
-       st->i2c_addr = i2c_addr;
-
-       demod                   = &st->demod;
-       demod->demodulator_priv = st;
-       memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
-       mutex_init(&st->i2c_buffer_lock);
-
-       st->timf_default = cfg->bw->timf;
-
-       if (dib7000m_identify(st) != 0)
-               goto error;
-
-       if (st->revision == 0x4000)
-               dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
-       else
-               dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
-
-       dib7000m_demod_reset(st);
-
-       return demod;
-
-error:
-       kfree(st);
-       return NULL;
-}
-EXPORT_SYMBOL(dib7000m_attach);
-
-static struct dvb_frontend_ops dib7000m_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "DiBcom 7000MA/MB/PA/PB/MC",
-               .frequency_min      = 44250000,
-               .frequency_max      = 867250000,
-               .frequency_stepsize = 62500,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release              = dib7000m_release,
-
-       .init                 = dib7000m_wakeup,
-       .sleep                = dib7000m_sleep,
-
-       .set_frontend         = dib7000m_set_frontend,
-       .get_tune_settings    = dib7000m_fe_get_tune_settings,
-       .get_frontend         = dib7000m_get_frontend,
-
-       .read_status          = dib7000m_read_status,
-       .read_ber             = dib7000m_read_ber,
-       .read_signal_strength = dib7000m_read_signal_strength,
-       .read_snr             = dib7000m_read_snr,
-       .read_ucblocks        = dib7000m_read_unc_blocks,
-};
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h
deleted file mode 100644 (file)
index 81fcf22..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef DIB7000M_H
-#define DIB7000M_H
-
-#include "dibx000_common.h"
-
-struct dib7000m_config {
-       u8 dvbt_mode;
-       u8 output_mpeg2_in_188_bytes;
-       u8 hostbus_diversity;
-       u8 tuner_is_baseband;
-       u8 mobile_mode;
-       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
-
-       u8 agc_config_count;
-       struct dibx000_agc_config *agc;
-
-       struct dibx000_bandwidth_config *bw;
-
-#define DIB7000M_GPIO_DEFAULT_DIRECTIONS 0xffff
-       u16 gpio_dir;
-#define DIB7000M_GPIO_DEFAULT_VALUES     0x0000
-       u16 gpio_val;
-#define DIB7000M_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
-#define DIB7000M_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
-#define DIB7000M_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
-#define DIB7000M_GPIO_PWM_POS3(v)         (v & 0xf)
-#define DIB7000M_GPIO_DEFAULT_PWM_POS    0xffff
-       u16 gpio_pwm_pos;
-
-       u16 pwm_freq_div;
-
-       u8 quartz_direct;
-
-       u8 input_clk_is_div_2;
-
-       int (*agc_control) (struct dvb_frontend *, u8 before);
-};
-
-#define DEFAULT_DIB7000M_I2C_ADDRESS 18
-
-#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
-                                    defined(MODULE))
-extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
-                                           u8 i2c_addr,
-                                           struct dib7000m_config *cfg);
-extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
-                                                  enum dibx000_i2c_interface,
-                                                  int);
-extern int dib7000m_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
-#else
-static inline
-struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
-                                    u8 i2c_addr, struct dib7000m_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline
-struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
-                                           enum dibx000_i2c_interface intf,
-                                           int gating)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id,
-                                               u16 pid, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe,
-                                               uint8_t onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-#endif
-
-/* TODO
-extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
-extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod);
-extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff);
-extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod);
-*/
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
deleted file mode 100644 (file)
index 3e1eefa..0000000
+++ /dev/null
@@ -1,2457 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
- *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_math.h"
-#include "dvb_frontend.h"
-
-#include "dib7000p.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-static int buggy_sfn_workaround;
-module_param(buggy_sfn_workaround, int, 0644);
-MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
-
-struct i2c_device {
-       struct i2c_adapter *i2c_adap;
-       u8 i2c_addr;
-};
-
-struct dib7000p_state {
-       struct dvb_frontend demod;
-       struct dib7000p_config cfg;
-
-       u8 i2c_addr;
-       struct i2c_adapter *i2c_adap;
-
-       struct dibx000_i2c_master i2c_master;
-
-       u16 wbd_ref;
-
-       u8 current_band;
-       u32 current_bandwidth;
-       struct dibx000_agc_config *current_agc;
-       u32 timf;
-
-       u8 div_force_off:1;
-       u8 div_state:1;
-       u16 div_sync_wait;
-
-       u8 agc_state;
-
-       u16 gpio_dir;
-       u16 gpio_val;
-
-       u8 sfn_workaround_active:1;
-
-#define SOC7090 0x7090
-       u16 version;
-
-       u16 tuner_enable;
-       struct i2c_adapter dib7090_tuner_adap;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[4];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-
-       u8 input_mode_mpeg;
-};
-
-enum dib7000p_power_mode {
-       DIB7000P_POWER_ALL = 0,
-       DIB7000P_POWER_ANALOG_ADC,
-       DIB7000P_POWER_INTERFACE_ONLY,
-};
-
-/* dib7090 specific fonctions */
-static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
-static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
-static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
-static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
-
-static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = reg >> 8;
-       state->i2c_write_buffer[1] = reg & 0xff;
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 2;
-       state->msg[1].addr = state->i2c_addr >> 1;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = state->i2c_read_buffer;
-       state->msg[1].len = 2;
-
-       if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
-               dprintk("i2c read error on %d", reg);
-
-       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       state->i2c_write_buffer[1] = reg & 0xff;
-       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-       state->i2c_write_buffer[3] = val & 0xff;
-
-       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 4;
-
-       ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
-                       -EREMOTEIO : 0);
-       mutex_unlock(&state->i2c_buffer_lock);
-       return ret;
-}
-
-static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
-{
-       u16 l = 0, r, *n;
-       n = buf;
-       l = *n++;
-       while (l) {
-               r = *n++;
-
-               do {
-                       dib7000p_write_word(state, r, *n++);
-                       r++;
-               } while (--l);
-               l = *n++;
-       }
-}
-
-static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
-{
-       int ret = 0;
-       u16 outreg, fifo_threshold, smo_mode;
-
-       outreg = 0;
-       fifo_threshold = 1792;
-       smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
-
-       dprintk("setting output mode for demod %p to %d", &state->demod, mode);
-
-       switch (mode) {
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-               outreg = (1 << 10);     /* 0x0400 */
-               break;
-       case OUTMODE_MPEG2_PAR_CONT_CLK:
-               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
-               break;
-       case OUTMODE_MPEG2_SERIAL:
-               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0480 */
-               break;
-       case OUTMODE_DIVERSITY:
-               if (state->cfg.hostbus_diversity)
-                       outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
-               else
-                       outreg = (1 << 11);
-               break;
-       case OUTMODE_MPEG2_FIFO:
-               smo_mode |= (3 << 1);
-               fifo_threshold = 512;
-               outreg = (1 << 10) | (5 << 6);
-               break;
-       case OUTMODE_ANALOG_ADC:
-               outreg = (1 << 10) | (3 << 6);
-               break;
-       case OUTMODE_HIGH_Z:
-               outreg = 0;
-               break;
-       default:
-               dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
-               break;
-       }
-
-       if (state->cfg.output_mpeg2_in_188_bytes)
-               smo_mode |= (1 << 5);
-
-       ret |= dib7000p_write_word(state, 235, smo_mode);
-       ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
-       if (state->version != SOC7090)
-               ret |= dib7000p_write_word(state, 1286, outreg);        /* P_Div_active */
-
-       return ret;
-}
-
-static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-
-       if (state->div_force_off) {
-               dprintk("diversity combination deactivated - forced by COFDM parameters");
-               onoff = 0;
-               dib7000p_write_word(state, 207, 0);
-       } else
-               dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
-
-       state->div_state = (u8) onoff;
-
-       if (onoff) {
-               dib7000p_write_word(state, 204, 6);
-               dib7000p_write_word(state, 205, 16);
-               /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-       } else {
-               dib7000p_write_word(state, 204, 1);
-               dib7000p_write_word(state, 205, 0);
-       }
-
-       return 0;
-}
-
-static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
-{
-       /* by default everything is powered off */
-       u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
-
-       /* now, depending on the requested mode, we power on */
-       switch (mode) {
-               /* power up everything in the demod */
-       case DIB7000P_POWER_ALL:
-               reg_774 = 0x0000;
-               reg_775 = 0x0000;
-               reg_776 = 0x0;
-               reg_899 = 0x0;
-               if (state->version == SOC7090)
-                       reg_1280 &= 0x001f;
-               else
-                       reg_1280 &= 0x01ff;
-               break;
-
-       case DIB7000P_POWER_ANALOG_ADC:
-               /* dem, cfg, iqc, sad, agc */
-               reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
-               /* nud */
-               reg_776 &= ~((1 << 0));
-               /* Dout */
-               if (state->version != SOC7090)
-                       reg_1280 &= ~((1 << 11));
-               reg_1280 &= ~(1 << 6);
-               /* fall through wanted to enable the interfaces */
-
-               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
-       case DIB7000P_POWER_INTERFACE_ONLY:     /* TODO power up either SDIO or I2C */
-               if (state->version == SOC7090)
-                       reg_1280 &= ~((1 << 7) | (1 << 5));
-               else
-                       reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
-               break;
-
-/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
-       }
-
-       dib7000p_write_word(state, 774, reg_774);
-       dib7000p_write_word(state, 775, reg_775);
-       dib7000p_write_word(state, 776, reg_776);
-       dib7000p_write_word(state, 1280, reg_1280);
-       if (state->version != SOC7090)
-               dib7000p_write_word(state, 899, reg_899);
-
-       return 0;
-}
-
-static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
-{
-       u16 reg_908 = 0, reg_909 = 0;
-       u16 reg;
-
-       if (state->version != SOC7090) {
-               reg_908 = dib7000p_read_word(state, 908);
-               reg_909 = dib7000p_read_word(state, 909);
-       }
-
-       switch (no) {
-       case DIBX000_SLOW_ADC_ON:
-               if (state->version == SOC7090) {
-                       reg = dib7000p_read_word(state, 1925);
-
-                       dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2));    /* en_slowAdc = 1 & reset_sladc = 1 */
-
-                       reg = dib7000p_read_word(state, 1925);  /* read acces to make it works... strange ... */
-                       msleep(200);
-                       dib7000p_write_word(state, 1925, reg & ~(1 << 4));      /* en_slowAdc = 1 & reset_sladc = 0 */
-
-                       reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
-                       dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524);      /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
-               } else {
-                       reg_909 |= (1 << 1) | (1 << 0);
-                       dib7000p_write_word(state, 909, reg_909);
-                       reg_909 &= ~(1 << 1);
-               }
-               break;
-
-       case DIBX000_SLOW_ADC_OFF:
-               if (state->version == SOC7090) {
-                       reg = dib7000p_read_word(state, 1925);
-                       dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
-               } else
-                       reg_909 |= (1 << 1) | (1 << 0);
-               break;
-
-       case DIBX000_ADC_ON:
-               reg_908 &= 0x0fff;
-               reg_909 &= 0x0003;
-               break;
-
-       case DIBX000_ADC_OFF:
-               reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
-               reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
-               break;
-
-       case DIBX000_VBG_ENABLE:
-               reg_908 &= ~(1 << 15);
-               break;
-
-       case DIBX000_VBG_DISABLE:
-               reg_908 |= (1 << 15);
-               break;
-
-       default:
-               break;
-       }
-
-//     dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
-
-       reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
-       reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
-
-       if (state->version != SOC7090) {
-               dib7000p_write_word(state, 908, reg_908);
-               dib7000p_write_word(state, 909, reg_909);
-       }
-}
-
-static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
-{
-       u32 timf;
-
-       // store the current bandwidth for later use
-       state->current_bandwidth = bw;
-
-       if (state->timf == 0) {
-               dprintk("using default timf");
-               timf = state->cfg.bw->timf;
-       } else {
-               dprintk("using updated timf");
-               timf = state->timf;
-       }
-
-       timf = timf * (bw / 50) / 160;
-
-       dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
-       dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
-
-       return 0;
-}
-
-static int dib7000p_sad_calib(struct dib7000p_state *state)
-{
-/* internal */
-       dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
-
-       if (state->version == SOC7090)
-               dib7000p_write_word(state, 74, 2048);
-       else
-               dib7000p_write_word(state, 74, 776);
-
-       /* do the calibration */
-       dib7000p_write_word(state, 73, (1 << 0));
-       dib7000p_write_word(state, 73, (0 << 0));
-
-       msleep(1);
-
-       return 0;
-}
-
-int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-       if (value > 4095)
-               value = 4095;
-       state->wbd_ref = value;
-       return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
-}
-EXPORT_SYMBOL(dib7000p_set_wbd_ref);
-
-int dib7000p_get_agc_values(struct dvb_frontend *fe,
-               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-
-       if (agc_global != NULL)
-               *agc_global = dib7000p_read_word(state, 394);
-       if (agc1 != NULL)
-               *agc1 = dib7000p_read_word(state, 392);
-       if (agc2 != NULL)
-               *agc2 = dib7000p_read_word(state, 393);
-       if (wbd != NULL)
-               *wbd = dib7000p_read_word(state, 397);
-
-       return 0;
-}
-EXPORT_SYMBOL(dib7000p_get_agc_values);
-
-static void dib7000p_reset_pll(struct dib7000p_state *state)
-{
-       struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
-       u16 clk_cfg0;
-
-       if (state->version == SOC7090) {
-               dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
-
-               while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
-                       ;
-
-               dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
-       } else {
-               /* force PLL bypass */
-               clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
-                       (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
-
-               dib7000p_write_word(state, 900, clk_cfg0);
-
-               /* P_pll_cfg */
-               dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
-               clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
-               dib7000p_write_word(state, 900, clk_cfg0);
-       }
-
-       dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
-       dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
-       dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
-       dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
-
-       dib7000p_write_word(state, 72, bw->sad_cfg);
-}
-
-static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
-{
-       u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
-       internal |= (u32) dib7000p_read_word(state, 19);
-       internal /= 1000;
-
-       return internal;
-}
-
-int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
-       u8 loopdiv, prediv;
-       u32 internal, xtal;
-
-       /* get back old values */
-       prediv = reg_1856 & 0x3f;
-       loopdiv = (reg_1856 >> 6) & 0x3f;
-
-       if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
-               dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
-               reg_1856 &= 0xf000;
-               reg_1857 = dib7000p_read_word(state, 1857);
-               dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
-
-               dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
-
-               /* write new system clk into P_sec_len */
-               internal = dib7000p_get_internal_freq(state);
-               xtal = (internal / loopdiv) * prediv;
-               internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio;      /* new internal */
-               dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
-               dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
-
-               dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
-
-               while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
-                       dprintk("Waiting for PLL to lock");
-
-               return 0;
-       }
-       return -EIO;
-}
-EXPORT_SYMBOL(dib7000p_update_pll);
-
-static int dib7000p_reset_gpio(struct dib7000p_state *st)
-{
-       /* reset the GPIOs */
-       dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
-
-       dib7000p_write_word(st, 1029, st->gpio_dir);
-       dib7000p_write_word(st, 1030, st->gpio_val);
-
-       /* TODO 1031 is P_gpio_od */
-
-       dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
-
-       dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
-       return 0;
-}
-
-static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
-{
-       st->gpio_dir = dib7000p_read_word(st, 1029);
-       st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
-       st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
-       dib7000p_write_word(st, 1029, st->gpio_dir);
-
-       st->gpio_val = dib7000p_read_word(st, 1030);
-       st->gpio_val &= ~(1 << num);    /* reset the direction bit */
-       st->gpio_val |= (val & 0x01) << num;    /* set the new value */
-       dib7000p_write_word(st, 1030, st->gpio_val);
-
-       return 0;
-}
-
-int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-       return dib7000p_cfg_gpio(state, num, dir, val);
-}
-EXPORT_SYMBOL(dib7000p_set_gpio);
-
-static u16 dib7000p_defaults[] = {
-       // auto search configuration
-       3, 2,
-       0x0004,
-       (1<<3)|(1<<11)|(1<<12)|(1<<13),
-       0x0814,                 /* Equal Lock */
-
-       12, 6,
-       0x001b,
-       0x7740,
-       0x005b,
-       0x8d80,
-       0x01c9,
-       0xc380,
-       0x0000,
-       0x0080,
-       0x0000,
-       0x0090,
-       0x0001,
-       0xd4c0,
-
-       1, 26,
-       0x6680,
-
-       /* set ADC level to -16 */
-       11, 79,
-       (1 << 13) - 825 - 117,
-       (1 << 13) - 837 - 117,
-       (1 << 13) - 811 - 117,
-       (1 << 13) - 766 - 117,
-       (1 << 13) - 737 - 117,
-       (1 << 13) - 693 - 117,
-       (1 << 13) - 648 - 117,
-       (1 << 13) - 619 - 117,
-       (1 << 13) - 575 - 117,
-       (1 << 13) - 531 - 117,
-       (1 << 13) - 501 - 117,
-
-       1, 142,
-       0x0410,
-
-       /* disable power smoothing */
-       8, 145,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-
-       1, 154,
-       1 << 13,
-
-       1, 168,
-       0x0ccd,
-
-       1, 183,
-       0x200f,
-
-       1, 212,
-               0x169,
-
-       5, 187,
-       0x023d,
-       0x00a4,
-       0x00a4,
-       0x7ff0,
-       0x3ccc,
-
-       1, 198,
-       0x800,
-
-       1, 222,
-       0x0010,
-
-       1, 235,
-       0x0062,
-
-       0,
-};
-
-static int dib7000p_demod_reset(struct dib7000p_state *state)
-{
-       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
-
-       if (state->version == SOC7090)
-               dibx000_reset_i2c_master(&state->i2c_master);
-
-       dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
-
-       /* restart all parts */
-       dib7000p_write_word(state, 770, 0xffff);
-       dib7000p_write_word(state, 771, 0xffff);
-       dib7000p_write_word(state, 772, 0x001f);
-       dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
-
-       dib7000p_write_word(state, 770, 0);
-       dib7000p_write_word(state, 771, 0);
-       dib7000p_write_word(state, 772, 0);
-       dib7000p_write_word(state, 1280, 0);
-
-       if (state->version != SOC7090) {
-               dib7000p_write_word(state,  898, 0x0003);
-               dib7000p_write_word(state,  898, 0);
-       }
-
-       /* default */
-       dib7000p_reset_pll(state);
-
-       if (dib7000p_reset_gpio(state) != 0)
-               dprintk("GPIO reset was not successful.");
-
-       if (state->version == SOC7090) {
-               dib7000p_write_word(state, 899, 0);
-
-               /* impulse noise */
-               dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
-               dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
-               dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
-               dib7000p_write_word(state, 273, (0<<6) | 30);
-       }
-       if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
-               dprintk("OUTPUT_MODE could not be reset.");
-
-       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-       dib7000p_sad_calib(state);
-       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
-
-       /* unforce divstr regardless whether i2c enumeration was done or not */
-       dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
-
-       dib7000p_set_bandwidth(state, 8000);
-
-       if (state->version == SOC7090) {
-               dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
-       } else {
-               if (state->cfg.tuner_is_baseband)
-                       dib7000p_write_word(state, 36, 0x0755);
-               else
-                       dib7000p_write_word(state, 36, 0x1f55);
-       }
-
-       dib7000p_write_tab(state, dib7000p_defaults);
-       if (state->version != SOC7090) {
-               dib7000p_write_word(state, 901, 0x0006);
-               dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
-               dib7000p_write_word(state, 905, 0x2c8e);
-       }
-
-       dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
-
-       return 0;
-}
-
-static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
-{
-       u16 tmp = 0;
-       tmp = dib7000p_read_word(state, 903);
-       dib7000p_write_word(state, 903, (tmp | 0x1));
-       tmp = dib7000p_read_word(state, 900);
-       dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
-}
-
-static void dib7000p_restart_agc(struct dib7000p_state *state)
-{
-       // P_restart_iqc & P_restart_agc
-       dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
-       dib7000p_write_word(state, 770, 0x0000);
-}
-
-static int dib7000p_update_lna(struct dib7000p_state *state)
-{
-       u16 dyn_gain;
-
-       if (state->cfg.update_lna) {
-               dyn_gain = dib7000p_read_word(state, 394);
-               if (state->cfg.update_lna(&state->demod, dyn_gain)) {
-                       dib7000p_restart_agc(state);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
-{
-       struct dibx000_agc_config *agc = NULL;
-       int i;
-       if (state->current_band == band && state->current_agc != NULL)
-               return 0;
-       state->current_band = band;
-
-       for (i = 0; i < state->cfg.agc_config_count; i++)
-               if (state->cfg.agc[i].band_caps & band) {
-                       agc = &state->cfg.agc[i];
-                       break;
-               }
-
-       if (agc == NULL) {
-               dprintk("no valid AGC configuration found for band 0x%02x", band);
-               return -EINVAL;
-       }
-
-       state->current_agc = agc;
-
-       /* AGC */
-       dib7000p_write_word(state, 75, agc->setup);
-       dib7000p_write_word(state, 76, agc->inv_gain);
-       dib7000p_write_word(state, 77, agc->time_stabiliz);
-       dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
-
-       // Demod AGC loop configuration
-       dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
-       dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
-
-       /* AGC continued */
-       dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
-               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
-
-       if (state->wbd_ref != 0)
-               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
-       else
-               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
-
-       dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
-
-       dib7000p_write_word(state, 107, agc->agc1_max);
-       dib7000p_write_word(state, 108, agc->agc1_min);
-       dib7000p_write_word(state, 109, agc->agc2_max);
-       dib7000p_write_word(state, 110, agc->agc2_min);
-       dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
-       dib7000p_write_word(state, 112, agc->agc1_pt3);
-       dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
-       dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
-       dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
-       return 0;
-}
-
-static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
-{
-       u32 internal = dib7000p_get_internal_freq(state);
-       s32 unit_khz_dds_val = 67108864 / (internal);   /* 2**26 / Fsampling is the unit 1KHz offset */
-       u32 abs_offset_khz = ABS(offset_khz);
-       u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
-       u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
-
-       dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
-
-       if (offset_khz < 0)
-               unit_khz_dds_val *= -1;
-
-       /* IF tuner */
-       if (invert)
-               dds -= (abs_offset_khz * unit_khz_dds_val);     /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
-       else
-               dds += (abs_offset_khz * unit_khz_dds_val);
-
-       if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
-               dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
-               dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
-       }
-}
-
-static int dib7000p_agc_startup(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000p_state *state = demod->demodulator_priv;
-       int ret = -1;
-       u8 *agc_state = &state->agc_state;
-       u8 agc_split;
-       u16 reg;
-       u32 upd_demod_gain_period = 0x1000;
-
-       switch (state->agc_state) {
-       case 0:
-               dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
-               if (state->version == SOC7090) {
-                       reg = dib7000p_read_word(state, 0x79b) & 0xff00;
-                       dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF);      /* lsb */
-                       dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
-
-                       /* enable adc i & q */
-                       reg = dib7000p_read_word(state, 0x780);
-                       dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
-               } else {
-                       dib7000p_set_adc_state(state, DIBX000_ADC_ON);
-                       dib7000p_pll_clk_cfg(state);
-               }
-
-               if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
-                       return -1;
-
-               dib7000p_set_dds(state, 0);
-               ret = 7;
-               (*agc_state)++;
-               break;
-
-       case 1:
-               if (state->cfg.agc_control)
-                       state->cfg.agc_control(&state->demod, 1);
-
-               dib7000p_write_word(state, 78, 32768);
-               if (!state->current_agc->perform_agc_softsplit) {
-                       /* we are using the wbd - so slow AGC startup */
-                       /* force 0 split on WBD and restart AGC */
-                       dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
-                       (*agc_state)++;
-                       ret = 5;
-               } else {
-                       /* default AGC startup */
-                       (*agc_state) = 4;
-                       /* wait AGC rough lock time */
-                       ret = 7;
-               }
-
-               dib7000p_restart_agc(state);
-               break;
-
-       case 2:         /* fast split search path after 5sec */
-               dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4));   /* freeze AGC loop */
-               dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8));     /* fast split search 0.25kHz */
-               (*agc_state)++;
-               ret = 14;
-               break;
-
-       case 3:         /* split search ended */
-               agc_split = (u8) dib7000p_read_word(state, 396);        /* store the split value for the next time */
-               dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
-
-               dib7000p_write_word(state, 75, state->current_agc->setup);      /* std AGC loop */
-               dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split);        /* standard split search */
-
-               dib7000p_restart_agc(state);
-
-               dprintk("SPLIT %p: %hd", demod, agc_split);
-
-               (*agc_state)++;
-               ret = 5;
-               break;
-
-       case 4:         /* LNA startup */
-               ret = 7;
-
-               if (dib7000p_update_lna(state))
-                       ret = 5;
-               else
-                       (*agc_state)++;
-               break;
-
-       case 5:
-               if (state->cfg.agc_control)
-                       state->cfg.agc_control(&state->demod, 0);
-               (*agc_state)++;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-static void dib7000p_update_timf(struct dib7000p_state *state)
-{
-       u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
-       state->timf = timf * 160 / (state->current_bandwidth / 50);
-       dib7000p_write_word(state, 23, (u16) (timf >> 16));
-       dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
-       dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
-
-}
-
-u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       switch (op) {
-       case DEMOD_TIMF_SET:
-               state->timf = timf;
-               break;
-       case DEMOD_TIMF_UPDATE:
-               dib7000p_update_timf(state);
-               break;
-       case DEMOD_TIMF_GET:
-               break;
-       }
-       dib7000p_set_bandwidth(state, state->current_bandwidth);
-       return state->timf;
-}
-EXPORT_SYMBOL(dib7000p_ctrl_timf);
-
-static void dib7000p_set_channel(struct dib7000p_state *state,
-                                struct dtv_frontend_properties *ch, u8 seq)
-{
-       u16 value, est[4];
-
-       dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
-
-       /* nfft, guard, qam, alpha */
-       value = 0;
-       switch (ch->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               value |= (0 << 7);
-               break;
-       case TRANSMISSION_MODE_4K:
-               value |= (2 << 7);
-               break;
-       default:
-       case TRANSMISSION_MODE_8K:
-               value |= (1 << 7);
-               break;
-       }
-       switch (ch->guard_interval) {
-       case GUARD_INTERVAL_1_32:
-               value |= (0 << 5);
-               break;
-       case GUARD_INTERVAL_1_16:
-               value |= (1 << 5);
-               break;
-       case GUARD_INTERVAL_1_4:
-               value |= (3 << 5);
-               break;
-       default:
-       case GUARD_INTERVAL_1_8:
-               value |= (2 << 5);
-               break;
-       }
-       switch (ch->modulation) {
-       case QPSK:
-               value |= (0 << 3);
-               break;
-       case QAM_16:
-               value |= (1 << 3);
-               break;
-       default:
-       case QAM_64:
-               value |= (2 << 3);
-               break;
-       }
-       switch (HIERARCHY_1) {
-       case HIERARCHY_2:
-               value |= 2;
-               break;
-       case HIERARCHY_4:
-               value |= 4;
-               break;
-       default:
-       case HIERARCHY_1:
-               value |= 1;
-               break;
-       }
-       dib7000p_write_word(state, 0, value);
-       dib7000p_write_word(state, 5, (seq << 4) | 1);  /* do not force tps, search list 0 */
-
-       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
-       value = 0;
-       if (1 != 0)
-               value |= (1 << 6);
-       if (ch->hierarchy == 1)
-               value |= (1 << 4);
-       if (1 == 1)
-               value |= 1;
-       switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
-       case FEC_2_3:
-               value |= (2 << 1);
-               break;
-       case FEC_3_4:
-               value |= (3 << 1);
-               break;
-       case FEC_5_6:
-               value |= (5 << 1);
-               break;
-       case FEC_7_8:
-               value |= (7 << 1);
-               break;
-       default:
-       case FEC_1_2:
-               value |= (1 << 1);
-               break;
-       }
-       dib7000p_write_word(state, 208, value);
-
-       /* offset loop parameters */
-       dib7000p_write_word(state, 26, 0x6680);
-       dib7000p_write_word(state, 32, 0x0003);
-       dib7000p_write_word(state, 29, 0x1273);
-       dib7000p_write_word(state, 33, 0x0005);
-
-       /* P_dvsy_sync_wait */
-       switch (ch->transmission_mode) {
-       case TRANSMISSION_MODE_8K:
-               value = 256;
-               break;
-       case TRANSMISSION_MODE_4K:
-               value = 128;
-               break;
-       case TRANSMISSION_MODE_2K:
-       default:
-               value = 64;
-               break;
-       }
-       switch (ch->guard_interval) {
-       case GUARD_INTERVAL_1_16:
-               value *= 2;
-               break;
-       case GUARD_INTERVAL_1_8:
-               value *= 4;
-               break;
-       case GUARD_INTERVAL_1_4:
-               value *= 8;
-               break;
-       default:
-       case GUARD_INTERVAL_1_32:
-               value *= 1;
-               break;
-       }
-       if (state->cfg.diversity_delay == 0)
-               state->div_sync_wait = (value * 3) / 2 + 48;
-       else
-               state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
-
-       /* deactive the possibility of diversity reception if extended interleaver */
-       state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K;
-       dib7000p_set_diversity_in(&state->demod, state->div_state);
-
-       /* channel estimation fine configuration */
-       switch (ch->modulation) {
-       case QAM_64:
-               est[0] = 0x0148;        /* P_adp_regul_cnt 0.04 */
-               est[1] = 0xfff0;        /* P_adp_noise_cnt -0.002 */
-               est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
-               est[3] = 0xfff8;        /* P_adp_noise_ext -0.001 */
-               break;
-       case QAM_16:
-               est[0] = 0x023d;        /* P_adp_regul_cnt 0.07 */
-               est[1] = 0xffdf;        /* P_adp_noise_cnt -0.004 */
-               est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
-               est[3] = 0xfff0;        /* P_adp_noise_ext -0.002 */
-               break;
-       default:
-               est[0] = 0x099a;        /* P_adp_regul_cnt 0.3 */
-               est[1] = 0xffae;        /* P_adp_noise_cnt -0.01 */
-               est[2] = 0x0333;        /* P_adp_regul_ext 0.1 */
-               est[3] = 0xfff8;        /* P_adp_noise_ext -0.002 */
-               break;
-       }
-       for (value = 0; value < 4; value++)
-               dib7000p_write_word(state, 187 + value, est[value]);
-}
-
-static int dib7000p_autosearch_start(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000p_state *state = demod->demodulator_priv;
-       struct dtv_frontend_properties schan;
-       u32 value, factor;
-       u32 internal = dib7000p_get_internal_freq(state);
-
-       schan = *ch;
-       schan.modulation = QAM_64;
-       schan.guard_interval = GUARD_INTERVAL_1_32;
-       schan.transmission_mode = TRANSMISSION_MODE_8K;
-       schan.code_rate_HP = FEC_2_3;
-       schan.code_rate_LP = FEC_3_4;
-       schan.hierarchy = 0;
-
-       dib7000p_set_channel(state, &schan, 7);
-
-       factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
-       if (factor >= 5000) {
-               if (state->version == SOC7090)
-                       factor = 2;
-               else
-                       factor = 1;
-       } else
-               factor = 6;
-
-       value = 30 * internal * factor;
-       dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
-       dib7000p_write_word(state, 7, (u16) (value & 0xffff));
-       value = 100 * internal * factor;
-       dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
-       dib7000p_write_word(state, 9, (u16) (value & 0xffff));
-       value = 500 * internal * factor;
-       dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
-       dib7000p_write_word(state, 11, (u16) (value & 0xffff));
-
-       value = dib7000p_read_word(state, 0);
-       dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
-       dib7000p_read_word(state, 1284);
-       dib7000p_write_word(state, 0, (u16) value);
-
-       return 0;
-}
-
-static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-       u16 irq_pending = dib7000p_read_word(state, 1284);
-
-       if (irq_pending & 0x1)
-               return 1;
-
-       if (irq_pending & 0x2)
-               return 2;
-
-       return 0;
-}
-
-static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
-{
-       static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
-       static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
-               24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
-               53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
-               82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
-               107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
-               128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
-               147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
-               166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
-               183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
-               199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
-               213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
-               225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
-               235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
-               244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
-               250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
-               254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-               255, 255, 255, 255, 255, 255
-       };
-
-       u32 xtal = state->cfg.bw->xtal_hz / 1000;
-       int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
-       int k;
-       int coef_re[8], coef_im[8];
-       int bw_khz = bw;
-       u32 pha;
-
-       dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
-
-       if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
-               return;
-
-       bw_khz /= 100;
-
-       dib7000p_write_word(state, 142, 0x0610);
-
-       for (k = 0; k < 8; k++) {
-               pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
-
-               if (pha == 0) {
-                       coef_re[k] = 256;
-                       coef_im[k] = 0;
-               } else if (pha < 256) {
-                       coef_re[k] = sine[256 - (pha & 0xff)];
-                       coef_im[k] = sine[pha & 0xff];
-               } else if (pha == 256) {
-                       coef_re[k] = 0;
-                       coef_im[k] = 256;
-               } else if (pha < 512) {
-                       coef_re[k] = -sine[pha & 0xff];
-                       coef_im[k] = sine[256 - (pha & 0xff)];
-               } else if (pha == 512) {
-                       coef_re[k] = -256;
-                       coef_im[k] = 0;
-               } else if (pha < 768) {
-                       coef_re[k] = -sine[256 - (pha & 0xff)];
-                       coef_im[k] = -sine[pha & 0xff];
-               } else if (pha == 768) {
-                       coef_re[k] = 0;
-                       coef_im[k] = -256;
-               } else {
-                       coef_re[k] = sine[pha & 0xff];
-                       coef_im[k] = -sine[256 - (pha & 0xff)];
-               }
-
-               coef_re[k] *= notch[k];
-               coef_re[k] += (1 << 14);
-               if (coef_re[k] >= (1 << 24))
-                       coef_re[k] = (1 << 24) - 1;
-               coef_re[k] /= (1 << 15);
-
-               coef_im[k] *= notch[k];
-               coef_im[k] += (1 << 14);
-               if (coef_im[k] >= (1 << 24))
-                       coef_im[k] = (1 << 24) - 1;
-               coef_im[k] /= (1 << 15);
-
-               dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
-
-               dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
-               dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
-               dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
-       }
-       dib7000p_write_word(state, 143, 0);
-}
-
-static int dib7000p_tune(struct dvb_frontend *demod)
-{
-       struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
-       struct dib7000p_state *state = demod->demodulator_priv;
-       u16 tmp = 0;
-
-       if (ch != NULL)
-               dib7000p_set_channel(state, ch, 0);
-       else
-               return -EINVAL;
-
-       // restart demod
-       dib7000p_write_word(state, 770, 0x4000);
-       dib7000p_write_word(state, 770, 0x0000);
-       msleep(45);
-
-       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
-       tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
-       if (state->sfn_workaround_active) {
-               dprintk("SFN workaround is active");
-               tmp |= (1 << 9);
-               dib7000p_write_word(state, 166, 0x4000);
-       } else {
-               dib7000p_write_word(state, 166, 0x0000);
-       }
-       dib7000p_write_word(state, 29, tmp);
-
-       // never achieved a lock with that bandwidth so far - wait for osc-freq to update
-       if (state->timf == 0)
-               msleep(200);
-
-       /* offset loop parameters */
-
-       /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
-       tmp = (6 << 8) | 0x80;
-       switch (ch->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               tmp |= (2 << 12);
-               break;
-       case TRANSMISSION_MODE_4K:
-               tmp |= (3 << 12);
-               break;
-       default:
-       case TRANSMISSION_MODE_8K:
-               tmp |= (4 << 12);
-               break;
-       }
-       dib7000p_write_word(state, 26, tmp);    /* timf_a(6xxx) */
-
-       /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
-       tmp = (0 << 4);
-       switch (ch->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               tmp |= 0x6;
-               break;
-       case TRANSMISSION_MODE_4K:
-               tmp |= 0x7;
-               break;
-       default:
-       case TRANSMISSION_MODE_8K:
-               tmp |= 0x8;
-               break;
-       }
-       dib7000p_write_word(state, 32, tmp);
-
-       /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
-       tmp = (0 << 4);
-       switch (ch->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               tmp |= 0x6;
-               break;
-       case TRANSMISSION_MODE_4K:
-               tmp |= 0x7;
-               break;
-       default:
-       case TRANSMISSION_MODE_8K:
-               tmp |= 0x8;
-               break;
-       }
-       dib7000p_write_word(state, 33, tmp);
-
-       tmp = dib7000p_read_word(state, 509);
-       if (!((tmp >> 6) & 0x1)) {
-               /* restart the fec */
-               tmp = dib7000p_read_word(state, 771);
-               dib7000p_write_word(state, 771, tmp | (1 << 1));
-               dib7000p_write_word(state, 771, tmp);
-               msleep(40);
-               tmp = dib7000p_read_word(state, 509);
-       }
-       // we achieved a lock - it's time to update the osc freq
-       if ((tmp >> 6) & 0x1) {
-               dib7000p_update_timf(state);
-               /* P_timf_alpha += 2 */
-               tmp = dib7000p_read_word(state, 26);
-               dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
-       }
-
-       if (state->cfg.spur_protect)
-               dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
-
-       dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
-       return 0;
-}
-
-static int dib7000p_wakeup(struct dvb_frontend *demod)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
-       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-       if (state->version == SOC7090)
-               dib7000p_sad_calib(state);
-       return 0;
-}
-
-static int dib7000p_sleep(struct dvb_frontend *demod)
-{
-       struct dib7000p_state *state = demod->demodulator_priv;
-       if (state->version == SOC7090)
-               return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
-       return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
-}
-
-static int dib7000p_identify(struct dib7000p_state *st)
-{
-       u16 value;
-       dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
-
-       if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
-               dprintk("wrong Vendor ID (read=0x%x)", value);
-               return -EREMOTEIO;
-       }
-
-       if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
-               dprintk("wrong Device ID (%x)", value);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int dib7000p_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 tps = dib7000p_read_word(state, 463);
-
-       fep->inversion = INVERSION_AUTO;
-
-       fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
-
-       switch ((tps >> 8) & 0x3) {
-       case 0:
-               fep->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               fep->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
-       }
-
-       switch (tps & 0x3) {
-       case 0:
-               fep->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               fep->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               fep->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               fep->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       switch ((tps >> 14) & 0x3) {
-       case 0:
-               fep->modulation = QPSK;
-               break;
-       case 1:
-               fep->modulation = QAM_16;
-               break;
-       case 2:
-       default:
-               fep->modulation = QAM_64;
-               break;
-       }
-
-       /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
-       /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
-
-       fep->hierarchy = HIERARCHY_NONE;
-       switch ((tps >> 5) & 0x7) {
-       case 1:
-               fep->code_rate_HP = FEC_1_2;
-               break;
-       case 2:
-               fep->code_rate_HP = FEC_2_3;
-               break;
-       case 3:
-               fep->code_rate_HP = FEC_3_4;
-               break;
-       case 5:
-               fep->code_rate_HP = FEC_5_6;
-               break;
-       case 7:
-       default:
-               fep->code_rate_HP = FEC_7_8;
-               break;
-
-       }
-
-       switch ((tps >> 2) & 0x7) {
-       case 1:
-               fep->code_rate_LP = FEC_1_2;
-               break;
-       case 2:
-               fep->code_rate_LP = FEC_2_3;
-               break;
-       case 3:
-               fep->code_rate_LP = FEC_3_4;
-               break;
-       case 5:
-               fep->code_rate_LP = FEC_5_6;
-               break;
-       case 7:
-       default:
-               fep->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       /* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
-
-       return 0;
-}
-
-static int dib7000p_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct dib7000p_state *state = fe->demodulator_priv;
-       int time, ret;
-
-       if (state->version == SOC7090)
-               dib7090_set_diversity_in(fe, 0);
-       else
-               dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
-
-       /* maybe the parameter has been changed */
-       state->sfn_workaround_active = buggy_sfn_workaround;
-
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* start up the AGC */
-       state->agc_state = 0;
-       do {
-               time = dib7000p_agc_startup(fe);
-               if (time != -1)
-                       msleep(time);
-       } while (time != -1);
-
-       if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
-               fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) {
-               int i = 800, found;
-
-               dib7000p_autosearch_start(fe);
-               do {
-                       msleep(1);
-                       found = dib7000p_autosearch_is_irq(fe);
-               } while (found == 0 && i--);
-
-               dprintk("autosearch returns: %d", found);
-               if (found == 0 || found == 1)
-                       return 0;
-
-               dib7000p_get_frontend(fe);
-       }
-
-       ret = dib7000p_tune(fe);
-
-       /* make this a config parameter */
-       if (state->version == SOC7090) {
-               dib7090_set_output_mode(fe, state->cfg.output_mode);
-               if (state->cfg.enMpegOutput == 0) {
-                       dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
-                       dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-               }
-       } else
-               dib7000p_set_output_mode(state, state->cfg.output_mode);
-
-       return ret;
-}
-
-static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 lock = dib7000p_read_word(state, 509);
-
-       *stat = 0;
-
-       if (lock & 0x8000)
-               *stat |= FE_HAS_SIGNAL;
-       if (lock & 0x3000)
-               *stat |= FE_HAS_CARRIER;
-       if (lock & 0x0100)
-               *stat |= FE_HAS_VITERBI;
-       if (lock & 0x0010)
-               *stat |= FE_HAS_SYNC;
-       if ((lock & 0x0038) == 0x38)
-               *stat |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
-       return 0;
-}
-
-static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       *unc = dib7000p_read_word(state, 506);
-       return 0;
-}
-
-static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 val = dib7000p_read_word(state, 394);
-       *strength = 65535 - val;
-       return 0;
-}
-
-static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 val;
-       s32 signal_mant, signal_exp, noise_mant, noise_exp;
-       u32 result = 0;
-
-       val = dib7000p_read_word(state, 479);
-       noise_mant = (val >> 4) & 0xff;
-       noise_exp = ((val & 0xf) << 2);
-       val = dib7000p_read_word(state, 480);
-       noise_exp += ((val >> 14) & 0x3);
-       if ((noise_exp & 0x20) != 0)
-               noise_exp -= 0x40;
-
-       signal_mant = (val >> 6) & 0xFF;
-       signal_exp = (val & 0x3F);
-       if ((signal_exp & 0x20) != 0)
-               signal_exp -= 0x40;
-
-       if (signal_mant != 0)
-               result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
-       else
-               result = intlog10(2) * 10 * signal_exp - 100;
-
-       if (noise_mant != 0)
-               result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
-       else
-               result -= intlog10(2) * 10 * noise_exp - 100;
-
-       *snr = result / ((1 << 24) / 10);
-       return 0;
-}
-
-static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void dib7000p_release(struct dvb_frontend *demod)
-{
-       struct dib7000p_state *st = demod->demodulator_priv;
-       dibx000_exit_i2c_master(&st->i2c_master);
-       i2c_del_adapter(&st->dib7090_tuner_adap);
-       kfree(st);
-}
-
-int dib7000pc_detection(struct i2c_adapter *i2c_adap)
-{
-       u8 *tx, *rx;
-       struct i2c_msg msg[2] = {
-               {.addr = 18 >> 1, .flags = 0, .len = 2},
-               {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
-       };
-       int ret = 0;
-
-       tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
-       if (!tx)
-               return -ENOMEM;
-       rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
-       if (!rx) {
-               ret = -ENOMEM;
-               goto rx_memory_error;
-       }
-
-       msg[0].buf = tx;
-       msg[1].buf = rx;
-
-       tx[0] = 0x03;
-       tx[1] = 0x00;
-
-       if (i2c_transfer(i2c_adap, msg, 2) == 2)
-               if (rx[0] == 0x01 && rx[1] == 0xb3) {
-                       dprintk("-D-  DiB7000PC detected");
-                       return 1;
-               }
-
-       msg[0].addr = msg[1].addr = 0x40;
-
-       if (i2c_transfer(i2c_adap, msg, 2) == 2)
-               if (rx[0] == 0x01 && rx[1] == 0xb3) {
-                       dprintk("-D-  DiB7000PC detected");
-                       return 1;
-               }
-
-       dprintk("-D-  DiB7000PC not detected");
-
-       kfree(rx);
-rx_memory_error:
-       kfree(tx);
-       return ret;
-}
-EXPORT_SYMBOL(dib7000pc_detection);
-
-struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
-{
-       struct dib7000p_state *st = demod->demodulator_priv;
-       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
-}
-EXPORT_SYMBOL(dib7000p_get_i2c_master);
-
-int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 val = dib7000p_read_word(state, 235) & 0xffef;
-       val |= (onoff & 0x1) << 4;
-       dprintk("PID filter enabled %d", onoff);
-       return dib7000p_write_word(state, 235, val);
-}
-EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
-
-int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
-       return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
-}
-EXPORT_SYMBOL(dib7000p_pid_filter);
-
-int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
-{
-       struct dib7000p_state *dpst;
-       int k = 0;
-       u8 new_addr = 0;
-
-       dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
-       if (!dpst)
-               return -ENOMEM;
-
-       dpst->i2c_adap = i2c;
-       mutex_init(&dpst->i2c_buffer_lock);
-
-       for (k = no_of_demods - 1; k >= 0; k--) {
-               dpst->cfg = cfg[k];
-
-               /* designated i2c address */
-               if (cfg[k].default_i2c_addr != 0)
-                       new_addr = cfg[k].default_i2c_addr + (k << 1);
-               else
-                       new_addr = (0x40 + k) << 1;
-               dpst->i2c_addr = new_addr;
-               dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
-               if (dib7000p_identify(dpst) != 0) {
-                       dpst->i2c_addr = default_addr;
-                       dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
-                       if (dib7000p_identify(dpst) != 0) {
-                               dprintk("DiB7000P #%d: not identified\n", k);
-                               kfree(dpst);
-                               return -EIO;
-                       }
-               }
-
-               /* start diversity to pull_down div_str - just for i2c-enumeration */
-               dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
-
-               /* set new i2c address and force divstart */
-               dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
-
-               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               dpst->cfg = cfg[k];
-               if (cfg[k].default_i2c_addr != 0)
-                       dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
-               else
-                       dpst->i2c_addr = (0x40 + k) << 1;
-
-               // unforce divstr
-               dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
-
-               /* deactivate div - it was just for i2c-enumeration */
-               dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
-       }
-
-       kfree(dpst);
-       return 0;
-}
-EXPORT_SYMBOL(dib7000p_i2c_enumeration);
-
-static const s32 lut_1000ln_mant[] = {
-       6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
-};
-
-static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u32 tmp_val = 0, exp = 0, mant = 0;
-       s32 pow_i;
-       u16 buf[2];
-       u8 ix = 0;
-
-       buf[0] = dib7000p_read_word(state, 0x184);
-       buf[1] = dib7000p_read_word(state, 0x185);
-       pow_i = (buf[0] << 16) | buf[1];
-       dprintk("raw pow_i = %d", pow_i);
-
-       tmp_val = pow_i;
-       while (tmp_val >>= 1)
-               exp++;
-
-       mant = (pow_i * 1000 / (1 << exp));
-       dprintk(" mant = %d exp = %d", mant / 1000, exp);
-
-       ix = (u8) ((mant - 1000) / 100);        /* index of the LUT */
-       dprintk(" ix = %d", ix);
-
-       pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
-       pow_i = (pow_i << 8) / 1000;
-       dprintk(" pow_i = %d", pow_i);
-
-       return pow_i;
-}
-
-static int map_addr_to_serpar_number(struct i2c_msg *msg)
-{
-       if ((msg->buf[0] <= 15))
-               msg->buf[0] -= 1;
-       else if (msg->buf[0] == 17)
-               msg->buf[0] = 15;
-       else if (msg->buf[0] == 16)
-               msg->buf[0] = 17;
-       else if (msg->buf[0] == 19)
-               msg->buf[0] = 16;
-       else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
-               msg->buf[0] -= 3;
-       else if (msg->buf[0] == 28)
-               msg->buf[0] = 23;
-       else
-               return -EINVAL;
-       return 0;
-}
-
-static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
-       u8 n_overflow = 1;
-       u16 i = 1000;
-       u16 serpar_num = msg[0].buf[0];
-
-       while (n_overflow == 1 && i) {
-               n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
-               i--;
-               if (i == 0)
-                       dprintk("Tuner ITF: write busy (overflow)");
-       }
-       dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
-       dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
-
-       return num;
-}
-
-static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
-       u8 n_overflow = 1, n_empty = 1;
-       u16 i = 1000;
-       u16 serpar_num = msg[0].buf[0];
-       u16 read_word;
-
-       while (n_overflow == 1 && i) {
-               n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
-               i--;
-               if (i == 0)
-                       dprintk("TunerITF: read busy (overflow)");
-       }
-       dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
-
-       i = 1000;
-       while (n_empty == 1 && i) {
-               n_empty = dib7000p_read_word(state, 1984) & 0x1;
-               i--;
-               if (i == 0)
-                       dprintk("TunerITF: read busy (empty)");
-       }
-       read_word = dib7000p_read_word(state, 1987);
-       msg[1].buf[0] = (read_word >> 8) & 0xff;
-       msg[1].buf[1] = (read_word) & 0xff;
-
-       return num;
-}
-
-static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       if (map_addr_to_serpar_number(&msg[0]) == 0) {  /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
-               if (num == 1) { /* write */
-                       return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
-               } else {        /* read */
-                       return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
-               }
-       }
-       return num;
-}
-
-static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num, u16 apb_address)
-{
-       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
-       u16 word;
-
-       if (num == 1) {         /* write */
-               dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
-       } else {
-               word = dib7000p_read_word(state, apb_address);
-               msg[1].buf[0] = (word >> 8) & 0xff;
-               msg[1].buf[1] = (word) & 0xff;
-       }
-
-       return num;
-}
-
-static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
-
-       u16 apb_address = 0, word;
-       int i = 0;
-       switch (msg[0].buf[0]) {
-       case 0x12:
-               apb_address = 1920;
-               break;
-       case 0x14:
-               apb_address = 1921;
-               break;
-       case 0x24:
-               apb_address = 1922;
-               break;
-       case 0x1a:
-               apb_address = 1923;
-               break;
-       case 0x22:
-               apb_address = 1924;
-               break;
-       case 0x33:
-               apb_address = 1926;
-               break;
-       case 0x34:
-               apb_address = 1927;
-               break;
-       case 0x35:
-               apb_address = 1928;
-               break;
-       case 0x36:
-               apb_address = 1929;
-               break;
-       case 0x37:
-               apb_address = 1930;
-               break;
-       case 0x38:
-               apb_address = 1931;
-               break;
-       case 0x39:
-               apb_address = 1932;
-               break;
-       case 0x2a:
-               apb_address = 1935;
-               break;
-       case 0x2b:
-               apb_address = 1936;
-               break;
-       case 0x2c:
-               apb_address = 1937;
-               break;
-       case 0x2d:
-               apb_address = 1938;
-               break;
-       case 0x2e:
-               apb_address = 1939;
-               break;
-       case 0x2f:
-               apb_address = 1940;
-               break;
-       case 0x30:
-               apb_address = 1941;
-               break;
-       case 0x31:
-               apb_address = 1942;
-               break;
-       case 0x32:
-               apb_address = 1943;
-               break;
-       case 0x3e:
-               apb_address = 1944;
-               break;
-       case 0x3f:
-               apb_address = 1945;
-               break;
-       case 0x40:
-               apb_address = 1948;
-               break;
-       case 0x25:
-               apb_address = 914;
-               break;
-       case 0x26:
-               apb_address = 915;
-               break;
-       case 0x27:
-               apb_address = 917;
-               break;
-       case 0x28:
-               apb_address = 916;
-               break;
-       case 0x1d:
-               i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
-               word = dib7000p_read_word(state, 384 + i);
-               msg[1].buf[0] = (word >> 8) & 0xff;
-               msg[1].buf[1] = (word) & 0xff;
-               return num;
-       case 0x1f:
-               if (num == 1) { /* write */
-                       word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
-                       word &= 0x3;
-                       word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
-                       dib7000p_write_word(state, 72, word);   /* Set the proper input */
-                       return num;
-               }
-       }
-
-       if (apb_address != 0)   /* R/W acces via APB */
-               return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
-       else                    /* R/W access via SERPAR  */
-               return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
-
-       return 0;
-}
-
-static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dib7090_tuner_xfer_algo = {
-       .master_xfer = dib7090_tuner_xfer,
-       .functionality = dib7000p_i2c_func,
-};
-
-struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
-{
-       struct dib7000p_state *st = fe->demodulator_priv;
-       return &st->dib7090_tuner_adap;
-}
-EXPORT_SYMBOL(dib7090_get_i2c_tuner);
-
-static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
-{
-       u16 reg;
-
-       /* drive host bus 2, 3, 4 */
-       reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive << 12) | (drive << 6) | drive;
-       dib7000p_write_word(state, 1798, reg);
-
-       /* drive host bus 5,6 */
-       reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
-       reg |= (drive << 8) | (drive << 2);
-       dib7000p_write_word(state, 1799, reg);
-
-       /* drive host bus 7, 8, 9 */
-       reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive << 12) | (drive << 6) | drive;
-       dib7000p_write_word(state, 1800, reg);
-
-       /* drive host bus 10, 11 */
-       reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
-       reg |= (drive << 8) | (drive << 2);
-       dib7000p_write_word(state, 1801, reg);
-
-       /* drive host bus 12, 13, 14 */
-       reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive << 12) | (drive << 6) | drive;
-       dib7000p_write_word(state, 1802, reg);
-
-       return 0;
-}
-
-static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
-{
-       u32 quantif = 3;
-       u32 nom = (insertExtSynchro * P_Kin + syncSize);
-       u32 denom = P_Kout;
-       u32 syncFreq = ((nom << quantif) / denom);
-
-       if ((syncFreq & ((1 << quantif) - 1)) != 0)
-               syncFreq = (syncFreq >> quantif) + 1;
-       else
-               syncFreq = (syncFreq >> quantif);
-
-       if (syncFreq != 0)
-               syncFreq = syncFreq - 1;
-
-       return syncFreq;
-}
-
-static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
-{
-       dprintk("Configure DibStream Tx");
-
-       dib7000p_write_word(state, 1615, 1);
-       dib7000p_write_word(state, 1603, P_Kin);
-       dib7000p_write_word(state, 1605, P_Kout);
-       dib7000p_write_word(state, 1606, insertExtSynchro);
-       dib7000p_write_word(state, 1608, synchroMode);
-       dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
-       dib7000p_write_word(state, 1610, syncWord & 0xffff);
-       dib7000p_write_word(state, 1612, syncSize);
-       dib7000p_write_word(state, 1615, 0);
-
-       return 0;
-}
-
-static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
-               u32 dataOutRate)
-{
-       u32 syncFreq;
-
-       dprintk("Configure DibStream Rx");
-       if ((P_Kin != 0) && (P_Kout != 0)) {
-               syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
-               dib7000p_write_word(state, 1542, syncFreq);
-       }
-       dib7000p_write_word(state, 1554, 1);
-       dib7000p_write_word(state, 1536, P_Kin);
-       dib7000p_write_word(state, 1537, P_Kout);
-       dib7000p_write_word(state, 1539, synchroMode);
-       dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
-       dib7000p_write_word(state, 1541, syncWord & 0xffff);
-       dib7000p_write_word(state, 1543, syncSize);
-       dib7000p_write_word(state, 1544, dataOutRate);
-       dib7000p_write_word(state, 1554, 0);
-
-       return 0;
-}
-
-static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
-{
-       u16 reg_1287 = dib7000p_read_word(state, 1287);
-
-       switch (onoff) {
-       case 1:
-                       reg_1287 &= ~(1<<7);
-                       break;
-       case 0:
-                       reg_1287 |= (1<<7);
-                       break;
-       }
-
-       dib7000p_write_word(state, 1287, reg_1287);
-}
-
-static void dib7090_configMpegMux(struct dib7000p_state *state,
-               u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
-{
-       dprintk("Enable Mpeg mux");
-
-       dib7090_enMpegMux(state, 0);
-
-       /* If the input mode is MPEG do not divide the serial clock */
-       if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
-               enSerialClkDiv2 = 0;
-
-       dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
-                       | ((enSerialMode & 0x1) << 1)
-                       | (enSerialClkDiv2 & 0x1));
-
-       dib7090_enMpegMux(state, 1);
-}
-
-static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
-{
-       u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
-
-       switch (mode) {
-       case MPEG_ON_DIBTX:
-                       dprintk("SET MPEG ON DIBSTREAM TX");
-                       dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
-                       reg_1288 |= (1<<9);
-                       break;
-       case DIV_ON_DIBTX:
-                       dprintk("SET DIV_OUT ON DIBSTREAM TX");
-                       dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
-                       reg_1288 |= (1<<8);
-                       break;
-       case ADC_ON_DIBTX:
-                       dprintk("SET ADC_OUT ON DIBSTREAM TX");
-                       dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
-                       reg_1288 |= (1<<7);
-                       break;
-       default:
-                       break;
-       }
-       dib7000p_write_word(state, 1288, reg_1288);
-}
-
-static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
-{
-       u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
-
-       switch (mode) {
-       case DEMOUT_ON_HOSTBUS:
-                       dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
-                       dib7090_enMpegMux(state, 0);
-                       reg_1288 |= (1<<6);
-                       break;
-       case DIBTX_ON_HOSTBUS:
-                       dprintk("SET DIBSTREAM TX ON HOST BUS");
-                       dib7090_enMpegMux(state, 0);
-                       reg_1288 |= (1<<5);
-                       break;
-       case MPEG_ON_HOSTBUS:
-                       dprintk("SET MPEG MUX ON HOST BUS");
-                       reg_1288 |= (1<<4);
-                       break;
-       default:
-                       break;
-       }
-       dib7000p_write_word(state, 1288, reg_1288);
-}
-
-int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 reg_1287;
-
-       switch (onoff) {
-       case 0: /* only use the internal way - not the diversity input */
-                       dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__);
-                       dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
-
-                       /* Do not divide the serial clock of MPEG MUX */
-                       /* in SERIAL MODE in case input mode MPEG is used */
-                       reg_1287 = dib7000p_read_word(state, 1287);
-                       /* enSerialClkDiv2 == 1 ? */
-                       if ((reg_1287 & 0x1) == 1) {
-                               /* force enSerialClkDiv2 = 0 */
-                               reg_1287 &= ~0x1;
-                               dib7000p_write_word(state, 1287, reg_1287);
-                       }
-                       state->input_mode_mpeg = 1;
-                       break;
-       case 1: /* both ways */
-       case 2: /* only the diversity input */
-                       dprintk("%s ON : Enable diversity INPUT", __func__);
-                       dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
-                       state->input_mode_mpeg = 0;
-                       break;
-       }
-
-       dib7000p_set_diversity_in(&state->demod, onoff);
-       return 0;
-}
-
-static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-
-       u16 outreg, smo_mode, fifo_threshold;
-       u8 prefer_mpeg_mux_use = 1;
-       int ret = 0;
-
-       dib7090_host_bus_drive(state, 1);
-
-       fifo_threshold = 1792;
-       smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
-       outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
-
-       switch (mode) {
-       case OUTMODE_HIGH_Z:
-               outreg = 0;
-               break;
-
-       case OUTMODE_MPEG2_SERIAL:
-               if (prefer_mpeg_mux_use) {
-                       dprintk("setting output mode TS_SERIAL using Mpeg Mux");
-                       dib7090_configMpegMux(state, 3, 1, 1);
-                       dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
-               } else {/* Use Smooth block */
-                       dprintk("setting output mode TS_SERIAL using Smooth bloc");
-                       dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-                       outreg |= (2<<6) | (0 << 1);
-               }
-               break;
-
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-               if (prefer_mpeg_mux_use) {
-                       dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
-                       dib7090_configMpegMux(state, 2, 0, 0);
-                       dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
-               } else { /* Use Smooth block */
-                       dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
-                       dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-                       outreg |= (0<<6);
-               }
-               break;
-
-       case OUTMODE_MPEG2_PAR_CONT_CLK:        /* Using Smooth block only */
-               dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
-               dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-               outreg |= (1<<6);
-               break;
-
-       case OUTMODE_MPEG2_FIFO:        /* Using Smooth block because not supported by new Mpeg Mux bloc */
-               dprintk("setting output mode TS_FIFO using Smooth block");
-               dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-               outreg |= (5<<6);
-               smo_mode |= (3 << 1);
-               fifo_threshold = 512;
-               break;
-
-       case OUTMODE_DIVERSITY:
-               dprintk("setting output mode MODE_DIVERSITY");
-               dib7090_setDibTxMux(state, DIV_ON_DIBTX);
-               dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-               break;
-
-       case OUTMODE_ANALOG_ADC:
-               dprintk("setting output mode MODE_ANALOG_ADC");
-               dib7090_setDibTxMux(state, ADC_ON_DIBTX);
-               dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-               break;
-       }
-       if (mode != OUTMODE_HIGH_Z)
-               outreg |= (1 << 10);
-
-       if (state->cfg.output_mpeg2_in_188_bytes)
-               smo_mode |= (1 << 5);
-
-       ret |= dib7000p_write_word(state, 235, smo_mode);
-       ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
-       ret |= dib7000p_write_word(state, 1286, outreg);
-
-       return ret;
-}
-
-int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 en_cur_state;
-
-       dprintk("sleep dib7090: %d", onoff);
-
-       en_cur_state = dib7000p_read_word(state, 1922);
-
-       if (en_cur_state > 0xff)
-               state->tuner_enable = en_cur_state;
-
-       if (onoff)
-               en_cur_state &= 0x00ff;
-       else {
-               if (state->tuner_enable != 0)
-                       en_cur_state = state->tuner_enable;
-       }
-
-       dib7000p_write_word(state, 1922, en_cur_state);
-
-       return 0;
-}
-EXPORT_SYMBOL(dib7090_tuner_sleep);
-
-int dib7090_get_adc_power(struct dvb_frontend *fe)
-{
-       return dib7000p_get_adc_power(fe);
-}
-EXPORT_SYMBOL(dib7090_get_adc_power);
-
-int dib7090_slave_reset(struct dvb_frontend *fe)
-{
-       struct dib7000p_state *state = fe->demodulator_priv;
-       u16 reg;
-
-       reg = dib7000p_read_word(state, 1794);
-       dib7000p_write_word(state, 1794, reg | (4 << 12));
-
-       dib7000p_write_word(state, 1032, 0xffff);
-       return 0;
-}
-EXPORT_SYMBOL(dib7090_slave_reset);
-
-static struct dvb_frontend_ops dib7000p_ops;
-struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
-{
-       struct dvb_frontend *demod;
-       struct dib7000p_state *st;
-       st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-
-       memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
-       st->i2c_adap = i2c_adap;
-       st->i2c_addr = i2c_addr;
-       st->gpio_val = cfg->gpio_val;
-       st->gpio_dir = cfg->gpio_dir;
-
-       /* Ensure the output mode remains at the previous default if it's
-        * not specifically set by the caller.
-        */
-       if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
-               st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
-
-       demod = &st->demod;
-       demod->demodulator_priv = st;
-       memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
-       mutex_init(&st->i2c_buffer_lock);
-
-       dib7000p_write_word(st, 1287, 0x0003);  /* sram lead in, rdy */
-
-       if (dib7000p_identify(st) != 0)
-               goto error;
-
-       st->version = dib7000p_read_word(st, 897);
-
-       /* FIXME: make sure the dev.parent field is initialized, or else
-          request_firmware() will hit an OOPS (this should be moved somewhere
-          more common) */
-       st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
-
-       dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
-
-       /* init 7090 tuner adapter */
-       strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
-       st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
-       st->dib7090_tuner_adap.algo_data = NULL;
-       st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
-       i2c_set_adapdata(&st->dib7090_tuner_adap, st);
-       i2c_add_adapter(&st->dib7090_tuner_adap);
-
-       dib7000p_demod_reset(st);
-
-       if (st->version == SOC7090) {
-               dib7090_set_output_mode(demod, st->cfg.output_mode);
-               dib7090_set_diversity_in(demod, 0);
-       }
-
-       return demod;
-
-error:
-       kfree(st);
-       return NULL;
-}
-EXPORT_SYMBOL(dib7000p_attach);
-
-static struct dvb_frontend_ops dib7000p_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-                .name = "DiBcom 7000PC",
-                .frequency_min = 44250000,
-                .frequency_max = 867250000,
-                .frequency_stepsize = 62500,
-                .caps = FE_CAN_INVERSION_AUTO |
-                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
-                },
-
-       .release = dib7000p_release,
-
-       .init = dib7000p_wakeup,
-       .sleep = dib7000p_sleep,
-
-       .set_frontend = dib7000p_set_frontend,
-       .get_tune_settings = dib7000p_fe_get_tune_settings,
-       .get_frontend = dib7000p_get_frontend,
-
-       .read_status = dib7000p_read_status,
-       .read_ber = dib7000p_read_ber,
-       .read_signal_strength = dib7000p_read_signal_strength,
-       .read_snr = dib7000p_read_snr,
-       .read_ucblocks = dib7000p_read_unc_blocks,
-};
-
-MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
deleted file mode 100644 (file)
index b61b03a..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef DIB7000P_H
-#define DIB7000P_H
-
-#include "dibx000_common.h"
-
-struct dib7000p_config {
-       u8 output_mpeg2_in_188_bytes;
-       u8 hostbus_diversity;
-       u8 tuner_is_baseband;
-       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
-
-       u8 agc_config_count;
-       struct dibx000_agc_config *agc;
-       struct dibx000_bandwidth_config *bw;
-
-#define DIB7000P_GPIO_DEFAULT_DIRECTIONS 0xffff
-       u16 gpio_dir;
-#define DIB7000P_GPIO_DEFAULT_VALUES     0x0000
-       u16 gpio_val;
-#define DIB7000P_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
-#define DIB7000P_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
-#define DIB7000P_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
-#define DIB7000P_GPIO_PWM_POS3(v)         (v & 0xf)
-#define DIB7000P_GPIO_DEFAULT_PWM_POS    0xffff
-       u16 gpio_pwm_pos;
-
-       u16 pwm_freq_div;
-
-       u8 quartz_direct;
-
-       u8 spur_protect;
-
-       int (*agc_control) (struct dvb_frontend *, u8 before);
-
-       u8 output_mode;
-       u8 disable_sample_and_hold:1;
-
-       u8 enable_current_mirror:1;
-       u16 diversity_delay;
-
-       u8 default_i2c_addr;
-       u8 enMpegOutput:1;
-};
-
-#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-
-#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
-                                       defined(MODULE))
-extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
-extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
-extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
-extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
-extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
-extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
-extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
-extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
-extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
-extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
-extern int dib7090_get_adc_power(struct dvb_frontend *fe);
-extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
-extern int dib7090_slave_reset(struct dvb_frontend *fe);
-extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
-               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
-#else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-
-static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib7090_slave_reset(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
-               u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
deleted file mode 100644 (file)
index 1f3bcb5..0000000
+++ /dev/null
@@ -1,3560 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
- *
- * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License as
- *  published by the Free Software Foundation, version 2.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_math.h"
-
-#include "dvb_frontend.h"
-
-#include "dib8000.h"
-
-#define LAYER_ALL -1
-#define LAYER_A   1
-#define LAYER_B   2
-#define LAYER_C   3
-
-#define FE_CALLBACK_TIME_NEVER 0xffffffff
-#define MAX_NUMBER_OF_FRONTENDS 6
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
-
-#define FE_STATUS_TUNE_FAILED 0
-
-struct i2c_device {
-       struct i2c_adapter *adap;
-       u8 addr;
-       u8 *i2c_write_buffer;
-       u8 *i2c_read_buffer;
-       struct mutex *i2c_buffer_lock;
-};
-
-struct dib8000_state {
-       struct dib8000_config cfg;
-
-       struct i2c_device i2c;
-
-       struct dibx000_i2c_master i2c_master;
-
-       u16 wbd_ref;
-
-       u8 current_band;
-       u32 current_bandwidth;
-       struct dibx000_agc_config *current_agc;
-       u32 timf;
-       u32 timf_default;
-
-       u8 div_force_off:1;
-       u8 div_state:1;
-       u16 div_sync_wait;
-
-       u8 agc_state;
-       u8 differential_constellation;
-       u8 diversity_onoff;
-
-       s16 ber_monitored_layer;
-       u16 gpio_dir;
-       u16 gpio_val;
-
-       u16 revision;
-       u8 isdbt_cfg_loaded;
-       enum frontend_tune_state tune_state;
-       u32 status;
-
-       struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[4];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-       u8 input_mode_mpeg;
-
-       u16 tuner_enable;
-       struct i2c_adapter dib8096p_tuner_adap;
-};
-
-enum dib8000_power_mode {
-       DIB8000_POWER_ALL = 0,
-       DIB8000_POWER_INTERFACE_ONLY,
-};
-
-static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
-{
-       u16 ret;
-       struct i2c_msg msg[2] = {
-               {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
-               {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
-       };
-
-       if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       msg[0].buf    = i2c->i2c_write_buffer;
-       msg[0].buf[0] = reg >> 8;
-       msg[0].buf[1] = reg & 0xff;
-       msg[1].buf    = i2c->i2c_read_buffer;
-
-       if (i2c_transfer(i2c->adap, msg, 2) != 2)
-               dprintk("i2c read error on %d", reg);
-
-       ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
-       mutex_unlock(i2c->i2c_buffer_lock);
-       return ret;
-}
-
-static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       state->i2c_write_buffer[0] = reg >> 8;
-       state->i2c_write_buffer[1] = reg & 0xff;
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c.addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 2;
-       state->msg[1].addr = state->i2c.addr >> 1;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = state->i2c_read_buffer;
-       state->msg[1].len = 2;
-
-       if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
-               dprintk("i2c read error on %d", reg);
-
-       ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
-       mutex_unlock(&state->i2c_buffer_lock);
-
-       return ret;
-}
-
-static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
-{
-       u16 rw[2];
-
-       rw[0] = dib8000_read_word(state, reg + 0);
-       rw[1] = dib8000_read_word(state, reg + 1);
-
-       return ((rw[0] << 16) | (rw[1]));
-}
-
-static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
-{
-       struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
-       int ret = 0;
-
-       if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       msg.buf    = i2c->i2c_write_buffer;
-       msg.buf[0] = (reg >> 8) & 0xff;
-       msg.buf[1] = reg & 0xff;
-       msg.buf[2] = (val >> 8) & 0xff;
-       msg.buf[3] = val & 0xff;
-
-       ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
-       mutex_unlock(i2c->i2c_buffer_lock);
-
-       return ret;
-}
-
-static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       state->i2c_write_buffer[1] = reg & 0xff;
-       state->i2c_write_buffer[2] = (val >> 8) & 0xff;
-       state->i2c_write_buffer[3] = val & 0xff;
-
-       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c.addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 4;
-
-       ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
-                       -EREMOTEIO : 0);
-       mutex_unlock(&state->i2c_buffer_lock);
-
-       return ret;
-}
-
-static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
-       (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
-               (920 << 5) | 0x09
-};
-
-static const s16 coeff_2k_sb_1seg[8] = {
-       (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
-};
-
-static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
-       (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
-               (-931 << 5) | 0x0f
-};
-
-static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
-       (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
-               (982 << 5) | 0x0c
-};
-
-static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
-       (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
-               (-720 << 5) | 0x0d
-};
-
-static const s16 coeff_2k_sb_3seg[8] = {
-       (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
-               (-610 << 5) | 0x0a
-};
-
-static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
-       (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
-               (-922 << 5) | 0x0d
-};
-
-static const s16 coeff_4k_sb_1seg[8] = {
-       (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
-               (-655 << 5) | 0x0a
-};
-
-static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
-       (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
-               (-958 << 5) | 0x13
-};
-
-static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
-       (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
-               (-568 << 5) | 0x0f
-};
-
-static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
-       (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
-               (-848 << 5) | 0x13
-};
-
-static const s16 coeff_4k_sb_3seg[8] = {
-       (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
-               (-869 << 5) | 0x13
-};
-
-static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
-       (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
-               (-598 << 5) | 0x10
-};
-
-static const s16 coeff_8k_sb_1seg[8] = {
-       (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
-               (585 << 5) | 0x0f
-};
-
-static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
-       (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
-               (0 << 5) | 0x14
-};
-
-static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
-       (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
-               (-877 << 5) | 0x15
-};
-
-static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
-       (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
-               (-921 << 5) | 0x14
-};
-
-static const s16 coeff_8k_sb_3seg[8] = {
-       (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
-               (690 << 5) | 0x14
-};
-
-static const s16 ana_fe_coeff_3seg[24] = {
-       81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
-};
-
-static const s16 ana_fe_coeff_1seg[24] = {
-       249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
-};
-
-static const s16 ana_fe_coeff_13seg[24] = {
-       396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
-};
-
-static u16 fft_to_mode(struct dib8000_state *state)
-{
-       u16 mode;
-       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               mode = 1;
-               break;
-       case TRANSMISSION_MODE_4K:
-               mode = 2;
-               break;
-       default:
-       case TRANSMISSION_MODE_AUTO:
-       case TRANSMISSION_MODE_8K:
-               mode = 3;
-               break;
-       }
-       return mode;
-}
-
-static void dib8000_set_acquisition_mode(struct dib8000_state *state)
-{
-       u16 nud = dib8000_read_word(state, 298);
-       nud |= (1 << 3) | (1 << 0);
-       dprintk("acquisition mode activated");
-       dib8000_write_word(state, 298, nud);
-}
-static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;    /* by default SDRAM deintlv is enabled */
-
-       outreg = 0;
-       fifo_threshold = 1792;
-       smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
-
-       dprintk("-I-    Setting output mode for demod %p to %d",
-                       &state->fe[0], mode);
-
-       switch (mode) {
-       case OUTMODE_MPEG2_PAR_GATED_CLK:       // STBs with parallel gated clock
-               outreg = (1 << 10);     /* 0x0400 */
-               break;
-       case OUTMODE_MPEG2_PAR_CONT_CLK:        // STBs with parallel continues clock
-               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
-               break;
-       case OUTMODE_MPEG2_SERIAL:      // STBs with serial input
-               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
-               break;
-       case OUTMODE_DIVERSITY:
-               if (state->cfg.hostbus_diversity) {
-                       outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
-                       sram &= 0xfdff;
-               } else
-                       sram |= 0x0c00;
-               break;
-       case OUTMODE_MPEG2_FIFO:        // e.g. USB feeding
-               smo_mode |= (3 << 1);
-               fifo_threshold = 512;
-               outreg = (1 << 10) | (5 << 6);
-               break;
-       case OUTMODE_HIGH_Z:    // disable
-               outreg = 0;
-               break;
-
-       case OUTMODE_ANALOG_ADC:
-               outreg = (1 << 10) | (3 << 6);
-               dib8000_set_acquisition_mode(state);
-               break;
-
-       default:
-               dprintk("Unhandled output_mode passed to be set for demod %p",
-                               &state->fe[0]);
-               return -EINVAL;
-       }
-
-       if (state->cfg.output_mpeg2_in_188_bytes)
-               smo_mode |= (1 << 5);
-
-       dib8000_write_word(state, 299, smo_mode);
-       dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
-       dib8000_write_word(state, 1286, outreg);
-       dib8000_write_word(state, 1291, sram);
-
-       return 0;
-}
-
-static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
-
-       if (!state->differential_constellation) {
-               dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
-               dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);       // sync_enable = 1; comb_mode = 2
-       } else {
-               dib8000_write_word(state, 272, 0);      //dvsy_off_lmod4 = 0
-               dib8000_write_word(state, 273, sync_wait);      // sync_enable = 0; comb_mode = 0
-       }
-       state->diversity_onoff = onoff;
-
-       switch (onoff) {
-       case 0:         /* only use the internal way - not the diversity input */
-               dib8000_write_word(state, 270, 1);
-               dib8000_write_word(state, 271, 0);
-               break;
-       case 1:         /* both ways */
-               dib8000_write_word(state, 270, 6);
-               dib8000_write_word(state, 271, 6);
-               break;
-       case 2:         /* only the diversity input */
-               dib8000_write_word(state, 270, 0);
-               dib8000_write_word(state, 271, 1);
-               break;
-       }
-       return 0;
-}
-
-static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
-{
-       /* by default everything is going to be powered off */
-       u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
-               reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
-               reg_1280;
-
-       if (state->revision != 0x8090)
-               reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
-       else
-               reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
-
-       /* now, depending on the requested mode, we power on */
-       switch (mode) {
-               /* power up everything in the demod */
-       case DIB8000_POWER_ALL:
-               reg_774 = 0x0000;
-               reg_775 = 0x0000;
-               reg_776 = 0x0000;
-               reg_900 &= 0xfffc;
-               if (state->revision != 0x8090)
-                       reg_1280 &= 0x00ff;
-               else
-                       reg_1280 &= 0x707f;
-               break;
-       case DIB8000_POWER_INTERFACE_ONLY:
-               if (state->revision != 0x8090)
-                       reg_1280 &= 0x00ff;
-               else
-                       reg_1280 &= 0xfa7b;
-               break;
-       }
-
-       dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
-       dib8000_write_word(state, 774, reg_774);
-       dib8000_write_word(state, 775, reg_775);
-       dib8000_write_word(state, 776, reg_776);
-       dib8000_write_word(state, 900, reg_900);
-       dib8000_write_word(state, 1280, reg_1280);
-}
-
-static int dib8000_init_sdram(struct dib8000_state *state)
-{
-       u16 reg = 0;
-       dprintk("Init sdram");
-
-       reg = dib8000_read_word(state, 274)&0xfff0;
-       /* P_dintlv_delay_ram = 7 because of MobileSdram */
-       dib8000_write_word(state, 274, reg | 0x7);
-
-       dib8000_write_word(state, 1803, (7<<2));
-
-       reg = dib8000_read_word(state, 1280);
-       /* force restart P_restart_sdram */
-       dib8000_write_word(state, 1280,  reg | (1<<2));
-
-       /* release restart P_restart_sdram */
-       dib8000_write_word(state, 1280,  reg);
-
-       return 0;
-}
-
-static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
-{
-       int ret = 0;
-       u16 reg, reg_907 = dib8000_read_word(state, 907);
-       u16 reg_908 = dib8000_read_word(state, 908);
-
-       switch (no) {
-       case DIBX000_SLOW_ADC_ON:
-               if (state->revision != 0x8090) {
-                       reg_908 |= (1 << 1) | (1 << 0);
-                       ret |= dib8000_write_word(state, 908, reg_908);
-                       reg_908 &= ~(1 << 1);
-               } else {
-                       reg = dib8000_read_word(state, 1925);
-                       /* en_slowAdc = 1 & reset_sladc = 1 */
-                       dib8000_write_word(state, 1925, reg |
-                                       (1<<4) | (1<<2));
-
-                       /* read acces to make it works... strange ... */
-                       reg = dib8000_read_word(state, 1925);
-                       msleep(20);
-                       /* en_slowAdc = 1 & reset_sladc = 0 */
-                       dib8000_write_word(state, 1925, reg & ~(1<<4));
-
-                       reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
-                                       | (0x3 << 12));
-                       /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
-                          (Vin2 = Vcm) */
-                       dib8000_write_word(state, 921, reg | (1 << 14)
-                                       | (3 << 12));
-               }
-               break;
-
-       case DIBX000_SLOW_ADC_OFF:
-               if (state->revision == 0x8090) {
-                       reg = dib8000_read_word(state, 1925);
-                       /* reset_sladc = 1 en_slowAdc = 0 */
-                       dib8000_write_word(state, 1925,
-                                       (reg & ~(1<<2)) | (1<<4));
-               }
-               reg_908 |= (1 << 1) | (1 << 0);
-               break;
-
-       case DIBX000_ADC_ON:
-               reg_907 &= 0x0fff;
-               reg_908 &= 0x0003;
-               break;
-
-       case DIBX000_ADC_OFF:   // leave the VBG voltage on
-               reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
-               reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
-               break;
-
-       case DIBX000_VBG_ENABLE:
-               reg_907 &= ~(1 << 15);
-               break;
-
-       case DIBX000_VBG_DISABLE:
-               reg_907 |= (1 << 15);
-               break;
-
-       default:
-               break;
-       }
-
-       ret |= dib8000_write_word(state, 907, reg_907);
-       ret |= dib8000_write_word(state, 908, reg_908);
-
-       return ret;
-}
-
-static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u32 timf;
-
-       if (bw == 0)
-               bw = 6000;
-
-       if (state->timf == 0) {
-               dprintk("using default timf");
-               timf = state->timf_default;
-       } else {
-               dprintk("using updated timf");
-               timf = state->timf;
-       }
-
-       dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
-       dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
-
-       return 0;
-}
-
-static int dib8000_sad_calib(struct dib8000_state *state)
-{
-       if (state->revision == 0x8090) {
-               dprintk("%s: the sad calibration is not needed for the dib8096P",
-                               __func__);
-               return 0;
-       }
-       /* internal */
-       dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
-       dib8000_write_word(state, 924, 776);    // 0.625*3.3 / 4096
-
-       /* do the calibration */
-       dib8000_write_word(state, 923, (1 << 0));
-       dib8000_write_word(state, 923, (0 << 0));
-
-       msleep(1);
-       return 0;
-}
-
-int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       if (value > 4095)
-               value = 4095;
-       state->wbd_ref = value;
-       return dib8000_write_word(state, 106, value);
-}
-
-EXPORT_SYMBOL(dib8000_set_wbd_ref);
-static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
-{
-       dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
-       if (state->revision != 0x8090) {
-               dib8000_write_word(state, 23,
-                               (u16) (((bw->internal * 1000) >> 16) & 0xffff));
-               dib8000_write_word(state, 24,
-                               (u16) ((bw->internal * 1000) & 0xffff));
-       } else {
-               dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
-               dib8000_write_word(state, 24,
-                               (u16) ((bw->internal  / 2 * 1000) & 0xffff));
-       }
-       dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
-       dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
-       dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
-
-       if (state->revision != 0x8090)
-               dib8000_write_word(state, 922, bw->sad_cfg);
-}
-
-static void dib8000_reset_pll(struct dib8000_state *state)
-{
-       const struct dibx000_bandwidth_config *pll = state->cfg.pll;
-       u16 clk_cfg1, reg;
-
-       if (state->revision != 0x8090) {
-               dib8000_write_word(state, 901,
-                               (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
-
-               clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
-                       (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
-                       (1 << 3) | (pll->pll_range << 1) |
-                       (pll->pll_reset << 0);
-
-               dib8000_write_word(state, 902, clk_cfg1);
-               clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
-               dib8000_write_word(state, 902, clk_cfg1);
-
-               dprintk("clk_cfg1: 0x%04x", clk_cfg1);
-
-               /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
-               if (state->cfg.pll->ADClkSrc == 0)
-                       dib8000_write_word(state, 904,
-                                       (0 << 15) | (0 << 12) | (0 << 10) |
-                                       (pll->modulo << 8) |
-                                       (pll->ADClkSrc << 7) | (0 << 1));
-               else if (state->cfg.refclksel != 0)
-                       dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
-                                       ((state->cfg.refclksel & 0x3) << 10) |
-                                       (pll->modulo << 8) |
-                                       (pll->ADClkSrc << 7) | (0 << 1));
-               else
-                       dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
-                                       (3 << 10) | (pll->modulo << 8) |
-                                       (pll->ADClkSrc << 7) | (0 << 1));
-       } else {
-               dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
-                               (pll->pll_range<<12) | (pll->pll_ratio<<6) |
-                               (pll->pll_prediv));
-
-               reg = dib8000_read_word(state, 1857);
-               dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
-
-               reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
-               dib8000_write_word(state, 1858, reg | 1);
-
-               dib8000_write_word(state, 904, (pll->modulo << 8));
-       }
-
-       dib8000_reset_pll_common(state, pll);
-}
-
-int dib8000_update_pll(struct dvb_frontend *fe,
-               struct dibx000_bandwidth_config *pll)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
-       u8 loopdiv, prediv;
-       u32 internal, xtal;
-
-       /* get back old values */
-       prediv = reg_1856 & 0x3f;
-       loopdiv = (reg_1856 >> 6) & 0x3f;
-
-       if ((pll != NULL) && (pll->pll_prediv != prediv ||
-                               pll->pll_ratio != loopdiv)) {
-               dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
-               reg_1856 &= 0xf000;
-               reg_1857 = dib8000_read_word(state, 1857);
-               /* disable PLL */
-               dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
-
-               dib8000_write_word(state, 1856, reg_1856 |
-                               ((pll->pll_ratio & 0x3f) << 6) |
-                               (pll->pll_prediv & 0x3f));
-
-               /* write new system clk into P_sec_len */
-               internal = dib8000_read32(state, 23) / 1000;
-               dprintk("Old Internal = %d", internal);
-               xtal = 2 * (internal / loopdiv) * prediv;
-               internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
-               dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
-               dprintk("New Internal = %d", internal);
-
-               dib8000_write_word(state, 23,
-                               (u16) (((internal / 2) >> 16) & 0xffff));
-               dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
-               /* enable PLL */
-               dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
-
-               while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
-                       dprintk("Waiting for PLL to lock");
-
-               /* verify */
-               reg_1856 = dib8000_read_word(state, 1856);
-               dprintk("PLL Updated with prediv = %d and loopdiv = %d",
-                               reg_1856&0x3f, (reg_1856>>6)&0x3f);
-
-               return 0;
-       }
-       return -EINVAL;
-}
-EXPORT_SYMBOL(dib8000_update_pll);
-
-
-static int dib8000_reset_gpio(struct dib8000_state *st)
-{
-       /* reset the GPIOs */
-       dib8000_write_word(st, 1029, st->cfg.gpio_dir);
-       dib8000_write_word(st, 1030, st->cfg.gpio_val);
-
-       /* TODO 782 is P_gpio_od */
-
-       dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
-
-       dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
-       return 0;
-}
-
-static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
-{
-       st->cfg.gpio_dir = dib8000_read_word(st, 1029);
-       st->cfg.gpio_dir &= ~(1 << num);        /* reset the direction bit */
-       st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
-       dib8000_write_word(st, 1029, st->cfg.gpio_dir);
-
-       st->cfg.gpio_val = dib8000_read_word(st, 1030);
-       st->cfg.gpio_val &= ~(1 << num);        /* reset the direction bit */
-       st->cfg.gpio_val |= (val & 0x01) << num;        /* set the new value */
-       dib8000_write_word(st, 1030, st->cfg.gpio_val);
-
-       dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
-
-       return 0;
-}
-
-int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       return dib8000_cfg_gpio(state, num, dir, val);
-}
-
-EXPORT_SYMBOL(dib8000_set_gpio);
-static const u16 dib8000_defaults[] = {
-       /* auto search configuration - lock0 by default waiting
-        * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
-       3, 7,
-       0x0004,
-       0x0400,
-       0x0814,
-
-       12, 11,
-       0x001b,
-       0x7740,
-       0x005b,
-       0x8d80,
-       0x01c9,
-       0xc380,
-       0x0000,
-       0x0080,
-       0x0000,
-       0x0090,
-       0x0001,
-       0xd4c0,
-
-       /*1, 32,
-               0x6680 // P_corm_thres Lock algorithms configuration */
-
-       11, 80,                 /* set ADC level to -16 */
-       (1 << 13) - 825 - 117,
-       (1 << 13) - 837 - 117,
-       (1 << 13) - 811 - 117,
-       (1 << 13) - 766 - 117,
-       (1 << 13) - 737 - 117,
-       (1 << 13) - 693 - 117,
-       (1 << 13) - 648 - 117,
-       (1 << 13) - 619 - 117,
-       (1 << 13) - 575 - 117,
-       (1 << 13) - 531 - 117,
-       (1 << 13) - 501 - 117,
-
-       4, 108,
-       0,
-       0,
-       0,
-       0,
-
-       1, 175,
-       0x0410,
-       1, 179,
-       8192,                   // P_fft_nb_to_cut
-
-       6, 181,
-       0x2800,                 // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
-       0x2800,
-       0x2800,
-       0x2800,                 // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
-       0x2800,
-       0x2800,
-
-       2, 193,
-       0x0666,                 // P_pha3_thres
-       0x0000,                 // P_cti_use_cpe, P_cti_use_prog
-
-       2, 205,
-       0x200f,                 // P_cspu_regul, P_cspu_win_cut
-       0x000f,                 // P_des_shift_work
-
-       5, 215,
-       0x023d,                 // P_adp_regul_cnt
-       0x00a4,                 // P_adp_noise_cnt
-       0x00a4,                 // P_adp_regul_ext
-       0x7ff0,                 // P_adp_noise_ext
-       0x3ccc,                 // P_adp_fil
-
-       1, 230,
-       0x0000,                 // P_2d_byp_ti_num
-
-       1, 263,
-       0x800,                  //P_equal_thres_wgn
-
-       1, 268,
-       (2 << 9) | 39,          // P_equal_ctrl_synchro, P_equal_speedmode
-
-       1, 270,
-       0x0001,                 // P_div_lock0_wait
-       1, 285,
-       0x0020,                 //p_fec_
-       1, 299,
-       0x0062,                 /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
-
-       1, 338,
-       (1 << 12) |             // P_ctrl_corm_thres4pre_freq_inh=1
-               (1 << 10) |
-               (0 << 9) |              /* P_ctrl_pre_freq_inh=0 */
-               (3 << 5) |              /* P_ctrl_pre_freq_step=3 */
-               (1 << 0),               /* P_pre_freq_win_len=1 */
-
-       0,
-};
-
-static u16 dib8000_identify(struct i2c_device *client)
-{
-       u16 value;
-
-       //because of glitches sometimes
-       value = dib8000_i2c_read16(client, 896);
-
-       if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
-               dprintk("wrong Vendor ID (read=0x%x)", value);
-               return 0;
-       }
-
-       value = dib8000_i2c_read16(client, 897);
-       if (value != 0x8000 && value != 0x8001 &&
-                       value != 0x8002 && value != 0x8090) {
-               dprintk("wrong Device ID (%x)", value);
-               return 0;
-       }
-
-       switch (value) {
-       case 0x8000:
-               dprintk("found DiB8000A");
-               break;
-       case 0x8001:
-               dprintk("found DiB8000B");
-               break;
-       case 0x8002:
-               dprintk("found DiB8000C");
-               break;
-       case 0x8090:
-               dprintk("found DiB8096P");
-               break;
-       }
-       return value;
-}
-
-static int dib8000_reset(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       if ((state->revision = dib8000_identify(&state->i2c)) == 0)
-               return -EINVAL;
-
-       /* sram lead in, rdy */
-       if (state->revision != 0x8090)
-               dib8000_write_word(state, 1287, 0x0003);
-
-       if (state->revision == 0x8000)
-               dprintk("error : dib8000 MA not supported");
-
-       dibx000_reset_i2c_master(&state->i2c_master);
-
-       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
-
-       /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
-       dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
-
-       /* restart all parts */
-       dib8000_write_word(state, 770, 0xffff);
-       dib8000_write_word(state, 771, 0xffff);
-       dib8000_write_word(state, 772, 0xfffc);
-       if (state->revision == 0x8090)
-               dib8000_write_word(state, 1280, 0x0045);
-       else
-               dib8000_write_word(state, 1280, 0x004d);
-       dib8000_write_word(state, 1281, 0x000c);
-
-       dib8000_write_word(state, 770, 0x0000);
-       dib8000_write_word(state, 771, 0x0000);
-       dib8000_write_word(state, 772, 0x0000);
-       dib8000_write_word(state, 898, 0x0004); // sad
-       dib8000_write_word(state, 1280, 0x0000);
-       dib8000_write_word(state, 1281, 0x0000);
-
-       /* drives */
-       if (state->revision != 0x8090) {
-               if (state->cfg.drives)
-                       dib8000_write_word(state, 906, state->cfg.drives);
-               else {
-                       dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
-                       /* min drive SDRAM - not optimal - adjust */
-                       dib8000_write_word(state, 906, 0x2d98);
-               }
-       }
-
-       dib8000_reset_pll(state);
-       if (state->revision != 0x8090)
-               dib8000_write_word(state, 898, 0x0004);
-
-       if (dib8000_reset_gpio(state) != 0)
-               dprintk("GPIO reset was not successful.");
-
-       if ((state->revision != 0x8090) &&
-                       (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
-               dprintk("OUTPUT_MODE could not be resetted.");
-
-       state->current_agc = NULL;
-
-       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
-       /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
-       if (state->cfg.pll->ifreq == 0)
-               dib8000_write_word(state, 40, 0x0755);  /* P_iqc_corr_inh = 0 enable IQcorr block */
-       else
-               dib8000_write_word(state, 40, 0x1f55);  /* P_iqc_corr_inh = 1 disable IQcorr block */
-
-       {
-               u16 l = 0, r;
-               const u16 *n;
-               n = dib8000_defaults;
-               l = *n++;
-               while (l) {
-                       r = *n++;
-                       do {
-                               dib8000_write_word(state, r, *n++);
-                               r++;
-                       } while (--l);
-                       l = *n++;
-               }
-       }
-       if (state->revision != 0x8090)
-               dib8000_write_word(state, 903, (0 << 4) | 2);
-       state->isdbt_cfg_loaded = 0;
-
-       //div_cfg override for special configs
-       if (state->cfg.div_cfg != 0)
-               dib8000_write_word(state, 903, state->cfg.div_cfg);
-
-       /* unforce divstr regardless whether i2c enumeration was done or not */
-       dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
-
-       dib8000_set_bandwidth(fe, 6000);
-
-       dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-       if (state->revision != 0x8090) {
-               dib8000_sad_calib(state);
-               dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
-       }
-
-       dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
-
-       return 0;
-}
-
-static void dib8000_restart_agc(struct dib8000_state *state)
-{
-       // P_restart_iqc & P_restart_agc
-       dib8000_write_word(state, 770, 0x0a00);
-       dib8000_write_word(state, 770, 0x0000);
-}
-
-static int dib8000_update_lna(struct dib8000_state *state)
-{
-       u16 dyn_gain;
-
-       if (state->cfg.update_lna) {
-               // read dyn_gain here (because it is demod-dependent and not tuner)
-               dyn_gain = dib8000_read_word(state, 390);
-
-               if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
-                       dib8000_restart_agc(state);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
-{
-       struct dibx000_agc_config *agc = NULL;
-       int i;
-       u16 reg;
-
-       if (state->current_band == band && state->current_agc != NULL)
-               return 0;
-       state->current_band = band;
-
-       for (i = 0; i < state->cfg.agc_config_count; i++)
-               if (state->cfg.agc[i].band_caps & band) {
-                       agc = &state->cfg.agc[i];
-                       break;
-               }
-
-       if (agc == NULL) {
-               dprintk("no valid AGC configuration found for band 0x%02x", band);
-               return -EINVAL;
-       }
-
-       state->current_agc = agc;
-
-       /* AGC */
-       dib8000_write_word(state, 76, agc->setup);
-       dib8000_write_word(state, 77, agc->inv_gain);
-       dib8000_write_word(state, 78, agc->time_stabiliz);
-       dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
-
-       // Demod AGC loop configuration
-       dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
-       dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
-
-       dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
-               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
-
-       /* AGC continued */
-       if (state->wbd_ref != 0)
-               dib8000_write_word(state, 106, state->wbd_ref);
-       else                    // use default
-               dib8000_write_word(state, 106, agc->wbd_ref);
-
-       if (state->revision == 0x8090) {
-               reg = dib8000_read_word(state, 922) & (0x3 << 2);
-               dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
-       }
-
-       dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
-       dib8000_write_word(state, 108, agc->agc1_max);
-       dib8000_write_word(state, 109, agc->agc1_min);
-       dib8000_write_word(state, 110, agc->agc2_max);
-       dib8000_write_word(state, 111, agc->agc2_min);
-       dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
-       dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
-       dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
-       dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
-
-       dib8000_write_word(state, 75, agc->agc1_pt3);
-       if (state->revision != 0x8090)
-               dib8000_write_word(state, 923,
-                               (dib8000_read_word(state, 923) & 0xffe3) |
-                               (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
-
-       return 0;
-}
-
-void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       dib8000_set_adc_state(state, DIBX000_ADC_ON);
-       dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
-}
-EXPORT_SYMBOL(dib8000_pwm_agc_reset);
-
-static int dib8000_agc_soft_split(struct dib8000_state *state)
-{
-       u16 agc, split_offset;
-
-       if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
-               return FE_CALLBACK_TIME_NEVER;
-
-       // n_agc_global
-       agc = dib8000_read_word(state, 390);
-
-       if (agc > state->current_agc->split.min_thres)
-               split_offset = state->current_agc->split.min;
-       else if (agc < state->current_agc->split.max_thres)
-               split_offset = state->current_agc->split.max;
-       else
-               split_offset = state->current_agc->split.max *
-                       (agc - state->current_agc->split.min_thres) /
-                       (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
-
-       dprintk("AGC split_offset: %d", split_offset);
-
-       // P_agc_force_split and P_agc_split_offset
-       dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
-       return 5000;
-}
-
-static int dib8000_agc_startup(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       enum frontend_tune_state *tune_state = &state->tune_state;
-       int ret = 0;
-       u16 reg, upd_demod_gain_period = 0x8000;
-
-       switch (*tune_state) {
-       case CT_AGC_START:
-               // set power-up level: interf+analog+AGC
-
-               if (state->revision != 0x8090)
-                       dib8000_set_adc_state(state, DIBX000_ADC_ON);
-               else {
-                       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
-
-                       reg = dib8000_read_word(state, 1947)&0xff00;
-                       dib8000_write_word(state, 1946,
-                                       upd_demod_gain_period & 0xFFFF);
-                       /* bit 14 = enDemodGain */
-                       dib8000_write_word(state, 1947, reg | (1<<14) |
-                                       ((upd_demod_gain_period >> 16) & 0xFF));
-
-                       /* enable adc i & q */
-                       reg = dib8000_read_word(state, 1920);
-                       dib8000_write_word(state, 1920, (reg | 0x3) &
-                                       (~(1 << 7)));
-               }
-
-               if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
-                       *tune_state = CT_AGC_STOP;
-                       state->status = FE_STATUS_TUNE_FAILED;
-                       break;
-               }
-
-               ret = 70;
-               *tune_state = CT_AGC_STEP_0;
-               break;
-
-       case CT_AGC_STEP_0:
-               //AGC initialization
-               if (state->cfg.agc_control)
-                       state->cfg.agc_control(fe, 1);
-
-               dib8000_restart_agc(state);
-
-               // wait AGC rough lock time
-               ret = 50;
-               *tune_state = CT_AGC_STEP_1;
-               break;
-
-       case CT_AGC_STEP_1:
-               // wait AGC accurate lock time
-               ret = 70;
-
-               if (dib8000_update_lna(state))
-                       // wait only AGC rough lock time
-                       ret = 50;
-               else
-                       *tune_state = CT_AGC_STEP_2;
-               break;
-
-       case CT_AGC_STEP_2:
-               dib8000_agc_soft_split(state);
-
-               if (state->cfg.agc_control)
-                       state->cfg.agc_control(fe, 0);
-
-               *tune_state = CT_AGC_STOP;
-               break;
-       default:
-               ret = dib8000_agc_soft_split(state);
-               break;
-       }
-       return ret;
-
-}
-
-static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
-{
-       u16 reg;
-
-       drive &= 0x7;
-
-       /* drive host bus 2, 3, 4 */
-       reg = dib8000_read_word(state, 1798) &
-               ~(0x7 | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive<<12) | (drive<<6) | drive;
-       dib8000_write_word(state, 1798, reg);
-
-       /* drive host bus 5,6 */
-       reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
-       reg |= (drive<<8) | (drive<<2);
-       dib8000_write_word(state, 1799, reg);
-
-       /* drive host bus 7, 8, 9 */
-       reg = dib8000_read_word(state, 1800) &
-               ~(0x7 | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive<<12) | (drive<<6) | drive;
-       dib8000_write_word(state, 1800, reg);
-
-       /* drive host bus 10, 11 */
-       reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
-       reg |= (drive<<8) | (drive<<2);
-       dib8000_write_word(state, 1801, reg);
-
-       /* drive host bus 12, 13, 14 */
-       reg = dib8000_read_word(state, 1802) &
-               ~(0x7 | (0x7 << 6) | (0x7 << 12));
-       reg |= (drive<<12) | (drive<<6) | drive;
-       dib8000_write_word(state, 1802, reg);
-}
-
-static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
-               u32 insertExtSynchro, u32 syncSize)
-{
-       u32 quantif = 3;
-       u32 nom = (insertExtSynchro * P_Kin+syncSize);
-       u32 denom = P_Kout;
-       u32 syncFreq = ((nom << quantif) / denom);
-
-       if ((syncFreq & ((1 << quantif) - 1)) != 0)
-               syncFreq = (syncFreq >> quantif) + 1;
-       else
-               syncFreq = (syncFreq >> quantif);
-
-       if (syncFreq != 0)
-               syncFreq = syncFreq - 1;
-
-       return syncFreq;
-}
-
-static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
-               u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
-               u32 syncWord, u32 syncSize)
-{
-       dprintk("Configure DibStream Tx");
-
-       dib8000_write_word(state, 1615, 1);
-       dib8000_write_word(state, 1603, P_Kin);
-       dib8000_write_word(state, 1605, P_Kout);
-       dib8000_write_word(state, 1606, insertExtSynchro);
-       dib8000_write_word(state, 1608, synchroMode);
-       dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
-       dib8000_write_word(state, 1610, syncWord & 0xffff);
-       dib8000_write_word(state, 1612, syncSize);
-       dib8000_write_word(state, 1615, 0);
-}
-
-static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
-               u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
-               u32 syncWord, u32 syncSize, u32 dataOutRate)
-{
-       u32 syncFreq;
-
-       dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
-
-       if ((P_Kin != 0) && (P_Kout != 0)) {
-               syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
-                               insertExtSynchro, syncSize);
-               dib8000_write_word(state, 1542, syncFreq);
-       }
-
-       dib8000_write_word(state, 1554, 1);
-       dib8000_write_word(state, 1536, P_Kin);
-       dib8000_write_word(state, 1537, P_Kout);
-       dib8000_write_word(state, 1539, synchroMode);
-       dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
-       dib8000_write_word(state, 1541, syncWord & 0xffff);
-       dib8000_write_word(state, 1543, syncSize);
-       dib8000_write_word(state, 1544, dataOutRate);
-       dib8000_write_word(state, 1554, 0);
-}
-
-static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
-{
-       u16 reg_1287;
-
-       reg_1287 = dib8000_read_word(state, 1287);
-
-       switch (onoff) {
-       case 1:
-                       reg_1287 &= ~(1 << 8);
-                       break;
-       case 0:
-                       reg_1287 |= (1 << 8);
-                       break;
-       }
-
-       dib8000_write_word(state, 1287, reg_1287);
-}
-
-static void dib8096p_configMpegMux(struct dib8000_state *state,
-               u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
-{
-       u16 reg_1287;
-
-       dprintk("Enable Mpeg mux");
-
-       dib8096p_enMpegMux(state, 0);
-
-       /* If the input mode is MPEG do not divide the serial clock */
-       if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
-               enSerialClkDiv2 = 0;
-
-       reg_1287 = ((pulseWidth & 0x1f) << 3) |
-               ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
-       dib8000_write_word(state, 1287, reg_1287);
-
-       dib8096p_enMpegMux(state, 1);
-}
-
-static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
-{
-       u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
-
-       switch (mode) {
-       case MPEG_ON_DIBTX:
-                       dprintk("SET MPEG ON DIBSTREAM TX");
-                       dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
-                       reg_1288 |= (1 << 9); break;
-       case DIV_ON_DIBTX:
-                       dprintk("SET DIV_OUT ON DIBSTREAM TX");
-                       dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
-                       reg_1288 |= (1 << 8); break;
-       case ADC_ON_DIBTX:
-                       dprintk("SET ADC_OUT ON DIBSTREAM TX");
-                       dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
-                       reg_1288 |= (1 << 7); break;
-       default:
-                       break;
-       }
-       dib8000_write_word(state, 1288, reg_1288);
-}
-
-static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
-{
-       u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
-
-       switch (mode) {
-       case DEMOUT_ON_HOSTBUS:
-                       dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
-                       dib8096p_enMpegMux(state, 0);
-                       reg_1288 |= (1 << 6);
-                       break;
-       case DIBTX_ON_HOSTBUS:
-                       dprintk("SET DIBSTREAM TX ON HOST BUS");
-                       dib8096p_enMpegMux(state, 0);
-                       reg_1288 |= (1 << 5);
-                       break;
-       case MPEG_ON_HOSTBUS:
-                       dprintk("SET MPEG MUX ON HOST BUS");
-                       reg_1288 |= (1 << 4);
-                       break;
-       default:
-                       break;
-       }
-       dib8000_write_word(state, 1288, reg_1288);
-}
-
-static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 reg_1287;
-
-       switch (onoff) {
-       case 0: /* only use the internal way - not the diversity input */
-                       dprintk("%s mode OFF : by default Enable Mpeg INPUT",
-                                       __func__);
-                       /* outputRate = 8 */
-                       dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
-
-                       /* Do not divide the serial clock of MPEG MUX in
-                          SERIAL MODE in case input mode MPEG is used */
-                       reg_1287 = dib8000_read_word(state, 1287);
-                       /* enSerialClkDiv2 == 1 ? */
-                       if ((reg_1287 & 0x1) == 1) {
-                               /* force enSerialClkDiv2 = 0 */
-                               reg_1287 &= ~0x1;
-                               dib8000_write_word(state, 1287, reg_1287);
-                       }
-                       state->input_mode_mpeg = 1;
-                       break;
-       case 1: /* both ways */
-       case 2: /* only the diversity input */
-                       dprintk("%s ON : Enable diversity INPUT", __func__);
-                       dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
-                       state->input_mode_mpeg = 0;
-                       break;
-       }
-
-       dib8000_set_diversity_in(state->fe[0], onoff);
-       return 0;
-}
-
-static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 outreg, smo_mode, fifo_threshold;
-       u8 prefer_mpeg_mux_use = 1;
-       int ret = 0;
-
-       dib8096p_host_bus_drive(state, 1);
-
-       fifo_threshold = 1792;
-       smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
-       outreg   = dib8000_read_word(state, 1286) &
-               ~((1 << 10) | (0x7 << 6) | (1 << 1));
-
-       switch (mode) {
-       case OUTMODE_HIGH_Z:
-                       outreg = 0;
-                       break;
-
-       case OUTMODE_MPEG2_SERIAL:
-                       if (prefer_mpeg_mux_use) {
-                               dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
-                               dib8096p_configMpegMux(state, 3, 1, 1);
-                               dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
-                       } else {/* Use Smooth block */
-                               dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
-                               dib8096p_setHostBusMux(state,
-                                               DEMOUT_ON_HOSTBUS);
-                               outreg |= (2 << 6) | (0 << 1);
-                       }
-                       break;
-
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-                       if (prefer_mpeg_mux_use) {
-                               dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
-                               dib8096p_configMpegMux(state, 2, 0, 0);
-                               dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
-                       } else { /* Use Smooth block */
-                               dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
-                               dib8096p_setHostBusMux(state,
-                                               DEMOUT_ON_HOSTBUS);
-                               outreg |= (0 << 6);
-                       }
-                       break;
-
-       case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
-                       dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
-                       dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-                       outreg |= (1 << 6);
-                       break;
-
-       case OUTMODE_MPEG2_FIFO:
-                       /* Using Smooth block because not supported
-                          by new Mpeg Mux bloc */
-                       dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
-                       dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
-                       outreg |= (5 << 6);
-                       smo_mode |= (3 << 1);
-                       fifo_threshold = 512;
-                       break;
-
-       case OUTMODE_DIVERSITY:
-                       dprintk("dib8096P setting output mode MODE_DIVERSITY");
-                       dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
-                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-                       break;
-
-       case OUTMODE_ANALOG_ADC:
-                       dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
-                       dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
-                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-                       break;
-       }
-
-       if (mode != OUTMODE_HIGH_Z)
-               outreg |= (1<<10);
-
-       dprintk("output_mpeg2_in_188_bytes = %d",
-                       state->cfg.output_mpeg2_in_188_bytes);
-       if (state->cfg.output_mpeg2_in_188_bytes)
-               smo_mode |= (1 << 5);
-
-       ret |= dib8000_write_word(state, 299, smo_mode);
-       /* synchronous fread */
-       ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
-       ret |= dib8000_write_word(state, 1286, outreg);
-
-       return ret;
-}
-
-static int map_addr_to_serpar_number(struct i2c_msg *msg)
-{
-       if (msg->buf[0] <= 15)
-               msg->buf[0] -= 1;
-       else if (msg->buf[0] == 17)
-               msg->buf[0] = 15;
-       else if (msg->buf[0] == 16)
-               msg->buf[0] = 17;
-       else if (msg->buf[0] == 19)
-               msg->buf[0] = 16;
-       else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
-               msg->buf[0] -= 3;
-       else if (msg->buf[0] == 28)
-               msg->buf[0] = 23;
-       else if (msg->buf[0] == 99)
-               msg->buf[0] = 99;
-       else
-               return -EINVAL;
-       return 0;
-}
-
-static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
-       u8 n_overflow = 1;
-       u16 i = 1000;
-       u16 serpar_num = msg[0].buf[0];
-
-       while (n_overflow == 1 && i) {
-               n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
-               i--;
-               if (i == 0)
-                       dprintk("Tuner ITF: write busy (overflow)");
-       }
-       dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
-       dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
-
-       return num;
-}
-
-static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
-       u8 n_overflow = 1, n_empty = 1;
-       u16 i = 1000;
-       u16 serpar_num = msg[0].buf[0];
-       u16 read_word;
-
-       while (n_overflow == 1 && i) {
-               n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
-               i--;
-               if (i == 0)
-                       dprintk("TunerITF: read busy (overflow)");
-       }
-       dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
-
-       i = 1000;
-       while (n_empty == 1 && i) {
-               n_empty = dib8000_read_word(state, 1984)&0x1;
-               i--;
-               if (i == 0)
-                       dprintk("TunerITF: read busy (empty)");
-       }
-
-       read_word = dib8000_read_word(state, 1987);
-       msg[1].buf[0] = (read_word >> 8) & 0xff;
-       msg[1].buf[1] = (read_word) & 0xff;
-
-       return num;
-}
-
-static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num)
-{
-       if (map_addr_to_serpar_number(&msg[0]) == 0) {
-               if (num == 1) /* write */
-                       return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
-               else /* read */
-                       return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
-       }
-       return num;
-}
-
-static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num, u16 apb_address)
-{
-       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
-       u16 word;
-
-       if (num == 1) {         /* write */
-               dib8000_write_word(state, apb_address,
-                               ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
-       } else {
-               word = dib8000_read_word(state, apb_address);
-               msg[1].buf[0] = (word >> 8) & 0xff;
-               msg[1].buf[1] = (word) & 0xff;
-       }
-       return num;
-}
-
-static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
-               struct i2c_msg msg[], int num)
-{
-       struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
-       u16 apb_address = 0, word;
-       int i = 0;
-
-       switch (msg[0].buf[0]) {
-       case 0x12:
-                       apb_address = 1920;
-                       break;
-       case 0x14:
-                       apb_address = 1921;
-                       break;
-       case 0x24:
-                       apb_address = 1922;
-                       break;
-       case 0x1a:
-                       apb_address = 1923;
-                       break;
-       case 0x22:
-                       apb_address = 1924;
-                       break;
-       case 0x33:
-                       apb_address = 1926;
-                       break;
-       case 0x34:
-                       apb_address = 1927;
-                       break;
-       case 0x35:
-                       apb_address = 1928;
-                       break;
-       case 0x36:
-                       apb_address = 1929;
-                       break;
-       case 0x37:
-                       apb_address = 1930;
-                       break;
-       case 0x38:
-                       apb_address = 1931;
-                       break;
-       case 0x39:
-                       apb_address = 1932;
-                       break;
-       case 0x2a:
-                       apb_address = 1935;
-                       break;
-       case 0x2b:
-                       apb_address = 1936;
-                       break;
-       case 0x2c:
-                       apb_address = 1937;
-                       break;
-       case 0x2d:
-                       apb_address = 1938;
-                       break;
-       case 0x2e:
-                       apb_address = 1939;
-                       break;
-       case 0x2f:
-                       apb_address = 1940;
-                       break;
-       case 0x30:
-                       apb_address = 1941;
-                       break;
-       case 0x31:
-                       apb_address = 1942;
-                       break;
-       case 0x32:
-                       apb_address = 1943;
-                       break;
-       case 0x3e:
-                       apb_address = 1944;
-                       break;
-       case 0x3f:
-                       apb_address = 1945;
-                       break;
-       case 0x40:
-                       apb_address = 1948;
-                       break;
-       case 0x25:
-                       apb_address = 936;
-                       break;
-       case 0x26:
-                       apb_address = 937;
-                       break;
-       case 0x27:
-                       apb_address = 938;
-                       break;
-       case 0x28:
-                       apb_address = 939;
-                       break;
-       case 0x1d:
-                       /* get sad sel request */
-                       i = ((dib8000_read_word(state, 921) >> 12)&0x3);
-                       word = dib8000_read_word(state, 924+i);
-                       msg[1].buf[0] = (word >> 8) & 0xff;
-                       msg[1].buf[1] = (word) & 0xff;
-                       return num;
-       case 0x1f:
-                       if (num == 1) { /* write */
-                               word = (u16) ((msg[0].buf[1] << 8) |
-                                               msg[0].buf[2]);
-                               /* in the VGAMODE Sel are located on bit 0/1 */
-                               word &= 0x3;
-                               word = (dib8000_read_word(state, 921) &
-                                               ~(3<<12)) | (word<<12);
-                               /* Set the proper input */
-                               dib8000_write_word(state, 921, word);
-                               return num;
-                       }
-       }
-
-       if (apb_address != 0) /* R/W acces via APB */
-               return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
-       else  /* R/W access via SERPAR  */
-               return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
-
-       return 0;
-}
-
-static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
-       .master_xfer = dib8096p_tuner_xfer,
-       .functionality = dib8096p_i2c_func,
-};
-
-struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
-{
-       struct dib8000_state *st = fe->demodulator_priv;
-       return &st->dib8096p_tuner_adap;
-}
-EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
-
-int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 en_cur_state;
-
-       dprintk("sleep dib8096p: %d", onoff);
-
-       en_cur_state = dib8000_read_word(state, 1922);
-
-       /* LNAs and MIX are ON and therefore it is a valid configuration */
-       if (en_cur_state > 0xff)
-               state->tuner_enable = en_cur_state ;
-
-       if (onoff)
-               en_cur_state &= 0x00ff;
-       else {
-               if (state->tuner_enable != 0)
-                       en_cur_state = state->tuner_enable;
-       }
-
-       dib8000_write_word(state, 1922, en_cur_state);
-
-       return 0;
-}
-EXPORT_SYMBOL(dib8096p_tuner_sleep);
-
-static const s32 lut_1000ln_mant[] =
-{
-       908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
-};
-
-s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
-       s32 val;
-
-       val = dib8000_read32(state, 384);
-       if (mode) {
-               tmp_val = val;
-               while (tmp_val >>= 1)
-                       exp++;
-               mant = (val * 1000 / (1<<exp));
-               ix = (u8)((mant-1000)/100); /* index of the LUT */
-               val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
-               val = (val*256)/1000;
-       }
-       return val;
-}
-EXPORT_SYMBOL(dib8000_get_adc_power);
-
-int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       int val = 0;
-
-       switch (IQ) {
-       case 1:
-                       val = dib8000_read_word(state, 403);
-                       break;
-       case 0:
-                       val = dib8000_read_word(state, 404);
-                       break;
-       }
-       if (val  & 0x200)
-               val -= 1024;
-
-       return val;
-}
-EXPORT_SYMBOL(dib8090p_get_dc_power);
-
-static void dib8000_update_timf(struct dib8000_state *state)
-{
-       u32 timf = state->timf = dib8000_read32(state, 435);
-
-       dib8000_write_word(state, 29, (u16) (timf >> 16));
-       dib8000_write_word(state, 30, (u16) (timf & 0xffff));
-       dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
-}
-
-u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       switch (op) {
-       case DEMOD_TIMF_SET:
-                       state->timf = timf;
-                       break;
-       case DEMOD_TIMF_UPDATE:
-                       dib8000_update_timf(state);
-                       break;
-       case DEMOD_TIMF_GET:
-                       break;
-       }
-       dib8000_set_bandwidth(state->fe[0], 6000);
-
-       return state->timf;
-}
-EXPORT_SYMBOL(dib8000_ctrl_timf);
-
-static const u16 adc_target_16dB[11] = {
-       (1 << 13) - 825 - 117,
-       (1 << 13) - 837 - 117,
-       (1 << 13) - 811 - 117,
-       (1 << 13) - 766 - 117,
-       (1 << 13) - 737 - 117,
-       (1 << 13) - 693 - 117,
-       (1 << 13) - 648 - 117,
-       (1 << 13) - 619 - 117,
-       (1 << 13) - 575 - 117,
-       (1 << 13) - 531 - 117,
-       (1 << 13) - 501 - 117
-};
-static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
-
-static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
-{
-       u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
-       u8 guard, crate, constellation, timeI;
-       u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;        // All 13 segments enabled
-       const s16 *ncoeff = NULL, *ana_fe;
-       u16 tmcc_pow = 0;
-       u16 coff_pow = 0x2800;
-       u16 init_prbs = 0xfff;
-       u16 ana_gain = 0;
-
-       if (state->revision == 0x8090)
-               dib8000_init_sdram(state);
-
-       if (state->ber_monitored_layer != LAYER_ALL)
-               dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
-       else
-               dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
-
-       i = dib8000_read_word(state, 26) & 1;   // P_dds_invspec
-       dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
-               //compute new dds_freq for the seg and adjust prbs
-               int seg_offset =
-                       state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
-                       (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
-                       (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
-               int clk = state->cfg.pll->internal;
-               u32 segtodds = ((u32) (430 << 23) / clk) << 3;  // segtodds = SegBW / Fclk * pow(2,26)
-               int dds_offset = seg_offset * segtodds;
-               int new_dds, sub_channel;
-               if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
-                       dds_offset -= (int)(segtodds / 2);
-
-               if (state->cfg.pll->ifreq == 0) {
-                       if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
-                               dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
-                               new_dds = dds_offset;
-                       } else
-                               new_dds = dds_offset;
-
-                       // We shift tuning frequency if the wanted segment is :
-                       //  - the segment of center frequency with an odd total number of segments
-                       //  - the segment to the left of center frequency with an even total number of segments
-                       //  - the segment to the right of center frequency with an even total number of segments
-                       if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
-                               && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
-                                       && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
-                                         && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
-                                 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
-                                        || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
-                                                && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
-                                        || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
-                                                && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
-                                                        ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
-                                       )) {
-                               new_dds -= ((u32) (850 << 22) / clk) << 4;      // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
-                       }
-               } else {
-                       if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
-                               new_dds = state->cfg.pll->ifreq - dds_offset;
-                       else
-                               new_dds = state->cfg.pll->ifreq + dds_offset;
-               }
-               dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
-               dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
-               if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
-                       sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
-               else
-                       sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
-               sub_channel -= 6;
-
-               if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
-                               || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
-                       dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);    //adp_pass =1
-                       dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));    //pha3_force_pha_shift = 1
-               } else {
-                       dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
-                       dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
-               }
-
-               switch (state->fe[0]->dtv_property_cache.transmission_mode) {
-               case TRANSMISSION_MODE_2K:
-                       switch (sub_channel) {
-                       case -6:
-                               init_prbs = 0x0;
-                               break;  // 41, 0, 1
-                       case -5:
-                               init_prbs = 0x423;
-                               break;  // 02~04
-                       case -4:
-                               init_prbs = 0x9;
-                               break;  // 05~07
-                       case -3:
-                               init_prbs = 0x5C7;
-                               break;  // 08~10
-                       case -2:
-                               init_prbs = 0x7A6;
-                               break;  // 11~13
-                       case -1:
-                               init_prbs = 0x3D8;
-                               break;  // 14~16
-                       case 0:
-                               init_prbs = 0x527;
-                               break;  // 17~19
-                       case 1:
-                               init_prbs = 0x7FF;
-                               break;  // 20~22
-                       case 2:
-                               init_prbs = 0x79B;
-                               break;  // 23~25
-                       case 3:
-                               init_prbs = 0x3D6;
-                               break;  // 26~28
-                       case 4:
-                               init_prbs = 0x3A2;
-                               break;  // 29~31
-                       case 5:
-                               init_prbs = 0x53B;
-                               break;  // 32~34
-                       case 6:
-                               init_prbs = 0x2F4;
-                               break;  // 35~37
-                       default:
-                       case 7:
-                               init_prbs = 0x213;
-                               break;  // 38~40
-                       }
-                       break;
-
-               case TRANSMISSION_MODE_4K:
-                       switch (sub_channel) {
-                       case -6:
-                               init_prbs = 0x0;
-                               break;  // 41, 0, 1
-                       case -5:
-                               init_prbs = 0x208;
-                               break;  // 02~04
-                       case -4:
-                               init_prbs = 0xC3;
-                               break;  // 05~07
-                       case -3:
-                               init_prbs = 0x7B9;
-                               break;  // 08~10
-                       case -2:
-                               init_prbs = 0x423;
-                               break;  // 11~13
-                       case -1:
-                               init_prbs = 0x5C7;
-                               break;  // 14~16
-                       case 0:
-                               init_prbs = 0x3D8;
-                               break;  // 17~19
-                       case 1:
-                               init_prbs = 0x7FF;
-                               break;  // 20~22
-                       case 2:
-                               init_prbs = 0x3D6;
-                               break;  // 23~25
-                       case 3:
-                               init_prbs = 0x53B;
-                               break;  // 26~28
-                       case 4:
-                               init_prbs = 0x213;
-                               break;  // 29~31
-                       case 5:
-                               init_prbs = 0x29;
-                               break;  // 32~34
-                       case 6:
-                               init_prbs = 0xD0;
-                               break;  // 35~37
-                       default:
-                       case 7:
-                               init_prbs = 0x48E;
-                               break;  // 38~40
-                       }
-                       break;
-
-               default:
-               case TRANSMISSION_MODE_8K:
-                       switch (sub_channel) {
-                       case -6:
-                               init_prbs = 0x0;
-                               break;  // 41, 0, 1
-                       case -5:
-                               init_prbs = 0x740;
-                               break;  // 02~04
-                       case -4:
-                               init_prbs = 0x069;
-                               break;  // 05~07
-                       case -3:
-                               init_prbs = 0x7DD;
-                               break;  // 08~10
-                       case -2:
-                               init_prbs = 0x208;
-                               break;  // 11~13
-                       case -1:
-                               init_prbs = 0x7B9;
-                               break;  // 14~16
-                       case 0:
-                               init_prbs = 0x5C7;
-                               break;  // 17~19
-                       case 1:
-                               init_prbs = 0x7FF;
-                               break;  // 20~22
-                       case 2:
-                               init_prbs = 0x53B;
-                               break;  // 23~25
-                       case 3:
-                               init_prbs = 0x29;
-                               break;  // 26~28
-                       case 4:
-                               init_prbs = 0x48E;
-                               break;  // 29~31
-                       case 5:
-                               init_prbs = 0x4C4;
-                               break;  // 32~34
-                       case 6:
-                               init_prbs = 0x367;
-                               break;  // 33~37
-                       default:
-                       case 7:
-                               init_prbs = 0x684;
-                               break;  // 38~40
-                       }
-                       break;
-               }
-       } else {
-               dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
-               dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
-               dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
-       }
-       /*P_mode == ?? */
-       dib8000_write_word(state, 10, (seq << 4));
-       //  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
-
-       switch (state->fe[0]->dtv_property_cache.guard_interval) {
-       case GUARD_INTERVAL_1_32:
-               guard = 0;
-               break;
-       case GUARD_INTERVAL_1_16:
-               guard = 1;
-               break;
-       case GUARD_INTERVAL_1_8:
-               guard = 2;
-               break;
-       case GUARD_INTERVAL_1_4:
-       default:
-               guard = 3;
-               break;
-       }
-
-       dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
-
-       max_constellation = DQPSK;
-       for (i = 0; i < 3; i++) {
-               switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
-               case DQPSK:
-                       constellation = 0;
-                       break;
-               case QPSK:
-                       constellation = 1;
-                       break;
-               case QAM_16:
-                       constellation = 2;
-                       break;
-               case QAM_64:
-               default:
-                       constellation = 3;
-                       break;
-               }
-
-               switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
-               case FEC_1_2:
-                       crate = 1;
-                       break;
-               case FEC_2_3:
-                       crate = 2;
-                       break;
-               case FEC_3_4:
-                       crate = 3;
-                       break;
-               case FEC_5_6:
-                       crate = 5;
-                       break;
-               case FEC_7_8:
-               default:
-                       crate = 7;
-                       break;
-               }
-
-               if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
-                               ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
-                                (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
-                       )
-                       timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
-               else
-                       timeI = 0;
-               dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
-                                       (crate << 3) | timeI);
-               if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
-                       switch (max_constellation) {
-                       case DQPSK:
-                       case QPSK:
-                               if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
-                                       state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
-                                       max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
-                               break;
-                       case QAM_16:
-                               if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
-                                       max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
-                               break;
-                       }
-               }
-       }
-
-       mode = fft_to_mode(state);
-
-       //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
-
-       dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
-                               ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
-                                                                                                isdbt_sb_mode & 1) << 4));
-
-       dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
-
-       /* signal optimization parameter */
-
-       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
-               seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
-               for (i = 1; i < 3; i++)
-                       nbseg_diff +=
-                               (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
-               for (i = 0; i < nbseg_diff; i++)
-                       seg_diff_mask |= 1 << permu_seg[i + 1];
-       } else {
-               for (i = 0; i < 3; i++)
-                       nbseg_diff +=
-                               (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
-               for (i = 0; i < nbseg_diff; i++)
-                       seg_diff_mask |= 1 << permu_seg[i];
-       }
-       dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
-
-       state->differential_constellation = (seg_diff_mask != 0);
-       if (state->revision != 0x8090)
-               dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
-       else
-               dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
-                       seg_mask13 = 0x00E0;
-               else            // 1-segment
-                       seg_mask13 = 0x0040;
-       } else
-               seg_mask13 = 0x1fff;
-
-       // WRITE: Mode & Diff mask
-       dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
-
-       if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
-               dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
-       else
-               dib8000_write_word(state, 268, (2 << 9) | 39);  //init value
-
-       // ---- SMALL ----
-       // P_small_seg_diff
-       dib8000_write_word(state, 352, seg_diff_mask);  // ADDR 352
-
-       dib8000_write_word(state, 353, seg_mask13);     // ADDR 353
-
-/*     // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
-
-       // ---- SMALL ----
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               switch (state->fe[0]->dtv_property_cache.transmission_mode) {
-               case TRANSMISSION_MODE_2K:
-                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
-                                       ncoeff = coeff_2k_sb_1seg_dqpsk;
-                               else    // QPSK or QAM
-                                       ncoeff = coeff_2k_sb_1seg;
-                       } else {        // 3-segments
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
-                                               ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
-                                       else    // QPSK or QAM on external segments
-                                               ncoeff = coeff_2k_sb_3seg_0dqpsk;
-                               } else {        // QPSK or QAM on central segment
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
-                                               ncoeff = coeff_2k_sb_3seg_1dqpsk;
-                                       else    // QPSK or QAM on external segments
-                                               ncoeff = coeff_2k_sb_3seg;
-                               }
-                       }
-                       break;
-
-               case TRANSMISSION_MODE_4K:
-                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
-                                       ncoeff = coeff_4k_sb_1seg_dqpsk;
-                               else    // QPSK or QAM
-                                       ncoeff = coeff_4k_sb_1seg;
-                       } else {        // 3-segments
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
-                                               ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
-                                       } else {        // QPSK or QAM on external segments
-                                               ncoeff = coeff_4k_sb_3seg_0dqpsk;
-                                       }
-                               } else {        // QPSK or QAM on central segment
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
-                                               ncoeff = coeff_4k_sb_3seg_1dqpsk;
-                                       } else  // QPSK or QAM on external segments
-                                               ncoeff = coeff_4k_sb_3seg;
-                               }
-                       }
-                       break;
-
-               case TRANSMISSION_MODE_AUTO:
-               case TRANSMISSION_MODE_8K:
-               default:
-                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
-                                       ncoeff = coeff_8k_sb_1seg_dqpsk;
-                               else    // QPSK or QAM
-                                       ncoeff = coeff_8k_sb_1seg;
-                       } else {        // 3-segments
-                               if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
-                                               ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
-                                       } else {        // QPSK or QAM on external segments
-                                               ncoeff = coeff_8k_sb_3seg_0dqpsk;
-                                       }
-                               } else {        // QPSK or QAM on central segment
-                                       if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
-                                               ncoeff = coeff_8k_sb_3seg_1dqpsk;
-                                       } else  // QPSK or QAM on external segments
-                                               ncoeff = coeff_8k_sb_3seg;
-                               }
-                       }
-                       break;
-               }
-               for (i = 0; i < 8; i++)
-                       dib8000_write_word(state, 343 + i, ncoeff[i]);
-       }
-
-       // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
-       dib8000_write_word(state, 351,
-                               (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
-
-       // ---- COFF ----
-       // Carloff, the most robust
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-
-               // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
-               // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
-               dib8000_write_word(state, 187,
-                                       (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
-                                       | 0x3);
-
-/*             // P_small_coef_ext_enable = 1 */
-/*             dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
-
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
-
-                       // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
-                       if (mode == 3)
-                               dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
-                       else
-                               dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
-                       // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
-                       // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
-                       dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
-                       // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
-                       dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
-                       // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
-                       dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
-
-                       // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
-                       dib8000_write_word(state, 181, 300);
-                       dib8000_write_word(state, 182, 150);
-                       dib8000_write_word(state, 183, 80);
-                       dib8000_write_word(state, 184, 300);
-                       dib8000_write_word(state, 185, 150);
-                       dib8000_write_word(state, 186, 80);
-               } else {        // Sound Broadcasting mode 3 seg
-                       // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
-                       /*      if (mode == 3) */
-                       /*              dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
-                       /*      else */
-                       /*              dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
-                       dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
-
-                       // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
-                       // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
-                       dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
-                       // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
-                       dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
-                       //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
-                       dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
-
-                       // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
-                       dib8000_write_word(state, 181, 350);
-                       dib8000_write_word(state, 182, 300);
-                       dib8000_write_word(state, 183, 250);
-                       dib8000_write_word(state, 184, 350);
-                       dib8000_write_word(state, 185, 300);
-                       dib8000_write_word(state, 186, 250);
-               }
-
-       } else if (state->isdbt_cfg_loaded == 0) {      // if not Sound Broadcasting mode : put default values for 13 segments
-               dib8000_write_word(state, 180, (16 << 6) | 9);
-               dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
-               coff_pow = 0x2800;
-               for (i = 0; i < 6; i++)
-                       dib8000_write_word(state, 181 + i, coff_pow);
-
-               // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
-               // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
-               dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
-
-               // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
-               dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
-               // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
-               dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
-       }
-       // ---- FFT ----
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
-               dib8000_write_word(state, 178, 64);     // P_fft_powrange=64
-       else
-               dib8000_write_word(state, 178, 32);     // P_fft_powrange=32
-
-       /* make the cpil_coff_lock more robust but slower p_coff_winlen
-        * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
-        */
-       /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
-               dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
-
-       dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);    /* P_lmod4_seg_inh       */
-       dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);    /* P_pha3_seg_inh        */
-       dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);    /* P_tac_seg_inh         */
-       if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
-               dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);     /* P_equal_noise_seg_inh */
-       else
-               dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);    /* P_equal_noise_seg_inh */
-       dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);   /* P_tmcc_seg_inh        */
-       //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
-       if (!autosearching)
-               dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
-       else
-               dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
-       dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
-
-       dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));  /* P_des_seg_enabled     */
-
-       /* offset loop parameters */
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
-                       /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
-                       dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
-
-               else            // Sound Broadcasting mode 3 seg
-                       /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
-                       dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
-       } else
-               // TODO in 13 seg, timf_alpha can always be the same or not ?
-               /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
-               dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
-                       /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (11-P_mode)  */
-                       dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
-
-               else            // Sound Broadcasting mode 3 seg
-                       /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
-                       dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
-       } else
-               /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
-               dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
-
-       /* P_dvsy_sync_wait - reuse mode */
-       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
-       case TRANSMISSION_MODE_8K:
-               mode = 256;
-               break;
-       case TRANSMISSION_MODE_4K:
-               mode = 128;
-               break;
-       default:
-       case TRANSMISSION_MODE_2K:
-               mode = 64;
-               break;
-       }
-       if (state->cfg.diversity_delay == 0)
-               mode = (mode * (1 << (guard)) * 3) / 2 + 48;    // add 50% SFN margin + compensate for one DVSY-fifo
-       else
-               mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay;    // add 50% SFN margin + compensate for DVSY-fifo
-       mode <<= 4;
-       dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
-
-       /* channel estimation fine configuration */
-       switch (max_constellation) {
-       case QAM_64:
-               ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
-               coeff[0] = 0x0148;      /* P_adp_regul_cnt 0.04 */
-               coeff[1] = 0xfff0;      /* P_adp_noise_cnt -0.002 */
-               coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
-               coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.001 */
-               //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
-               break;
-       case QAM_16:
-               ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
-               coeff[0] = 0x023d;      /* P_adp_regul_cnt 0.07 */
-               coeff[1] = 0xffdf;      /* P_adp_noise_cnt -0.004 */
-               coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
-               coeff[3] = 0xfff0;      /* P_adp_noise_ext -0.002 */
-               //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
-               break;
-       default:
-               ana_gain = 0;   // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
-               coeff[0] = 0x099a;      /* P_adp_regul_cnt 0.3 */
-               coeff[1] = 0xffae;      /* P_adp_noise_cnt -0.01 */
-               coeff[2] = 0x0333;      /* P_adp_regul_ext 0.1 */
-               coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.002 */
-               break;
-       }
-       for (mode = 0; mode < 4; mode++)
-               dib8000_write_word(state, 215 + mode, coeff[mode]);
-
-       // update ana_gain depending on max constellation
-       dib8000_write_word(state, 116, ana_gain);
-       // update ADC target depending on ana_gain
-       if (ana_gain) {         // set -16dB ADC target for ana_gain=-1
-               for (i = 0; i < 10; i++)
-                       dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
-       } else {                // set -22dB ADC target for ana_gain=0
-               for (i = 0; i < 10; i++)
-                       dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
-       }
-
-       // ---- ANA_FE ----
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
-                       ana_fe = ana_fe_coeff_3seg;
-               else            // 1-segment
-                       ana_fe = ana_fe_coeff_1seg;
-       } else
-               ana_fe = ana_fe_coeff_13seg;
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
-               for (mode = 0; mode < 24; mode++)
-                       dib8000_write_word(state, 117 + mode, ana_fe[mode]);
-
-       // ---- CHAN_BLK ----
-       for (i = 0; i < 13; i++) {
-               if ((((~seg_diff_mask) >> i) & 1) == 1) {
-                       P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
-                       P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
-               }
-       }
-       dib8000_write_word(state, 222, P_cfr_left_edge);        // P_cfr_left_edge
-       dib8000_write_word(state, 223, P_cfr_right_edge);       // P_cfr_right_edge
-       // "P_cspu_left_edge"  not used => do not care
-       // "P_cspu_right_edge" not used => do not care
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               dib8000_write_word(state, 228, 1);      // P_2d_mode_byp=1
-               dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
-                       && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
-                       //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
-                       dib8000_write_word(state, 265, 15);     // P_equal_noise_sel = 15
-               }
-       } else if (state->isdbt_cfg_loaded == 0) {
-               dib8000_write_word(state, 228, 0);      // default value
-               dib8000_write_word(state, 265, 31);     // default value
-               dib8000_write_word(state, 205, 0x200f); // init value
-       }
-       // ---- TMCC ----
-       for (i = 0; i < 3; i++)
-               tmcc_pow +=
-                       (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
-       // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
-       // Threshold is set at 1/4 of max power.
-       tmcc_pow *= (1 << (9 - 2));
-
-       dib8000_write_word(state, 290, tmcc_pow);       // P_tmcc_dec_thres_2k
-       dib8000_write_word(state, 291, tmcc_pow);       // P_tmcc_dec_thres_4k
-       dib8000_write_word(state, 292, tmcc_pow);       // P_tmcc_dec_thres_8k
-       //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
-       // ---- PHA3 ----
-
-       if (state->isdbt_cfg_loaded == 0)
-               dib8000_write_word(state, 250, 3285);   /*p_2d_hspeed_thr0 */
-
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
-               state->isdbt_cfg_loaded = 0;
-       else
-               state->isdbt_cfg_loaded = 1;
-
-}
-
-static int dib8000_autosearch_start(struct dvb_frontend *fe)
-{
-       u8 factor;
-       u32 value;
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       int slist = 0;
-
-       state->fe[0]->dtv_property_cache.inversion = 0;
-       if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
-               state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
-       state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
-       state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
-       state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
-
-       //choose the right list, in sb, always do everything
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
-               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
-               slist = 7;
-               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
-       } else {
-               if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
-                       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
-                               slist = 7;
-                               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1 to have autosearch start ok with mode2
-                       } else
-                               slist = 3;
-               } else {
-                       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
-                               slist = 2;
-                               dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1
-                       } else
-                               slist = 0;
-               }
-
-               if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
-                       state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
-               if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
-                       state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
-
-               dprintk("using list for autosearch : %d", slist);
-               dib8000_set_channel(state, (unsigned char)slist, 1);
-               //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  // P_mode = 1
-
-               factor = 1;
-
-               //set lock_mask values
-               dib8000_write_word(state, 6, 0x4);
-               dib8000_write_word(state, 7, 0x8);
-               dib8000_write_word(state, 8, 0x1000);
-
-               //set lock_mask wait time values
-               value = 50 * state->cfg.pll->internal * factor;
-               dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff));  // lock0 wait time
-               dib8000_write_word(state, 12, (u16) (value & 0xffff));  // lock0 wait time
-               value = 100 * state->cfg.pll->internal * factor;
-               dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff));  // lock1 wait time
-               dib8000_write_word(state, 14, (u16) (value & 0xffff));  // lock1 wait time
-               value = 1000 * state->cfg.pll->internal * factor;
-               dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff));  // lock2 wait time
-               dib8000_write_word(state, 16, (u16) (value & 0xffff));  // lock2 wait time
-
-               value = dib8000_read_word(state, 0);
-               dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
-               dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
-               dib8000_write_word(state, 0, (u16) value);
-
-       }
-
-       return 0;
-}
-
-static int dib8000_autosearch_irq(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 irq_pending = dib8000_read_word(state, 1284);
-
-       if (irq_pending & 0x1) {        // failed
-               dprintk("dib8000_autosearch_irq failed");
-               return 1;
-       }
-
-       if (irq_pending & 0x2) {        // succeeded
-               dprintk("dib8000_autosearch_irq succeeded");
-               return 2;
-       }
-
-       return 0;               // still pending
-}
-
-static int dib8000_tune(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       int ret = 0;
-       u16 lock, value, mode;
-
-       // we are already tuned - just resuming from suspend
-       if (state == NULL)
-               return -EINVAL;
-
-       mode = fft_to_mode(state);
-
-       dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
-       dib8000_set_channel(state, 0, 0);
-
-       // restart demod
-       ret |= dib8000_write_word(state, 770, 0x4000);
-       ret |= dib8000_write_word(state, 770, 0x0000);
-       msleep(45);
-
-       /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
-       /*  ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) );  workaround inh_isi stays at 1 */
-
-       // never achieved a lock before - wait for timfreq to update
-       if (state->timf == 0) {
-               if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-                       if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
-                               msleep(300);
-                       else    // Sound Broadcasting mode 3 seg
-                               msleep(500);
-               } else          // 13 seg
-                       msleep(200);
-       }
-       if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
-               if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
-
-                       /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40  alpha to check on board */
-                       dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
-                       //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
-
-                       /*  P_ctrl_sfreq_step= (12-P_mode)   P_ctrl_sfreq_inh =0     P_ctrl_pha_off_max  */
-                       ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
-
-               } else {        // Sound Broadcasting mode 3 seg
-
-                       /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60  alpha to check on board */
-                       dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
-
-                       ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
-               }
-
-       } else {                // 13 seg
-               /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80  alpha to check on board */
-               dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
-
-               ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
-
-       }
-
-       // we achieved a coff_cpil_lock - it's time to update the timf
-       if (state->revision != 0x8090)
-               lock = dib8000_read_word(state, 568);
-       else
-               lock = dib8000_read_word(state, 570);
-       if ((lock >> 11) & 0x1)
-               dib8000_update_timf(state);
-
-       //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
-       dib8000_write_word(state, 6, 0x200);
-
-       if (state->revision == 0x8002) {
-               value = dib8000_read_word(state, 903);
-               dib8000_write_word(state, 903, value & ~(1 << 3));
-               msleep(1);
-               dib8000_write_word(state, 903, value | (1 << 3));
-       }
-
-       return ret;
-}
-
-static int dib8000_wakeup(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       int ret;
-
-       dib8000_set_power_mode(state, DIB8000_POWER_ALL);
-       dib8000_set_adc_state(state, DIBX000_ADC_ON);
-       if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
-               dprintk("could not start Slow ADC");
-
-       if (state->revision != 0x8090)
-               dib8000_sad_calib(state);
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int dib8000_sleep(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       int ret;
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (state->revision != 0x8090)
-               dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
-       dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
-       return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
-}
-
-enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       return state->tune_state;
-}
-EXPORT_SYMBOL(dib8000_get_tune_state);
-
-int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       state->tune_state = tune_state;
-       return 0;
-}
-EXPORT_SYMBOL(dib8000_set_tune_state);
-
-static int dib8000_get_frontend(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 i, val = 0;
-       fe_status_t stat;
-       u8 index_frontend, sub_index_frontend;
-
-       fe->dtv_property_cache.bandwidth_hz = 6000000;
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
-               if (stat&FE_HAS_SYNC) {
-                       dprintk("TMCC lock on the slave%i", index_frontend);
-                       /* synchronize the cache with the other frontends */
-                       state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
-                       for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
-                               if (sub_index_frontend != index_frontend) {
-                                       state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
-                                       for (i = 0; i < 3; i++) {
-                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
-                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
-                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
-                                               state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
-                                       }
-                               }
-                       }
-                       return 0;
-               }
-       }
-
-       fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
-
-       if (state->revision == 0x8090)
-               val = dib8000_read_word(state, 572);
-       else
-               val = dib8000_read_word(state, 570);
-       fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
-       switch ((val & 0x30) >> 4) {
-       case 1:
-               fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 3:
-       default:
-               fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       }
-
-       switch (val & 0x3) {
-       case 0:
-               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
-               dprintk("dib8000_get_frontend GI = 1/32 ");
-               break;
-       case 1:
-               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
-               dprintk("dib8000_get_frontend GI = 1/16 ");
-               break;
-       case 2:
-               dprintk("dib8000_get_frontend GI = 1/8 ");
-               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               dprintk("dib8000_get_frontend GI = 1/4 ");
-               fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       val = dib8000_read_word(state, 505);
-       fe->dtv_property_cache.isdbt_partial_reception = val & 1;
-       dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
-
-       for (i = 0; i < 3; i++) {
-               val = dib8000_read_word(state, 493 + i);
-               fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
-               dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
-
-               val = dib8000_read_word(state, 499 + i);
-               fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
-               dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
-
-               val = dib8000_read_word(state, 481 + i);
-               switch (val & 0x7) {
-               case 1:
-                       fe->dtv_property_cache.layer[i].fec = FEC_1_2;
-                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
-                       break;
-               case 2:
-                       fe->dtv_property_cache.layer[i].fec = FEC_2_3;
-                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
-                       break;
-               case 3:
-                       fe->dtv_property_cache.layer[i].fec = FEC_3_4;
-                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
-                       break;
-               case 5:
-                       fe->dtv_property_cache.layer[i].fec = FEC_5_6;
-                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
-                       break;
-               default:
-                       fe->dtv_property_cache.layer[i].fec = FEC_7_8;
-                       dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
-                       break;
-               }
-
-               val = dib8000_read_word(state, 487 + i);
-               switch (val & 0x3) {
-               case 0:
-                       dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
-                       fe->dtv_property_cache.layer[i].modulation = DQPSK;
-                       break;
-               case 1:
-                       fe->dtv_property_cache.layer[i].modulation = QPSK;
-                       dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
-                       break;
-               case 2:
-                       fe->dtv_property_cache.layer[i].modulation = QAM_16;
-                       dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
-                       break;
-               case 3:
-               default:
-                       dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
-                       fe->dtv_property_cache.layer[i].modulation = QAM_64;
-                       break;
-               }
-       }
-
-       /* synchronize the cache with the other frontends */
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
-               state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
-               state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
-               state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
-               state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
-               for (i = 0; i < 3; i++) {
-                       state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
-                       state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
-                       state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
-                       state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
-               }
-       }
-       return 0;
-}
-
-static int dib8000_set_frontend(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 nbr_pending, exit_condition, index_frontend;
-       s8 index_frontend_success = -1;
-       int time, ret;
-       int  time_slave = FE_CALLBACK_TIME_NEVER;
-
-       if (state->fe[0]->dtv_property_cache.frequency == 0) {
-               dprintk("dib8000: must at least specify frequency ");
-               return 0;
-       }
-
-       if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
-               dprintk("dib8000: no bandwidth specified, set to default ");
-               state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
-       }
-
-       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               /* synchronization of the cache */
-               state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
-               memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
-
-               if (state->revision != 0x8090)
-                       dib8000_set_output_mode(state->fe[index_frontend],
-                                       OUTMODE_HIGH_Z);
-               else
-                       dib8096p_set_output_mode(state->fe[index_frontend],
-                                       OUTMODE_HIGH_Z);
-               if (state->fe[index_frontend]->ops.tuner_ops.set_params)
-                       state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
-
-               dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
-       }
-
-       /* start up the AGC */
-       do {
-               time = dib8000_agc_startup(state->fe[0]);
-               for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       time_slave = dib8000_agc_startup(state->fe[index_frontend]);
-                       if (time == FE_CALLBACK_TIME_NEVER)
-                               time = time_slave;
-                       else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
-                               time = time_slave;
-               }
-               if (time != FE_CALLBACK_TIME_NEVER)
-                       msleep(time / 10);
-               else
-                       break;
-               exit_condition = 1;
-               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
-                               exit_condition = 0;
-                               break;
-                       }
-               }
-       } while (exit_condition == 0);
-
-       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
-
-       if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
-                       (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
-                       (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
-                       (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
-                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
-                        (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
-                        (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
-                        ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
-                         (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
-                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
-                        (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
-                        (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
-                        ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
-                         (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
-                       (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
-                        (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
-                        (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
-                        ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
-                         (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
-                       (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
-                         ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
-                        ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
-                         ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
-                        ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
-               int i = 100;
-               u8 found = 0;
-               u8 tune_failed = 0;
-
-               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
-                       dib8000_autosearch_start(state->fe[index_frontend]);
-               }
-
-               do {
-                       msleep(20);
-                       nbr_pending = 0;
-                       exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
-                       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                               if (((tune_failed >> index_frontend) & 0x1) == 0) {
-                                       found = dib8000_autosearch_irq(state->fe[index_frontend]);
-                                       switch (found) {
-                                       case 0: /* tune pending */
-                                                nbr_pending++;
-                                                break;
-                                       case 2:
-                                                dprintk("autosearch succeed on the frontend%i", index_frontend);
-                                                exit_condition = 2;
-                                                index_frontend_success = index_frontend;
-                                                break;
-                                       default:
-                                                dprintk("unhandled autosearch result");
-                                       case 1:
-                                                tune_failed |= (1 << index_frontend);
-                                                dprintk("autosearch failed for the frontend%i", index_frontend);
-                                                break;
-                                       }
-                               }
-                       }
-
-                       /* if all tune are done and no success, exit: tune failed */
-                       if ((nbr_pending == 0) && (exit_condition == 0))
-                               exit_condition = 1;
-               } while ((exit_condition == 0) && i--);
-
-               if (exit_condition == 1) { /* tune failed */
-                       dprintk("tune failed");
-                       return 0;
-               }
-
-               dprintk("tune success on frontend%i", index_frontend_success);
-
-               dib8000_get_frontend(fe);
-       }
-
-       for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               ret = dib8000_tune(state->fe[index_frontend]);
-
-       /* set output mode and diversity input */
-       if (state->revision != 0x8090) {
-               dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
-               for (index_frontend = 1;
-                               (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
-                               (state->fe[index_frontend] != NULL);
-                               index_frontend++) {
-                       dib8000_set_output_mode(state->fe[index_frontend],
-                                       OUTMODE_DIVERSITY);
-                       dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
-               }
-
-               /* turn off the diversity of the last chip */
-               dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
-       } else {
-               dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
-               if (state->cfg.enMpegOutput == 0) {
-                       dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
-                       dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
-               }
-               for (index_frontend = 1;
-                               (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
-                               (state->fe[index_frontend] != NULL);
-                               index_frontend++) {
-                       dib8096p_set_output_mode(state->fe[index_frontend],
-                                       OUTMODE_DIVERSITY);
-                       dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
-               }
-
-               /* turn off the diversity of the last chip */
-               dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
-       }
-
-       return ret;
-}
-
-static u16 dib8000_read_lock(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       if (state->revision == 0x8090)
-               return dib8000_read_word(state, 570);
-       return dib8000_read_word(state, 568);
-}
-
-static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u16 lock_slave = 0, lock;
-       u8 index_frontend;
-
-       if (state->revision == 0x8090)
-               lock = dib8000_read_word(state, 570);
-       else
-               lock = dib8000_read_word(state, 568);
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
-
-       *stat = 0;
-
-       if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
-               *stat |= FE_HAS_SIGNAL;
-
-       if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
-               *stat |= FE_HAS_CARRIER;
-
-       if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
-               *stat |= FE_HAS_SYNC;
-
-       if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
-               *stat |= FE_HAS_LOCK;
-
-       if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
-               lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
-               if (lock & 0x01)
-                       *stat |= FE_HAS_VITERBI;
-
-               lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
-               if (lock & 0x01)
-                       *stat |= FE_HAS_VITERBI;
-
-               lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
-               if (lock & 0x01)
-                       *stat |= FE_HAS_VITERBI;
-       }
-
-       return 0;
-}
-
-static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       /* 13 segments */
-       if (state->revision == 0x8090)
-               *ber = (dib8000_read_word(state, 562) << 16) |
-                       dib8000_read_word(state, 563);
-       else
-               *ber = (dib8000_read_word(state, 560) << 16) |
-                       dib8000_read_word(state, 561);
-       return 0;
-}
-
-static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       /* packet error on 13 seg */
-       if (state->revision == 0x8090)
-               *unc = dib8000_read_word(state, 567);
-       else
-               *unc = dib8000_read_word(state, 565);
-       return 0;
-}
-
-static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       u16 val;
-
-       *strength = 0;
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
-               if (val > 65535 - *strength)
-                       *strength = 65535;
-               else
-                       *strength += val;
-       }
-
-       val = 65535 - dib8000_read_word(state, 390);
-       if (val > 65535 - *strength)
-               *strength = 65535;
-       else
-               *strength += val;
-       return 0;
-}
-
-static u32 dib8000_get_snr(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u32 n, s, exp;
-       u16 val;
-
-       if (state->revision != 0x8090)
-               val = dib8000_read_word(state, 542);
-       else
-               val = dib8000_read_word(state, 544);
-       n = (val >> 6) & 0xff;
-       exp = (val & 0x3f);
-       if ((exp & 0x20) != 0)
-               exp -= 0x40;
-       n <<= exp+16;
-
-       if (state->revision != 0x8090)
-               val = dib8000_read_word(state, 543);
-       else
-               val = dib8000_read_word(state, 545);
-       s = (val >> 6) & 0xff;
-       exp = (val & 0x3f);
-       if ((exp & 0x20) != 0)
-               exp -= 0x40;
-       s <<= exp+16;
-
-       if (n > 0) {
-               u32 t = (s/n) << 16;
-               return t + ((s << 16) - n*t) / n;
-       }
-       return 0xffffffff;
-}
-
-static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       u32 snr_master;
-
-       snr_master = dib8000_get_snr(fe);
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               snr_master += dib8000_get_snr(state->fe[index_frontend]);
-
-       if ((snr_master >> 16) != 0) {
-               snr_master = 10*intlog10(snr_master>>16);
-               *snr = snr_master / ((1 << 24) / 10);
-       }
-       else
-               *snr = 0;
-
-       return 0;
-}
-
-int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend = 1;
-
-       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
-               index_frontend++;
-       if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
-               dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
-               state->fe[index_frontend] = fe_slave;
-               return 0;
-       }
-
-       dprintk("too many slave frontend");
-       return -ENOMEM;
-}
-EXPORT_SYMBOL(dib8000_set_slave_frontend);
-
-int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-       u8 index_frontend = 1;
-
-       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
-               index_frontend++;
-       if (index_frontend != 1) {
-               dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
-               state->fe[index_frontend] = NULL;
-               return 0;
-       }
-
-       dprintk("no frontend to be removed");
-       return -ENODEV;
-}
-EXPORT_SYMBOL(dib8000_remove_slave_frontend);
-
-struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
-{
-       struct dib8000_state *state = fe->demodulator_priv;
-
-       if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
-               return NULL;
-       return state->fe[slave_index];
-}
-EXPORT_SYMBOL(dib8000_get_slave_frontend);
-
-
-int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
-               u8 default_addr, u8 first_addr, u8 is_dib8096p)
-{
-       int k = 0, ret = 0;
-       u8 new_addr = 0;
-       struct i2c_device client = {.adap = host };
-
-       client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-       if (!client.i2c_write_buffer) {
-               dprintk("%s: not enough memory", __func__);
-               return -ENOMEM;
-       }
-       client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-       if (!client.i2c_read_buffer) {
-               dprintk("%s: not enough memory", __func__);
-               ret = -ENOMEM;
-               goto error_memory_read;
-       }
-       client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
-       if (!client.i2c_buffer_lock) {
-               dprintk("%s: not enough memory", __func__);
-               ret = -ENOMEM;
-               goto error_memory_lock;
-       }
-       mutex_init(client.i2c_buffer_lock);
-
-       for (k = no_of_demods - 1; k >= 0; k--) {
-               /* designated i2c address */
-               new_addr = first_addr + (k << 1);
-
-               client.addr = new_addr;
-               if (!is_dib8096p)
-                       dib8000_i2c_write16(&client, 1287, 0x0003);     /* sram lead in, rdy */
-               if (dib8000_identify(&client) == 0) {
-                       /* sram lead in, rdy */
-                       if (!is_dib8096p)
-                               dib8000_i2c_write16(&client, 1287, 0x0003);
-                       client.addr = default_addr;
-                       if (dib8000_identify(&client) == 0) {
-                               dprintk("#%d: not identified", k);
-                               ret  = -EINVAL;
-                               goto error;
-                       }
-               }
-
-               /* start diversity to pull_down div_str - just for i2c-enumeration */
-               dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
-
-               /* set new i2c address and force divstart */
-               dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
-               client.addr = new_addr;
-               dib8000_identify(&client);
-
-               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               new_addr = first_addr | (k << 1);
-               client.addr = new_addr;
-
-               // unforce divstr
-               dib8000_i2c_write16(&client, 1285, new_addr << 2);
-
-               /* deactivate div - it was just for i2c-enumeration */
-               dib8000_i2c_write16(&client, 1286, 0);
-       }
-
-error:
-       kfree(client.i2c_buffer_lock);
-error_memory_lock:
-       kfree(client.i2c_read_buffer);
-error_memory_read:
-       kfree(client.i2c_write_buffer);
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dib8000_i2c_enumeration);
-static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       tune->step_size = 0;
-       tune->max_drift = 0;
-       return 0;
-}
-
-static void dib8000_release(struct dvb_frontend *fe)
-{
-       struct dib8000_state *st = fe->demodulator_priv;
-       u8 index_frontend;
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
-               dvb_frontend_detach(st->fe[index_frontend]);
-
-       dibx000_exit_i2c_master(&st->i2c_master);
-       i2c_del_adapter(&st->dib8096p_tuner_adap);
-       kfree(st->fe[0]);
-       kfree(st);
-}
-
-struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
-{
-       struct dib8000_state *st = fe->demodulator_priv;
-       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
-}
-
-EXPORT_SYMBOL(dib8000_get_i2c_master);
-
-int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       struct dib8000_state *st = fe->demodulator_priv;
-       u16 val = dib8000_read_word(st, 299) & 0xffef;
-       val |= (onoff & 0x1) << 4;
-
-       dprintk("pid filter enabled %d", onoff);
-       return dib8000_write_word(st, 299, val);
-}
-EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
-
-int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       struct dib8000_state *st = fe->demodulator_priv;
-       dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
-       return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
-}
-EXPORT_SYMBOL(dib8000_pid_filter);
-
-static const struct dvb_frontend_ops dib8000_ops = {
-       .delsys = { SYS_ISDBT },
-       .info = {
-                .name = "DiBcom 8000 ISDB-T",
-                .frequency_min = 44250000,
-                .frequency_max = 867250000,
-                .frequency_stepsize = 62500,
-                .caps = FE_CAN_INVERSION_AUTO |
-                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
-                },
-
-       .release = dib8000_release,
-
-       .init = dib8000_wakeup,
-       .sleep = dib8000_sleep,
-
-       .set_frontend = dib8000_set_frontend,
-       .get_tune_settings = dib8000_fe_get_tune_settings,
-       .get_frontend = dib8000_get_frontend,
-
-       .read_status = dib8000_read_status,
-       .read_ber = dib8000_read_ber,
-       .read_signal_strength = dib8000_read_signal_strength,
-       .read_snr = dib8000_read_snr,
-       .read_ucblocks = dib8000_read_unc_blocks,
-};
-
-struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
-{
-       struct dvb_frontend *fe;
-       struct dib8000_state *state;
-
-       dprintk("dib8000_attach");
-
-       state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-       fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
-       if (fe == NULL)
-               goto error;
-
-       memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
-       state->i2c.adap = i2c_adap;
-       state->i2c.addr = i2c_addr;
-       state->i2c.i2c_write_buffer = state->i2c_write_buffer;
-       state->i2c.i2c_read_buffer = state->i2c_read_buffer;
-       mutex_init(&state->i2c_buffer_lock);
-       state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
-       state->gpio_val = cfg->gpio_val;
-       state->gpio_dir = cfg->gpio_dir;
-
-       /* Ensure the output mode remains at the previous default if it's
-        * not specifically set by the caller.
-        */
-       if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
-               state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
-
-       state->fe[0] = fe;
-       fe->demodulator_priv = state;
-       memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
-
-       state->timf_default = cfg->pll->timf;
-
-       if (dib8000_identify(&state->i2c) == 0)
-               goto error;
-
-       dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
-
-       /* init 8096p tuner adapter */
-       strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
-                       sizeof(state->dib8096p_tuner_adap.name));
-       state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
-       state->dib8096p_tuner_adap.algo_data = NULL;
-       state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
-       i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
-       i2c_add_adapter(&state->dib8096p_tuner_adap);
-
-       dib8000_reset(fe);
-
-       dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));     /* ber_rs_len = 3 */
-
-       return fe;
-
- error:
-       kfree(state);
-       return NULL;
-}
-
-EXPORT_SYMBOL(dib8000_attach);
-
-MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
deleted file mode 100644 (file)
index 39591bb..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-#ifndef DIB8000_H
-#define DIB8000_H
-
-#include "dibx000_common.h"
-
-struct dib8000_config {
-       u8 output_mpeg2_in_188_bytes;
-       u8 hostbus_diversity;
-       u8 tuner_is_baseband;
-       int (*update_lna) (struct dvb_frontend *, u16 agc_global);
-
-       u8 agc_config_count;
-       struct dibx000_agc_config *agc;
-       struct dibx000_bandwidth_config *pll;
-
-#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
-       u16 gpio_dir;
-#define DIB8000_GPIO_DEFAULT_VALUES     0x0000
-       u16 gpio_val;
-#define DIB8000_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
-#define DIB8000_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
-#define DIB8000_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
-#define DIB8000_GPIO_PWM_POS3(v)         (v & 0xf)
-#define DIB8000_GPIO_DEFAULT_PWM_POS    0xffff
-       u16 gpio_pwm_pos;
-       u16 pwm_freq_div;
-
-       void (*agc_control) (struct dvb_frontend *, u8 before);
-
-       u16 drives;
-       u16 diversity_delay;
-       u8 div_cfg;
-       u8 output_mode;
-       u8 refclksel;
-       u8 enMpegOutput:1;
-};
-
-#define DEFAULT_DIB8000_I2C_ADDRESS 18
-
-#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
-extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
-
-extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
-               u8 default_addr, u8 first_addr, u8 is_dib8096p);
-
-extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
-extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
-extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
-extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
-extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
-extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
-extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
-extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
-extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
-extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
-extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
-               uint8_t op, uint32_t timf);
-extern int dib8000_update_pll(struct dvb_frontend *fe,
-               struct dibx000_bandwidth_config *pll);
-extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
-extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
-extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
-#else
-static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
-               int no_of_demods, u8 default_addr, u8 first_addr,
-               u8 is_dib8096p)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return CT_SHUTDOWN;
-}
-static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
-               uint8_t op, uint32_t timf)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return 0;
-}
-static inline int dib8000_update_pll(struct dvb_frontend *fe,
-               struct dibx000_bandwidth_config *pll)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
deleted file mode 100644 (file)
index 6201c59..0000000
+++ /dev/null
@@ -1,2590 +0,0 @@
-/*
- * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
- *
- * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
- *
- * This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2.
- */
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#include "dvb_math.h"
-#include "dvb_frontend.h"
-
-#include "dib9000.h"
-#include "dibx000_common.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0)
-#define MAX_NUMBER_OF_FRONTENDS 6
-
-struct i2c_device {
-       struct i2c_adapter *i2c_adap;
-       u8 i2c_addr;
-       u8 *i2c_read_buffer;
-       u8 *i2c_write_buffer;
-};
-
-struct dib9000_pid_ctrl {
-#define DIB9000_PID_FILTER_CTRL 0
-#define DIB9000_PID_FILTER      1
-       u8 cmd;
-       u8 id;
-       u16 pid;
-       u8 onoff;
-};
-
-struct dib9000_state {
-       struct i2c_device i2c;
-
-       struct dibx000_i2c_master i2c_master;
-       struct i2c_adapter tuner_adap;
-       struct i2c_adapter component_bus;
-
-       u16 revision;
-       u8 reg_offs;
-
-       enum frontend_tune_state tune_state;
-       u32 status;
-       struct dvb_frontend_parametersContext channel_status;
-
-       u8 fe_id;
-
-#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
-       u16 gpio_dir;
-#define DIB9000_GPIO_DEFAULT_VALUES     0x0000
-       u16 gpio_val;
-#define DIB9000_GPIO_DEFAULT_PWM_POS    0xffff
-       u16 gpio_pwm_pos;
-
-       union {                 /* common for all chips */
-               struct {
-                       u8 mobile_mode:1;
-               } host;
-
-               struct {
-                       struct dib9000_fe_memory_map {
-                               u16 addr;
-                               u16 size;
-                       } fe_mm[18];
-                       u8 memcmd;
-
-                       struct mutex mbx_if_lock;       /* to protect read/write operations */
-                       struct mutex mbx_lock;  /* to protect the whole mailbox handling */
-
-                       struct mutex mem_lock;  /* to protect the memory accesses */
-                       struct mutex mem_mbx_lock;      /* to protect the memory-based mailbox */
-
-#define MBX_MAX_WORDS (256 - 200 - 2)
-#define DIB9000_MSG_CACHE_SIZE 2
-                       u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
-                       u8 fw_is_running;
-               } risc;
-       } platform;
-
-       union {                 /* common for all platforms */
-               struct {
-                       struct dib9000_config cfg;
-               } d9;
-       } chip;
-
-       struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
-       u16 component_bus_speed;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[2];
-       u8 i2c_write_buffer[255];
-       u8 i2c_read_buffer[255];
-       struct mutex demod_lock;
-       u8 get_frontend_internal;
-       struct dib9000_pid_ctrl pid_ctrl[10];
-       s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
-};
-
-static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0
-};
-
-enum dib9000_power_mode {
-       DIB9000_POWER_ALL = 0,
-
-       DIB9000_POWER_NO,
-       DIB9000_POWER_INTERF_ANALOG_AGC,
-       DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
-       DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
-       DIB9000_POWER_INTERFACE_ONLY,
-};
-
-enum dib9000_out_messages {
-       OUT_MSG_HBM_ACK,
-       OUT_MSG_HOST_BUF_FAIL,
-       OUT_MSG_REQ_VERSION,
-       OUT_MSG_BRIDGE_I2C_W,
-       OUT_MSG_BRIDGE_I2C_R,
-       OUT_MSG_BRIDGE_APB_W,
-       OUT_MSG_BRIDGE_APB_R,
-       OUT_MSG_SCAN_CHANNEL,
-       OUT_MSG_MONIT_DEMOD,
-       OUT_MSG_CONF_GPIO,
-       OUT_MSG_DEBUG_HELP,
-       OUT_MSG_SUBBAND_SEL,
-       OUT_MSG_ENABLE_TIME_SLICE,
-       OUT_MSG_FE_FW_DL,
-       OUT_MSG_FE_CHANNEL_SEARCH,
-       OUT_MSG_FE_CHANNEL_TUNE,
-       OUT_MSG_FE_SLEEP,
-       OUT_MSG_FE_SYNC,
-       OUT_MSG_CTL_MONIT,
-
-       OUT_MSG_CONF_SVC,
-       OUT_MSG_SET_HBM,
-       OUT_MSG_INIT_DEMOD,
-       OUT_MSG_ENABLE_DIVERSITY,
-       OUT_MSG_SET_OUTPUT_MODE,
-       OUT_MSG_SET_PRIORITARY_CHANNEL,
-       OUT_MSG_ACK_FRG,
-       OUT_MSG_INIT_PMU,
-};
-
-enum dib9000_in_messages {
-       IN_MSG_DATA,
-       IN_MSG_FRAME_INFO,
-       IN_MSG_CTL_MONIT,
-       IN_MSG_ACK_FREE_ITEM,
-       IN_MSG_DEBUG_BUF,
-       IN_MSG_MPE_MONITOR,
-       IN_MSG_RAWTS_MONITOR,
-       IN_MSG_END_BRIDGE_I2C_RW,
-       IN_MSG_END_BRIDGE_APB_RW,
-       IN_MSG_VERSION,
-       IN_MSG_END_OF_SCAN,
-       IN_MSG_MONIT_DEMOD,
-       IN_MSG_ERROR,
-       IN_MSG_FE_FW_DL_DONE,
-       IN_MSG_EVENT,
-       IN_MSG_ACK_CHANGE_SVC,
-       IN_MSG_HBM_PROF,
-};
-
-/* memory_access requests */
-#define FE_MM_W_CHANNEL                   0
-#define FE_MM_W_FE_INFO                   1
-#define FE_MM_RW_SYNC                     2
-
-#define FE_SYNC_CHANNEL          1
-#define FE_SYNC_W_GENERIC_MONIT         2
-#define FE_SYNC_COMPONENT_ACCESS 3
-
-#define FE_MM_R_CHANNEL_SEARCH_STATE      3
-#define FE_MM_R_CHANNEL_UNION_CONTEXT     4
-#define FE_MM_R_FE_INFO                   5
-#define FE_MM_R_FE_MONITOR                6
-
-#define FE_MM_W_CHANNEL_HEAD              7
-#define FE_MM_W_CHANNEL_UNION             8
-#define FE_MM_W_CHANNEL_CONTEXT           9
-#define FE_MM_R_CHANNEL_UNION            10
-#define FE_MM_R_CHANNEL_CONTEXT          11
-#define FE_MM_R_CHANNEL_TUNE_STATE       12
-
-#define FE_MM_R_GENERIC_MONITORING_SIZE         13
-#define FE_MM_W_GENERIC_MONITORING          14
-#define FE_MM_R_GENERIC_MONITORING          15
-
-#define FE_MM_W_COMPONENT_ACCESS         16
-#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
-static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
-static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
-
-static u16 to_fw_output_mode(u16 mode)
-{
-       switch (mode) {
-       case OUTMODE_HIGH_Z:
-               return 0;
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-               return 4;
-       case OUTMODE_MPEG2_PAR_CONT_CLK:
-               return 8;
-       case OUTMODE_MPEG2_SERIAL:
-               return 16;
-       case OUTMODE_DIVERSITY:
-               return 128;
-       case OUTMODE_MPEG2_FIFO:
-               return 2;
-       case OUTMODE_ANALOG_ADC:
-               return 1;
-       default:
-               return 0;
-       }
-}
-
-static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 len, u16 attribute)
-{
-       u32 chunk_size = 126;
-       u32 l;
-       int ret;
-
-       if (state->platform.risc.fw_is_running && (reg < 1024))
-               return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
-
-       memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c.i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = 2;
-       state->msg[1].addr = state->i2c.i2c_addr >> 1;
-       state->msg[1].flags = I2C_M_RD;
-       state->msg[1].buf = b;
-       state->msg[1].len = len;
-
-       state->i2c_write_buffer[0] = reg >> 8;
-       state->i2c_write_buffer[1] = reg & 0xff;
-
-       if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-               state->i2c_write_buffer[0] |= (1 << 5);
-       if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-               state->i2c_write_buffer[0] |= (1 << 4);
-
-       do {
-               l = len < chunk_size ? len : chunk_size;
-               state->msg[1].len = l;
-               state->msg[1].buf = b;
-               ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
-               if (ret != 0) {
-                       dprintk("i2c read error on %d", reg);
-                       return -EREMOTEIO;
-               }
-
-               b += l;
-               len -= l;
-
-               if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
-                       reg += l / 2;
-       } while ((ret == 0) && len);
-
-       return 0;
-}
-
-static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
-{
-       struct i2c_msg msg[2] = {
-               {.addr = i2c->i2c_addr >> 1, .flags = 0,
-                       .buf = i2c->i2c_write_buffer, .len = 2},
-               {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
-                       .buf = i2c->i2c_read_buffer, .len = 2},
-       };
-
-       i2c->i2c_write_buffer[0] = reg >> 8;
-       i2c->i2c_write_buffer[1] = reg & 0xff;
-
-       if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
-               dprintk("read register %x error", reg);
-               return 0;
-       }
-
-       return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
-}
-
-static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
-{
-       if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
-               return 0;
-       return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
-}
-
-static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
-{
-       if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
-                               attribute) != 0)
-               return 0;
-       return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
-}
-
-#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-
-static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
-{
-       u32 chunk_size = 126;
-       u32 l;
-       int ret;
-
-       if (state->platform.risc.fw_is_running && (reg < 1024)) {
-               if (dib9000_risc_apb_access_write
-                   (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
-                       return -EINVAL;
-               return 0;
-       }
-
-       memset(&state->msg[0], 0, sizeof(struct i2c_msg));
-       state->msg[0].addr = state->i2c.i2c_addr >> 1;
-       state->msg[0].flags = 0;
-       state->msg[0].buf = state->i2c_write_buffer;
-       state->msg[0].len = len + 2;
-
-       state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       state->i2c_write_buffer[1] = (reg) & 0xff;
-
-       if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-               state->i2c_write_buffer[0] |= (1 << 5);
-       if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-               state->i2c_write_buffer[0] |= (1 << 4);
-
-       do {
-               l = len < chunk_size ? len : chunk_size;
-               state->msg[0].len = l + 2;
-               memcpy(&state->i2c_write_buffer[2], buf, l);
-
-               ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
-
-               buf += l;
-               len -= l;
-
-               if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
-                       reg += l / 2;
-       } while ((ret == 0) && len);
-
-       return ret;
-}
-
-static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
-{
-       struct i2c_msg msg = {
-               .addr = i2c->i2c_addr >> 1, .flags = 0,
-               .buf = i2c->i2c_write_buffer, .len = 4
-       };
-
-       i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       i2c->i2c_write_buffer[1] = reg & 0xff;
-       i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
-       i2c->i2c_write_buffer[3] = val & 0xff;
-
-       return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
-}
-
-static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
-{
-       u8 b[2] = { val >> 8, val & 0xff };
-       return dib9000_write16_attr(state, reg, b, 2, 0);
-}
-
-static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
-{
-       u8 b[2] = { val >> 8, val & 0xff };
-       return dib9000_write16_attr(state, reg, b, 2, attribute);
-}
-
-#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
-#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
-
-#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
-#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
-
-#define MAC_IRQ      (1 << 1)
-#define IRQ_POL_MSK  (1 << 4)
-
-#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-
-static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
-{
-       u8 b[14] = { 0 };
-
-/*      dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
-/*      b[0] = 0 << 7; */
-       b[1] = 1;
-
-/*      b[2] = 0; */
-/*      b[3] = 0; */
-       b[4] = (u8) (addr >> 8);
-       b[5] = (u8) (addr & 0xff);
-
-/*      b[10] = 0; */
-/*      b[11] = 0; */
-       b[12] = (u8) (addr >> 8);
-       b[13] = (u8) (addr & 0xff);
-
-       addr += len;
-/*      b[6] = 0; */
-/*      b[7] = 0; */
-       b[8] = (u8) (addr >> 8);
-       b[9] = (u8) (addr & 0xff);
-
-       dib9000_write(state, 1056, b, 14);
-       if (reading)
-               dib9000_write_word(state, 1056, (1 << 15) | 1);
-       state->platform.risc.memcmd = -1;       /* if it was called directly reset it - to force a future setup-call to set it */
-}
-
-static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
-{
-       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
-       /* decide whether we need to "refresh" the memory controller */
-       if (state->platform.risc.memcmd == cmd &&       /* same command */
-           !(cmd & 0x80 && m->size < 67))      /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
-               return;
-       dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
-       state->platform.risc.memcmd = cmd;
-}
-
-static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
-{
-       if (!state->platform.risc.fw_is_running)
-               return -EIO;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       dib9000_risc_mem_setup(state, cmd | 0x80);
-       dib9000_risc_mem_read_chunks(state, b, len);
-       mutex_unlock(&state->platform.risc.mem_lock);
-       return 0;
-}
-
-static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
-{
-       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
-       if (!state->platform.risc.fw_is_running)
-               return -EIO;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       dib9000_risc_mem_setup(state, cmd);
-       dib9000_risc_mem_write_chunks(state, b, m->size);
-       mutex_unlock(&state->platform.risc.mem_lock);
-       return 0;
-}
-
-static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
-{
-       u16 offs;
-
-       if (risc_id == 1)
-               offs = 16;
-       else
-               offs = 0;
-
-       /* config crtl reg */
-       dib9000_write_word(state, 1024 + offs, 0x000f);
-       dib9000_write_word(state, 1025 + offs, 0);
-       dib9000_write_word(state, 1031 + offs, key);
-
-       dprintk("going to download %dB of microcode", len);
-       if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
-               dprintk("error while downloading microcode for RISC %c", 'A' + risc_id);
-               return -EIO;
-       }
-
-       dprintk("Microcode for RISC %c loaded", 'A' + risc_id);
-
-       return 0;
-}
-
-static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
-{
-       u16 mbox_offs;
-       u16 reset_reg;
-       u16 tries = 1000;
-
-       if (risc_id == 1)
-               mbox_offs = 16;
-       else
-               mbox_offs = 0;
-
-       /* Reset mailbox  */
-       dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
-
-       /* Read reset status */
-       do {
-               reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
-               msleep(100);
-       } while ((reset_reg & 0x8000) && --tries);
-
-       if (reset_reg & 0x8000) {
-               dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id);
-               return -EIO;
-       }
-       dprintk("MBX: initialized");
-       return 0;
-}
-
-#define MAX_MAILBOX_TRY 100
-static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
-{
-       u8 *d, b[2];
-       u16 tmp;
-       u16 size;
-       u32 i;
-       int ret = 0;
-
-       if (!state->platform.risc.fw_is_running)
-               return -EINVAL;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       tmp = MAX_MAILBOX_TRY;
-       do {
-               size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
-               if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
-                       dprintk("MBX: RISC mbx full, retrying");
-                       msleep(100);
-               } else
-                       break;
-       } while (1);
-
-       /*dprintk( "MBX: size: %d", size); */
-
-       if (tmp == 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-#ifdef DUMP_MSG
-       dprintk("--> %02x %d ", id, len + 1);
-       for (i = 0; i < len; i++)
-               dprintk("%04x ", data[i]);
-       dprintk("\n");
-#endif
-
-       /* byte-order conversion - works on big (where it is not necessary) or little endian */
-       d = (u8 *) data;
-       for (i = 0; i < len; i++) {
-               tmp = data[i];
-               *d++ = tmp >> 8;
-               *d++ = tmp & 0xff;
-       }
-
-       /* write msg */
-       b[0] = id;
-       b[1] = len + 1;
-       if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
-               ret = -EIO;
-               goto out;
-       }
-
-       /* update register nb_mes_in_RX */
-       ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
-
-out:
-       mutex_unlock(&state->platform.risc.mbx_if_lock);
-
-       return ret;
-}
-
-static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
-{
-#ifdef DUMP_MSG
-       u16 *d = data;
-#endif
-
-       u16 tmp, i;
-       u8 size;
-       u8 mc_base;
-
-       if (!state->platform.risc.fw_is_running)
-               return 0;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
-               dprintk("could not get the lock");
-               return 0;
-       }
-       if (risc_id == 1)
-               mc_base = 16;
-       else
-               mc_base = 0;
-
-       /* Length and type in the first word */
-       *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
-
-       size = *data & 0xff;
-       if (size <= MBX_MAX_WORDS) {
-               data++;
-               size--;         /* Initial word already read */
-
-               dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
-
-               /* to word conversion */
-               for (i = 0; i < size; i++) {
-                       tmp = *data;
-                       *data = (tmp >> 8) | (tmp << 8);
-                       data++;
-               }
-
-#ifdef DUMP_MSG
-               dprintk("<-- ");
-               for (i = 0; i < size + 1; i++)
-                       dprintk("%04x ", d[i]);
-               dprintk("\n");
-#endif
-       } else {
-               dprintk("MBX: message is too big for message cache (%d), flushing message", size);
-               size--;         /* Initial word already read */
-               while (size--)
-                       dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
-       }
-       /* Update register nb_mes_in_TX */
-       dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
-
-       mutex_unlock(&state->platform.risc.mbx_if_lock);
-
-       return size + 1;
-}
-
-static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
-{
-       u32 ts = data[1] << 16 | data[0];
-       char *b = (char *)&data[2];
-
-       b[2 * (size - 2) - 1] = '\0';   /* Bullet proof the buffer */
-       if (*b == '~') {
-               b++;
-               dprintk(b);
-       } else
-               dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>");
-       return 1;
-}
-
-static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
-{
-       int i;
-       u8 size;
-       u16 *block;
-       /* find a free slot */
-       for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
-               block = state->platform.risc.message_cache[i];
-               if (*block == 0) {
-                       size = dib9000_mbx_read(state, block, 1, attr);
-
-/*                      dprintk( "MBX: fetched %04x message to cache", *block); */
-
-                       switch (*block >> 8) {
-                       case IN_MSG_DEBUG_BUF:
-                               dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
-                               *block = 0;     /* free the block */
-                               break;
-#if 0
-                       case IN_MSG_DATA:       /* FE-TRACE */
-                               dib9000_risc_data_process(state, block + 1, size);
-                               *block = 0;
-                               break;
-#endif
-                       default:
-                               break;
-                       }
-
-                       return 1;
-               }
-       }
-       dprintk("MBX: no free cache-slot found for new message...");
-       return -1;
-}
-
-static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
-{
-       if (risc_id == 0)
-               return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f;   /* 5 bit field */
-       else
-               return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f;    /* 7 bit field */
-}
-
-static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
-{
-       int ret = 0;
-
-       if (!state->platform.risc.fw_is_running)
-               return -1;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               return -1;
-       }
-
-       if (dib9000_mbx_count(state, 1, attr))  /* 1=RiscB */
-               ret = dib9000_mbx_fetch_to_cache(state, attr);
-
-       dib9000_read_word_attr(state, 1229, attr);      /* Clear the IRQ */
-/*      if (tmp) */
-/*              dprintk( "cleared IRQ: %x", tmp); */
-       mutex_unlock(&state->platform.risc.mbx_lock);
-
-       return ret;
-}
-
-static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
-{
-       u8 i;
-       u16 *block;
-       u16 timeout = 30;
-
-       *msg = 0;
-       do {
-               /* dib9000_mbx_get_from_cache(); */
-               for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
-                       block = state->platform.risc.message_cache[i];
-                       if ((*block >> 8) == id) {
-                               *size = (*block & 0xff) - 1;
-                               memcpy(msg, block + 1, (*size) * 2);
-                               *block = 0;     /* free the block */
-                               i = 0;  /* signal that we found a message */
-                               break;
-                       }
-               }
-
-               if (i == 0)
-                       break;
-
-               if (dib9000_mbx_process(state, attr) == -1)     /* try to fetch one message - if any */
-                       return -1;
-
-       } while (--timeout);
-
-       if (timeout == 0) {
-               dprintk("waiting for message %d timed out", id);
-               return -1;
-       }
-
-       return i == 0;
-}
-
-static int dib9000_risc_check_version(struct dib9000_state *state)
-{
-       u8 r[4];
-       u8 size;
-       u16 fw_version = 0;
-
-       if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
-               return -EIO;
-
-       if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
-               return -EIO;
-
-       fw_version = (r[0] << 8) | r[1];
-       dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
-
-       if ((fw_version >> 10) != 7)
-               return -EINVAL;
-
-       switch (fw_version & 0x3ff) {
-       case 11:
-       case 12:
-       case 14:
-       case 15:
-       case 16:
-       case 17:
-               break;
-       default:
-               dprintk("RISC: invalid firmware version");
-               return -EINVAL;
-       }
-
-       dprintk("RISC: valid firmware version");
-       return 0;
-}
-
-static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
-{
-       /* Reconfig pool mac ram */
-       dib9000_write_word(state, 1225, 0x02);  /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
-       dib9000_write_word(state, 1226, 0x05);
-
-       /* Toggles IP crypto to Host APB interface. */
-       dib9000_write_word(state, 1542, 1);
-
-       /* Set jump and no jump in the dma box */
-       dib9000_write_word(state, 1074, 0);
-       dib9000_write_word(state, 1075, 0);
-
-       /* Set MAC as APB Master. */
-       dib9000_write_word(state, 1237, 0);
-
-       /* Reset the RISCs */
-       if (codeA != NULL)
-               dib9000_write_word(state, 1024, 2);
-       else
-               dib9000_write_word(state, 1024, 15);
-       if (codeB != NULL)
-               dib9000_write_word(state, 1040, 2);
-
-       if (codeA != NULL)
-               dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
-       if (codeB != NULL)
-               dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
-
-       /* Run the RISCs */
-       if (codeA != NULL)
-               dib9000_write_word(state, 1024, 0);
-       if (codeB != NULL)
-               dib9000_write_word(state, 1040, 0);
-
-       if (codeA != NULL)
-               if (dib9000_mbx_host_init(state, 0) != 0)
-                       return -EIO;
-       if (codeB != NULL)
-               if (dib9000_mbx_host_init(state, 1) != 0)
-                       return -EIO;
-
-       msleep(100);
-       state->platform.risc.fw_is_running = 1;
-
-       if (dib9000_risc_check_version(state) != 0)
-               return -EINVAL;
-
-       state->platform.risc.memcmd = 0xff;
-       return 0;
-}
-
-static u16 dib9000_identify(struct i2c_device *client)
-{
-       u16 value;
-
-       value = dib9000_i2c_read16(client, 896);
-       if (value != 0x01b3) {
-               dprintk("wrong Vendor ID (0x%x)", value);
-               return 0;
-       }
-
-       value = dib9000_i2c_read16(client, 897);
-       if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
-               dprintk("wrong Device ID (0x%x)", value);
-               return 0;
-       }
-
-       /* protect this driver to be used with 7000PC */
-       if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
-               dprintk("this driver does not work with DiB7000PC");
-               return 0;
-       }
-
-       switch (value) {
-       case 0x4000:
-               dprintk("found DiB7000MA/PA/MB/PB");
-               break;
-       case 0x4001:
-               dprintk("found DiB7000HC");
-               break;
-       case 0x4002:
-               dprintk("found DiB7000MC");
-               break;
-       case 0x4003:
-               dprintk("found DiB9000A");
-               break;
-       case 0x4004:
-               dprintk("found DiB9000H");
-               break;
-       case 0x4005:
-               dprintk("found DiB9000M");
-               break;
-       }
-
-       return value;
-}
-
-static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
-{
-       /* by default everything is going to be powered off */
-       u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
-       u8 offset;
-
-       if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
-               offset = 1;
-       else
-               offset = 0;
-
-       reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
-
-       /* now, depending on the requested mode, we power on */
-       switch (mode) {
-               /* power up everything in the demod */
-       case DIB9000_POWER_ALL:
-               reg_903 = 0x0000;
-               reg_904 = 0x0000;
-               reg_905 = 0x0000;
-               reg_906 = 0x0000;
-               break;
-
-               /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
-       case DIB9000_POWER_INTERFACE_ONLY:      /* TODO power up either SDIO or I2C or SRAM */
-               reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
-               break;
-
-       case DIB9000_POWER_INTERF_ANALOG_AGC:
-               reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
-               reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
-               reg_906 &= ~((1 << 0));
-               break;
-
-       case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
-               reg_903 = 0x0000;
-               reg_904 = 0x801f;
-               reg_905 = 0x0000;
-               reg_906 &= ~((1 << 0));
-               break;
-
-       case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
-               reg_903 = 0x0000;
-               reg_904 = 0x8000;
-               reg_905 = 0x010b;
-               reg_906 &= ~((1 << 0));
-               break;
-       default:
-       case DIB9000_POWER_NO:
-               break;
-       }
-
-       /* always power down unused parts */
-       if (!state->platform.host.mobile_mode)
-               reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
-
-       /* P_sdio_select_clk = 0 on MC and after */
-       if (state->revision != 0x4000)
-               reg_906 <<= 1;
-
-       dib9000_write_word(state, 903 + offset, reg_903);
-       dib9000_write_word(state, 904 + offset, reg_904);
-       dib9000_write_word(state, 905 + offset, reg_905);
-       dib9000_write_word(state, 906 + offset, reg_906);
-}
-
-static int dib9000_fw_reset(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-
-       dib9000_write_word(state, 1817, 0x0003);
-
-       dib9000_write_word(state, 1227, 1);
-       dib9000_write_word(state, 1227, 0);
-
-       switch ((state->revision = dib9000_identify(&state->i2c))) {
-       case 0x4003:
-       case 0x4004:
-       case 0x4005:
-               state->reg_offs = 1;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* reset the i2c-master to use the host interface */
-       dibx000_reset_i2c_master(&state->i2c_master);
-
-       dib9000_set_power_mode(state, DIB9000_POWER_ALL);
-
-       /* unforce divstr regardless whether i2c enumeration was done or not */
-       dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
-       dib9000_write_word(state, 1796, 0);
-       dib9000_write_word(state, 1805, 0x805);
-
-       /* restart all parts */
-       dib9000_write_word(state, 898, 0xffff);
-       dib9000_write_word(state, 899, 0xffff);
-       dib9000_write_word(state, 900, 0x0001);
-       dib9000_write_word(state, 901, 0xff19);
-       dib9000_write_word(state, 902, 0x003c);
-
-       dib9000_write_word(state, 898, 0);
-       dib9000_write_word(state, 899, 0);
-       dib9000_write_word(state, 900, 0);
-       dib9000_write_word(state, 901, 0);
-       dib9000_write_word(state, 902, 0);
-
-       dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
-
-       dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
-
-       return 0;
-}
-
-static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
-{
-       u16 mb[10];
-       u8 i, s;
-
-       if (address >= 1024 || !state->platform.risc.fw_is_running)
-               return -EINVAL;
-
-       /* dprintk( "APB access thru rd fw %d %x", address, attribute); */
-
-       mb[0] = (u16) address;
-       mb[1] = len / 2;
-       dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
-       switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
-       case 1:
-               s--;
-               for (i = 0; i < s; i++) {
-                       b[i * 2] = (mb[i + 1] >> 8) & 0xff;
-                       b[i * 2 + 1] = (mb[i + 1]) & 0xff;
-               }
-               return 0;
-       default:
-               return -EIO;
-       }
-       return -EIO;
-}
-
-static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
-{
-       u16 mb[10];
-       u8 s, i;
-
-       if (address >= 1024 || !state->platform.risc.fw_is_running)
-               return -EINVAL;
-
-       /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
-
-       mb[0] = (unsigned short)address;
-       for (i = 0; i < len && i < 20; i += 2)
-               mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
-
-       dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
-       return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
-}
-
-static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
-{
-       u8 index_loop = 10;
-
-       if (!state->platform.risc.fw_is_running)
-               return 0;
-       dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
-       do {
-               dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
-       } while (state->i2c_read_buffer[0] && index_loop--);
-
-       if (index_loop > 0)
-               return 0;
-       return -EIO;
-}
-
-static int dib9000_fw_init(struct dib9000_state *state)
-{
-       struct dibGPIOFunction *f;
-       u16 b[40] = { 0 };
-       u8 i;
-       u8 size;
-
-       if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
-               return -EIO;
-
-       /* initialize the firmware */
-       for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
-               f = &state->chip.d9.cfg.gpio_function[i];
-               if (f->mask) {
-                       switch (f->function) {
-                       case BOARD_GPIO_FUNCTION_COMPONENT_ON:
-                               b[0] = (u16) f->mask;
-                               b[1] = (u16) f->direction;
-                               b[2] = (u16) f->value;
-                               break;
-                       case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
-                               b[3] = (u16) f->mask;
-                               b[4] = (u16) f->direction;
-                               b[5] = (u16) f->value;
-                               break;
-                       }
-               }
-       }
-       if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
-               return -EIO;
-
-       /* subband */
-       b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
-       for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
-               b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
-               b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
-               b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
-               b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
-       }
-       b[1 + i * 4] = 0;       /* fe_id */
-       if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
-               return -EIO;
-
-       /* 0 - id, 1 - no_of_frontends */
-       b[0] = (0 << 8) | 1;
-       /* 0 = i2c-address demod, 0 = tuner */
-       b[1] = (0 << 8) | (0);
-       b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
-       b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
-       b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
-       b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
-       b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
-       b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
-       b[29] = state->chip.d9.cfg.if_drives;
-       if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
-               return -EIO;
-
-       if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
-               return -EIO;
-
-       if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
-               return -EIO;
-
-       if (size > ARRAY_SIZE(b)) {
-               dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
-                       (int)ARRAY_SIZE(b));
-               return -EINVAL;
-       }
-
-       for (i = 0; i < size; i += 2) {
-               state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
-               state->platform.risc.fe_mm[i / 2].size = b[i + 1];
-       }
-
-       return 0;
-}
-
-static void dib9000_fw_set_channel_head(struct dib9000_state *state)
-{
-       u8 b[9];
-       u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
-       if (state->fe_id % 2)
-               freq += 101;
-
-       b[0] = (u8) ((freq >> 0) & 0xff);
-       b[1] = (u8) ((freq >> 8) & 0xff);
-       b[2] = (u8) ((freq >> 16) & 0xff);
-       b[3] = (u8) ((freq >> 24) & 0xff);
-       b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
-       b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
-       b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
-       b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
-       b[8] = 0x80;            /* do not wait for CELL ID when doing autosearch */
-       if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
-               b[8] |= 1;
-       dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
-}
-
-static int dib9000_fw_get_channel(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       struct dibDVBTChannel {
-               s8 spectrum_inversion;
-
-               s8 nfft;
-               s8 guard;
-               s8 constellation;
-
-               s8 hrch;
-               s8 alpha;
-               s8 code_rate_hp;
-               s8 code_rate_lp;
-               s8 select_hp;
-
-               s8 intlv_native;
-       };
-       struct dibDVBTChannel *ch;
-       int ret = 0;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
-               ret = -EIO;
-               goto error;
-       }
-
-       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
-                       state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
-       ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
-
-
-       switch (ch->spectrum_inversion & 0x7) {
-       case 1:
-               state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
-               break;
-       case 0:
-               state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
-               break;
-       }
-       switch (ch->nfft) {
-       case 0:
-               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 2:
-               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
-               break;
-       case 1:
-               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
-               break;
-       }
-       switch (ch->guard) {
-       case 0:
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
-               break;
-       }
-       switch (ch->constellation) {
-       case 2:
-               state->fe[0]->dtv_property_cache.modulation = QAM_64;
-               break;
-       case 1:
-               state->fe[0]->dtv_property_cache.modulation = QAM_16;
-               break;
-       case 0:
-               state->fe[0]->dtv_property_cache.modulation = QPSK;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
-               break;
-       }
-       switch (ch->hrch) {
-       case 0:
-               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
-               break;
-       }
-       switch (ch->code_rate_hp) {
-       case 1:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
-               break;
-       case 2:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
-               break;
-       case 3:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
-               break;
-       case 5:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
-               break;
-       case 7:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
-               break;
-       }
-       switch (ch->code_rate_lp) {
-       case 1:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
-               break;
-       case 2:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
-               break;
-       case 3:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
-               break;
-       case 5:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
-               break;
-       case 7:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
-               break;
-       default:
-       case -1:
-               state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
-               break;
-       }
-
-error:
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-       return ret;
-}
-
-static int dib9000_fw_set_channel_union(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       struct dibDVBTChannel {
-               s8 spectrum_inversion;
-
-               s8 nfft;
-               s8 guard;
-               s8 constellation;
-
-               s8 hrch;
-               s8 alpha;
-               s8 code_rate_hp;
-               s8 code_rate_lp;
-               s8 select_hp;
-
-               s8 intlv_native;
-       };
-       struct dibDVBTChannel ch;
-
-       switch (state->fe[0]->dtv_property_cache.inversion) {
-       case INVERSION_ON:
-               ch.spectrum_inversion = 1;
-               break;
-       case INVERSION_OFF:
-               ch.spectrum_inversion = 0;
-               break;
-       default:
-       case INVERSION_AUTO:
-               ch.spectrum_inversion = -1;
-               break;
-       }
-       switch (state->fe[0]->dtv_property_cache.transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               ch.nfft = 0;
-               break;
-       case TRANSMISSION_MODE_4K:
-               ch.nfft = 2;
-               break;
-       case TRANSMISSION_MODE_8K:
-               ch.nfft = 1;
-               break;
-       default:
-       case TRANSMISSION_MODE_AUTO:
-               ch.nfft = 1;
-               break;
-       }
-       switch (state->fe[0]->dtv_property_cache.guard_interval) {
-       case GUARD_INTERVAL_1_32:
-               ch.guard = 0;
-               break;
-       case GUARD_INTERVAL_1_16:
-               ch.guard = 1;
-               break;
-       case GUARD_INTERVAL_1_8:
-               ch.guard = 2;
-               break;
-       case GUARD_INTERVAL_1_4:
-               ch.guard = 3;
-               break;
-       default:
-       case GUARD_INTERVAL_AUTO:
-               ch.guard = -1;
-               break;
-       }
-       switch (state->fe[0]->dtv_property_cache.modulation) {
-       case QAM_64:
-               ch.constellation = 2;
-               break;
-       case QAM_16:
-               ch.constellation = 1;
-               break;
-       case QPSK:
-               ch.constellation = 0;
-               break;
-       default:
-       case QAM_AUTO:
-               ch.constellation = -1;
-               break;
-       }
-       switch (state->fe[0]->dtv_property_cache.hierarchy) {
-       case HIERARCHY_NONE:
-               ch.hrch = 0;
-               break;
-       case HIERARCHY_1:
-       case HIERARCHY_2:
-       case HIERARCHY_4:
-               ch.hrch = 1;
-               break;
-       default:
-       case HIERARCHY_AUTO:
-               ch.hrch = -1;
-               break;
-       }
-       ch.alpha = 1;
-       switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
-       case FEC_1_2:
-               ch.code_rate_hp = 1;
-               break;
-       case FEC_2_3:
-               ch.code_rate_hp = 2;
-               break;
-       case FEC_3_4:
-               ch.code_rate_hp = 3;
-               break;
-       case FEC_5_6:
-               ch.code_rate_hp = 5;
-               break;
-       case FEC_7_8:
-               ch.code_rate_hp = 7;
-               break;
-       default:
-       case FEC_AUTO:
-               ch.code_rate_hp = -1;
-               break;
-       }
-       switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
-       case FEC_1_2:
-               ch.code_rate_lp = 1;
-               break;
-       case FEC_2_3:
-               ch.code_rate_lp = 2;
-               break;
-       case FEC_3_4:
-               ch.code_rate_lp = 3;
-               break;
-       case FEC_5_6:
-               ch.code_rate_lp = 5;
-               break;
-       case FEC_7_8:
-               ch.code_rate_lp = 7;
-               break;
-       default:
-       case FEC_AUTO:
-               ch.code_rate_lp = -1;
-               break;
-       }
-       ch.select_hp = 1;
-       ch.intlv_native = 1;
-
-       dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
-
-       return 0;
-}
-
-static int dib9000_fw_tune(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
-       s8 i;
-
-       switch (state->tune_state) {
-       case CT_DEMOD_START:
-               dib9000_fw_set_channel_head(state);
-
-               /* write the channel context - a channel is initialized to 0, so it is OK */
-               dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
-               dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
-
-               if (search)
-                       dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
-               else {
-                       dib9000_fw_set_channel_union(fe);
-                       dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
-               }
-               state->tune_state = CT_DEMOD_STEP_1;
-               break;
-       case CT_DEMOD_STEP_1:
-               if (search)
-                       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
-               else
-                       dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
-               i = (s8)state->i2c_read_buffer[0];
-               switch (i) {    /* something happened */
-               case 0:
-                       break;
-               case -2:        /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
-                       if (search)
-                               state->status = FE_STATUS_DEMOD_SUCCESS;
-                       else {
-                               state->tune_state = CT_DEMOD_STOP;
-                               state->status = FE_STATUS_LOCKED;
-                       }
-                       break;
-               default:
-                       state->status = FE_STATUS_TUNE_FAILED;
-                       state->tune_state = CT_DEMOD_STOP;
-                       break;
-               }
-               break;
-       default:
-               ret = FE_CALLBACK_TIME_NEVER;
-               break;
-       }
-
-       return ret;
-}
-
-static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 mode = (u16) onoff;
-       return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
-}
-
-static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 outreg, smo_mode;
-
-       dprintk("setting output mode for demod %p to %d", fe, mode);
-
-       switch (mode) {
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-               outreg = (1 << 10);     /* 0x0400 */
-               break;
-       case OUTMODE_MPEG2_PAR_CONT_CLK:
-               outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
-               break;
-       case OUTMODE_MPEG2_SERIAL:
-               outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
-               break;
-       case OUTMODE_DIVERSITY:
-               outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
-               break;
-       case OUTMODE_MPEG2_FIFO:
-               outreg = (1 << 10) | (5 << 6);
-               break;
-       case OUTMODE_HIGH_Z:
-               outreg = 0;
-               break;
-       default:
-               dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]);
-               return -EINVAL;
-       }
-
-       dib9000_write_word(state, 1795, outreg);
-
-       switch (mode) {
-       case OUTMODE_MPEG2_PAR_GATED_CLK:
-       case OUTMODE_MPEG2_PAR_CONT_CLK:
-       case OUTMODE_MPEG2_SERIAL:
-       case OUTMODE_MPEG2_FIFO:
-               smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
-               if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
-                       smo_mode |= (1 << 5);
-               dib9000_write_word(state, 295, smo_mode);
-               break;
-       }
-
-       outreg = to_fw_output_mode(mode);
-       return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
-}
-
-static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
-       u16 i, len, t, index_msg;
-
-       for (index_msg = 0; index_msg < num; index_msg++) {
-               if (msg[index_msg].flags & I2C_M_RD) {  /* read */
-                       len = msg[index_msg].len;
-                       if (len > 16)
-                               len = 16;
-
-                       if (dib9000_read_word(state, 790) != 0)
-                               dprintk("TunerITF: read busy");
-
-                       dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
-                       dib9000_write_word(state, 787, (len / 2) - 1);
-                       dib9000_write_word(state, 786, 1);      /* start read */
-
-                       i = 1000;
-                       while (dib9000_read_word(state, 790) != (len / 2) && i)
-                               i--;
-
-                       if (i == 0)
-                               dprintk("TunerITF: read failed");
-
-                       for (i = 0; i < len; i += 2) {
-                               t = dib9000_read_word(state, 785);
-                               msg[index_msg].buf[i] = (t >> 8) & 0xff;
-                               msg[index_msg].buf[i + 1] = (t) & 0xff;
-                       }
-                       if (dib9000_read_word(state, 790) != 0)
-                               dprintk("TunerITF: read more data than expected");
-               } else {
-                       i = 1000;
-                       while (dib9000_read_word(state, 789) && i)
-                               i--;
-                       if (i == 0)
-                               dprintk("TunerITF: write busy");
-
-                       len = msg[index_msg].len;
-                       if (len > 16)
-                               len = 16;
-
-                       for (i = 0; i < len; i += 2)
-                               dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
-                       dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
-                       dib9000_write_word(state, 787, (len / 2) - 1);
-                       dib9000_write_word(state, 786, 0);      /* start write */
-
-                       i = 1000;
-                       while (dib9000_read_word(state, 791) > 0 && i)
-                               i--;
-                       if (i == 0)
-                               dprintk("TunerITF: write failed");
-               }
-       }
-       return num;
-}
-
-int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-
-       state->component_bus_speed = speed;
-       return 0;
-}
-EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
-
-static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
-       u8 type = 0;            /* I2C */
-       u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
-       u16 scl = state->component_bus_speed;   /* SCL frequency */
-       struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
-       u8 p[13] = { 0 };
-
-       p[0] = type;
-       p[1] = port;
-       p[2] = msg[0].addr << 1;
-
-       p[3] = (u8) scl & 0xff; /* scl */
-       p[4] = (u8) (scl >> 8);
-
-       p[7] = 0;
-       p[8] = 0;
-
-       p[9] = (u8) (msg[0].len);
-       p[10] = (u8) (msg[0].len >> 8);
-       if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
-               p[11] = (u8) (msg[1].len);
-               p[12] = (u8) (msg[1].len >> 8);
-       } else {
-               p[11] = 0;
-               p[12] = 0;
-       }
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               return 0;
-       }
-
-       dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
-
-       {                       /* write-part */
-               dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
-               dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
-       }
-
-       /* do the transaction */
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
-               mutex_unlock(&state->platform.risc.mem_mbx_lock);
-               return 0;
-       }
-
-       /* read back any possible result */
-       if ((num > 1) && (msg[1].flags & I2C_M_RD))
-               dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
-
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-
-       return num;
-}
-
-static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dib9000_tuner_algo = {
-       .master_xfer = dib9000_tuner_xfer,
-       .functionality = dib9000_i2c_func,
-};
-
-static struct i2c_algorithm dib9000_component_bus_algo = {
-       .master_xfer = dib9000_fw_component_bus_xfer,
-       .functionality = dib9000_i2c_func,
-};
-
-struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
-{
-       struct dib9000_state *st = fe->demodulator_priv;
-       return &st->tuner_adap;
-}
-EXPORT_SYMBOL(dib9000_get_tuner_interface);
-
-struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
-{
-       struct dib9000_state *st = fe->demodulator_priv;
-       return &st->component_bus;
-}
-EXPORT_SYMBOL(dib9000_get_component_bus_interface);
-
-struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
-{
-       struct dib9000_state *st = fe->demodulator_priv;
-       return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
-}
-EXPORT_SYMBOL(dib9000_get_i2c_master);
-
-int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
-{
-       struct dib9000_state *st = fe->demodulator_priv;
-
-       st->i2c.i2c_adap = i2c;
-       return 0;
-}
-EXPORT_SYMBOL(dib9000_set_i2c_adapter);
-
-static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
-{
-       st->gpio_dir = dib9000_read_word(st, 773);
-       st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
-       st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
-       dib9000_write_word(st, 773, st->gpio_dir);
-
-       st->gpio_val = dib9000_read_word(st, 774);
-       st->gpio_val &= ~(1 << num);    /* reset the direction bit */
-       st->gpio_val |= (val & 0x01) << num;    /* set the new value */
-       dib9000_write_word(st, 774, st->gpio_val);
-
-       dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val);
-
-       return 0;
-}
-
-int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       return dib9000_cfg_gpio(state, num, dir, val);
-}
-EXPORT_SYMBOL(dib9000_set_gpio);
-
-int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 val;
-       int ret;
-
-       if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
-               /* postpone the pid filtering cmd */
-               dprintk("pid filter cmd postpone");
-               state->pid_ctrl_index++;
-               state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
-               state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
-               return 0;
-       }
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-
-       val = dib9000_read_word(state, 294 + 1) & 0xffef;
-       val |= (onoff & 0x1) << 4;
-
-       dprintk("PID filter enabled %d", onoff);
-       ret = dib9000_write_word(state, 294 + 1, val);
-       mutex_unlock(&state->demod_lock);
-       return ret;
-
-}
-EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
-
-int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       int ret;
-
-       if (state->pid_ctrl_index != -2) {
-               /* postpone the pid filtering cmd */
-               dprintk("pid filter postpone");
-               if (state->pid_ctrl_index < 9) {
-                       state->pid_ctrl_index++;
-                       state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
-                       state->pid_ctrl[state->pid_ctrl_index].id = id;
-                       state->pid_ctrl[state->pid_ctrl_index].pid = pid;
-                       state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
-               } else
-                       dprintk("can not add any more pid ctrl cmd");
-               return 0;
-       }
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
-       ret = dib9000_write_word(state, 300 + 1 + id,
-                       onoff ? (1 << 13) | pid : 0);
-       mutex_unlock(&state->demod_lock);
-       return ret;
-}
-EXPORT_SYMBOL(dib9000_fw_pid_filter);
-
-int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       return dib9000_fw_init(state);
-}
-EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
-
-static void dib9000_release(struct dvb_frontend *demod)
-{
-       struct dib9000_state *st = demod->demodulator_priv;
-       u8 index_frontend;
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
-               dvb_frontend_detach(st->fe[index_frontend]);
-
-       dibx000_exit_i2c_master(&st->i2c_master);
-
-       i2c_del_adapter(&st->tuner_adap);
-       i2c_del_adapter(&st->component_bus);
-       kfree(st->fe[0]);
-       kfree(st);
-}
-
-static int dib9000_wakeup(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int dib9000_sleep(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       int ret = 0;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
-               if (ret < 0)
-                       goto error;
-       }
-       ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
-
-error:
-       mutex_unlock(&state->demod_lock);
-       return ret;
-}
-
-static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static int dib9000_get_frontend(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend, sub_index_frontend;
-       fe_status_t stat;
-       int ret = 0;
-
-       if (state->get_frontend_internal == 0) {
-               if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-                       dprintk("could not get the lock");
-                       return -EINTR;
-               }
-       }
-
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
-               if (stat & FE_HAS_SYNC) {
-                       dprintk("TPS lock on the slave%i", index_frontend);
-
-                       /* synchronize the cache with the other frontends */
-                       state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
-                       for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
-                            sub_index_frontend++) {
-                               if (sub_index_frontend != index_frontend) {
-                                       state->fe[sub_index_frontend]->dtv_property_cache.modulation =
-                                           state->fe[index_frontend]->dtv_property_cache.modulation;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.inversion =
-                                           state->fe[index_frontend]->dtv_property_cache.inversion;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
-                                           state->fe[index_frontend]->dtv_property_cache.transmission_mode;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
-                                           state->fe[index_frontend]->dtv_property_cache.guard_interval;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
-                                           state->fe[index_frontend]->dtv_property_cache.hierarchy;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
-                                           state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
-                                           state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
-                                       state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
-                                           state->fe[index_frontend]->dtv_property_cache.rolloff;
-                               }
-                       }
-                       ret = 0;
-                       goto return_value;
-               }
-       }
-
-       /* get the channel from master chip */
-       ret = dib9000_fw_get_channel(fe);
-       if (ret != 0)
-               goto return_value;
-
-       /* synchronize the cache with the other frontends */
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
-               state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
-               state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
-               state->fe[index_frontend]->dtv_property_cache.modulation = fe->dtv_property_cache.modulation;
-               state->fe[index_frontend]->dtv_property_cache.hierarchy = fe->dtv_property_cache.hierarchy;
-               state->fe[index_frontend]->dtv_property_cache.code_rate_HP = fe->dtv_property_cache.code_rate_HP;
-               state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
-               state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
-       }
-       ret = 0;
-
-return_value:
-       if (state->get_frontend_internal == 0)
-               mutex_unlock(&state->demod_lock);
-       return ret;
-}
-
-static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       state->tune_state = tune_state;
-       if (tune_state == CT_DEMOD_START)
-               state->status = FE_STATUS_TUNE_PENDING;
-
-       return 0;
-}
-
-static u32 dib9000_get_status(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       return state->status;
-}
-
-static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-
-       memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
-       return 0;
-}
-
-static int dib9000_set_frontend(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       int sleep_time, sleep_time_slave;
-       u32 frontend_status;
-       u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
-       struct dvb_frontend_parametersContext channel_status;
-
-       /* check that the correct parameters are set */
-       if (state->fe[0]->dtv_property_cache.frequency == 0) {
-               dprintk("dib9000: must specify frequency ");
-               return 0;
-       }
-
-       if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
-               dprintk("dib9000: must specify bandwidth ");
-               return 0;
-       }
-
-       state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return 0;
-       }
-
-       fe->dtv_property_cache.delivery_system = SYS_DVBT;
-
-       /* set the master status */
-       if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO ||
-           state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO ||
-           state->fe[0]->dtv_property_cache.modulation == QAM_AUTO ||
-           state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) {
-               /* no channel specified, autosearch the channel */
-               state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
-       } else
-               state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
-
-       /* set mode and status for the different frontends */
-       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
-
-               /* synchronization of the cache */
-               memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
-
-               state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
-               dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
-
-               dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
-               dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
-       }
-
-       /* actual tune */
-       exit_condition = 0;     /* 0: tune pending; 1: tune failed; 2:tune success */
-       index_frontend_success = 0;
-       do {
-               sleep_time = dib9000_fw_tune(state->fe[0]);
-               for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
-                       if (sleep_time == FE_CALLBACK_TIME_NEVER)
-                               sleep_time = sleep_time_slave;
-                       else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
-                               sleep_time = sleep_time_slave;
-               }
-               if (sleep_time != FE_CALLBACK_TIME_NEVER)
-                       msleep(sleep_time / 10);
-               else
-                       break;
-
-               nbr_pending = 0;
-               exit_condition = 0;
-               index_frontend_success = 0;
-               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       frontend_status = -dib9000_get_status(state->fe[index_frontend]);
-                       if (frontend_status > -FE_STATUS_TUNE_PENDING) {
-                               exit_condition = 2;     /* tune success */
-                               index_frontend_success = index_frontend;
-                               break;
-                       }
-                       if (frontend_status == -FE_STATUS_TUNE_PENDING)
-                               nbr_pending++;  /* some frontends are still tuning */
-               }
-               if ((exit_condition != 2) && (nbr_pending == 0))
-                       exit_condition = 1;     /* if all tune are done and no success, exit: tune failed */
-
-       } while (exit_condition == 0);
-
-       /* check the tune result */
-       if (exit_condition == 1) {      /* tune failed */
-               dprintk("tune failed");
-               mutex_unlock(&state->demod_lock);
-               /* tune failed; put all the pid filtering cmd to junk */
-               state->pid_ctrl_index = -1;
-               return 0;
-       }
-
-       dprintk("tune success on frontend%i", index_frontend_success);
-
-       /* synchronize all the channel cache */
-       state->get_frontend_internal = 1;
-       dib9000_get_frontend(state->fe[0]);
-       state->get_frontend_internal = 0;
-
-       /* retune the other frontends with the found channel */
-       channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
-       for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               /* only retune the frontends which was not tuned success */
-               if (index_frontend != index_frontend_success) {
-                       dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
-                       dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
-               }
-       }
-       do {
-               sleep_time = FE_CALLBACK_TIME_NEVER;
-               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       if (index_frontend != index_frontend_success) {
-                               sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
-                               if (sleep_time == FE_CALLBACK_TIME_NEVER)
-                                       sleep_time = sleep_time_slave;
-                               else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
-                                       sleep_time = sleep_time_slave;
-                       }
-               }
-               if (sleep_time != FE_CALLBACK_TIME_NEVER)
-                       msleep(sleep_time / 10);
-               else
-                       break;
-
-               nbr_pending = 0;
-               for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-                       if (index_frontend != index_frontend_success) {
-                               frontend_status = -dib9000_get_status(state->fe[index_frontend]);
-                               if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
-                                       nbr_pending++;  /* some frontends are still tuning */
-                       }
-               }
-       } while (nbr_pending != 0);
-
-       /* set the output mode */
-       dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
-
-       /* turn off the diversity for the last frontend */
-       dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
-
-       mutex_unlock(&state->demod_lock);
-       if (state->pid_ctrl_index >= 0) {
-               u8 index_pid_filter_cmd;
-               u8 pid_ctrl_index = state->pid_ctrl_index;
-
-               state->pid_ctrl_index = -2;
-               for (index_pid_filter_cmd = 0;
-                               index_pid_filter_cmd <= pid_ctrl_index;
-                               index_pid_filter_cmd++) {
-                       if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
-                               dib9000_fw_pid_filter_ctrl(state->fe[0],
-                                               state->pid_ctrl[index_pid_filter_cmd].onoff);
-                       else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
-                               dib9000_fw_pid_filter(state->fe[0],
-                                               state->pid_ctrl[index_pid_filter_cmd].id,
-                                               state->pid_ctrl[index_pid_filter_cmd].pid,
-                                               state->pid_ctrl[index_pid_filter_cmd].onoff);
-               }
-       }
-       /* do not postpone any more the pid filtering */
-       state->pid_ctrl_index = -2;
-
-       return 0;
-}
-
-static u16 dib9000_read_lock(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-
-       return dib9000_read_word(state, 535);
-}
-
-static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       u16 lock = 0, lock_slave = 0;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
-
-       lock = dib9000_read_word(state, 535);
-
-       *stat = 0;
-
-       if ((lock & 0x8000) || (lock_slave & 0x8000))
-               *stat |= FE_HAS_SIGNAL;
-       if ((lock & 0x3000) || (lock_slave & 0x3000))
-               *stat |= FE_HAS_CARRIER;
-       if ((lock & 0x0100) || (lock_slave & 0x0100))
-               *stat |= FE_HAS_VITERBI;
-       if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
-               *stat |= FE_HAS_SYNC;
-       if ((lock & 0x0008) || (lock_slave & 0x0008))
-               *stat |= FE_HAS_LOCK;
-
-       mutex_unlock(&state->demod_lock);
-
-       return 0;
-}
-
-static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 *c;
-       int ret = 0;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               ret = -EINTR;
-               goto error;
-       }
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
-               mutex_unlock(&state->platform.risc.mem_mbx_lock);
-               ret = -EIO;
-               goto error;
-       }
-       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
-                       state->i2c_read_buffer, 16 * 2);
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-
-       c = (u16 *)state->i2c_read_buffer;
-
-       *ber = c[10] << 16 | c[11];
-
-error:
-       mutex_unlock(&state->demod_lock);
-       return ret;
-}
-
-static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       u16 *c = (u16 *)state->i2c_read_buffer;
-       u16 val;
-       int ret = 0;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       *strength = 0;
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-               state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
-               if (val > 65535 - *strength)
-                       *strength = 65535;
-               else
-                       *strength += val;
-       }
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               ret = -EINTR;
-               goto error;
-       }
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
-               mutex_unlock(&state->platform.risc.mem_mbx_lock);
-               ret = -EIO;
-               goto error;
-       }
-       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-
-       val = 65535 - c[4];
-       if (val > 65535 - *strength)
-               *strength = 65535;
-       else
-               *strength += val;
-
-error:
-       mutex_unlock(&state->demod_lock);
-       return ret;
-}
-
-static u32 dib9000_get_snr(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 *c = (u16 *)state->i2c_read_buffer;
-       u32 n, s, exp;
-       u16 val;
-
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               return 0;
-       }
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
-               mutex_unlock(&state->platform.risc.mem_mbx_lock);
-               return 0;
-       }
-       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-
-       val = c[7];
-       n = (val >> 4) & 0xff;
-       exp = ((val & 0xf) << 2);
-       val = c[8];
-       exp += ((val >> 14) & 0x3);
-       if ((exp & 0x20) != 0)
-               exp -= 0x40;
-       n <<= exp + 16;
-
-       s = (val >> 6) & 0xFF;
-       exp = (val & 0x3F);
-       if ((exp & 0x20) != 0)
-               exp -= 0x40;
-       s <<= exp + 16;
-
-       if (n > 0) {
-               u32 t = (s / n) << 16;
-               return t + ((s << 16) - n * t) / n;
-       }
-       return 0xffffffff;
-}
-
-static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend;
-       u32 snr_master;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       snr_master = dib9000_get_snr(fe);
-       for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
-               snr_master += dib9000_get_snr(state->fe[index_frontend]);
-
-       if ((snr_master >> 16) != 0) {
-               snr_master = 10 * intlog10(snr_master >> 16);
-               *snr = snr_master / ((1 << 24) / 10);
-       } else
-               *snr = 0;
-
-       mutex_unlock(&state->demod_lock);
-
-       return 0;
-}
-
-static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u16 *c = (u16 *)state->i2c_read_buffer;
-       int ret = 0;
-
-       if (mutex_lock_interruptible(&state->demod_lock) < 0) {
-               dprintk("could not get the lock");
-               return -EINTR;
-       }
-       if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
-               dprintk("could not get the lock");
-               ret = -EINTR;
-               goto error;
-       }
-       if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
-               mutex_unlock(&state->platform.risc.mem_mbx_lock);
-               ret = -EIO;
-               goto error;
-       }
-       dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
-       mutex_unlock(&state->platform.risc.mem_mbx_lock);
-
-       *unc = c[12];
-
-error:
-       mutex_unlock(&state->demod_lock);
-       return ret;
-}
-
-int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
-{
-       int k = 0, ret = 0;
-       u8 new_addr = 0;
-       struct i2c_device client = {.i2c_adap = i2c };
-
-       client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-       if (!client.i2c_write_buffer) {
-               dprintk("%s: not enough memory", __func__);
-               return -ENOMEM;
-       }
-       client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
-       if (!client.i2c_read_buffer) {
-               dprintk("%s: not enough memory", __func__);
-               ret = -ENOMEM;
-               goto error_memory;
-       }
-
-       client.i2c_addr = default_addr + 16;
-       dib9000_i2c_write16(&client, 1796, 0x0);
-
-       for (k = no_of_demods - 1; k >= 0; k--) {
-               /* designated i2c address */
-               new_addr = first_addr + (k << 1);
-               client.i2c_addr = default_addr;
-
-               dib9000_i2c_write16(&client, 1817, 3);
-               dib9000_i2c_write16(&client, 1796, 0);
-               dib9000_i2c_write16(&client, 1227, 1);
-               dib9000_i2c_write16(&client, 1227, 0);
-
-               client.i2c_addr = new_addr;
-               dib9000_i2c_write16(&client, 1817, 3);
-               dib9000_i2c_write16(&client, 1796, 0);
-               dib9000_i2c_write16(&client, 1227, 1);
-               dib9000_i2c_write16(&client, 1227, 0);
-
-               if (dib9000_identify(&client) == 0) {
-                       client.i2c_addr = default_addr;
-                       if (dib9000_identify(&client) == 0) {
-                               dprintk("DiB9000 #%d: not identified", k);
-                               ret = -EIO;
-                               goto error;
-                       }
-               }
-
-               dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
-               dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
-
-               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
-       }
-
-       for (k = 0; k < no_of_demods; k++) {
-               new_addr = first_addr | (k << 1);
-               client.i2c_addr = new_addr;
-
-               dib9000_i2c_write16(&client, 1794, (new_addr << 2));
-               dib9000_i2c_write16(&client, 1795, 0);
-       }
-
-error:
-       kfree(client.i2c_read_buffer);
-error_memory:
-       kfree(client.i2c_write_buffer);
-
-       return ret;
-}
-EXPORT_SYMBOL(dib9000_i2c_enumeration);
-
-int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend = 1;
-
-       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
-               index_frontend++;
-       if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
-               dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
-               state->fe[index_frontend] = fe_slave;
-               return 0;
-       }
-
-       dprintk("too many slave frontend");
-       return -ENOMEM;
-}
-EXPORT_SYMBOL(dib9000_set_slave_frontend);
-
-int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-       u8 index_frontend = 1;
-
-       while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
-               index_frontend++;
-       if (index_frontend != 1) {
-               dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1);
-               state->fe[index_frontend] = NULL;
-               return 0;
-       }
-
-       dprintk("no frontend to be removed");
-       return -ENODEV;
-}
-EXPORT_SYMBOL(dib9000_remove_slave_frontend);
-
-struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
-{
-       struct dib9000_state *state = fe->demodulator_priv;
-
-       if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
-               return NULL;
-       return state->fe[slave_index];
-}
-EXPORT_SYMBOL(dib9000_get_slave_frontend);
-
-static struct dvb_frontend_ops dib9000_ops;
-struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
-{
-       struct dvb_frontend *fe;
-       struct dib9000_state *st;
-       st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
-       if (st == NULL)
-               return NULL;
-       fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
-       if (fe == NULL) {
-               kfree(st);
-               return NULL;
-       }
-
-       memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
-       st->i2c.i2c_adap = i2c_adap;
-       st->i2c.i2c_addr = i2c_addr;
-       st->i2c.i2c_write_buffer = st->i2c_write_buffer;
-       st->i2c.i2c_read_buffer = st->i2c_read_buffer;
-
-       st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
-       st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
-       st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
-
-       mutex_init(&st->platform.risc.mbx_if_lock);
-       mutex_init(&st->platform.risc.mbx_lock);
-       mutex_init(&st->platform.risc.mem_lock);
-       mutex_init(&st->platform.risc.mem_mbx_lock);
-       mutex_init(&st->demod_lock);
-       st->get_frontend_internal = 0;
-
-       st->pid_ctrl_index = -2;
-
-       st->fe[0] = fe;
-       fe->demodulator_priv = st;
-       memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
-
-       /* Ensure the output mode remains at the previous default if it's
-        * not specifically set by the caller.
-        */
-       if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
-               st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
-
-       if (dib9000_identify(&st->i2c) == 0)
-               goto error;
-
-       dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
-
-       st->tuner_adap.dev.parent = i2c_adap->dev.parent;
-       strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name));
-       st->tuner_adap.algo = &dib9000_tuner_algo;
-       st->tuner_adap.algo_data = NULL;
-       i2c_set_adapdata(&st->tuner_adap, st);
-       if (i2c_add_adapter(&st->tuner_adap) < 0)
-               goto error;
-
-       st->component_bus.dev.parent = i2c_adap->dev.parent;
-       strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name));
-       st->component_bus.algo = &dib9000_component_bus_algo;
-       st->component_bus.algo_data = NULL;
-       st->component_bus_speed = 340;
-       i2c_set_adapdata(&st->component_bus, st);
-       if (i2c_add_adapter(&st->component_bus) < 0)
-               goto component_bus_add_error;
-
-       dib9000_fw_reset(fe);
-
-       return fe;
-
-component_bus_add_error:
-       i2c_del_adapter(&st->tuner_adap);
-error:
-       kfree(st);
-       return NULL;
-}
-EXPORT_SYMBOL(dib9000_attach);
-
-static struct dvb_frontend_ops dib9000_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-                .name = "DiBcom 9000",
-                .frequency_min = 44250000,
-                .frequency_max = 867250000,
-                .frequency_stepsize = 62500,
-                .caps = FE_CAN_INVERSION_AUTO |
-                FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
-                },
-
-       .release = dib9000_release,
-
-       .init = dib9000_wakeup,
-       .sleep = dib9000_sleep,
-
-       .set_frontend = dib9000_set_frontend,
-       .get_tune_settings = dib9000_fe_get_tune_settings,
-       .get_frontend = dib9000_get_frontend,
-
-       .read_status = dib9000_read_status,
-       .read_ber = dib9000_read_ber,
-       .read_signal_strength = dib9000_read_signal_strength,
-       .read_snr = dib9000_read_snr,
-       .read_ucblocks = dib9000_read_unc_blocks,
-};
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
-MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb/frontends/dib9000.h
deleted file mode 100644 (file)
index b5781a4..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef DIB9000_H
-#define DIB9000_H
-
-#include "dibx000_common.h"
-
-struct dib9000_config {
-       u8 dvbt_mode;
-       u8 output_mpeg2_in_188_bytes;
-       u8 hostbus_diversity;
-       struct dibx000_bandwidth_config *bw;
-
-       u16 if_drives;
-
-       u32 timing_frequency;
-       u32 xtal_clock_khz;
-       u32 vcxo_timer;
-       u32 demod_clock_khz;
-
-       const u8 *microcode_B_fe_buffer;
-       u32 microcode_B_fe_size;
-
-       struct dibGPIOFunction gpio_function[2];
-       struct dibSubbandSelection subband;
-
-       u8 output_mode;
-};
-
-#define DEFAULT_DIB9000_I2C_ADDRESS 18
-
-#if defined(CONFIG_DVB_DIB9000) || (defined(CONFIG_DVB_DIB9000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
-extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
-extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
-extern struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
-extern int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
-extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
-extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
-extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe);
-extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
-extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe);
-extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
-extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe);
-extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c);
-extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed);
-#else
-static inline struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib9000_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-
-static inline int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
deleted file mode 100644 (file)
index 43be723..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-
-#include "dibx000_common.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
-
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
-
-static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
-{
-       int ret;
-
-       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
-       mst->i2c_write_buffer[1] = reg & 0xff;
-       mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
-       mst->i2c_write_buffer[3] = val & 0xff;
-
-       memset(mst->msg, 0, sizeof(struct i2c_msg));
-       mst->msg[0].addr = mst->i2c_addr;
-       mst->msg[0].flags = 0;
-       mst->msg[0].buf = mst->i2c_write_buffer;
-       mst->msg[0].len = 4;
-
-       ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
-       mutex_unlock(&mst->i2c_buffer_lock);
-
-       return ret;
-}
-
-static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
-{
-       u16 ret;
-
-       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return 0;
-       }
-
-       mst->i2c_write_buffer[0] = reg >> 8;
-       mst->i2c_write_buffer[1] = reg & 0xff;
-
-       memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
-       mst->msg[0].addr = mst->i2c_addr;
-       mst->msg[0].flags = 0;
-       mst->msg[0].buf = mst->i2c_write_buffer;
-       mst->msg[0].len = 2;
-       mst->msg[1].addr = mst->i2c_addr;
-       mst->msg[1].flags = I2C_M_RD;
-       mst->msg[1].buf = mst->i2c_read_buffer;
-       mst->msg[1].len = 2;
-
-       if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
-               dprintk("i2c read error on %d", reg);
-
-       ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
-       mutex_unlock(&mst->i2c_buffer_lock);
-
-       return ret;
-}
-
-static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
-{
-       int i = 100;
-       u16 status;
-
-       while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
-               ;
-
-       /* i2c timed out */
-       if (i == 0)
-               return -EREMOTEIO;
-
-       /* no acknowledge */
-       if ((status & 0x0080) == 0)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
-{
-       u16 data;
-       u16 da;
-       u16 i;
-       u16 txlen = msg->len, len;
-       const u8 *b = msg->buf;
-
-       while (txlen) {
-               dibx000_read_word(mst, mst->base_reg + 2);
-
-               len = txlen > 8 ? 8 : txlen;
-               for (i = 0; i < len; i += 2) {
-                       data = *b++ << 8;
-                       if (i+1 < len)
-                               data |= *b++;
-                       dibx000_write_word(mst, mst->base_reg, data);
-               }
-               da = (((u8) (msg->addr))  << 9) |
-                       (1           << 8) |
-                       (1           << 7) |
-                       (0           << 6) |
-                       (0           << 5) |
-                       ((len & 0x7) << 2) |
-                       (0           << 1) |
-                       (0           << 0);
-
-               if (txlen == msg->len)
-                       da |= 1 << 5; /* start */
-
-               if (txlen-len == 0 && stop)
-                       da |= 1 << 6; /* stop */
-
-               dibx000_write_word(mst, mst->base_reg+1, da);
-
-               if (dibx000_is_i2c_done(mst) != 0)
-                       return -EREMOTEIO;
-               txlen -= len;
-       }
-
-       return 0;
-}
-
-static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
-{
-       u16 da;
-       u8 *b = msg->buf;
-       u16 rxlen = msg->len, len;
-
-       while (rxlen) {
-               len = rxlen > 8 ? 8 : rxlen;
-               da = (((u8) (msg->addr)) << 9) |
-                       (1           << 8) |
-                       (1           << 7) |
-                       (0           << 6) |
-                       (0           << 5) |
-                       ((len & 0x7) << 2) |
-                       (1           << 1) |
-                       (0           << 0);
-
-               if (rxlen == msg->len)
-                       da |= 1 << 5; /* start */
-
-               if (rxlen-len == 0)
-                       da |= 1 << 6; /* stop */
-               dibx000_write_word(mst, mst->base_reg+1, da);
-
-               if (dibx000_is_i2c_done(mst) != 0)
-                       return -EREMOTEIO;
-
-               rxlen -= len;
-
-               while (len) {
-                       da = dibx000_read_word(mst, mst->base_reg);
-                       *b++ = (da >> 8) & 0xff;
-                       len--;
-                       if (len >= 1) {
-                               *b++ =  da   & 0xff;
-                               len--;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
-{
-       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-
-       if (mst->device_rev < DIB7000MC && speed < 235)
-               speed = 235;
-       return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
-
-}
-EXPORT_SYMBOL(dibx000_i2c_set_speed);
-
-static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
-                                       enum dibx000_i2c_interface intf)
-{
-       if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
-               dprintk("selecting interface: %d", intf);
-               mst->selected_interface = intf;
-               return dibx000_write_word(mst, mst->base_reg + 4, intf);
-       }
-       return 0;
-}
-
-static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-       int msg_index;
-       int ret = 0;
-
-       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
-       for (msg_index = 0; msg_index < num; msg_index++) {
-               if (msg[msg_index].flags & I2C_M_RD) {
-                       ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
-                       if (ret != 0)
-                               return 0;
-               } else {
-                       ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
-                       if (ret != 0)
-                               return 0;
-               }
-       }
-
-       return num;
-}
-
-static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-       int msg_index;
-       int ret = 0;
-
-       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
-       for (msg_index = 0; msg_index < num; msg_index++) {
-               if (msg[msg_index].flags & I2C_M_RD) {
-                       ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
-                       if (ret != 0)
-                               return 0;
-               } else {
-                       ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
-                       if (ret != 0)
-                               return 0;
-               }
-       }
-
-       return num;
-}
-
-static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
-       .master_xfer = dibx000_i2c_master_xfer_gpio12,
-       .functionality = dibx000_i2c_func,
-};
-
-static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
-       .master_xfer = dibx000_i2c_master_xfer_gpio34,
-       .functionality = dibx000_i2c_func,
-};
-
-static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
-                                u8 addr, int onoff)
-{
-       u16 val;
-
-
-       if (onoff)
-               val = addr << 8;        // bit 7 = use master or not, if 0, the gate is open
-       else
-               val = 1 << 7;
-
-       if (mst->device_rev > DIB7000)
-               val <<= 1;
-
-       tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
-       tx[1] = ((mst->base_reg + 1) & 0xff);
-       tx[2] = val >> 8;
-       tx[3] = val & 0xff;
-
-       return 0;
-}
-
-static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
-                                       struct i2c_msg msg[], int num)
-{
-       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-       int ret;
-
-       if (num > 32) {
-               dprintk("%s: too much I2C message to be transmitted (%i).\
-                               Maximum is 32", __func__, num);
-               return -ENOMEM;
-       }
-
-       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
-
-       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-
-       memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
-
-       /* open the gate */
-       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
-       mst->msg[0].addr = mst->i2c_addr;
-       mst->msg[0].buf = &mst->i2c_write_buffer[0];
-       mst->msg[0].len = 4;
-
-       memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
-
-       /* close the gate */
-       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
-       mst->msg[num + 1].addr = mst->i2c_addr;
-       mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
-       mst->msg[num + 1].len = 4;
-
-       ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
-                       num : -EIO);
-
-       mutex_unlock(&mst->i2c_buffer_lock);
-       return ret;
-}
-
-static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
-       .master_xfer = dibx000_i2c_gated_gpio67_xfer,
-       .functionality = dibx000_i2c_func,
-};
-
-static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
-                                       struct i2c_msg msg[], int num)
-{
-       struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-       int ret;
-
-       if (num > 32) {
-               dprintk("%s: too much I2C message to be transmitted (%i).\
-                               Maximum is 32", __func__, num);
-               return -ENOMEM;
-       }
-
-       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
-
-       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-       memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
-
-       /* open the gate */
-       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
-       mst->msg[0].addr = mst->i2c_addr;
-       mst->msg[0].buf = &mst->i2c_write_buffer[0];
-       mst->msg[0].len = 4;
-
-       memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
-
-       /* close the gate */
-       dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
-       mst->msg[num + 1].addr = mst->i2c_addr;
-       mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
-       mst->msg[num + 1].len = 4;
-
-       ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
-                       num : -EIO);
-       mutex_unlock(&mst->i2c_buffer_lock);
-       return ret;
-}
-
-static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
-       .master_xfer = dibx000_i2c_gated_tuner_xfer,
-       .functionality = dibx000_i2c_func,
-};
-
-struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
-                                               enum dibx000_i2c_interface intf,
-                                               int gating)
-{
-       struct i2c_adapter *i2c = NULL;
-
-       switch (intf) {
-       case DIBX000_I2C_INTERFACE_TUNER:
-               if (gating)
-                       i2c = &mst->gated_tuner_i2c_adap;
-               break;
-       case DIBX000_I2C_INTERFACE_GPIO_1_2:
-               if (!gating)
-                       i2c = &mst->master_i2c_adap_gpio12;
-               break;
-       case DIBX000_I2C_INTERFACE_GPIO_3_4:
-               if (!gating)
-                       i2c = &mst->master_i2c_adap_gpio34;
-               break;
-       case DIBX000_I2C_INTERFACE_GPIO_6_7:
-               if (gating)
-                       i2c = &mst->master_i2c_adap_gpio67;
-               break;
-       default:
-               printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
-               break;
-       }
-
-       return i2c;
-}
-
-EXPORT_SYMBOL(dibx000_get_i2c_adapter);
-
-void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
-{
-       /* initialize the i2c-master by closing the gate */
-       u8 tx[4];
-       struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
-
-       dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
-       i2c_transfer(mst->i2c_adap, &m, 1);
-       mst->selected_interface = 0xff; // the first time force a select of the I2C
-       dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
-}
-
-EXPORT_SYMBOL(dibx000_reset_i2c_master);
-
-static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
-                               struct i2c_algorithm *algo, const char *name,
-                               struct dibx000_i2c_master *mst)
-{
-       strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
-       i2c_adap->algo = algo;
-       i2c_adap->algo_data = NULL;
-       i2c_set_adapdata(i2c_adap, mst);
-       if (i2c_add_adapter(i2c_adap) < 0)
-               return -ENODEV;
-       return 0;
-}
-
-int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
-                               struct i2c_adapter *i2c_adap, u8 i2c_addr)
-{
-       int ret;
-
-       mutex_init(&mst->i2c_buffer_lock);
-       if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
-               dprintk("could not acquire lock");
-               return -EINVAL;
-       }
-       memset(mst->msg, 0, sizeof(struct i2c_msg));
-       mst->msg[0].addr = i2c_addr >> 1;
-       mst->msg[0].flags = 0;
-       mst->msg[0].buf = mst->i2c_write_buffer;
-       mst->msg[0].len = 4;
-
-       mst->device_rev = device_rev;
-       mst->i2c_adap = i2c_adap;
-       mst->i2c_addr = i2c_addr >> 1;
-
-       if (device_rev == DIB7000P || device_rev == DIB8000)
-               mst->base_reg = 1024;
-       else
-               mst->base_reg = 768;
-
-       mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
-       if (i2c_adapter_init
-                       (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
-                        "DiBX000 tuner I2C bus", mst) != 0)
-               printk(KERN_ERR
-                               "DiBX000: could not initialize the tuner i2c_adapter\n");
-
-       mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
-       if (i2c_adapter_init
-                       (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
-                        "DiBX000 master GPIO12 I2C bus", mst) != 0)
-               printk(KERN_ERR
-                               "DiBX000: could not initialize the master i2c_adapter\n");
-
-       mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
-       if (i2c_adapter_init
-                       (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
-                        "DiBX000 master GPIO34 I2C bus", mst) != 0)
-               printk(KERN_ERR
-                               "DiBX000: could not initialize the master i2c_adapter\n");
-
-       mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
-       if (i2c_adapter_init
-                       (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
-                        "DiBX000 master GPIO67 I2C bus", mst) != 0)
-               printk(KERN_ERR
-                               "DiBX000: could not initialize the master i2c_adapter\n");
-
-       /* initialize the i2c-master by closing the gate */
-       dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
-
-       ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
-       mutex_unlock(&mst->i2c_buffer_lock);
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dibx000_init_i2c_master);
-
-void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
-{
-       i2c_del_adapter(&mst->gated_tuner_i2c_adap);
-       i2c_del_adapter(&mst->master_i2c_adap_gpio12);
-       i2c_del_adapter(&mst->master_i2c_adap_gpio34);
-       i2c_del_adapter(&mst->master_i2c_adap_gpio67);
-}
-EXPORT_SYMBOL(dibx000_exit_i2c_master);
-
-
-u32 systime(void)
-{
-       struct timespec t;
-
-       t = current_kernel_time();
-       return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
-}
-EXPORT_SYMBOL(systime);
-
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
deleted file mode 100644 (file)
index 5f48488..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-#ifndef DIBX000_COMMON_H
-#define DIBX000_COMMON_H
-
-enum dibx000_i2c_interface {
-       DIBX000_I2C_INTERFACE_TUNER = 0,
-       DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
-       DIBX000_I2C_INTERFACE_GPIO_3_4 = 2,
-       DIBX000_I2C_INTERFACE_GPIO_6_7 = 3
-};
-
-struct dibx000_i2c_master {
-#define DIB3000MC 1
-#define DIB7000   2
-#define DIB7000P  11
-#define DIB7000MC 12
-#define DIB8000   13
-       u16 device_rev;
-
-       enum dibx000_i2c_interface selected_interface;
-
-/*     struct i2c_adapter  tuner_i2c_adap; */
-       struct i2c_adapter gated_tuner_i2c_adap;
-       struct i2c_adapter master_i2c_adap_gpio12;
-       struct i2c_adapter master_i2c_adap_gpio34;
-       struct i2c_adapter master_i2c_adap_gpio67;
-
-       struct i2c_adapter *i2c_adap;
-       u8 i2c_addr;
-
-       u16 base_reg;
-
-       /* for the I2C transfer */
-       struct i2c_msg msg[34];
-       u8 i2c_write_buffer[8];
-       u8 i2c_read_buffer[2];
-       struct mutex i2c_buffer_lock;
-};
-
-extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
-                                       u16 device_rev, struct i2c_adapter *i2c_adap,
-                                       u8 i2c_addr);
-extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
-                                                       *mst,
-                                                       enum dibx000_i2c_interface
-                                                       intf, int gating);
-extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
-extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
-extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed);
-
-extern u32 systime(void);
-
-#define BAND_LBAND 0x01
-#define BAND_UHF   0x02
-#define BAND_VHF   0x04
-#define BAND_SBAND 0x08
-#define BAND_FM           0x10
-#define BAND_CBAND 0x20
-
-#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
-                                                                       (freq_kHz) <= 115000 ? BAND_FM : \
-                                                                       (freq_kHz) <= 250000 ? BAND_VHF : \
-                                                                       (freq_kHz) <= 863000 ? BAND_UHF : \
-                                                                       (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
-
-struct dibx000_agc_config {
-       /* defines the capabilities of this AGC-setting - using the BAND_-defines */
-       u8 band_caps;
-
-       u16 setup;
-
-       u16 inv_gain;
-       u16 time_stabiliz;
-
-       u8 alpha_level;
-       u16 thlock;
-
-       u8 wbd_inv;
-       u16 wbd_ref;
-       u8 wbd_sel;
-       u8 wbd_alpha;
-
-       u16 agc1_max;
-       u16 agc1_min;
-       u16 agc2_max;
-       u16 agc2_min;
-
-       u8 agc1_pt1;
-       u8 agc1_pt2;
-       u8 agc1_pt3;
-
-       u8 agc1_slope1;
-       u8 agc1_slope2;
-
-       u8 agc2_pt1;
-       u8 agc2_pt2;
-
-       u8 agc2_slope1;
-       u8 agc2_slope2;
-
-       u8 alpha_mant;
-       u8 alpha_exp;
-
-       u8 beta_mant;
-       u8 beta_exp;
-
-       u8 perform_agc_softsplit;
-
-       struct {
-               u16 min;
-               u16 max;
-               u16 min_thres;
-               u16 max_thres;
-       } split;
-};
-
-struct dibx000_bandwidth_config {
-       u32 internal;
-       u32 sampling;
-
-       u8 pll_prediv;
-       u8 pll_ratio;
-       u8 pll_range;
-       u8 pll_reset;
-       u8 pll_bypass;
-
-       u8 enable_refdiv;
-       u8 bypclk_div;
-       u8 IO_CLK_en_core;
-       u8 ADClkSrc;
-       u8 modulo;
-
-       u16 sad_cfg;
-
-       u32 ifreq;
-       u32 timf;
-
-       u32 xtal_hz;
-};
-
-enum dibx000_adc_states {
-       DIBX000_SLOW_ADC_ON = 0,
-       DIBX000_SLOW_ADC_OFF,
-       DIBX000_ADC_ON,
-       DIBX000_ADC_OFF,
-       DIBX000_VBG_ENABLE,
-       DIBX000_VBG_DISABLE,
-};
-
-#define BANDWIDTH_TO_KHZ(v)    ((v) / 1000)
-#define BANDWIDTH_TO_HZ(v)     ((v) * 1000)
-
-/* Chip output mode. */
-#define OUTMODE_HIGH_Z              0
-#define OUTMODE_MPEG2_PAR_GATED_CLK 1
-#define OUTMODE_MPEG2_PAR_CONT_CLK  2
-#define OUTMODE_MPEG2_SERIAL        7
-#define OUTMODE_DIVERSITY           4
-#define OUTMODE_MPEG2_FIFO          5
-#define OUTMODE_ANALOG_ADC          6
-
-#define INPUT_MODE_OFF                0x11
-#define INPUT_MODE_DIVERSITY          0x12
-#define INPUT_MODE_MPEG               0x13
-
-enum frontend_tune_state {
-       CT_TUNER_START = 10,
-       CT_TUNER_STEP_0,
-       CT_TUNER_STEP_1,
-       CT_TUNER_STEP_2,
-       CT_TUNER_STEP_3,
-       CT_TUNER_STEP_4,
-       CT_TUNER_STEP_5,
-       CT_TUNER_STEP_6,
-       CT_TUNER_STEP_7,
-       CT_TUNER_STOP,
-
-       CT_AGC_START = 20,
-       CT_AGC_STEP_0,
-       CT_AGC_STEP_1,
-       CT_AGC_STEP_2,
-       CT_AGC_STEP_3,
-       CT_AGC_STEP_4,
-       CT_AGC_STOP,
-
-       CT_DEMOD_START = 30,
-       CT_DEMOD_STEP_1,
-       CT_DEMOD_STEP_2,
-       CT_DEMOD_STEP_3,
-       CT_DEMOD_STEP_4,
-       CT_DEMOD_STEP_5,
-       CT_DEMOD_STEP_6,
-       CT_DEMOD_STEP_7,
-       CT_DEMOD_STEP_8,
-       CT_DEMOD_STEP_9,
-       CT_DEMOD_STEP_10,
-       CT_DEMOD_SEARCH_NEXT = 41,
-       CT_DEMOD_STEP_LOCKED,
-       CT_DEMOD_STOP,
-
-       CT_DONE = 100,
-       CT_SHUTDOWN,
-
-};
-
-struct dvb_frontend_parametersContext {
-#define CHANNEL_STATUS_PARAMETERS_UNKNOWN   0x01
-#define CHANNEL_STATUS_PARAMETERS_SET       0x02
-       u8 status;
-       u32 tune_time_estimation[2];
-       s32 tps_available;
-       u16 tps[9];
-};
-
-#define FE_STATUS_TUNE_FAILED          0
-#define FE_STATUS_TUNE_TIMED_OUT      -1
-#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
-#define FE_STATUS_TUNE_PENDING        -3
-#define FE_STATUS_STD_SUCCESS         -4
-#define FE_STATUS_FFT_SUCCESS         -5
-#define FE_STATUS_DEMOD_SUCCESS       -6
-#define FE_STATUS_LOCKED              -7
-#define FE_STATUS_DATA_LOCKED         -8
-
-#define FE_CALLBACK_TIME_NEVER 0xffffffff
-
-#define ABS(x) ((x < 0) ? (-x) : (x))
-
-#define DATA_BUS_ACCESS_MODE_8BIT                 0x01
-#define DATA_BUS_ACCESS_MODE_16BIT                0x02
-#define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10
-
-struct dibGPIOFunction {
-#define BOARD_GPIO_COMPONENT_BUS_ADAPTER 1
-#define BOARD_GPIO_COMPONENT_DEMOD       2
-       u8 component;
-
-#define BOARD_GPIO_FUNCTION_BOARD_ON      1
-#define BOARD_GPIO_FUNCTION_BOARD_OFF     2
-#define BOARD_GPIO_FUNCTION_COMPONENT_ON  3
-#define BOARD_GPIO_FUNCTION_COMPONENT_OFF 4
-#define BOARD_GPIO_FUNCTION_SUBBAND_PWM   5
-#define BOARD_GPIO_FUNCTION_SUBBAND_GPIO   6
-       u8 function;
-
-/* mask, direction and value are used specify which GPIO to change GPIO0
- * is LSB and possible GPIO31 is MSB.  The same bit-position as in the
- * mask is used for the direction and the value. Direction == 1 is OUT,
- * 0 == IN. For direction "OUT" value is either 1 or 0, for direction IN
- * value has no meaning.
- *
- * In case of BOARD_GPIO_FUNCTION_PWM mask is giving the GPIO to be
- * used to do the PWM. Direction gives the PWModulator to be used.
- * Value gives the PWM value in device-dependent scale.
- */
-       u32 mask;
-       u32 direction;
-       u32 value;
-};
-
-#define MAX_NB_SUBBANDS   8
-struct dibSubbandSelection {
-       u8  size; /* Actual number of subbands. */
-       struct {
-               u16 f_mhz;
-               struct dibGPIOFunction gpio;
-       } subband[MAX_NB_SUBBANDS];
-};
-
-#define DEMOD_TIMF_SET    0x00
-#define DEMOD_TIMF_GET    0x01
-#define DEMOD_TIMF_UPDATE 0x02
-
-#define MPEG_ON_DIBTX          1
-#define DIV_ON_DIBTX           2
-#define ADC_ON_DIBTX           3
-#define DEMOUT_ON_HOSTBUS      4
-#define DIBTX_ON_HOSTBUS       5
-#define MPEG_ON_HOSTBUS                6
-
-#endif
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h
deleted file mode 100644 (file)
index 216c8c3..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * drxd.h: DRXD DVB-T demodulator driver
- *
- * Copyright (C) 2005-2007 Micronas
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef _DRXD_H_
-#define _DRXD_H_
-
-#include <linux/types.h>
-#include <linux/i2c.h>
-
-struct drxd_config {
-       u8 index;
-
-       u8 pll_address;
-       u8 pll_type;
-#define DRXD_PLL_NONE     0
-#define DRXD_PLL_DTT7520X 1
-#define DRXD_PLL_MT3X0823 2
-
-       u32 clock;
-       u8 insert_rs_byte;
-
-       u8 demod_address;
-       u8 demoda_address;
-       u8 demod_revision;
-
-       /* If the tuner is not behind an i2c gate, be sure to flip this bit
-          or else the i2c bus could get wedged */
-       u8 disable_i2c_gate_ctrl;
-
-       u32 IF;
-        s16(*osc_deviation) (void *priv, s16 dev, int flag);
-};
-
-#if defined(CONFIG_DVB_DRXD) || \
-                       (defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE))
-extern
-struct dvb_frontend *drxd_attach(const struct drxd_config *config,
-                                void *priv, struct i2c_adapter *i2c,
-                                struct device *dev);
-#else
-static inline
-struct dvb_frontend *drxd_attach(const struct drxd_config *config,
-                                void *priv, struct i2c_adapter *i2c,
-                                struct device *dev)
-{
-       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
-              __func__);
-       return NULL;
-}
-#endif
-
-extern int drxd_config_i2c(struct dvb_frontend *, int);
-#endif
diff --git a/drivers/media/dvb/frontends/drxd_firm.c b/drivers/media/dvb/frontends/drxd_firm.c
deleted file mode 100644 (file)
index 5418b0b..0000000
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * drxd_firm.c : DRXD firmware tables
- *
- * Copyright (C) 2006-2007 Micronas
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-/* TODO: generate this file with a script from a settings file */
-
-/* Contains A2 firmware version: 1.4.2
- * Contains B1 firmware version: 3.3.33
- * Contains settings from driver 1.4.23
-*/
-
-#include "drxd_firm.h"
-
-#define ADDRESS(x)     ((x) & 0xFF), (((x)>>8) & 0xFF), (((x)>>16) & 0xFF), (((x)>>24) & 0xFF)
-#define LENGTH(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
-
-/* Is written via block write, must be little endian */
-#define DATA16(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
-
-#define WRBLOCK(a, l) ADDRESS(a), LENGTH(l)
-#define WR16(a, d) ADDRESS(a), LENGTH(1), DATA16(d)
-
-#define END_OF_TABLE      0xFF, 0xFF, 0xFF, 0xFF
-
-/* HI firmware patches */
-
-#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
-#define HI_TR_FUNC_SIZE 9      /* size of this function in instruction words */
-
-u8 DRXD_InitAtomicRead[] = {
-       WRBLOCK(HI_TR_FUNC_ADDR, HI_TR_FUNC_SIZE),
-       0x26, 0x00,             /* 0         -> ring.rdy;           */
-       0x60, 0x04,             /* r0rami.dt -> ring.xba;           */
-       0x61, 0x04,             /* r0rami.dt -> ring.xad;           */
-       0xE3, 0x07,             /* HI_RA_RAM_USR_BEGIN -> ring.iad; */
-       0x40, 0x00,             /* (long immediate)                 */
-       0x64, 0x04,             /* r0rami.dt -> ring.len;           */
-       0x65, 0x04,             /* r0rami.dt -> ring.ctl;           */
-       0x26, 0x00,             /* 0         -> ring.rdy;           */
-       0x38, 0x00,             /* 0         -> jumps.ad;           */
-       END_OF_TABLE
-};
-
-/* Pins D0 and D1 of the parallel MPEG output can be used
-   to set the I2C address of a device. */
-
-#define HI_RST_FUNC_ADDR (HI_IF_RAM_USR_BEGIN__A + HI_TR_FUNC_SIZE)
-#define HI_RST_FUNC_SIZE 54    /* size of this function in instruction words */
-
-/* D0 Version */
-u8 DRXD_HiI2cPatch_1[] = {
-       WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
-       0xC8, 0x07, 0x01, 0x00, /* MASK      -> reg0.dt;                        */
-       0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
-       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
-       0xA2, 0x00,             /* M_BNK_ID_DAT -> ring.iba;                    */
-       0x23, 0x00,             /* &data     -> ring.iad;                       */
-       0x24, 0x00,             /* 0         -> ring.len;                       */
-       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
-       0xC0, 0x07, 0xFF, 0x0F, /* -1        -> w0ram.dt;                       */
-       0x63, 0x00,             /* &data+1   -> ring.iad;                       */
-       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
-       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
-       0x23, 0x00,             /* &data     -> ring.iad;                       */
-       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
-       0x0F, 0x04,             /* r0ram.dt  -> and.op;                         */
-       0x1C, 0x06,             /* reg0.dt   -> and.tr;                         */
-       0xCF, 0x04,             /* and.rs    -> add.op;                         */
-       0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr;                        */
-       0xD0, 0x04,             /* add.rs    -> add.tr;                         */
-       0xC8, 0x04,             /* add.rs    -> reg0.dt;                        */
-       0x60, 0x00,             /* reg0.dt   -> w0ram.dt;                       */
-       0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
-       0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
-       0xC2, 0x07, 0x30, 0x00, /* CMD_BASE  -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x68, 0x00,             /* M_IC_SEL_PT1 -> i2c.sel;                     */
-       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
-       0x28, 0x00,             /* M_IC_SEL_PT0 -> i2c.sel;                     */
-       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
-       0xF8, 0x07, 0x2F, 0x00, /* 0x2F      -> jumps.ad;                       */
-
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-
-       /* Force quick and dirty reset */
-       WR16(B_HI_CT_REG_COMM_STATE__A, 0),
-       END_OF_TABLE
-};
-
-/* D0,D1 Version */
-u8 DRXD_HiI2cPatch_3[] = {
-       WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
-       0xC8, 0x07, 0x03, 0x00, /* MASK      -> reg0.dt;                        */
-       0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
-       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
-       0xA2, 0x00,             /* M_BNK_ID_DAT -> ring.iba;                    */
-       0x23, 0x00,             /* &data     -> ring.iad;                       */
-       0x24, 0x00,             /* 0         -> ring.len;                       */
-       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
-       0xC0, 0x07, 0xFF, 0x0F, /* -1        -> w0ram.dt;                       */
-       0x63, 0x00,             /* &data+1   -> ring.iad;                       */
-       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
-       0xA5, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
-       0x23, 0x00,             /* &data     -> ring.iad;                       */
-       0x65, 0x02,             /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
-       0x26, 0x00,             /* 0         -> ring.rdy;                       */
-       0x42, 0x00,             /* &data+1   -> w0ram.ad;                       */
-       0x0F, 0x04,             /* r0ram.dt  -> and.op;                         */
-       0x1C, 0x06,             /* reg0.dt   -> and.tr;                         */
-       0xCF, 0x04,             /* and.rs    -> add.op;                         */
-       0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr;                        */
-       0xD0, 0x04,             /* add.rs    -> add.tr;                         */
-       0xC8, 0x04,             /* add.rs    -> reg0.dt;                        */
-       0x60, 0x00,             /* reg0.dt   -> w0ram.dt;                       */
-       0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
-       0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x06,             /* reg0.dt   -> w0rami.dt;                      */
-       0xC2, 0x07, 0x30, 0x00, /* CMD_BASE  -> w0rami.ad;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x01, 0x00,             /* 0         -> w0rami.dt;                      */
-       0x68, 0x00,             /* M_IC_SEL_PT1 -> i2c.sel;                     */
-       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
-       0x28, 0x00,             /* M_IC_SEL_PT0 -> i2c.sel;                     */
-       0x29, 0x00,             /* M_IC_CMD_RESET -> i2c.cmd;                   */
-       0xF8, 0x07, 0x2F, 0x00, /* 0x2F      -> jumps.ad;                       */
-
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-       WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
-            (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
-
-       /* Force quick and dirty reset */
-       WR16(B_HI_CT_REG_COMM_STATE__A, 0),
-       END_OF_TABLE
-};
-
-u8 DRXD_ResetCEFR[] = {
-       WRBLOCK(CE_REG_FR_TREAL00__A, 57),
-       0x52, 0x00,             /* CE_REG_FR_TREAL00__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG00__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL01__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG01__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL02__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG02__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL03__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG03__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL04__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG04__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL05__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG05__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL06__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG06__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL07__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG07__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL08__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG08__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL09__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG09__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL10__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG10__A */
-       0x52, 0x00,             /* CE_REG_FR_TREAL11__A */
-       0x00, 0x00,             /* CE_REG_FR_TIMAG11__A */
-
-       0x52, 0x00,             /* CE_REG_FR_MID_TAP__A */
-
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G00__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G01__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G02__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G03__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G04__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G05__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G06__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G07__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G08__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G09__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G10__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G11__A */
-       0x0B, 0x00,             /* CE_REG_FR_SQS_G12__A */
-
-       0xFF, 0x01,             /* CE_REG_FR_RIO_G00__A */
-       0x90, 0x01,             /* CE_REG_FR_RIO_G01__A */
-       0x0B, 0x01,             /* CE_REG_FR_RIO_G02__A */
-       0xC8, 0x00,             /* CE_REG_FR_RIO_G03__A */
-       0xA0, 0x00,             /* CE_REG_FR_RIO_G04__A */
-       0x85, 0x00,             /* CE_REG_FR_RIO_G05__A */
-       0x72, 0x00,             /* CE_REG_FR_RIO_G06__A */
-       0x64, 0x00,             /* CE_REG_FR_RIO_G07__A */
-       0x59, 0x00,             /* CE_REG_FR_RIO_G08__A */
-       0x50, 0x00,             /* CE_REG_FR_RIO_G09__A */
-       0x49, 0x00,             /* CE_REG_FR_RIO_G10__A */
-
-       0x10, 0x00,             /* CE_REG_FR_MODE__A     */
-       0x78, 0x00,             /* CE_REG_FR_SQS_TRH__A  */
-       0x00, 0x00,             /* CE_REG_FR_RIO_GAIN__A */
-       0x00, 0x02,             /* CE_REG_FR_BYPASS__A   */
-       0x0D, 0x00,             /* CE_REG_FR_PM_SET__A   */
-       0x07, 0x00,             /* CE_REG_FR_ERR_SH__A   */
-       0x04, 0x00,             /* CE_REG_FR_MAN_SH__A   */
-       0x06, 0x00,             /* CE_REG_FR_TAP_SH__A   */
-
-       END_OF_TABLE
-};
-
-u8 DRXD_InitFEA2_1[] = {
-       WRBLOCK(FE_AD_REG_PD__A, 3),
-       0x00, 0x00,             /* FE_AD_REG_PD__A          */
-       0x01, 0x00,             /* FE_AD_REG_INVEXT__A      */
-       0x00, 0x00,             /* FE_AD_REG_CLKNEG__A      */
-
-       WRBLOCK(FE_AG_REG_DCE_AUR_CNT__A, 2),
-       0x10, 0x00,             /* FE_AG_REG_DCE_AUR_CNT__A */
-       0x10, 0x00,             /* FE_AG_REG_DCE_RUR_CNT__A */
-
-       WRBLOCK(FE_AG_REG_ACE_AUR_CNT__A, 2),
-       0x0E, 0x00,             /* FE_AG_REG_ACE_AUR_CNT__A */
-       0x00, 0x00,             /* FE_AG_REG_ACE_RUR_CNT__A */
-
-       WRBLOCK(FE_AG_REG_EGC_FLA_RGN__A, 5),
-       0x04, 0x00,             /* FE_AG_REG_EGC_FLA_RGN__A */
-       0x1F, 0x00,             /* FE_AG_REG_EGC_SLO_RGN__A */
-       0x00, 0x00,             /* FE_AG_REG_EGC_JMP_PSN__A */
-       0x00, 0x00,             /* FE_AG_REG_EGC_FLA_INC__A */
-       0x00, 0x00,             /* FE_AG_REG_EGC_FLA_DEC__A */
-
-       WRBLOCK(FE_AG_REG_GC1_AGC_MAX__A, 2),
-       0xFF, 0x01,             /* FE_AG_REG_GC1_AGC_MAX__A */
-       0x00, 0xFE,             /* FE_AG_REG_GC1_AGC_MIN__A */
-
-       WRBLOCK(FE_AG_REG_IND_WIN__A, 29),
-       0x00, 0x00,             /* FE_AG_REG_IND_WIN__A     */
-       0x05, 0x00,             /* FE_AG_REG_IND_THD_LOL__A */
-       0x0F, 0x00,             /* FE_AG_REG_IND_THD_HIL__A */
-       0x00, 0x00,             /* FE_AG_REG_IND_DEL__A     don't care */
-       0x1E, 0x00,             /* FE_AG_REG_IND_PD1_WRI__A */
-       0x0C, 0x00,             /* FE_AG_REG_PDA_AUR_CNT__A */
-       0x00, 0x00,             /* FE_AG_REG_PDA_RUR_CNT__A */
-       0x00, 0x00,             /* FE_AG_REG_PDA_AVE_DAT__A don't care  */
-       0x00, 0x00,             /* FE_AG_REG_PDC_RUR_CNT__A */
-       0x01, 0x00,             /* FE_AG_REG_PDC_SET_LVL__A */
-       0x02, 0x00,             /* FE_AG_REG_PDC_FLA_RGN__A */
-       0x00, 0x00,             /* FE_AG_REG_PDC_JMP_PSN__A don't care  */
-       0xFF, 0xFF,             /* FE_AG_REG_PDC_FLA_STP__A */
-       0xFF, 0xFF,             /* FE_AG_REG_PDC_SLO_STP__A */
-       0x00, 0x1F,             /* FE_AG_REG_PDC_PD2_WRI__A don't care  */
-       0x00, 0x00,             /* FE_AG_REG_PDC_MAP_DAT__A don't care  */
-       0x02, 0x00,             /* FE_AG_REG_PDC_MAX__A     */
-       0x0C, 0x00,             /* FE_AG_REG_TGA_AUR_CNT__A */
-       0x00, 0x00,             /* FE_AG_REG_TGA_RUR_CNT__A */
-       0x00, 0x00,             /* FE_AG_REG_TGA_AVE_DAT__A don't care  */
-       0x00, 0x00,             /* FE_AG_REG_TGC_RUR_CNT__A */
-       0x22, 0x00,             /* FE_AG_REG_TGC_SET_LVL__A */
-       0x15, 0x00,             /* FE_AG_REG_TGC_FLA_RGN__A */
-       0x00, 0x00,             /* FE_AG_REG_TGC_JMP_PSN__A don't care  */
-       0x01, 0x00,             /* FE_AG_REG_TGC_FLA_STP__A */
-       0x0A, 0x00,             /* FE_AG_REG_TGC_SLO_STP__A */
-       0x00, 0x00,             /* FE_AG_REG_TGC_MAP_DAT__A don't care  */
-       0x10, 0x00,             /* FE_AG_REG_FGA_AUR_CNT__A */
-       0x10, 0x00,             /* FE_AG_REG_FGA_RUR_CNT__A */
-
-       WRBLOCK(FE_AG_REG_BGC_FGC_WRI__A, 2),
-       0x00, 0x00,             /* FE_AG_REG_BGC_FGC_WRI__A */
-       0x00, 0x00,             /* FE_AG_REG_BGC_CGC_WRI__A */
-
-       WRBLOCK(FE_FD_REG_SCL__A, 3),
-       0x05, 0x00,             /* FE_FD_REG_SCL__A         */
-       0x03, 0x00,             /* FE_FD_REG_MAX_LEV__A     */
-       0x05, 0x00,             /* FE_FD_REG_NR__A          */
-
-       WRBLOCK(FE_CF_REG_SCL__A, 5),
-       0x16, 0x00,             /* FE_CF_REG_SCL__A         */
-       0x04, 0x00,             /* FE_CF_REG_MAX_LEV__A     */
-       0x06, 0x00,             /* FE_CF_REG_NR__A          */
-       0x00, 0x00,             /* FE_CF_REG_IMP_VAL__A     */
-       0x01, 0x00,             /* FE_CF_REG_MEAS_VAL__A    */
-
-       WRBLOCK(FE_CU_REG_FRM_CNT_RST__A, 2),
-       0x00, 0x08,             /* FE_CU_REG_FRM_CNT_RST__A */
-       0x00, 0x00,             /* FE_CU_REG_FRM_CNT_STR__A */
-
-       END_OF_TABLE
-};
-
-   /* with PGA */
-/*   WR16COND( DRXD_WITH_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0004), */
-   /* without PGA */
-/*   WR16COND( DRXD_WITHOUT_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0001), */
-/*   WR16(FE_AG_REG_AG_AGC_SIO__A,  (extAttr -> FeAgRegAgAgcSio), 0x0000 );*/
-/*   WR16(FE_AG_REG_AG_PWD__A        ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
-
-u8 DRXD_InitFEA2_2[] = {
-       WR16(FE_AG_REG_CDR_RUR_CNT__A, 0x0010),
-       WR16(FE_AG_REG_FGM_WRI__A, 48),
-       /* Activate measurement, activate scale */
-       WR16(FE_FD_REG_MEAS_VAL__A, 0x0001),
-
-       WR16(FE_CU_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_CF_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_IF_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_FD_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_FS_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_AD_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_AG_REG_COMM_EXEC__A, 0x0001),
-       WR16(FE_AG_REG_AG_MODE_LOP__A, 0x895E),
-
-       END_OF_TABLE
-};
-
-u8 DRXD_InitFEB1_1[] = {
-       WR16(B_FE_AD_REG_PD__A, 0x0000),
-       WR16(B_FE_AD_REG_CLKNEG__A, 0x0000),
-       WR16(B_FE_AG_REG_BGC_FGC_WRI__A, 0x0000),
-       WR16(B_FE_AG_REG_BGC_CGC_WRI__A, 0x0000),
-       WR16(B_FE_AG_REG_AG_MODE_LOP__A, 0x000a),
-       WR16(B_FE_AG_REG_IND_PD1_WRI__A, 35),
-       WR16(B_FE_AG_REG_IND_WIN__A, 0),
-       WR16(B_FE_AG_REG_IND_THD_LOL__A, 8),
-       WR16(B_FE_AG_REG_IND_THD_HIL__A, 8),
-       WR16(B_FE_CF_REG_IMP_VAL__A, 1),
-       WR16(B_FE_AG_REG_EGC_FLA_RGN__A, 7),
-       END_OF_TABLE
-};
-
-       /* with PGA */
-/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   , 0x0000, 0x0000); */
-       /* without PGA */
-/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   ,
-            B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);*/
-                                                                            /*   WR16(B_FE_AG_REG_AG_AGC_SIO__A,(extAttr -> FeAgRegAgAgcSio), 0x0000 );*//*added HS 23-05-2005 */
-/*   WR16(B_FE_AG_REG_AG_PWD__A    ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
-
-u8 DRXD_InitFEB1_2[] = {
-       WR16(B_FE_COMM_EXEC__A, 0x0001),
-
-       /* RF-AGC setup */
-       WR16(B_FE_AG_REG_PDA_AUR_CNT__A, 0x0C),
-       WR16(B_FE_AG_REG_PDC_SET_LVL__A, 0x01),
-       WR16(B_FE_AG_REG_PDC_FLA_RGN__A, 0x02),
-       WR16(B_FE_AG_REG_PDC_FLA_STP__A, 0xFFFF),
-       WR16(B_FE_AG_REG_PDC_SLO_STP__A, 0xFFFF),
-       WR16(B_FE_AG_REG_PDC_MAX__A, 0x02),
-       WR16(B_FE_AG_REG_TGA_AUR_CNT__A, 0x0C),
-       WR16(B_FE_AG_REG_TGC_SET_LVL__A, 0x22),
-       WR16(B_FE_AG_REG_TGC_FLA_RGN__A, 0x15),
-       WR16(B_FE_AG_REG_TGC_FLA_STP__A, 0x01),
-       WR16(B_FE_AG_REG_TGC_SLO_STP__A, 0x0A),
-
-       WR16(B_FE_CU_REG_DIV_NFC_CLP__A, 0),
-       WR16(B_FE_CU_REG_CTR_NFC_OCR__A, 25000),
-       WR16(B_FE_CU_REG_CTR_NFC_ICR__A, 1),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitCPA2[] = {
-       WRBLOCK(CP_REG_BR_SPL_OFFSET__A, 2),
-       0x07, 0x00,             /* CP_REG_BR_SPL_OFFSET__A  */
-       0x0A, 0x00,             /* CP_REG_BR_STR_DEL__A     */
-
-       WRBLOCK(CP_REG_RT_ANG_INC0__A, 4),
-       0x00, 0x00,             /* CP_REG_RT_ANG_INC0__A    */
-       0x00, 0x00,             /* CP_REG_RT_ANG_INC1__A    */
-       0x03, 0x00,             /* CP_REG_RT_DETECT_ENA__A  */
-       0x03, 0x00,             /* CP_REG_RT_DETECT_TRH__A  */
-
-       WRBLOCK(CP_REG_AC_NEXP_OFFS__A, 5),
-       0x32, 0x00,             /* CP_REG_AC_NEXP_OFFS__A   */
-       0x62, 0x00,             /* CP_REG_AC_AVER_POW__A    */
-       0x82, 0x00,             /* CP_REG_AC_MAX_POW__A     */
-       0x26, 0x00,             /* CP_REG_AC_WEIGHT_MAN__A  */
-       0x0F, 0x00,             /* CP_REG_AC_WEIGHT_EXP__A  */
-
-       WRBLOCK(CP_REG_AC_AMP_MODE__A, 2),
-       0x02, 0x00,             /* CP_REG_AC_AMP_MODE__A    */
-       0x01, 0x00,             /* CP_REG_AC_AMP_FIX__A     */
-
-       WR16(CP_REG_INTERVAL__A, 0x0005),
-       WR16(CP_REG_RT_EXP_MARG__A, 0x0004),
-       WR16(CP_REG_AC_ANG_MODE__A, 0x0003),
-
-       WR16(CP_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitCPB1[] = {
-       WR16(B_CP_REG_BR_SPL_OFFSET__A, 0x0008),
-       WR16(B_CP_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitCEA2[] = {
-       WRBLOCK(CE_REG_AVG_POW__A, 4),
-       0x62, 0x00,             /* CE_REG_AVG_POW__A        */
-       0x78, 0x00,             /* CE_REG_MAX_POW__A        */
-       0x62, 0x00,             /* CE_REG_ATT__A            */
-       0x17, 0x00,             /* CE_REG_NRED__A           */
-
-       WRBLOCK(CE_REG_NE_ERR_SELECT__A, 2),
-       0x07, 0x00,             /* CE_REG_NE_ERR_SELECT__A  */
-       0xEB, 0xFF,             /* CE_REG_NE_TD_CAL__A      */
-
-       WRBLOCK(CE_REG_NE_MIXAVG__A, 2),
-       0x06, 0x00,             /* CE_REG_NE_MIXAVG__A      */
-       0x00, 0x00,             /* CE_REG_NE_NUPD_OFS__A    */
-
-       WRBLOCK(CE_REG_PE_NEXP_OFFS__A, 2),
-       0x00, 0x00,             /* CE_REG_PE_NEXP_OFFS__A   */
-       0x00, 0x00,             /* CE_REG_PE_TIMESHIFT__A   */
-
-       WRBLOCK(CE_REG_TP_A0_TAP_NEW__A, 3),
-       0x00, 0x01,             /* CE_REG_TP_A0_TAP_NEW__A       */
-       0x01, 0x00,             /* CE_REG_TP_A0_TAP_NEW_VALID__A */
-       0x0E, 0x00,             /* CE_REG_TP_A0_MU_LMS_STEP__A   */
-
-       WRBLOCK(CE_REG_TP_A1_TAP_NEW__A, 3),
-       0x00, 0x00,             /* CE_REG_TP_A1_TAP_NEW__A        */
-       0x01, 0x00,             /* CE_REG_TP_A1_TAP_NEW_VALID__A  */
-       0x0A, 0x00,             /* CE_REG_TP_A1_MU_LMS_STEP__A    */
-
-       WRBLOCK(CE_REG_FI_SHT_INCR__A, 2),
-       0x12, 0x00,             /* CE_REG_FI_SHT_INCR__A          */
-       0x0C, 0x00,             /* CE_REG_FI_EXP_NORM__A          */
-
-       WRBLOCK(CE_REG_IR_INPUTSEL__A, 3),
-       0x00, 0x00,             /* CE_REG_IR_INPUTSEL__A          */
-       0x00, 0x00,             /* CE_REG_IR_STARTPOS__A          */
-       0xFF, 0x00,             /* CE_REG_IR_NEXP_THRES__A        */
-
-       WR16(CE_REG_TI_NEXP_OFFS__A, 0x0000),
-
-       END_OF_TABLE
-};
-
-u8 DRXD_InitCEB1[] = {
-       WR16(B_CE_REG_TI_PHN_ENABLE__A, 0x0001),
-       WR16(B_CE_REG_FR_PM_SET__A, 0x000D),
-
-       END_OF_TABLE
-};
-
-u8 DRXD_InitEQA2[] = {
-       WRBLOCK(EQ_REG_OT_QNT_THRES0__A, 4),
-       0x1E, 0x00,             /* EQ_REG_OT_QNT_THRES0__A        */
-       0x1F, 0x00,             /* EQ_REG_OT_QNT_THRES1__A        */
-       0x06, 0x00,             /* EQ_REG_OT_CSI_STEP__A          */
-       0x02, 0x00,             /* EQ_REG_OT_CSI_OFFSET__A        */
-
-       WR16(EQ_REG_TD_REQ_SMB_CNT__A, 0x0200),
-       WR16(EQ_REG_IS_CLIP_EXP__A, 0x001F),
-       WR16(EQ_REG_SN_OFFSET__A, (u16) (-7)),
-       WR16(EQ_REG_RC_SEL_CAR__A, 0x0002),
-       WR16(EQ_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitEQB1[] = {
-       WR16(B_EQ_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_ResetECRAM[] = {
-       /* Reset packet sync bytes in EC_VD ram */
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
-
-       /* Reset packet sync bytes in EC_RS ram */
-       WR16(EC_RS_EC_RAM__A, 0x0000),
-       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitECA2[] = {
-       WRBLOCK(EC_SB_REG_CSI_HI__A, 6),
-       0x1F, 0x00,             /* EC_SB_REG_CSI_HI__A            */
-       0x1E, 0x00,             /* EC_SB_REG_CSI_LO__A            */
-       0x01, 0x00,             /* EC_SB_REG_SMB_TGL__A           */
-       0x7F, 0x00,             /* EC_SB_REG_SNR_HI__A            */
-       0x7F, 0x00,             /* EC_SB_REG_SNR_MID__A           */
-       0x7F, 0x00,             /* EC_SB_REG_SNR_LO__A            */
-
-       WRBLOCK(EC_RS_REG_REQ_PCK_CNT__A, 2),
-       0x00, 0x10,             /* EC_RS_REG_REQ_PCK_CNT__A       */
-       DATA16(EC_RS_REG_VAL_PCK),      /* EC_RS_REG_VAL__A               */
-
-       WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
-       0x03, 0x00,             /* EC_OC_REG_TMD_TOP_MODE__A      */
-       0xF4, 0x01,             /* EC_OC_REG_TMD_TOP_CNT__A       */
-       0xC0, 0x03,             /* EC_OC_REG_TMD_HIL_MAR__A       */
-       0x40, 0x00,             /* EC_OC_REG_TMD_LOL_MAR__A       */
-       0x03, 0x00,             /* EC_OC_REG_TMD_CUR_CNT__A       */
-
-       WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
-       0x06, 0x00,             /* EC_OC_REG_AVR_ASH_CNT__A       */
-       0x02, 0x00,             /* EC_OC_REG_AVR_BSH_CNT__A       */
-
-       WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
-       0x07, 0x00,             /* EC_OC_REG_RCN_MODE__A          */
-       0x00, 0x00,             /* EC_OC_REG_RCN_CRA_LOP__A       */
-       0xc0, 0x00,             /* EC_OC_REG_RCN_CRA_HIP__A       */
-       0x00, 0x10,             /* EC_OC_REG_RCN_CST_LOP__A       */
-       0x00, 0x00,             /* EC_OC_REG_RCN_CST_HIP__A       */
-       0xFF, 0x01,             /* EC_OC_REG_RCN_SET_LVL__A       */
-       0x0D, 0x00,             /* EC_OC_REG_RCN_GAI_LVL__A       */
-
-       WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
-       0x00, 0x00,             /* EC_OC_REG_RCN_CLP_LOP__A       */
-       0xC0, 0x00,             /* EC_OC_REG_RCN_CLP_HIP__A       */
-
-       WR16(EC_SB_REG_CSI_OFS__A, 0x0001),
-       WR16(EC_VD_REG_FORCE__A, 0x0002),
-       WR16(EC_VD_REG_REQ_SMB_CNT__A, 0x0001),
-       WR16(EC_VD_REG_RLK_ENA__A, 0x0001),
-       WR16(EC_OD_REG_SYNC__A, 0x0664),
-       WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
-       WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
-       /* Output zero on monitorbus pads, power saving */
-       WR16(EC_OC_REG_OCR_MON_UOS__A,
-            (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
-       WR16(EC_OC_REG_OCR_MON_WRI__A,
-            EC_OC_REG_OCR_MON_WRI_INIT),
-
-/*   CHK_ERROR(ResetECRAM(demod)); */
-       /* Reset packet sync bytes in EC_VD ram */
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
-
-       /* Reset packet sync bytes in EC_RS ram */
-       WR16(EC_RS_EC_RAM__A, 0x0000),
-       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
-
-       WR16(EC_SB_REG_COMM_EXEC__A, 0x0001),
-       WR16(EC_VD_REG_COMM_EXEC__A, 0x0001),
-       WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
-       WR16(EC_RS_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitECB1[] = {
-       WR16(B_EC_SB_REG_CSI_OFS0__A, 0x0001),
-       WR16(B_EC_SB_REG_CSI_OFS1__A, 0x0001),
-       WR16(B_EC_SB_REG_CSI_OFS2__A, 0x0001),
-       WR16(B_EC_SB_REG_CSI_LO__A, 0x000c),
-       WR16(B_EC_SB_REG_CSI_HI__A, 0x0018),
-       WR16(B_EC_SB_REG_SNR_HI__A, 0x007f),
-       WR16(B_EC_SB_REG_SNR_MID__A, 0x007f),
-       WR16(B_EC_SB_REG_SNR_LO__A, 0x007f),
-
-       WR16(B_EC_OC_REG_DTO_CLKMODE__A, 0x0002),
-       WR16(B_EC_OC_REG_DTO_PER__A, 0x0006),
-       WR16(B_EC_OC_REG_DTO_BUR__A, 0x0001),
-       WR16(B_EC_OC_REG_RCR_CLKMODE__A, 0x0000),
-       WR16(B_EC_OC_REG_RCN_GAI_LVL__A, 0x000D),
-       WR16(B_EC_OC_REG_OC_MPG_SIO__A, 0x0000),
-
-       /* Needed because shadow registers do not have correct default value */
-       WR16(B_EC_OC_REG_RCN_CST_LOP__A, 0x1000),
-       WR16(B_EC_OC_REG_RCN_CST_HIP__A, 0x0000),
-       WR16(B_EC_OC_REG_RCN_CRA_LOP__A, 0x0000),
-       WR16(B_EC_OC_REG_RCN_CRA_HIP__A, 0x00C0),
-       WR16(B_EC_OC_REG_RCN_CLP_LOP__A, 0x0000),
-       WR16(B_EC_OC_REG_RCN_CLP_HIP__A, 0x00C0),
-       WR16(B_EC_OC_REG_DTO_INC_LOP__A, 0x0000),
-       WR16(B_EC_OC_REG_DTO_INC_HIP__A, 0x00C0),
-
-       WR16(B_EC_OD_REG_SYNC__A, 0x0664),
-       WR16(B_EC_RS_REG_REQ_PCK_CNT__A, 0x1000),
-
-/*   CHK_ERROR(ResetECRAM(demod)); */
-       /* Reset packet sync bytes in EC_VD ram */
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
-
-       /* Reset packet sync bytes in EC_RS ram */
-       WR16(EC_RS_EC_RAM__A, 0x0000),
-       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
-
-       WR16(B_EC_SB_REG_COMM_EXEC__A, 0x0001),
-       WR16(B_EC_VD_REG_COMM_EXEC__A, 0x0001),
-       WR16(B_EC_OD_REG_COMM_EXEC__A, 0x0001),
-       WR16(B_EC_RS_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_ResetECA2[] = {
-
-       WR16(EC_OC_REG_COMM_EXEC__A, 0x0000),
-       WR16(EC_OD_REG_COMM_EXEC__A, 0x0000),
-
-       WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
-       0x03, 0x00,             /* EC_OC_REG_TMD_TOP_MODE__A      */
-       0xF4, 0x01,             /* EC_OC_REG_TMD_TOP_CNT__A       */
-       0xC0, 0x03,             /* EC_OC_REG_TMD_HIL_MAR__A       */
-       0x40, 0x00,             /* EC_OC_REG_TMD_LOL_MAR__A       */
-       0x03, 0x00,             /* EC_OC_REG_TMD_CUR_CNT__A       */
-
-       WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
-       0x06, 0x00,             /* EC_OC_REG_AVR_ASH_CNT__A       */
-       0x02, 0x00,             /* EC_OC_REG_AVR_BSH_CNT__A       */
-
-       WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
-       0x07, 0x00,             /* EC_OC_REG_RCN_MODE__A          */
-       0x00, 0x00,             /* EC_OC_REG_RCN_CRA_LOP__A       */
-       0xc0, 0x00,             /* EC_OC_REG_RCN_CRA_HIP__A       */
-       0x00, 0x10,             /* EC_OC_REG_RCN_CST_LOP__A       */
-       0x00, 0x00,             /* EC_OC_REG_RCN_CST_HIP__A       */
-       0xFF, 0x01,             /* EC_OC_REG_RCN_SET_LVL__A       */
-       0x0D, 0x00,             /* EC_OC_REG_RCN_GAI_LVL__A       */
-
-       WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
-       0x00, 0x00,             /* EC_OC_REG_RCN_CLP_LOP__A       */
-       0xC0, 0x00,             /* EC_OC_REG_RCN_CLP_HIP__A       */
-
-       WR16(EC_OD_REG_SYNC__A, 0x0664),
-       WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
-       WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
-       /* Output zero on monitorbus pads, power saving */
-       WR16(EC_OC_REG_OCR_MON_UOS__A,
-            (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
-             EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
-       WR16(EC_OC_REG_OCR_MON_WRI__A,
-            EC_OC_REG_OCR_MON_WRI_INIT),
-
-/*   CHK_ERROR(ResetECRAM(demod)); */
-       /* Reset packet sync bytes in EC_VD ram */
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
-       WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
-
-       /* Reset packet sync bytes in EC_RS ram */
-       WR16(EC_RS_EC_RAM__A, 0x0000),
-       WR16(EC_RS_EC_RAM__A + 204, 0x0000),
-
-       WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_InitSC[] = {
-       WR16(SC_COMM_EXEC__A, 0),
-       WR16(SC_COMM_STATE__A, 0),
-
-#ifdef COMPILE_FOR_QT
-       WR16(SC_RA_RAM_BE_OPT_DELAY__A, 0x100),
-#endif
-
-       /* SC is not started, this is done in SetChannels() */
-       END_OF_TABLE
-};
-
-/* Diversity settings */
-
-u8 DRXD_InitDiversityFront[] = {
-       /* Start demod ********* RF in , diversity out **************************** */
-       WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
-            B_SC_RA_RAM_CONFIG_FREQSCAN__M),
-
-       WR16(B_SC_RA_RAM_LC_ABS_2K__A, 0x7),
-       WR16(B_SC_RA_RAM_LC_ABS_8K__A, 0x7),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
-
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
-
-       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
-       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
-       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
-
-       WR16(B_CC_REG_DIVERSITY__A, 0x0001),
-       WR16(B_EC_OC_REG_OC_MODE_HIP__A, 0x0010),
-       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |
-            B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
-
-       /*    0x2a ), *//* CE to PASS mux */
-
-       END_OF_TABLE
-};
-
-u8 DRXD_InitDiversityEnd[] = {
-       /* End demod *********** combining RF in and diversity in, MPEG TS out **** */
-       /* disable near/far; switch on timing slave mode */
-       WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
-            B_SC_RA_RAM_CONFIG_FREQSCAN__M |
-            B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M |
-            B_SC_RA_RAM_CONFIG_SLAVE__M |
-            B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M
-/* MV from CtrlDiversity */
-           ),
-#ifdef DRXDDIV_SRMM_SLAVING
-       WR16(SC_RA_RAM_LC_ABS_2K__A, 0x3c7),
-       WR16(SC_RA_RAM_LC_ABS_8K__A, 0x3c7),
-#else
-       WR16(SC_RA_RAM_LC_ABS_2K__A, 0x7),
-       WR16(SC_RA_RAM_LC_ABS_8K__A, 0x7),
-#endif
-
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
-
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
-
-       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
-       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
-       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
-
-       WR16(B_CC_REG_DIVERSITY__A, 0x0001),
-       END_OF_TABLE
-};
-
-u8 DRXD_DisableDiversity[] = {
-       WR16(B_SC_RA_RAM_LC_ABS_2K__A, B_SC_RA_RAM_LC_ABS_2K__PRE),
-       WR16(B_SC_RA_RAM_LC_ABS_8K__A, B_SC_RA_RAM_LC_ABS_8K__PRE),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A,
-            B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A,
-            B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE),
-       WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A,
-            B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A,
-            B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A,
-            B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A,
-            B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE),
-
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A,
-            B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A,
-            B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE),
-       WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A,
-            B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A,
-            B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A,
-            B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE),
-       WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A,
-            B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE),
-
-       WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, B_LC_RA_RAM_FILTER_CRMM_A__PRE),
-       WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, B_LC_RA_RAM_FILTER_CRMM_B__PRE),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, B_LC_RA_RAM_FILTER_SRMM_A__PRE),
-       WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, B_LC_RA_RAM_FILTER_SRMM_B__PRE),
-       WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, B_LC_RA_RAM_FILTER_SYM_SET__PRE),
-
-       WR16(B_CC_REG_DIVERSITY__A, 0x0000),
-       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_INIT), /* combining disabled */
-
-       END_OF_TABLE
-};
-
-u8 DRXD_StartDiversityFront[] = {
-       /* Start demod, RF in and diversity out, no combining */
-       WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),
-       WR16(B_FE_AD_REG_FDB_IN__A, 0x0),
-       WR16(B_FE_AD_REG_INVEXT__A, 0x0),
-       WR16(B_EQ_REG_COMM_MB__A, 0x12),        /* EQ to MB out */
-       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |    /* CE to PASS mux */
-            B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
-
-       WR16(SC_RA_RAM_ECHO_SHIFT_LIM__A, 2),
-
-       END_OF_TABLE
-};
-
-u8 DRXD_StartDiversityEnd[] = {
-       /* End demod, combining RF in and diversity in, MPEG TS out */
-       WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),      /* disable impulse noise cruncher */
-       WR16(B_FE_AD_REG_INVEXT__A, 0x0),       /* clock inversion (for sohard board) */
-       WR16(B_CP_REG_BR_STR_DEL__A, 10),       /* apperently no mb delay matching is best */
-
-       WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_DIV_ON |       /* org = 0x81 combining enabled */
-            B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
-            B_EQ_REG_RC_SEL_CAR_PASS_A_CC | B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC),
-
-       END_OF_TABLE
-};
-
-u8 DRXD_DiversityDelay8MHZ[] = {
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1150 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1100 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 1000 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 800 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5420 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5200 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4800 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 4000 - 50),
-       END_OF_TABLE
-};
-
-u8 DRXD_DiversityDelay6MHZ[] = /* also used ok for 7 MHz */
-{
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1100 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1000 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 900 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 600 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5300 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5000 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4500 - 50),
-       WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 3500 - 50),
-       END_OF_TABLE
-};
diff --git a/drivers/media/dvb/frontends/drxd_firm.h b/drivers/media/dvb/frontends/drxd_firm.h
deleted file mode 100644 (file)
index 41597e8..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * drxd_firm.h
- *
- * Copyright (C) 2006-2007 Micronas
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef _DRXD_FIRM_H_
-#define _DRXD_FIRM_H_
-
-#include <linux/types.h>
-#include "drxd_map_firm.h"
-
-#define VERSION_MAJOR 1
-#define VERSION_MINOR 4
-#define VERSION_PATCH 23
-
-#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
-
-#define DRXD_MAX_RETRIES (1000)
-#define HI_I2C_DELAY     84
-#define HI_I2C_BRIDGE_DELAY   750
-
-#define EQ_TD_TPS_PWR_UNKNOWN          0x00C0  /* Unknown configurations */
-#define EQ_TD_TPS_PWR_QPSK             0x016a
-#define EQ_TD_TPS_PWR_QAM16_ALPHAN     0x0195
-#define EQ_TD_TPS_PWR_QAM16_ALPHA1     0x0195
-#define EQ_TD_TPS_PWR_QAM16_ALPHA2     0x011E
-#define EQ_TD_TPS_PWR_QAM16_ALPHA4     0x01CE
-#define EQ_TD_TPS_PWR_QAM64_ALPHAN     0x019F
-#define EQ_TD_TPS_PWR_QAM64_ALPHA1     0x019F
-#define EQ_TD_TPS_PWR_QAM64_ALPHA2     0x00F8
-#define EQ_TD_TPS_PWR_QAM64_ALPHA4     0x014D
-
-#define DRXD_DEF_AG_PWD_CONSUMER 0x000E
-#define DRXD_DEF_AG_PWD_PRO 0x0000
-#define DRXD_DEF_AG_AGC_SIO 0x0000
-
-#define DRXD_FE_CTRL_MAX 1023
-
-#define DRXD_OSCDEV_DO_SCAN  (16)
-
-#define DRXD_OSCDEV_DONT_SCAN  (0)
-
-#define DRXD_OSCDEV_STEP  (275)
-
-#define DRXD_SCAN_TIMEOUT    (650)
-
-#define DRXD_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
-#define DRXD_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
-#define DRXD_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
-
-#define IRLEN_COARSE_8K       (10)
-#define IRLEN_FINE_8K         (10)
-#define IRLEN_COARSE_2K       (7)
-#define IRLEN_FINE_2K         (9)
-#define DIFF_INVALID          (511)
-#define DIFF_TARGET           (4)
-#define DIFF_MARGIN           (1)
-
-extern u8 DRXD_InitAtomicRead[];
-extern u8 DRXD_HiI2cPatch_1[];
-extern u8 DRXD_HiI2cPatch_3[];
-
-extern u8 DRXD_InitSC[];
-
-extern u8 DRXD_ResetCEFR[];
-extern u8 DRXD_InitFEA2_1[];
-extern u8 DRXD_InitFEA2_2[];
-extern u8 DRXD_InitCPA2[];
-extern u8 DRXD_InitCEA2[];
-extern u8 DRXD_InitEQA2[];
-extern u8 DRXD_InitECA2[];
-extern u8 DRXD_ResetECA2[];
-extern u8 DRXD_ResetECRAM[];
-
-extern u8 DRXD_A2_microcode[];
-extern u32 DRXD_A2_microcode_length;
-
-extern u8 DRXD_InitFEB1_1[];
-extern u8 DRXD_InitFEB1_2[];
-extern u8 DRXD_InitCPB1[];
-extern u8 DRXD_InitCEB1[];
-extern u8 DRXD_InitEQB1[];
-extern u8 DRXD_InitECB1[];
-
-extern u8 DRXD_InitDiversityFront[];
-extern u8 DRXD_InitDiversityEnd[];
-extern u8 DRXD_DisableDiversity[];
-extern u8 DRXD_StartDiversityFront[];
-extern u8 DRXD_StartDiversityEnd[];
-
-extern u8 DRXD_DiversityDelay8MHZ[];
-extern u8 DRXD_DiversityDelay6MHZ[];
-
-extern u8 DRXD_B1_microcode[];
-extern u32 DRXD_B1_microcode_length;
-
-#endif
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c
deleted file mode 100644 (file)
index f380eb4..0000000
+++ /dev/null
@@ -1,2992 +0,0 @@
-/*
- * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
- *
- * Copyright (C) 2003-2007 Micronas
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/i2c.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "drxd.h"
-#include "drxd_firm.h"
-
-#define DRX_FW_FILENAME_A2 "drxd-a2-1.1.fw"
-#define DRX_FW_FILENAME_B1 "drxd-b1-1.1.fw"
-
-#define CHUNK_SIZE 48
-
-#define DRX_I2C_RMW           0x10
-#define DRX_I2C_BROADCAST     0x20
-#define DRX_I2C_CLEARCRC      0x80
-#define DRX_I2C_SINGLE_MASTER 0xC0
-#define DRX_I2C_MODEFLAGS     0xC0
-#define DRX_I2C_FLAGS         0xF0
-
-#ifndef SIZEOF_ARRAY
-#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
-#endif
-
-#define DEFAULT_LOCK_TIMEOUT    1100
-
-#define DRX_CHANNEL_AUTO 0
-#define DRX_CHANNEL_HIGH 1
-#define DRX_CHANNEL_LOW  2
-
-#define DRX_LOCK_MPEG  1
-#define DRX_LOCK_FEC   2
-#define DRX_LOCK_DEMOD 4
-
-/****************************************************************************/
-
-enum CSCDState {
-       CSCD_INIT = 0,
-       CSCD_SET,
-       CSCD_SAVED
-};
-
-enum CDrxdState {
-       DRXD_UNINITIALIZED = 0,
-       DRXD_STOPPED,
-       DRXD_STARTED
-};
-
-enum AGC_CTRL_MODE {
-       AGC_CTRL_AUTO = 0,
-       AGC_CTRL_USER,
-       AGC_CTRL_OFF
-};
-
-enum OperationMode {
-       OM_Default,
-       OM_DVBT_Diversity_Front,
-       OM_DVBT_Diversity_End
-};
-
-struct SCfgAgc {
-       enum AGC_CTRL_MODE ctrlMode;
-       u16 outputLevel;        /* range [0, ... , 1023], 1/n of fullscale range */
-       u16 settleLevel;        /* range [0, ... , 1023], 1/n of fullscale range */
-       u16 minOutputLevel;     /* range [0, ... , 1023], 1/n of fullscale range */
-       u16 maxOutputLevel;     /* range [0, ... , 1023], 1/n of fullscale range */
-       u16 speed;              /* range [0, ... , 1023], 1/n of fullscale range */
-
-       u16 R1;
-       u16 R2;
-       u16 R3;
-};
-
-struct SNoiseCal {
-       int cpOpt;
-       short cpNexpOfs;
-       short tdCal2k;
-       short tdCal8k;
-};
-
-enum app_env {
-       APPENV_STATIC = 0,
-       APPENV_PORTABLE = 1,
-       APPENV_MOBILE = 2
-};
-
-enum EIFFilter {
-       IFFILTER_SAW = 0,
-       IFFILTER_DISCRETE = 1
-};
-
-struct drxd_state {
-       struct dvb_frontend frontend;
-       struct dvb_frontend_ops ops;
-       struct dtv_frontend_properties props;
-
-       const struct firmware *fw;
-       struct device *dev;
-
-       struct i2c_adapter *i2c;
-       void *priv;
-       struct drxd_config config;
-
-       int i2c_access;
-       int init_done;
-       struct mutex mutex;
-
-       u8 chip_adr;
-       u16 hi_cfg_timing_div;
-       u16 hi_cfg_bridge_delay;
-       u16 hi_cfg_wakeup_key;
-       u16 hi_cfg_ctrl;
-
-       u16 intermediate_freq;
-       u16 osc_clock_freq;
-
-       enum CSCDState cscd_state;
-       enum CDrxdState drxd_state;
-
-       u16 sys_clock_freq;
-       s16 osc_clock_deviation;
-       u16 expected_sys_clock_freq;
-
-       u16 insert_rs_byte;
-       u16 enable_parallel;
-
-       int operation_mode;
-
-       struct SCfgAgc if_agc_cfg;
-       struct SCfgAgc rf_agc_cfg;
-
-       struct SNoiseCal noise_cal;
-
-       u32 fe_fs_add_incr;
-       u32 org_fe_fs_add_incr;
-       u16 current_fe_if_incr;
-
-       u16 m_FeAgRegAgPwd;
-       u16 m_FeAgRegAgAgcSio;
-
-       u16 m_EcOcRegOcModeLop;
-       u16 m_EcOcRegSncSncLvl;
-       u8 *m_InitAtomicRead;
-       u8 *m_HiI2cPatch;
-
-       u8 *m_ResetCEFR;
-       u8 *m_InitFE_1;
-       u8 *m_InitFE_2;
-       u8 *m_InitCP;
-       u8 *m_InitCE;
-       u8 *m_InitEQ;
-       u8 *m_InitSC;
-       u8 *m_InitEC;
-       u8 *m_ResetECRAM;
-       u8 *m_InitDiversityFront;
-       u8 *m_InitDiversityEnd;
-       u8 *m_DisableDiversity;
-       u8 *m_StartDiversityFront;
-       u8 *m_StartDiversityEnd;
-
-       u8 *m_DiversityDelay8MHZ;
-       u8 *m_DiversityDelay6MHZ;
-
-       u8 *microcode;
-       u32 microcode_length;
-
-       int type_A;
-       int PGA;
-       int diversity;
-       int tuner_mirrors;
-
-       enum app_env app_env_default;
-       enum app_env app_env_diversity;
-
-};
-
-/****************************************************************************/
-/* I2C **********************************************************************/
-/****************************************************************************/
-
-static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 * data, int len)
-{
-       struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len };
-
-       if (i2c_transfer(adap, &msg, 1) != 1)
-               return -1;
-       return 0;
-}
-
-static int i2c_read(struct i2c_adapter *adap,
-                   u8 adr, u8 *msg, int len, u8 *answ, int alen)
-{
-       struct i2c_msg msgs[2] = {
-               {
-                       .addr = adr, .flags = 0,
-                       .buf = msg, .len = len
-               }, {
-                       .addr = adr, .flags = I2C_M_RD,
-                       .buf = answ, .len = alen
-               }
-       };
-       if (i2c_transfer(adap, msgs, 2) != 2)
-               return -1;
-       return 0;
-}
-
-static inline u32 MulDiv32(u32 a, u32 b, u32 c)
-{
-       u64 tmp64;
-
-       tmp64 = (u64)a * (u64)b;
-       do_div(tmp64, c);
-
-       return (u32) tmp64;
-}
-
-static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
-{
-       u8 adr = state->config.demod_address;
-       u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
-               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
-       };
-       u8 mm2[2];
-       if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2) < 0)
-               return -1;
-       if (data)
-               *data = mm2[0] | (mm2[1] << 8);
-       return mm2[0] | (mm2[1] << 8);
-}
-
-static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
-{
-       u8 adr = state->config.demod_address;
-       u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
-               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
-       };
-       u8 mm2[4];
-
-       if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4) < 0)
-               return -1;
-       if (data)
-               *data =
-                   mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
-       return 0;
-}
-
-static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
-{
-       u8 adr = state->config.demod_address;
-       u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
-               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
-               data & 0xff, (data >> 8) & 0xff
-       };
-
-       if (i2c_write(state->i2c, adr, mm, 6) < 0)
-               return -1;
-       return 0;
-}
-
-static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
-{
-       u8 adr = state->config.demod_address;
-       u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
-               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
-               data & 0xff, (data >> 8) & 0xff,
-               (data >> 16) & 0xff, (data >> 24) & 0xff
-       };
-
-       if (i2c_write(state->i2c, adr, mm, 8) < 0)
-               return -1;
-       return 0;
-}
-
-static int write_chunk(struct drxd_state *state,
-                      u32 reg, u8 *data, u32 len, u8 flags)
-{
-       u8 adr = state->config.demod_address;
-       u8 mm[CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
-               flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
-       };
-       int i;
-
-       for (i = 0; i < len; i++)
-               mm[4 + i] = data[i];
-       if (i2c_write(state->i2c, adr, mm, 4 + len) < 0) {
-               printk(KERN_ERR "error in write_chunk\n");
-               return -1;
-       }
-       return 0;
-}
-
-static int WriteBlock(struct drxd_state *state,
-                     u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
-{
-       while (BlockSize > 0) {
-               u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
-
-               if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
-                       return -1;
-               pBlock += Chunk;
-               Address += (Chunk >> 1);
-               BlockSize -= Chunk;
-       }
-       return 0;
-}
-
-static int WriteTable(struct drxd_state *state, u8 * pTable)
-{
-       int status = 0;
-
-       if (pTable == NULL)
-               return 0;
-
-       while (!status) {
-               u16 Length;
-               u32 Address = pTable[0] | (pTable[1] << 8) |
-                   (pTable[2] << 16) | (pTable[3] << 24);
-
-               if (Address == 0xFFFFFFFF)
-                       break;
-               pTable += sizeof(u32);
-
-               Length = pTable[0] | (pTable[1] << 8);
-               pTable += sizeof(u16);
-               if (!Length)
-                       break;
-               status = WriteBlock(state, Address, Length * 2, pTable, 0);
-               pTable += (Length * 2);
-       }
-       return status;
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static int ResetCEFR(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_ResetCEFR);
-}
-
-static int InitCP(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_InitCP);
-}
-
-static int InitCE(struct drxd_state *state)
-{
-       int status;
-       enum app_env AppEnv = state->app_env_default;
-
-       do {
-               status = WriteTable(state, state->m_InitCE);
-               if (status < 0)
-                       break;
-
-               if (state->operation_mode == OM_DVBT_Diversity_Front ||
-                   state->operation_mode == OM_DVBT_Diversity_End) {
-                       AppEnv = state->app_env_diversity;
-               }
-               if (AppEnv == APPENV_STATIC) {
-                       status = Write16(state, CE_REG_TAPSET__A, 0x0000, 0);
-                       if (status < 0)
-                               break;
-               } else if (AppEnv == APPENV_PORTABLE) {
-                       status = Write16(state, CE_REG_TAPSET__A, 0x0001, 0);
-                       if (status < 0)
-                               break;
-               } else if (AppEnv == APPENV_MOBILE && state->type_A) {
-                       status = Write16(state, CE_REG_TAPSET__A, 0x0002, 0);
-                       if (status < 0)
-                               break;
-               } else if (AppEnv == APPENV_MOBILE && !state->type_A) {
-                       status = Write16(state, CE_REG_TAPSET__A, 0x0006, 0);
-                       if (status < 0)
-                               break;
-               }
-
-               /* start ce */
-               status = Write16(state, B_CE_REG_COMM_EXEC__A, 0x0001, 0);
-               if (status < 0)
-                       break;
-       } while (0);
-       return status;
-}
-
-static int StopOC(struct drxd_state *state)
-{
-       int status = 0;
-       u16 ocSyncLvl = 0;
-       u16 ocModeLop = state->m_EcOcRegOcModeLop;
-       u16 dtoIncLop = 0;
-       u16 dtoIncHip = 0;
-
-       do {
-               /* Store output configuration */
-               status = Read16(state, EC_OC_REG_SNC_ISC_LVL__A, &ocSyncLvl, 0);
-               if (status < 0)
-                       break;
-               /* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A, &ocModeLop)); */
-               state->m_EcOcRegSncSncLvl = ocSyncLvl;
-               /* m_EcOcRegOcModeLop = ocModeLop; */
-
-               /* Flush FIFO (byte-boundary) at fixed rate */
-               status = Read16(state, EC_OC_REG_RCN_MAP_LOP__A, &dtoIncLop, 0);
-               if (status < 0)
-                       break;
-               status = Read16(state, EC_OC_REG_RCN_MAP_HIP__A, &dtoIncHip, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_DTO_INC_LOP__A, dtoIncLop, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_DTO_INC_HIP__A, dtoIncHip, 0);
-               if (status < 0)
-                       break;
-               ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
-               ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
-               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
-               if (status < 0)
-                       break;
-
-               msleep(1);
-               /* Output pins to '0' */
-               status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS__M, 0);
-               if (status < 0)
-                       break;
-
-               /* Force the OC out of sync */
-               ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
-               status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, ocSyncLvl, 0);
-               if (status < 0)
-                       break;
-               ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
-               ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
-               ocModeLop |= 0x2;       /* Magically-out-of-sync */
-               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
-               if (status < 0)
-                       break;
-       } while (0);
-
-       return status;
-}
-
-static int StartOC(struct drxd_state *state)
-{
-       int status = 0;
-
-       do {
-               /* Stop OC */
-               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
-               if (status < 0)
-                       break;
-
-               /* Restore output configuration */
-               status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, state->m_EcOcRegSncSncLvl, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, state->m_EcOcRegOcModeLop, 0);
-               if (status < 0)
-                       break;
-
-               /* Output pins active again */
-               status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS_INIT, 0);
-               if (status < 0)
-                       break;
-
-               /* Start OC */
-               status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
-               if (status < 0)
-                       break;
-       } while (0);
-       return status;
-}
-
-static int InitEQ(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_InitEQ);
-}
-
-static int InitEC(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_InitEC);
-}
-
-static int InitSC(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_InitSC);
-}
-
-static int InitAtomicRead(struct drxd_state *state)
-{
-       return WriteTable(state, state->m_InitAtomicRead);
-}
-
-static int CorrectSysClockDeviation(struct drxd_state *state);
-
-static int DRX_GetLockStatus(struct drxd_state *state, u32 * pLockStatus)
-{
-       u16 ScRaRamLock = 0;
-       const u16 mpeg_lock_mask = (SC_RA_RAM_LOCK_MPEG__M |
-                                   SC_RA_RAM_LOCK_FEC__M |
-                                   SC_RA_RAM_LOCK_DEMOD__M);
-       const u16 fec_lock_mask = (SC_RA_RAM_LOCK_FEC__M |
-                                  SC_RA_RAM_LOCK_DEMOD__M);
-       const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M;
-
-       int status;
-
-       *pLockStatus = 0;
-
-       status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000);
-       if (status < 0) {
-               printk(KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
-               return status;
-       }
-
-       if (state->drxd_state != DRXD_STARTED)
-               return 0;
-
-       if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
-               *pLockStatus |= DRX_LOCK_MPEG;
-               CorrectSysClockDeviation(state);
-       }
-
-       if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
-               *pLockStatus |= DRX_LOCK_FEC;
-
-       if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
-               *pLockStatus |= DRX_LOCK_DEMOD;
-       return 0;
-}
-
-/****************************************************************************/
-
-static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
-{
-       int status;
-
-       if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
-               return -1;
-
-       if (cfg->ctrlMode == AGC_CTRL_USER) {
-               do {
-                       u16 FeAgRegPm1AgcWri;
-                       u16 FeAgRegAgModeLop;
-
-                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
-                       if (status < 0)
-                               break;
-                       FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
-                       FeAgRegAgModeLop |= FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
-                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
-                       if (status < 0)
-                               break;
-
-                       FeAgRegPm1AgcWri = (u16) (cfg->outputLevel &
-                                                 FE_AG_REG_PM1_AGC_WRI__M);
-                       status = Write16(state, FE_AG_REG_PM1_AGC_WRI__A, FeAgRegPm1AgcWri, 0);
-                       if (status < 0)
-                               break;
-               } while (0);
-       } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
-               if (((cfg->maxOutputLevel) < (cfg->minOutputLevel)) ||
-                   ((cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX) ||
-                   ((cfg->speed) > DRXD_FE_CTRL_MAX) ||
-                   ((cfg->settleLevel) > DRXD_FE_CTRL_MAX)
-                   )
-                       return -1;
-               do {
-                       u16 FeAgRegAgModeLop;
-                       u16 FeAgRegEgcSetLvl;
-                       u16 slope, offset;
-
-                       /* == Mode == */
-
-                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
-                       if (status < 0)
-                               break;
-                       FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
-                       FeAgRegAgModeLop |=
-                           FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
-                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
-                       if (status < 0)
-                               break;
-
-                       /* == Settle level == */
-
-                       FeAgRegEgcSetLvl = (u16) ((cfg->settleLevel >> 1) &
-                                                 FE_AG_REG_EGC_SET_LVL__M);
-                       status = Write16(state, FE_AG_REG_EGC_SET_LVL__A, FeAgRegEgcSetLvl, 0);
-                       if (status < 0)
-                               break;
-
-                       /* == Min/Max == */
-
-                       slope = (u16) ((cfg->maxOutputLevel -
-                                       cfg->minOutputLevel) / 2);
-                       offset = (u16) ((cfg->maxOutputLevel +
-                                        cfg->minOutputLevel) / 2 - 511);
-
-                       status = Write16(state, FE_AG_REG_GC1_AGC_RIC__A, slope, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, FE_AG_REG_GC1_AGC_OFF__A, offset, 0);
-                       if (status < 0)
-                               break;
-
-                       /* == Speed == */
-                       {
-                               const u16 maxRur = 8;
-                               const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
-                               const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
-                                       17, 18, 18, 19,
-                                       20, 21, 22, 23,
-                                       24, 26, 27, 28,
-                                       29, 31
-                               };
-
-                               u16 fineSteps = (DRXD_FE_CTRL_MAX + 1) /
-                                   (maxRur + 1);
-                               u16 fineSpeed = (u16) (cfg->speed -
-                                                      ((cfg->speed /
-                                                        fineSteps) *
-                                                       fineSteps));
-                               u16 invRurCount = (u16) (cfg->speed /
-                                                        fineSteps);
-                               u16 rurCount;
-                               if (invRurCount > maxRur) {
-                                       rurCount = 0;
-                                       fineSpeed += fineSteps;
-                               } else {
-                                       rurCount = maxRur - invRurCount;
-                               }
-
-                               /*
-                                  fastInc = default *
-                                  (2^(fineSpeed/fineSteps))
-                                  => range[default...2*default>
-                                  slowInc = default *
-                                  (2^(fineSpeed/fineSteps))
-                                */
-                               {
-                                       u16 fastIncrDec =
-                                           fastIncrDecLUT[fineSpeed /
-                                                          ((fineSteps /
-                                                            (14 + 1)) + 1)];
-                                       u16 slowIncrDec =
-                                           slowIncrDecLUT[fineSpeed /
-                                                          (fineSteps /
-                                                           (3 + 1))];
-
-                                       status = Write16(state, FE_AG_REG_EGC_RUR_CNT__A, rurCount, 0);
-                                       if (status < 0)
-                                               break;
-                                       status = Write16(state, FE_AG_REG_EGC_FAS_INC__A, fastIncrDec, 0);
-                                       if (status < 0)
-                                               break;
-                                       status = Write16(state, FE_AG_REG_EGC_FAS_DEC__A, fastIncrDec, 0);
-                                       if (status < 0)
-                                               break;
-                                       status = Write16(state, FE_AG_REG_EGC_SLO_INC__A, slowIncrDec, 0);
-                                       if (status < 0)
-                                               break;
-                                       status = Write16(state, FE_AG_REG_EGC_SLO_DEC__A, slowIncrDec, 0);
-                                       if (status < 0)
-                                               break;
-                               }
-                       }
-               } while (0);
-
-       } else {
-               /* No OFF mode for IF control */
-               return -1;
-       }
-       return status;
-}
-
-static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
-{
-       int status = 0;
-
-       if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
-               return -1;
-
-       if (cfg->ctrlMode == AGC_CTRL_USER) {
-               do {
-                       u16 AgModeLop = 0;
-                       u16 level = (cfg->outputLevel);
-
-                       if (level == DRXD_FE_CTRL_MAX)
-                               level++;
-
-                       status = Write16(state, FE_AG_REG_PM2_AGC_WRI__A, level, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /*==== Mode ====*/
-
-                       /* Powerdown PD2, WRI source */
-                       state->m_FeAgRegAgPwd &= ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
-                       state->m_FeAgRegAgPwd |=
-                           FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
-                       status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
-                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
-                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
-                                     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
-                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* enable AGC2 pin */
-                       {
-                               u16 FeAgRegAgAgcSio = 0;
-                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                               FeAgRegAgAgcSio &=
-                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
-                               FeAgRegAgAgcSio |=
-                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
-                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-
-               } while (0);
-       } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
-               u16 AgModeLop = 0;
-
-               do {
-                       u16 level;
-                       /* Automatic control */
-                       /* Powerup PD2, AGC2 as output, TGC source */
-                       (state->m_FeAgRegAgPwd) &=
-                           ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
-                       (state->m_FeAgRegAgPwd) |=
-                           FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
-                       status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
-                       if (status < 0)
-                               break;
-
-                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
-                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
-                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
-                                     FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC);
-                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       /* Settle level */
-                       level = (((cfg->settleLevel) >> 4) &
-                                FE_AG_REG_TGC_SET_LVL__M);
-                       status = Write16(state, FE_AG_REG_TGC_SET_LVL__A, level, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* Min/max: don't care */
-
-                       /* Speed: TODO */
-
-                       /* enable AGC2 pin */
-                       {
-                               u16 FeAgRegAgAgcSio = 0;
-                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                               FeAgRegAgAgcSio &=
-                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
-                               FeAgRegAgAgcSio |=
-                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
-                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-
-               } while (0);
-       } else {
-               u16 AgModeLop = 0;
-
-               do {
-                       /* No RF AGC control */
-                       /* Powerdown PD2, AGC2 as output, WRI source */
-                       (state->m_FeAgRegAgPwd) &=
-                           ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
-                       (state->m_FeAgRegAgPwd) |=
-                           FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
-                       status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
-                       if (status < 0)
-                               break;
-
-                       status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
-                                       FE_AG_REG_AG_MODE_LOP_MODE_E__M));
-                       AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
-                                     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
-                       status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* set FeAgRegAgAgcSio AGC2 (RF) as input */
-                       {
-                               u16 FeAgRegAgAgcSio = 0;
-                               status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                               FeAgRegAgAgcSio &=
-                                   ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
-                               FeAgRegAgAgcSio |=
-                                   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
-                               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-               } while (0);
-       }
-       return status;
-}
-
-static int ReadIFAgc(struct drxd_state *state, u32 * pValue)
-{
-       int status = 0;
-
-       *pValue = 0;
-       if (state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF) {
-               u16 Value;
-               status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A, &Value, 0);
-               Value &= FE_AG_REG_GC1_AGC_DAT__M;
-               if (status >= 0) {
-                       /*           3.3V
-                          |
-                          R1
-                          |
-                          Vin - R3 - * -- Vout
-                          |
-                          R2
-                          |
-                          GND
-                        */
-                       u32 R1 = state->if_agc_cfg.R1;
-                       u32 R2 = state->if_agc_cfg.R2;
-                       u32 R3 = state->if_agc_cfg.R3;
-
-                       u32 Vmax, Rpar, Vmin, Vout;
-
-                       if (R2 == 0 && (R1 == 0 || R3 == 0))
-                               return 0;
-
-                       Vmax = (3300 * R2) / (R1 + R2);
-                       Rpar = (R2 * R3) / (R3 + R2);
-                       Vmin = (3300 * Rpar) / (R1 + Rpar);
-                       Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
-
-                       *pValue = Vout;
-               }
-       }
-       return status;
-}
-
-static int load_firmware(struct drxd_state *state, const char *fw_name)
-{
-       const struct firmware *fw;
-
-       if (request_firmware(&fw, fw_name, state->dev) < 0) {
-               printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
-               return -EIO;
-       }
-
-       state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
-       if (state->microcode == NULL) {
-               release_firmware(fw);
-               printk(KERN_ERR "drxd: firmware load failure: no memory\n");
-               return -ENOMEM;
-       }
-
-       state->microcode_length = fw->size;
-       release_firmware(fw);
-       return 0;
-}
-
-static int DownloadMicrocode(struct drxd_state *state,
-                            const u8 *pMCImage, u32 Length)
-{
-       u8 *pSrc;
-       u32 Address;
-       u16 nBlocks;
-       u16 BlockSize;
-       u32 offset = 0;
-       int i, status = 0;
-
-       pSrc = (u8 *) pMCImage;
-       /* We're not using Flags */
-       /* Flags = (pSrc[0] << 8) | pSrc[1]; */
-       pSrc += sizeof(u16);
-       offset += sizeof(u16);
-       nBlocks = (pSrc[0] << 8) | pSrc[1];
-       pSrc += sizeof(u16);
-       offset += sizeof(u16);
-
-       for (i = 0; i < nBlocks; i++) {
-               Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
-                   (pSrc[2] << 8) | pSrc[3];
-               pSrc += sizeof(u32);
-               offset += sizeof(u32);
-
-               BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-               /* We're not using Flags */
-               /* u16 Flags = (pSrc[0] << 8) | pSrc[1]; */
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-               /* We're not using BlockCRC */
-               /* u16 BlockCRC = (pSrc[0] << 8) | pSrc[1]; */
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-               status = WriteBlock(state, Address, BlockSize,
-                                   pSrc, DRX_I2C_CLEARCRC);
-               if (status < 0)
-                       break;
-               pSrc += BlockSize;
-               offset += BlockSize;
-       }
-
-       return status;
-}
-
-static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
-{
-       u32 nrRetries = 0;
-       u16 waitCmd;
-       int status;
-
-       status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
-       if (status < 0)
-               return status;
-
-       do {
-               nrRetries += 1;
-               if (nrRetries > DRXD_MAX_RETRIES) {
-                       status = -1;
-                       break;
-               };
-               status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
-       } while (waitCmd != 0);
-
-       if (status >= 0)
-               status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
-       return status;
-}
-
-static int HI_CfgCommand(struct drxd_state *state)
-{
-       int status = 0;
-
-       mutex_lock(&state->mutex);
-       Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
-       Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
-       Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, state->hi_cfg_bridge_delay, 0);
-       Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
-       Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
-
-       Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
-
-       if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE) ==
-           HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
-               status = Write16(state, HI_RA_RAM_SRV_CMD__A,
-                                HI_RA_RAM_SRV_CMD_CONFIG, 0);
-       else
-               status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-static int InitHI(struct drxd_state *state)
-{
-       state->hi_cfg_wakeup_key = (state->chip_adr);
-       /* port/bridge/power down ctrl */
-       state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
-       return HI_CfgCommand(state);
-}
-
-static int HI_ResetCommand(struct drxd_state *state)
-{
-       int status;
-
-       mutex_lock(&state->mutex);
-       status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
-                        HI_RA_RAM_SRV_RST_KEY_ACT, 0);
-       if (status == 0)
-               status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
-       mutex_unlock(&state->mutex);
-       msleep(1);
-       return status;
-}
-
-static int DRX_ConfigureI2CBridge(struct drxd_state *state, int bEnableBridge)
-{
-       state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
-       if (bEnableBridge)
-               state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
-       else
-               state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
-
-       return HI_CfgCommand(state);
-}
-
-#define HI_TR_WRITE      0x9
-#define HI_TR_READ       0xA
-#define HI_TR_READ_WRITE 0xB
-#define HI_TR_BROADCAST  0x4
-
-#if 0
-static int AtomicReadBlock(struct drxd_state *state,
-                          u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
-{
-       int status;
-       int i = 0;
-
-       /* Parameter check */
-       if ((!pData) || ((DataSize & 1) != 0))
-               return -1;
-
-       mutex_lock(&state->mutex);
-
-       do {
-               /* Instruct HI to read n bytes */
-               /* TODO use proper names forthese egisters */
-               status = Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, (HI_TR_FUNC_ADDR & 0xFFFF), 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, (u16) (Addr >> 16), 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, (u16) (Addr & 0xFFFF), 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, (u16) ((DataSize / 2) - 1), 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, HI_TR_READ, 0);
-               if (status < 0)
-                       break;
-
-               status = HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE, 0);
-               if (status < 0)
-                       break;
-
-       } while (0);
-
-       if (status >= 0) {
-               for (i = 0; i < (DataSize / 2); i += 1) {
-                       u16 word;
-
-                       status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
-                                       &word, 0);
-                       if (status < 0)
-                               break;
-                       pData[2 * i] = (u8) (word & 0xFF);
-                       pData[(2 * i) + 1] = (u8) (word >> 8);
-               }
-       }
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-static int AtomicReadReg32(struct drxd_state *state,
-                          u32 Addr, u32 *pData, u8 Flags)
-{
-       u8 buf[sizeof(u32)];
-       int status;
-
-       if (!pData)
-               return -1;
-       status = AtomicReadBlock(state, Addr, sizeof(u32), buf, Flags);
-       *pData = (((u32) buf[0]) << 0) +
-           (((u32) buf[1]) << 8) +
-           (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
-       return status;
-}
-#endif
-
-static int StopAllProcessors(struct drxd_state *state)
-{
-       return Write16(state, HI_COMM_EXEC__A,
-                      SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
-}
-
-static int EnableAndResetMB(struct drxd_state *state)
-{
-       if (state->type_A) {
-               /* disable? monitor bus observe @ EC_OC */
-               Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
-       }
-
-       /* do inverse broadcast, followed by explicit write to HI */
-       Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
-       Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
-       return 0;
-}
-
-static int InitCC(struct drxd_state *state)
-{
-       if (state->osc_clock_freq == 0 ||
-           state->osc_clock_freq > 20000 ||
-           (state->osc_clock_freq % 4000) != 0) {
-               printk(KERN_ERR "invalid osc frequency %d\n", state->osc_clock_freq);
-               return -1;
-       }
-
-       Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
-       Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
-               CC_REG_PLL_MODE_PUMP_CUR_12, 0);
-       Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq / 4000, 0);
-       Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
-       Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
-
-       return 0;
-}
-
-static int ResetECOD(struct drxd_state *state)
-{
-       int status = 0;
-
-       if (state->type_A)
-               status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
-       else
-               status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
-
-       if (!(status < 0))
-               status = WriteTable(state, state->m_ResetECRAM);
-       if (!(status < 0))
-               status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
-       return status;
-}
-
-/* Configure PGA switch */
-
-static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
-{
-       int status;
-       u16 AgModeLop = 0;
-       u16 AgModeHip = 0;
-       do {
-               if (pgaSwitch) {
-                       /* PGA on */
-                       /* fine gain */
-                       status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
-                       AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
-                       status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* coarse gain */
-                       status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
-                       AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC;
-                       status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* enable fine and coarse gain, enable AAF,
-                          no ext resistor */
-                       status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN, 0x0000);
-                       if (status < 0)
-                               break;
-               } else {
-                       /* PGA off, bypass */
-
-                       /* fine gain */
-                       status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
-                       AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC;
-                       status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* coarse gain */
-                       status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
-                       if (status < 0)
-                               break;
-                       AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
-                       AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC;
-                       status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       /* disable fine and coarse gain, enable AAF,
-                          no ext resistor */
-                       status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);
-                       if (status < 0)
-                               break;
-               }
-       } while (0);
-       return status;
-}
-
-static int InitFE(struct drxd_state *state)
-{
-       int status;
-
-       do {
-               status = WriteTable(state, state->m_InitFE_1);
-               if (status < 0)
-                       break;
-
-               if (state->type_A) {
-                       status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
-                                        FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
-                                        0);
-               } else {
-                       if (state->PGA)
-                               status = SetCfgPga(state, 0);
-                       else
-                               status =
-                                   Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
-                                           B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
-                                           0);
-               }
-
-               if (status < 0)
-                       break;
-               status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, state->m_FeAgRegAgAgcSio, 0x0000);
-               if (status < 0)
-                       break;
-               status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
-               if (status < 0)
-                       break;
-
-               status = WriteTable(state, state->m_InitFE_2);
-               if (status < 0)
-                       break;
-
-       } while (0);
-
-       return status;
-}
-
-static int InitFT(struct drxd_state *state)
-{
-       /*
-          norm OFFSET,  MB says =2 voor 8K en =3 voor 2K waarschijnlijk
-          SC stuff
-        */
-       return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000);
-}
-
-static int SC_WaitForReady(struct drxd_state *state)
-{
-       u16 curCmd;
-       int i;
-
-       for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
-               int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
-               if (status == 0 || curCmd == 0)
-                       return status;
-       }
-       return -1;
-}
-
-static int SC_SendCommand(struct drxd_state *state, u16 cmd)
-{
-       int status = 0;
-       u16 errCode;
-
-       Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
-       SC_WaitForReady(state);
-
-       Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
-
-       if (errCode == 0xFFFF) {
-               printk(KERN_ERR "Command Error\n");
-               status = -1;
-       }
-
-       return status;
-}
-
-static int SC_ProcStartCommand(struct drxd_state *state,
-                              u16 subCmd, u16 param0, u16 param1)
-{
-       int status = 0;
-       u16 scExec;
-
-       mutex_lock(&state->mutex);
-       do {
-               Read16(state, SC_COMM_EXEC__A, &scExec, 0);
-               if (scExec != 1) {
-                       status = -1;
-                       break;
-               }
-               SC_WaitForReady(state);
-               Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
-               Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
-               Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
-
-               SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
-       } while (0);
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-static int SC_SetPrefParamCommand(struct drxd_state *state,
-                                 u16 subCmd, u16 param0, u16 param1)
-{
-       int status;
-
-       mutex_lock(&state->mutex);
-       do {
-               status = SC_WaitForReady(state);
-               if (status < 0)
-                       break;
-               status = Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
-               if (status < 0)
-                       break;
-
-               status = SC_SendCommand(state, SC_RA_RAM_CMD_SET_PREF_PARAM);
-               if (status < 0)
-                       break;
-       } while (0);
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-#if 0
-static int SC_GetOpParamCommand(struct drxd_state *state, u16 * result)
-{
-       int status = 0;
-
-       mutex_lock(&state->mutex);
-       do {
-               status = SC_WaitForReady(state);
-               if (status < 0)
-                       break;
-               status = SC_SendCommand(state, SC_RA_RAM_CMD_GET_OP_PARAM);
-               if (status < 0)
-                       break;
-               status = Read16(state, SC_RA_RAM_PARAM0__A, result, 0);
-               if (status < 0)
-                       break;
-       } while (0);
-       mutex_unlock(&state->mutex);
-       return status;
-}
-#endif
-
-static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
-{
-       int status;
-
-       do {
-               u16 EcOcRegIprInvMpg = 0;
-               u16 EcOcRegOcModeLop = 0;
-               u16 EcOcRegOcModeHip = 0;
-               u16 EcOcRegOcMpgSio = 0;
-
-               /*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A, &EcOcRegOcModeLop, 0)); */
-
-               if (state->operation_mode == OM_DVBT_Diversity_Front) {
-                       if (bEnableOutput) {
-                               EcOcRegOcModeHip |=
-                                   B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
-                       } else
-                               EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
-                       EcOcRegOcModeLop |=
-                           EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
-               } else {
-                       EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
-
-                       if (bEnableOutput)
-                               EcOcRegOcMpgSio &= (~(EC_OC_REG_OC_MPG_SIO__M));
-                       else
-                               EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
-
-                       /* Don't Insert RS Byte */
-                       if (state->insert_rs_byte) {
-                               EcOcRegOcModeLop &=
-                                   (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
-                               EcOcRegOcModeHip &=
-                                   (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
-                               EcOcRegOcModeHip |=
-                                   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
-                       } else {
-                               EcOcRegOcModeLop |=
-                                   EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
-                               EcOcRegOcModeHip &=
-                                   (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
-                               EcOcRegOcModeHip |=
-                                   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
-                       }
-
-                       /* Mode = Parallel */
-                       if (state->enable_parallel)
-                               EcOcRegOcModeLop &=
-                                   (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
-                       else
-                               EcOcRegOcModeLop |=
-                                   EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
-               }
-               /* Invert Data */
-               /* EcOcRegIprInvMpg |= 0x00FF; */
-               EcOcRegIprInvMpg &= (~(0x00FF));
-
-               /* Invert Error ( we don't use the pin ) */
-               /*  EcOcRegIprInvMpg |= 0x0100; */
-               EcOcRegIprInvMpg &= (~(0x0100));
-
-               /* Invert Start ( we don't use the pin ) */
-               /* EcOcRegIprInvMpg |= 0x0200; */
-               EcOcRegIprInvMpg &= (~(0x0200));
-
-               /* Invert Valid ( we don't use the pin ) */
-               /* EcOcRegIprInvMpg |= 0x0400; */
-               EcOcRegIprInvMpg &= (~(0x0400));
-
-               /* Invert Clock */
-               /* EcOcRegIprInvMpg |= 0x0800; */
-               EcOcRegIprInvMpg &= (~(0x0800));
-
-               /* EcOcRegOcModeLop =0x05; */
-               status = Write16(state, EC_OC_REG_IPR_INV_MPG__A, EcOcRegIprInvMpg, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, EcOcRegOcModeLop, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_OC_MODE_HIP__A, EcOcRegOcModeHip, 0x0000);
-               if (status < 0)
-                       break;
-               status = Write16(state, EC_OC_REG_OC_MPG_SIO__A, EcOcRegOcMpgSio, 0);
-               if (status < 0)
-                       break;
-       } while (0);
-       return status;
-}
-
-static int SetDeviceTypeId(struct drxd_state *state)
-{
-       int status = 0;
-       u16 deviceId = 0;
-
-       do {
-               status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
-               if (status < 0)
-                       break;
-               /* TODO: why twice? */
-               status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
-               if (status < 0)
-                       break;
-               printk(KERN_INFO "drxd: deviceId = %04x\n", deviceId);
-
-               state->type_A = 0;
-               state->PGA = 0;
-               state->diversity = 0;
-               if (deviceId == 0) {    /* on A2 only 3975 available */
-                       state->type_A = 1;
-                       printk(KERN_INFO "DRX3975D-A2\n");
-               } else {
-                       deviceId >>= 12;
-                       printk(KERN_INFO "DRX397%dD-B1\n", deviceId);
-                       switch (deviceId) {
-                       case 4:
-                               state->diversity = 1;
-                       case 3:
-                       case 7:
-                               state->PGA = 1;
-                               break;
-                       case 6:
-                               state->diversity = 1;
-                       case 5:
-                       case 8:
-                               break;
-                       default:
-                               status = -1;
-                               break;
-                       }
-               }
-       } while (0);
-
-       if (status < 0)
-               return status;
-
-       /* Init Table selection */
-       state->m_InitAtomicRead = DRXD_InitAtomicRead;
-       state->m_InitSC = DRXD_InitSC;
-       state->m_ResetECRAM = DRXD_ResetECRAM;
-       if (state->type_A) {
-               state->m_ResetCEFR = DRXD_ResetCEFR;
-               state->m_InitFE_1 = DRXD_InitFEA2_1;
-               state->m_InitFE_2 = DRXD_InitFEA2_2;
-               state->m_InitCP = DRXD_InitCPA2;
-               state->m_InitCE = DRXD_InitCEA2;
-               state->m_InitEQ = DRXD_InitEQA2;
-               state->m_InitEC = DRXD_InitECA2;
-               if (load_firmware(state, DRX_FW_FILENAME_A2))
-                       return -EIO;
-       } else {
-               state->m_ResetCEFR = NULL;
-               state->m_InitFE_1 = DRXD_InitFEB1_1;
-               state->m_InitFE_2 = DRXD_InitFEB1_2;
-               state->m_InitCP = DRXD_InitCPB1;
-               state->m_InitCE = DRXD_InitCEB1;
-               state->m_InitEQ = DRXD_InitEQB1;
-               state->m_InitEC = DRXD_InitECB1;
-               if (load_firmware(state, DRX_FW_FILENAME_B1))
-                       return -EIO;
-       }
-       if (state->diversity) {
-               state->m_InitDiversityFront = DRXD_InitDiversityFront;
-               state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
-               state->m_DisableDiversity = DRXD_DisableDiversity;
-               state->m_StartDiversityFront = DRXD_StartDiversityFront;
-               state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
-               state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
-               state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
-       } else {
-               state->m_InitDiversityFront = NULL;
-               state->m_InitDiversityEnd = NULL;
-               state->m_DisableDiversity = NULL;
-               state->m_StartDiversityFront = NULL;
-               state->m_StartDiversityEnd = NULL;
-               state->m_DiversityDelay8MHZ = NULL;
-               state->m_DiversityDelay6MHZ = NULL;
-       }
-
-       return status;
-}
-
-static int CorrectSysClockDeviation(struct drxd_state *state)
-{
-       int status;
-       s32 incr = 0;
-       s32 nomincr = 0;
-       u32 bandwidth = 0;
-       u32 sysClockInHz = 0;
-       u32 sysClockFreq = 0;   /* in kHz */
-       s16 oscClockDeviation;
-       s16 Diff;
-
-       do {
-               /* Retrieve bandwidth and incr, sanity check */
-
-               /* These accesses should be AtomicReadReg32, but that
-                  causes trouble (at least for diversity */
-               status = Read32(state, LC_RA_RAM_IFINCR_NOM_L__A, ((u32 *) &nomincr), 0);
-               if (status < 0)
-                       break;
-               status = Read32(state, FE_IF_REG_INCR0__A, (u32 *) &incr, 0);
-               if (status < 0)
-                       break;
-
-               if (state->type_A) {
-                       if ((nomincr - incr < -500) || (nomincr - incr > 500))
-                               break;
-               } else {
-                       if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
-                               break;
-               }
-
-               switch (state->props.bandwidth_hz) {
-               case 8000000:
-                       bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
-                       break;
-               case 7000000:
-                       bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
-                       break;
-               case 6000000:
-                       bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
-                       break;
-               default:
-                       return -1;
-                       break;
-               }
-
-               /* Compute new sysclock value
-                  sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
-               incr += (1 << 23);
-               sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
-               sysClockFreq = (u32) (sysClockInHz / 1000);
-               /* rounding */
-               if ((sysClockInHz % 1000) > 500)
-                       sysClockFreq++;
-
-               /* Compute clock deviation in ppm */
-               oscClockDeviation = (u16) ((((s32) (sysClockFreq) -
-                                            (s32)
-                                            (state->expected_sys_clock_freq)) *
-                                           1000000L) /
-                                          (s32)
-                                          (state->expected_sys_clock_freq));
-
-               Diff = oscClockDeviation - state->osc_clock_deviation;
-               /*printk(KERN_INFO "sysclockdiff=%d\n", Diff); */
-               if (Diff >= -200 && Diff <= 200) {
-                       state->sys_clock_freq = (u16) sysClockFreq;
-                       if (oscClockDeviation != state->osc_clock_deviation) {
-                               if (state->config.osc_deviation) {
-                                       state->config.osc_deviation(state->priv,
-                                                                   oscClockDeviation,
-                                                                   1);
-                                       state->osc_clock_deviation =
-                                           oscClockDeviation;
-                               }
-                       }
-                       /* switch OFF SRMM scan in SC */
-                       status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DONT_SCAN, 0);
-                       if (status < 0)
-                               break;
-                       /* overrule FE_IF internal value for
-                          proper re-locking */
-                       status = Write16(state, SC_RA_RAM_IF_SAVE__AX, state->current_fe_if_incr, 0);
-                       if (status < 0)
-                               break;
-                       state->cscd_state = CSCD_SAVED;
-               }
-       } while (0);
-
-       return status;
-}
-
-static int DRX_Stop(struct drxd_state *state)
-{
-       int status;
-
-       if (state->drxd_state != DRXD_STARTED)
-               return 0;
-
-       do {
-               if (state->cscd_state != CSCD_SAVED) {
-                       u32 lock;
-                       status = DRX_GetLockStatus(state, &lock);
-                       if (status < 0)
-                               break;
-               }
-
-               status = StopOC(state);
-               if (status < 0)
-                       break;
-
-               state->drxd_state = DRXD_STOPPED;
-
-               status = ConfigureMPEGOutput(state, 0);
-               if (status < 0)
-                       break;
-
-               if (state->type_A) {
-                       /* Stop relevant processors off the device */
-                       status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0x0000);
-                       if (status < 0)
-                               break;
-
-                       status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-               } else {
-                       /* Stop all processors except HI & CC & FE */
-                       status = Write16(state, B_SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_FT_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_CP_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_CE_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_EQ_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0);
-                       if (status < 0)
-                               break;
-               }
-
-       } while (0);
-       return status;
-}
-
-int SetOperationMode(struct drxd_state *state, int oMode)
-{
-       int status;
-
-       do {
-               if (state->drxd_state != DRXD_STOPPED) {
-                       status = -1;
-                       break;
-               }
-
-               if (oMode == state->operation_mode) {
-                       status = 0;
-                       break;
-               }
-
-               if (oMode != OM_Default && !state->diversity) {
-                       status = -1;
-                       break;
-               }
-
-               switch (oMode) {
-               case OM_DVBT_Diversity_Front:
-                       status = WriteTable(state, state->m_InitDiversityFront);
-                       break;
-               case OM_DVBT_Diversity_End:
-                       status = WriteTable(state, state->m_InitDiversityEnd);
-                       break;
-               case OM_Default:
-                       /* We need to check how to
-                          get DRXD out of diversity */
-               default:
-                       status = WriteTable(state, state->m_DisableDiversity);
-                       break;
-               }
-       } while (0);
-
-       if (!status)
-               state->operation_mode = oMode;
-       return status;
-}
-
-static int StartDiversity(struct drxd_state *state)
-{
-       int status = 0;
-       u16 rcControl;
-
-       do {
-               if (state->operation_mode == OM_DVBT_Diversity_Front) {
-                       status = WriteTable(state, state->m_StartDiversityFront);
-                       if (status < 0)
-                               break;
-               } else if (state->operation_mode == OM_DVBT_Diversity_End) {
-                       status = WriteTable(state, state->m_StartDiversityEnd);
-                       if (status < 0)
-                               break;
-                       if (state->props.bandwidth_hz == 8000000) {
-                               status = WriteTable(state, state->m_DiversityDelay8MHZ);
-                               if (status < 0)
-                                       break;
-                       } else {
-                               status = WriteTable(state, state->m_DiversityDelay6MHZ);
-                               if (status < 0)
-                                       break;
-                       }
-
-                       status = Read16(state, B_EQ_REG_RC_SEL_CAR__A, &rcControl, 0);
-                       if (status < 0)
-                               break;
-                       rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
-                       rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
-                           /*  combining enabled */
-                           B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
-                           B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
-                           B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
-                       status = Write16(state, B_EQ_REG_RC_SEL_CAR__A, rcControl, 0);
-                       if (status < 0)
-                               break;
-               }
-       } while (0);
-       return status;
-}
-
-static int SetFrequencyShift(struct drxd_state *state,
-                            u32 offsetFreq, int channelMirrored)
-{
-       int negativeShift = (state->tuner_mirrors == channelMirrored);
-
-       /* Handle all mirroring
-        *
-        * Note: ADC mirroring (aliasing) is implictly handled by limiting
-        * feFsRegAddInc to 28 bits below
-        * (if the result before masking is more than 28 bits, this means
-        *  that the ADC is mirroring.
-        * The masking is in fact the aliasing of the ADC)
-        *
-        */
-
-       /* Compute register value, unsigned computation */
-       state->fe_fs_add_incr = MulDiv32(state->intermediate_freq +
-                                        offsetFreq,
-                                        1 << 28, state->sys_clock_freq);
-       /* Remove integer part */
-       state->fe_fs_add_incr &= 0x0FFFFFFFL;
-       if (negativeShift)
-               state->fe_fs_add_incr = ((1 << 28) - state->fe_fs_add_incr);
-
-       /* Save the frequency shift without tunerOffset compensation
-          for CtrlGetChannel. */
-       state->org_fe_fs_add_incr = MulDiv32(state->intermediate_freq,
-                                            1 << 28, state->sys_clock_freq);
-       /* Remove integer part */
-       state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
-       if (negativeShift)
-               state->org_fe_fs_add_incr = ((1L << 28) -
-                                            state->org_fe_fs_add_incr);
-
-       return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
-                      state->fe_fs_add_incr, 0);
-}
-
-static int SetCfgNoiseCalibration(struct drxd_state *state,
-                                 struct SNoiseCal *noiseCal)
-{
-       u16 beOptEna;
-       int status = 0;
-
-       do {
-               status = Read16(state, SC_RA_RAM_BE_OPT_ENA__A, &beOptEna, 0);
-               if (status < 0)
-                       break;
-               if (noiseCal->cpOpt) {
-                       beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
-               } else {
-                       beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
-                       status = Write16(state, CP_REG_AC_NEXP_OFFS__A, noiseCal->cpNexpOfs, 0);
-                       if (status < 0)
-                               break;
-               }
-               status = Write16(state, SC_RA_RAM_BE_OPT_ENA__A, beOptEna, 0);
-               if (status < 0)
-                       break;
-
-               if (!state->type_A) {
-                       status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_2K__A, noiseCal->tdCal2k, 0);
-                       if (status < 0)
-                               break;
-                       status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_8K__A, noiseCal->tdCal8k, 0);
-                       if (status < 0)
-                               break;
-               }
-       } while (0);
-
-       return status;
-}
-
-static int DRX_Start(struct drxd_state *state, s32 off)
-{
-       struct dtv_frontend_properties *p = &state->props;
-       int status;
-
-       u16 transmissionParams = 0;
-       u16 operationMode = 0;
-       u16 qpskTdTpsPwr = 0;
-       u16 qam16TdTpsPwr = 0;
-       u16 qam64TdTpsPwr = 0;
-       u32 feIfIncr = 0;
-       u32 bandwidth = 0;
-       int mirrorFreqSpect;
-
-       u16 qpskSnCeGain = 0;
-       u16 qam16SnCeGain = 0;
-       u16 qam64SnCeGain = 0;
-       u16 qpskIsGainMan = 0;
-       u16 qam16IsGainMan = 0;
-       u16 qam64IsGainMan = 0;
-       u16 qpskIsGainExp = 0;
-       u16 qam16IsGainExp = 0;
-       u16 qam64IsGainExp = 0;
-       u16 bandwidthParam = 0;
-
-       if (off < 0)
-               off = (off - 500) / 1000;
-       else
-               off = (off + 500) / 1000;
-
-       do {
-               if (state->drxd_state != DRXD_STOPPED)
-                       return -1;
-               status = ResetECOD(state);
-               if (status < 0)
-                       break;
-               if (state->type_A) {
-                       status = InitSC(state);
-                       if (status < 0)
-                               break;
-               } else {
-                       status = InitFT(state);
-                       if (status < 0)
-                               break;
-                       status = InitCP(state);
-                       if (status < 0)
-                               break;
-                       status = InitCE(state);
-                       if (status < 0)
-                               break;
-                       status = InitEQ(state);
-                       if (status < 0)
-                               break;
-                       status = InitSC(state);
-                       if (status < 0)
-                               break;
-               }
-
-               /* Restore current IF & RF AGC settings */
-
-               status = SetCfgIfAgc(state, &state->if_agc_cfg);
-               if (status < 0)
-                       break;
-               status = SetCfgRfAgc(state, &state->rf_agc_cfg);
-               if (status < 0)
-                       break;
-
-               mirrorFreqSpect = (state->props.inversion == INVERSION_ON);
-
-               switch (p->transmission_mode) {
-               default:        /* Not set, detect it automatically */
-                       operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
-                       /* fall through , try first guess DRX_FFTMODE_8K */
-               case TRANSMISSION_MODE_8K:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
-                       if (state->type_A) {
-                               status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_8K, 0x0000);
-                               if (status < 0)
-                                       break;
-                               qpskSnCeGain = 99;
-                               qam16SnCeGain = 83;
-                               qam64SnCeGain = 67;
-                       }
-                       break;
-               case TRANSMISSION_MODE_2K:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
-                       if (state->type_A) {
-                               status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_2K, 0x0000);
-                               if (status < 0)
-                                       break;
-                               qpskSnCeGain = 97;
-                               qam16SnCeGain = 71;
-                               qam64SnCeGain = 65;
-                       }
-                       break;
-               }
-
-               switch (p->guard_interval) {
-               case GUARD_INTERVAL_1_4:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
-                       break;
-               case GUARD_INTERVAL_1_8:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
-                       break;
-               case GUARD_INTERVAL_1_16:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
-                       break;
-               case GUARD_INTERVAL_1_32:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
-                       break;
-               default:        /* Not set, detect it automatically */
-                       operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
-                       /* try first guess 1/4 */
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
-                       break;
-               }
-
-               switch (p->hierarchy) {
-               case HIERARCHY_1:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0001, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0001, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
-                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
-                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
-
-                               qpskIsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
-                               qam16IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
-                               qam64IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
-
-                               qpskIsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
-                               qam16IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
-                               qam64IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
-                       }
-                       break;
-
-               case HIERARCHY_2:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0002, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0002, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
-                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
-                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
-
-                               qpskIsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
-                               qam16IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
-                               qam64IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
-
-                               qpskIsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
-                               qam16IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
-                               qam64IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
-                       }
-                       break;
-               case HIERARCHY_4:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0003, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0003, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
-                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
-                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
-
-                               qpskIsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
-                               qam16IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
-                               qam64IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
-
-                               qpskIsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
-                               qam16IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
-                               qam64IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
-                       }
-                       break;
-               case HIERARCHY_AUTO:
-               default:
-                       /* Not set, detect it automatically, start with none */
-                       operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_ALPHA__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
-                               qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
-                               qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
-
-                               qpskIsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
-                               qam16IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
-                               qam64IsGainMan =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
-
-                               qpskIsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
-                               qam16IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
-                               qam64IsGainExp =
-                                   SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
-                       }
-                       break;
-               }
-               status = status;
-               if (status < 0)
-                       break;
-
-               switch (p->modulation) {
-               default:
-                       operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
-                       /* fall through , try first guess
-                          DRX_CONSTELLATION_QAM64 */
-               case QAM_64:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0002, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_64QAM, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0020, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0008, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0002, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam64TdTpsPwr, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qam64SnCeGain, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam64IsGainMan, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam64IsGainExp, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               case QPSK:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_QPSK, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qpskTdTpsPwr, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qpskSnCeGain, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qpskIsGainMan, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qpskIsGainExp, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-
-               case QAM_16:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
-                       if (state->type_A) {
-                               status = Write16(state, EQ_REG_OT_CONST__A, 0x0001, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_16QAM, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0004, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
-                               if (status < 0)
-                                       break;
-
-                               status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam16TdTpsPwr, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_SN_CEGAIN__A, qam16SnCeGain, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam16IsGainMan, 0x0000);
-                               if (status < 0)
-                                       break;
-                               status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam16IsGainExp, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-
-               }
-               status = status;
-               if (status < 0)
-                       break;
-
-               switch (DRX_CHANNEL_HIGH) {
-               default:
-               case DRX_CHANNEL_AUTO:
-               case DRX_CHANNEL_LOW:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
-                       status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000);
-                       if (status < 0)
-                               break;
-                       break;
-               case DRX_CHANNEL_HIGH:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
-                       status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000);
-                       if (status < 0)
-                               break;
-                       break;
-
-               }
-
-               switch (p->code_rate_HP) {
-               case FEC_1_2:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
-                       if (state->type_A) {
-                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               default:
-                       operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
-               case FEC_2_3:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
-                       if (state->type_A) {
-                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               case FEC_3_4:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
-                       if (state->type_A) {
-                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               case FEC_5_6:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
-                       if (state->type_A) {
-                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               case FEC_7_8:
-                       transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
-                       if (state->type_A) {
-                               status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000);
-                               if (status < 0)
-                                       break;
-                       }
-                       break;
-               }
-               status = status;
-               if (status < 0)
-                       break;
-
-               /* First determine real bandwidth (Hz) */
-               /* Also set delay for impulse noise cruncher (only A2) */
-               /* Also set parameters for EC_OC fix, note
-                  EC_OC_REG_TMD_HIL_MAR is changed
-                  by SC for fix for some 8K,1/8 guard but is restored by
-                  InitEC and ResetEC
-                  functions */
-               switch (p->bandwidth_hz) {
-               case 0:
-                       p->bandwidth_hz = 8000000;
-                       /* fall through */
-               case 8000000:
-                       /* (64/7)*(8/8)*1000000 */
-                       bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
-
-                       bandwidthParam = 0;
-                       status = Write16(state,
-                                        FE_AG_REG_IND_DEL__A, 50, 0x0000);
-                       break;
-               case 7000000:
-                       /* (64/7)*(7/8)*1000000 */
-                       bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
-                       bandwidthParam = 0x4807;        /*binary:0100 1000 0000 0111 */
-                       status = Write16(state,
-                                        FE_AG_REG_IND_DEL__A, 59, 0x0000);
-                       break;
-               case 6000000:
-                       /* (64/7)*(6/8)*1000000 */
-                       bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
-                       bandwidthParam = 0x0F07;        /*binary: 0000 1111 0000 0111 */
-                       status = Write16(state,
-                                        FE_AG_REG_IND_DEL__A, 71, 0x0000);
-                       break;
-               default:
-                       status = -EINVAL;
-               }
-               if (status < 0)
-                       break;
-
-               status = Write16(state, SC_RA_RAM_BAND__A, bandwidthParam, 0x0000);
-               if (status < 0)
-                       break;
-
-               {
-                       u16 sc_config;
-                       status = Read16(state, SC_RA_RAM_CONFIG__A, &sc_config, 0);
-                       if (status < 0)
-                               break;
-
-                       /* enable SLAVE mode in 2k 1/32 to
-                          prevent timing change glitches */
-                       if ((p->transmission_mode == TRANSMISSION_MODE_2K) &&
-                           (p->guard_interval == GUARD_INTERVAL_1_32)) {
-                               /* enable slave */
-                               sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
-                       } else {
-                               /* disable slave */
-                               sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
-                       }
-                       status = Write16(state, SC_RA_RAM_CONFIG__A, sc_config, 0);
-                       if (status < 0)
-                               break;
-               }
-
-               status = SetCfgNoiseCalibration(state, &state->noise_cal);
-               if (status < 0)
-                       break;
-
-               if (state->cscd_state == CSCD_INIT) {
-                       /* switch on SRMM scan in SC */
-                       status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DO_SCAN, 0x0000);
-                       if (status < 0)
-                               break;
-/*            CHK_ERROR(Write16(SC_RA_RAM_SAMPLE_RATE_STEP__A, DRXD_OSCDEV_STEP, 0x0000));*/
-                       state->cscd_state = CSCD_SET;
-               }
-
-               /* Now compute FE_IF_REG_INCR */
-               /*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
-                  ((SysFreq / BandWidth) * (2^21) ) - (2^23) */
-               feIfIncr = MulDiv32(state->sys_clock_freq * 1000,
-                                   (1ULL << 21), bandwidth) - (1 << 23);
-               status = Write16(state, FE_IF_REG_INCR0__A, (u16) (feIfIncr & FE_IF_REG_INCR0__M), 0x0000);
-               if (status < 0)
-                       break;
-               status = Write16(state, FE_IF_REG_INCR1__A, (u16) ((feIfIncr >> FE_IF_REG_INCR0__W) & FE_IF_REG_INCR1__M), 0x0000);
-               if (status < 0)
-                       break;
-               /* Bandwidth setting done */
-
-               /* Mirror & frequency offset */
-               SetFrequencyShift(state, off, mirrorFreqSpect);
-
-               /* Start SC, write channel settings to SC */
-
-               /* Enable SC after setting all other parameters */
-               status = Write16(state, SC_COMM_STATE__A, 0, 0x0000);
-               if (status < 0)
-                       break;
-               status = Write16(state, SC_COMM_EXEC__A, 1, 0x0000);
-               if (status < 0)
-                       break;
-
-               /* Write SC parameter registers, operation mode */
-#if 1
-               operationMode = (SC_RA_RAM_OP_AUTO_MODE__M |
-                                SC_RA_RAM_OP_AUTO_GUARD__M |
-                                SC_RA_RAM_OP_AUTO_CONST__M |
-                                SC_RA_RAM_OP_AUTO_HIER__M |
-                                SC_RA_RAM_OP_AUTO_RATE__M);
-#endif
-               status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
-               if (status < 0)
-                       break;
-
-               /* Start correct processes to get in lock */
-               status = SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK, SC_RA_RAM_SW_EVENT_RUN_NMASK__M, SC_RA_RAM_LOCKTRACK_MIN);
-               if (status < 0)
-                       break;
-
-               status = StartOC(state);
-               if (status < 0)
-                       break;
-
-               if (state->operation_mode != OM_Default) {
-                       status = StartDiversity(state);
-                       if (status < 0)
-                               break;
-               }
-
-               state->drxd_state = DRXD_STARTED;
-       } while (0);
-
-       return status;
-}
-
-static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
-{
-       u32 ulRfAgcOutputLevel = 0xffffffff;
-       u32 ulRfAgcSettleLevel = 528;   /* Optimum value for MT2060 */
-       u32 ulRfAgcMinLevel = 0;        /* Currently unused */
-       u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX; /* Currently unused */
-       u32 ulRfAgcSpeed = 0;   /* Currently unused */
-       u32 ulRfAgcMode = 0;    /*2;   Off */
-       u32 ulRfAgcR1 = 820;
-       u32 ulRfAgcR2 = 2200;
-       u32 ulRfAgcR3 = 150;
-       u32 ulIfAgcMode = 0;    /* Auto */
-       u32 ulIfAgcOutputLevel = 0xffffffff;
-       u32 ulIfAgcSettleLevel = 0xffffffff;
-       u32 ulIfAgcMinLevel = 0xffffffff;
-       u32 ulIfAgcMaxLevel = 0xffffffff;
-       u32 ulIfAgcSpeed = 0xffffffff;
-       u32 ulIfAgcR1 = 820;
-       u32 ulIfAgcR2 = 2200;
-       u32 ulIfAgcR3 = 150;
-       u32 ulClock = state->config.clock;
-       u32 ulSerialMode = 0;
-       u32 ulEcOcRegOcModeLop = 4;     /* Dynamic DTO source */
-       u32 ulHiI2cDelay = HI_I2C_DELAY;
-       u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
-       u32 ulHiI2cPatch = 0;
-       u32 ulEnvironment = APPENV_PORTABLE;
-       u32 ulEnvironmentDiversity = APPENV_MOBILE;
-       u32 ulIFFilter = IFFILTER_SAW;
-
-       state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
-       state->if_agc_cfg.outputLevel = 0;
-       state->if_agc_cfg.settleLevel = 140;
-       state->if_agc_cfg.minOutputLevel = 0;
-       state->if_agc_cfg.maxOutputLevel = 1023;
-       state->if_agc_cfg.speed = 904;
-
-       if (ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
-               state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
-               state->if_agc_cfg.outputLevel = (u16) (ulIfAgcOutputLevel);
-       }
-
-       if (ulIfAgcMode == 0 &&
-           ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
-           ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
-           ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
-           ulIfAgcSpeed <= DRXD_FE_CTRL_MAX) {
-               state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
-               state->if_agc_cfg.settleLevel = (u16) (ulIfAgcSettleLevel);
-               state->if_agc_cfg.minOutputLevel = (u16) (ulIfAgcMinLevel);
-               state->if_agc_cfg.maxOutputLevel = (u16) (ulIfAgcMaxLevel);
-               state->if_agc_cfg.speed = (u16) (ulIfAgcSpeed);
-       }
-
-       state->if_agc_cfg.R1 = (u16) (ulIfAgcR1);
-       state->if_agc_cfg.R2 = (u16) (ulIfAgcR2);
-       state->if_agc_cfg.R3 = (u16) (ulIfAgcR3);
-
-       state->rf_agc_cfg.R1 = (u16) (ulRfAgcR1);
-       state->rf_agc_cfg.R2 = (u16) (ulRfAgcR2);
-       state->rf_agc_cfg.R3 = (u16) (ulRfAgcR3);
-
-       state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
-       /* rest of the RFAgcCfg structure currently unused */
-       if (ulRfAgcMode == 1 && ulRfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
-               state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
-               state->rf_agc_cfg.outputLevel = (u16) (ulRfAgcOutputLevel);
-       }
-
-       if (ulRfAgcMode == 0 &&
-           ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
-           ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
-           ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
-           ulRfAgcSpeed <= DRXD_FE_CTRL_MAX) {
-               state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
-               state->rf_agc_cfg.settleLevel = (u16) (ulRfAgcSettleLevel);
-               state->rf_agc_cfg.minOutputLevel = (u16) (ulRfAgcMinLevel);
-               state->rf_agc_cfg.maxOutputLevel = (u16) (ulRfAgcMaxLevel);
-               state->rf_agc_cfg.speed = (u16) (ulRfAgcSpeed);
-       }
-
-       if (ulRfAgcMode == 2)
-               state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
-
-       if (ulEnvironment <= 2)
-               state->app_env_default = (enum app_env)
-                   (ulEnvironment);
-       if (ulEnvironmentDiversity <= 2)
-               state->app_env_diversity = (enum app_env)
-                   (ulEnvironmentDiversity);
-
-       if (ulIFFilter == IFFILTER_DISCRETE) {
-               /* discrete filter */
-               state->noise_cal.cpOpt = 0;
-               state->noise_cal.cpNexpOfs = 40;
-               state->noise_cal.tdCal2k = -40;
-               state->noise_cal.tdCal8k = -24;
-       } else {
-               /* SAW filter */
-               state->noise_cal.cpOpt = 1;
-               state->noise_cal.cpNexpOfs = 0;
-               state->noise_cal.tdCal2k = -21;
-               state->noise_cal.tdCal8k = -24;
-       }
-       state->m_EcOcRegOcModeLop = (u16) (ulEcOcRegOcModeLop);
-
-       state->chip_adr = (state->config.demod_address << 1) | 1;
-       switch (ulHiI2cPatch) {
-       case 1:
-               state->m_HiI2cPatch = DRXD_HiI2cPatch_1;
-               break;
-       case 3:
-               state->m_HiI2cPatch = DRXD_HiI2cPatch_3;
-               break;
-       default:
-               state->m_HiI2cPatch = NULL;
-       }
-
-       /* modify tuner and clock attributes */
-       state->intermediate_freq = (u16) (IntermediateFrequency / 1000);
-       /* expected system clock frequency in kHz */
-       state->expected_sys_clock_freq = 48000;
-       /* real system clock frequency in kHz */
-       state->sys_clock_freq = 48000;
-       state->osc_clock_freq = (u16) ulClock;
-       state->osc_clock_deviation = 0;
-       state->cscd_state = CSCD_INIT;
-       state->drxd_state = DRXD_UNINITIALIZED;
-
-       state->PGA = 0;
-       state->type_A = 0;
-       state->tuner_mirrors = 0;
-
-       /* modify MPEG output attributes */
-       state->insert_rs_byte = state->config.insert_rs_byte;
-       state->enable_parallel = (ulSerialMode != 1);
-
-       /* Timing div, 250ns/Psys */
-       /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
-
-       state->hi_cfg_timing_div = (u16) ((state->sys_clock_freq / 1000) *
-                                         ulHiI2cDelay) / 1000;
-       /* Bridge delay, uses oscilator clock */
-       /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
-       state->hi_cfg_bridge_delay = (u16) ((state->osc_clock_freq / 1000) *
-                                           ulHiI2cBridgeDelay) / 1000;
-
-       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
-       /* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
-       state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
-       return 0;
-}
-
-int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
-{
-       int status = 0;
-       u32 driverVersion;
-
-       if (state->init_done)
-               return 0;
-
-       CDRXD(state, state->config.IF ? state->config.IF : 36000000);
-
-       do {
-               state->operation_mode = OM_Default;
-
-               status = SetDeviceTypeId(state);
-               if (status < 0)
-                       break;
-
-               /* Apply I2c address patch to B1 */
-               if (!state->type_A && state->m_HiI2cPatch != NULL)
-                       status = WriteTable(state, state->m_HiI2cPatch);
-                       if (status < 0)
-                               break;
-
-               if (state->type_A) {
-                       /* HI firmware patch for UIO readout,
-                          avoid clearing of result register */
-                       status = Write16(state, 0x43012D, 0x047f, 0);
-                       if (status < 0)
-                               break;
-               }
-
-               status = HI_ResetCommand(state);
-               if (status < 0)
-                       break;
-
-               status = StopAllProcessors(state);
-               if (status < 0)
-                       break;
-               status = InitCC(state);
-               if (status < 0)
-                       break;
-
-               state->osc_clock_deviation = 0;
-
-               if (state->config.osc_deviation)
-                       state->osc_clock_deviation =
-                           state->config.osc_deviation(state->priv, 0, 0);
-               {
-                       /* Handle clock deviation */
-                       s32 devB;
-                       s32 devA = (s32) (state->osc_clock_deviation) *
-                           (s32) (state->expected_sys_clock_freq);
-                       /* deviation in kHz */
-                       s32 deviation = (devA / (1000000L));
-                       /* rounding, signed */
-                       if (devA > 0)
-                               devB = (2);
-                       else
-                               devB = (-2);
-                       if ((devB * (devA % 1000000L) > 1000000L)) {
-                               /* add +1 or -1 */
-                               deviation += (devB / 2);
-                       }
-
-                       state->sys_clock_freq =
-                           (u16) ((state->expected_sys_clock_freq) +
-                                  deviation);
-               }
-               status = InitHI(state);
-               if (status < 0)
-                       break;
-               status = InitAtomicRead(state);
-               if (status < 0)
-                       break;
-
-               status = EnableAndResetMB(state);
-               if (status < 0)
-                       break;
-               if (state->type_A)
-                       status = ResetCEFR(state);
-                       if (status < 0)
-                               break;
-
-               if (fw) {
-                       status = DownloadMicrocode(state, fw, fw_size);
-                       if (status < 0)
-                               break;
-               } else {
-                       status = DownloadMicrocode(state, state->microcode, state->microcode_length);
-                       if (status < 0)
-                               break;
-               }
-
-               if (state->PGA) {
-                       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
-                       SetCfgPga(state, 0);    /* PGA = 0 dB */
-               } else {
-                       state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
-               }
-
-               state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
-
-               status = InitFE(state);
-               if (status < 0)
-                       break;
-               status = InitFT(state);
-               if (status < 0)
-                       break;
-               status = InitCP(state);
-               if (status < 0)
-                       break;
-               status = InitCE(state);
-               if (status < 0)
-                       break;
-               status = InitEQ(state);
-               if (status < 0)
-                       break;
-               status = InitEC(state);
-               if (status < 0)
-                       break;
-               status = InitSC(state);
-               if (status < 0)
-                       break;
-
-               status = SetCfgIfAgc(state, &state->if_agc_cfg);
-               if (status < 0)
-                       break;
-               status = SetCfgRfAgc(state, &state->rf_agc_cfg);
-               if (status < 0)
-                       break;
-
-               state->cscd_state = CSCD_INIT;
-               status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-               if (status < 0)
-                       break;
-               status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
-               if (status < 0)
-                       break;
-
-               driverVersion = (((VERSION_MAJOR / 10) << 4) +
-                                (VERSION_MAJOR % 10)) << 24;
-               driverVersion += (((VERSION_MINOR / 10) << 4) +
-                                 (VERSION_MINOR % 10)) << 16;
-               driverVersion += ((VERSION_PATCH / 1000) << 12) +
-                   ((VERSION_PATCH / 100) << 8) +
-                   ((VERSION_PATCH / 10) << 4) + (VERSION_PATCH % 10);
-
-               status = Write32(state, SC_RA_RAM_DRIVER_VERSION__AX, driverVersion, 0);
-               if (status < 0)
-                       break;
-
-               status = StopOC(state);
-               if (status < 0)
-                       break;
-
-               state->drxd_state = DRXD_STOPPED;
-               state->init_done = 1;
-               status = 0;
-       } while (0);
-       return status;
-}
-
-int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
-{
-       DRX_GetLockStatus(state, pLockStatus);
-
-       /*if (*pLockStatus&DRX_LOCK_MPEG) */
-       if (*pLockStatus & DRX_LOCK_FEC) {
-               ConfigureMPEGOutput(state, 1);
-               /* Get status again, in case we have MPEG lock now */
-               /*DRX_GetLockStatus(state, pLockStatus); */
-       }
-
-       return 0;
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-       u32 value;
-       int res;
-
-       res = ReadIFAgc(state, &value);
-       if (res < 0)
-               *strength = 0;
-       else
-               *strength = 0xffff - (value << 4);
-       return 0;
-}
-
-static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-       u32 lock;
-
-       DRXD_status(state, &lock);
-       *status = 0;
-       /* No MPEG lock in V255 firmware, bug ? */
-#if 1
-       if (lock & DRX_LOCK_MPEG)
-               *status |= FE_HAS_LOCK;
-#else
-       if (lock & DRX_LOCK_FEC)
-               *status |= FE_HAS_LOCK;
-#endif
-       if (lock & DRX_LOCK_FEC)
-               *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
-       if (lock & DRX_LOCK_DEMOD)
-               *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-
-       return 0;
-}
-
-static int drxd_init(struct dvb_frontend *fe)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-       int err = 0;
-
-/*     if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
-       return DRXD_init(state, 0, 0);
-
-       err = DRXD_init(state, state->fw->data, state->fw->size);
-       release_firmware(state->fw);
-       return err;
-}
-
-int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-
-       if (state->config.disable_i2c_gate_ctrl == 1)
-               return 0;
-
-       return DRX_ConfigureI2CBridge(state, onoff);
-}
-EXPORT_SYMBOL(drxd_config_i2c);
-
-static int drxd_get_tune_settings(struct dvb_frontend *fe,
-                                 struct dvb_frontend_tune_settings *sets)
-{
-       sets->min_delay_ms = 10000;
-       sets->max_drift = 0;
-       sets->step_size = 0;
-       return 0;
-}
-
-static int drxd_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       *ber = 0;
-       return 0;
-}
-
-static int drxd_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       *snr = 0;
-       return 0;
-}
-
-static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-static int drxd_sleep(struct dvb_frontend *fe)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-
-       ConfigureMPEGOutput(state, 0);
-       return 0;
-}
-
-static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       return drxd_config_i2c(fe, enable);
-}
-
-static int drxd_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct drxd_state *state = fe->demodulator_priv;
-       s32 off = 0;
-
-       state->props = *p;
-       DRX_Stop(state);
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       msleep(200);
-
-       return DRX_Start(state, off);
-}
-
-static void drxd_release(struct dvb_frontend *fe)
-{
-       struct drxd_state *state = fe->demodulator_priv;
-
-       kfree(state);
-}
-
-static struct dvb_frontend_ops drxd_ops = {
-       .delsys = { SYS_DVBT},
-       .info = {
-                .name = "Micronas DRXD DVB-T",
-                .frequency_min = 47125000,
-                .frequency_max = 855250000,
-                .frequency_stepsize = 166667,
-                .frequency_tolerance = 0,
-                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                FE_CAN_FEC_AUTO |
-                FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                FE_CAN_QAM_AUTO |
-                FE_CAN_TRANSMISSION_MODE_AUTO |
-                FE_CAN_GUARD_INTERVAL_AUTO |
-                FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
-
-       .release = drxd_release,
-       .init = drxd_init,
-       .sleep = drxd_sleep,
-       .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
-
-       .set_frontend = drxd_set_frontend,
-       .get_tune_settings = drxd_get_tune_settings,
-
-       .read_status = drxd_read_status,
-       .read_ber = drxd_read_ber,
-       .read_signal_strength = drxd_read_signal_strength,
-       .read_snr = drxd_read_snr,
-       .read_ucblocks = drxd_read_ucblocks,
-};
-
-struct dvb_frontend *drxd_attach(const struct drxd_config *config,
-                                void *priv, struct i2c_adapter *i2c,
-                                struct device *dev)
-{
-       struct drxd_state *state = NULL;
-
-       state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-       memset(state, 0, sizeof(*state));
-
-       memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
-       state->dev = dev;
-       state->config = *config;
-       state->i2c = i2c;
-       state->priv = priv;
-
-       mutex_init(&state->mutex);
-
-       if (Read16(state, 0, 0, 0) < 0)
-               goto error;
-
-       memcpy(&state->frontend.ops, &drxd_ops,
-              sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       ConfigureMPEGOutput(state, 0);
-       return &state->frontend;
-
-error:
-       printk(KERN_ERR "drxd: not found\n");
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(drxd_attach);
-
-MODULE_DESCRIPTION("DRXD driver");
-MODULE_AUTHOR("Micronas");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxd_map_firm.h b/drivers/media/dvb/frontends/drxd_map_firm.h
deleted file mode 100644 (file)
index 6bc553a..0000000
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * drx3973d_map_firm.h
- *
- * Copyright (C) 2006-2007 Micronas
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef __DRX3973D_MAP__H__
-#define __DRX3973D_MAP__H__
-
-/*
- * Note: originally, this file contained 12000+ lines of data
- * Probably a few lines for every firwmare assembler instruction. However,
- * only a few defines were actually used. So, removed all uneeded lines.
- * If ever needed, the other lines can be easily obtained via git history.
- */
-
-#define HI_COMM_EXEC__A                                              0x400000
-#define HI_COMM_MB__A                                                0x400002
-#define HI_CT_REG_COMM_STATE__A                                      0x410001
-#define HI_RA_RAM_SRV_RES__A                                         0x420031
-#define HI_RA_RAM_SRV_CMD__A                                         0x420032
-#define   HI_RA_RAM_SRV_CMD_RESET                                    0x2
-#define   HI_RA_RAM_SRV_CMD_CONFIG                                   0x3
-#define   HI_RA_RAM_SRV_CMD_EXECUTE                                  0x6
-#define HI_RA_RAM_SRV_RST_KEY__A                                     0x420033
-#define   HI_RA_RAM_SRV_RST_KEY_ACT                                  0x3973
-#define HI_RA_RAM_SRV_CFG_KEY__A                                     0x420033
-#define HI_RA_RAM_SRV_CFG_DIV__A                                     0x420034
-#define HI_RA_RAM_SRV_CFG_BDL__A                                     0x420035
-#define HI_RA_RAM_SRV_CFG_WUP__A                                     0x420036
-#define HI_RA_RAM_SRV_CFG_ACT__A                                     0x420037
-#define     HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                            0x1
-#define   HI_RA_RAM_SRV_CFG_ACT_BRD__M                               0x4
-#define     HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                            0x0
-#define     HI_RA_RAM_SRV_CFG_ACT_BRD_ON                             0x4
-#define     HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                            0x8
-#define HI_RA_RAM_USR_BEGIN__A                                       0x420040
-#define HI_IF_RAM_TRP_BPT0__AX                                       0x430000
-#define HI_IF_RAM_USR_BEGIN__A                                       0x430200
-#define SC_COMM_EXEC__A                                              0x800000
-#define     SC_COMM_EXEC_CTL_STOP                                    0x0
-#define SC_COMM_STATE__A                                             0x800001
-#define SC_RA_RAM_PARAM0__A                                          0x820040
-#define SC_RA_RAM_PARAM1__A                                          0x820041
-#define SC_RA_RAM_CMD_ADDR__A                                        0x820042
-#define SC_RA_RAM_CMD__A                                             0x820043
-#define   SC_RA_RAM_CMD_PROC_START                                   0x1
-#define   SC_RA_RAM_CMD_SET_PREF_PARAM                               0x3
-#define   SC_RA_RAM_CMD_GET_OP_PARAM                                 0x5
-#define   SC_RA_RAM_SW_EVENT_RUN_NMASK__M                            0x1
-#define   SC_RA_RAM_LOCKTRACK_MIN                                    0x1
-#define     SC_RA_RAM_OP_PARAM_MODE_2K                               0x0
-#define     SC_RA_RAM_OP_PARAM_MODE_8K                               0x1
-#define     SC_RA_RAM_OP_PARAM_GUARD_32                              0x0
-#define     SC_RA_RAM_OP_PARAM_GUARD_16                              0x4
-#define     SC_RA_RAM_OP_PARAM_GUARD_8                               0x8
-#define     SC_RA_RAM_OP_PARAM_GUARD_4                               0xC
-#define     SC_RA_RAM_OP_PARAM_CONST_QPSK                            0x0
-#define     SC_RA_RAM_OP_PARAM_CONST_QAM16                           0x10
-#define     SC_RA_RAM_OP_PARAM_CONST_QAM64                           0x20
-#define     SC_RA_RAM_OP_PARAM_HIER_NO                               0x0
-#define     SC_RA_RAM_OP_PARAM_HIER_A1                               0x40
-#define     SC_RA_RAM_OP_PARAM_HIER_A2                               0x80
-#define     SC_RA_RAM_OP_PARAM_HIER_A4                               0xC0
-#define     SC_RA_RAM_OP_PARAM_RATE_1_2                              0x0
-#define     SC_RA_RAM_OP_PARAM_RATE_2_3                              0x200
-#define     SC_RA_RAM_OP_PARAM_RATE_3_4                              0x400
-#define     SC_RA_RAM_OP_PARAM_RATE_5_6                              0x600
-#define     SC_RA_RAM_OP_PARAM_RATE_7_8                              0x800
-#define     SC_RA_RAM_OP_PARAM_PRIO_HI                               0x0
-#define     SC_RA_RAM_OP_PARAM_PRIO_LO                               0x1000
-#define   SC_RA_RAM_OP_AUTO_MODE__M                                  0x1
-#define   SC_RA_RAM_OP_AUTO_GUARD__M                                 0x2
-#define   SC_RA_RAM_OP_AUTO_CONST__M                                 0x4
-#define   SC_RA_RAM_OP_AUTO_HIER__M                                  0x8
-#define   SC_RA_RAM_OP_AUTO_RATE__M                                  0x10
-#define SC_RA_RAM_LOCK__A                                            0x82004B
-#define   SC_RA_RAM_LOCK_DEMOD__M                                    0x1
-#define   SC_RA_RAM_LOCK_FEC__M                                      0x2
-#define   SC_RA_RAM_LOCK_MPEG__M                                     0x4
-#define SC_RA_RAM_BE_OPT_ENA__A                                      0x82004C
-#define   SC_RA_RAM_BE_OPT_ENA_CP_OPT                                0x1
-#define SC_RA_RAM_BE_OPT_DELAY__A                                    0x82004D
-#define SC_RA_RAM_CONFIG__A                                          0x820050
-#define   SC_RA_RAM_CONFIG_FR_ENABLE__M                              0x4
-#define   SC_RA_RAM_CONFIG_FREQSCAN__M                               0x10
-#define   SC_RA_RAM_CONFIG_SLAVE__M                                  0x20
-#define SC_RA_RAM_IF_SAVE__AX                                        0x82008E
-#define SC_RA_RAM_IR_COARSE_2K_LENGTH__A                             0x8200D1
-#define SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                           0x9
-#define SC_RA_RAM_IR_COARSE_2K_FREQINC__A                            0x8200D2
-#define SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                          0x4
-#define SC_RA_RAM_IR_COARSE_2K_KAISINC__A                            0x8200D3
-#define SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                          0x100
-#define SC_RA_RAM_IR_COARSE_8K_LENGTH__A                             0x8200D4
-#define SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                           0x8
-#define SC_RA_RAM_IR_COARSE_8K_FREQINC__A                            0x8200D5
-#define SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                          0x8
-#define SC_RA_RAM_IR_COARSE_8K_KAISINC__A                            0x8200D6
-#define SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                          0x200
-#define SC_RA_RAM_IR_FINE_2K_LENGTH__A                               0x8200D7
-#define SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                             0x9
-#define SC_RA_RAM_IR_FINE_2K_FREQINC__A                              0x8200D8
-#define SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                            0x4
-#define SC_RA_RAM_IR_FINE_2K_KAISINC__A                              0x8200D9
-#define SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                            0x100
-#define SC_RA_RAM_IR_FINE_8K_LENGTH__A                               0x8200DA
-#define SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                             0xB
-#define SC_RA_RAM_IR_FINE_8K_FREQINC__A                              0x8200DB
-#define SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                            0x1
-#define SC_RA_RAM_IR_FINE_8K_KAISINC__A                              0x8200DC
-#define SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                            0x40
-#define SC_RA_RAM_ECHO_SHIFT_LIM__A                                  0x8200DD
-#define SC_RA_RAM_SAMPLE_RATE_COUNT__A                               0x8200E8
-#define SC_RA_RAM_SAMPLE_RATE_STEP__A                                0x8200E9
-#define SC_RA_RAM_BAND__A                                            0x8200EC
-#define SC_RA_RAM_LC_ABS_2K__A                                       0x8200F4
-#define SC_RA_RAM_LC_ABS_2K__PRE                                     0x1F
-#define SC_RA_RAM_LC_ABS_8K__A                                       0x8200F5
-#define SC_RA_RAM_LC_ABS_8K__PRE                                     0x1F
-#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                        0x1D6
-#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                        0x4
-#define SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                           0x1BB
-#define SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                           0x5
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                          0x1EF
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                          0x5
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                       0x15E
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                       0x5
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                       0x11A
-#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                       0x6
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                          0x1FB
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                          0x5
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                       0x12F
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                       0x5
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                       0x197
-#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                       0x5
-#define SC_RA_RAM_DRIVER_VERSION__AX                                 0x8201FE
-#define   SC_RA_RAM_PROC_LOCKTRACK                                   0x0
-#define FE_COMM_EXEC__A                                              0xC00000
-#define FE_AD_REG_COMM_EXEC__A                                       0xC10000
-#define FE_AD_REG_FDB_IN__A                                          0xC10012
-#define FE_AD_REG_PD__A                                              0xC10013
-#define FE_AD_REG_INVEXT__A                                          0xC10014
-#define FE_AD_REG_CLKNEG__A                                          0xC10015
-#define FE_AG_REG_COMM_EXEC__A                                       0xC20000
-#define FE_AG_REG_AG_MODE_LOP__A                                     0xC20010
-#define   FE_AG_REG_AG_MODE_LOP_MODE_4__M                            0x10
-#define     FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                      0x0
-#define     FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                     0x10
-#define   FE_AG_REG_AG_MODE_LOP_MODE_5__M                            0x20
-#define     FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                      0x0
-#define   FE_AG_REG_AG_MODE_LOP_MODE_C__M                            0x1000
-#define     FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                      0x0
-#define     FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                     0x1000
-#define   FE_AG_REG_AG_MODE_LOP_MODE_E__M                            0x4000
-#define     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                      0x0
-#define     FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                     0x4000
-#define FE_AG_REG_AG_MODE_HIP__A                                     0xC20011
-#define FE_AG_REG_AG_PGA_MODE__A                                     0xC20012
-#define   FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                      0x0
-#define   FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                      0x1
-#define FE_AG_REG_AG_AGC_SIO__A                                      0xC20013
-#define   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                          0x2
-#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                    0x0
-#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                     0x2
-#define FE_AG_REG_AG_PWD__A                                          0xC20015
-#define   FE_AG_REG_AG_PWD_PWD_PD2__M                                0x2
-#define     FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                         0x0
-#define     FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                          0x2
-#define FE_AG_REG_DCE_AUR_CNT__A                                     0xC20016
-#define FE_AG_REG_DCE_RUR_CNT__A                                     0xC20017
-#define FE_AG_REG_ACE_AUR_CNT__A                                     0xC2001A
-#define FE_AG_REG_ACE_RUR_CNT__A                                     0xC2001B
-#define FE_AG_REG_CDR_RUR_CNT__A                                     0xC20020
-#define FE_AG_REG_EGC_RUR_CNT__A                                     0xC20024
-#define FE_AG_REG_EGC_SET_LVL__A                                     0xC20025
-#define FE_AG_REG_EGC_SET_LVL__M                                     0x1FF
-#define FE_AG_REG_EGC_FLA_RGN__A                                     0xC20026
-#define FE_AG_REG_EGC_SLO_RGN__A                                     0xC20027
-#define FE_AG_REG_EGC_JMP_PSN__A                                     0xC20028
-#define FE_AG_REG_EGC_FLA_INC__A                                     0xC20029
-#define FE_AG_REG_EGC_FLA_DEC__A                                     0xC2002A
-#define FE_AG_REG_EGC_SLO_INC__A                                     0xC2002B
-#define FE_AG_REG_EGC_SLO_DEC__A                                     0xC2002C
-#define FE_AG_REG_EGC_FAS_INC__A                                     0xC2002D
-#define FE_AG_REG_EGC_FAS_DEC__A                                     0xC2002E
-#define FE_AG_REG_PM1_AGC_WRI__A                                     0xC20030
-#define FE_AG_REG_PM1_AGC_WRI__M                                     0x7FF
-#define FE_AG_REG_GC1_AGC_RIC__A                                     0xC20031
-#define FE_AG_REG_GC1_AGC_OFF__A                                     0xC20032
-#define FE_AG_REG_GC1_AGC_MAX__A                                     0xC20033
-#define FE_AG_REG_GC1_AGC_MIN__A                                     0xC20034
-#define FE_AG_REG_GC1_AGC_DAT__A                                     0xC20035
-#define FE_AG_REG_GC1_AGC_DAT__M                                     0x3FF
-#define FE_AG_REG_PM2_AGC_WRI__A                                     0xC20036
-#define FE_AG_REG_IND_WIN__A                                         0xC2003C
-#define FE_AG_REG_IND_THD_LOL__A                                     0xC2003D
-#define FE_AG_REG_IND_THD_HIL__A                                     0xC2003E
-#define FE_AG_REG_IND_DEL__A                                         0xC2003F
-#define FE_AG_REG_IND_PD1_WRI__A                                     0xC20040
-#define FE_AG_REG_PDA_AUR_CNT__A                                     0xC20041
-#define FE_AG_REG_PDA_RUR_CNT__A                                     0xC20042
-#define FE_AG_REG_PDA_AVE_DAT__A                                     0xC20043
-#define FE_AG_REG_PDC_RUR_CNT__A                                     0xC20044
-#define FE_AG_REG_PDC_SET_LVL__A                                     0xC20045
-#define FE_AG_REG_PDC_FLA_RGN__A                                     0xC20046
-#define FE_AG_REG_PDC_JMP_PSN__A                                     0xC20047
-#define FE_AG_REG_PDC_FLA_STP__A                                     0xC20048
-#define FE_AG_REG_PDC_SLO_STP__A                                     0xC20049
-#define FE_AG_REG_PDC_PD2_WRI__A                                     0xC2004A
-#define FE_AG_REG_PDC_MAP_DAT__A                                     0xC2004B
-#define FE_AG_REG_PDC_MAX__A                                         0xC2004C
-#define FE_AG_REG_TGA_AUR_CNT__A                                     0xC2004D
-#define FE_AG_REG_TGA_RUR_CNT__A                                     0xC2004E
-#define FE_AG_REG_TGA_AVE_DAT__A                                     0xC2004F
-#define FE_AG_REG_TGC_RUR_CNT__A                                     0xC20050
-#define FE_AG_REG_TGC_SET_LVL__A                                     0xC20051
-#define FE_AG_REG_TGC_SET_LVL__M                                     0x3F
-#define FE_AG_REG_TGC_FLA_RGN__A                                     0xC20052
-#define FE_AG_REG_TGC_JMP_PSN__A                                     0xC20053
-#define FE_AG_REG_TGC_FLA_STP__A                                     0xC20054
-#define FE_AG_REG_TGC_SLO_STP__A                                     0xC20055
-#define FE_AG_REG_TGC_MAP_DAT__A                                     0xC20056
-#define FE_AG_REG_FGA_AUR_CNT__A                                     0xC20057
-#define FE_AG_REG_FGA_RUR_CNT__A                                     0xC20058
-#define FE_AG_REG_FGM_WRI__A                                         0xC20061
-#define FE_AG_REG_BGC_FGC_WRI__A                                     0xC20068
-#define FE_AG_REG_BGC_CGC_WRI__A                                     0xC20069
-#define FE_FS_REG_COMM_EXEC__A                                       0xC30000
-#define FE_FS_REG_ADD_INC_LOP__A                                     0xC30010
-#define FE_FD_REG_COMM_EXEC__A                                       0xC40000
-#define FE_FD_REG_SCL__A                                             0xC40010
-#define FE_FD_REG_MAX_LEV__A                                         0xC40011
-#define FE_FD_REG_NR__A                                              0xC40012
-#define FE_FD_REG_MEAS_VAL__A                                        0xC40014
-#define FE_IF_REG_COMM_EXEC__A                                       0xC50000
-#define FE_IF_REG_INCR0__A                                           0xC50010
-#define FE_IF_REG_INCR0__W                                           16
-#define FE_IF_REG_INCR0__M                                           0xFFFF
-#define FE_IF_REG_INCR1__A                                           0xC50011
-#define FE_IF_REG_INCR1__M                                           0xFF
-#define FE_CF_REG_COMM_EXEC__A                                       0xC60000
-#define FE_CF_REG_SCL__A                                             0xC60010
-#define FE_CF_REG_MAX_LEV__A                                         0xC60011
-#define FE_CF_REG_NR__A                                              0xC60012
-#define FE_CF_REG_IMP_VAL__A                                         0xC60013
-#define FE_CF_REG_MEAS_VAL__A                                        0xC60014
-#define FE_CU_REG_COMM_EXEC__A                                       0xC70000
-#define FE_CU_REG_FRM_CNT_RST__A                                     0xC70011
-#define FE_CU_REG_FRM_CNT_STR__A                                     0xC70012
-#define FT_COMM_EXEC__A                                              0x1000000
-#define FT_REG_COMM_EXEC__A                                          0x1010000
-#define CP_COMM_EXEC__A                                              0x1400000
-#define CP_REG_COMM_EXEC__A                                          0x1410000
-#define CP_REG_INTERVAL__A                                           0x1410011
-#define CP_REG_BR_SPL_OFFSET__A                                      0x1410023
-#define CP_REG_BR_STR_DEL__A                                         0x1410024
-#define CP_REG_RT_ANG_INC0__A                                        0x1410030
-#define CP_REG_RT_ANG_INC1__A                                        0x1410031
-#define CP_REG_RT_DETECT_ENA__A                                      0x1410032
-#define CP_REG_RT_DETECT_TRH__A                                      0x1410033
-#define CP_REG_RT_EXP_MARG__A                                        0x141003E
-#define CP_REG_AC_NEXP_OFFS__A                                       0x1410040
-#define CP_REG_AC_AVER_POW__A                                        0x1410041
-#define CP_REG_AC_MAX_POW__A                                         0x1410042
-#define CP_REG_AC_WEIGHT_MAN__A                                      0x1410043
-#define CP_REG_AC_WEIGHT_EXP__A                                      0x1410044
-#define CP_REG_AC_AMP_MODE__A                                        0x1410047
-#define CP_REG_AC_AMP_FIX__A                                         0x1410048
-#define CP_REG_AC_ANG_MODE__A                                        0x141004A
-#define CE_COMM_EXEC__A                                              0x1800000
-#define CE_REG_COMM_EXEC__A                                          0x1810000
-#define CE_REG_TAPSET__A                                             0x1810011
-#define CE_REG_AVG_POW__A                                            0x1810012
-#define CE_REG_MAX_POW__A                                            0x1810013
-#define CE_REG_ATT__A                                                0x1810014
-#define CE_REG_NRED__A                                               0x1810015
-#define CE_REG_NE_ERR_SELECT__A                                      0x1810043
-#define CE_REG_NE_TD_CAL__A                                          0x1810044
-#define CE_REG_NE_MIXAVG__A                                          0x1810046
-#define CE_REG_NE_NUPD_OFS__A                                        0x1810047
-#define CE_REG_PE_NEXP_OFFS__A                                       0x1810050
-#define CE_REG_PE_TIMESHIFT__A                                       0x1810051
-#define CE_REG_TP_A0_TAP_NEW__A                                      0x1810064
-#define CE_REG_TP_A0_TAP_NEW_VALID__A                                0x1810065
-#define CE_REG_TP_A0_MU_LMS_STEP__A                                  0x1810066
-#define CE_REG_TP_A1_TAP_NEW__A                                      0x1810068
-#define CE_REG_TP_A1_TAP_NEW_VALID__A                                0x1810069
-#define CE_REG_TP_A1_MU_LMS_STEP__A                                  0x181006A
-#define CE_REG_TI_NEXP_OFFS__A                                       0x1810070
-#define CE_REG_FI_SHT_INCR__A                                        0x1810090
-#define CE_REG_FI_EXP_NORM__A                                        0x1810091
-#define CE_REG_IR_INPUTSEL__A                                        0x18100A0
-#define CE_REG_IR_STARTPOS__A                                        0x18100A1
-#define CE_REG_IR_NEXP_THRES__A                                      0x18100A2
-#define CE_REG_FR_TREAL00__A                                         0x1820010
-#define CE_REG_FR_TIMAG00__A                                         0x1820011
-#define CE_REG_FR_TREAL01__A                                         0x1820012
-#define CE_REG_FR_TIMAG01__A                                         0x1820013
-#define CE_REG_FR_TREAL02__A                                         0x1820014
-#define CE_REG_FR_TIMAG02__A                                         0x1820015
-#define CE_REG_FR_TREAL03__A                                         0x1820016
-#define CE_REG_FR_TIMAG03__A                                         0x1820017
-#define CE_REG_FR_TREAL04__A                                         0x1820018
-#define CE_REG_FR_TIMAG04__A                                         0x1820019
-#define CE_REG_FR_TREAL05__A                                         0x182001A
-#define CE_REG_FR_TIMAG05__A                                         0x182001B
-#define CE_REG_FR_TREAL06__A                                         0x182001C
-#define CE_REG_FR_TIMAG06__A                                         0x182001D
-#define CE_REG_FR_TREAL07__A                                         0x182001E
-#define CE_REG_FR_TIMAG07__A                                         0x182001F
-#define CE_REG_FR_TREAL08__A                                         0x1820020
-#define CE_REG_FR_TIMAG08__A                                         0x1820021
-#define CE_REG_FR_TREAL09__A                                         0x1820022
-#define CE_REG_FR_TIMAG09__A                                         0x1820023
-#define CE_REG_FR_TREAL10__A                                         0x1820024
-#define CE_REG_FR_TIMAG10__A                                         0x1820025
-#define CE_REG_FR_TREAL11__A                                         0x1820026
-#define CE_REG_FR_TIMAG11__A                                         0x1820027
-#define CE_REG_FR_MID_TAP__A                                         0x1820028
-#define CE_REG_FR_SQS_G00__A                                         0x1820029
-#define CE_REG_FR_SQS_G01__A                                         0x182002A
-#define CE_REG_FR_SQS_G02__A                                         0x182002B
-#define CE_REG_FR_SQS_G03__A                                         0x182002C
-#define CE_REG_FR_SQS_G04__A                                         0x182002D
-#define CE_REG_FR_SQS_G05__A                                         0x182002E
-#define CE_REG_FR_SQS_G06__A                                         0x182002F
-#define CE_REG_FR_SQS_G07__A                                         0x1820030
-#define CE_REG_FR_SQS_G08__A                                         0x1820031
-#define CE_REG_FR_SQS_G09__A                                         0x1820032
-#define CE_REG_FR_SQS_G10__A                                         0x1820033
-#define CE_REG_FR_SQS_G11__A                                         0x1820034
-#define CE_REG_FR_SQS_G12__A                                         0x1820035
-#define CE_REG_FR_RIO_G00__A                                         0x1820036
-#define CE_REG_FR_RIO_G01__A                                         0x1820037
-#define CE_REG_FR_RIO_G02__A                                         0x1820038
-#define CE_REG_FR_RIO_G03__A                                         0x1820039
-#define CE_REG_FR_RIO_G04__A                                         0x182003A
-#define CE_REG_FR_RIO_G05__A                                         0x182003B
-#define CE_REG_FR_RIO_G06__A                                         0x182003C
-#define CE_REG_FR_RIO_G07__A                                         0x182003D
-#define CE_REG_FR_RIO_G08__A                                         0x182003E
-#define CE_REG_FR_RIO_G09__A                                         0x182003F
-#define CE_REG_FR_RIO_G10__A                                         0x1820040
-#define CE_REG_FR_MODE__A                                            0x1820041
-#define CE_REG_FR_SQS_TRH__A                                         0x1820042
-#define CE_REG_FR_RIO_GAIN__A                                        0x1820043
-#define CE_REG_FR_BYPASS__A                                          0x1820044
-#define CE_REG_FR_PM_SET__A                                          0x1820045
-#define CE_REG_FR_ERR_SH__A                                          0x1820046
-#define CE_REG_FR_MAN_SH__A                                          0x1820047
-#define CE_REG_FR_TAP_SH__A                                          0x1820048
-#define EQ_COMM_EXEC__A                                              0x1C00000
-#define EQ_REG_COMM_EXEC__A                                          0x1C10000
-#define EQ_REG_COMM_MB__A                                            0x1C10002
-#define EQ_REG_IS_GAIN_MAN__A                                        0x1C10015
-#define EQ_REG_IS_GAIN_EXP__A                                        0x1C10016
-#define EQ_REG_IS_CLIP_EXP__A                                        0x1C10017
-#define EQ_REG_SN_CEGAIN__A                                          0x1C1002A
-#define EQ_REG_SN_OFFSET__A                                          0x1C1002B
-#define EQ_REG_RC_SEL_CAR__A                                         0x1C10032
-#define   EQ_REG_RC_SEL_CAR_INIT                                     0x0
-#define     EQ_REG_RC_SEL_CAR_DIV_ON                                 0x1
-#define     EQ_REG_RC_SEL_CAR_PASS_A_CC                              0x0
-#define     EQ_REG_RC_SEL_CAR_PASS_B_CE                              0x2
-#define     EQ_REG_RC_SEL_CAR_LOCAL_A_CC                             0x0
-#define     EQ_REG_RC_SEL_CAR_LOCAL_B_CE                             0x8
-#define     EQ_REG_RC_SEL_CAR_MEAS_A_CC                              0x0
-#define     EQ_REG_RC_SEL_CAR_MEAS_B_CE                              0x20
-#define EQ_REG_OT_CONST__A                                           0x1C10046
-#define EQ_REG_OT_ALPHA__A                                           0x1C10047
-#define EQ_REG_OT_QNT_THRES0__A                                      0x1C10048
-#define EQ_REG_OT_QNT_THRES1__A                                      0x1C10049
-#define EQ_REG_OT_CSI_STEP__A                                        0x1C1004A
-#define EQ_REG_OT_CSI_OFFSET__A                                      0x1C1004B
-#define EQ_REG_TD_REQ_SMB_CNT__A                                     0x1C10061
-#define EQ_REG_TD_TPS_PWR_OFS__A                                     0x1C10062
-#define EC_SB_REG_COMM_EXEC__A                                       0x2010000
-#define EC_SB_REG_TR_MODE__A                                         0x2010010
-#define   EC_SB_REG_TR_MODE_8K                                       0x0
-#define   EC_SB_REG_TR_MODE_2K                                       0x1
-#define EC_SB_REG_CONST__A                                           0x2010011
-#define   EC_SB_REG_CONST_QPSK                                       0x0
-#define   EC_SB_REG_CONST_16QAM                                      0x1
-#define   EC_SB_REG_CONST_64QAM                                      0x2
-#define EC_SB_REG_ALPHA__A                                           0x2010012
-#define EC_SB_REG_PRIOR__A                                           0x2010013
-#define   EC_SB_REG_PRIOR_HI                                         0x0
-#define   EC_SB_REG_PRIOR_LO                                         0x1
-#define EC_SB_REG_CSI_HI__A                                          0x2010014
-#define EC_SB_REG_CSI_LO__A                                          0x2010015
-#define EC_SB_REG_SMB_TGL__A                                         0x2010016
-#define EC_SB_REG_SNR_HI__A                                          0x2010017
-#define EC_SB_REG_SNR_MID__A                                         0x2010018
-#define EC_SB_REG_SNR_LO__A                                          0x2010019
-#define EC_SB_REG_SCALE_MSB__A                                       0x201001A
-#define EC_SB_REG_SCALE_BIT2__A                                      0x201001B
-#define EC_SB_REG_SCALE_LSB__A                                       0x201001C
-#define EC_SB_REG_CSI_OFS__A                                         0x201001D
-#define EC_VD_REG_COMM_EXEC__A                                       0x2090000
-#define EC_VD_REG_FORCE__A                                           0x2090010
-#define EC_VD_REG_SET_CODERATE__A                                    0x2090011
-#define   EC_VD_REG_SET_CODERATE_C1_2                                0x0
-#define   EC_VD_REG_SET_CODERATE_C2_3                                0x1
-#define   EC_VD_REG_SET_CODERATE_C3_4                                0x2
-#define   EC_VD_REG_SET_CODERATE_C5_6                                0x3
-#define   EC_VD_REG_SET_CODERATE_C7_8                                0x4
-#define EC_VD_REG_REQ_SMB_CNT__A                                     0x2090012
-#define EC_VD_REG_RLK_ENA__A                                         0x2090014
-#define EC_OD_REG_COMM_EXEC__A                                       0x2110000
-#define EC_OD_REG_SYNC__A                                            0x2110010
-#define EC_OD_DEINT_RAM__A                                           0x2120000
-#define EC_RS_REG_COMM_EXEC__A                                       0x2130000
-#define EC_RS_REG_REQ_PCK_CNT__A                                     0x2130010
-#define EC_RS_REG_VAL__A                                             0x2130011
-#define   EC_RS_REG_VAL_PCK                                          0x1
-#define EC_RS_EC_RAM__A                                              0x2140000
-#define EC_OC_REG_COMM_EXEC__A                                       0x2150000
-#define     EC_OC_REG_COMM_EXEC_CTL_ACTIVE                           0x1
-#define     EC_OC_REG_COMM_EXEC_CTL_HOLD                             0x2
-#define EC_OC_REG_COMM_INT_STA__A                                    0x2150007
-#define EC_OC_REG_OC_MODE_LOP__A                                     0x2150010
-#define   EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                           0x1
-#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                     0x0
-#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                    0x1
-#define   EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                       0x4
-#define     EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC                 0x0
-#define   EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                       0x80
-#define     EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL                 0x80
-#define EC_OC_REG_OC_MODE_HIP__A                                     0x2150011
-#define     EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR                0x10
-#define   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                       0x200
-#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE                0x0
-#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE                 0x200
-#define EC_OC_REG_OC_MPG_SIO__A                                      0x2150012
-#define EC_OC_REG_OC_MPG_SIO__M                                      0xFFF
-#define EC_OC_REG_OC_MON_SIO__A                                      0x2150013
-#define EC_OC_REG_DTO_INC_LOP__A                                     0x2150014
-#define EC_OC_REG_DTO_INC_HIP__A                                     0x2150015
-#define EC_OC_REG_SNC_ISC_LVL__A                                     0x2150016
-#define   EC_OC_REG_SNC_ISC_LVL_OSC__M                               0xF0
-#define EC_OC_REG_TMD_TOP_MODE__A                                    0x215001D
-#define EC_OC_REG_TMD_TOP_CNT__A                                     0x215001E
-#define EC_OC_REG_TMD_HIL_MAR__A                                     0x215001F
-#define EC_OC_REG_TMD_LOL_MAR__A                                     0x2150020
-#define EC_OC_REG_TMD_CUR_CNT__A                                     0x2150021
-#define EC_OC_REG_AVR_ASH_CNT__A                                     0x2150023
-#define EC_OC_REG_AVR_BSH_CNT__A                                     0x2150024
-#define EC_OC_REG_RCN_MODE__A                                        0x2150027
-#define EC_OC_REG_RCN_CRA_LOP__A                                     0x2150028
-#define EC_OC_REG_RCN_CRA_HIP__A                                     0x2150029
-#define EC_OC_REG_RCN_CST_LOP__A                                     0x215002A
-#define EC_OC_REG_RCN_CST_HIP__A                                     0x215002B
-#define EC_OC_REG_RCN_SET_LVL__A                                     0x215002C
-#define EC_OC_REG_RCN_GAI_LVL__A                                     0x215002D
-#define EC_OC_REG_RCN_CLP_LOP__A                                     0x2150032
-#define EC_OC_REG_RCN_CLP_HIP__A                                     0x2150033
-#define EC_OC_REG_RCN_MAP_LOP__A                                     0x2150034
-#define EC_OC_REG_RCN_MAP_HIP__A                                     0x2150035
-#define EC_OC_REG_OCR_MPG_UOS__A                                     0x2150036
-#define EC_OC_REG_OCR_MPG_UOS__M                                     0xFFF
-#define   EC_OC_REG_OCR_MPG_UOS_INIT                                 0x0
-#define EC_OC_REG_OCR_MPG_USR_DAT__A                                 0x2150038
-#define EC_OC_REG_OCR_MON_UOS__A                                     0x2150039
-#define     EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE                       0x1
-#define     EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE                       0x2
-#define     EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE                       0x4
-#define     EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE                       0x8
-#define     EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE                       0x10
-#define     EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE                       0x20
-#define     EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE                       0x40
-#define     EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE                       0x80
-#define     EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE                       0x100
-#define     EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE                       0x200
-#define     EC_OC_REG_OCR_MON_UOS_VAL_ENABLE                         0x400
-#define     EC_OC_REG_OCR_MON_UOS_CLK_ENABLE                         0x800
-#define EC_OC_REG_OCR_MON_WRI__A                                     0x215003A
-#define   EC_OC_REG_OCR_MON_WRI_INIT                                 0x0
-#define EC_OC_REG_IPR_INV_MPG__A                                     0x2150045
-#define CC_REG_OSC_MODE__A                                           0x2410010
-#define   CC_REG_OSC_MODE_M20                                        0x1
-#define CC_REG_PLL_MODE__A                                           0x2410011
-#define     CC_REG_PLL_MODE_BYPASS_PLL                               0x1
-#define     CC_REG_PLL_MODE_PUMP_CUR_12                              0x14
-#define CC_REG_REF_DIVIDE__A                                         0x2410012
-#define CC_REG_PWD_MODE__A                                           0x2410015
-#define   CC_REG_PWD_MODE_DOWN_PLL                                   0x2
-#define CC_REG_UPDATE__A                                             0x2410017
-#define   CC_REG_UPDATE_KEY                                          0x3973
-#define CC_REG_JTAGID_L__A                                           0x2410019
-#define LC_COMM_EXEC__A                                              0x2800000
-#define LC_RA_RAM_IFINCR_NOM_L__A                                    0x282000C
-#define LC_RA_RAM_FILTER_SYM_SET__A                                  0x282001A
-#define LC_RA_RAM_FILTER_SYM_SET__PRE                                0x3E8
-#define LC_RA_RAM_FILTER_CRMM_A__A                                   0x2820060
-#define LC_RA_RAM_FILTER_CRMM_A__PRE                                 0x4
-#define LC_RA_RAM_FILTER_CRMM_B__A                                   0x2820061
-#define LC_RA_RAM_FILTER_CRMM_B__PRE                                 0x1
-#define LC_RA_RAM_FILTER_SRMM_A__A                                   0x2820068
-#define LC_RA_RAM_FILTER_SRMM_A__PRE                                 0x4
-#define LC_RA_RAM_FILTER_SRMM_B__A                                   0x2820069
-#define LC_RA_RAM_FILTER_SRMM_B__PRE                                 0x1
-#define B_HI_COMM_EXEC__A                                            0x400000
-#define B_HI_COMM_MB__A                                              0x400002
-#define B_HI_CT_REG_COMM_STATE__A                                    0x410001
-#define B_HI_RA_RAM_SRV_RES__A                                       0x420031
-#define B_HI_RA_RAM_SRV_CMD__A                                       0x420032
-#define   B_HI_RA_RAM_SRV_CMD_RESET                                  0x2
-#define   B_HI_RA_RAM_SRV_CMD_CONFIG                                 0x3
-#define   B_HI_RA_RAM_SRV_CMD_EXECUTE                                0x6
-#define B_HI_RA_RAM_SRV_RST_KEY__A                                   0x420033
-#define   B_HI_RA_RAM_SRV_RST_KEY_ACT                                0x3973
-#define B_HI_RA_RAM_SRV_CFG_KEY__A                                   0x420033
-#define B_HI_RA_RAM_SRV_CFG_DIV__A                                   0x420034
-#define B_HI_RA_RAM_SRV_CFG_BDL__A                                   0x420035
-#define B_HI_RA_RAM_SRV_CFG_WUP__A                                   0x420036
-#define B_HI_RA_RAM_SRV_CFG_ACT__A                                   0x420037
-#define     B_HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                          0x1
-#define   B_HI_RA_RAM_SRV_CFG_ACT_BRD__M                             0x4
-#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                          0x0
-#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_ON                           0x4
-#define     B_HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                          0x8
-#define B_HI_RA_RAM_USR_BEGIN__A                                     0x420040
-#define B_HI_IF_RAM_TRP_BPT0__AX                                     0x430000
-#define B_HI_IF_RAM_USR_BEGIN__A                                     0x430200
-#define B_SC_COMM_EXEC__A                                            0x800000
-#define     B_SC_COMM_EXEC_CTL_STOP                                  0x0
-#define B_SC_COMM_STATE__A                                           0x800001
-#define B_SC_RA_RAM_PARAM0__A                                        0x820040
-#define B_SC_RA_RAM_PARAM1__A                                        0x820041
-#define B_SC_RA_RAM_CMD_ADDR__A                                      0x820042
-#define B_SC_RA_RAM_CMD__A                                           0x820043
-#define   B_SC_RA_RAM_CMD_PROC_START                                 0x1
-#define   B_SC_RA_RAM_CMD_SET_PREF_PARAM                             0x3
-#define   B_SC_RA_RAM_CMD_GET_OP_PARAM                               0x5
-#define   B_SC_RA_RAM_SW_EVENT_RUN_NMASK__M                          0x1
-#define   B_SC_RA_RAM_LOCKTRACK_MIN                                  0x1
-#define     B_SC_RA_RAM_OP_PARAM_MODE_2K                             0x0
-#define     B_SC_RA_RAM_OP_PARAM_MODE_8K                             0x1
-#define     B_SC_RA_RAM_OP_PARAM_GUARD_32                            0x0
-#define     B_SC_RA_RAM_OP_PARAM_GUARD_16                            0x4
-#define     B_SC_RA_RAM_OP_PARAM_GUARD_8                             0x8
-#define     B_SC_RA_RAM_OP_PARAM_GUARD_4                             0xC
-#define     B_SC_RA_RAM_OP_PARAM_CONST_QPSK                          0x0
-#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM16                         0x10
-#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM64                         0x20
-#define     B_SC_RA_RAM_OP_PARAM_HIER_NO                             0x0
-#define     B_SC_RA_RAM_OP_PARAM_HIER_A1                             0x40
-#define     B_SC_RA_RAM_OP_PARAM_HIER_A2                             0x80
-#define     B_SC_RA_RAM_OP_PARAM_HIER_A4                             0xC0
-#define     B_SC_RA_RAM_OP_PARAM_RATE_1_2                            0x0
-#define     B_SC_RA_RAM_OP_PARAM_RATE_2_3                            0x200
-#define     B_SC_RA_RAM_OP_PARAM_RATE_3_4                            0x400
-#define     B_SC_RA_RAM_OP_PARAM_RATE_5_6                            0x600
-#define     B_SC_RA_RAM_OP_PARAM_RATE_7_8                            0x800
-#define     B_SC_RA_RAM_OP_PARAM_PRIO_HI                             0x0
-#define     B_SC_RA_RAM_OP_PARAM_PRIO_LO                             0x1000
-#define   B_SC_RA_RAM_OP_AUTO_MODE__M                                0x1
-#define   B_SC_RA_RAM_OP_AUTO_GUARD__M                               0x2
-#define   B_SC_RA_RAM_OP_AUTO_CONST__M                               0x4
-#define   B_SC_RA_RAM_OP_AUTO_HIER__M                                0x8
-#define   B_SC_RA_RAM_OP_AUTO_RATE__M                                0x10
-#define B_SC_RA_RAM_LOCK__A                                          0x82004B
-#define   B_SC_RA_RAM_LOCK_DEMOD__M                                  0x1
-#define   B_SC_RA_RAM_LOCK_FEC__M                                    0x2
-#define   B_SC_RA_RAM_LOCK_MPEG__M                                   0x4
-#define B_SC_RA_RAM_BE_OPT_ENA__A                                    0x82004C
-#define   B_SC_RA_RAM_BE_OPT_ENA_CP_OPT                              0x1
-#define B_SC_RA_RAM_BE_OPT_DELAY__A                                  0x82004D
-#define B_SC_RA_RAM_CONFIG__A                                        0x820050
-#define   B_SC_RA_RAM_CONFIG_FR_ENABLE__M                            0x4
-#define   B_SC_RA_RAM_CONFIG_FREQSCAN__M                             0x10
-#define   B_SC_RA_RAM_CONFIG_SLAVE__M                                0x20
-#define   B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M                     0x200
-#define   B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M                      0x400
-#define B_SC_RA_RAM_CO_TD_CAL_2K__A                                  0x82005D
-#define B_SC_RA_RAM_CO_TD_CAL_8K__A                                  0x82005E
-#define B_SC_RA_RAM_IF_SAVE__AX                                      0x82008E
-#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A                         0x820098
-#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A                         0x820099
-#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A                          0x82009A
-#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A                          0x82009B
-#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A                         0x82009C
-#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A                         0x82009D
-#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A                          0x82009E
-#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A                          0x82009F
-#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A                           0x8200D1
-#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                         0x9
-#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A                          0x8200D2
-#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                        0x4
-#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A                          0x8200D3
-#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                        0x100
-#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A                           0x8200D4
-#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                         0x8
-#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A                          0x8200D5
-#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                        0x8
-#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A                          0x8200D6
-#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                        0x200
-#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__A                             0x8200D7
-#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                           0x9
-#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__A                            0x8200D8
-#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                          0x4
-#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__A                            0x8200D9
-#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                          0x100
-#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__A                             0x8200DA
-#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                           0xB
-#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__A                            0x8200DB
-#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                          0x1
-#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__A                            0x8200DC
-#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                          0x40
-#define B_SC_RA_RAM_ECHO_SHIFT_LIM__A                                0x8200DD
-#define B_SC_RA_RAM_SAMPLE_RATE_COUNT__A                             0x8200E8
-#define B_SC_RA_RAM_SAMPLE_RATE_STEP__A                              0x8200E9
-#define B_SC_RA_RAM_BAND__A                                          0x8200EC
-#define B_SC_RA_RAM_LC_ABS_2K__A                                     0x8200F4
-#define B_SC_RA_RAM_LC_ABS_2K__PRE                                   0x1F
-#define B_SC_RA_RAM_LC_ABS_8K__A                                     0x8200F5
-#define B_SC_RA_RAM_LC_ABS_8K__PRE                                   0x1F
-#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                      0x100
-#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                      0x4
-#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                         0x1E2
-#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                         0x4
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                        0x10D
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                        0x5
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                     0x17D
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                     0x4
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                     0x133
-#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                     0x5
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                        0x114
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                        0x5
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                     0x14A
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                     0x4
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                     0x1BB
-#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                     0x4
-#define B_SC_RA_RAM_DRIVER_VERSION__AX                               0x8201FE
-#define   B_SC_RA_RAM_PROC_LOCKTRACK                                 0x0
-#define B_FE_COMM_EXEC__A                                            0xC00000
-#define B_FE_AD_REG_COMM_EXEC__A                                     0xC10000
-#define B_FE_AD_REG_FDB_IN__A                                        0xC10012
-#define B_FE_AD_REG_PD__A                                            0xC10013
-#define B_FE_AD_REG_INVEXT__A                                        0xC10014
-#define B_FE_AD_REG_CLKNEG__A                                        0xC10015
-#define B_FE_AG_REG_COMM_EXEC__A                                     0xC20000
-#define B_FE_AG_REG_AG_MODE_LOP__A                                   0xC20010
-#define   B_FE_AG_REG_AG_MODE_LOP_MODE_4__M                          0x10
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                    0x0
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                   0x10
-#define   B_FE_AG_REG_AG_MODE_LOP_MODE_5__M                          0x20
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                    0x0
-#define   B_FE_AG_REG_AG_MODE_LOP_MODE_C__M                          0x1000
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                    0x0
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                   0x1000
-#define   B_FE_AG_REG_AG_MODE_LOP_MODE_E__M                          0x4000
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                    0x0
-#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                   0x4000
-#define B_FE_AG_REG_AG_MODE_HIP__A                                   0xC20011
-#define   B_FE_AG_REG_AG_MODE_HIP_MODE_J__M                          0x8
-#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC                    0x0
-#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC                   0x8
-#define B_FE_AG_REG_AG_PGA_MODE__A                                   0xC20012
-#define   B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                    0x0
-#define   B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                    0x1
-#define B_FE_AG_REG_AG_AGC_SIO__A                                    0xC20013
-#define   B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                        0x2
-#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                  0x0
-#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                   0x2
-#define B_FE_AG_REG_AG_PWD__A                                        0xC20015
-#define   B_FE_AG_REG_AG_PWD_PWD_PD2__M                              0x2
-#define     B_FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                       0x0
-#define     B_FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                        0x2
-#define B_FE_AG_REG_DCE_AUR_CNT__A                                   0xC20016
-#define B_FE_AG_REG_DCE_RUR_CNT__A                                   0xC20017
-#define B_FE_AG_REG_ACE_AUR_CNT__A                                   0xC2001A
-#define B_FE_AG_REG_ACE_RUR_CNT__A                                   0xC2001B
-#define B_FE_AG_REG_CDR_RUR_CNT__A                                   0xC20020
-#define B_FE_AG_REG_EGC_RUR_CNT__A                                   0xC20024
-#define B_FE_AG_REG_EGC_SET_LVL__A                                   0xC20025
-#define B_FE_AG_REG_EGC_SET_LVL__M                                   0x1FF
-#define B_FE_AG_REG_EGC_FLA_RGN__A                                   0xC20026
-#define B_FE_AG_REG_EGC_SLO_RGN__A                                   0xC20027
-#define B_FE_AG_REG_EGC_JMP_PSN__A                                   0xC20028
-#define B_FE_AG_REG_EGC_FLA_INC__A                                   0xC20029
-#define B_FE_AG_REG_EGC_FLA_DEC__A                                   0xC2002A
-#define B_FE_AG_REG_EGC_SLO_INC__A                                   0xC2002B
-#define B_FE_AG_REG_EGC_SLO_DEC__A                                   0xC2002C
-#define B_FE_AG_REG_EGC_FAS_INC__A                                   0xC2002D
-#define B_FE_AG_REG_EGC_FAS_DEC__A                                   0xC2002E
-#define B_FE_AG_REG_PM1_AGC_WRI__A                                   0xC20030
-#define B_FE_AG_REG_PM1_AGC_WRI__M                                   0x7FF
-#define B_FE_AG_REG_GC1_AGC_RIC__A                                   0xC20031
-#define B_FE_AG_REG_GC1_AGC_OFF__A                                   0xC20032
-#define B_FE_AG_REG_GC1_AGC_MAX__A                                   0xC20033
-#define B_FE_AG_REG_GC1_AGC_MIN__A                                   0xC20034
-#define B_FE_AG_REG_GC1_AGC_DAT__A                                   0xC20035
-#define B_FE_AG_REG_GC1_AGC_DAT__M                                   0x3FF
-#define B_FE_AG_REG_PM2_AGC_WRI__A                                   0xC20036
-#define B_FE_AG_REG_IND_WIN__A                                       0xC2003C
-#define B_FE_AG_REG_IND_THD_LOL__A                                   0xC2003D
-#define B_FE_AG_REG_IND_THD_HIL__A                                   0xC2003E
-#define B_FE_AG_REG_IND_DEL__A                                       0xC2003F
-#define B_FE_AG_REG_IND_PD1_WRI__A                                   0xC20040
-#define B_FE_AG_REG_PDA_AUR_CNT__A                                   0xC20041
-#define B_FE_AG_REG_PDA_RUR_CNT__A                                   0xC20042
-#define B_FE_AG_REG_PDA_AVE_DAT__A                                   0xC20043
-#define B_FE_AG_REG_PDC_RUR_CNT__A                                   0xC20044
-#define B_FE_AG_REG_PDC_SET_LVL__A                                   0xC20045
-#define B_FE_AG_REG_PDC_FLA_RGN__A                                   0xC20046
-#define B_FE_AG_REG_PDC_JMP_PSN__A                                   0xC20047
-#define B_FE_AG_REG_PDC_FLA_STP__A                                   0xC20048
-#define B_FE_AG_REG_PDC_SLO_STP__A                                   0xC20049
-#define B_FE_AG_REG_PDC_PD2_WRI__A                                   0xC2004A
-#define B_FE_AG_REG_PDC_MAP_DAT__A                                   0xC2004B
-#define B_FE_AG_REG_PDC_MAX__A                                       0xC2004C
-#define B_FE_AG_REG_TGA_AUR_CNT__A                                   0xC2004D
-#define B_FE_AG_REG_TGA_RUR_CNT__A                                   0xC2004E
-#define B_FE_AG_REG_TGA_AVE_DAT__A                                   0xC2004F
-#define B_FE_AG_REG_TGC_RUR_CNT__A                                   0xC20050
-#define B_FE_AG_REG_TGC_SET_LVL__A                                   0xC20051
-#define B_FE_AG_REG_TGC_SET_LVL__M                                   0x3F
-#define B_FE_AG_REG_TGC_FLA_RGN__A                                   0xC20052
-#define B_FE_AG_REG_TGC_JMP_PSN__A                                   0xC20053
-#define B_FE_AG_REG_TGC_FLA_STP__A                                   0xC20054
-#define B_FE_AG_REG_TGC_SLO_STP__A                                   0xC20055
-#define B_FE_AG_REG_TGC_MAP_DAT__A                                   0xC20056
-#define B_FE_AG_REG_FGM_WRI__A                                       0xC20061
-#define B_FE_AG_REG_BGC_FGC_WRI__A                                   0xC20068
-#define B_FE_AG_REG_BGC_CGC_WRI__A                                   0xC20069
-#define B_FE_FS_REG_COMM_EXEC__A                                     0xC30000
-#define B_FE_FS_REG_ADD_INC_LOP__A                                   0xC30010
-#define B_FE_FD_REG_COMM_EXEC__A                                     0xC40000
-#define B_FE_FD_REG_SCL__A                                           0xC40010
-#define B_FE_FD_REG_MAX_LEV__A                                       0xC40011
-#define B_FE_FD_REG_NR__A                                            0xC40012
-#define B_FE_FD_REG_MEAS_VAL__A                                      0xC40014
-#define B_FE_IF_REG_COMM_EXEC__A                                     0xC50000
-#define B_FE_IF_REG_INCR0__A                                         0xC50010
-#define B_FE_IF_REG_INCR0__W                                         16
-#define B_FE_IF_REG_INCR0__M                                         0xFFFF
-#define B_FE_IF_REG_INCR1__A                                         0xC50011
-#define B_FE_IF_REG_INCR1__M                                         0xFF
-#define B_FE_CF_REG_COMM_EXEC__A                                     0xC60000
-#define B_FE_CF_REG_SCL__A                                           0xC60010
-#define B_FE_CF_REG_MAX_LEV__A                                       0xC60011
-#define B_FE_CF_REG_NR__A                                            0xC60012
-#define B_FE_CF_REG_IMP_VAL__A                                       0xC60013
-#define B_FE_CF_REG_MEAS_VAL__A                                      0xC60014
-#define B_FE_CU_REG_COMM_EXEC__A                                     0xC70000
-#define B_FE_CU_REG_FRM_CNT_RST__A                                   0xC70011
-#define B_FE_CU_REG_FRM_CNT_STR__A                                   0xC70012
-#define B_FE_CU_REG_CTR_NFC_ICR__A                                   0xC70020
-#define B_FE_CU_REG_CTR_NFC_OCR__A                                   0xC70021
-#define B_FE_CU_REG_DIV_NFC_CLP__A                                   0xC70027
-#define B_FT_COMM_EXEC__A                                            0x1000000
-#define B_FT_REG_COMM_EXEC__A                                        0x1010000
-#define B_CP_COMM_EXEC__A                                            0x1400000
-#define B_CP_REG_COMM_EXEC__A                                        0x1410000
-#define B_CP_REG_INTERVAL__A                                         0x1410011
-#define B_CP_REG_BR_SPL_OFFSET__A                                    0x1410023
-#define B_CP_REG_BR_STR_DEL__A                                       0x1410024
-#define B_CP_REG_RT_ANG_INC0__A                                      0x1410030
-#define B_CP_REG_RT_ANG_INC1__A                                      0x1410031
-#define B_CP_REG_RT_DETECT_TRH__A                                    0x1410033
-#define B_CP_REG_AC_NEXP_OFFS__A                                     0x1410040
-#define B_CP_REG_AC_AVER_POW__A                                      0x1410041
-#define B_CP_REG_AC_MAX_POW__A                                       0x1410042
-#define B_CP_REG_AC_WEIGHT_MAN__A                                    0x1410043
-#define B_CP_REG_AC_WEIGHT_EXP__A                                    0x1410044
-#define B_CP_REG_AC_AMP_MODE__A                                      0x1410047
-#define B_CP_REG_AC_AMP_FIX__A                                       0x1410048
-#define B_CP_REG_AC_ANG_MODE__A                                      0x141004A
-#define B_CE_COMM_EXEC__A                                            0x1800000
-#define B_CE_REG_COMM_EXEC__A                                        0x1810000
-#define B_CE_REG_TAPSET__A                                           0x1810011
-#define B_CE_REG_AVG_POW__A                                          0x1810012
-#define B_CE_REG_MAX_POW__A                                          0x1810013
-#define B_CE_REG_ATT__A                                              0x1810014
-#define B_CE_REG_NRED__A                                             0x1810015
-#define B_CE_REG_NE_ERR_SELECT__A                                    0x1810043
-#define B_CE_REG_NE_TD_CAL__A                                        0x1810044
-#define B_CE_REG_NE_MIXAVG__A                                        0x1810046
-#define B_CE_REG_NE_NUPD_OFS__A                                      0x1810047
-#define B_CE_REG_PE_NEXP_OFFS__A                                     0x1810050
-#define B_CE_REG_PE_TIMESHIFT__A                                     0x1810051
-#define B_CE_REG_TP_A0_TAP_NEW__A                                    0x1810064
-#define B_CE_REG_TP_A0_TAP_NEW_VALID__A                              0x1810065
-#define B_CE_REG_TP_A0_MU_LMS_STEP__A                                0x1810066
-#define B_CE_REG_TP_A1_TAP_NEW__A                                    0x1810068
-#define B_CE_REG_TP_A1_TAP_NEW_VALID__A                              0x1810069
-#define B_CE_REG_TP_A1_MU_LMS_STEP__A                                0x181006A
-#define B_CE_REG_TI_PHN_ENABLE__A                                    0x1810073
-#define B_CE_REG_FI_SHT_INCR__A                                      0x1810090
-#define B_CE_REG_FI_EXP_NORM__A                                      0x1810091
-#define B_CE_REG_IR_INPUTSEL__A                                      0x18100A0
-#define B_CE_REG_IR_STARTPOS__A                                      0x18100A1
-#define B_CE_REG_IR_NEXP_THRES__A                                    0x18100A2
-#define B_CE_REG_FR_TREAL00__A                                       0x1820010
-#define B_CE_REG_FR_TIMAG00__A                                       0x1820011
-#define B_CE_REG_FR_TREAL01__A                                       0x1820012
-#define B_CE_REG_FR_TIMAG01__A                                       0x1820013
-#define B_CE_REG_FR_TREAL02__A                                       0x1820014
-#define B_CE_REG_FR_TIMAG02__A                                       0x1820015
-#define B_CE_REG_FR_TREAL03__A                                       0x1820016
-#define B_CE_REG_FR_TIMAG03__A                                       0x1820017
-#define B_CE_REG_FR_TREAL04__A                                       0x1820018
-#define B_CE_REG_FR_TIMAG04__A                                       0x1820019
-#define B_CE_REG_FR_TREAL05__A                                       0x182001A
-#define B_CE_REG_FR_TIMAG05__A                                       0x182001B
-#define B_CE_REG_FR_TREAL06__A                                       0x182001C
-#define B_CE_REG_FR_TIMAG06__A                                       0x182001D
-#define B_CE_REG_FR_TREAL07__A                                       0x182001E
-#define B_CE_REG_FR_TIMAG07__A                                       0x182001F
-#define B_CE_REG_FR_TREAL08__A                                       0x1820020
-#define B_CE_REG_FR_TIMAG08__A                                       0x1820021
-#define B_CE_REG_FR_TREAL09__A                                       0x1820022
-#define B_CE_REG_FR_TIMAG09__A                                       0x1820023
-#define B_CE_REG_FR_TREAL10__A                                       0x1820024
-#define B_CE_REG_FR_TIMAG10__A                                       0x1820025
-#define B_CE_REG_FR_TREAL11__A                                       0x1820026
-#define B_CE_REG_FR_TIMAG11__A                                       0x1820027
-#define B_CE_REG_FR_MID_TAP__A                                       0x1820028
-#define B_CE_REG_FR_SQS_G00__A                                       0x1820029
-#define B_CE_REG_FR_SQS_G01__A                                       0x182002A
-#define B_CE_REG_FR_SQS_G02__A                                       0x182002B
-#define B_CE_REG_FR_SQS_G03__A                                       0x182002C
-#define B_CE_REG_FR_SQS_G04__A                                       0x182002D
-#define B_CE_REG_FR_SQS_G05__A                                       0x182002E
-#define B_CE_REG_FR_SQS_G06__A                                       0x182002F
-#define B_CE_REG_FR_SQS_G07__A                                       0x1820030
-#define B_CE_REG_FR_SQS_G08__A                                       0x1820031
-#define B_CE_REG_FR_SQS_G09__A                                       0x1820032
-#define B_CE_REG_FR_SQS_G10__A                                       0x1820033
-#define B_CE_REG_FR_SQS_G11__A                                       0x1820034
-#define B_CE_REG_FR_SQS_G12__A                                       0x1820035
-#define B_CE_REG_FR_RIO_G00__A                                       0x1820036
-#define B_CE_REG_FR_RIO_G01__A                                       0x1820037
-#define B_CE_REG_FR_RIO_G02__A                                       0x1820038
-#define B_CE_REG_FR_RIO_G03__A                                       0x1820039
-#define B_CE_REG_FR_RIO_G04__A                                       0x182003A
-#define B_CE_REG_FR_RIO_G05__A                                       0x182003B
-#define B_CE_REG_FR_RIO_G06__A                                       0x182003C
-#define B_CE_REG_FR_RIO_G07__A                                       0x182003D
-#define B_CE_REG_FR_RIO_G08__A                                       0x182003E
-#define B_CE_REG_FR_RIO_G09__A                                       0x182003F
-#define B_CE_REG_FR_RIO_G10__A                                       0x1820040
-#define B_CE_REG_FR_MODE__A                                          0x1820041
-#define B_CE_REG_FR_SQS_TRH__A                                       0x1820042
-#define B_CE_REG_FR_RIO_GAIN__A                                      0x1820043
-#define B_CE_REG_FR_BYPASS__A                                        0x1820044
-#define B_CE_REG_FR_PM_SET__A                                        0x1820045
-#define B_CE_REG_FR_ERR_SH__A                                        0x1820046
-#define B_CE_REG_FR_MAN_SH__A                                        0x1820047
-#define B_CE_REG_FR_TAP_SH__A                                        0x1820048
-#define B_EQ_COMM_EXEC__A                                            0x1C00000
-#define B_EQ_REG_COMM_EXEC__A                                        0x1C10000
-#define B_EQ_REG_COMM_MB__A                                          0x1C10002
-#define B_EQ_REG_IS_GAIN_MAN__A                                      0x1C10015
-#define B_EQ_REG_IS_GAIN_EXP__A                                      0x1C10016
-#define B_EQ_REG_IS_CLIP_EXP__A                                      0x1C10017
-#define B_EQ_REG_SN_CEGAIN__A                                        0x1C1002A
-#define B_EQ_REG_SN_OFFSET__A                                        0x1C1002B
-#define B_EQ_REG_RC_SEL_CAR__A                                       0x1C10032
-#define   B_EQ_REG_RC_SEL_CAR_INIT                                   0x2
-#define     B_EQ_REG_RC_SEL_CAR_DIV_ON                               0x1
-#define     B_EQ_REG_RC_SEL_CAR_PASS_A_CC                            0x0
-#define     B_EQ_REG_RC_SEL_CAR_PASS_B_CE                            0x2
-#define     B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC                           0x0
-#define     B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE                           0x8
-#define     B_EQ_REG_RC_SEL_CAR_MEAS_A_CC                            0x0
-#define     B_EQ_REG_RC_SEL_CAR_MEAS_B_CE                            0x20
-#define   B_EQ_REG_RC_SEL_CAR_FFTMODE__M                             0x80
-#define B_EQ_REG_OT_CONST__A                                         0x1C10046
-#define B_EQ_REG_OT_ALPHA__A                                         0x1C10047
-#define B_EQ_REG_OT_QNT_THRES0__A                                    0x1C10048
-#define B_EQ_REG_OT_QNT_THRES1__A                                    0x1C10049
-#define B_EQ_REG_OT_CSI_STEP__A                                      0x1C1004A
-#define B_EQ_REG_OT_CSI_OFFSET__A                                    0x1C1004B
-#define B_EQ_REG_TD_REQ_SMB_CNT__A                                   0x1C10061
-#define B_EQ_REG_TD_TPS_PWR_OFS__A                                   0x1C10062
-#define B_EC_SB_REG_COMM_EXEC__A                                     0x2010000
-#define B_EC_SB_REG_TR_MODE__A                                       0x2010010
-#define   B_EC_SB_REG_TR_MODE_8K                                     0x0
-#define   B_EC_SB_REG_TR_MODE_2K                                     0x1
-#define B_EC_SB_REG_CONST__A                                         0x2010011
-#define   B_EC_SB_REG_CONST_QPSK                                     0x0
-#define   B_EC_SB_REG_CONST_16QAM                                    0x1
-#define   B_EC_SB_REG_CONST_64QAM                                    0x2
-#define B_EC_SB_REG_ALPHA__A                                         0x2010012
-#define B_EC_SB_REG_PRIOR__A                                         0x2010013
-#define   B_EC_SB_REG_PRIOR_HI                                       0x0
-#define   B_EC_SB_REG_PRIOR_LO                                       0x1
-#define B_EC_SB_REG_CSI_HI__A                                        0x2010014
-#define B_EC_SB_REG_CSI_LO__A                                        0x2010015
-#define B_EC_SB_REG_SMB_TGL__A                                       0x2010016
-#define B_EC_SB_REG_SNR_HI__A                                        0x2010017
-#define B_EC_SB_REG_SNR_MID__A                                       0x2010018
-#define B_EC_SB_REG_SNR_LO__A                                        0x2010019
-#define B_EC_SB_REG_SCALE_MSB__A                                     0x201001A
-#define B_EC_SB_REG_SCALE_BIT2__A                                    0x201001B
-#define B_EC_SB_REG_SCALE_LSB__A                                     0x201001C
-#define B_EC_SB_REG_CSI_OFS0__A                                      0x201001D
-#define B_EC_SB_REG_CSI_OFS1__A                                      0x201001E
-#define B_EC_SB_REG_CSI_OFS2__A                                      0x201001F
-#define B_EC_VD_REG_COMM_EXEC__A                                     0x2090000
-#define B_EC_VD_REG_FORCE__A                                         0x2090010
-#define B_EC_VD_REG_SET_CODERATE__A                                  0x2090011
-#define   B_EC_VD_REG_SET_CODERATE_C1_2                              0x0
-#define   B_EC_VD_REG_SET_CODERATE_C2_3                              0x1
-#define   B_EC_VD_REG_SET_CODERATE_C3_4                              0x2
-#define   B_EC_VD_REG_SET_CODERATE_C5_6                              0x3
-#define   B_EC_VD_REG_SET_CODERATE_C7_8                              0x4
-#define B_EC_VD_REG_REQ_SMB_CNT__A                                   0x2090012
-#define B_EC_VD_REG_RLK_ENA__A                                       0x2090014
-#define B_EC_OD_REG_COMM_EXEC__A                                     0x2110000
-#define B_EC_OD_REG_SYNC__A                                          0x2110664
-#define B_EC_OD_DEINT_RAM__A                                         0x2120000
-#define B_EC_RS_REG_COMM_EXEC__A                                     0x2130000
-#define B_EC_RS_REG_REQ_PCK_CNT__A                                   0x2130010
-#define B_EC_RS_REG_VAL__A                                           0x2130011
-#define   B_EC_RS_REG_VAL_PCK                                        0x1
-#define B_EC_RS_EC_RAM__A                                            0x2140000
-#define B_EC_OC_REG_COMM_EXEC__A                                     0x2150000
-#define     B_EC_OC_REG_COMM_EXEC_CTL_ACTIVE                         0x1
-#define     B_EC_OC_REG_COMM_EXEC_CTL_HOLD                           0x2
-#define B_EC_OC_REG_COMM_INT_STA__A                                  0x2150007
-#define B_EC_OC_REG_OC_MODE_LOP__A                                   0x2150010
-#define   B_EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                         0x1
-#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                   0x0
-#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                  0x1
-#define   B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                     0x4
-#define     B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC               0x0
-#define   B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                     0x80
-#define     B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL               0x80
-#define B_EC_OC_REG_OC_MODE_HIP__A                                   0x2150011
-#define     B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR              0x10
-#define   B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                     0x200
-#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE              0x0
-#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE               0x200
-#define B_EC_OC_REG_OC_MPG_SIO__A                                    0x2150012
-#define B_EC_OC_REG_OC_MPG_SIO__M                                    0xFFF
-#define B_EC_OC_REG_DTO_INC_LOP__A                                   0x2150014
-#define B_EC_OC_REG_DTO_INC_HIP__A                                   0x2150015
-#define B_EC_OC_REG_SNC_ISC_LVL__A                                   0x2150016
-#define   B_EC_OC_REG_SNC_ISC_LVL_OSC__M                             0xF0
-#define B_EC_OC_REG_TMD_TOP_MODE__A                                  0x215001D
-#define B_EC_OC_REG_TMD_TOP_CNT__A                                   0x215001E
-#define B_EC_OC_REG_TMD_HIL_MAR__A                                   0x215001F
-#define B_EC_OC_REG_TMD_LOL_MAR__A                                   0x2150020
-#define B_EC_OC_REG_TMD_CUR_CNT__A                                   0x2150021
-#define B_EC_OC_REG_AVR_ASH_CNT__A                                   0x2150023
-#define B_EC_OC_REG_AVR_BSH_CNT__A                                   0x2150024
-#define B_EC_OC_REG_RCN_MODE__A                                      0x2150027
-#define B_EC_OC_REG_RCN_CRA_LOP__A                                   0x2150028
-#define B_EC_OC_REG_RCN_CRA_HIP__A                                   0x2150029
-#define B_EC_OC_REG_RCN_CST_LOP__A                                   0x215002A
-#define B_EC_OC_REG_RCN_CST_HIP__A                                   0x215002B
-#define B_EC_OC_REG_RCN_SET_LVL__A                                   0x215002C
-#define B_EC_OC_REG_RCN_GAI_LVL__A                                   0x215002D
-#define B_EC_OC_REG_RCN_CLP_LOP__A                                   0x2150032
-#define B_EC_OC_REG_RCN_CLP_HIP__A                                   0x2150033
-#define B_EC_OC_REG_RCN_MAP_LOP__A                                   0x2150034
-#define B_EC_OC_REG_RCN_MAP_HIP__A                                   0x2150035
-#define B_EC_OC_REG_OCR_MPG_UOS__A                                   0x2150036
-#define B_EC_OC_REG_OCR_MPG_UOS__M                                   0xFFF
-#define   B_EC_OC_REG_OCR_MPG_UOS_INIT                               0x0
-#define B_EC_OC_REG_OCR_MPG_USR_DAT__A                               0x2150038
-#define B_EC_OC_REG_IPR_INV_MPG__A                                   0x2150045
-#define B_EC_OC_REG_DTO_CLKMODE__A                                   0x2150047
-#define B_EC_OC_REG_DTO_PER__A                                       0x2150048
-#define B_EC_OC_REG_DTO_BUR__A                                       0x2150049
-#define B_EC_OC_REG_RCR_CLKMODE__A                                   0x215004A
-#define B_CC_REG_OSC_MODE__A                                         0x2410010
-#define   B_CC_REG_OSC_MODE_M20                                      0x1
-#define B_CC_REG_PLL_MODE__A                                         0x2410011
-#define     B_CC_REG_PLL_MODE_BYPASS_PLL                             0x1
-#define     B_CC_REG_PLL_MODE_PUMP_CUR_12                            0x14
-#define B_CC_REG_REF_DIVIDE__A                                       0x2410012
-#define B_CC_REG_PWD_MODE__A                                         0x2410015
-#define   B_CC_REG_PWD_MODE_DOWN_PLL                                 0x2
-#define B_CC_REG_UPDATE__A                                           0x2410017
-#define   B_CC_REG_UPDATE_KEY                                        0x3973
-#define B_CC_REG_JTAGID_L__A                                         0x2410019
-#define B_CC_REG_DIVERSITY__A                                        0x241001B
-#define B_LC_COMM_EXEC__A                                            0x2800000
-#define B_LC_RA_RAM_IFINCR_NOM_L__A                                  0x282000C
-#define B_LC_RA_RAM_FILTER_SYM_SET__A                                0x282001A
-#define B_LC_RA_RAM_FILTER_SYM_SET__PRE                              0x3E8
-#define B_LC_RA_RAM_FILTER_CRMM_A__A                                 0x2820060
-#define B_LC_RA_RAM_FILTER_CRMM_A__PRE                               0x4
-#define B_LC_RA_RAM_FILTER_CRMM_B__A                                 0x2820061
-#define B_LC_RA_RAM_FILTER_CRMM_B__PRE                               0x1
-#define B_LC_RA_RAM_FILTER_SRMM_A__A                                 0x2820068
-#define B_LC_RA_RAM_FILTER_SRMM_A__PRE                               0x4
-#define B_LC_RA_RAM_FILTER_SRMM_B__A                                 0x2820069
-#define B_LC_RA_RAM_FILTER_SRMM_B__PRE                               0x1
-
-#endif
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
deleted file mode 100644 (file)
index d615d7d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _DRXK_H_
-#define _DRXK_H_
-
-#include <linux/types.h>
-#include <linux/i2c.h>
-
-/**
- * struct drxk_config - Configure the initial parameters for DRX-K
- *
- * @adr:               I2C Address of the DRX-K
- * @parallel_ts:       True means that the device uses parallel TS,
- *                     Serial otherwise.
- * @dynamic_clk:       True means that the clock will be dynamically
- *                     adjusted. Static clock otherwise.
- * @enable_merr_cfg:   Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
- * @single_master:     Device is on the single master mode
- * @no_i2c_bridge:     Don't switch the I2C bridge to talk with tuner
- * @antenna_gpio:      GPIO bit used to control the antenna
- * @antenna_dvbt:      GPIO bit for changing antenna to DVB-C. A value of 1
- *                     means that 1=DVBC, 0 = DVBT. Zero means the opposite.
- * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
- * @microcode_name:    Name of the firmware file with the microcode
- * @qam_demod_parameter_count: The number of parameters used for the command
- *                             to set the demodulator parameters. All
- *                             firmwares are using the 2-parameter commmand.
- *                             An exception is the "drxk_a3.mc" firmware,
- *                             which uses the 4-parameter command.
- *                             A value of 0 (default) or lower indicates that
- *                             the correct number of parameters will be
- *                             automatically detected.
- *
- * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
- * UIO-3.
- */
-struct drxk_config {
-       u8      adr;
-       bool    single_master;
-       bool    no_i2c_bridge;
-       bool    parallel_ts;
-       bool    dynamic_clk;
-       bool    enable_merr_cfg;
-
-       bool    antenna_dvbt;
-       u16     antenna_gpio;
-
-       u8      mpeg_out_clk_strength;
-       int     chunk_size;
-
-       const char      *microcode_name;
-       int              qam_demod_parameter_count;
-};
-
-#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
-        && defined(MODULE))
-extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
-                                       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
-                                       struct i2c_adapter *i2c)
-{
-        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-        return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
deleted file mode 100644 (file)
index 1ab8154..0000000
+++ /dev/null
@@ -1,6637 +0,0 @@
-/*
- * drxk_hard: DRX-K DVB-C/T demodulator driver
- *
- * Copyright (C) 2010-2011 Digital Devices GmbH
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/i2c.h>
-#include <linux/hardirq.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "drxk.h"
-#include "drxk_hard.h"
-
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
-static int PowerDownQAM(struct drxk_state *state);
-static int SetDVBTStandard(struct drxk_state *state,
-                          enum OperationMode oMode);
-static int SetQAMStandard(struct drxk_state *state,
-                         enum OperationMode oMode);
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-                 s32 tunerFreqOffset);
-static int SetDVBTStandard(struct drxk_state *state,
-                          enum OperationMode oMode);
-static int DVBTStart(struct drxk_state *state);
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-                  s32 tunerFreqOffset);
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int SwitchAntennaToQAM(struct drxk_state *state);
-static int SwitchAntennaToDVBT(struct drxk_state *state);
-
-static bool IsDVBT(struct drxk_state *state)
-{
-       return state->m_OperationMode == OM_DVBT;
-}
-
-static bool IsQAM(struct drxk_state *state)
-{
-       return state->m_OperationMode == OM_QAM_ITU_A ||
-           state->m_OperationMode == OM_QAM_ITU_B ||
-           state->m_OperationMode == OM_QAM_ITU_C;
-}
-
-bool IsA1WithPatchCode(struct drxk_state *state)
-{
-       return state->m_DRXK_A1_PATCH_CODE;
-}
-
-bool IsA1WithRomCode(struct drxk_state *state)
-{
-       return state->m_DRXK_A1_ROM_CODE;
-}
-
-#define NOA1ROM 0
-
-#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
-#define DRXDAP_FASI_LONG_FORMAT(addr)  (((addr) & 0xFC30FF80) != 0)
-
-#define DEFAULT_MER_83  165
-#define DEFAULT_MER_93  250
-
-#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
-#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
-#endif
-
-#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
-#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
-#endif
-
-#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
-#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
-
-#ifndef DRXK_KI_RAGC_ATV
-#define DRXK_KI_RAGC_ATV   4
-#endif
-#ifndef DRXK_KI_IAGC_ATV
-#define DRXK_KI_IAGC_ATV   6
-#endif
-#ifndef DRXK_KI_DAGC_ATV
-#define DRXK_KI_DAGC_ATV   7
-#endif
-
-#ifndef DRXK_KI_RAGC_QAM
-#define DRXK_KI_RAGC_QAM   3
-#endif
-#ifndef DRXK_KI_IAGC_QAM
-#define DRXK_KI_IAGC_QAM   4
-#endif
-#ifndef DRXK_KI_DAGC_QAM
-#define DRXK_KI_DAGC_QAM   7
-#endif
-#ifndef DRXK_KI_RAGC_DVBT
-#define DRXK_KI_RAGC_DVBT  (IsA1WithPatchCode(state) ? 3 : 2)
-#endif
-#ifndef DRXK_KI_IAGC_DVBT
-#define DRXK_KI_IAGC_DVBT  (IsA1WithPatchCode(state) ? 4 : 2)
-#endif
-#ifndef DRXK_KI_DAGC_DVBT
-#define DRXK_KI_DAGC_DVBT  (IsA1WithPatchCode(state) ? 10 : 7)
-#endif
-
-#ifndef DRXK_AGC_DAC_OFFSET
-#define DRXK_AGC_DAC_OFFSET (0x800)
-#endif
-
-#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
-#define DRXK_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
-#endif
-
-#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
-#define DRXK_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
-#endif
-
-#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
-#define DRXK_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
-#endif
-
-#ifndef DRXK_QAM_SYMBOLRATE_MAX
-#define DRXK_QAM_SYMBOLRATE_MAX         (7233000)
-#endif
-
-#define DRXK_BL_ROM_OFFSET_TAPS_DVBT    56
-#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A   64
-#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C   0x5FE0
-#define DRXK_BL_ROM_OFFSET_TAPS_BG      24
-#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP  32
-#define DRXK_BL_ROM_OFFSET_TAPS_NTSC    40
-#define DRXK_BL_ROM_OFFSET_TAPS_FM      48
-#define DRXK_BL_ROM_OFFSET_UCODE        0
-
-#define DRXK_BLC_TIMEOUT                100
-
-#define DRXK_BLCC_NR_ELEMENTS_TAPS      2
-#define DRXK_BLCC_NR_ELEMENTS_UCODE     6
-
-#define DRXK_BLDC_NR_ELEMENTS_TAPS      28
-
-#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
-#define DRXK_OFDM_NE_NOTCH_WIDTH             (4)
-#endif
-
-#define DRXK_QAM_SL_SIG_POWER_QAM16       (40960)
-#define DRXK_QAM_SL_SIG_POWER_QAM32       (20480)
-#define DRXK_QAM_SL_SIG_POWER_QAM64       (43008)
-#define DRXK_QAM_SL_SIG_POWER_QAM128      (20992)
-#define DRXK_QAM_SL_SIG_POWER_QAM256      (43520)
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
-
-#define dprintk(level, fmt, arg...) do {                       \
-if (debug >= level)                                            \
-       printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg);    \
-} while (0)
-
-
-static inline u32 MulDiv32(u32 a, u32 b, u32 c)
-{
-       u64 tmp64;
-
-       tmp64 = (u64) a * (u64) b;
-       do_div(tmp64, c);
-
-       return (u32) tmp64;
-}
-
-inline u32 Frac28a(u32 a, u32 c)
-{
-       int i = 0;
-       u32 Q1 = 0;
-       u32 R0 = 0;
-
-       R0 = (a % c) << 4;      /* 32-28 == 4 shifts possible at max */
-       Q1 = a / c;             /* integer part, only the 4 least significant bits
-                                  will be visible in the result */
-
-       /* division using radix 16, 7 nibbles in the result */
-       for (i = 0; i < 7; i++) {
-               Q1 = (Q1 << 4) | (R0 / c);
-               R0 = (R0 % c) << 4;
-       }
-       /* rounding */
-       if ((R0 >> 3) >= c)
-               Q1++;
-
-       return Q1;
-}
-
-static u32 Log10Times100(u32 x)
-{
-       static const u8 scale = 15;
-       static const u8 indexWidth = 5;
-       u8 i = 0;
-       u32 y = 0;
-       u32 d = 0;
-       u32 k = 0;
-       u32 r = 0;
-       /*
-          log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
-          0 <= n < ((1<<INDEXWIDTH)+1)
-        */
-
-       static const u32 log2lut[] = {
-               0,              /* 0.000000 */
-               290941,         /* 290941.300628 */
-               573196,         /* 573196.476418 */
-               847269,         /* 847269.179851 */
-               1113620,        /* 1113620.489452 */
-               1372674,        /* 1372673.576986 */
-               1624818,        /* 1624817.752104 */
-               1870412,        /* 1870411.981536 */
-               2109788,        /* 2109787.962654 */
-               2343253,        /* 2343252.817465 */
-               2571091,        /* 2571091.461923 */
-               2793569,        /* 2793568.696416 */
-               3010931,        /* 3010931.055901 */
-               3223408,        /* 3223408.452106 */
-               3431216,        /* 3431215.635215 */
-               3634553,        /* 3634553.498355 */
-               3833610,        /* 3833610.244726 */
-               4028562,        /* 4028562.434393 */
-               4219576,        /* 4219575.925308 */
-               4406807,        /* 4406806.721144 */
-               4590402,        /* 4590401.736809 */
-               4770499,        /* 4770499.491025 */
-               4947231,        /* 4947230.734179 */
-               5120719,        /* 5120719.018555 */
-               5291081,        /* 5291081.217197 */
-               5458428,        /* 5458427.996830 */
-               5622864,        /* 5622864.249668 */
-               5784489,        /* 5784489.488298 */
-               5943398,        /* 5943398.207380 */
-               6099680,        /* 6099680.215452 */
-               6253421,        /* 6253420.939751 */
-               6404702,        /* 6404701.706649 */
-               6553600,        /* 6553600.000000 */
-       };
-
-
-       if (x == 0)
-               return 0;
-
-       /* Scale x (normalize) */
-       /* computing y in log(x/y) = log(x) - log(y) */
-       if ((x & ((0xffffffff) << (scale + 1))) == 0) {
-               for (k = scale; k > 0; k--) {
-                       if (x & (((u32) 1) << scale))
-                               break;
-                       x <<= 1;
-               }
-       } else {
-               for (k = scale; k < 31; k++) {
-                       if ((x & (((u32) (-1)) << (scale + 1))) == 0)
-                               break;
-                       x >>= 1;
-               }
-       }
-       /*
-          Now x has binary point between bit[scale] and bit[scale-1]
-          and 1.0 <= x < 2.0 */
-
-       /* correction for divison: log(x) = log(x/y)+log(y) */
-       y = k * ((((u32) 1) << scale) * 200);
-
-       /* remove integer part */
-       x &= ((((u32) 1) << scale) - 1);
-       /* get index */
-       i = (u8) (x >> (scale - indexWidth));
-       /* compute delta (x - a) */
-       d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
-       /* compute log, multiplication (d* (..)) must be within range ! */
-       y += log2lut[i] +
-           ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
-       /* Conver to log10() */
-       y /= 108853;            /* (log2(10) << scale) */
-       r = (y >> 1);
-       /* rounding */
-       if (y & ((u32) 1))
-               r++;
-       return r;
-}
-
-/****************************************************************************/
-/* I2C **********************************************************************/
-/****************************************************************************/
-
-static int drxk_i2c_lock(struct drxk_state *state)
-{
-       i2c_lock_adapter(state->i2c);
-       state->drxk_i2c_exclusive_lock = true;
-
-       return 0;
-}
-
-static void drxk_i2c_unlock(struct drxk_state *state)
-{
-       if (!state->drxk_i2c_exclusive_lock)
-               return;
-
-       i2c_unlock_adapter(state->i2c);
-       state->drxk_i2c_exclusive_lock = false;
-}
-
-static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
-                            unsigned len)
-{
-       if (state->drxk_i2c_exclusive_lock)
-               return __i2c_transfer(state->i2c, msgs, len);
-       else
-               return i2c_transfer(state->i2c, msgs, len);
-}
-
-static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
-{
-       struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
-                                   .buf = val, .len = 1}
-       };
-
-       return drxk_i2c_transfer(state, msgs, 1);
-}
-
-static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
-{
-       int status;
-       struct i2c_msg msg = {
-           .addr = adr, .flags = 0, .buf = data, .len = len };
-
-       dprintk(3, ":");
-       if (debug > 2) {
-               int i;
-               for (i = 0; i < len; i++)
-                       printk(KERN_CONT " %02x", data[i]);
-               printk(KERN_CONT "\n");
-       }
-       status = drxk_i2c_transfer(state, &msg, 1);
-       if (status >= 0 && status != 1)
-               status = -EIO;
-
-       if (status < 0)
-               printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
-
-       return status;
-}
-
-static int i2c_read(struct drxk_state *state,
-                   u8 adr, u8 *msg, int len, u8 *answ, int alen)
-{
-       int status;
-       struct i2c_msg msgs[2] = {
-               {.addr = adr, .flags = 0,
-                                   .buf = msg, .len = len},
-               {.addr = adr, .flags = I2C_M_RD,
-                .buf = answ, .len = alen}
-       };
-
-       status = drxk_i2c_transfer(state, msgs, 2);
-       if (status != 2) {
-               if (debug > 2)
-                       printk(KERN_CONT ": ERROR!\n");
-               if (status >= 0)
-                       status = -EIO;
-
-               printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
-               return status;
-       }
-       if (debug > 2) {
-               int i;
-               dprintk(2, ": read from");
-               for (i = 0; i < len; i++)
-                       printk(KERN_CONT " %02x", msg[i]);
-               printk(KERN_CONT ", value = ");
-               for (i = 0; i < alen; i++)
-                       printk(KERN_CONT " %02x", answ[i]);
-               printk(KERN_CONT "\n");
-       }
-       return 0;
-}
-
-static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
-{
-       int status;
-       u8 adr = state->demod_address, mm1[4], mm2[2], len;
-
-       if (state->single_master)
-               flags |= 0xC0;
-
-       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
-               mm1[0] = (((reg << 1) & 0xFF) | 0x01);
-               mm1[1] = ((reg >> 16) & 0xFF);
-               mm1[2] = ((reg >> 24) & 0xFF) | flags;
-               mm1[3] = ((reg >> 7) & 0xFF);
-               len = 4;
-       } else {
-               mm1[0] = ((reg << 1) & 0xFF);
-               mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
-               len = 2;
-       }
-       dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
-       status = i2c_read(state, adr, mm1, len, mm2, 2);
-       if (status < 0)
-               return status;
-       if (data)
-               *data = mm2[0] | (mm2[1] << 8);
-
-       return 0;
-}
-
-static int read16(struct drxk_state *state, u32 reg, u16 *data)
-{
-       return read16_flags(state, reg, data, 0);
-}
-
-static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
-{
-       int status;
-       u8 adr = state->demod_address, mm1[4], mm2[4], len;
-
-       if (state->single_master)
-               flags |= 0xC0;
-
-       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
-               mm1[0] = (((reg << 1) & 0xFF) | 0x01);
-               mm1[1] = ((reg >> 16) & 0xFF);
-               mm1[2] = ((reg >> 24) & 0xFF) | flags;
-               mm1[3] = ((reg >> 7) & 0xFF);
-               len = 4;
-       } else {
-               mm1[0] = ((reg << 1) & 0xFF);
-               mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
-               len = 2;
-       }
-       dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
-       status = i2c_read(state, adr, mm1, len, mm2, 4);
-       if (status < 0)
-               return status;
-       if (data)
-               *data = mm2[0] | (mm2[1] << 8) |
-                   (mm2[2] << 16) | (mm2[3] << 24);
-
-       return 0;
-}
-
-static int read32(struct drxk_state *state, u32 reg, u32 *data)
-{
-       return read32_flags(state, reg, data, 0);
-}
-
-static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
-{
-       u8 adr = state->demod_address, mm[6], len;
-
-       if (state->single_master)
-               flags |= 0xC0;
-       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
-               mm[0] = (((reg << 1) & 0xFF) | 0x01);
-               mm[1] = ((reg >> 16) & 0xFF);
-               mm[2] = ((reg >> 24) & 0xFF) | flags;
-               mm[3] = ((reg >> 7) & 0xFF);
-               len = 4;
-       } else {
-               mm[0] = ((reg << 1) & 0xFF);
-               mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
-               len = 2;
-       }
-       mm[len] = data & 0xff;
-       mm[len + 1] = (data >> 8) & 0xff;
-
-       dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
-       return i2c_write(state, adr, mm, len + 2);
-}
-
-static int write16(struct drxk_state *state, u32 reg, u16 data)
-{
-       return write16_flags(state, reg, data, 0);
-}
-
-static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
-{
-       u8 adr = state->demod_address, mm[8], len;
-
-       if (state->single_master)
-               flags |= 0xC0;
-       if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
-               mm[0] = (((reg << 1) & 0xFF) | 0x01);
-               mm[1] = ((reg >> 16) & 0xFF);
-               mm[2] = ((reg >> 24) & 0xFF) | flags;
-               mm[3] = ((reg >> 7) & 0xFF);
-               len = 4;
-       } else {
-               mm[0] = ((reg << 1) & 0xFF);
-               mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
-               len = 2;
-       }
-       mm[len] = data & 0xff;
-       mm[len + 1] = (data >> 8) & 0xff;
-       mm[len + 2] = (data >> 16) & 0xff;
-       mm[len + 3] = (data >> 24) & 0xff;
-       dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
-
-       return i2c_write(state, adr, mm, len + 4);
-}
-
-static int write32(struct drxk_state *state, u32 reg, u32 data)
-{
-       return write32_flags(state, reg, data, 0);
-}
-
-static int write_block(struct drxk_state *state, u32 Address,
-                     const int BlockSize, const u8 pBlock[])
-{
-       int status = 0, BlkSize = BlockSize;
-       u8 Flags = 0;
-
-       if (state->single_master)
-               Flags |= 0xC0;
-
-       while (BlkSize > 0) {
-               int Chunk = BlkSize > state->m_ChunkSize ?
-                   state->m_ChunkSize : BlkSize;
-               u8 *AdrBuf = &state->Chunk[0];
-               u32 AdrLength = 0;
-
-               if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
-                       AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
-                       AdrBuf[1] = ((Address >> 16) & 0xFF);
-                       AdrBuf[2] = ((Address >> 24) & 0xFF);
-                       AdrBuf[3] = ((Address >> 7) & 0xFF);
-                       AdrBuf[2] |= Flags;
-                       AdrLength = 4;
-                       if (Chunk == state->m_ChunkSize)
-                               Chunk -= 2;
-               } else {
-                       AdrBuf[0] = ((Address << 1) & 0xFF);
-                       AdrBuf[1] = (((Address >> 16) & 0x0F) |
-                                    ((Address >> 18) & 0xF0));
-                       AdrLength = 2;
-               }
-               memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
-               dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
-               if (debug > 1) {
-                       int i;
-                       if (pBlock)
-                               for (i = 0; i < Chunk; i++)
-                                       printk(KERN_CONT " %02x", pBlock[i]);
-                       printk(KERN_CONT "\n");
-               }
-               status = i2c_write(state, state->demod_address,
-                                  &state->Chunk[0], Chunk + AdrLength);
-               if (status < 0) {
-                       printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
-                              __func__, Address);
-                       break;
-               }
-               pBlock += Chunk;
-               Address += (Chunk >> 1);
-               BlkSize -= Chunk;
-       }
-       return status;
-}
-
-#ifndef DRXK_MAX_RETRIES_POWERUP
-#define DRXK_MAX_RETRIES_POWERUP 20
-#endif
-
-int PowerUpDevice(struct drxk_state *state)
-{
-       int status;
-       u8 data = 0;
-       u16 retryCount = 0;
-
-       dprintk(1, "\n");
-
-       status = i2c_read1(state, state->demod_address, &data);
-       if (status < 0) {
-               do {
-                       data = 0;
-                       status = i2c_write(state, state->demod_address,
-                                          &data, 1);
-                       msleep(10);
-                       retryCount++;
-                       if (status < 0)
-                               continue;
-                       status = i2c_read1(state, state->demod_address,
-                                          &data);
-               } while (status < 0 &&
-                        (retryCount < DRXK_MAX_RETRIES_POWERUP));
-               if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
-                       goto error;
-       }
-
-       /* Make sure all clk domains are active */
-       status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
-       if (status < 0)
-               goto error;
-       /* Enable pll lock tests */
-       status = write16(state, SIO_CC_PLL_LOCK__A, 1);
-       if (status < 0)
-               goto error;
-
-       state->m_currentPowerMode = DRX_POWER_UP;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-
-static int init_state(struct drxk_state *state)
-{
-       /*
-        * FIXME: most (all?) of the values bellow should be moved into
-        * struct drxk_config, as they are probably board-specific
-        */
-       u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
-       u32 ulVSBIfAgcOutputLevel = 0;
-       u32 ulVSBIfAgcMinLevel = 0;
-       u32 ulVSBIfAgcMaxLevel = 0x7FFF;
-       u32 ulVSBIfAgcSpeed = 3;
-
-       u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
-       u32 ulVSBRfAgcOutputLevel = 0;
-       u32 ulVSBRfAgcMinLevel = 0;
-       u32 ulVSBRfAgcMaxLevel = 0x7FFF;
-       u32 ulVSBRfAgcSpeed = 3;
-       u32 ulVSBRfAgcTop = 9500;
-       u32 ulVSBRfAgcCutOffCurrent = 4000;
-
-       u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
-       u32 ulATVIfAgcOutputLevel = 0;
-       u32 ulATVIfAgcMinLevel = 0;
-       u32 ulATVIfAgcMaxLevel = 0;
-       u32 ulATVIfAgcSpeed = 3;
-
-       u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
-       u32 ulATVRfAgcOutputLevel = 0;
-       u32 ulATVRfAgcMinLevel = 0;
-       u32 ulATVRfAgcMaxLevel = 0;
-       u32 ulATVRfAgcTop = 9500;
-       u32 ulATVRfAgcCutOffCurrent = 4000;
-       u32 ulATVRfAgcSpeed = 3;
-
-       u32 ulQual83 = DEFAULT_MER_83;
-       u32 ulQual93 = DEFAULT_MER_93;
-
-       u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-       u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
-
-       /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
-       /* io_pad_cfg_mode output mode is drive always */
-       /* io_pad_cfg_drive is set to power 2 (23 mA) */
-       u32 ulGPIOCfg = 0x0113;
-       u32 ulInvertTSClock = 0;
-       u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
-       u32 ulDVBTBitrate = 50000000;
-       u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
-
-       u32 ulInsertRSByte = 0;
-
-       u32 ulRfMirror = 1;
-       u32 ulPowerDown = 0;
-
-       dprintk(1, "\n");
-
-       state->m_hasLNA = false;
-       state->m_hasDVBT = false;
-       state->m_hasDVBC = false;
-       state->m_hasATV = false;
-       state->m_hasOOB = false;
-       state->m_hasAudio = false;
-
-       if (!state->m_ChunkSize)
-               state->m_ChunkSize = 124;
-
-       state->m_oscClockFreq = 0;
-       state->m_smartAntInverted = false;
-       state->m_bPDownOpenBridge = false;
-
-       /* real system clock frequency in kHz */
-       state->m_sysClockFreq = 151875;
-       /* Timing div, 250ns/Psys */
-       /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
-       state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
-                                  HI_I2C_DELAY) / 1000;
-       /* Clipping */
-       if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
-               state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
-       state->m_HICfgWakeUpKey = (state->demod_address << 1);
-       /* port/bridge/power down ctrl */
-       state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
-
-       state->m_bPowerDown = (ulPowerDown != 0);
-
-       state->m_DRXK_A1_PATCH_CODE = false;
-       state->m_DRXK_A1_ROM_CODE = false;
-       state->m_DRXK_A2_ROM_CODE = false;
-       state->m_DRXK_A3_ROM_CODE = false;
-       state->m_DRXK_A2_PATCH_CODE = false;
-       state->m_DRXK_A3_PATCH_CODE = false;
-
-       /* Init AGC and PGA parameters */
-       /* VSB IF */
-       state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
-       state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
-       state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
-       state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
-       state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
-       state->m_vsbPgaCfg = 140;
-
-       /* VSB RF */
-       state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
-       state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
-       state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
-       state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
-       state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
-       state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
-       state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
-       state->m_vsbPreSawCfg.reference = 0x07;
-       state->m_vsbPreSawCfg.usePreSaw = true;
-
-       state->m_Quality83percent = DEFAULT_MER_83;
-       state->m_Quality93percent = DEFAULT_MER_93;
-       if (ulQual93 <= 500 && ulQual83 < ulQual93) {
-               state->m_Quality83percent = ulQual83;
-               state->m_Quality93percent = ulQual93;
-       }
-
-       /* ATV IF */
-       state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
-       state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
-       state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
-       state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
-       state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
-
-       /* ATV RF */
-       state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
-       state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
-       state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
-       state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
-       state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
-       state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
-       state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
-       state->m_atvPreSawCfg.reference = 0x04;
-       state->m_atvPreSawCfg.usePreSaw = true;
-
-
-       /* DVBT RF */
-       state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-       state->m_dvbtRfAgcCfg.outputLevel = 0;
-       state->m_dvbtRfAgcCfg.minOutputLevel = 0;
-       state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
-       state->m_dvbtRfAgcCfg.top = 0x2100;
-       state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
-       state->m_dvbtRfAgcCfg.speed = 1;
-
-
-       /* DVBT IF */
-       state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-       state->m_dvbtIfAgcCfg.outputLevel = 0;
-       state->m_dvbtIfAgcCfg.minOutputLevel = 0;
-       state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
-       state->m_dvbtIfAgcCfg.top = 13424;
-       state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
-       state->m_dvbtIfAgcCfg.speed = 3;
-       state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
-       state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
-       /* state->m_dvbtPgaCfg = 140; */
-
-       state->m_dvbtPreSawCfg.reference = 4;
-       state->m_dvbtPreSawCfg.usePreSaw = false;
-
-       /* QAM RF */
-       state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-       state->m_qamRfAgcCfg.outputLevel = 0;
-       state->m_qamRfAgcCfg.minOutputLevel = 6023;
-       state->m_qamRfAgcCfg.maxOutputLevel = 27000;
-       state->m_qamRfAgcCfg.top = 0x2380;
-       state->m_qamRfAgcCfg.cutOffCurrent = 4000;
-       state->m_qamRfAgcCfg.speed = 3;
-
-       /* QAM IF */
-       state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-       state->m_qamIfAgcCfg.outputLevel = 0;
-       state->m_qamIfAgcCfg.minOutputLevel = 0;
-       state->m_qamIfAgcCfg.maxOutputLevel = 9000;
-       state->m_qamIfAgcCfg.top = 0x0511;
-       state->m_qamIfAgcCfg.cutOffCurrent = 0;
-       state->m_qamIfAgcCfg.speed = 3;
-       state->m_qamIfAgcCfg.IngainTgtMax = 5119;
-       state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
-
-       state->m_qamPgaCfg = 140;
-       state->m_qamPreSawCfg.reference = 4;
-       state->m_qamPreSawCfg.usePreSaw = false;
-
-       state->m_OperationMode = OM_NONE;
-       state->m_DrxkState = DRXK_UNINITIALIZED;
-
-       /* MPEG output configuration */
-       state->m_enableMPEGOutput = true;       /* If TRUE; enable MPEG ouput */
-       state->m_insertRSByte = false;  /* If TRUE; insert RS byte */
-       state->m_invertDATA = false;    /* If TRUE; invert DATA signals */
-       state->m_invertERR = false;     /* If TRUE; invert ERR signal */
-       state->m_invertSTR = false;     /* If TRUE; invert STR signals */
-       state->m_invertVAL = false;     /* If TRUE; invert VAL signals */
-       state->m_invertCLK = (ulInvertTSClock != 0);    /* If TRUE; invert CLK signals */
-
-       /* If TRUE; static MPEG clockrate will be used;
-          otherwise clockrate will adapt to the bitrate of the TS */
-
-       state->m_DVBTBitrate = ulDVBTBitrate;
-       state->m_DVBCBitrate = ulDVBCBitrate;
-
-       state->m_TSDataStrength = (ulTSDataStrength & 0x07);
-
-       /* Maximum bitrate in b/s in case static clockrate is selected */
-       state->m_mpegTsStaticBitrate = 19392658;
-       state->m_disableTEIhandling = false;
-
-       if (ulInsertRSByte)
-               state->m_insertRSByte = true;
-
-       state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-       if (ulMpegLockTimeOut < 10000)
-               state->m_MpegLockTimeOut = ulMpegLockTimeOut;
-       state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
-       if (ulDemodLockTimeOut < 10000)
-               state->m_DemodLockTimeOut = ulDemodLockTimeOut;
-
-       /* QAM defaults */
-       state->m_Constellation = DRX_CONSTELLATION_AUTO;
-       state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
-       state->m_fecRsPlen = 204 * 8;   /* fecRsPlen  annex A */
-       state->m_fecRsPrescale = 1;
-
-       state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
-       state->m_agcFastClipCtrlDelay = 0;
-
-       state->m_GPIOCfg = (ulGPIOCfg);
-
-       state->m_bPowerDown = false;
-       state->m_currentPowerMode = DRX_POWER_DOWN;
-
-       state->m_rfmirror = (ulRfMirror == 0);
-       state->m_IfAgcPol = false;
-       return 0;
-}
-
-static int DRXX_Open(struct drxk_state *state)
-{
-       int status = 0;
-       u32 jtag = 0;
-       u16 bid = 0;
-       u16 key = 0;
-
-       dprintk(1, "\n");
-       /* stop lock indicator process */
-       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-       if (status < 0)
-               goto error;
-       /* Check device id */
-       status = read16(state, SIO_TOP_COMM_KEY__A, &key);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
-       if (status < 0)
-               goto error;
-       status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
-       if (status < 0)
-               goto error;
-       status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_TOP_COMM_KEY__A, key);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int GetDeviceCapabilities(struct drxk_state *state)
-{
-       u16 sioPdrOhwCfg = 0;
-       u32 sioTopJtagidLo = 0;
-       int status;
-       const char *spin = "";
-
-       dprintk(1, "\n");
-
-       /* driver 0.9.0 */
-       /* stop lock indicator process */
-       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
-       if (status < 0)
-               goto error;
-       status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
-       if (status < 0)
-               goto error;
-
-       switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
-       case 0:
-               /* ignore (bypass ?) */
-               break;
-       case 1:
-               /* 27 MHz */
-               state->m_oscClockFreq = 27000;
-               break;
-       case 2:
-               /* 20.25 MHz */
-               state->m_oscClockFreq = 20250;
-               break;
-       case 3:
-               /* 4 MHz */
-               state->m_oscClockFreq = 20250;
-               break;
-       default:
-               printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
-               return -EINVAL;
-       }
-       /*
-               Determine device capabilities
-               Based on pinning v14
-               */
-       status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
-       if (status < 0)
-               goto error;
-
-       printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
-
-       /* driver 0.9.0 */
-       switch ((sioTopJtagidLo >> 29) & 0xF) {
-       case 0:
-               state->m_deviceSpin = DRXK_SPIN_A1;
-               spin = "A1";
-               break;
-       case 2:
-               state->m_deviceSpin = DRXK_SPIN_A2;
-               spin = "A2";
-               break;
-       case 3:
-               state->m_deviceSpin = DRXK_SPIN_A3;
-               spin = "A3";
-               break;
-       default:
-               state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
-               status = -EINVAL;
-               printk(KERN_ERR "drxk: Spin %d unknown\n",
-                      (sioTopJtagidLo >> 29) & 0xF);
-               goto error2;
-       }
-       switch ((sioTopJtagidLo >> 12) & 0xFF) {
-       case 0x13:
-               /* typeId = DRX3913K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = false;
-               state->m_hasAudio = false;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = true;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = false;
-               state->m_hasGPIO1 = false;
-               state->m_hasIRQN = false;
-               break;
-       case 0x15:
-               /* typeId = DRX3915K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = false;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = false;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x16:
-               /* typeId = DRX3916K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = false;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = false;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x18:
-               /* typeId = DRX3918K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = true;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = false;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x21:
-               /* typeId = DRX3921K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = true;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = true;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x23:
-               /* typeId = DRX3923K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = true;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = true;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x25:
-               /* typeId = DRX3925K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = true;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = true;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       case 0x26:
-               /* typeId = DRX3926K_TYPE_ID */
-               state->m_hasLNA = false;
-               state->m_hasOOB = false;
-               state->m_hasATV = true;
-               state->m_hasAudio = false;
-               state->m_hasDVBT = true;
-               state->m_hasDVBC = true;
-               state->m_hasSAWSW = true;
-               state->m_hasGPIO2 = true;
-               state->m_hasGPIO1 = true;
-               state->m_hasIRQN = false;
-               break;
-       default:
-               printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
-                       ((sioTopJtagidLo >> 12) & 0xFF));
-               status = -EINVAL;
-               goto error2;
-       }
-
-       printk(KERN_INFO
-              "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
-              ((sioTopJtagidLo >> 12) & 0xFF), spin,
-              state->m_oscClockFreq / 1000,
-              state->m_oscClockFreq % 1000);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-error2:
-       return status;
-}
-
-static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
-{
-       int status;
-       bool powerdown_cmd;
-
-       dprintk(1, "\n");
-
-       /* Write command */
-       status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
-       if (status < 0)
-               goto error;
-       if (cmd == SIO_HI_RA_RAM_CMD_RESET)
-               msleep(1);
-
-       powerdown_cmd =
-           (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
-                   ((state->m_HICfgCtrl) &
-                    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
-                   SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
-       if (powerdown_cmd == false) {
-               /* Wait until command rdy */
-               u32 retryCount = 0;
-               u16 waitCmd;
-
-               do {
-                       msleep(1);
-                       retryCount += 1;
-                       status = read16(state, SIO_HI_RA_RAM_CMD__A,
-                                         &waitCmd);
-               } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
-                        && (waitCmd != 0));
-               if (status < 0)
-                       goto error;
-               status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int HI_CfgCommand(struct drxk_state *state)
-{
-       int status;
-
-       dprintk(1, "\n");
-
-       mutex_lock(&state->mutex);
-
-       status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
-       if (status < 0)
-               goto error;
-       status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
-       if (status < 0)
-               goto error;
-
-       state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-error:
-       mutex_unlock(&state->mutex);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int InitHI(struct drxk_state *state)
-{
-       dprintk(1, "\n");
-
-       state->m_HICfgWakeUpKey = (state->demod_address << 1);
-       state->m_HICfgTimeout = 0x96FF;
-       /* port/bridge/power down ctrl */
-       state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
-
-       return HI_CfgCommand(state);
-}
-
-static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
-{
-       int status = -1;
-       u16 sioPdrMclkCfg = 0;
-       u16 sioPdrMdxCfg = 0;
-       u16 err_cfg = 0;
-
-       dprintk(1, ": mpeg %s, %s mode\n",
-               mpegEnable ? "enable" : "disable",
-               state->m_enableParallel ? "parallel" : "serial");
-
-       /* stop lock indicator process */
-       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-       if (status < 0)
-               goto error;
-
-       /*  MPEG TS pad configuration */
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
-       if (status < 0)
-               goto error;
-
-       if (mpegEnable == false) {
-               /*  Set MPEG TS pads to inputmode */
-               status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
-               if (status < 0)
-                       goto error;
-       } else {
-               /* Enable MPEG output */
-               sioPdrMdxCfg =
-                       ((state->m_TSDataStrength <<
-                       SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
-               sioPdrMclkCfg = ((state->m_TSClockkStrength <<
-                                       SIO_PDR_MCLK_CFG_DRIVE__B) |
-                                       0x0003);
-
-               status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
-               if (status < 0)
-                       goto error;
-
-               if (state->enable_merr_cfg)
-                       err_cfg = sioPdrMdxCfg;
-
-               status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
-               if (status < 0)
-                       goto error;
-
-               if (state->m_enableParallel == true) {
-                       /* paralel -> enable MD1 to MD7 */
-                       status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
-                       if (status < 0)
-                               goto error;
-               } else {
-                       sioPdrMdxCfg = ((state->m_TSDataStrength <<
-                                               SIO_PDR_MD0_CFG_DRIVE__B)
-                                       | 0x0003);
-                       /* serial -> disable MD1 to MD7 */
-                       status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-                       status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
-                       if (status < 0)
-                               goto error;
-               }
-               status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
-               if (status < 0)
-                       goto error;
-       }
-       /*  Enable MB output over MPEG pads and ctl input */
-       status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
-       if (status < 0)
-               goto error;
-       /*  Write nomagic word to enable pdr reg write */
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int MPEGTSDisable(struct drxk_state *state)
-{
-       dprintk(1, "\n");
-
-       return MPEGTSConfigurePins(state, false);
-}
-
-static int BLChainCmd(struct drxk_state *state,
-                     u16 romOffset, u16 nrOfElements, u32 timeOut)
-{
-       u16 blStatus = 0;
-       int status;
-       unsigned long end;
-
-       dprintk(1, "\n");
-       mutex_lock(&state->mutex);
-       status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
-       if (status < 0)
-               goto error;
-
-       end = jiffies + msecs_to_jiffies(timeOut);
-       do {
-               msleep(1);
-               status = read16(state, SIO_BL_STATUS__A, &blStatus);
-               if (status < 0)
-                       goto error;
-       } while ((blStatus == 0x1) &&
-                       ((time_is_after_jiffies(end))));
-
-       if (blStatus == 0x1) {
-               printk(KERN_ERR "drxk: SIO not ready\n");
-               status = -EINVAL;
-               goto error2;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-error2:
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-
-static int DownloadMicrocode(struct drxk_state *state,
-                            const u8 pMCImage[], u32 Length)
-{
-       const u8 *pSrc = pMCImage;
-       u32 Address;
-       u16 nBlocks;
-       u16 BlockSize;
-       u32 offset = 0;
-       u32 i;
-       int status = 0;
-
-       dprintk(1, "\n");
-
-       /* down the drain (we don't care about MAGIC_WORD) */
-#if 0
-       /* For future reference */
-       Drain = (pSrc[0] << 8) | pSrc[1];
-#endif
-       pSrc += sizeof(u16);
-       offset += sizeof(u16);
-       nBlocks = (pSrc[0] << 8) | pSrc[1];
-       pSrc += sizeof(u16);
-       offset += sizeof(u16);
-
-       for (i = 0; i < nBlocks; i += 1) {
-               Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
-                   (pSrc[2] << 8) | pSrc[3];
-               pSrc += sizeof(u32);
-               offset += sizeof(u32);
-
-               BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-#if 0
-               /* For future reference */
-               Flags = (pSrc[0] << 8) | pSrc[1];
-#endif
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-#if 0
-               /* For future reference */
-               BlockCRC = (pSrc[0] << 8) | pSrc[1];
-#endif
-               pSrc += sizeof(u16);
-               offset += sizeof(u16);
-
-               if (offset + BlockSize > Length) {
-                       printk(KERN_ERR "drxk: Firmware is corrupted.\n");
-                       return -EINVAL;
-               }
-
-               status = write_block(state, Address, BlockSize, pSrc);
-               if (status < 0) {
-                       printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
-                       break;
-               }
-               pSrc += BlockSize;
-               offset += BlockSize;
-       }
-       return status;
-}
-
-static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
-{
-       int status;
-       u16 data = 0;
-       u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
-       u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
-       unsigned long end;
-
-       dprintk(1, "\n");
-
-       if (enable == false) {
-               desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
-               desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
-       }
-
-       status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-       if (status >= 0 && data == desiredStatus) {
-               /* tokenring already has correct status */
-               return status;
-       }
-       /* Disable/enable dvbt tokenring bridge   */
-       status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
-
-       end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
-       do {
-               status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-               if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
-                       break;
-               msleep(1);
-       } while (1);
-       if (data != desiredStatus) {
-               printk(KERN_ERR "drxk: SIO not ready\n");
-               return -EINVAL;
-       }
-       return status;
-}
-
-static int MPEGTSStop(struct drxk_state *state)
-{
-       int status = 0;
-       u16 fecOcSncMode = 0;
-       u16 fecOcIprMode = 0;
-
-       dprintk(1, "\n");
-
-       /* Gracefull shutdown (byte boundaries) */
-       status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
-       if (status < 0)
-               goto error;
-       fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
-       status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
-       if (status < 0)
-               goto error;
-
-       /* Suppress MCLK during absence of data */
-       status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
-       if (status < 0)
-               goto error;
-       fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
-       status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int scu_command(struct drxk_state *state,
-                      u16 cmd, u8 parameterLen,
-                      u16 *parameter, u8 resultLen, u16 *result)
-{
-#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
-#error DRXK register mapping no longer compatible with this routine!
-#endif
-       u16 curCmd = 0;
-       int status = -EINVAL;
-       unsigned long end;
-       u8 buffer[34];
-       int cnt = 0, ii;
-       const char *p;
-       char errname[30];
-
-       dprintk(1, "\n");
-
-       if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-           ((resultLen > 0) && (result == NULL))) {
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-               return status;
-       }
-
-       mutex_lock(&state->mutex);
-
-       /* assume that the command register is ready
-               since it is checked afterwards */
-       for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
-               buffer[cnt++] = (parameter[ii] & 0xFF);
-               buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
-       }
-       buffer[cnt++] = (cmd & 0xFF);
-       buffer[cnt++] = ((cmd >> 8) & 0xFF);
-
-       write_block(state, SCU_RAM_PARAM_0__A -
-                       (parameterLen - 1), cnt, buffer);
-       /* Wait until SCU has processed command */
-       end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
-       do {
-               msleep(1);
-               status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
-               if (status < 0)
-                       goto error;
-       } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
-       if (curCmd != DRX_SCU_READY) {
-               printk(KERN_ERR "drxk: SCU not ready\n");
-               status = -EIO;
-               goto error2;
-       }
-       /* read results */
-       if ((resultLen > 0) && (result != NULL)) {
-               s16 err;
-               int ii;
-
-               for (ii = resultLen - 1; ii >= 0; ii -= 1) {
-                       status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
-                       if (status < 0)
-                               goto error;
-               }
-
-               /* Check if an error was reported by SCU */
-               err = (s16)result[0];
-               if (err >= 0)
-                       goto error;
-
-               /* check for the known error codes */
-               switch (err) {
-               case SCU_RESULT_UNKCMD:
-                       p = "SCU_RESULT_UNKCMD";
-                       break;
-               case SCU_RESULT_UNKSTD:
-                       p = "SCU_RESULT_UNKSTD";
-                       break;
-               case SCU_RESULT_SIZE:
-                       p = "SCU_RESULT_SIZE";
-                       break;
-               case SCU_RESULT_INVPAR:
-                       p = "SCU_RESULT_INVPAR";
-                       break;
-               default: /* Other negative values are errors */
-                       sprintf(errname, "ERROR: %d\n", err);
-                       p = errname;
-               }
-               printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
-               print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
-               status = -EINVAL;
-               goto error2;
-       }
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-error2:
-       mutex_unlock(&state->mutex);
-       return status;
-}
-
-static int SetIqmAf(struct drxk_state *state, bool active)
-{
-       u16 data = 0;
-       int status;
-
-       dprintk(1, "\n");
-
-       /* Configure IQM */
-       status = read16(state, IQM_AF_STDBY__A, &data);
-       if (status < 0)
-               goto error;
-
-       if (!active) {
-               data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
-                               | IQM_AF_STDBY_STDBY_AMP_STANDBY
-                               | IQM_AF_STDBY_STDBY_PD_STANDBY
-                               | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
-                               | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
-       } else {
-               data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
-                               & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
-                               & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
-                               & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
-                               & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
-                       );
-       }
-       status = write16(state, IQM_AF_STDBY__A, data);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
-{
-       int status = 0;
-       u16 sioCcPwdMode = 0;
-
-       dprintk(1, "\n");
-
-       /* Check arguments */
-       if (mode == NULL)
-               return -EINVAL;
-
-       switch (*mode) {
-       case DRX_POWER_UP:
-               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
-               break;
-       case DRXK_POWER_DOWN_OFDM:
-               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
-               break;
-       case DRXK_POWER_DOWN_CORE:
-               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
-               break;
-       case DRXK_POWER_DOWN_PLL:
-               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
-               break;
-       case DRX_POWER_DOWN:
-               sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
-               break;
-       default:
-               /* Unknow sleep mode */
-               return -EINVAL;
-       }
-
-       /* If already in requested power mode, do nothing */
-       if (state->m_currentPowerMode == *mode)
-               return 0;
-
-       /* For next steps make sure to start from DRX_POWER_UP mode */
-       if (state->m_currentPowerMode != DRX_POWER_UP) {
-               status = PowerUpDevice(state);
-               if (status < 0)
-                       goto error;
-               status = DVBTEnableOFDMTokenRing(state, true);
-               if (status < 0)
-                       goto error;
-       }
-
-       if (*mode == DRX_POWER_UP) {
-               /* Restore analog & pin configuartion */
-       } else {
-               /* Power down to requested mode */
-               /* Backup some register settings */
-               /* Set pins with possible pull-ups connected
-                  to them in input mode */
-               /* Analog power down */
-               /* ADC power down */
-               /* Power down device */
-               /* stop all comm_exec */
-               /* Stop and power down previous standard */
-               switch (state->m_OperationMode) {
-               case OM_DVBT:
-                       status = MPEGTSStop(state);
-                       if (status < 0)
-                               goto error;
-                       status = PowerDownDVBT(state, false);
-                       if (status < 0)
-                               goto error;
-                       break;
-               case OM_QAM_ITU_A:
-               case OM_QAM_ITU_C:
-                       status = MPEGTSStop(state);
-                       if (status < 0)
-                               goto error;
-                       status = PowerDownQAM(state);
-                       if (status < 0)
-                               goto error;
-                       break;
-               default:
-                       break;
-               }
-               status = DVBTEnableOFDMTokenRing(state, false);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
-               if (status < 0)
-                       goto error;
-
-               if (*mode != DRXK_POWER_DOWN_OFDM) {
-                       state->m_HICfgCtrl |=
-                               SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-                       status = HI_CfgCommand(state);
-                       if (status < 0)
-                               goto error;
-               }
-       }
-       state->m_currentPowerMode = *mode;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
-{
-       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-       u16 cmdResult = 0;
-       u16 data = 0;
-       int status;
-
-       dprintk(1, "\n");
-
-       status = read16(state, SCU_COMM_EXEC__A, &data);
-       if (status < 0)
-               goto error;
-       if (data == SCU_COMM_EXEC_ACTIVE) {
-               /* Send OFDM stop command */
-               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
-               if (status < 0)
-                       goto error;
-               /* Send OFDM reset command */
-               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
-               if (status < 0)
-                       goto error;
-       }
-
-       /* Reset datapath for OFDM, processors first */
-       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
-       if (status < 0)
-               goto error;
-
-       /* powerdown AFE                   */
-       status = SetIqmAf(state, false);
-       if (status < 0)
-               goto error;
-
-       /* powerdown to OFDM mode          */
-       if (setPowerMode) {
-               status = CtrlPowerMode(state, &powerMode);
-               if (status < 0)
-                       goto error;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SetOperationMode(struct drxk_state *state,
-                           enum OperationMode oMode)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-       /*
-          Stop and power down previous standard
-          TODO investigate total power down instead of partial
-          power down depending on "previous" standard.
-        */
-
-       /* disable HW lock indicator */
-       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-       if (status < 0)
-               goto error;
-
-       /* Device is already at the required mode */
-       if (state->m_OperationMode == oMode)
-               return 0;
-
-       switch (state->m_OperationMode) {
-               /* OM_NONE was added for start up */
-       case OM_NONE:
-               break;
-       case OM_DVBT:
-               status = MPEGTSStop(state);
-               if (status < 0)
-                       goto error;
-               status = PowerDownDVBT(state, true);
-               if (status < 0)
-                       goto error;
-               state->m_OperationMode = OM_NONE;
-               break;
-       case OM_QAM_ITU_A:      /* fallthrough */
-       case OM_QAM_ITU_C:
-               status = MPEGTSStop(state);
-               if (status < 0)
-                       goto error;
-               status = PowerDownQAM(state);
-               if (status < 0)
-                       goto error;
-               state->m_OperationMode = OM_NONE;
-               break;
-       case OM_QAM_ITU_B:
-       default:
-               status = -EINVAL;
-               goto error;
-       }
-
-       /*
-               Power up new standard
-               */
-       switch (oMode) {
-       case OM_DVBT:
-               dprintk(1, ": DVB-T\n");
-               state->m_OperationMode = oMode;
-               status = SetDVBTStandard(state, oMode);
-               if (status < 0)
-                       goto error;
-               break;
-       case OM_QAM_ITU_A:      /* fallthrough */
-       case OM_QAM_ITU_C:
-               dprintk(1, ": DVB-C Annex %c\n",
-                       (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
-               state->m_OperationMode = oMode;
-               status = SetQAMStandard(state, oMode);
-               if (status < 0)
-                       goto error;
-               break;
-       case OM_QAM_ITU_B:
-       default:
-               status = -EINVAL;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int Start(struct drxk_state *state, s32 offsetFreq,
-                s32 IntermediateFrequency)
-{
-       int status = -EINVAL;
-
-       u16 IFreqkHz;
-       s32 OffsetkHz = offsetFreq / 1000;
-
-       dprintk(1, "\n");
-       if (state->m_DrxkState != DRXK_STOPPED &&
-               state->m_DrxkState != DRXK_DTV_STARTED)
-               goto error;
-
-       state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
-
-       if (IntermediateFrequency < 0) {
-               state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
-               IntermediateFrequency = -IntermediateFrequency;
-       }
-
-       switch (state->m_OperationMode) {
-       case OM_QAM_ITU_A:
-       case OM_QAM_ITU_C:
-               IFreqkHz = (IntermediateFrequency / 1000);
-               status = SetQAM(state, IFreqkHz, OffsetkHz);
-               if (status < 0)
-                       goto error;
-               state->m_DrxkState = DRXK_DTV_STARTED;
-               break;
-       case OM_DVBT:
-               IFreqkHz = (IntermediateFrequency / 1000);
-               status = MPEGTSStop(state);
-               if (status < 0)
-                       goto error;
-               status = SetDVBT(state, IFreqkHz, OffsetkHz);
-               if (status < 0)
-                       goto error;
-               status = DVBTStart(state);
-               if (status < 0)
-                       goto error;
-               state->m_DrxkState = DRXK_DTV_STARTED;
-               break;
-       default:
-               break;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int ShutDown(struct drxk_state *state)
-{
-       dprintk(1, "\n");
-
-       MPEGTSStop(state);
-       return 0;
-}
-
-static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
-                        u32 Time)
-{
-       int status = -EINVAL;
-
-       dprintk(1, "\n");
-
-       if (pLockStatus == NULL)
-               goto error;
-
-       *pLockStatus = NOT_LOCKED;
-
-       /* define the SCU command code */
-       switch (state->m_OperationMode) {
-       case OM_QAM_ITU_A:
-       case OM_QAM_ITU_B:
-       case OM_QAM_ITU_C:
-               status = GetQAMLockStatus(state, pLockStatus);
-               break;
-       case OM_DVBT:
-               status = GetDVBTLockStatus(state, pLockStatus);
-               break;
-       default:
-               break;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int MPEGTSStart(struct drxk_state *state)
-{
-       int status;
-
-       u16 fecOcSncMode = 0;
-
-       /* Allow OC to sync again */
-       status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
-       if (status < 0)
-               goto error;
-       fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
-       status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int MPEGTSDtoInit(struct drxk_state *state)
-{
-       int status;
-
-       dprintk(1, "\n");
-
-       /* Rate integration settings */
-       status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
-       if (status < 0)
-               goto error;
-
-       /* Additional configuration */
-       status = write16(state, FEC_OC_OCR_INVERT__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_SNC_LWM__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_SNC_HWM__A, 12);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int MPEGTSDtoSetup(struct drxk_state *state,
-                         enum OperationMode oMode)
-{
-       int status;
-
-       u16 fecOcRegMode = 0;   /* FEC_OC_MODE       register value */
-       u16 fecOcRegIprMode = 0;        /* FEC_OC_IPR_MODE   register value */
-       u16 fecOcDtoMode = 0;   /* FEC_OC_IPR_INVERT register value */
-       u16 fecOcFctMode = 0;   /* FEC_OC_IPR_INVERT register value */
-       u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
-       u16 fecOcDtoBurstLen = 188;     /* FEC_OC_IPR_INVERT register value */
-       u32 fecOcRcnCtlRate = 0;        /* FEC_OC_IPR_INVERT register value */
-       u16 fecOcTmdMode = 0;
-       u16 fecOcTmdIntUpdRate = 0;
-       u32 maxBitRate = 0;
-       bool staticCLK = false;
-
-       dprintk(1, "\n");
-
-       /* Check insertion of the Reed-Solomon parity bytes */
-       status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
-       if (status < 0)
-               goto error;
-       status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
-       if (status < 0)
-               goto error;
-       fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
-       fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
-       if (state->m_insertRSByte == true) {
-               /* enable parity symbol forward */
-               fecOcRegMode |= FEC_OC_MODE_PARITY__M;
-               /* MVAL disable during parity bytes */
-               fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
-               /* TS burst length to 204 */
-               fecOcDtoBurstLen = 204;
-       }
-
-       /* Check serial or parrallel output */
-       fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
-       if (state->m_enableParallel == false) {
-               /* MPEG data output is serial -> set ipr_mode[0] */
-               fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
-       }
-
-       switch (oMode) {
-       case OM_DVBT:
-               maxBitRate = state->m_DVBTBitrate;
-               fecOcTmdMode = 3;
-               fecOcRcnCtlRate = 0xC00000;
-               staticCLK = state->m_DVBTStaticCLK;
-               break;
-       case OM_QAM_ITU_A:      /* fallthrough */
-       case OM_QAM_ITU_C:
-               fecOcTmdMode = 0x0004;
-               fecOcRcnCtlRate = 0xD2B4EE;     /* good for >63 Mb/s */
-               maxBitRate = state->m_DVBCBitrate;
-               staticCLK = state->m_DVBCStaticCLK;
-               break;
-       default:
-               status = -EINVAL;
-       }               /* switch (standard) */
-       if (status < 0)
-               goto error;
-
-       /* Configure DTO's */
-       if (staticCLK) {
-               u32 bitRate = 0;
-
-               /* Rational DTO for MCLK source (static MCLK rate),
-                       Dynamic DTO for optimal grouping
-                       (avoid intra-packet gaps),
-                       DTO offset enable to sync TS burst with MSTRT */
-               fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
-                               FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
-               fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
-                               FEC_OC_FCT_MODE_VIRT_ENA__M);
-
-               /* Check user defined bitrate */
-               bitRate = maxBitRate;
-               if (bitRate > 75900000UL) {     /* max is 75.9 Mb/s */
-                       bitRate = 75900000UL;
-               }
-               /* Rational DTO period:
-                       dto_period = (Fsys / bitrate) - 2
-
-                       Result should be floored,
-                       to make sure >= requested bitrate
-                       */
-               fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
-                                               * 1000) / bitRate);
-               if (fecOcDtoPeriod <= 2)
-                       fecOcDtoPeriod = 0;
-               else
-                       fecOcDtoPeriod -= 2;
-               fecOcTmdIntUpdRate = 8;
-       } else {
-               /* (commonAttr->staticCLK == false) => dynamic mode */
-               fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
-               fecOcFctMode = FEC_OC_FCT_MODE__PRE;
-               fecOcTmdIntUpdRate = 5;
-       }
-
-       /* Write appropriate registers with requested configuration */
-       status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
-       if (status < 0)
-               goto error;
-
-       /* Rate integration settings */
-       status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int MPEGTSConfigurePolarity(struct drxk_state *state)
-{
-       u16 fecOcRegIprInvert = 0;
-
-       /* Data mask for the output data byte */
-       u16 InvertDataMask =
-           FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
-           FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
-           FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
-           FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
-
-       dprintk(1, "\n");
-
-       /* Control selective inversion of output bits */
-       fecOcRegIprInvert &= (~(InvertDataMask));
-       if (state->m_invertDATA == true)
-               fecOcRegIprInvert |= InvertDataMask;
-       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
-       if (state->m_invertERR == true)
-               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
-       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
-       if (state->m_invertSTR == true)
-               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
-       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
-       if (state->m_invertVAL == true)
-               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
-       fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
-       if (state->m_invertCLK == true)
-               fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
-
-       return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
-}
-
-#define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
-
-static int SetAgcRf(struct drxk_state *state,
-                   struct SCfgAgc *pAgcCfg, bool isDTV)
-{
-       int status = -EINVAL;
-       u16 data = 0;
-       struct SCfgAgc *pIfAgcSettings;
-
-       dprintk(1, "\n");
-
-       if (pAgcCfg == NULL)
-               goto error;
-
-       switch (pAgcCfg->ctrlMode) {
-       case DRXK_AGC_CTRL_AUTO:
-               /* Enable RF AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-
-               /* Enable SCU RF AGC loop */
-               data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
-
-               /* Polarity */
-               if (state->m_RfAgcPol)
-                       data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
-               else
-                       data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Set speed (using complementary reduction value) */
-               status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
-               if (status < 0)
-                       goto error;
-
-               data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
-               data |= (~(pAgcCfg->speed <<
-                               SCU_RAM_AGC_KI_RED_RAGC_RED__B)
-                               & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
-
-               status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
-               if (status < 0)
-                       goto error;
-
-               if (IsDVBT(state))
-                       pIfAgcSettings = &state->m_dvbtIfAgcCfg;
-               else if (IsQAM(state))
-                       pIfAgcSettings = &state->m_qamIfAgcCfg;
-               else
-                       pIfAgcSettings = &state->m_atvIfAgcCfg;
-               if (pIfAgcSettings == NULL) {
-                       status = -EINVAL;
-                       goto error;
-               }
-
-               /* Set TOP, only if IF-AGC is in AUTO mode */
-               if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
-                       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
-                       if (status < 0)
-                               goto error;
-
-               /* Cut-Off current */
-               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
-               if (status < 0)
-                       goto error;
-
-               /* Max. output level */
-               status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
-               if (status < 0)
-                       goto error;
-
-               break;
-
-       case DRXK_AGC_CTRL_USER:
-               /* Enable RF AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Disable SCU RF AGC loop */
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-               data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
-               if (state->m_RfAgcPol)
-                       data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
-               else
-                       data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* SCU c.o.c. to 0, enabling full control range */
-               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
-               if (status < 0)
-                       goto error;
-
-               /* Write value to output pin */
-               status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
-               if (status < 0)
-                       goto error;
-               break;
-
-       case DRXK_AGC_CTRL_OFF:
-               /* Disable RF AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Disable SCU RF AGC loop */
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-               data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-               break;
-
-       default:
-               status = -EINVAL;
-
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
-
-static int SetAgcIf(struct drxk_state *state,
-                   struct SCfgAgc *pAgcCfg, bool isDTV)
-{
-       u16 data = 0;
-       int status = 0;
-       struct SCfgAgc *pRfAgcSettings;
-
-       dprintk(1, "\n");
-
-       switch (pAgcCfg->ctrlMode) {
-       case DRXK_AGC_CTRL_AUTO:
-
-               /* Enable IF AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-
-               /* Enable SCU IF AGC loop */
-               data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
-
-               /* Polarity */
-               if (state->m_IfAgcPol)
-                       data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
-               else
-                       data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Set speed (using complementary reduction value) */
-               status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
-               if (status < 0)
-                       goto error;
-               data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
-               data |= (~(pAgcCfg->speed <<
-                               SCU_RAM_AGC_KI_RED_IAGC_RED__B)
-                               & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
-
-               status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
-               if (status < 0)
-                       goto error;
-
-               if (IsQAM(state))
-                       pRfAgcSettings = &state->m_qamRfAgcCfg;
-               else
-                       pRfAgcSettings = &state->m_atvRfAgcCfg;
-               if (pRfAgcSettings == NULL)
-                       return -1;
-               /* Restore TOP */
-               status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
-               if (status < 0)
-                       goto error;
-               break;
-
-       case DRXK_AGC_CTRL_USER:
-
-               /* Enable IF AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-
-               /* Disable SCU IF AGC loop */
-               data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
-
-               /* Polarity */
-               if (state->m_IfAgcPol)
-                       data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
-               else
-                       data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Write value to output pin */
-               status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
-               if (status < 0)
-                       goto error;
-               break;
-
-       case DRXK_AGC_CTRL_OFF:
-
-               /* Disable If AGC DAC */
-               status = read16(state, IQM_AF_STDBY__A, &data);
-               if (status < 0)
-                       goto error;
-               data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
-               status = write16(state, IQM_AF_STDBY__A, data);
-               if (status < 0)
-                       goto error;
-
-               /* Disable SCU IF AGC loop */
-               status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
-               if (status < 0)
-                       goto error;
-               data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
-               status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
-               if (status < 0)
-                       goto error;
-               break;
-       }               /* switch (agcSettingsIf->ctrlMode) */
-
-       /* always set the top to support
-               configurations without if-loop */
-       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
-{
-       u16 agcDacLvl;
-       int status;
-       u16 Level = 0;
-
-       dprintk(1, "\n");
-
-       status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
-       if (status < 0) {
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-               return status;
-       }
-
-       *pValue = 0;
-
-       if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
-               Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
-       if (Level < 14000)
-               *pValue = (14000 - Level) / 4;
-       else
-               *pValue = 0;
-
-       return status;
-}
-
-static int GetQAMSignalToNoise(struct drxk_state *state,
-                              s32 *pSignalToNoise)
-{
-       int status = 0;
-       u16 qamSlErrPower = 0;  /* accum. error between
-                                       raw and sliced symbols */
-       u32 qamSlSigPower = 0;  /* used for MER, depends of
-                                       QAM modulation */
-       u32 qamSlMer = 0;       /* QAM MER */
-
-       dprintk(1, "\n");
-
-       /* MER calculation */
-
-       /* get the register value needed for MER */
-       status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
-       if (status < 0) {
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-               return -EINVAL;
-       }
-
-       switch (state->props.modulation) {
-       case QAM_16:
-               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
-               break;
-       case QAM_32:
-               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
-               break;
-       case QAM_64:
-               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
-               break;
-       case QAM_128:
-               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
-               break;
-       default:
-       case QAM_256:
-               qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
-               break;
-       }
-
-       if (qamSlErrPower > 0) {
-               qamSlMer = Log10Times100(qamSlSigPower) -
-                       Log10Times100((u32) qamSlErrPower);
-       }
-       *pSignalToNoise = qamSlMer;
-
-       return status;
-}
-
-static int GetDVBTSignalToNoise(struct drxk_state *state,
-                               s32 *pSignalToNoise)
-{
-       int status;
-       u16 regData = 0;
-       u32 EqRegTdSqrErrI = 0;
-       u32 EqRegTdSqrErrQ = 0;
-       u16 EqRegTdSqrErrExp = 0;
-       u16 EqRegTdTpsPwrOfs = 0;
-       u16 EqRegTdReqSmbCnt = 0;
-       u32 tpsCnt = 0;
-       u32 SqrErrIQ = 0;
-       u32 a = 0;
-       u32 b = 0;
-       u32 c = 0;
-       u32 iMER = 0;
-       u16 transmissionParams = 0;
-
-       dprintk(1, "\n");
-
-       status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
-       if (status < 0)
-               goto error;
-       status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
-       if (status < 0)
-               goto error;
-       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
-       if (status < 0)
-               goto error;
-       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
-       if (status < 0)
-               goto error;
-       /* Extend SQR_ERR_I operational range */
-       EqRegTdSqrErrI = (u32) regData;
-       if ((EqRegTdSqrErrExp > 11) &&
-               (EqRegTdSqrErrI < 0x00000FFFUL)) {
-               EqRegTdSqrErrI += 0x00010000UL;
-       }
-       status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
-       if (status < 0)
-               goto error;
-       /* Extend SQR_ERR_Q operational range */
-       EqRegTdSqrErrQ = (u32) regData;
-       if ((EqRegTdSqrErrExp > 11) &&
-               (EqRegTdSqrErrQ < 0x00000FFFUL))
-               EqRegTdSqrErrQ += 0x00010000UL;
-
-       status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
-       if (status < 0)
-               goto error;
-
-       /* Check input data for MER */
-
-       /* MER calculation (in 0.1 dB) without math.h */
-       if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
-               iMER = 0;
-       else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
-               /* No error at all, this must be the HW reset value
-                       * Apparently no first measurement yet
-                       * Set MER to 0.0 */
-               iMER = 0;
-       } else {
-               SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
-                       EqRegTdSqrErrExp;
-               if ((transmissionParams &
-                       OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
-                       == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
-                       tpsCnt = 17;
-               else
-                       tpsCnt = 68;
-
-               /* IMER = 100 * log10 (x)
-                       where x = (EqRegTdTpsPwrOfs^2 *
-                       EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
-
-                       => IMER = a + b -c
-                       where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
-                       b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
-                       c = 100 * log10 (SqrErrIQ)
-                       */
-
-               /* log(x) x = 9bits * 9bits->18 bits  */
-               a = Log10Times100(EqRegTdTpsPwrOfs *
-                                       EqRegTdTpsPwrOfs);
-               /* log(x) x = 16bits * 7bits->23 bits  */
-               b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
-               /* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
-               c = Log10Times100(SqrErrIQ);
-
-               iMER = a + b;
-               /* No negative MER, clip to zero */
-               if (iMER > c)
-                       iMER -= c;
-               else
-                       iMER = 0;
-       }
-       *pSignalToNoise = iMER;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
-{
-       dprintk(1, "\n");
-
-       *pSignalToNoise = 0;
-       switch (state->m_OperationMode) {
-       case OM_DVBT:
-               return GetDVBTSignalToNoise(state, pSignalToNoise);
-       case OM_QAM_ITU_A:
-       case OM_QAM_ITU_C:
-               return GetQAMSignalToNoise(state, pSignalToNoise);
-       default:
-               break;
-       }
-       return 0;
-}
-
-#if 0
-static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
-{
-       /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
-       int status = 0;
-
-       dprintk(1, "\n");
-
-       static s32 QE_SN[] = {
-               51,             /* QPSK 1/2 */
-               69,             /* QPSK 2/3 */
-               79,             /* QPSK 3/4 */
-               89,             /* QPSK 5/6 */
-               97,             /* QPSK 7/8 */
-               108,            /* 16-QAM 1/2 */
-               131,            /* 16-QAM 2/3 */
-               146,            /* 16-QAM 3/4 */
-               156,            /* 16-QAM 5/6 */
-               160,            /* 16-QAM 7/8 */
-               165,            /* 64-QAM 1/2 */
-               187,            /* 64-QAM 2/3 */
-               202,            /* 64-QAM 3/4 */
-               216,            /* 64-QAM 5/6 */
-               225,            /* 64-QAM 7/8 */
-       };
-
-       *pQuality = 0;
-
-       do {
-               s32 SignalToNoise = 0;
-               u16 Constellation = 0;
-               u16 CodeRate = 0;
-               u32 SignalToNoiseRel;
-               u32 BERQuality;
-
-               status = GetDVBTSignalToNoise(state, &SignalToNoise);
-               if (status < 0)
-                       break;
-               status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
-               if (status < 0)
-                       break;
-               Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
-
-               status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
-               if (status < 0)
-                       break;
-               CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
-
-               if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
-                   CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
-                       break;
-               SignalToNoiseRel = SignalToNoise -
-                   QE_SN[Constellation * 5 + CodeRate];
-               BERQuality = 100;
-
-               if (SignalToNoiseRel < -70)
-                       *pQuality = 0;
-               else if (SignalToNoiseRel < 30)
-                       *pQuality = ((SignalToNoiseRel + 70) *
-                                    BERQuality) / 100;
-               else
-                       *pQuality = BERQuality;
-       } while (0);
-       return 0;
-};
-
-static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
-{
-       int status = 0;
-       *pQuality = 0;
-
-       dprintk(1, "\n");
-
-       do {
-               u32 SignalToNoise = 0;
-               u32 BERQuality = 100;
-               u32 SignalToNoiseRel = 0;
-
-               status = GetQAMSignalToNoise(state, &SignalToNoise);
-               if (status < 0)
-                       break;
-
-               switch (state->props.modulation) {
-               case QAM_16:
-                       SignalToNoiseRel = SignalToNoise - 200;
-                       break;
-               case QAM_32:
-                       SignalToNoiseRel = SignalToNoise - 230;
-                       break;  /* Not in NorDig */
-               case QAM_64:
-                       SignalToNoiseRel = SignalToNoise - 260;
-                       break;
-               case QAM_128:
-                       SignalToNoiseRel = SignalToNoise - 290;
-                       break;
-               default:
-               case QAM_256:
-                       SignalToNoiseRel = SignalToNoise - 320;
-                       break;
-               }
-
-               if (SignalToNoiseRel < -70)
-                       *pQuality = 0;
-               else if (SignalToNoiseRel < 30)
-                       *pQuality = ((SignalToNoiseRel + 70) *
-                                    BERQuality) / 100;
-               else
-                       *pQuality = BERQuality;
-       } while (0);
-
-       return status;
-}
-
-static int GetQuality(struct drxk_state *state, s32 *pQuality)
-{
-       dprintk(1, "\n");
-
-       switch (state->m_OperationMode) {
-       case OM_DVBT:
-               return GetDVBTQuality(state, pQuality);
-       case OM_QAM_ITU_A:
-               return GetDVBCQuality(state, pQuality);
-       default:
-               break;
-       }
-
-       return 0;
-}
-#endif
-
-/* Free data ram in SIO HI */
-#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
-#define SIO_HI_RA_RAM_USR_END__A   0x420060
-
-#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
-#define DRXK_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
-#define DRXK_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
-#define DRXK_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
-
-#define DRXDAP_FASI_ADDR2BLOCK(addr)  (((addr) >> 22) & 0x3F)
-#define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
-#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
-
-static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
-{
-       int status = -EINVAL;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return 0;
-       if (state->m_DrxkState == DRXK_POWERED_DOWN)
-               goto error;
-
-       if (state->no_i2c_bridge)
-               return 0;
-
-       status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
-       if (status < 0)
-               goto error;
-       if (bEnableBridge) {
-               status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
-               if (status < 0)
-                       goto error;
-       } else {
-               status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
-               if (status < 0)
-                       goto error;
-       }
-
-       status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SetPreSaw(struct drxk_state *state,
-                    struct SCfgPreSaw *pPreSawCfg)
-{
-       int status = -EINVAL;
-
-       dprintk(1, "\n");
-
-       if ((pPreSawCfg == NULL)
-           || (pPreSawCfg->reference > IQM_AF_PDREF__M))
-               goto error;
-
-       status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
-                      u16 romOffset, u16 nrOfElements, u32 timeOut)
-{
-       u16 blStatus = 0;
-       u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
-       u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
-       int status;
-       unsigned long end;
-
-       dprintk(1, "\n");
-
-       mutex_lock(&state->mutex);
-       status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_TGT_ADDR__A, offset);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
-       if (status < 0)
-               goto error;
-
-       end = jiffies + msecs_to_jiffies(timeOut);
-       do {
-               status = read16(state, SIO_BL_STATUS__A, &blStatus);
-               if (status < 0)
-                       goto error;
-       } while ((blStatus == 0x1) && time_is_after_jiffies(end));
-       if (blStatus == 0x1) {
-               printk(KERN_ERR "drxk: SIO not ready\n");
-               status = -EINVAL;
-               goto error2;
-       }
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-error2:
-       mutex_unlock(&state->mutex);
-       return status;
-
-}
-
-static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
-{
-       u16 data = 0;
-       int status;
-
-       dprintk(1, "\n");
-
-       /* Start measurement */
-       status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_START_LOCK__A, 1);
-       if (status < 0)
-               goto error;
-
-       *count = 0;
-       status = read16(state, IQM_AF_PHASE0__A, &data);
-       if (status < 0)
-               goto error;
-       if (data == 127)
-               *count = *count + 1;
-       status = read16(state, IQM_AF_PHASE1__A, &data);
-       if (status < 0)
-               goto error;
-       if (data == 127)
-               *count = *count + 1;
-       status = read16(state, IQM_AF_PHASE2__A, &data);
-       if (status < 0)
-               goto error;
-       if (data == 127)
-               *count = *count + 1;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int ADCSynchronization(struct drxk_state *state)
-{
-       u16 count = 0;
-       int status;
-
-       dprintk(1, "\n");
-
-       status = ADCSyncMeasurement(state, &count);
-       if (status < 0)
-               goto error;
-
-       if (count == 1) {
-               /* Try sampling on a diffrent edge */
-               u16 clkNeg = 0;
-
-               status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
-               if (status < 0)
-                       goto error;
-               if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
-                       IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
-                       clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-                       clkNeg |=
-                               IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
-               } else {
-                       clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-                       clkNeg |=
-                               IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
-               }
-               status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
-               if (status < 0)
-                       goto error;
-               status = ADCSyncMeasurement(state, &count);
-               if (status < 0)
-                       goto error;
-       }
-
-       if (count < 2)
-               status = -EINVAL;
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SetFrequencyShifter(struct drxk_state *state,
-                              u16 intermediateFreqkHz,
-                              s32 tunerFreqOffset, bool isDTV)
-{
-       bool selectPosImage = false;
-       u32 rfFreqResidual = tunerFreqOffset;
-       u32 fmFrequencyShift = 0;
-       bool tunerMirror = !state->m_bMirrorFreqSpect;
-       u32 adcFreq;
-       bool adcFlip;
-       int status;
-       u32 ifFreqActual;
-       u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
-       u32 frequencyShift;
-       bool imageToSelect;
-
-       dprintk(1, "\n");
-
-       /*
-          Program frequency shifter
-          No need to account for mirroring on RF
-        */
-       if (isDTV) {
-               if ((state->m_OperationMode == OM_QAM_ITU_A) ||
-                   (state->m_OperationMode == OM_QAM_ITU_C) ||
-                   (state->m_OperationMode == OM_DVBT))
-                       selectPosImage = true;
-               else
-                       selectPosImage = false;
-       }
-       if (tunerMirror)
-               /* tuner doesn't mirror */
-               ifFreqActual = intermediateFreqkHz +
-                   rfFreqResidual + fmFrequencyShift;
-       else
-               /* tuner mirrors */
-               ifFreqActual = intermediateFreqkHz -
-                   rfFreqResidual - fmFrequencyShift;
-       if (ifFreqActual > samplingFrequency / 2) {
-               /* adc mirrors */
-               adcFreq = samplingFrequency - ifFreqActual;
-               adcFlip = true;
-       } else {
-               /* adc doesn't mirror */
-               adcFreq = ifFreqActual;
-               adcFlip = false;
-       }
-
-       frequencyShift = adcFreq;
-       imageToSelect = state->m_rfmirror ^ tunerMirror ^
-           adcFlip ^ selectPosImage;
-       state->m_IqmFsRateOfs =
-           Frac28a((frequencyShift), samplingFrequency);
-
-       if (imageToSelect)
-               state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
-
-       /* Program frequency shifter with tuner offset compensation */
-       /* frequencyShift += tunerFreqOffset; TODO */
-       status = write32(state, IQM_FS_RATE_OFS_LO__A,
-                        state->m_IqmFsRateOfs);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int InitAGC(struct drxk_state *state, bool isDTV)
-{
-       u16 ingainTgt = 0;
-       u16 ingainTgtMin = 0;
-       u16 ingainTgtMax = 0;
-       u16 clpCyclen = 0;
-       u16 clpSumMin = 0;
-       u16 clpDirTo = 0;
-       u16 snsSumMin = 0;
-       u16 snsSumMax = 0;
-       u16 clpSumMax = 0;
-       u16 snsDirTo = 0;
-       u16 kiInnergainMin = 0;
-       u16 ifIaccuHiTgt = 0;
-       u16 ifIaccuHiTgtMin = 0;
-       u16 ifIaccuHiTgtMax = 0;
-       u16 data = 0;
-       u16 fastClpCtrlDelay = 0;
-       u16 clpCtrlMode = 0;
-       int status = 0;
-
-       dprintk(1, "\n");
-
-       /* Common settings */
-       snsSumMax = 1023;
-       ifIaccuHiTgtMin = 2047;
-       clpCyclen = 500;
-       clpSumMax = 1023;
-
-       /* AGCInit() not available for DVBT; init done in microcode */
-       if (!IsQAM(state)) {
-               printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
-               return -EINVAL;
-       }
-
-       /* FIXME: Analog TV AGC require different settings */
-
-       /* Standard specific settings */
-       clpSumMin = 8;
-       clpDirTo = (u16) -9;
-       clpCtrlMode = 0;
-       snsSumMin = 8;
-       snsDirTo = (u16) -9;
-       kiInnergainMin = (u16) -1030;
-       ifIaccuHiTgtMax = 0x2380;
-       ifIaccuHiTgt = 0x2380;
-       ingainTgtMin = 0x0511;
-       ingainTgt = 0x0511;
-       ingainTgtMax = 5119;
-       fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
-
-       status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
-       if (status < 0)
-               goto error;
-
-       /* Initialize inner-loop KI gain factors */
-       status = read16(state, SCU_RAM_AGC_KI__A, &data);
-       if (status < 0)
-               goto error;
-
-       data = 0x0657;
-       data &= ~SCU_RAM_AGC_KI_RF__M;
-       data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
-       data &= ~SCU_RAM_AGC_KI_IF__M;
-       data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
-
-       status = write16(state, SCU_RAM_AGC_KI__A, data);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
-{
-       int status;
-
-       dprintk(1, "\n");
-       if (packetErr == NULL)
-               status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
-       else
-               status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int DVBTScCommand(struct drxk_state *state,
-                        u16 cmd, u16 subcmd,
-                        u16 param0, u16 param1, u16 param2,
-                        u16 param3, u16 param4)
-{
-       u16 curCmd = 0;
-       u16 errCode = 0;
-       u16 retryCnt = 0;
-       u16 scExec = 0;
-       int status;
-
-       dprintk(1, "\n");
-       status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
-       if (scExec != 1) {
-               /* SC is not running */
-               status = -EINVAL;
-       }
-       if (status < 0)
-               goto error;
-
-       /* Wait until sc is ready to receive command */
-       retryCnt = 0;
-       do {
-               msleep(1);
-               status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-               retryCnt++;
-       } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-       if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
-               goto error;
-
-       /* Write sub-command */
-       switch (cmd) {
-               /* All commands using sub-cmd */
-       case OFDM_SC_RA_RAM_CMD_PROC_START:
-       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
-       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
-               status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
-               if (status < 0)
-                       goto error;
-               break;
-       default:
-               /* Do nothing */
-               break;
-       }
-
-       /* Write needed parameters and the command */
-       switch (cmd) {
-               /* All commands using 5 parameters */
-               /* All commands using 4 parameters */
-               /* All commands using 3 parameters */
-               /* All commands using 2 parameters */
-       case OFDM_SC_RA_RAM_CMD_PROC_START:
-       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
-       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
-               status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
-               /* All commands using 1 parameters */
-       case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
-       case OFDM_SC_RA_RAM_CMD_USER_IO:
-               status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
-               /* All commands using 0 parameters */
-       case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
-       case OFDM_SC_RA_RAM_CMD_NULL:
-               /* Write command */
-               status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
-               break;
-       default:
-               /* Unknown command */
-               status = -EINVAL;
-       }
-       if (status < 0)
-               goto error;
-
-       /* Wait until sc is ready processing command */
-       retryCnt = 0;
-       do {
-               msleep(1);
-               status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-               retryCnt++;
-       } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-       if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
-               goto error;
-
-       /* Check for illegal cmd */
-       status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
-       if (errCode == 0xFFFF) {
-               /* illegal command */
-               status = -EINVAL;
-       }
-       if (status < 0)
-               goto error;
-
-       /* Retreive results parameters from SC */
-       switch (cmd) {
-               /* All commands yielding 5 results */
-               /* All commands yielding 4 results */
-               /* All commands yielding 3 results */
-               /* All commands yielding 2 results */
-               /* All commands yielding 1 result */
-       case OFDM_SC_RA_RAM_CMD_USER_IO:
-       case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
-               status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
-               /* All commands yielding 0 results */
-       case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
-       case OFDM_SC_RA_RAM_CMD_SET_TIMER:
-       case OFDM_SC_RA_RAM_CMD_PROC_START:
-       case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
-       case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
-       case OFDM_SC_RA_RAM_CMD_NULL:
-               break;
-       default:
-               /* Unknown command */
-               status = -EINVAL;
-               break;
-       }                       /* switch (cmd->cmd) */
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int PowerUpDVBT(struct drxk_state *state)
-{
-       enum DRXPowerMode powerMode = DRX_POWER_UP;
-       int status;
-
-       dprintk(1, "\n");
-       status = CtrlPowerMode(state, &powerMode);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
-{
-       int status;
-
-       dprintk(1, "\n");
-       if (*enabled == true)
-               status = write16(state, IQM_CF_BYPASSDET__A, 0);
-       else
-               status = write16(state, IQM_CF_BYPASSDET__A, 1);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-#define DEFAULT_FR_THRES_8K     4000
-static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
-{
-
-       int status;
-
-       dprintk(1, "\n");
-       if (*enabled == true) {
-               /* write mask to 1 */
-               status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
-                                  DEFAULT_FR_THRES_8K);
-       } else {
-               /* write mask to 0 */
-               status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
-       }
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
-                                   struct DRXKCfgDvbtEchoThres_t *echoThres)
-{
-       u16 data = 0;
-       int status;
-
-       dprintk(1, "\n");
-       status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
-       if (status < 0)
-               goto error;
-
-       switch (echoThres->fftMode) {
-       case DRX_FFTMODE_2K:
-               data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
-               data |= ((echoThres->threshold <<
-                       OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
-                       & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
-               break;
-       case DRX_FFTMODE_8K:
-               data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
-               data |= ((echoThres->threshold <<
-                       OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
-                       & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
-                              enum DRXKCfgDvbtSqiSpeed *speed)
-{
-       int status = -EINVAL;
-
-       dprintk(1, "\n");
-
-       switch (*speed) {
-       case DRXK_DVBT_SQI_SPEED_FAST:
-       case DRXK_DVBT_SQI_SPEED_MEDIUM:
-       case DRXK_DVBT_SQI_SPEED_SLOW:
-               break;
-       default:
-               goto error;
-       }
-       status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
-                          (u16) *speed);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief Activate DVBT specific presets
-* \param demod instance of demodulator.
-* \return DRXStatus_t.
-*
-* Called in DVBTSetStandard
-*
-*/
-static int DVBTActivatePresets(struct drxk_state *state)
-{
-       int status;
-       bool setincenable = false;
-       bool setfrenable = true;
-
-       struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
-       struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
-
-       dprintk(1, "\n");
-       status = DVBTCtrlSetIncEnable(state, &setincenable);
-       if (status < 0)
-               goto error;
-       status = DVBTCtrlSetFrEnable(state, &setfrenable);
-       if (status < 0)
-               goto error;
-       status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
-       if (status < 0)
-               goto error;
-       status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief Initialize channelswitch-independent settings for DVBT.
-* \param demod instance of demodulator.
-* \return DRXStatus_t.
-*
-* For ROM code channel filter taps are loaded from the bootloader. For microcode
-* the DVB-T taps from the drxk_filters.h are used.
-*/
-static int SetDVBTStandard(struct drxk_state *state,
-                          enum OperationMode oMode)
-{
-       u16 cmdResult = 0;
-       u16 data = 0;
-       int status;
-
-       dprintk(1, "\n");
-
-       PowerUpDVBT(state);
-       /* added antenna switch */
-       SwitchAntennaToDVBT(state);
-       /* send OFDM reset command */
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
-       if (status < 0)
-               goto error;
-
-       /* send OFDM setenv command */
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
-       if (status < 0)
-               goto error;
-
-       /* reset datapath for OFDM, processors first */
-       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
-       if (status < 0)
-               goto error;
-
-       /* IQM setup */
-       /* synchronize on ofdstate->m_festart */
-       status = write16(state, IQM_AF_UPD_SEL__A, 1);
-       if (status < 0)
-               goto error;
-       /* window size for clipping ADC detection */
-       status = write16(state, IQM_AF_CLP_LEN__A, 0);
-       if (status < 0)
-               goto error;
-       /* window size for for sense pre-SAW detection */
-       status = write16(state, IQM_AF_SNS_LEN__A, 0);
-       if (status < 0)
-               goto error;
-       /* sense threshold for sense pre-SAW detection */
-       status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
-       if (status < 0)
-               goto error;
-       status = SetIqmAf(state, true);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_AF_AGC_RF__A, 0);
-       if (status < 0)
-               goto error;
-
-       /* Impulse noise cruncher setup */
-       status = write16(state, IQM_AF_INC_LCT__A, 0);  /* crunch in IQM_CF */
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_DET_LCT__A, 0);  /* detect in IQM_CF */
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_WND_LEN__A, 3);  /* peak detector window length */
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_RC_STRETCH__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_OUT_ENA__A, 0x4);        /* enable output 2 */
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_SCALE__A, 1600);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_SCALE_SH__A, 0);
-       if (status < 0)
-               goto error;
-
-       /* virtual clipping threshold for clipping ADC detection */
-       status = write16(state, IQM_AF_CLP_TH__A, 448);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
-       if (status < 0)
-               goto error;
-
-       status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_CF_PKDTH__A, 2);    /* peak detector threshold */
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
-       if (status < 0)
-               goto error;
-       /* enable power measurement interrupt */
-       status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
-       if (status < 0)
-               goto error;
-
-       /* IQM will not be reset from here, sync ADC and update/init AGC */
-       status = ADCSynchronization(state);
-       if (status < 0)
-               goto error;
-       status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
-       if (status < 0)
-               goto error;
-
-       /* Halt SCU to enable safe non-atomic accesses */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
-       if (status < 0)
-               goto error;
-
-       status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
-       if (status < 0)
-               goto error;
-       status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
-       if (status < 0)
-               goto error;
-
-       /* Set Noise Estimation notch width and enable DC fix */
-       status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
-       if (status < 0)
-               goto error;
-       data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
-       status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
-       if (status < 0)
-               goto error;
-
-       /* Activate SCU to enable SCU commands */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-
-       if (!state->m_DRXK_A3_ROM_CODE) {
-               /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay  */
-               status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
-               if (status < 0)
-                       goto error;
-       }
-
-       /* OFDM_SC setup */
-#ifdef COMPILE_FOR_NONRT
-       status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
-       if (status < 0)
-               goto error;
-#endif
-
-       /* FEC setup */
-       status = write16(state, FEC_DI_INPUT_CTL__A, 1);        /* OFDM input */
-       if (status < 0)
-               goto error;
-
-
-#ifdef COMPILE_FOR_NONRT
-       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
-       if (status < 0)
-               goto error;
-#else
-       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
-       if (status < 0)
-               goto error;
-#endif
-       status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
-       if (status < 0)
-               goto error;
-
-       /* Setup MPEG bus */
-       status = MPEGTSDtoSetup(state, OM_DVBT);
-       if (status < 0)
-               goto error;
-       /* Set DVBT Presets */
-       status = DVBTActivatePresets(state);
-       if (status < 0)
-               goto error;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-/**
-* \brief Start dvbt demodulating for channel.
-* \param demod instance of demodulator.
-* \return DRXStatus_t.
-*/
-static int DVBTStart(struct drxk_state *state)
-{
-       u16 param1;
-       int status;
-       /* DRXKOfdmScCmd_t scCmd; */
-
-       dprintk(1, "\n");
-       /* Start correct processes to get in lock */
-       /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
-       param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
-       status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
-       if (status < 0)
-               goto error;
-       /* Start FEC OC */
-       status = MPEGTSStart(state);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-
-/*============================================================================*/
-
-/**
-* \brief Set up dvbt demodulator for channel.
-* \param demod instance of demodulator.
-* \return DRXStatus_t.
-* // original DVBTSetChannel()
-*/
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-                  s32 tunerFreqOffset)
-{
-       u16 cmdResult = 0;
-       u16 transmissionParams = 0;
-       u16 operationMode = 0;
-       u32 iqmRcRateOfs = 0;
-       u32 bandwidth = 0;
-       u16 param1;
-       int status;
-
-       dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
-
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
-       if (status < 0)
-               goto error;
-
-       /* Halt SCU to enable safe non-atomic accesses */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
-       if (status < 0)
-               goto error;
-
-       /* Stop processors */
-       status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-
-       /* Mandatory fix, always stop CP, required to set spl offset back to
-               hardware default (is set to 0 by ucode during pilot detection */
-       status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-
-       /*== Write channel settings to device =====================================*/
-
-       /* mode */
-       switch (state->props.transmission_mode) {
-       case TRANSMISSION_MODE_AUTO:
-       default:
-               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
-               /* fall through , try first guess DRX_FFTMODE_8K */
-       case TRANSMISSION_MODE_8K:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
-               break;
-       case TRANSMISSION_MODE_2K:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
-               break;
-       }
-
-       /* guard */
-       switch (state->props.guard_interval) {
-       default:
-       case GUARD_INTERVAL_AUTO:
-               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
-               /* fall through , try first guess DRX_GUARD_1DIV4 */
-       case GUARD_INTERVAL_1_4:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
-               break;
-       case GUARD_INTERVAL_1_32:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
-               break;
-       case GUARD_INTERVAL_1_16:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
-               break;
-       case GUARD_INTERVAL_1_8:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
-               break;
-       }
-
-       /* hierarchy */
-       switch (state->props.hierarchy) {
-       case HIERARCHY_AUTO:
-       case HIERARCHY_NONE:
-       default:
-               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
-               /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
-               /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
-               /* break; */
-       case HIERARCHY_1:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
-               break;
-       case HIERARCHY_2:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
-               break;
-       case HIERARCHY_4:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
-               break;
-       }
-
-
-       /* modulation */
-       switch (state->props.modulation) {
-       case QAM_AUTO:
-       default:
-               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
-               /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
-       case QAM_64:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
-               break;
-       case QPSK:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
-               break;
-       case QAM_16:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
-               break;
-       }
-#if 0
-       /* No hierachical channels support in BDA */
-       /* Priority (only for hierarchical channels) */
-       switch (channel->priority) {
-       case DRX_PRIORITY_LOW:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
-               WR16(devAddr, OFDM_EC_SB_PRIOR__A,
-                       OFDM_EC_SB_PRIOR_LO);
-               break;
-       case DRX_PRIORITY_HIGH:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
-               WR16(devAddr, OFDM_EC_SB_PRIOR__A,
-                       OFDM_EC_SB_PRIOR_HI));
-               break;
-       case DRX_PRIORITY_UNKNOWN:      /* fall through */
-       default:
-               status = -EINVAL;
-               goto error;
-       }
-#else
-       /* Set Priorty high */
-       transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
-       status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
-       if (status < 0)
-               goto error;
-#endif
-
-       /* coderate */
-       switch (state->props.code_rate_HP) {
-       case FEC_AUTO:
-       default:
-               operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
-               /* fall through , try first guess DRX_CODERATE_2DIV3 */
-       case FEC_2_3:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
-               break;
-       case FEC_1_2:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
-               break;
-       case FEC_3_4:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
-               break;
-       case FEC_5_6:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
-               break;
-       case FEC_7_8:
-               transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
-               break;
-       }
-
-       /* SAW filter selection: normaly not necesarry, but if wanted
-               the application can select a SAW filter via the driver by using UIOs */
-       /* First determine real bandwidth (Hz) */
-       /* Also set delay for impulse noise cruncher */
-       /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
-               by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
-               functions */
-       switch (state->props.bandwidth_hz) {
-       case 0:
-               state->props.bandwidth_hz = 8000000;
-               /* fall though */
-       case 8000000:
-               bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
-               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
-               if (status < 0)
-                       goto error;
-               /* cochannel protection for PAL 8 MHz */
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
-               if (status < 0)
-                       goto error;
-               break;
-       case 7000000:
-               bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
-               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
-               if (status < 0)
-                       goto error;
-               /* cochannel protection for PAL 7 MHz */
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
-               if (status < 0)
-                       goto error;
-               break;
-       case 6000000:
-               bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
-               status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
-               if (status < 0)
-                       goto error;
-               /* cochannel protection for NTSC 6 MHz */
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
-               if (status < 0)
-                       goto error;
-               status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
-               if (status < 0)
-                       goto error;
-               break;
-       default:
-               status = -EINVAL;
-               goto error;
-       }
-
-       if (iqmRcRateOfs == 0) {
-               /* Now compute IQM_RC_RATE_OFS
-                       (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
-                       =>
-                       ((SysFreq / BandWidth) * (2^21)) - (2^23)
-                       */
-               /* (SysFreq / BandWidth) * (2^28)  */
-               /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
-                       => assert(MAX(sysClk) < 16*MIN(bandwidth))
-                       => assert(109714272 > 48000000) = true so Frac 28 can be used  */
-               iqmRcRateOfs = Frac28a((u32)
-                                       ((state->m_sysClockFreq *
-                                               1000) / 3), bandwidth);
-               /* (SysFreq / BandWidth) * (2^21), rounding before truncating  */
-               if ((iqmRcRateOfs & 0x7fL) >= 0x40)
-                       iqmRcRateOfs += 0x80L;
-               iqmRcRateOfs = iqmRcRateOfs >> 7;
-               /* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
-               iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
-       }
-
-       iqmRcRateOfs &=
-               ((((u32) IQM_RC_RATE_OFS_HI__M) <<
-               IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
-       status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
-       if (status < 0)
-               goto error;
-
-       /* Bandwidth setting done */
-
-#if 0
-       status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
-       if (status < 0)
-               goto error;
-#endif
-       status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
-       if (status < 0)
-               goto error;
-
-       /*== Start SC, write channel settings to SC ===============================*/
-
-       /* Activate SCU to enable SCU commands */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-
-       /* Enable SC after setting all other parameters */
-       status = write16(state, OFDM_SC_COMM_STATE__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
-       if (status < 0)
-               goto error;
-
-
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
-       if (status < 0)
-               goto error;
-
-       /* Write SC parameter registers, set all AUTO flags in operation mode */
-       param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
-                       OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
-                       OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
-                       OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
-                       OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
-       status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
-                               0, transmissionParams, param1, 0, 0, 0);
-       if (status < 0)
-               goto error;
-
-       if (!state->m_DRXK_A3_ROM_CODE)
-               status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-
-/*============================================================================*/
-
-/**
-* \brief Retreive lock status .
-* \param demod    Pointer to demodulator instance.
-* \param lockStat Pointer to lock status structure.
-* \return DRXStatus_t.
-*
-*/
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
-{
-       int status;
-       const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
-                                   OFDM_SC_RA_RAM_LOCK_FEC__M);
-       const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
-       const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
-
-       u16 ScRaRamLock = 0;
-       u16 ScCommExec = 0;
-
-       dprintk(1, "\n");
-
-       *pLockStatus = NOT_LOCKED;
-       /* driver 0.9.0 */
-       /* Check if SC is running */
-       status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
-       if (status < 0)
-               goto end;
-       if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
-               goto end;
-
-       status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
-       if (status < 0)
-               goto end;
-
-       if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
-               *pLockStatus = MPEG_LOCK;
-       else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
-               *pLockStatus = FEC_LOCK;
-       else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
-               *pLockStatus = DEMOD_LOCK;
-       else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
-               *pLockStatus = NEVER_LOCK;
-end:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int PowerUpQAM(struct drxk_state *state)
-{
-       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-       int status;
-
-       dprintk(1, "\n");
-       status = CtrlPowerMode(state, &powerMode);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-
-/** Power Down QAM */
-static int PowerDownQAM(struct drxk_state *state)
-{
-       u16 data = 0;
-       u16 cmdResult;
-       int status = 0;
-
-       dprintk(1, "\n");
-       status = read16(state, SCU_COMM_EXEC__A, &data);
-       if (status < 0)
-               goto error;
-       if (data == SCU_COMM_EXEC_ACTIVE) {
-               /*
-                       STOP demodulator
-                       QAM and HW blocks
-                       */
-               /* stop all comstate->m_exec */
-               status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
-               if (status < 0)
-                       goto error;
-               status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
-               if (status < 0)
-                       goto error;
-       }
-       /* powerdown AFE                   */
-       status = SetIqmAf(state, false);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief Setup of the QAM Measurement intervals for signal quality
-* \param demod instance of demod.
-* \param modulation current modulation.
-* \return DRXStatus_t.
-*
-*  NOTE:
-*  Take into account that for certain settings the errorcounters can overflow.
-*  The implementation does not check this.
-*
-*/
-static int SetQAMMeasurement(struct drxk_state *state,
-                            enum EDrxkConstellation modulation,
-                            u32 symbolRate)
-{
-       u32 fecBitsDesired = 0; /* BER accounting period */
-       u32 fecRsPeriodTotal = 0;       /* Total period */
-       u16 fecRsPrescale = 0;  /* ReedSolomon Measurement Prescale */
-       u16 fecRsPeriod = 0;    /* Value for corresponding I2C register */
-       int status = 0;
-
-       dprintk(1, "\n");
-
-       fecRsPrescale = 1;
-       /* fecBitsDesired = symbolRate [kHz] *
-               FrameLenght [ms] *
-               (modulation + 1) *
-               SyncLoss (== 1) *
-               ViterbiLoss (==1)
-               */
-       switch (modulation) {
-       case DRX_CONSTELLATION_QAM16:
-               fecBitsDesired = 4 * symbolRate;
-               break;
-       case DRX_CONSTELLATION_QAM32:
-               fecBitsDesired = 5 * symbolRate;
-               break;
-       case DRX_CONSTELLATION_QAM64:
-               fecBitsDesired = 6 * symbolRate;
-               break;
-       case DRX_CONSTELLATION_QAM128:
-               fecBitsDesired = 7 * symbolRate;
-               break;
-       case DRX_CONSTELLATION_QAM256:
-               fecBitsDesired = 8 * symbolRate;
-               break;
-       default:
-               status = -EINVAL;
-       }
-       if (status < 0)
-               goto error;
-
-       fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz]  */
-       fecBitsDesired *= 500;  /* meas. period [ms] */
-
-       /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
-       /* fecRsPeriodTotal = fecBitsDesired / 1632 */
-       fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1;       /* roughly ceil */
-
-       /* fecRsPeriodTotal =  fecRsPrescale * fecRsPeriod  */
-       fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
-       if (fecRsPrescale == 0) {
-               /* Divide by zero (though impossible) */
-               status = -EINVAL;
-               if (status < 0)
-                       goto error;
-       }
-       fecRsPeriod =
-               ((u16) fecRsPeriodTotal +
-               (fecRsPrescale >> 1)) / fecRsPrescale;
-
-       /* write corresponding registers */
-       status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SetQAM16(struct drxk_state *state)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-       /* QAM Equalizer Setup */
-       /* Equalizer */
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
-       if (status < 0)
-               goto error;
-       /* Decision Feedback Equalizer */
-       status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
-       if (status < 0)
-               goto error;
-
-       /* QAM Slicer Settings */
-       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
-       if (status < 0)
-               goto error;
-
-       /* QAM Loop Controller Coeficients */
-       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM State Machine (FSM) Thresholds */
-
-       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM FSM Tracking Parameters */
-
-       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
-       if (status < 0)
-               goto error;
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief QAM32 specific setup
-* \param demod instance of demod.
-* \return DRXStatus_t.
-*/
-static int SetQAM32(struct drxk_state *state)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-
-       /* QAM Equalizer Setup */
-       /* Equalizer */
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
-       if (status < 0)
-               goto error;
-
-       /* Decision Feedback Equalizer */
-       status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_SY_SYNC_HWM__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_AWM__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
-       if (status < 0)
-               goto error;
-
-       /* QAM Slicer Settings */
-
-       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM Loop Controller Coeficients */
-
-       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM State Machine (FSM) Thresholds */
-
-       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM FSM Tracking Parameters */
-
-       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief QAM64 specific setup
-* \param demod instance of demod.
-* \return DRXStatus_t.
-*/
-static int SetQAM64(struct drxk_state *state)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-       /* QAM Equalizer Setup */
-       /* Equalizer */
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
-       if (status < 0)
-               goto error;
-
-       /* Decision Feedback Equalizer */
-       status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
-       if (status < 0)
-               goto error;
-
-       /* QAM Slicer Settings */
-       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM Loop Controller Coeficients */
-
-       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM State Machine (FSM) Thresholds */
-
-       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM FSM Tracking Parameters */
-
-       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief QAM128 specific setup
-* \param demod: instance of demod.
-* \return DRXStatus_t.
-*/
-static int SetQAM128(struct drxk_state *state)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-       /* QAM Equalizer Setup */
-       /* Equalizer */
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
-       if (status < 0)
-               goto error;
-
-       /* Decision Feedback Equalizer */
-       status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_SY_SYNC_HWM__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_AWM__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM Slicer Settings */
-
-       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM Loop Controller Coeficients */
-
-       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM State Machine (FSM) Thresholds */
-
-       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
-       if (status < 0)
-               goto error;
-
-       /* QAM FSM Tracking Parameters */
-
-       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief QAM256 specific setup
-* \param demod: instance of demod.
-* \return DRXStatus_t.
-*/
-static int SetQAM256(struct drxk_state *state)
-{
-       int status = 0;
-
-       dprintk(1, "\n");
-       /* QAM Equalizer Setup */
-       /* Equalizer */
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
-       if (status < 0)
-               goto error;
-
-       /* Decision Feedback Equalizer */
-       status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_SY_SYNC_HWM__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_AWM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_SYNC_LWM__A, 3);
-       if (status < 0)
-               goto error;
-
-       /* QAM Slicer Settings */
-
-       status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM Loop Controller Coeficients */
-
-       status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM State Machine (FSM) Thresholds */
-
-       status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
-       if (status < 0)
-               goto error;
-
-
-       /* QAM FSM Tracking Parameters */
-
-       status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-
-/*============================================================================*/
-/**
-* \brief Reset QAM block.
-* \param demod:   instance of demod.
-* \param channel: pointer to channel data.
-* \return DRXStatus_t.
-*/
-static int QAMResetQAM(struct drxk_state *state)
-{
-       int status;
-       u16 cmdResult;
-
-       dprintk(1, "\n");
-       /* Stop QAM comstate->m_exec */
-       status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief Set QAM symbolrate.
-* \param demod:   instance of demod.
-* \param channel: pointer to channel data.
-* \return DRXStatus_t.
-*/
-static int QAMSetSymbolrate(struct drxk_state *state)
-{
-       u32 adcFrequency = 0;
-       u32 symbFreq = 0;
-       u32 iqmRcRate = 0;
-       u16 ratesel = 0;
-       u32 lcSymbRate = 0;
-       int status;
-
-       dprintk(1, "\n");
-       /* Select & calculate correct IQM rate */
-       adcFrequency = (state->m_sysClockFreq * 1000) / 3;
-       ratesel = 0;
-       /* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
-       if (state->props.symbol_rate <= 1188750)
-               ratesel = 3;
-       else if (state->props.symbol_rate <= 2377500)
-               ratesel = 2;
-       else if (state->props.symbol_rate <= 4755000)
-               ratesel = 1;
-       status = write16(state, IQM_FD_RATESEL__A, ratesel);
-       if (status < 0)
-               goto error;
-
-       /*
-               IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
-               */
-       symbFreq = state->props.symbol_rate * (1 << ratesel);
-       if (symbFreq == 0) {
-               /* Divide by zero */
-               status = -EINVAL;
-               goto error;
-       }
-       iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
-               (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
-               (1 << 23);
-       status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
-       if (status < 0)
-               goto error;
-       state->m_iqmRcRate = iqmRcRate;
-       /*
-               LcSymbFreq = round (.125 *  symbolrate / adcFreq * (1<<15))
-               */
-       symbFreq = state->props.symbol_rate;
-       if (adcFrequency == 0) {
-               /* Divide by zero */
-               status = -EINVAL;
-               goto error;
-       }
-       lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
-               (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
-               16);
-       if (lcSymbRate > 511)
-               lcSymbRate = 511;
-       status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-/*============================================================================*/
-
-/**
-* \brief Get QAM lock status.
-* \param demod:   instance of demod.
-* \param channel: pointer to channel data.
-* \return DRXStatus_t.
-*/
-
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
-{
-       int status;
-       u16 Result[2] = { 0, 0 };
-
-       dprintk(1, "\n");
-       *pLockStatus = NOT_LOCKED;
-       status = scu_command(state,
-                       SCU_RAM_COMMAND_STANDARD_QAM |
-                       SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
-                       Result);
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
-               /* 0x0000 NOT LOCKED */
-       } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
-               /* 0x4000 DEMOD LOCKED */
-               *pLockStatus = DEMOD_LOCK;
-       } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
-               /* 0x8000 DEMOD + FEC LOCKED (system lock) */
-               *pLockStatus = MPEG_LOCK;
-       } else {
-               /* 0xC000 NEVER LOCKED */
-               /* (system will never be able to lock to the signal) */
-               /* TODO: check this, intermediate & standard specific lock states are not
-                  taken into account here */
-               *pLockStatus = NEVER_LOCK;
-       }
-       return status;
-}
-
-#define QAM_MIRROR__M         0x03
-#define QAM_MIRROR_NORMAL     0x00
-#define QAM_MIRRORED          0x01
-#define QAM_MIRROR_AUTO_ON    0x02
-#define QAM_LOCKRANGE__M      0x10
-#define QAM_LOCKRANGE_NORMAL  0x10
-
-static int QAMDemodulatorCommand(struct drxk_state *state,
-                                int numberOfParameters)
-{
-       int status;
-       u16 cmdResult;
-       u16 setParamParameters[4] = { 0, 0, 0, 0 };
-
-       setParamParameters[0] = state->m_Constellation; /* modulation     */
-       setParamParameters[1] = DRXK_QAM_I12_J17;       /* interleave mode   */
-
-       if (numberOfParameters == 2) {
-               u16 setEnvParameters[1] = { 0 };
-
-               if (state->m_OperationMode == OM_QAM_ITU_C)
-                       setEnvParameters[0] = QAM_TOP_ANNEX_C;
-               else
-                       setEnvParameters[0] = QAM_TOP_ANNEX_A;
-
-               status = scu_command(state,
-                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
-                                    1, setEnvParameters, 1, &cmdResult);
-               if (status < 0)
-                       goto error;
-
-               status = scu_command(state,
-                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-                                    numberOfParameters, setParamParameters,
-                                    1, &cmdResult);
-       } else if (numberOfParameters == 4) {
-               if (state->m_OperationMode == OM_QAM_ITU_C)
-                       setParamParameters[2] = QAM_TOP_ANNEX_C;
-               else
-                       setParamParameters[2] = QAM_TOP_ANNEX_A;
-
-               setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
-               /* Env parameters */
-               /* check for LOCKRANGE Extented */
-               /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
-
-               status = scu_command(state,
-                                    SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-                                    numberOfParameters, setParamParameters,
-                                    1, &cmdResult);
-       } else {
-               printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
-                       "count %d\n", numberOfParameters);
-       }
-
-error:
-       if (status < 0)
-               printk(KERN_WARNING "drxk: Warning %d on %s\n",
-                      status, __func__);
-       return status;
-}
-
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-                 s32 tunerFreqOffset)
-{
-       int status;
-       u16 cmdResult;
-       int qamDemodParamCount = state->qam_demod_parameter_count;
-
-       dprintk(1, "\n");
-       /*
-        * STEP 1: reset demodulator
-        *      resets FEC DI and FEC RS
-        *      resets QAM block
-        *      resets SCU variables
-        */
-       status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
-       if (status < 0)
-               goto error;
-       status = QAMResetQAM(state);
-       if (status < 0)
-               goto error;
-
-       /*
-        * STEP 2: configure demodulator
-        *      -set params; resets IQM,QAM,FEC HW; initializes some
-        *       SCU variables
-        */
-       status = QAMSetSymbolrate(state);
-       if (status < 0)
-               goto error;
-
-       /* Set params */
-       switch (state->props.modulation) {
-       case QAM_256:
-               state->m_Constellation = DRX_CONSTELLATION_QAM256;
-               break;
-       case QAM_AUTO:
-       case QAM_64:
-               state->m_Constellation = DRX_CONSTELLATION_QAM64;
-               break;
-       case QAM_16:
-               state->m_Constellation = DRX_CONSTELLATION_QAM16;
-               break;
-       case QAM_32:
-               state->m_Constellation = DRX_CONSTELLATION_QAM32;
-               break;
-       case QAM_128:
-               state->m_Constellation = DRX_CONSTELLATION_QAM128;
-               break;
-       default:
-               status = -EINVAL;
-               break;
-       }
-       if (status < 0)
-               goto error;
-
-       /* Use the 4-parameter if it's requested or we're probing for
-        * the correct command. */
-       if (state->qam_demod_parameter_count == 4
-               || !state->qam_demod_parameter_count) {
-               qamDemodParamCount = 4;
-               status = QAMDemodulatorCommand(state, qamDemodParamCount);
-       }
-
-       /* Use the 2-parameter command if it was requested or if we're
-        * probing for the correct command and the 4-parameter command
-        * failed. */
-       if (state->qam_demod_parameter_count == 2
-               || (!state->qam_demod_parameter_count && status < 0)) {
-               qamDemodParamCount = 2;
-               status = QAMDemodulatorCommand(state, qamDemodParamCount);
-       }
-
-       if (status < 0) {
-               dprintk(1, "Could not set demodulator parameters. Make "
-                       "sure qam_demod_parameter_count (%d) is correct for "
-                       "your firmware (%s).\n",
-                       state->qam_demod_parameter_count,
-                       state->microcode_name);
-               goto error;
-       } else if (!state->qam_demod_parameter_count) {
-               dprintk(1, "Auto-probing the correct QAM demodulator command "
-                       "parameters was successful - using %d parameters.\n",
-                       qamDemodParamCount);
-
-               /*
-                * One of our commands was successful. We don't need to
-                * auto-probe anymore, now that we got the correct command.
-                */
-               state->qam_demod_parameter_count = qamDemodParamCount;
-       }
-
-       /*
-        * STEP 3: enable the system in a mode where the ADC provides valid
-        * signal setup modulation independent registers
-        */
-#if 0
-       status = SetFrequency(channel, tunerFreqOffset));
-       if (status < 0)
-               goto error;
-#endif
-       status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
-       if (status < 0)
-               goto error;
-
-       /* Setup BER measurement */
-       status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
-       if (status < 0)
-               goto error;
-
-       /* Reset default values */
-       status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
-       if (status < 0)
-               goto error;
-
-       /* Reset default LC values */
-       status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_MODE__A, 7);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
-       if (status < 0)
-               goto error;
-
-       /* Mirroring, QAM-block starting point not inverted */
-       status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
-       if (status < 0)
-               goto error;
-
-       /* Halt SCU to enable safe non-atomic accesses */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
-       if (status < 0)
-               goto error;
-
-       /* STEP 4: modulation specific setup */
-       switch (state->props.modulation) {
-       case QAM_16:
-               status = SetQAM16(state);
-               break;
-       case QAM_32:
-               status = SetQAM32(state);
-               break;
-       case QAM_AUTO:
-       case QAM_64:
-               status = SetQAM64(state);
-               break;
-       case QAM_128:
-               status = SetQAM128(state);
-               break;
-       case QAM_256:
-               status = SetQAM256(state);
-               break;
-       default:
-               status = -EINVAL;
-               break;
-       }
-       if (status < 0)
-               goto error;
-
-       /* Activate SCU to enable SCU commands */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-
-       /* Re-configure MPEG output, requires knowledge of channel bitrate */
-       /* extAttr->currentChannel.modulation = channel->modulation; */
-       /* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
-       status = MPEGTSDtoSetup(state, state->m_OperationMode);
-       if (status < 0)
-               goto error;
-
-       /* Start processes */
-       status = MPEGTSStart(state);
-       if (status < 0)
-               goto error;
-       status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-       status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
-       if (status < 0)
-               goto error;
-
-       /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
-       status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
-       if (status < 0)
-               goto error;
-
-       /* update global DRXK data container */
-/*?     extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
-
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SetQAMStandard(struct drxk_state *state,
-                         enum OperationMode oMode)
-{
-       int status;
-#ifdef DRXK_QAM_TAPS
-#define DRXK_QAMA_TAPS_SELECT
-#include "drxk_filters.h"
-#undef DRXK_QAMA_TAPS_SELECT
-#endif
-
-       dprintk(1, "\n");
-
-       /* added antenna switch */
-       SwitchAntennaToQAM(state);
-
-       /* Ensure correct power-up mode */
-       status = PowerUpQAM(state);
-       if (status < 0)
-               goto error;
-       /* Reset QAM block */
-       status = QAMResetQAM(state);
-       if (status < 0)
-               goto error;
-
-       /* Setup IQM */
-
-       status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
-       if (status < 0)
-               goto error;
-
-       /* Upload IQM Channel Filter settings by
-               boot loader from ROM table */
-       switch (oMode) {
-       case OM_QAM_ITU_A:
-               status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
-               break;
-       case OM_QAM_ITU_C:
-               status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
-               if (status < 0)
-                       goto error;
-               status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
-               break;
-       default:
-               status = -EINVAL;
-       }
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_SYMMETRIC__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_RC_STRETCH__A, 21);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_CLP_LEN__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_CLP_TH__A, 448);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_SNS_LEN__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, IQM_FS_ADJ_SEL__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_RC_ADJ_SEL__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_ADJ_SEL__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_UPD_SEL__A, 0);
-       if (status < 0)
-               goto error;
-
-       /* IQM Impulse Noise Processing Unit */
-       status = write16(state, IQM_CF_CLP_VAL__A, 500);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_DATATH__A, 1000);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_BYPASSDET__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_DET_LCT__A, 0);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_WND_LEN__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_CF_PKDTH__A, 1);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_INC_BYPASS__A, 1);
-       if (status < 0)
-               goto error;
-
-       /* turn on IQMAF. Must be done before setAgc**() */
-       status = SetIqmAf(state, true);
-       if (status < 0)
-               goto error;
-       status = write16(state, IQM_AF_START_LOCK__A, 0x01);
-       if (status < 0)
-               goto error;
-
-       /* IQM will not be reset from here, sync ADC and update/init AGC */
-       status = ADCSynchronization(state);
-       if (status < 0)
-               goto error;
-
-       /* Set the FSM step period */
-       status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
-       if (status < 0)
-               goto error;
-
-       /* Halt SCU to enable safe non-atomic accesses */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
-       if (status < 0)
-               goto error;
-
-       /* No more resets of the IQM, current standard correctly set =>
-               now AGCs can be configured. */
-
-       status = InitAGC(state, true);
-       if (status < 0)
-               goto error;
-       status = SetPreSaw(state, &(state->m_qamPreSawCfg));
-       if (status < 0)
-               goto error;
-
-       /* Configure AGC's */
-       status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
-       if (status < 0)
-               goto error;
-       status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
-       if (status < 0)
-               goto error;
-
-       /* Activate SCU to enable SCU commands */
-       status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int WriteGPIO(struct drxk_state *state)
-{
-       int status;
-       u16 value = 0;
-
-       dprintk(1, "\n");
-       /* stop lock indicator process */
-       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-       if (status < 0)
-               goto error;
-
-       /*  Write magic word to enable pdr reg write               */
-       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
-       if (status < 0)
-               goto error;
-
-       if (state->m_hasSAWSW) {
-               if (state->UIO_mask & 0x0001) { /* UIO-1 */
-                       /* write to io pad configuration register - output mode */
-                       status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
-                       if (status < 0)
-                               goto error;
-
-                       /* use corresponding bit in io data output registar */
-                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
-                       if (status < 0)
-                               goto error;
-                       if ((state->m_GPIO & 0x0001) == 0)
-                               value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
-                       else
-                               value |= 0x8000;        /* write one to 15th bit - 1st UIO */
-                       /* write back to io data output register */
-                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
-                       if (status < 0)
-                               goto error;
-               }
-               if (state->UIO_mask & 0x0002) { /* UIO-2 */
-                       /* write to io pad configuration register - output mode */
-                       status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
-                       if (status < 0)
-                               goto error;
-
-                       /* use corresponding bit in io data output registar */
-                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
-                       if (status < 0)
-                               goto error;
-                       if ((state->m_GPIO & 0x0002) == 0)
-                               value &= 0xBFFF;        /* write zero to 14th bit - 2st UIO */
-                       else
-                               value |= 0x4000;        /* write one to 14th bit - 2st UIO */
-                       /* write back to io data output register */
-                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
-                       if (status < 0)
-                               goto error;
-               }
-               if (state->UIO_mask & 0x0004) { /* UIO-3 */
-                       /* write to io pad configuration register - output mode */
-                       status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
-                       if (status < 0)
-                               goto error;
-
-                       /* use corresponding bit in io data output registar */
-                       status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
-                       if (status < 0)
-                               goto error;
-                       if ((state->m_GPIO & 0x0004) == 0)
-                               value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
-                       else
-                               value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
-                       /* write back to io data output register */
-                       status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
-                       if (status < 0)
-                               goto error;
-               }
-       }
-       /*  Write magic word to disable pdr reg write               */
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SwitchAntennaToQAM(struct drxk_state *state)
-{
-       int status = 0;
-       bool gpio_state;
-
-       dprintk(1, "\n");
-
-       if (!state->antenna_gpio)
-               return 0;
-
-       gpio_state = state->m_GPIO & state->antenna_gpio;
-
-       if (state->antenna_dvbt ^ gpio_state) {
-               /* Antenna is on DVB-T mode. Switch */
-               if (state->antenna_dvbt)
-                       state->m_GPIO &= ~state->antenna_gpio;
-               else
-                       state->m_GPIO |= state->antenna_gpio;
-               status = WriteGPIO(state);
-       }
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-static int SwitchAntennaToDVBT(struct drxk_state *state)
-{
-       int status = 0;
-       bool gpio_state;
-
-       dprintk(1, "\n");
-
-       if (!state->antenna_gpio)
-               return 0;
-
-       gpio_state = state->m_GPIO & state->antenna_gpio;
-
-       if (!(state->antenna_dvbt ^ gpio_state)) {
-               /* Antenna is on DVB-C mode. Switch */
-               if (state->antenna_dvbt)
-                       state->m_GPIO |= state->antenna_gpio;
-               else
-                       state->m_GPIO &= ~state->antenna_gpio;
-               status = WriteGPIO(state);
-       }
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       return status;
-}
-
-
-static int PowerDownDevice(struct drxk_state *state)
-{
-       /* Power down to requested mode */
-       /* Backup some register settings */
-       /* Set pins with possible pull-ups connected to them in input mode */
-       /* Analog power down */
-       /* ADC power down */
-       /* Power down device */
-       int status;
-
-       dprintk(1, "\n");
-       if (state->m_bPDownOpenBridge) {
-               /* Open I2C bridge before power down of DRXK */
-               status = ConfigureI2CBridge(state, true);
-               if (status < 0)
-                       goto error;
-       }
-       /* driver 0.9.0 */
-       status = DVBTEnableOFDMTokenRing(state, false);
-       if (status < 0)
-               goto error;
-
-       status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
-       if (status < 0)
-               goto error;
-       status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
-       if (status < 0)
-               goto error;
-       state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-       status = HI_CfgCommand(state);
-error:
-       if (status < 0)
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-
-       return status;
-}
-
-static int init_drxk(struct drxk_state *state)
-{
-       int status = 0, n = 0;
-       enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-       u16 driverVersion;
-
-       dprintk(1, "\n");
-       if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
-               drxk_i2c_lock(state);
-               status = PowerUpDevice(state);
-               if (status < 0)
-                       goto error;
-               status = DRXX_Open(state);
-               if (status < 0)
-                       goto error;
-               /* Soft reset of OFDM-, sys- and osc-clockdomain */
-               status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
-               if (status < 0)
-                       goto error;
-               /* TODO is this needed, if yes how much delay in worst case scenario */
-               msleep(1);
-               state->m_DRXK_A3_PATCH_CODE = true;
-               status = GetDeviceCapabilities(state);
-               if (status < 0)
-                       goto error;
-
-               /* Bridge delay, uses oscilator clock */
-               /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
-               /* SDA brdige delay */
-               state->m_HICfgBridgeDelay =
-                       (u16) ((state->m_oscClockFreq / 1000) *
-                               HI_I2C_BRIDGE_DELAY) / 1000;
-               /* Clipping */
-               if (state->m_HICfgBridgeDelay >
-                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
-                       state->m_HICfgBridgeDelay =
-                               SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
-               }
-               /* SCL bridge delay, same as SDA for now */
-               state->m_HICfgBridgeDelay +=
-                       state->m_HICfgBridgeDelay <<
-                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
-
-               status = InitHI(state);
-               if (status < 0)
-                       goto error;
-               /* disable various processes */
-#if NOA1ROM
-               if (!(state->m_DRXK_A1_ROM_CODE)
-                       && !(state->m_DRXK_A2_ROM_CODE))
-#endif
-               {
-                       status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
-                       if (status < 0)
-                               goto error;
-               }
-
-               /* disable MPEG port */
-               status = MPEGTSDisable(state);
-               if (status < 0)
-                       goto error;
-
-               /* Stop AUD and SCU */
-               status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
-               if (status < 0)
-                       goto error;
-               status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
-               if (status < 0)
-                       goto error;
-
-               /* enable token-ring bus through OFDM block for possible ucode upload */
-               status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
-               if (status < 0)
-                       goto error;
-
-               /* include boot loader section */
-               status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
-               if (status < 0)
-                       goto error;
-               status = BLChainCmd(state, 0, 6, 100);
-               if (status < 0)
-                       goto error;
-
-               if (state->fw) {
-                       status = DownloadMicrocode(state, state->fw->data,
-                                                  state->fw->size);
-                       if (status < 0)
-                               goto error;
-               }
-
-               /* disable token-ring bus through OFDM block for possible ucode upload */
-               status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
-               if (status < 0)
-                       goto error;
-
-               /* Run SCU for a little while to initialize microcode version numbers */
-               status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
-               if (status < 0)
-                       goto error;
-               status = DRXX_Open(state);
-               if (status < 0)
-                       goto error;
-               /* added for test */
-               msleep(30);
-
-               powerMode = DRXK_POWER_DOWN_OFDM;
-               status = CtrlPowerMode(state, &powerMode);
-               if (status < 0)
-                       goto error;
-
-               /* Stamp driver version number in SCU data RAM in BCD code
-                       Done to enable field application engineers to retreive drxdriver version
-                       via I2C from SCU RAM.
-                       Not using SCU command interface for SCU register access since no
-                       microcode may be present.
-                       */
-               driverVersion =
-                       (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
-                       (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
-                       ((DRXK_VERSION_MAJOR % 10) << 4) +
-                       (DRXK_VERSION_MINOR % 10);
-               status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
-               if (status < 0)
-                       goto error;
-               driverVersion =
-                       (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
-                       (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
-                       (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
-                       (DRXK_VERSION_PATCH % 10);
-               status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
-               if (status < 0)
-                       goto error;
-
-               printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
-                       DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
-                       DRXK_VERSION_PATCH);
-
-               /* Dirty fix of default values for ROM/PATCH microcode
-                       Dirty because this fix makes it impossible to setup suitable values
-                       before calling DRX_Open. This solution requires changes to RF AGC speed
-                       to be done via the CTRL function after calling DRX_Open */
-
-               /* m_dvbtRfAgcCfg.speed = 3; */
-
-               /* Reset driver debug flags to 0 */
-               status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
-               if (status < 0)
-                       goto error;
-               /* driver 0.9.0 */
-               /* Setup FEC OC:
-                       NOTE: No more full FEC resets allowed afterwards!! */
-               status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
-               if (status < 0)
-                       goto error;
-               /* MPEGTS functions are still the same */
-               status = MPEGTSDtoInit(state);
-               if (status < 0)
-                       goto error;
-               status = MPEGTSStop(state);
-               if (status < 0)
-                       goto error;
-               status = MPEGTSConfigurePolarity(state);
-               if (status < 0)
-                       goto error;
-               status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
-               if (status < 0)
-                       goto error;
-               /* added: configure GPIO */
-               status = WriteGPIO(state);
-               if (status < 0)
-                       goto error;
-
-               state->m_DrxkState = DRXK_STOPPED;
-
-               if (state->m_bPowerDown) {
-                       status = PowerDownDevice(state);
-                       if (status < 0)
-                               goto error;
-                       state->m_DrxkState = DRXK_POWERED_DOWN;
-               } else
-                       state->m_DrxkState = DRXK_STOPPED;
-
-               /* Initialize the supported delivery systems */
-               n = 0;
-               if (state->m_hasDVBC) {
-                       state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
-                       state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
-                       strlcat(state->frontend.ops.info.name, " DVB-C",
-                               sizeof(state->frontend.ops.info.name));
-               }
-               if (state->m_hasDVBT) {
-                       state->frontend.ops.delsys[n++] = SYS_DVBT;
-                       strlcat(state->frontend.ops.info.name, " DVB-T",
-                               sizeof(state->frontend.ops.info.name));
-               }
-               drxk_i2c_unlock(state);
-       }
-error:
-       if (status < 0) {
-               state->m_DrxkState = DRXK_NO_DEV;
-               drxk_i2c_unlock(state);
-               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
-       }
-
-       return status;
-}
-
-static void load_firmware_cb(const struct firmware *fw,
-                            void *context)
-{
-       struct drxk_state *state = context;
-
-       dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
-       if (!fw) {
-               printk(KERN_ERR
-                      "drxk: Could not load firmware file %s.\n",
-                       state->microcode_name);
-               printk(KERN_INFO
-                      "drxk: Copy %s to your hotplug directory!\n",
-                       state->microcode_name);
-               state->microcode_name = NULL;
-
-               /*
-                * As firmware is now load asynchronous, it is not possible
-                * anymore to fail at frontend attach. We might silently
-                * return here, and hope that the driver won't crash.
-                * We might also change all DVB callbacks to return -ENODEV
-                * if the device is not initialized.
-                * As the DRX-K devices have their own internal firmware,
-                * let's just hope that it will match a firmware revision
-                * compatible with this driver and proceed.
-                */
-       }
-       state->fw = fw;
-
-       init_drxk(state);
-}
-
-static void drxk_release(struct dvb_frontend *fe)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-
-       dprintk(1, "\n");
-       if (state->fw)
-               release_firmware(state->fw);
-
-       kfree(state);
-}
-
-static int drxk_sleep(struct dvb_frontend *fe)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return 0;
-
-       ShutDown(state);
-       return 0;
-}
-
-static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-
-       dprintk(1, ": %s\n", enable ? "enable" : "disable");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-
-       return ConfigureI2CBridge(state, enable ? true : false);
-}
-
-static int drxk_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u32 delsys  = p->delivery_system, old_delsys;
-       struct drxk_state *state = fe->demodulator_priv;
-       u32 IF;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       if (!fe->ops.tuner_ops.get_if_frequency) {
-               printk(KERN_ERR
-                      "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
-               return -EINVAL;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       old_delsys = state->props.delivery_system;
-       state->props = *p;
-
-       if (old_delsys != delsys) {
-               ShutDown(state);
-               switch (delsys) {
-               case SYS_DVBC_ANNEX_A:
-               case SYS_DVBC_ANNEX_C:
-                       if (!state->m_hasDVBC)
-                               return -EINVAL;
-                       state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
-                       if (state->m_itut_annex_c)
-                               SetOperationMode(state, OM_QAM_ITU_C);
-                       else
-                               SetOperationMode(state, OM_QAM_ITU_A);
-                       break;
-               case SYS_DVBT:
-                       if (!state->m_hasDVBT)
-                               return -EINVAL;
-                       SetOperationMode(state, OM_DVBT);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       fe->ops.tuner_ops.get_if_frequency(fe, &IF);
-       Start(state, 0, IF);
-
-       /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
-
-       return 0;
-}
-
-static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-       u32 stat;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       *status = 0;
-       GetLockStatus(state, &stat, 0);
-       if (stat == MPEG_LOCK)
-               *status |= 0x1f;
-       if (stat == FEC_LOCK)
-               *status |= 0x0f;
-       if (stat == DEMOD_LOCK)
-               *status |= 0x07;
-       return 0;
-}
-
-static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       *ber = 0;
-       return 0;
-}
-
-static int drxk_read_signal_strength(struct dvb_frontend *fe,
-                                    u16 *strength)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-       u32 val = 0;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       ReadIFAgc(state, &val);
-       *strength = val & 0xffff;
-       return 0;
-}
-
-static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-       s32 snr2;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       GetSignalToNoise(state, &snr2);
-       *snr = snr2 & 0xffff;
-       return 0;
-}
-
-static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-       u16 err;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       DVBTQAMGetAccPktErr(state, &err);
-       *ucblocks = (u32) err;
-       return 0;
-}
-
-static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
-                                   *sets)
-{
-       struct drxk_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       dprintk(1, "\n");
-
-       if (state->m_DrxkState == DRXK_NO_DEV)
-               return -ENODEV;
-       if (state->m_DrxkState == DRXK_UNINITIALIZED)
-               return -EAGAIN;
-
-       switch (p->delivery_system) {
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-       case SYS_DVBT:
-               sets->min_delay_ms = 3000;
-               sets->max_drift = 0;
-               sets->step_size = 0;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static struct dvb_frontend_ops drxk_ops = {
-       /* .delsys will be filled dynamically */
-       .info = {
-               .name = "DRXK",
-               .frequency_min = 47000000,
-               .frequency_max = 865000000,
-                /* For DVB-C */
-               .symbol_rate_min = 870000,
-               .symbol_rate_max = 11700000,
-               /* For DVB-T */
-               .frequency_stepsize = 166667,
-
-               .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
-                       FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
-       },
-
-       .release = drxk_release,
-       .sleep = drxk_sleep,
-       .i2c_gate_ctrl = drxk_gate_ctrl,
-
-       .set_frontend = drxk_set_parameters,
-       .get_tune_settings = drxk_get_tune_settings,
-
-       .read_status = drxk_read_status,
-       .read_ber = drxk_read_ber,
-       .read_signal_strength = drxk_read_signal_strength,
-       .read_snr = drxk_read_snr,
-       .read_ucblocks = drxk_read_ucblocks,
-};
-
-struct dvb_frontend *drxk_attach(const struct drxk_config *config,
-                                struct i2c_adapter *i2c)
-{
-       struct drxk_state *state = NULL;
-       u8 adr = config->adr;
-       int status;
-
-       dprintk(1, "\n");
-       state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       state->i2c = i2c;
-       state->demod_address = adr;
-       state->single_master = config->single_master;
-       state->microcode_name = config->microcode_name;
-       state->qam_demod_parameter_count = config->qam_demod_parameter_count;
-       state->no_i2c_bridge = config->no_i2c_bridge;
-       state->antenna_gpio = config->antenna_gpio;
-       state->antenna_dvbt = config->antenna_dvbt;
-       state->m_ChunkSize = config->chunk_size;
-       state->enable_merr_cfg = config->enable_merr_cfg;
-
-       if (config->dynamic_clk) {
-               state->m_DVBTStaticCLK = 0;
-               state->m_DVBCStaticCLK = 0;
-       } else {
-               state->m_DVBTStaticCLK = 1;
-               state->m_DVBCStaticCLK = 1;
-       }
-
-
-       if (config->mpeg_out_clk_strength)
-               state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
-       else
-               state->m_TSClockkStrength = 0x06;
-
-       if (config->parallel_ts)
-               state->m_enableParallel = true;
-       else
-               state->m_enableParallel = false;
-
-       /* NOTE: as more UIO bits will be used, add them to the mask */
-       state->UIO_mask = config->antenna_gpio;
-
-       /* Default gpio to DVB-C */
-       if (!state->antenna_dvbt && state->antenna_gpio)
-               state->m_GPIO |= state->antenna_gpio;
-       else
-               state->m_GPIO &= ~state->antenna_gpio;
-
-       mutex_init(&state->mutex);
-
-       memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
-       state->frontend.demodulator_priv = state;
-
-       init_state(state);
-
-       /* Load firmware and initialize DRX-K */
-       if (state->microcode_name) {
-               status = request_firmware_nowait(THIS_MODULE, 1,
-                                             state->microcode_name,
-                                             state->i2c->dev.parent,
-                                             GFP_KERNEL,
-                                             state, load_firmware_cb);
-               if (status < 0) {
-                       printk(KERN_ERR
-                       "drxk: failed to request a firmware\n");
-                       return NULL;
-               }
-       } else if (init_drxk(state) < 0)
-               goto error;
-
-       printk(KERN_INFO "drxk: frontend initialized.\n");
-       return &state->frontend;
-
-error:
-       printk(KERN_ERR "drxk: not found\n");
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(drxk_attach);
-
-MODULE_DESCRIPTION("DRX-K driver");
-MODULE_AUTHOR("Ralph Metzler");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
deleted file mode 100644 (file)
index 6bb9fc4..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-#include "drxk_map.h"
-
-#define DRXK_VERSION_MAJOR 0
-#define DRXK_VERSION_MINOR 9
-#define DRXK_VERSION_PATCH 4300
-
-#define HI_I2C_DELAY        42
-#define HI_I2C_BRIDGE_DELAY 350
-#define DRXK_MAX_RETRIES    100
-
-#define DRIVER_4400 1
-
-#define DRXX_JTAGID   0x039210D9
-#define DRXX_J_JTAGID 0x239310D9
-#define DRXX_K_JTAGID 0x039210D9
-
-#define DRX_UNKNOWN     254
-#define DRX_AUTO        255
-
-#define DRX_SCU_READY   0
-#define DRXK_MAX_WAITTIME (200)
-#define SCU_RESULT_OK      0
-#define SCU_RESULT_SIZE   -4
-#define SCU_RESULT_INVPAR -3
-#define SCU_RESULT_UNKSTD -2
-#define SCU_RESULT_UNKCMD -1
-
-#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
-#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
-#endif
-
-#define DRXK_8VSB_MPEG_BIT_RATE     19392658UL  /*bps*/
-#define DRXK_DVBT_MPEG_BIT_RATE     32000000UL  /*bps*/
-#define DRXK_QAM16_MPEG_BIT_RATE    27000000UL  /*bps*/
-#define DRXK_QAM32_MPEG_BIT_RATE    33000000UL  /*bps*/
-#define DRXK_QAM64_MPEG_BIT_RATE    40000000UL  /*bps*/
-#define DRXK_QAM128_MPEG_BIT_RATE   46000000UL  /*bps*/
-#define DRXK_QAM256_MPEG_BIT_RATE   52000000UL  /*bps*/
-#define DRXK_MAX_MPEG_BIT_RATE      52000000UL  /*bps*/
-
-#define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
-#define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
-#define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
-#define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
-#define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
-#define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
-#define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
-
-enum OperationMode {
-       OM_NONE,
-       OM_QAM_ITU_A,
-       OM_QAM_ITU_B,
-       OM_QAM_ITU_C,
-       OM_DVBT
-};
-
-enum DRXPowerMode {
-       DRX_POWER_UP = 0,
-       DRX_POWER_MODE_1,
-       DRX_POWER_MODE_2,
-       DRX_POWER_MODE_3,
-       DRX_POWER_MODE_4,
-       DRX_POWER_MODE_5,
-       DRX_POWER_MODE_6,
-       DRX_POWER_MODE_7,
-       DRX_POWER_MODE_8,
-
-       DRX_POWER_MODE_9,
-       DRX_POWER_MODE_10,
-       DRX_POWER_MODE_11,
-       DRX_POWER_MODE_12,
-       DRX_POWER_MODE_13,
-       DRX_POWER_MODE_14,
-       DRX_POWER_MODE_15,
-       DRX_POWER_MODE_16,
-       DRX_POWER_DOWN = 255
-};
-
-
-/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
-#ifndef DRXK_POWER_DOWN_OFDM
-#define DRXK_POWER_DOWN_OFDM        DRX_POWER_MODE_1
-#endif
-
-/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
-#ifndef DRXK_POWER_DOWN_CORE
-#define DRXK_POWER_DOWN_CORE        DRX_POWER_MODE_9
-#endif
-
-/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
-#ifndef DRXK_POWER_DOWN_PLL
-#define DRXK_POWER_DOWN_PLL         DRX_POWER_MODE_10
-#endif
-
-
-enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
-enum EDrxkState {
-       DRXK_UNINITIALIZED = 0,
-       DRXK_STOPPED,
-       DRXK_DTV_STARTED,
-       DRXK_ATV_STARTED,
-       DRXK_POWERED_DOWN,
-       DRXK_NO_DEV                     /* If drxk init failed */
-};
-
-enum EDrxkCoefArrayIndex {
-       DRXK_COEF_IDX_MN = 0,
-       DRXK_COEF_IDX_FM    ,
-       DRXK_COEF_IDX_L     ,
-       DRXK_COEF_IDX_LP    ,
-       DRXK_COEF_IDX_BG    ,
-       DRXK_COEF_IDX_DK    ,
-       DRXK_COEF_IDX_I     ,
-       DRXK_COEF_IDX_MAX
-};
-enum EDrxkSifAttenuation {
-       DRXK_SIF_ATTENUATION_0DB,
-       DRXK_SIF_ATTENUATION_3DB,
-       DRXK_SIF_ATTENUATION_6DB,
-       DRXK_SIF_ATTENUATION_9DB
-};
-enum EDrxkConstellation {
-       DRX_CONSTELLATION_BPSK = 0,
-       DRX_CONSTELLATION_QPSK,
-       DRX_CONSTELLATION_PSK8,
-       DRX_CONSTELLATION_QAM16,
-       DRX_CONSTELLATION_QAM32,
-       DRX_CONSTELLATION_QAM64,
-       DRX_CONSTELLATION_QAM128,
-       DRX_CONSTELLATION_QAM256,
-       DRX_CONSTELLATION_QAM512,
-       DRX_CONSTELLATION_QAM1024,
-       DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
-       DRX_CONSTELLATION_AUTO    = DRX_AUTO
-};
-enum EDrxkInterleaveMode {
-       DRXK_QAM_I12_J17    = 16,
-       DRXK_QAM_I_UNKNOWN  = DRX_UNKNOWN
-};
-enum {
-       DRXK_SPIN_A1 = 0,
-       DRXK_SPIN_A2,
-       DRXK_SPIN_A3,
-       DRXK_SPIN_UNKNOWN
-};
-
-enum DRXKCfgDvbtSqiSpeed {
-       DRXK_DVBT_SQI_SPEED_FAST = 0,
-       DRXK_DVBT_SQI_SPEED_MEDIUM,
-       DRXK_DVBT_SQI_SPEED_SLOW,
-       DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
-} ;
-
-enum DRXFftmode_t {
-       DRX_FFTMODE_2K = 0,
-       DRX_FFTMODE_4K,
-       DRX_FFTMODE_8K,
-       DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
-       DRX_FFTMODE_AUTO    = DRX_AUTO
-};
-
-enum DRXMPEGStrWidth_t {
-       DRX_MPEG_STR_WIDTH_1,
-       DRX_MPEG_STR_WIDTH_8
-};
-
-enum DRXQamLockRange_t {
-       DRX_QAM_LOCKRANGE_NORMAL,
-       DRX_QAM_LOCKRANGE_EXTENDED
-};
-
-struct DRXKCfgDvbtEchoThres_t {
-       u16             threshold;
-       enum DRXFftmode_t      fftMode;
-} ;
-
-struct SCfgAgc {
-       enum AGC_CTRL_MODE     ctrlMode;        /* off, user, auto */
-       u16            outputLevel;     /* range dependent on AGC */
-       u16            minOutputLevel;  /* range dependent on AGC */
-       u16            maxOutputLevel;  /* range dependent on AGC */
-       u16            speed;           /* range dependent on AGC */
-       u16            top;             /* rf-agc take over point */
-       u16            cutOffCurrent;   /* rf-agc is accelerated if output current
-                                          is below cut-off current */
-       u16            IngainTgtMax;
-       u16            FastClipCtrlDelay;
-};
-
-struct SCfgPreSaw {
-       u16        reference; /* pre SAW reference value, range 0 .. 31 */
-       bool          usePreSaw; /* TRUE algorithms must use pre SAW sense */
-};
-
-struct DRXKOfdmScCmd_t {
-       u16 cmd;        /**< Command number */
-       u16 subcmd;     /**< Sub-command parameter*/
-       u16 param0;     /**< General purpous param */
-       u16 param1;     /**< General purpous param */
-       u16 param2;     /**< General purpous param */
-       u16 param3;     /**< General purpous param */
-       u16 param4;     /**< General purpous param */
-};
-
-struct drxk_state {
-       struct dvb_frontend frontend;
-       struct dtv_frontend_properties props;
-       struct device *dev;
-
-       struct i2c_adapter *i2c;
-       u8     demod_address;
-       void  *priv;
-
-       struct mutex mutex;
-
-       u32    m_Instance;           /**< Channel 1,2,3 or 4 */
-
-       int    m_ChunkSize;
-       u8 Chunk[256];
-
-       bool   m_hasLNA;
-       bool   m_hasDVBT;
-       bool   m_hasDVBC;
-       bool   m_hasAudio;
-       bool   m_hasATV;
-       bool   m_hasOOB;
-       bool   m_hasSAWSW;         /**< TRUE if mat_tx is available */
-       bool   m_hasGPIO1;         /**< TRUE if mat_rx is available */
-       bool   m_hasGPIO2;         /**< TRUE if GPIO is available */
-       bool   m_hasIRQN;          /**< TRUE if IRQN is available */
-       u16    m_oscClockFreq;
-       u16    m_HICfgTimingDiv;
-       u16    m_HICfgBridgeDelay;
-       u16    m_HICfgWakeUpKey;
-       u16    m_HICfgTimeout;
-       u16    m_HICfgCtrl;
-       s32    m_sysClockFreq;      /**< system clock frequency in kHz */
-
-       enum EDrxkState    m_DrxkState;      /**< State of Drxk (init,stopped,started) */
-       enum OperationMode m_OperationMode;  /**< digital standards */
-       struct SCfgAgc     m_vsbRfAgcCfg;    /**< settings for VSB RF-AGC */
-       struct SCfgAgc     m_vsbIfAgcCfg;    /**< settings for VSB IF-AGC */
-       u16                m_vsbPgaCfg;      /**< settings for VSB PGA */
-       struct SCfgPreSaw  m_vsbPreSawCfg;   /**< settings for pre SAW sense */
-       s32    m_Quality83percent;  /**< MER level (*0.1 dB) for 83% quality indication */
-       s32    m_Quality93percent;  /**< MER level (*0.1 dB) for 93% quality indication */
-       bool   m_smartAntInverted;
-       bool   m_bDebugEnableBridge;
-       bool   m_bPDownOpenBridge;  /**< only open DRXK bridge before power-down once it has been accessed */
-       bool   m_bPowerDown;        /**< Power down when not used */
-
-       u32    m_IqmFsRateOfs;      /**< frequency shift as written to DRXK register (28bit fixpoint) */
-
-       bool   m_enableMPEGOutput;  /**< If TRUE, enable MPEG output */
-       bool   m_insertRSByte;      /**< If TRUE, insert RS byte */
-       bool   m_enableParallel;    /**< If TRUE, parallel out otherwise serial */
-       bool   m_invertDATA;        /**< If TRUE, invert DATA signals */
-       bool   m_invertERR;         /**< If TRUE, invert ERR signal */
-       bool   m_invertSTR;         /**< If TRUE, invert STR signals */
-       bool   m_invertVAL;         /**< If TRUE, invert VAL signals */
-       bool   m_invertCLK;         /**< If TRUE, invert CLK signals */
-       bool   m_DVBCStaticCLK;
-       bool   m_DVBTStaticCLK;     /**< If TRUE, static MPEG clockrate will
-                                        be used, otherwise clockrate will
-                                        adapt to the bitrate of the TS */
-       u32    m_DVBTBitrate;
-       u32    m_DVBCBitrate;
-
-       u8     m_TSDataStrength;
-       u8     m_TSClockkStrength;
-
-       bool   m_itut_annex_c;      /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
-
-       enum DRXMPEGStrWidth_t  m_widthSTR;    /**< MPEG start width */
-       u32    m_mpegTsStaticBitrate;          /**< Maximum bitrate in b/s in case
-                                                   static clockrate is selected */
-
-       /* LARGE_INTEGER   m_StartTime; */     /**< Contains the time of the last demod start */
-       s32    m_MpegLockTimeOut;      /**< WaitForLockStatus Timeout (counts from start time) */
-       s32    m_DemodLockTimeOut;     /**< WaitForLockStatus Timeout (counts from start time) */
-
-       bool   m_disableTEIhandling;
-
-       bool   m_RfAgcPol;
-       bool   m_IfAgcPol;
-
-       struct SCfgAgc    m_atvRfAgcCfg;  /**< settings for ATV RF-AGC */
-       struct SCfgAgc    m_atvIfAgcCfg;  /**< settings for ATV IF-AGC */
-       struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
-       bool              m_phaseCorrectionBypass;
-       s16               m_atvTopVidPeak;
-       u16               m_atvTopNoiseTh;
-       enum EDrxkSifAttenuation m_sifAttenuation;
-       bool              m_enableCVBSOutput;
-       bool              m_enableSIFOutput;
-       bool              m_bMirrorFreqSpect;
-       enum EDrxkConstellation  m_Constellation; /**< Constellation type of the channel */
-       u32               m_CurrSymbolRate;       /**< Current QAM symbol rate */
-       struct SCfgAgc    m_qamRfAgcCfg;          /**< settings for QAM RF-AGC */
-       struct SCfgAgc    m_qamIfAgcCfg;          /**< settings for QAM IF-AGC */
-       u16               m_qamPgaCfg;            /**< settings for QAM PGA */
-       struct SCfgPreSaw m_qamPreSawCfg;         /**< settings for QAM pre SAW sense */
-       enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
-       u16               m_fecRsPlen;
-       u16               m_fecRsPrescale;
-
-       enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
-
-       u16               m_GPIO;
-       u16               m_GPIOCfg;
-
-       struct SCfgAgc    m_dvbtRfAgcCfg;     /**< settings for QAM RF-AGC */
-       struct SCfgAgc    m_dvbtIfAgcCfg;     /**< settings for QAM IF-AGC */
-       struct SCfgPreSaw m_dvbtPreSawCfg;    /**< settings for QAM pre SAW sense */
-
-       u16               m_agcFastClipCtrlDelay;
-       bool              m_adcCompPassed;
-       u16               m_adcCompCoef[64];
-       u16               m_adcState;
-
-       u8               *m_microcode;
-       int               m_microcode_length;
-       bool              m_DRXK_A1_PATCH_CODE;
-       bool              m_DRXK_A1_ROM_CODE;
-       bool              m_DRXK_A2_ROM_CODE;
-       bool              m_DRXK_A3_ROM_CODE;
-       bool              m_DRXK_A2_PATCH_CODE;
-       bool              m_DRXK_A3_PATCH_CODE;
-
-       bool              m_rfmirror;
-       u8                m_deviceSpin;
-       u32               m_iqmRcRate;
-
-       enum DRXPowerMode m_currentPowerMode;
-
-       /* when true, avoids other devices to use the I2C bus */
-       bool              drxk_i2c_exclusive_lock;
-
-       /*
-        * Configurable parameters at the driver. They stores the values found
-        * at struct drxk_config.
-        */
-
-       u16     UIO_mask;       /* Bits used by UIO */
-
-       bool    enable_merr_cfg;
-       bool    single_master;
-       bool    no_i2c_bridge;
-       bool    antenna_dvbt;
-       u16     antenna_gpio;
-
-       /* Firmware */
-       const char *microcode_name;
-       struct completion fw_wait_load;
-       const struct firmware *fw;
-       int qam_demod_parameter_count;
-};
-
-#define NEVER_LOCK 0
-#define NOT_LOCKED 1
-#define DEMOD_LOCK 2
-#define FEC_LOCK   3
-#define MPEG_LOCK  4
-
diff --git a/drivers/media/dvb/frontends/drxk_map.h b/drivers/media/dvb/frontends/drxk_map.h
deleted file mode 100644 (file)
index 23e16c1..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-#define  AUD_COMM_EXEC__A                                                  0x1000000
-#define    AUD_COMM_EXEC_STOP                                              0x0
-#define  FEC_COMM_EXEC__A                                                  0x1C00000
-#define    FEC_COMM_EXEC_STOP                                              0x0
-#define    FEC_COMM_EXEC_ACTIVE                                            0x1
-#define  FEC_DI_COMM_EXEC__A                                               0x1C20000
-#define    FEC_DI_COMM_EXEC_STOP                                           0x0
-#define  FEC_DI_INPUT_CTL__A                                               0x1C20016
-#define  FEC_RS_COMM_EXEC__A                                               0x1C30000
-#define    FEC_RS_COMM_EXEC_STOP                                           0x0
-#define  FEC_RS_MEASUREMENT_PERIOD__A                                      0x1C30012
-#define  FEC_RS_MEASUREMENT_PRESCALE__A                                    0x1C30013
-#define  FEC_OC_MODE__A                                                    0x1C40011
-#define    FEC_OC_MODE_PARITY__M                                           0x1
-#define  FEC_OC_DTO_MODE__A                                                0x1C40014
-#define    FEC_OC_DTO_MODE_DYNAMIC__M                                      0x1
-#define    FEC_OC_DTO_MODE_OFFSET_ENABLE__M                                0x4
-#define  FEC_OC_DTO_PERIOD__A                                              0x1C40015
-#define  FEC_OC_DTO_BURST_LEN__A                                           0x1C40018
-#define  FEC_OC_FCT_MODE__A                                                0x1C4001A
-#define  FEC_OC_FCT_MODE__PRE                                              0x0
-#define    FEC_OC_FCT_MODE_RAT_ENA__M                                      0x1
-#define    FEC_OC_FCT_MODE_VIRT_ENA__M                                     0x2
-#define  FEC_OC_TMD_MODE__A                                                0x1C4001E
-#define  FEC_OC_TMD_COUNT__A                                               0x1C4001F
-#define  FEC_OC_TMD_HI_MARGIN__A                                           0x1C40020
-#define  FEC_OC_TMD_LO_MARGIN__A                                           0x1C40021
-#define  FEC_OC_TMD_INT_UPD_RATE__A                                        0x1C40023
-#define  FEC_OC_AVR_PARM_A__A                                              0x1C40026
-#define  FEC_OC_AVR_PARM_B__A                                              0x1C40027
-#define  FEC_OC_RCN_GAIN__A                                                0x1C4002E
-#define  FEC_OC_RCN_CTL_RATE_LO__A                                         0x1C40030
-#define  FEC_OC_RCN_CTL_STEP_LO__A                                         0x1C40032
-#define  FEC_OC_RCN_CTL_STEP_HI__A                                         0x1C40033
-#define  FEC_OC_SNC_MODE__A                                                0x1C40040
-#define    FEC_OC_SNC_MODE_SHUTDOWN__M                                     0x10
-#define  FEC_OC_SNC_LWM__A                                                 0x1C40041
-#define  FEC_OC_SNC_HWM__A                                                 0x1C40042
-#define  FEC_OC_SNC_UNLOCK__A                                              0x1C40043
-#define  FEC_OC_SNC_FAIL_PERIOD__A                                         0x1C40046
-#define  FEC_OC_IPR_MODE__A                                                0x1C40048
-#define    FEC_OC_IPR_MODE_SERIAL__M                                       0x1
-#define    FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M                             0x4
-#define    FEC_OC_IPR_MODE_MVAL_DIS_PAR__M                                 0x10
-#define  FEC_OC_IPR_INVERT__A                                              0x1C40049
-#define    FEC_OC_IPR_INVERT_MD0__M                                        0x1
-#define    FEC_OC_IPR_INVERT_MD1__M                                        0x2
-#define    FEC_OC_IPR_INVERT_MD2__M                                        0x4
-#define    FEC_OC_IPR_INVERT_MD3__M                                        0x8
-#define    FEC_OC_IPR_INVERT_MD4__M                                        0x10
-#define    FEC_OC_IPR_INVERT_MD5__M                                        0x20
-#define    FEC_OC_IPR_INVERT_MD6__M                                        0x40
-#define    FEC_OC_IPR_INVERT_MD7__M                                        0x80
-#define    FEC_OC_IPR_INVERT_MERR__M                                       0x100
-#define    FEC_OC_IPR_INVERT_MSTRT__M                                      0x200
-#define    FEC_OC_IPR_INVERT_MVAL__M                                       0x400
-#define    FEC_OC_IPR_INVERT_MCLK__M                                       0x800
-#define  FEC_OC_OCR_INVERT__A                                              0x1C40052
-#define  IQM_COMM_EXEC__A                                                  0x1800000
-#define      IQM_COMM_EXEC_B_STOP                                          0x0
-#define      IQM_COMM_EXEC_B_ACTIVE                                        0x1
-#define  IQM_FS_RATE_OFS_LO__A                                             0x1820010
-#define  IQM_FS_ADJ_SEL__A                                                 0x1820014
-#define      IQM_FS_ADJ_SEL_B_OFF                                          0x0
-#define      IQM_FS_ADJ_SEL_B_QAM                                          0x1
-#define      IQM_FS_ADJ_SEL_B_VSB                                          0x2
-#define  IQM_FD_RATESEL__A                                                 0x1830010
-#define  IQM_RC_RATE_OFS_LO__A                                             0x1840010
-#define  IQM_RC_RATE_OFS_LO__W                                             16
-#define  IQM_RC_RATE_OFS_LO__M                                             0xFFFF
-#define  IQM_RC_RATE_OFS_HI__M                                             0xFF
-#define  IQM_RC_ADJ_SEL__A                                                 0x1840014
-#define      IQM_RC_ADJ_SEL_B_OFF                                          0x0
-#define      IQM_RC_ADJ_SEL_B_QAM                                          0x1
-#define      IQM_RC_ADJ_SEL_B_VSB                                          0x2
-#define  IQM_RC_STRETCH__A                                                 0x1840016
-#define  IQM_CF_COMM_INT_MSK__A                                            0x1860006
-#define  IQM_CF_SYMMETRIC__A                                               0x1860010
-#define  IQM_CF_MIDTAP__A                                                  0x1860011
-#define    IQM_CF_MIDTAP_RE__B                                             0
-#define    IQM_CF_MIDTAP_IM__B                                             1
-#define  IQM_CF_OUT_ENA__A                                                 0x1860012
-#define    IQM_CF_OUT_ENA_QAM__B                                           1
-#define    IQM_CF_OUT_ENA_OFDM__M                                          0x4
-#define  IQM_CF_ADJ_SEL__A                                                 0x1860013
-#define  IQM_CF_SCALE__A                                                   0x1860014
-#define  IQM_CF_SCALE_SH__A                                                0x1860015
-#define  IQM_CF_SCALE_SH__PRE                                              0x0
-#define  IQM_CF_POW_MEAS_LEN__A                                            0x1860017
-#define  IQM_CF_DS_ENA__A                                                  0x1860019
-#define  IQM_CF_TAP_RE0__A                                                 0x1860020
-#define  IQM_CF_TAP_IM0__A                                                 0x1860040
-#define  IQM_CF_CLP_VAL__A                                                 0x1860060
-#define  IQM_CF_DATATH__A                                                  0x1860061
-#define  IQM_CF_PKDTH__A                                                   0x1860062
-#define  IQM_CF_WND_LEN__A                                                 0x1860063
-#define  IQM_CF_DET_LCT__A                                                 0x1860064
-#define  IQM_CF_BYPASSDET__A                                               0x1860067
-#define  IQM_AF_COMM_EXEC__A                                               0x1870000
-#define    IQM_AF_COMM_EXEC_ACTIVE                                         0x1
-#define  IQM_AF_CLKNEG__A                                                  0x1870012
-#define    IQM_AF_CLKNEG_CLKNEGDATA__M                                     0x2
-#define      IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS                     0x0
-#define      IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG                     0x2
-#define  IQM_AF_START_LOCK__A                                              0x187001B
-#define  IQM_AF_PHASE0__A                                                  0x187001C
-#define  IQM_AF_PHASE1__A                                                  0x187001D
-#define  IQM_AF_PHASE2__A                                                  0x187001E
-#define  IQM_AF_CLP_LEN__A                                                 0x1870023
-#define  IQM_AF_CLP_TH__A                                                  0x1870024
-#define  IQM_AF_SNS_LEN__A                                                 0x1870026
-#define  IQM_AF_AGC_IF__A                                                  0x1870028
-#define  IQM_AF_AGC_RF__A                                                  0x1870029
-#define  IQM_AF_PDREF__A                                                   0x187002B
-#define  IQM_AF_PDREF__M                                                   0x1F
-#define  IQM_AF_STDBY__A                                                   0x187002C
-#define      IQM_AF_STDBY_STDBY_ADC_STANDBY                                0x2
-#define      IQM_AF_STDBY_STDBY_AMP_STANDBY                                0x4
-#define      IQM_AF_STDBY_STDBY_PD_STANDBY                                 0x8
-#define      IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY                            0x10
-#define      IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY                            0x20
-#define  IQM_AF_AMUX__A                                                    0x187002D
-#define    IQM_AF_AMUX_SIGNAL2ADC                                          0x1
-#define  IQM_AF_UPD_SEL__A                                                 0x187002F
-#define  IQM_AF_INC_LCT__A                                                 0x1870034
-#define  IQM_AF_INC_BYPASS__A                                              0x1870036
-#define  OFDM_CP_COMM_EXEC__A                                              0x2800000
-#define    OFDM_CP_COMM_EXEC_STOP                                          0x0
-#define  OFDM_EC_SB_PRIOR__A                                               0x3410013
-#define    OFDM_EC_SB_PRIOR_HI                                             0x0
-#define    OFDM_EC_SB_PRIOR_LO                                             0x1
-#define  OFDM_EQ_TOP_TD_TPS_CONST__A                                       0x3010054
-#define  OFDM_EQ_TOP_TD_TPS_CONST__M                                       0x3
-#define    OFDM_EQ_TOP_TD_TPS_CONST_64QAM                                  0x2
-#define  OFDM_EQ_TOP_TD_TPS_CODE_HP__A                                     0x3010056
-#define  OFDM_EQ_TOP_TD_TPS_CODE_HP__M                                     0x7
-#define    OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8                                  0x4
-#define  OFDM_EQ_TOP_TD_SQR_ERR_I__A                                       0x301005E
-#define  OFDM_EQ_TOP_TD_SQR_ERR_Q__A                                       0x301005F
-#define  OFDM_EQ_TOP_TD_SQR_ERR_EXP__A                                     0x3010060
-#define  OFDM_EQ_TOP_TD_REQ_SMB_CNT__A                                     0x3010061
-#define  OFDM_EQ_TOP_TD_TPS_PWR_OFS__A                                     0x3010062
-#define  OFDM_LC_COMM_EXEC__A                                              0x3800000
-#define    OFDM_LC_COMM_EXEC_STOP                                          0x0
-#define  OFDM_SC_COMM_EXEC__A                                              0x3C00000
-#define    OFDM_SC_COMM_EXEC_STOP                                          0x0
-#define  OFDM_SC_COMM_STATE__A                                             0x3C00001
-#define  OFDM_SC_RA_RAM_PARAM0__A                                          0x3C20040
-#define  OFDM_SC_RA_RAM_PARAM1__A                                          0x3C20041
-#define  OFDM_SC_RA_RAM_CMD_ADDR__A                                        0x3C20042
-#define  OFDM_SC_RA_RAM_CMD__A                                             0x3C20043
-#define    OFDM_SC_RA_RAM_CMD_NULL                                         0x0
-#define    OFDM_SC_RA_RAM_CMD_PROC_START                                   0x1
-#define    OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM                               0x3
-#define    OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM                                0x4
-#define    OFDM_SC_RA_RAM_CMD_GET_OP_PARAM                                 0x5
-#define    OFDM_SC_RA_RAM_CMD_USER_IO                                      0x6
-#define    OFDM_SC_RA_RAM_CMD_SET_TIMER                                    0x7
-#define    OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING                              0x8
-#define    OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M                            0x1
-#define    OFDM_SC_RA_RAM_LOCKTRACK_MIN                                    0x1
-#define  OFDM_SC_RA_RAM_OP_PARAM__A                                        0x3C20048
-#define    OFDM_SC_RA_RAM_OP_PARAM_MODE__M                                 0x3
-#define      OFDM_SC_RA_RAM_OP_PARAM_MODE_2K                               0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_MODE_8K                               0x1
-#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_32                              0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_16                              0x4
-#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_8                               0x8
-#define      OFDM_SC_RA_RAM_OP_PARAM_GUARD_4                               0xC
-#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK                            0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16                           0x10
-#define      OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64                           0x20
-#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_NO                               0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A1                               0x40
-#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A2                               0x80
-#define      OFDM_SC_RA_RAM_OP_PARAM_HIER_A4                               0xC0
-#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2                              0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3                              0x200
-#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4                              0x400
-#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6                              0x600
-#define      OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8                              0x800
-#define      OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI                               0x0
-#define      OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO                               0x1000
-#define    OFDM_SC_RA_RAM_OP_AUTO_MODE__M                                  0x1
-#define    OFDM_SC_RA_RAM_OP_AUTO_GUARD__M                                 0x2
-#define    OFDM_SC_RA_RAM_OP_AUTO_CONST__M                                 0x4
-#define    OFDM_SC_RA_RAM_OP_AUTO_HIER__M                                  0x8
-#define    OFDM_SC_RA_RAM_OP_AUTO_RATE__M                                  0x10
-#define  OFDM_SC_RA_RAM_LOCK__A                                            0x3C2004B
-#define    OFDM_SC_RA_RAM_LOCK_DEMOD__M                                    0x1
-#define    OFDM_SC_RA_RAM_LOCK_FEC__M                                      0x2
-#define    OFDM_SC_RA_RAM_LOCK_MPEG__M                                     0x4
-#define    OFDM_SC_RA_RAM_LOCK_NODVBT__M                                   0x8
-#define  OFDM_SC_RA_RAM_BE_OPT_DELAY__A                                    0x3C2004D
-#define  OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A                               0x3C2004E
-#define  OFDM_SC_RA_RAM_ECHO_THRES__A                                      0x3C2004F
-#define    OFDM_SC_RA_RAM_ECHO_THRES_8K__B                                 0
-#define    OFDM_SC_RA_RAM_ECHO_THRES_8K__M                                 0xFF
-#define    OFDM_SC_RA_RAM_ECHO_THRES_2K__B                                 8
-#define    OFDM_SC_RA_RAM_ECHO_THRES_2K__M                                 0xFF00
-#define  OFDM_SC_RA_RAM_CONFIG__A                                          0x3C20050
-#define    OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M                          0x800
-#define  OFDM_SC_RA_RAM_FR_THRES_8K__A                                     0x3C2007D
-#define  OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A                             0x3C200E0
-#define  OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A                            0x3C200E1
-#define  OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A                             0x3C200E3
-#define  OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A                            0x3C200E4
-#define  OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A                                0x3C200F8
-#define  QAM_COMM_EXEC__A                                                  0x1400000
-#define    QAM_COMM_EXEC_STOP                                              0x0
-#define    QAM_COMM_EXEC_ACTIVE                                            0x1
-#define    QAM_TOP_ANNEX_A                                                 0x0
-#define    QAM_TOP_ANNEX_C                                                 0x2
-#define  QAM_SL_ERR_POWER__A                                               0x1430017
-#define  QAM_DQ_QUAL_FUN0__A                                               0x1440018
-#define  QAM_DQ_QUAL_FUN1__A                                               0x1440019
-#define  QAM_DQ_QUAL_FUN2__A                                               0x144001A
-#define  QAM_DQ_QUAL_FUN3__A                                               0x144001B
-#define  QAM_DQ_QUAL_FUN4__A                                               0x144001C
-#define  QAM_DQ_QUAL_FUN5__A                                               0x144001D
-#define  QAM_LC_MODE__A                                                    0x1450010
-#define  QAM_LC_QUAL_TAB0__A                                               0x1450018
-#define  QAM_LC_QUAL_TAB1__A                                               0x1450019
-#define  QAM_LC_QUAL_TAB2__A                                               0x145001A
-#define  QAM_LC_QUAL_TAB3__A                                               0x145001B
-#define  QAM_LC_QUAL_TAB4__A                                               0x145001C
-#define  QAM_LC_QUAL_TAB5__A                                               0x145001D
-#define  QAM_LC_QUAL_TAB6__A                                               0x145001E
-#define  QAM_LC_QUAL_TAB8__A                                               0x145001F
-#define  QAM_LC_QUAL_TAB9__A                                               0x1450020
-#define  QAM_LC_QUAL_TAB10__A                                              0x1450021
-#define  QAM_LC_QUAL_TAB12__A                                              0x1450022
-#define  QAM_LC_QUAL_TAB15__A                                              0x1450023
-#define  QAM_LC_QUAL_TAB16__A                                              0x1450024
-#define  QAM_LC_QUAL_TAB20__A                                              0x1450025
-#define  QAM_LC_QUAL_TAB25__A                                              0x1450026
-#define  QAM_LC_LPF_FACTORP__A                                             0x1450028
-#define  QAM_LC_LPF_FACTORI__A                                             0x1450029
-#define  QAM_LC_RATE_LIMIT__A                                              0x145002A
-#define  QAM_LC_SYMBOL_FREQ__A                                             0x145002B
-#define  QAM_SY_TIMEOUT__A                                                 0x1470011
-#define  QAM_SY_TIMEOUT__PRE                                               0x3A98
-#define  QAM_SY_SYNC_LWM__A                                                0x1470012
-#define  QAM_SY_SYNC_AWM__A                                                0x1470013
-#define  QAM_SY_SYNC_HWM__A                                                0x1470014
-#define  QAM_SY_SP_INV__A                                                  0x1470017
-#define    QAM_SY_SP_INV_SPECTRUM_INV_DIS                                  0x0
-#define  SCU_COMM_EXEC__A                                                  0x800000
-#define    SCU_COMM_EXEC_STOP                                              0x0
-#define    SCU_COMM_EXEC_ACTIVE                                            0x1
-#define    SCU_COMM_EXEC_HOLD                                              0x2
-#define  SCU_RAM_DRIVER_DEBUG__A                                           0x831EBF
-#define  SCU_RAM_QAM_FSM_STEP_PERIOD__A                                    0x831EC4
-#define  SCU_RAM_GPIO__A                                                   0x831EC7
-#define      SCU_RAM_GPIO_HW_LOCK_IND_DISABLE                              0x0
-#define  SCU_RAM_AGC_CLP_CTRL_MODE__A                                      0x831EC8
-#define  SCU_RAM_FEC_ACCUM_PKT_FAILURES__A                                 0x831ECB
-#define  SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A                               0x831F05
-#define  SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A                                0x831F15
-#define  SCU_RAM_AGC_KI_CYCLEN__A                                          0x831F17
-#define  SCU_RAM_AGC_SNS_CYCLEN__A                                         0x831F18
-#define  SCU_RAM_AGC_RF_SNS_DEV_MAX__A                                     0x831F19
-#define  SCU_RAM_AGC_RF_SNS_DEV_MIN__A                                     0x831F1A
-#define  SCU_RAM_AGC_RF_MAX__A                                             0x831F1B
-#define  SCU_RAM_AGC_CONFIG__A                                             0x831F24
-#define    SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M                            0x1
-#define    SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M                            0x2
-#define    SCU_RAM_AGC_CONFIG_INV_IF_POL__M                                0x100
-#define    SCU_RAM_AGC_CONFIG_INV_RF_POL__M                                0x200
-#define  SCU_RAM_AGC_KI__A                                                 0x831F25
-#define    SCU_RAM_AGC_KI_RF__B                                            4
-#define    SCU_RAM_AGC_KI_RF__M                                            0xF0
-#define    SCU_RAM_AGC_KI_IF__B                                            8
-#define    SCU_RAM_AGC_KI_IF__M                                            0xF00
-#define  SCU_RAM_AGC_KI_RED__A                                             0x831F26
-#define    SCU_RAM_AGC_KI_RED_RAGC_RED__B                                  2
-#define    SCU_RAM_AGC_KI_RED_RAGC_RED__M                                  0xC
-#define    SCU_RAM_AGC_KI_RED_IAGC_RED__B                                  4
-#define    SCU_RAM_AGC_KI_RED_IAGC_RED__M                                  0x30
-#define  SCU_RAM_AGC_KI_INNERGAIN_MIN__A                                   0x831F27
-#define  SCU_RAM_AGC_KI_MINGAIN__A                                         0x831F28
-#define  SCU_RAM_AGC_KI_MAXGAIN__A                                         0x831F29
-#define  SCU_RAM_AGC_KI_MAXMINGAIN_TH__A                                   0x831F2A
-#define  SCU_RAM_AGC_KI_MIN__A                                             0x831F2B
-#define  SCU_RAM_AGC_KI_MAX__A                                             0x831F2C
-#define  SCU_RAM_AGC_CLP_SUM__A                                            0x831F2D
-#define  SCU_RAM_AGC_CLP_SUM_MIN__A                                        0x831F2E
-#define  SCU_RAM_AGC_CLP_SUM_MAX__A                                        0x831F2F
-#define  SCU_RAM_AGC_CLP_CYCLEN__A                                         0x831F30
-#define  SCU_RAM_AGC_CLP_CYCCNT__A                                         0x831F31
-#define  SCU_RAM_AGC_CLP_DIR_TO__A                                         0x831F32
-#define  SCU_RAM_AGC_CLP_DIR_WD__A                                         0x831F33
-#define  SCU_RAM_AGC_CLP_DIR_STP__A                                        0x831F34
-#define  SCU_RAM_AGC_SNS_SUM__A                                            0x831F35
-#define  SCU_RAM_AGC_SNS_SUM_MIN__A                                        0x831F36
-#define  SCU_RAM_AGC_SNS_SUM_MAX__A                                        0x831F37
-#define  SCU_RAM_AGC_SNS_CYCCNT__A                                         0x831F38
-#define  SCU_RAM_AGC_SNS_DIR_TO__A                                         0x831F39
-#define  SCU_RAM_AGC_SNS_DIR_WD__A                                         0x831F3A
-#define  SCU_RAM_AGC_SNS_DIR_STP__A                                        0x831F3B
-#define  SCU_RAM_AGC_INGAIN_TGT__A                                         0x831F3D
-#define  SCU_RAM_AGC_INGAIN_TGT_MIN__A                                     0x831F3E
-#define  SCU_RAM_AGC_INGAIN_TGT_MAX__A                                     0x831F3F
-#define  SCU_RAM_AGC_IF_IACCU_HI__A                                        0x831F40
-#define  SCU_RAM_AGC_IF_IACCU_LO__A                                        0x831F41
-#define  SCU_RAM_AGC_IF_IACCU_HI_TGT__A                                    0x831F42
-#define  SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A                                0x831F43
-#define  SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A                                0x831F44
-#define  SCU_RAM_AGC_RF_IACCU_HI__A                                        0x831F45
-#define  SCU_RAM_AGC_RF_IACCU_LO__A                                        0x831F46
-#define  SCU_RAM_AGC_RF_IACCU_HI_CO__A                                     0x831F47
-#define  SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A                                 0x831F84
-#define  SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A                                0x831F85
-#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A                                  0x831F86
-#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A                                  0x831F87
-#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A                                  0x831F88
-#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A                                  0x831F89
-#define  SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A                                  0x831F8A
-#define  SCU_RAM_QAM_FSM_RTH__A                                            0x831F8E
-#define  SCU_RAM_QAM_FSM_FTH__A                                            0x831F8F
-#define  SCU_RAM_QAM_FSM_PTH__A                                            0x831F90
-#define  SCU_RAM_QAM_FSM_MTH__A                                            0x831F91
-#define  SCU_RAM_QAM_FSM_CTH__A                                            0x831F92
-#define  SCU_RAM_QAM_FSM_QTH__A                                            0x831F93
-#define  SCU_RAM_QAM_FSM_RATE_LIM__A                                       0x831F94
-#define  SCU_RAM_QAM_FSM_FREQ_LIM__A                                       0x831F95
-#define  SCU_RAM_QAM_FSM_COUNT_LIM__A                                      0x831F96
-#define  SCU_RAM_QAM_LC_CA_COARSE__A                                       0x831F97
-#define  SCU_RAM_QAM_LC_CA_FINE__A                                         0x831F99
-#define  SCU_RAM_QAM_LC_CP_COARSE__A                                       0x831F9A
-#define  SCU_RAM_QAM_LC_CP_MEDIUM__A                                       0x831F9B
-#define  SCU_RAM_QAM_LC_CP_FINE__A                                         0x831F9C
-#define  SCU_RAM_QAM_LC_CI_COARSE__A                                       0x831F9D
-#define  SCU_RAM_QAM_LC_CI_MEDIUM__A                                       0x831F9E
-#define  SCU_RAM_QAM_LC_CI_FINE__A                                         0x831F9F
-#define  SCU_RAM_QAM_LC_EP_COARSE__A                                       0x831FA0
-#define  SCU_RAM_QAM_LC_EP_MEDIUM__A                                       0x831FA1
-#define  SCU_RAM_QAM_LC_EP_FINE__A                                         0x831FA2
-#define  SCU_RAM_QAM_LC_EI_COARSE__A                                       0x831FA3
-#define  SCU_RAM_QAM_LC_EI_MEDIUM__A                                       0x831FA4
-#define  SCU_RAM_QAM_LC_EI_FINE__A                                         0x831FA5
-#define  SCU_RAM_QAM_LC_CF_COARSE__A                                       0x831FA6
-#define  SCU_RAM_QAM_LC_CF_MEDIUM__A                                       0x831FA7
-#define  SCU_RAM_QAM_LC_CF_FINE__A                                         0x831FA8
-#define  SCU_RAM_QAM_LC_CF1_COARSE__A                                      0x831FA9
-#define  SCU_RAM_QAM_LC_CF1_MEDIUM__A                                      0x831FAA
-#define  SCU_RAM_QAM_LC_CF1_FINE__A                                        0x831FAB
-#define  SCU_RAM_QAM_SL_SIG_POWER__A                                       0x831FAC
-#define  SCU_RAM_QAM_EQ_CMA_RAD0__A                                        0x831FAD
-#define  SCU_RAM_QAM_EQ_CMA_RAD1__A                                        0x831FAE
-#define  SCU_RAM_QAM_EQ_CMA_RAD2__A                                        0x831FAF
-#define  SCU_RAM_QAM_EQ_CMA_RAD3__A                                        0x831FB0
-#define  SCU_RAM_QAM_EQ_CMA_RAD4__A                                        0x831FB1
-#define  SCU_RAM_QAM_EQ_CMA_RAD5__A                                        0x831FB2
-#define      SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED                        0x4000
-#define      SCU_RAM_QAM_LOCKED_LOCKED_LOCKED                              0x8000
-#define      SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK                          0xC000
-#define  SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A                                0x831FEA
-#define  SCU_RAM_DRIVER_VER_HI__A                                          0x831FEB
-#define  SCU_RAM_DRIVER_VER_LO__A                                          0x831FEC
-#define  SCU_RAM_PARAM_15__A                                               0x831FED
-#define  SCU_RAM_PARAM_0__A                                                0x831FFC
-#define  SCU_RAM_COMMAND__A                                                0x831FFD
-#define    SCU_RAM_COMMAND_CMD_DEMOD_RESET                                 0x1
-#define    SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV                               0x2
-#define    SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM                             0x3
-#define    SCU_RAM_COMMAND_CMD_DEMOD_START                                 0x4
-#define    SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK                              0x5
-#define    SCU_RAM_COMMAND_CMD_DEMOD_STOP                                  0x9
-#define      SCU_RAM_COMMAND_STANDARD_QAM                                  0x200
-#define      SCU_RAM_COMMAND_STANDARD_OFDM                                 0x400
-#define  SIO_TOP_COMM_KEY__A                                               0x41000F
-#define    SIO_TOP_COMM_KEY_KEY                                            0xFABA
-#define  SIO_TOP_JTAGID_LO__A                                              0x410012
-#define  SIO_HI_RA_RAM_RES__A                                              0x420031
-#define  SIO_HI_RA_RAM_CMD__A                                              0x420032
-#define    SIO_HI_RA_RAM_CMD_RESET                                         0x2
-#define    SIO_HI_RA_RAM_CMD_CONFIG                                        0x3
-#define    SIO_HI_RA_RAM_CMD_BRDCTRL                                       0x7
-#define  SIO_HI_RA_RAM_PAR_1__A                                            0x420033
-#define      SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY                              0x3945
-#define  SIO_HI_RA_RAM_PAR_2__A                                            0x420034
-#define    SIO_HI_RA_RAM_PAR_2_CFG_DIV__M                                  0x7F
-#define      SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN                              0x0
-#define      SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED                            0x4
-#define  SIO_HI_RA_RAM_PAR_3__A                                            0x420035
-#define    SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M                              0x7F
-#define    SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B                              7
-#define      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ                               0x0
-#define      SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE                              0x8
-#define  SIO_HI_RA_RAM_PAR_4__A                                            0x420036
-#define  SIO_HI_RA_RAM_PAR_5__A                                            0x420037
-#define      SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE                            0x1
-#define    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M                                0x8
-#define      SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ                             0x8
-#define  SIO_HI_RA_RAM_PAR_6__A                                            0x420038
-#define  SIO_CC_PLL_LOCK__A                                                0x450012
-#define  SIO_CC_PWD_MODE__A                                                0x450015
-#define      SIO_CC_PWD_MODE_LEVEL_NONE                                    0x0
-#define      SIO_CC_PWD_MODE_LEVEL_OFDM                                    0x1
-#define      SIO_CC_PWD_MODE_LEVEL_CLOCK                                   0x2
-#define      SIO_CC_PWD_MODE_LEVEL_PLL                                     0x3
-#define      SIO_CC_PWD_MODE_LEVEL_OSC                                     0x4
-#define  SIO_CC_SOFT_RST__A                                                0x450016
-#define    SIO_CC_SOFT_RST_OFDM__M                                         0x1
-#define    SIO_CC_SOFT_RST_SYS__M                                          0x2
-#define    SIO_CC_SOFT_RST_OSC__M                                          0x4
-#define  SIO_CC_UPDATE__A                                                  0x450017
-#define    SIO_CC_UPDATE_KEY                                               0xFABA
-#define  SIO_OFDM_SH_OFDM_RING_ENABLE__A                                   0x470010
-#define    SIO_OFDM_SH_OFDM_RING_ENABLE_OFF                                0x0
-#define    SIO_OFDM_SH_OFDM_RING_ENABLE_ON                                 0x1
-#define  SIO_OFDM_SH_OFDM_RING_STATUS__A                                   0x470012
-#define    SIO_OFDM_SH_OFDM_RING_STATUS_DOWN                               0x0
-#define    SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED                            0x1
-#define  SIO_BL_COMM_EXEC__A                                               0x480000
-#define    SIO_BL_COMM_EXEC_ACTIVE                                         0x1
-#define  SIO_BL_STATUS__A                                                  0x480010
-#define  SIO_BL_MODE__A                                                    0x480011
-#define    SIO_BL_MODE_DIRECT                                              0x0
-#define    SIO_BL_MODE_CHAIN                                               0x1
-#define  SIO_BL_ENABLE__A                                                  0x480012
-#define    SIO_BL_ENABLE_ON                                                0x1
-#define  SIO_BL_TGT_HDR__A                                                 0x480014
-#define  SIO_BL_TGT_ADDR__A                                                0x480015
-#define  SIO_BL_SRC_ADDR__A                                                0x480016
-#define  SIO_BL_SRC_LEN__A                                                 0x480017
-#define  SIO_BL_CHAIN_ADDR__A                                              0x480018
-#define  SIO_BL_CHAIN_LEN__A                                               0x480019
-#define  SIO_PDR_MON_CFG__A                                                0x7F0010
-#define  SIO_PDR_UIO_IN_HI__A                                              0x7F0015
-#define  SIO_PDR_UIO_OUT_LO__A                                             0x7F0016
-#define  SIO_PDR_OHW_CFG__A                                                0x7F001F
-#define    SIO_PDR_OHW_CFG_FREF_SEL__M                                     0x3
-#define  SIO_PDR_GPIO_CFG__A                                               0x7F0021
-#define  SIO_PDR_MSTRT_CFG__A                                              0x7F0025
-#define  SIO_PDR_MERR_CFG__A                                               0x7F0026
-#define  SIO_PDR_MCLK_CFG__A                                               0x7F0028
-#define    SIO_PDR_MCLK_CFG_DRIVE__B                                       3
-#define  SIO_PDR_MVAL_CFG__A                                               0x7F0029
-#define  SIO_PDR_MD0_CFG__A                                                0x7F002A
-#define    SIO_PDR_MD0_CFG_DRIVE__B                                        3
-#define  SIO_PDR_MD1_CFG__A                                                0x7F002B
-#define  SIO_PDR_MD2_CFG__A                                                0x7F002C
-#define  SIO_PDR_MD3_CFG__A                                                0x7F002D
-#define  SIO_PDR_MD4_CFG__A                                                0x7F002F
-#define  SIO_PDR_MD5_CFG__A                                                0x7F0030
-#define  SIO_PDR_MD6_CFG__A                                                0x7F0031
-#define  SIO_PDR_MD7_CFG__A                                                0x7F0032
-#define  SIO_PDR_SMA_RX_CFG__A                                             0x7F0037
-#define  SIO_PDR_SMA_TX_CFG__A                                             0x7F0038
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
deleted file mode 100644 (file)
index 4c8ac26..0000000
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
-    Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
-    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
-
-    Copyright (C) 2009 TurboSight.com
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/firmware.h>
-
-#include "dvb_frontend.h"
-#include "ds3000.h"
-
-static int debug;
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(args); \
-       } while (0)
-
-/* as of March 2009 current DS3000 firmware version is 1.78 */
-/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
-#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
-
-#define DS3000_SAMPLE_RATE 96000 /* in kHz */
-#define DS3000_XTAL_FREQ   27000 /* in kHz */
-
-/* Register values to initialise the demod in DVB-S mode */
-static u8 ds3000_dvbs_init_tab[] = {
-       0x23, 0x05,
-       0x08, 0x03,
-       0x0c, 0x00,
-       0x21, 0x54,
-       0x25, 0x82,
-       0x27, 0x31,
-       0x30, 0x08,
-       0x31, 0x40,
-       0x32, 0x32,
-       0x33, 0x35,
-       0x35, 0xff,
-       0x3a, 0x00,
-       0x37, 0x10,
-       0x38, 0x10,
-       0x39, 0x02,
-       0x42, 0x60,
-       0x4a, 0x40,
-       0x4b, 0x04,
-       0x4d, 0x91,
-       0x5d, 0xc8,
-       0x50, 0x77,
-       0x51, 0x77,
-       0x52, 0x36,
-       0x53, 0x36,
-       0x56, 0x01,
-       0x63, 0x43,
-       0x64, 0x30,
-       0x65, 0x40,
-       0x68, 0x26,
-       0x69, 0x4c,
-       0x70, 0x20,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x40,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x60,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x80,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0xa0,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x1f,
-       0x76, 0x00,
-       0x77, 0xd1,
-       0x78, 0x0c,
-       0x79, 0x80,
-       0x7f, 0x04,
-       0x7c, 0x00,
-       0x80, 0x86,
-       0x81, 0xa6,
-       0x85, 0x04,
-       0xcd, 0xf4,
-       0x90, 0x33,
-       0xa0, 0x44,
-       0xc0, 0x18,
-       0xc3, 0x10,
-       0xc4, 0x08,
-       0xc5, 0x80,
-       0xc6, 0x80,
-       0xc7, 0x0a,
-       0xc8, 0x1a,
-       0xc9, 0x80,
-       0xfe, 0x92,
-       0xe0, 0xf8,
-       0xe6, 0x8b,
-       0xd0, 0x40,
-       0xf8, 0x20,
-       0xfa, 0x0f,
-       0xfd, 0x20,
-       0xad, 0x20,
-       0xae, 0x07,
-       0xb8, 0x00,
-};
-
-/* Register values to initialise the demod in DVB-S2 mode */
-static u8 ds3000_dvbs2_init_tab[] = {
-       0x23, 0x0f,
-       0x08, 0x07,
-       0x0c, 0x00,
-       0x21, 0x54,
-       0x25, 0x82,
-       0x27, 0x31,
-       0x30, 0x08,
-       0x31, 0x32,
-       0x32, 0x32,
-       0x33, 0x35,
-       0x35, 0xff,
-       0x3a, 0x00,
-       0x37, 0x10,
-       0x38, 0x10,
-       0x39, 0x02,
-       0x42, 0x60,
-       0x4a, 0x80,
-       0x4b, 0x04,
-       0x4d, 0x81,
-       0x5d, 0x88,
-       0x50, 0x36,
-       0x51, 0x36,
-       0x52, 0x36,
-       0x53, 0x36,
-       0x63, 0x60,
-       0x64, 0x10,
-       0x65, 0x10,
-       0x68, 0x04,
-       0x69, 0x29,
-       0x70, 0x20,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x40,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x60,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x80,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0xa0,
-       0x71, 0x70,
-       0x72, 0x04,
-       0x73, 0x00,
-       0x70, 0x1f,
-       0xa0, 0x44,
-       0xc0, 0x08,
-       0xc1, 0x10,
-       0xc2, 0x08,
-       0xc3, 0x10,
-       0xc4, 0x08,
-       0xc5, 0xf0,
-       0xc6, 0xf0,
-       0xc7, 0x0a,
-       0xc8, 0x1a,
-       0xc9, 0x80,
-       0xca, 0x23,
-       0xcb, 0x24,
-       0xce, 0x74,
-       0x90, 0x03,
-       0x76, 0x80,
-       0x77, 0x42,
-       0x78, 0x0a,
-       0x79, 0x80,
-       0xad, 0x40,
-       0xae, 0x07,
-       0x7f, 0xd4,
-       0x7c, 0x00,
-       0x80, 0xa8,
-       0x81, 0xda,
-       0x7c, 0x01,
-       0x80, 0xda,
-       0x81, 0xec,
-       0x7c, 0x02,
-       0x80, 0xca,
-       0x81, 0xeb,
-       0x7c, 0x03,
-       0x80, 0xba,
-       0x81, 0xdb,
-       0x85, 0x08,
-       0x86, 0x00,
-       0x87, 0x02,
-       0x89, 0x80,
-       0x8b, 0x44,
-       0x8c, 0xaa,
-       0x8a, 0x10,
-       0xba, 0x00,
-       0xf5, 0x04,
-       0xfe, 0x44,
-       0xd2, 0x32,
-       0xb8, 0x00,
-};
-
-struct ds3000_state {
-       struct i2c_adapter *i2c;
-       const struct ds3000_config *config;
-       struct dvb_frontend frontend;
-       u8 skip_fw_load;
-       /* previous uncorrected block counter for DVB-S2 */
-       u16 prevUCBS2;
-};
-
-static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-               .flags = 0, .buf = buf, .len = 2 };
-       int err;
-
-       dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
-
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
-                        " value == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = 0x60,
-               .flags = 0, .buf = buf, .len = 2 };
-       int err;
-
-       dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
-
-       ds3000_writereg(state, 0x03, 0x11);
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk("%s: writereg error(err == %i, reg == 0x%02x,"
-                        " value == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-/* I2C write for 8k firmware load */
-static int ds3000_writeFW(struct ds3000_state *state, int reg,
-                               const u8 *data, u16 len)
-{
-       int i, ret = -EREMOTEIO;
-       struct i2c_msg msg;
-       u8 *buf;
-
-       buf = kmalloc(33, GFP_KERNEL);
-       if (buf == NULL) {
-               printk(KERN_ERR "Unable to kmalloc\n");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       *(buf) = reg;
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.buf = buf;
-       msg.len = 33;
-
-       for (i = 0; i < len; i += 32) {
-               memcpy(buf + 1, data + i, 32);
-
-               dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
-
-               ret = i2c_transfer(state->i2c, &msg, 1);
-               if (ret != 1) {
-                       printk(KERN_ERR "%s: write error(err == %i, "
-                               "reg == 0x%02x\n", __func__, ret, reg);
-                       ret = -EREMOTEIO;
-               }
-       }
-
-error:
-       kfree(buf);
-
-       return ret;
-}
-
-static int ds3000_readreg(struct ds3000_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
-               return ret;
-       }
-
-       dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
-
-       return b1[0];
-}
-
-static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = 0x60,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = 0x60,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-
-       ds3000_writereg(state, 0x03, 0x12);
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
-               return ret;
-       }
-
-       dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
-
-       return b1[0];
-}
-
-static int ds3000_load_firmware(struct dvb_frontend *fe,
-                                       const struct firmware *fw);
-
-static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret = 0;
-
-       dprintk("%s()\n", __func__);
-
-       if (ds3000_readreg(state, 0xb2) <= 0)
-               return ret;
-
-       if (state->skip_fw_load)
-               return 0;
-       /* Load firmware */
-       /* request the firmware, this will block until someone uploads it */
-       printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
-                               DS3000_DEFAULT_FIRMWARE);
-       ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
-                               state->i2c->dev.parent);
-       printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
-       if (ret) {
-               printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
-                               "found?)\n", __func__);
-               return ret;
-       }
-
-       /* Make sure we don't recurse back through here during loading */
-       state->skip_fw_load = 1;
-
-       ret = ds3000_load_firmware(fe, fw);
-       if (ret)
-               printk("%s: Writing firmware to device failed\n", __func__);
-
-       release_firmware(fw);
-
-       dprintk("%s: Firmware upload %s\n", __func__,
-                       ret == 0 ? "complete" : "failed");
-
-       /* Ensure firmware is always loaded if required */
-       state->skip_fw_load = 0;
-
-       return ret;
-}
-
-static int ds3000_load_firmware(struct dvb_frontend *fe,
-                                       const struct firmware *fw)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-       dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
-                       fw->size,
-                       fw->data[0],
-                       fw->data[1],
-                       fw->data[fw->size - 2],
-                       fw->data[fw->size - 1]);
-
-       /* Begin the firmware load process */
-       ds3000_writereg(state, 0xb2, 0x01);
-       /* write the entire firmware */
-       ds3000_writeFW(state, 0xb0, fw->data, fw->size);
-       ds3000_writereg(state, 0xb2, 0x00);
-
-       return 0;
-}
-
-static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       u8 data;
-
-       dprintk("%s(%d)\n", __func__, voltage);
-
-       data = ds3000_readreg(state, 0xa2);
-       data |= 0x03; /* bit0 V/H, bit1 off/on */
-
-       switch (voltage) {
-       case SEC_VOLTAGE_18:
-               data &= ~0x03;
-               break;
-       case SEC_VOLTAGE_13:
-               data &= ~0x03;
-               data |= 0x01;
-               break;
-       case SEC_VOLTAGE_OFF:
-               break;
-       }
-
-       ds3000_writereg(state, 0xa2, data);
-
-       return 0;
-}
-
-static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int lock;
-
-       *status = 0;
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               lock = ds3000_readreg(state, 0xd1);
-               if ((lock & 0x07) == 0x07)
-                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC |
-                               FE_HAS_LOCK;
-
-               break;
-       case SYS_DVBS2:
-               lock = ds3000_readreg(state, 0x0d);
-               if ((lock & 0x8f) == 0x8f)
-                       *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC |
-                               FE_HAS_LOCK;
-
-               break;
-       default:
-               return 1;
-       }
-
-       dprintk("%s: status = 0x%02x\n", __func__, lock);
-
-       return 0;
-}
-
-/* read DS3000 BER value */
-static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 data;
-       u32 ber_reading, lpdc_frames;
-
-       dprintk("%s()\n", __func__);
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               /* set the number of bytes checked during
-               BER estimation */
-               ds3000_writereg(state, 0xf9, 0x04);
-               /* read BER estimation status */
-               data = ds3000_readreg(state, 0xf8);
-               /* check if BER estimation is ready */
-               if ((data & 0x10) == 0) {
-                       /* this is the number of error bits,
-                       to calculate the bit error rate
-                       divide to 8388608 */
-                       *ber = (ds3000_readreg(state, 0xf7) << 8) |
-                               ds3000_readreg(state, 0xf6);
-                       /* start counting error bits */
-                       /* need to be set twice
-                       otherwise it fails sometimes */
-                       data |= 0x10;
-                       ds3000_writereg(state, 0xf8, data);
-                       ds3000_writereg(state, 0xf8, data);
-               } else
-                       /* used to indicate that BER estimation
-                       is not ready, i.e. BER is unknown */
-                       *ber = 0xffffffff;
-               break;
-       case SYS_DVBS2:
-               /* read the number of LPDC decoded frames */
-               lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
-                               (ds3000_readreg(state, 0xd6) << 8) |
-                               ds3000_readreg(state, 0xd5);
-               /* read the number of packets with bad CRC */
-               ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
-                               ds3000_readreg(state, 0xf7);
-               if (lpdc_frames > 750) {
-                       /* clear LPDC frame counters */
-                       ds3000_writereg(state, 0xd1, 0x01);
-                       /* clear bad packets counter */
-                       ds3000_writereg(state, 0xf9, 0x01);
-                       /* enable bad packets counter */
-                       ds3000_writereg(state, 0xf9, 0x00);
-                       /* enable LPDC frame counters */
-                       ds3000_writereg(state, 0xd1, 0x00);
-                       *ber = ber_reading;
-               } else
-                       /* used to indicate that BER estimation is not ready,
-                       i.e. BER is unknown */
-                       *ber = 0xffffffff;
-               break;
-       default:
-               return 1;
-       }
-
-       return 0;
-}
-
-/* read TS2020 signal strength */
-static int ds3000_read_signal_strength(struct dvb_frontend *fe,
-                                               u16 *signal_strength)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       u16 sig_reading, sig_strength;
-       u8 rfgain, bbgain;
-
-       dprintk("%s()\n", __func__);
-
-       rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
-       bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
-
-       if (rfgain > 15)
-               rfgain = 15;
-       if (bbgain > 13)
-               bbgain = 13;
-
-       sig_reading = rfgain * 2 + bbgain * 3;
-
-       sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
-
-       /* cook the value to be suitable for szap-s2 human readable output */
-       *signal_strength = sig_strength * 1000;
-
-       dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
-                       sig_reading, *signal_strength);
-
-       return 0;
-}
-
-/* calculate DS3000 snr value in dB */
-static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 snr_reading, snr_value;
-       u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
-       static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
-               0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
-               0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
-               0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
-       };
-       static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
-               0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
-               0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
-               0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
-               0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
-               0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
-               0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
-               0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
-               0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
-               0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
-               0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
-               0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
-               0x49e9, 0x4a20, 0x4a57
-       };
-
-       dprintk("%s()\n", __func__);
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               snr_reading = ds3000_readreg(state, 0xff);
-               snr_reading /= 8;
-               if (snr_reading == 0)
-                       *snr = 0x0000;
-               else {
-                       if (snr_reading > 20)
-                               snr_reading = 20;
-                       snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
-                       /* cook the value to be suitable for szap-s2
-                       human readable output */
-                       *snr = snr_value * 8 * 655;
-               }
-               dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
-                               snr_reading, *snr);
-               break;
-       case SYS_DVBS2:
-               dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
-                               (ds3000_readreg(state, 0x8d) << 4);
-               dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
-               tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
-               if (tmp == 0) {
-                       *snr = 0x0000;
-                       return 0;
-               }
-               if (dvbs2_noise_reading == 0) {
-                       snr_value = 0x0013;
-                       /* cook the value to be suitable for szap-s2
-                       human readable output */
-                       *snr = 0xffff;
-                       return 0;
-               }
-               if (tmp > dvbs2_noise_reading) {
-                       snr_reading = tmp / dvbs2_noise_reading;
-                       if (snr_reading > 80)
-                               snr_reading = 80;
-                       snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
-                       /* cook the value to be suitable for szap-s2
-                       human readable output */
-                       *snr = snr_value * 5 * 655;
-               } else {
-                       snr_reading = dvbs2_noise_reading / tmp;
-                       if (snr_reading > 80)
-                               snr_reading = 80;
-                       *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
-               }
-               dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
-                               snr_reading, *snr);
-               break;
-       default:
-               return 1;
-       }
-
-       return 0;
-}
-
-/* read DS3000 uncorrected blocks */
-static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 data;
-       u16 _ucblocks;
-
-       dprintk("%s()\n", __func__);
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
-                               ds3000_readreg(state, 0xf4);
-               data = ds3000_readreg(state, 0xf8);
-               /* clear packet counters */
-               data &= ~0x20;
-               ds3000_writereg(state, 0xf8, data);
-               /* enable packet counters */
-               data |= 0x20;
-               ds3000_writereg(state, 0xf8, data);
-               break;
-       case SYS_DVBS2:
-               _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
-                               ds3000_readreg(state, 0xe1);
-               if (_ucblocks > state->prevUCBS2)
-                       *ucblocks = _ucblocks - state->prevUCBS2;
-               else
-                       *ucblocks = state->prevUCBS2 - _ucblocks;
-               state->prevUCBS2 = _ucblocks;
-               break;
-       default:
-               return 1;
-       }
-
-       return 0;
-}
-
-static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       u8 data;
-
-       dprintk("%s(%d)\n", __func__, tone);
-       if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
-               printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
-               return -EINVAL;
-       }
-
-       data = ds3000_readreg(state, 0xa2);
-       data &= ~0xc0;
-       ds3000_writereg(state, 0xa2, data);
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               dprintk("%s: setting tone on\n", __func__);
-               data = ds3000_readreg(state, 0xa1);
-               data &= ~0x43;
-               data |= 0x04;
-               ds3000_writereg(state, 0xa1, data);
-               break;
-       case SEC_TONE_OFF:
-               dprintk("%s: setting tone off\n", __func__);
-               data = ds3000_readreg(state, 0xa2);
-               data |= 0x80;
-               ds3000_writereg(state, 0xa2, data);
-               break;
-       }
-
-       return 0;
-}
-
-static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
-                               struct dvb_diseqc_master_cmd *d)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       int i;
-       u8 data;
-
-       /* Dump DiSEqC message */
-       dprintk("%s(", __func__);
-       for (i = 0 ; i < d->msg_len;) {
-               dprintk("0x%02x", d->msg[i]);
-               if (++i < d->msg_len)
-                       dprintk(", ");
-       }
-
-       /* enable DiSEqC message send pin */
-       data = ds3000_readreg(state, 0xa2);
-       data &= ~0xc0;
-       ds3000_writereg(state, 0xa2, data);
-
-       /* DiSEqC message */
-       for (i = 0; i < d->msg_len; i++)
-               ds3000_writereg(state, 0xa3 + i, d->msg[i]);
-
-       data = ds3000_readreg(state, 0xa1);
-       /* clear DiSEqC message length and status,
-       enable DiSEqC message send */
-       data &= ~0xf8;
-       /* set DiSEqC mode, modulation active during 33 pulses,
-       set DiSEqC message length */
-       data |= ((d->msg_len - 1) << 3) | 0x07;
-       ds3000_writereg(state, 0xa1, data);
-
-       /* wait up to 150ms for DiSEqC transmission to complete */
-       for (i = 0; i < 15; i++) {
-               data = ds3000_readreg(state, 0xa1);
-               if ((data & 0x40) == 0)
-                       break;
-               msleep(10);
-       }
-
-       /* DiSEqC timeout after 150ms */
-       if (i == 15) {
-               data = ds3000_readreg(state, 0xa1);
-               data &= ~0x80;
-               data |= 0x40;
-               ds3000_writereg(state, 0xa1, data);
-
-               data = ds3000_readreg(state, 0xa2);
-               data &= ~0xc0;
-               data |= 0x80;
-               ds3000_writereg(state, 0xa2, data);
-
-               return 1;
-       }
-
-       data = ds3000_readreg(state, 0xa2);
-       data &= ~0xc0;
-       data |= 0x80;
-       ds3000_writereg(state, 0xa2, data);
-
-       return 0;
-}
-
-/* Send DiSEqC burst */
-static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
-                                       fe_sec_mini_cmd_t burst)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       int i;
-       u8 data;
-
-       dprintk("%s()\n", __func__);
-
-       data = ds3000_readreg(state, 0xa2);
-       data &= ~0xc0;
-       ds3000_writereg(state, 0xa2, data);
-
-       /* DiSEqC burst */
-       if (burst == SEC_MINI_A)
-               /* Unmodulated tone burst */
-               ds3000_writereg(state, 0xa1, 0x02);
-       else if (burst == SEC_MINI_B)
-               /* Modulated tone burst */
-               ds3000_writereg(state, 0xa1, 0x01);
-       else
-               return -EINVAL;
-
-       msleep(13);
-       for (i = 0; i < 5; i++) {
-               data = ds3000_readreg(state, 0xa1);
-               if ((data & 0x40) == 0)
-                       break;
-               msleep(1);
-       }
-
-       if (i == 5) {
-               data = ds3000_readreg(state, 0xa1);
-               data &= ~0x80;
-               data |= 0x40;
-               ds3000_writereg(state, 0xa1, data);
-
-               data = ds3000_readreg(state, 0xa2);
-               data &= ~0xc0;
-               data |= 0x80;
-               ds3000_writereg(state, 0xa2, data);
-
-               return 1;
-       }
-
-       data = ds3000_readreg(state, 0xa2);
-       data &= ~0xc0;
-       data |= 0x80;
-       ds3000_writereg(state, 0xa2, data);
-
-       return 0;
-}
-
-static void ds3000_release(struct dvb_frontend *fe)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       dprintk("%s\n", __func__);
-       kfree(state);
-}
-
-static struct dvb_frontend_ops ds3000_ops;
-
-struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct ds3000_state *state = NULL;
-       int ret;
-
-       dprintk("%s\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
-       if (state == NULL) {
-               printk(KERN_ERR "Unable to kmalloc\n");
-               goto error2;
-       }
-
-       state->config = config;
-       state->i2c = i2c;
-       state->prevUCBS2 = 0;
-
-       /* check if the demod is present */
-       ret = ds3000_readreg(state, 0x00) & 0xfe;
-       if (ret != 0xe0) {
-               printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
-               goto error3;
-       }
-
-       printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
-                       ds3000_readreg(state, 0x02),
-                       ds3000_readreg(state, 0x01));
-
-       memcpy(&state->frontend.ops, &ds3000_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error3:
-       kfree(state);
-error2:
-       return NULL;
-}
-EXPORT_SYMBOL(ds3000_attach);
-
-static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
-                                       s32 carrier_offset_khz)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       s32 tmp;
-
-       tmp = carrier_offset_khz;
-       tmp *= 65536;
-       tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
-
-       if (tmp < 0)
-               tmp += 65536;
-
-       ds3000_writereg(state, 0x5f, tmp >> 8);
-       ds3000_writereg(state, 0x5e, tmp & 0xff);
-
-       return 0;
-}
-
-static int ds3000_set_frontend(struct dvb_frontend *fe)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-       int i;
-       fe_status_t status;
-       u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf, div4;
-       s32 offset_khz;
-       u16 value, ndiv;
-       u32 f3db;
-
-       dprintk("%s() ", __func__);
-
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-       /* Tune */
-       /* unknown */
-       ds3000_tuner_writereg(state, 0x07, 0x02);
-       ds3000_tuner_writereg(state, 0x10, 0x00);
-       ds3000_tuner_writereg(state, 0x60, 0x79);
-       ds3000_tuner_writereg(state, 0x08, 0x01);
-       ds3000_tuner_writereg(state, 0x00, 0x01);
-       div4 = 0;
-
-       /* calculate and set freq divider */
-       if (c->frequency < 1146000) {
-               ds3000_tuner_writereg(state, 0x10, 0x11);
-               div4 = 1;
-               ndiv = ((c->frequency * (6 + 8) * 4) +
-                               (DS3000_XTAL_FREQ / 2)) /
-                               DS3000_XTAL_FREQ - 1024;
-       } else {
-               ds3000_tuner_writereg(state, 0x10, 0x01);
-               ndiv = ((c->frequency * (6 + 8) * 2) +
-                               (DS3000_XTAL_FREQ / 2)) /
-                               DS3000_XTAL_FREQ - 1024;
-       }
-
-       ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
-       ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
-
-       /* set pll */
-       ds3000_tuner_writereg(state, 0x03, 0x06);
-       ds3000_tuner_writereg(state, 0x51, 0x0f);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x10);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-       msleep(5);
-
-       /* unknown */
-       ds3000_tuner_writereg(state, 0x51, 0x17);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x08);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-       msleep(5);
-
-       value = ds3000_tuner_readreg(state, 0x3d);
-       value &= 0x0f;
-       if ((value > 4) && (value < 15)) {
-               value -= 3;
-               if (value < 4)
-                       value = 4;
-               value = ((value << 3) | 0x01) & 0x79;
-       }
-
-       ds3000_tuner_writereg(state, 0x60, value);
-       ds3000_tuner_writereg(state, 0x51, 0x17);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x08);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-
-       /* set low-pass filter period */
-       ds3000_tuner_writereg(state, 0x04, 0x2e);
-       ds3000_tuner_writereg(state, 0x51, 0x1b);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x04);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-       msleep(5);
-
-       f3db = ((c->symbol_rate / 1000) << 2) / 5 + 2000;
-       if ((c->symbol_rate / 1000) < 5000)
-               f3db += 3000;
-       if (f3db < 7000)
-               f3db = 7000;
-       if (f3db > 40000)
-               f3db = 40000;
-
-       /* set low-pass filter baseband */
-       value = ds3000_tuner_readreg(state, 0x26);
-       mlpf = 0x2e * 207 / ((value << 1) + 151);
-       mlpf_max = mlpf * 135 / 100;
-       mlpf_min = mlpf * 78 / 100;
-       if (mlpf_max > 63)
-               mlpf_max = 63;
-
-       /* rounded to the closest integer */
-       nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
-                       / (2766 * DS3000_XTAL_FREQ);
-       if (nlpf > 23)
-               nlpf = 23;
-       if (nlpf < 1)
-               nlpf = 1;
-
-       /* rounded to the closest integer */
-       mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
-                       (1000 * f3db / 2)) / (1000 * f3db);
-
-       if (mlpf_new < mlpf_min) {
-               nlpf++;
-               mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
-                               (1000 * f3db / 2)) / (1000 * f3db);
-       }
-
-       if (mlpf_new > mlpf_max)
-               mlpf_new = mlpf_max;
-
-       ds3000_tuner_writereg(state, 0x04, mlpf_new);
-       ds3000_tuner_writereg(state, 0x06, nlpf);
-       ds3000_tuner_writereg(state, 0x51, 0x1b);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x04);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-       msleep(5);
-
-       /* unknown */
-       ds3000_tuner_writereg(state, 0x51, 0x1e);
-       ds3000_tuner_writereg(state, 0x51, 0x1f);
-       ds3000_tuner_writereg(state, 0x50, 0x01);
-       ds3000_tuner_writereg(state, 0x50, 0x00);
-       msleep(60);
-
-       offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ
-               / (6 + 8) / (div4 + 1) / 2 - c->frequency;
-
-       /* ds3000 global reset */
-       ds3000_writereg(state, 0x07, 0x80);
-       ds3000_writereg(state, 0x07, 0x00);
-       /* ds3000 build-in uC reset */
-       ds3000_writereg(state, 0xb2, 0x01);
-       /* ds3000 software reset */
-       ds3000_writereg(state, 0x00, 0x01);
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               /* initialise the demod in DVB-S mode */
-               for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
-                       ds3000_writereg(state,
-                               ds3000_dvbs_init_tab[i],
-                               ds3000_dvbs_init_tab[i + 1]);
-               value = ds3000_readreg(state, 0xfe);
-               value &= 0xc0;
-               value |= 0x1b;
-               ds3000_writereg(state, 0xfe, value);
-               break;
-       case SYS_DVBS2:
-               /* initialise the demod in DVB-S2 mode */
-               for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
-                       ds3000_writereg(state,
-                               ds3000_dvbs2_init_tab[i],
-                               ds3000_dvbs2_init_tab[i + 1]);
-               if (c->symbol_rate >= 30000000)
-                       ds3000_writereg(state, 0xfe, 0x54);
-               else
-                       ds3000_writereg(state, 0xfe, 0x98);
-               break;
-       default:
-               return 1;
-       }
-
-       /* enable 27MHz clock output */
-       ds3000_writereg(state, 0x29, 0x80);
-       /* enable ac coupling */
-       ds3000_writereg(state, 0x25, 0x8a);
-
-       /* enhance symbol rate performance */
-       if ((c->symbol_rate / 1000) <= 5000) {
-               value = 29777 / (c->symbol_rate / 1000) + 1;
-               if (value % 2 != 0)
-                       value++;
-               ds3000_writereg(state, 0xc3, 0x0d);
-               ds3000_writereg(state, 0xc8, value);
-               ds3000_writereg(state, 0xc4, 0x10);
-               ds3000_writereg(state, 0xc7, 0x0e);
-       } else if ((c->symbol_rate / 1000) <= 10000) {
-               value = 92166 / (c->symbol_rate / 1000) + 1;
-               if (value % 2 != 0)
-                       value++;
-               ds3000_writereg(state, 0xc3, 0x07);
-               ds3000_writereg(state, 0xc8, value);
-               ds3000_writereg(state, 0xc4, 0x09);
-               ds3000_writereg(state, 0xc7, 0x12);
-       } else if ((c->symbol_rate / 1000) <= 20000) {
-               value = 64516 / (c->symbol_rate / 1000) + 1;
-               ds3000_writereg(state, 0xc3, value);
-               ds3000_writereg(state, 0xc8, 0x0e);
-               ds3000_writereg(state, 0xc4, 0x07);
-               ds3000_writereg(state, 0xc7, 0x18);
-       } else {
-               value = 129032 / (c->symbol_rate / 1000) + 1;
-               ds3000_writereg(state, 0xc3, value);
-               ds3000_writereg(state, 0xc8, 0x0a);
-               ds3000_writereg(state, 0xc4, 0x05);
-               ds3000_writereg(state, 0xc7, 0x24);
-       }
-
-       /* normalized symbol rate rounded to the closest integer */
-       value = (((c->symbol_rate / 1000) << 16) +
-                       (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
-       ds3000_writereg(state, 0x61, value & 0x00ff);
-       ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
-
-       /* co-channel interference cancellation disabled */
-       ds3000_writereg(state, 0x56, 0x00);
-
-       /* equalizer disabled */
-       ds3000_writereg(state, 0x76, 0x00);
-
-       /*ds3000_writereg(state, 0x08, 0x03);
-       ds3000_writereg(state, 0xfd, 0x22);
-       ds3000_writereg(state, 0x08, 0x07);
-       ds3000_writereg(state, 0xfd, 0x42);
-       ds3000_writereg(state, 0x08, 0x07);*/
-
-       if (state->config->ci_mode) {
-               switch (c->delivery_system) {
-               case SYS_DVBS:
-               default:
-                       ds3000_writereg(state, 0xfd, 0x80);
-               break;
-               case SYS_DVBS2:
-                       ds3000_writereg(state, 0xfd, 0x01);
-                       break;
-               }
-       }
-
-       /* ds3000 out of software reset */
-       ds3000_writereg(state, 0x00, 0x00);
-       /* start ds3000 build-in uC */
-       ds3000_writereg(state, 0xb2, 0x00);
-
-       ds3000_set_carrier_offset(fe, offset_khz);
-
-       for (i = 0; i < 30 ; i++) {
-               ds3000_read_status(fe, &status);
-               if (status & FE_HAS_LOCK)
-                       break;
-
-               msleep(10);
-       }
-
-       return 0;
-}
-
-static int ds3000_tune(struct dvb_frontend *fe,
-                       bool re_tune,
-                       unsigned int mode_flags,
-                       unsigned int *delay,
-                       fe_status_t *status)
-{
-       if (re_tune) {
-               int ret = ds3000_set_frontend(fe);
-               if (ret)
-                       return ret;
-       }
-
-       *delay = HZ / 5;
-
-       return ds3000_read_status(fe, status);
-}
-
-static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
-{
-       dprintk("%s()\n", __func__);
-       return DVBFE_ALGO_HW;
-}
-
-/*
- * Initialise or wake up device
- *
- * Power config will reset and load initial firmware if required
- */
-static int ds3000_initfe(struct dvb_frontend *fe)
-{
-       struct ds3000_state *state = fe->demodulator_priv;
-       int ret;
-
-       dprintk("%s()\n", __func__);
-       /* hard reset */
-       ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
-       msleep(1);
-
-       /* TS2020 init */
-       ds3000_tuner_writereg(state, 0x42, 0x73);
-       ds3000_tuner_writereg(state, 0x05, 0x01);
-       ds3000_tuner_writereg(state, 0x62, 0xf5);
-       /* Load the firmware if required */
-       ret = ds3000_firmware_ondemand(fe);
-       if (ret != 0) {
-               printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
-               return ret;
-       }
-
-       return 0;
-}
-
-/* Put device to sleep */
-static int ds3000_sleep(struct dvb_frontend *fe)
-{
-       dprintk("%s()\n", __func__);
-       return 0;
-}
-
-static struct dvb_frontend_ops ds3000_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2},
-       .info = {
-               .name = "Montage Technology DS3000/TS2020",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_stepsize = 1011, /* kHz for QPSK frontends */
-               .frequency_tolerance = 5000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_2G_MODULATION |
-                       FE_CAN_QPSK | FE_CAN_RECOVER
-       },
-
-       .release = ds3000_release,
-
-       .init = ds3000_initfe,
-       .sleep = ds3000_sleep,
-       .read_status = ds3000_read_status,
-       .read_ber = ds3000_read_ber,
-       .read_signal_strength = ds3000_read_signal_strength,
-       .read_snr = ds3000_read_snr,
-       .read_ucblocks = ds3000_read_ucblocks,
-       .set_voltage = ds3000_set_voltage,
-       .set_tone = ds3000_set_tone,
-       .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
-       .diseqc_send_burst = ds3000_diseqc_send_burst,
-       .get_frontend_algo = ds3000_get_algo,
-
-       .set_frontend = ds3000_set_frontend,
-       .tune = ds3000_tune,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
-                       "DS3000/TS2020 hardware");
-MODULE_AUTHOR("Konstantin Dimitrov");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
deleted file mode 100644 (file)
index 1b73688..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-    Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
-    Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
-
-    Copyright (C) 2009 TurboSight.com
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef DS3000_H
-#define DS3000_H
-
-#include <linux/dvb/frontend.h>
-
-struct ds3000_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-       u8 ci_mode;
-       /* Set device param to start dma */
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-};
-
-#if defined(CONFIG_DVB_DS3000) || \
-                       (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
-                                       struct i2c_adapter *i2c);
-#else
-static inline
-struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_DS3000 */
-#endif /* DS3000_H */
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
deleted file mode 100644 (file)
index 6d8fe88..0000000
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- * descriptions + helper functions for simple dvb plls.
- *
- * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <asm/types.h>
-
-#include "dvb-pll.h"
-
-struct dvb_pll_priv {
-       /* pll number */
-       int nr;
-
-       /* i2c details */
-       int pll_i2c_address;
-       struct i2c_adapter *i2c;
-
-       /* the PLL descriptor */
-       struct dvb_pll_desc *pll_desc;
-
-       /* cached frequency/bandwidth */
-       u32 frequency;
-       u32 bandwidth;
-};
-
-#define DVB_PLL_MAX 64
-
-static unsigned int dvb_pll_devcount;
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-static unsigned int id[DVB_PLL_MAX] =
-       { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
-module_param_array(id, int, NULL, 0644);
-MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
-
-/* ----------------------------------------------------------- */
-
-struct dvb_pll_desc {
-       char *name;
-       u32  min;
-       u32  max;
-       u32  iffreq;
-       void (*set)(struct dvb_frontend *fe, u8 *buf);
-       u8   *initdata;
-       u8   *initdata2;
-       u8   *sleepdata;
-       int  count;
-       struct {
-               u32 limit;
-               u32 stepsize;
-               u8  config;
-               u8  cb;
-       } entries[12];
-};
-
-/* ----------------------------------------------------------- */
-/* descriptions                                                */
-
-static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
-       .name  = "Thomson dtt7579",
-       .min   = 177000000,
-       .max   = 858000000,
-       .iffreq= 36166667,
-       .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
-       .count = 4,
-       .entries = {
-               {  443250000, 166667, 0xb4, 0x02 },
-               {  542000000, 166667, 0xb4, 0x08 },
-               {  771000000, 166667, 0xbc, 0x08 },
-               {  999999999, 166667, 0xf4, 0x08 },
-       },
-};
-
-static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       if (bw == 7000000)
-               buf[3] |= 0x10;
-}
-
-static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
-       .name  = "Thomson dtt759x",
-       .min   = 177000000,
-       .max   = 896000000,
-       .set   = thomson_dtt759x_bw,
-       .iffreq= 36166667,
-       .sleepdata = (u8[]){ 2, 0x84, 0x03 },
-       .count = 5,
-       .entries = {
-               {  264000000, 166667, 0xb4, 0x02 },
-               {  470000000, 166667, 0xbc, 0x02 },
-               {  735000000, 166667, 0xbc, 0x08 },
-               {  835000000, 166667, 0xf4, 0x08 },
-               {  999999999, 166667, 0xfc, 0x08 },
-       },
-};
-
-static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       if (bw == 8000000)
-               buf[3] ^= 0x10;
-}
-
-static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
-       .name  = "Thomson dtt7520x",
-       .min   = 185000000,
-       .max   = 900000000,
-       .set   = thomson_dtt7520x_bw,
-       .iffreq = 36166667,
-       .count = 7,
-       .entries = {
-               {  305000000, 166667, 0xb4, 0x12 },
-               {  405000000, 166667, 0xbc, 0x12 },
-               {  445000000, 166667, 0xbc, 0x12 },
-               {  465000000, 166667, 0xf4, 0x18 },
-               {  735000000, 166667, 0xfc, 0x18 },
-               {  835000000, 166667, 0xbc, 0x18 },
-               {  999999999, 166667, 0xfc, 0x18 },
-       },
-};
-
-static struct dvb_pll_desc dvb_pll_lg_z201 = {
-       .name  = "LG z201",
-       .min   = 174000000,
-       .max   = 862000000,
-       .iffreq= 36166667,
-       .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
-       .count = 5,
-       .entries = {
-               {  157500000, 166667, 0xbc, 0x01 },
-               {  443250000, 166667, 0xbc, 0x02 },
-               {  542000000, 166667, 0xbc, 0x04 },
-               {  830000000, 166667, 0xf4, 0x04 },
-               {  999999999, 166667, 0xfc, 0x04 },
-       },
-};
-
-static struct dvb_pll_desc dvb_pll_unknown_1 = {
-       .name  = "unknown 1", /* used by dntv live dvb-t */
-       .min   = 174000000,
-       .max   = 862000000,
-       .iffreq= 36166667,
-       .count = 9,
-       .entries = {
-               {  150000000, 166667, 0xb4, 0x01 },
-               {  173000000, 166667, 0xbc, 0x01 },
-               {  250000000, 166667, 0xb4, 0x02 },
-               {  400000000, 166667, 0xbc, 0x02 },
-               {  420000000, 166667, 0xf4, 0x02 },
-               {  470000000, 166667, 0xfc, 0x02 },
-               {  600000000, 166667, 0xbc, 0x08 },
-               {  730000000, 166667, 0xf4, 0x08 },
-               {  999999999, 166667, 0xfc, 0x08 },
-       },
-};
-
-/* Infineon TUA6010XS
- * used in Thomson Cable Tuner
- */
-static struct dvb_pll_desc dvb_pll_tua6010xs = {
-       .name  = "Infineon TUA6010XS",
-       .min   =  44250000,
-       .max   = 858000000,
-       .iffreq= 36125000,
-       .count = 3,
-       .entries = {
-               {  115750000, 62500, 0x8e, 0x03 },
-               {  403250000, 62500, 0x8e, 0x06 },
-               {  999999999, 62500, 0x8e, 0x85 },
-       },
-};
-
-/* Panasonic env57h1xd5 (some Philips PLL ?) */
-static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
-       .name  = "Panasonic ENV57H1XD5",
-       .min   =  44250000,
-       .max   = 858000000,
-       .iffreq= 36125000,
-       .count = 4,
-       .entries = {
-               {  153000000, 166667, 0xc2, 0x41 },
-               {  470000000, 166667, 0xc2, 0x42 },
-               {  526000000, 166667, 0xc2, 0x84 },
-               {  999999999, 166667, 0xc2, 0xa4 },
-       },
-};
-
-/* Philips TDA6650/TDA6651
- * used in Panasonic ENV77H11D5
- */
-static void tda665x_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       if (bw == 8000000)
-               buf[3] |= 0x08;
-}
-
-static struct dvb_pll_desc dvb_pll_tda665x = {
-       .name  = "Philips TDA6650/TDA6651",
-       .min   =  44250000,
-       .max   = 858000000,
-       .set   = tda665x_bw,
-       .iffreq= 36166667,
-       .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
-       .count = 12,
-       .entries = {
-               {   93834000, 166667, 0xca, 0x61 /* 011 0 0 0  01 */ },
-               {  123834000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
-               {  161000000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
-               {  163834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
-               {  253834000, 166667, 0xca, 0x62 /* 011 0 0 0  10 */ },
-               {  383834000, 166667, 0xca, 0xa2 /* 101 0 0 0  10 */ },
-               {  443834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
-               {  444000000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
-               {  583834000, 166667, 0xca, 0x64 /* 011 0 0 1  00 */ },
-               {  793834000, 166667, 0xca, 0xa4 /* 101 0 0 1  00 */ },
-               {  444834000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
-               {  861000000, 166667, 0xca, 0xe4 /* 111 0 0 1  00 */ },
-       }
-};
-
-/* Infineon TUA6034
- * used in LG TDTP E102P
- */
-static void tua6034_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       if (bw == 7000000)
-               buf[3] |= 0x08;
-}
-
-static struct dvb_pll_desc dvb_pll_tua6034 = {
-       .name  = "Infineon TUA6034",
-       .min   =  44250000,
-       .max   = 858000000,
-       .iffreq= 36166667,
-       .count = 3,
-       .set   = tua6034_bw,
-       .entries = {
-               {  174500000, 62500, 0xce, 0x01 },
-               {  230000000, 62500, 0xce, 0x02 },
-               {  999999999, 62500, 0xce, 0x04 },
-       },
-};
-
-/* ALPS TDED4
- * used in Nebula-Cards and USB boxes
- */
-static void tded4_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       if (bw == 8000000)
-               buf[3] |= 0x04;
-}
-
-static struct dvb_pll_desc dvb_pll_tded4 = {
-       .name = "ALPS TDED4",
-       .min = 47000000,
-       .max = 863000000,
-       .iffreq= 36166667,
-       .set   = tded4_bw,
-       .count = 4,
-       .entries = {
-               { 153000000, 166667, 0x85, 0x01 },
-               { 470000000, 166667, 0x85, 0x02 },
-               { 823000000, 166667, 0x85, 0x08 },
-               { 999999999, 166667, 0x85, 0x88 },
-       }
-};
-
-/* ALPS TDHU2
- * used in AverTVHD MCE A180
- */
-static struct dvb_pll_desc dvb_pll_tdhu2 = {
-       .name = "ALPS TDHU2",
-       .min = 54000000,
-       .max = 864000000,
-       .iffreq= 44000000,
-       .count = 4,
-       .entries = {
-               { 162000000, 62500, 0x85, 0x01 },
-               { 426000000, 62500, 0x85, 0x02 },
-               { 782000000, 62500, 0x85, 0x08 },
-               { 999999999, 62500, 0x85, 0x88 },
-       }
-};
-
-/* Samsung TBMV30111IN / TBMV30712IN1
- * used in Air2PC ATSC - 2nd generation (nxt2002)
- */
-static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
-       .name = "Samsung TBMV30111IN / TBMV30712IN1",
-       .min = 54000000,
-       .max = 860000000,
-       .iffreq= 44000000,
-       .count = 6,
-       .entries = {
-               { 172000000, 166667, 0xb4, 0x01 },
-               { 214000000, 166667, 0xb4, 0x02 },
-               { 467000000, 166667, 0xbc, 0x02 },
-               { 721000000, 166667, 0xbc, 0x08 },
-               { 841000000, 166667, 0xf4, 0x08 },
-               { 999999999, 166667, 0xfc, 0x02 },
-       }
-};
-
-/*
- * Philips SD1878 Tuner.
- */
-static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
-       .name  = "Philips SD1878",
-       .min   =  950000,
-       .max   = 2150000,
-       .iffreq= 249, /* zero-IF, offset 249 is to round up */
-       .count = 4,
-       .entries = {
-               { 1250000, 500, 0xc4, 0x00},
-               { 1450000, 500, 0xc4, 0x40},
-               { 2050000, 500, 0xc4, 0x80},
-               { 2150000, 500, 0xc4, 0xc0},
-       },
-};
-
-static void opera1_bw(struct dvb_frontend *fe, u8 *buf)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       u32 b_w  = (c->symbol_rate * 27) / 32000;
-       struct i2c_msg msg = {
-               .addr = priv->pll_i2c_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 4
-       };
-       int result;
-       u8 lpf;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       result = i2c_transfer(priv->i2c, &msg, 1);
-       if (result != 1)
-               printk(KERN_ERR "%s: i2c_transfer failed:%d",
-                       __func__, result);
-
-       if (b_w <= 10000)
-               lpf = 0xc;
-       else if (b_w <= 12000)
-               lpf = 0x2;
-       else if (b_w <= 14000)
-               lpf = 0xa;
-       else if (b_w <= 16000)
-               lpf = 0x6;
-       else if (b_w <= 18000)
-               lpf = 0xe;
-       else if (b_w <= 20000)
-               lpf = 0x1;
-       else if (b_w <= 22000)
-               lpf = 0x9;
-       else if (b_w <= 24000)
-               lpf = 0x5;
-       else if (b_w <= 26000)
-               lpf = 0xd;
-       else if (b_w <= 28000)
-               lpf = 0x3;
-               else
-               lpf = 0xb;
-       buf[2] ^= 0x1c; /* Flip bits 3-5 */
-       /* Set lpf */
-       buf[2] |= ((lpf >> 2) & 0x3) << 3;
-       buf[3] |= (lpf & 0x3) << 2;
-
-       return;
-}
-
-static struct dvb_pll_desc dvb_pll_opera1 = {
-       .name  = "Opera Tuner",
-       .min   =  900000,
-       .max   = 2250000,
-       .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
-       .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
-       .iffreq= 0,
-       .set   = opera1_bw,
-       .count = 8,
-       .entries = {
-               { 1064000, 500, 0xf9, 0xc2 },
-               { 1169000, 500, 0xf9, 0xe2 },
-               { 1299000, 500, 0xf9, 0x20 },
-               { 1444000, 500, 0xf9, 0x40 },
-               { 1606000, 500, 0xf9, 0x60 },
-               { 1777000, 500, 0xf9, 0x80 },
-               { 1941000, 500, 0xf9, 0xa0 },
-               { 2250000, 500, 0xf9, 0xc0 },
-       }
-};
-
-static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       struct i2c_msg msg = {
-               .addr = priv->pll_i2c_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 4
-       };
-       int result;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       result = i2c_transfer(priv->i2c, &msg, 1);
-       if (result != 1)
-               printk(KERN_ERR "%s: i2c_transfer failed:%d",
-                       __func__, result);
-
-       buf[2] = 0x9e;
-       buf[3] = 0x90;
-
-       return;
-}
-
-/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
-static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
-       .name   = "Samsung DTOS403IH102A",
-       .min    =  44250000,
-       .max    = 858000000,
-       .iffreq =  36125000,
-       .count  = 8,
-       .set    = samsung_dtos403ih102a_set,
-       .entries = {
-               { 135000000, 62500, 0xbe, 0x01 },
-               { 177000000, 62500, 0xf6, 0x01 },
-               { 370000000, 62500, 0xbe, 0x02 },
-               { 450000000, 62500, 0xf6, 0x02 },
-               { 466000000, 62500, 0xfe, 0x02 },
-               { 538000000, 62500, 0xbe, 0x08 },
-               { 826000000, 62500, 0xf6, 0x08 },
-               { 999999999, 62500, 0xfe, 0x08 },
-       }
-};
-
-/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
-static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
-       .name   = "Samsung TDTC9251DH0",
-       .min    =  48000000,
-       .max    = 863000000,
-       .iffreq =  36166667,
-       .count  = 3,
-       .entries = {
-               { 157500000, 166667, 0xcc, 0x09 },
-               { 443000000, 166667, 0xcc, 0x0a },
-               { 863000000, 166667, 0xcc, 0x08 },
-       }
-};
-
-/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
-static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
-       .name = "Samsung TBDU18132",
-       .min    =  950000,
-       .max    = 2150000, /* guesses */
-       .iffreq = 0,
-       .count = 2,
-       .entries = {
-               { 1550000, 125, 0x84, 0x82 },
-               { 4095937, 125, 0x84, 0x80 },
-       }
-       /* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
-        * by this driver.  The two extra bits are 0x60 in the third byte.  15
-        * bits is enough for over 4 GHz, which is enough to cover the range
-        * of this tuner.  We could use the additional divisor bits by adding
-        * more entries, e.g.
-        { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
-        { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
-        { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
-};
-
-/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
-static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
-       .name = "Samsung TBMU24112",
-       .min    =  950000,
-       .max    = 2150000, /* guesses */
-       .iffreq = 0,
-       .count = 2,
-       .entries = {
-               { 1500000, 125, 0x84, 0x18 },
-               { 9999999, 125, 0x84, 0x08 },
-       }
-};
-
-/* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
-/* byte 4 : 1  *   *   AGD R3  R2  R1  R0
- * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
- * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
- * Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
- *  47 - 153   0  *  0   0   0   0   0   1   0x01
- * 153 - 430   0  *  0   0   0   0   1   0   0x02
- * 430 - 822   0  *  0   0   1   0   0   0   0x08
- * 822 - 862   1  *  0   0   1   0   0   0   0x88 */
-static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
-       .name = "ALPS TDEE4",
-       .min    =  47000000,
-       .max    = 862000000,
-       .iffreq =  36125000,
-       .count = 4,
-       .entries = {
-               { 153000000, 62500, 0x95, 0x01 },
-               { 430000000, 62500, 0x95, 0x02 },
-               { 822000000, 62500, 0x95, 0x08 },
-               { 999999999, 62500, 0x95, 0x88 },
-       }
-};
-
-/* ----------------------------------------------------------- */
-
-static struct dvb_pll_desc *pll_list[] = {
-       [DVB_PLL_UNDEFINED]              = NULL,
-       [DVB_PLL_THOMSON_DTT7579]        = &dvb_pll_thomson_dtt7579,
-       [DVB_PLL_THOMSON_DTT759X]        = &dvb_pll_thomson_dtt759x,
-       [DVB_PLL_THOMSON_DTT7520X]       = &dvb_pll_thomson_dtt7520x,
-       [DVB_PLL_LG_Z201]                = &dvb_pll_lg_z201,
-       [DVB_PLL_UNKNOWN_1]              = &dvb_pll_unknown_1,
-       [DVB_PLL_TUA6010XS]              = &dvb_pll_tua6010xs,
-       [DVB_PLL_ENV57H1XD5]             = &dvb_pll_env57h1xd5,
-       [DVB_PLL_TUA6034]                = &dvb_pll_tua6034,
-       [DVB_PLL_TDA665X]                = &dvb_pll_tda665x,
-       [DVB_PLL_TDED4]                  = &dvb_pll_tded4,
-       [DVB_PLL_TDEE4]                  = &dvb_pll_alps_tdee4,
-       [DVB_PLL_TDHU2]                  = &dvb_pll_tdhu2,
-       [DVB_PLL_SAMSUNG_TBMV]           = &dvb_pll_samsung_tbmv,
-       [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
-       [DVB_PLL_OPERA1]                 = &dvb_pll_opera1,
-       [DVB_PLL_SAMSUNG_DTOS403IH102A]  = &dvb_pll_samsung_dtos403ih102a,
-       [DVB_PLL_SAMSUNG_TDTC9251DH0]    = &dvb_pll_samsung_tdtc9251dh0,
-       [DVB_PLL_SAMSUNG_TBDU18132]      = &dvb_pll_samsung_tbdu18132,
-       [DVB_PLL_SAMSUNG_TBMU24112]      = &dvb_pll_samsung_tbmu24112,
-};
-
-/* ----------------------------------------------------------- */
-/* code                                                        */
-
-static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
-                            const u32 frequency)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       struct dvb_pll_desc *desc = priv->pll_desc;
-       u32 div;
-       int i;
-
-       if (frequency && (frequency < desc->min || frequency > desc->max))
-               return -EINVAL;
-
-       for (i = 0; i < desc->count; i++) {
-               if (frequency > desc->entries[i].limit)
-                       continue;
-               break;
-       }
-
-       if (debug)
-               printk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
-                      frequency, i, desc->count);
-       if (i == desc->count)
-               return -EINVAL;
-
-       div = (frequency + desc->iffreq +
-              desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
-       buf[0] = div >> 8;
-       buf[1] = div & 0xff;
-       buf[2] = desc->entries[i].config;
-       buf[3] = desc->entries[i].cb;
-
-       if (desc->set)
-               desc->set(fe, buf);
-
-       if (debug)
-               printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
-                      desc->name, div, buf[0], buf[1], buf[2], buf[3]);
-
-       // calculate the frequency we set it to
-       return (div * desc->entries[i].stepsize) - desc->iffreq;
-}
-
-static int dvb_pll_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int dvb_pll_sleep(struct dvb_frontend *fe)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-
-       if (priv->i2c == NULL)
-               return -EINVAL;
-
-       if (priv->pll_desc->sleepdata) {
-               struct i2c_msg msg = { .flags = 0,
-                       .addr = priv->pll_i2c_address,
-                       .buf = priv->pll_desc->sleepdata + 1,
-                       .len = priv->pll_desc->sleepdata[0] };
-
-               int result;
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
-                       return result;
-               }
-               return 0;
-       }
-       /* Shouldn't be called when initdata is NULL, maybe BUG()? */
-       return -EINVAL;
-}
-
-static int dvb_pll_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       u8 buf[4];
-       struct i2c_msg msg =
-               { .addr = priv->pll_i2c_address, .flags = 0,
-                 .buf = buf, .len = sizeof(buf) };
-       int result;
-       u32 frequency = 0;
-
-       if (priv->i2c == NULL)
-               return -EINVAL;
-
-       result = dvb_pll_configure(fe, buf, c->frequency);
-       if (result < 0)
-               return result;
-       else
-               frequency = result;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
-               return result;
-       }
-
-       priv->frequency = frequency;
-       priv->bandwidth = c->bandwidth_hz;
-
-       return 0;
-}
-
-static int dvb_pll_calc_regs(struct dvb_frontend *fe,
-                            u8 *buf, int buf_len)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       int result;
-       u32 frequency = 0;
-
-       if (buf_len < 5)
-               return -EINVAL;
-
-       result = dvb_pll_configure(fe, buf + 1, c->frequency);
-       if (result < 0)
-               return result;
-       else
-               frequency = result;
-
-       buf[0] = priv->pll_i2c_address;
-
-       priv->frequency = frequency;
-       priv->bandwidth = c->bandwidth_hz;
-
-       return 5;
-}
-
-static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int dvb_pll_init(struct dvb_frontend *fe)
-{
-       struct dvb_pll_priv *priv = fe->tuner_priv;
-
-       if (priv->i2c == NULL)
-               return -EINVAL;
-
-       if (priv->pll_desc->initdata) {
-               struct i2c_msg msg = { .flags = 0,
-                       .addr = priv->pll_i2c_address,
-                       .buf = priv->pll_desc->initdata + 1,
-                       .len = priv->pll_desc->initdata[0] };
-
-               int result;
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               result = i2c_transfer(priv->i2c, &msg, 1);
-               if (result != 1)
-                       return result;
-               if (priv->pll_desc->initdata2) {
-                       msg.buf = priv->pll_desc->initdata2 + 1;
-                       msg.len = priv->pll_desc->initdata2[0];
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 1);
-                       result = i2c_transfer(priv->i2c, &msg, 1);
-                       if (result != 1)
-                               return result;
-               }
-               return 0;
-       }
-       /* Shouldn't be called when initdata is NULL, maybe BUG()? */
-       return -EINVAL;
-}
-
-static struct dvb_tuner_ops dvb_pll_tuner_ops = {
-       .release = dvb_pll_release,
-       .sleep = dvb_pll_sleep,
-       .init = dvb_pll_init,
-       .set_params = dvb_pll_set_params,
-       .calc_regs = dvb_pll_calc_regs,
-       .get_frequency = dvb_pll_get_frequency,
-       .get_bandwidth = dvb_pll_get_bandwidth,
-};
-
-struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
-                                   struct i2c_adapter *i2c,
-                                   unsigned int pll_desc_id)
-{
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
-                              .buf = b1, .len = 1 };
-       struct dvb_pll_priv *priv = NULL;
-       int ret;
-       struct dvb_pll_desc *desc;
-
-       if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
-           (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
-               pll_desc_id = id[dvb_pll_devcount];
-
-       BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
-
-       desc = pll_list[pll_desc_id];
-
-       if (i2c != NULL) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = i2c_transfer (i2c, &msg, 1);
-               if (ret != 1)
-                       return NULL;
-               if (fe->ops.i2c_gate_ctrl)
-                            fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->pll_i2c_address = pll_addr;
-       priv->i2c = i2c;
-       priv->pll_desc = desc;
-       priv->nr = dvb_pll_devcount++;
-
-       memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       strncpy(fe->ops.tuner_ops.info.name, desc->name,
-               sizeof(fe->ops.tuner_ops.info.name));
-       fe->ops.tuner_ops.info.frequency_min = desc->min;
-       fe->ops.tuner_ops.info.frequency_max = desc->max;
-       if (!desc->initdata)
-               fe->ops.tuner_ops.init = NULL;
-       if (!desc->sleepdata)
-               fe->ops.tuner_ops.sleep = NULL;
-
-       fe->tuner_priv = priv;
-
-       if ((debug) || (id[priv->nr] == pll_desc_id)) {
-               printk("dvb-pll[%d]", priv->nr);
-               if (i2c != NULL)
-                       printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
-               printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
-                      id[priv->nr] == pll_desc_id ?
-                               "insmod option" : "autodetected");
-       }
-
-       return fe;
-}
-EXPORT_SYMBOL(dvb_pll_attach);
-
-MODULE_DESCRIPTION("dvb pll library");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
deleted file mode 100644 (file)
index 4de754f..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * descriptions + helper functions for simple dvb plls.
- */
-
-#ifndef __DVB_PLL_H__
-#define __DVB_PLL_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-#define DVB_PLL_UNDEFINED               0
-#define DVB_PLL_THOMSON_DTT7579         1
-#define DVB_PLL_THOMSON_DTT759X         2
-#define DVB_PLL_LG_Z201                 3
-#define DVB_PLL_UNKNOWN_1               4
-#define DVB_PLL_TUA6010XS               5
-#define DVB_PLL_ENV57H1XD5              6
-#define DVB_PLL_TUA6034                 7
-#define DVB_PLL_TDA665X                 8
-#define DVB_PLL_TDED4                   9
-#define DVB_PLL_TDHU2                  10
-#define DVB_PLL_SAMSUNG_TBMV           11
-#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
-#define DVB_PLL_OPERA1                 13
-#define DVB_PLL_SAMSUNG_DTOS403IH102A  14
-#define DVB_PLL_SAMSUNG_TDTC9251DH0    15
-#define DVB_PLL_SAMSUNG_TBDU18132      16
-#define DVB_PLL_SAMSUNG_TBMU24112      17
-#define DVB_PLL_TDEE4                 18
-#define DVB_PLL_THOMSON_DTT7520X       19
-
-/**
- * Attach a dvb-pll to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param pll_addr i2c address of the PLL (if used).
- * @param i2c i2c adapter to use (set to NULL if not used).
- * @param pll_desc_id dvb_pll_desc to use.
- * @return Frontend pointer on success, NULL on failure
- */
-#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
-                                          int pll_addr,
-                                          struct i2c_adapter *i2c,
-                                          unsigned int pll_desc_id);
-#else
-static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
-                                          int pll_addr,
-                                          struct i2c_adapter *i2c,
-                                          unsigned int pll_desc_id)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
deleted file mode 100644 (file)
index dcfc902..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *  Driver for Dummy Frontend
- *
- *  Written by Emard <emard@softhome.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "dvb_dummy_fe.h"
-
-
-struct dvb_dummy_fe_state {
-       struct dvb_frontend frontend;
-};
-
-
-static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       *status = FE_HAS_SIGNAL
-               | FE_HAS_CARRIER
-               | FE_HAS_VITERBI
-               | FE_HAS_SYNC
-               | FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       *ber = 0;
-       return 0;
-}
-
-static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       *strength = 0;
-       return 0;
-}
-
-static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       *snr = 0;
-       return 0;
-}
-
-static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-/*
- * Only needed if it actually reads something from the hardware
- */
-static int dvb_dummy_fe_get_frontend(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe)
-{
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       return 0;
-}
-
-static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int dvb_dummy_fe_init(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       return 0;
-}
-
-static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       return 0;
-}
-
-static void dvb_dummy_fe_release(struct dvb_frontend* fe)
-{
-       struct dvb_dummy_fe_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
-
-struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
-{
-       struct dvb_dummy_fe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
-
-struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
-{
-       struct dvb_dummy_fe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
-
-struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
-{
-       struct dvb_dummy_fe_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Dummy DVB-T",
-               .frequency_min          = 0,
-               .frequency_max          = 863250000,
-               .frequency_stepsize     = 62500,
-               .caps = 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_6_7 |
-                               FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                               FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                               FE_CAN_TRANSMISSION_MODE_AUTO |
-                               FE_CAN_GUARD_INTERVAL_AUTO |
-                               FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = dvb_dummy_fe_release,
-
-       .init = dvb_dummy_fe_init,
-       .sleep = dvb_dummy_fe_sleep,
-
-       .set_frontend = dvb_dummy_fe_set_frontend,
-       .get_frontend = dvb_dummy_fe_get_frontend,
-
-       .read_status = dvb_dummy_fe_read_status,
-       .read_ber = dvb_dummy_fe_read_ber,
-       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
-       .read_snr = dvb_dummy_fe_read_snr,
-       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
-};
-
-static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-               .name                   = "Dummy DVB-C",
-               .frequency_stepsize     = 62500,
-               .frequency_min          = 51000000,
-               .frequency_max          = 858000000,
-               .symbol_rate_min        = (57840000/2)/64,     /* SACLK/64 == (XIN/2)/64 */
-               .symbol_rate_max        = (57840000/2)/4,      /* SACLK/4 */
-               .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
-                       FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
-       },
-
-       .release = dvb_dummy_fe_release,
-
-       .init = dvb_dummy_fe_init,
-       .sleep = dvb_dummy_fe_sleep,
-
-       .set_frontend = dvb_dummy_fe_set_frontend,
-       .get_frontend = dvb_dummy_fe_get_frontend,
-
-       .read_status = dvb_dummy_fe_read_status,
-       .read_ber = dvb_dummy_fe_read_ber,
-       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
-       .read_snr = dvb_dummy_fe_read_snr,
-       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
-};
-
-static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "Dummy DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 250,           /* kHz for QPSK frontends */
-               .frequency_tolerance    = 29500,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK
-       },
-
-       .release = dvb_dummy_fe_release,
-
-       .init = dvb_dummy_fe_init,
-       .sleep = dvb_dummy_fe_sleep,
-
-       .set_frontend = dvb_dummy_fe_set_frontend,
-       .get_frontend = dvb_dummy_fe_get_frontend,
-
-       .read_status = dvb_dummy_fe_read_status,
-       .read_ber = dvb_dummy_fe_read_ber,
-       .read_signal_strength = dvb_dummy_fe_read_signal_strength,
-       .read_snr = dvb_dummy_fe_read_snr,
-       .read_ucblocks = dvb_dummy_fe_read_ucblocks,
-
-       .set_voltage = dvb_dummy_fe_set_voltage,
-       .set_tone = dvb_dummy_fe_set_tone,
-};
-
-MODULE_DESCRIPTION("DVB DUMMY Frontend");
-MODULE_AUTHOR("Emard");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
-EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
-EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
deleted file mode 100644 (file)
index 1fcb987..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Driver for Dummy Frontend
- *
- *  Written by Emard <emard@softhome.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef DVB_DUMMY_FE_H
-#define DVB_DUMMY_FE_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
-defined(MODULE))
-extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
-extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
-extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
-#else
-static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_DUMMY_FE */
-
-#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c
deleted file mode 100644 (file)
index c56fddb..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * E3C EC100 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "dvb_frontend.h"
-#include "ec100_priv.h"
-#include "ec100.h"
-
-int ec100_debug;
-module_param_named(debug, ec100_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-struct ec100_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend frontend;
-       struct ec100_config config;
-
-       u16 ber;
-};
-
-/* write single register */
-static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
-{
-       u8 buf[2] = {reg, val};
-       struct i2c_msg msg = {
-               .addr = state->config.demod_address,
-               .flags = 0,
-               .len = 2,
-               .buf = buf};
-
-       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
-               warn("I2C write failed reg:%02x", reg);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* read single register */
-static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = state->config.demod_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg
-               }, {
-                       .addr = state->config.demod_address,
-                       .flags = I2C_M_RD,
-                       .len = 1,
-                       .buf = val
-               }
-       };
-
-       if (i2c_transfer(state->i2c, msg, 2) != 2) {
-               warn("I2C read failed reg:%02x", reg);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int ec100_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct ec100_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp, tmp2;
-
-       deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency,
-               c->bandwidth_hz);
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       ret = ec100_write_reg(state, 0x04, 0x06);
-       if (ret)
-               goto error;
-       ret = ec100_write_reg(state, 0x67, 0x58);
-       if (ret)
-               goto error;
-       ret = ec100_write_reg(state, 0x05, 0x18);
-       if (ret)
-               goto error;
-
-       /* reg/bw |   6  |   7  |   8
-          -------+------+------+------
-          A 0x1b | 0xa1 | 0xe7 | 0x2c
-          A 0x1c | 0x55 | 0x63 | 0x72
-          -------+------+------+------
-          B 0x1b | 0xb7 | 0x00 | 0x49
-          B 0x1c | 0x55 | 0x64 | 0x72 */
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               tmp = 0xb7;
-               tmp2 = 0x55;
-               break;
-       case 7000000:
-               tmp = 0x00;
-               tmp2 = 0x64;
-               break;
-       case 8000000:
-       default:
-               tmp = 0x49;
-               tmp2 = 0x72;
-       }
-
-       ret = ec100_write_reg(state, 0x1b, tmp);
-       if (ret)
-               goto error;
-       ret = ec100_write_reg(state, 0x1c, tmp2);
-       if (ret)
-               goto error;
-
-       ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
-       if (ret)
-               goto error;
-       ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
-       if (ret)
-               goto error;
-
-       ret = ec100_write_reg(state, 0x08, 0x24);
-       if (ret)
-               goto error;
-
-       ret = ec100_write_reg(state, 0x00, 0x00); /* go */
-       if (ret)
-               goto error;
-       ret = ec100_write_reg(state, 0x00, 0x20); /* go */
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       deb_info("%s: failed:%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec100_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 300;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-
-       return 0;
-}
-
-static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct ec100_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-       *status = 0;
-
-       ret = ec100_read_reg(state, 0x42, &tmp);
-       if (ret)
-               goto error;
-
-       if (tmp & 0x80) {
-               /* bit7 set - have lock */
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-                       FE_HAS_SYNC | FE_HAS_LOCK;
-       } else {
-               ret = ec100_read_reg(state, 0x01, &tmp);
-               if (ret)
-                       goto error;
-
-               if (tmp & 0x10) {
-                       /* bit4 set - have signal */
-                       *status |= FE_HAS_SIGNAL;
-                       if (!(tmp & 0x01)) {
-                               /* bit0 clear - have ~valid signal */
-                               *status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
-                       }
-               }
-       }
-
-       return ret;
-error:
-       deb_info("%s: failed:%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct ec100_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp, tmp2;
-       u16 ber2;
-
-       *ber = 0;
-
-       ret = ec100_read_reg(state, 0x65, &tmp);
-       if (ret)
-               goto error;
-       ret = ec100_read_reg(state, 0x66, &tmp2);
-       if (ret)
-               goto error;
-
-       ber2 = (tmp2 << 8) | tmp;
-
-       /* if counter overflow or clear */
-       if (ber2 < state->ber)
-               *ber = ber2;
-       else
-               *ber = ber2 - state->ber;
-
-       state->ber = ber2;
-
-       return ret;
-error:
-       deb_info("%s: failed:%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct ec100_state *state = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-
-       ret = ec100_read_reg(state, 0x24, &tmp);
-       if (ret) {
-               *strength = 0;
-               goto error;
-       }
-
-       *strength = ((tmp << 8) | tmp);
-
-       return ret;
-error:
-       deb_info("%s: failed:%d\n", __func__, ret);
-       return ret;
-}
-
-static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       *snr = 0;
-       return 0;
-}
-
-static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-static void ec100_release(struct dvb_frontend *fe)
-{
-       struct ec100_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops ec100_ops;
-
-struct dvb_frontend *ec100_attach(const struct ec100_config *config,
-       struct i2c_adapter *i2c)
-{
-       int ret;
-       struct ec100_state *state = NULL;
-       u8 tmp;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->config, config, sizeof(struct ec100_config));
-
-       /* check if the demod is there */
-       ret = ec100_read_reg(state, 0x33, &tmp);
-       if (ret || tmp != 0x0b)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &ec100_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(ec100_attach);
-
-static struct dvb_frontend_ops ec100_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "E3C EC100 DVB-T",
-               .caps =
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 |
-                       FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = ec100_release,
-       .set_frontend = ec100_set_frontend,
-       .get_tune_settings = ec100_get_tune_settings,
-       .read_status = ec100_read_status,
-       .read_ber = ec100_read_ber,
-       .read_signal_strength = ec100_read_signal_strength,
-       .read_snr = ec100_read_snr,
-       .read_ucblocks = ec100_read_ucblocks,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb/frontends/ec100.h
deleted file mode 100644 (file)
index ee8e524..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * E3C EC100 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef EC100_H
-#define EC100_H
-
-#include <linux/dvb/frontend.h>
-
-struct ec100_config {
-       /* demodulator's I2C address */
-       u8 demod_address;
-};
-
-
-#if defined(CONFIG_DVB_EC100) || \
-       (defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
-extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *ec100_attach(
-       const struct ec100_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* EC100_H */
diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h
deleted file mode 100644 (file)
index 5c99014..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * E3C EC100 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef EC100_PRIV
-#define EC100_PRIV
-
-#define LOG_PREFIX "ec100"
-
-#define dprintk(var, level, args...) \
-       do { if ((var & level)) printk(args); } while (0)
-
-#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
-
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
deleted file mode 100644 (file)
index c983f2f..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* eds1547.h Earda EDS-1547 tuner support
-*
-* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
-*
-*      This program is free software; you can redistribute it and/or modify it
-*      under the terms of the GNU General Public License as published by the
-*      Free Software Foundation, version 2.
-*
-* see Documentation/dvb/README.dvb-usb for more information
-*/
-
-#ifndef EDS1547
-#define EDS1547
-
-static u8 stv0288_earda_inittab[] = {
-       0x01, 0x57,
-       0x02, 0x20,
-       0x03, 0x8e,
-       0x04, 0x8e,
-       0x05, 0x12,
-       0x06, 0x00,
-       0x07, 0x00,
-       0x09, 0x00,
-       0x0a, 0x04,
-       0x0b, 0x00,
-       0x0c, 0x00,
-       0x0d, 0x00,
-       0x0e, 0xd4,
-       0x0f, 0x30,
-       0x11, 0x44,
-       0x12, 0x03,
-       0x13, 0x48,
-       0x14, 0x84,
-       0x15, 0x45,
-       0x16, 0xb7,
-       0x17, 0x9c,
-       0x18, 0x00,
-       0x19, 0xa6,
-       0x1a, 0x88,
-       0x1b, 0x8f,
-       0x1c, 0xf0,
-       0x20, 0x0b,
-       0x21, 0x54,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x2b, 0xff,
-       0x2c, 0xf7,
-       0x30, 0x00,
-       0x31, 0x1e,
-       0x32, 0x14,
-       0x33, 0x0f,
-       0x34, 0x09,
-       0x35, 0x0c,
-       0x36, 0x05,
-       0x37, 0x2f,
-       0x38, 0x16,
-       0x39, 0xbd,
-       0x3a, 0x00,
-       0x3b, 0x13,
-       0x3c, 0x11,
-       0x3d, 0x30,
-       0x40, 0x63,
-       0x41, 0x04,
-       0x42, 0x20,
-       0x43, 0x00,
-       0x44, 0x00,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x47, 0x00,
-       0x4a, 0x00,
-       0x50, 0x10,
-       0x51, 0x36,
-       0x52, 0x09,
-       0x53, 0x94,
-       0x54, 0x62,
-       0x55, 0x29,
-       0x56, 0x64,
-       0x57, 0x2b,
-       0x58, 0x54,
-       0x59, 0x86,
-       0x5a, 0x00,
-       0x5b, 0x9b,
-       0x5c, 0x08,
-       0x5d, 0x7f,
-       0x5e, 0x00,
-       0x5f, 0xff,
-       0x70, 0x00,
-       0x71, 0x00,
-       0x72, 0x00,
-       0x74, 0x00,
-       0x75, 0x00,
-       0x76, 0x00,
-       0x81, 0x00,
-       0x82, 0x3f,
-       0x83, 0x3f,
-       0x84, 0x00,
-       0x85, 0x00,
-       0x88, 0x00,
-       0x89, 0x00,
-       0x8a, 0x00,
-       0x8b, 0x00,
-       0x8c, 0x00,
-       0x90, 0x00,
-       0x91, 0x00,
-       0x92, 0x00,
-       0x93, 0x00,
-       0x94, 0x1c,
-       0x97, 0x00,
-       0xa0, 0x48,
-       0xa1, 0x00,
-       0xb0, 0xb8,
-       0xb1, 0x3a,
-       0xb2, 0x10,
-       0xb3, 0x82,
-       0xb4, 0x80,
-       0xb5, 0x82,
-       0xb6, 0x82,
-       0xb7, 0x82,
-       0xb8, 0x20,
-       0xb9, 0x00,
-       0xf0, 0x00,
-       0xf1, 0x00,
-       0xf2, 0xc0,
-       0xff,0xff,
-};
-
-static struct stv0288_config earda_config = {
-       .demod_address = 0x68,
-       .min_delay_ms = 100,
-       .inittab = stv0288_earda_inittab,
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/hd29l2.c b/drivers/media/dvb/frontends/hd29l2.c
deleted file mode 100644 (file)
index a003181..0000000
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "hd29l2_priv.h"
-
-int hd29l2_debug;
-module_param_named(debug, hd29l2_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-/* write multiple registers */
-static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[2 + len];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = 0x00;
-       buf[1] = reg;
-       memcpy(&buf[2], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* read multiple registers */
-static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[2] = { 0x00, reg };
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 2,
-                       .buf = buf,
-               }, {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write single register */
-static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val)
-{
-       return hd29l2_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val)
-{
-       return hd29l2_rd_regs(priv, reg, val, 1);
-}
-
-/* write single register with mask */
-static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return hd29l2_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register with mask */
-int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static int hd29l2_soft_reset(struct hd29l2_priv *priv)
-{
-       int ret;
-       u8 tmp;
-
-       ret = hd29l2_rd_reg(priv, 0x26, &tmp);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_wr_reg(priv, 0x26, 0x0d);
-       if (ret)
-               goto err;
-
-       usleep_range(10000, 20000);
-
-       ret = hd29l2_wr_reg(priv, 0x26, tmp);
-       if (ret)
-               goto err;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 tmp;
-
-       dbg("%s: enable=%d", __func__, enable);
-
-       /* set tuner address for demod */
-       if (!priv->tuner_i2c_addr_programmed && enable) {
-               /* no need to set tuner address every time, once is enough */
-               ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1);
-               if (ret)
-                       goto err;
-
-               priv->tuner_i2c_addr_programmed = true;
-       }
-
-       /* open / close gate */
-       ret = hd29l2_wr_reg(priv, 0x9f, enable);
-       if (ret)
-               goto err;
-
-       /* wait demod ready */
-       for (i = 10; i; i--) {
-               ret = hd29l2_rd_reg(priv, 0x9e, &tmp);
-               if (ret)
-                       goto err;
-
-               if (tmp == enable)
-                       break;
-
-               usleep_range(5000, 10000);
-       }
-
-       dbg("%s: loop=%d", __func__, i);
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-
-       *status = 0;
-
-       ret = hd29l2_rd_reg(priv, 0x05, &buf[0]);
-       if (ret)
-               goto err;
-
-       if (buf[0] & 0x01) {
-               /* full lock */
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-                       FE_HAS_SYNC | FE_HAS_LOCK;
-       } else {
-               ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]);
-               if (ret)
-                       goto err;
-
-               if ((buf[1] & 0xfe) == 0x78)
-                       /* partial lock */
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC;
-       }
-
-       priv->fe_status = *status;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-       u16 tmp;
-
-       if (!(priv->fe_status & FE_HAS_LOCK)) {
-               *snr = 0;
-               ret = 0;
-               goto err;
-       }
-
-       ret = hd29l2_rd_regs(priv, 0x0b, buf, 2);
-       if (ret)
-               goto err;
-
-       tmp = (buf[0] << 8) | buf[1];
-
-       /* report SNR in dB * 10 */
-       #define LOG10_20736_24 72422627 /* log10(20736) << 24 */
-       if (tmp)
-               *snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100);
-       else
-               *snr = 0;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-       u16 tmp;
-
-       *strength = 0;
-
-       ret = hd29l2_rd_regs(priv, 0xd5, buf, 2);
-       if (ret)
-               goto err;
-
-       tmp = buf[0] << 8 | buf[1];
-       tmp = ~tmp & 0x0fff;
-
-       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
-       *strength = tmp * 0xffff / 0x0fff;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-
-       if (!(priv->fe_status & FE_HAS_SYNC)) {
-               *ber = 0;
-               ret = 0;
-               goto err;
-       }
-
-       ret = hd29l2_rd_regs(priv, 0xd9, buf, 2);
-       if (ret) {
-               *ber = 0;
-               goto err;
-       }
-
-       /* LDPC BER */
-       *ber = ((buf[0] & 0x0f) << 8) | buf[1];
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       /* no way to read? */
-       *ucblocks = 0;
-       return 0;
-}
-
-static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 tmp, buf[3];
-       u8 modulation, carrier, guard_interval, interleave, code_rate;
-       u64 num64;
-       u32 if_freq, if_ctl;
-       bool auto_mode;
-
-       dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d " \
-               "modulation=%d inversion=%d fec_inner=%d guard_interval=%d",
-                __func__,
-               c->delivery_system, c->frequency, c->bandwidth_hz,
-               c->modulation, c->inversion, c->fec_inner, c->guard_interval);
-
-       /* as for now we detect always params automatically */
-       auto_mode = true;
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* get and program IF */
-       if (fe->ops.tuner_ops.get_if_frequency)
-               fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
-       else
-               if_freq = 0;
-
-       if (if_freq) {
-               /* normal IF */
-
-               /* calc IF control value */
-               num64 = if_freq;
-               num64 *= 0x800000;
-               num64 = div_u64(num64, HD29L2_XTAL);
-               num64 -= 0x800000;
-               if_ctl = num64;
-
-               tmp = 0xfc; /* tuner type normal */
-       } else {
-               /* zero IF */
-               if_ctl = 0;
-               tmp = 0xfe; /* tuner type Zero-IF */
-       }
-
-       buf[0] = ((if_ctl >>  0) & 0xff);
-       buf[1] = ((if_ctl >>  8) & 0xff);
-       buf[2] = ((if_ctl >> 16) & 0xff);
-
-       /* program IF control */
-       ret = hd29l2_wr_regs(priv, 0x14, buf, 3);
-       if (ret)
-               goto err;
-
-       /* program tuner type */
-       ret = hd29l2_wr_reg(priv, 0xab, tmp);
-       if (ret)
-               goto err;
-
-       dbg("%s: if_freq=%d if_ctl=%x", __func__, if_freq, if_ctl);
-
-       if (auto_mode) {
-               /*
-                * use auto mode
-                */
-
-               /* disable quick mode */
-               ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02);
-               if (ret)
-                       goto err;
-
-               /* enable auto mode */
-               ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08);
-               if (ret)
-                       goto err;
-
-               /* soft reset */
-               ret = hd29l2_soft_reset(priv);
-               if (ret)
-                       goto err;
-
-               /* detect modulation */
-               for (i = 30; i; i--) {
-                       msleep(100);
-
-                       ret = hd29l2_rd_reg(priv, 0x0d, &tmp);
-                       if (ret)
-                               goto err;
-
-                       if ((((tmp & 0xf0) >= 0x10) &&
-                               ((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c))
-                               break;
-               }
-
-               dbg("%s: loop=%d", __func__, i);
-
-               if (i == 0)
-                       /* detection failed */
-                       return DVBFE_ALGO_SEARCH_FAILED;
-
-               /* read modulation */
-               ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07);
-               if (ret)
-                       goto err;
-       } else {
-               /*
-                * use manual mode
-                */
-
-               modulation = HD29L2_QAM64;
-               carrier = HD29L2_CARRIER_MULTI;
-               guard_interval = HD29L2_PN945;
-               interleave = HD29L2_INTERLEAVER_420;
-               code_rate = HD29L2_CODE_RATE_08;
-
-               tmp = (code_rate << 3) | modulation;
-               ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f);
-               if (ret)
-                       goto err;
-
-               tmp = (carrier << 2) | guard_interval;
-               ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f);
-               if (ret)
-                       goto err;
-
-               tmp = interleave;
-               ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03);
-               if (ret)
-                       goto err;
-       }
-
-       /* ensure modulation validy */
-       /* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */
-       if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
-               dbg("%s: modulation=%d not valid", __func__, modulation);
-               goto err;
-       }
-
-       /* program registers according to modulation */
-       for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) {
-               ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg,
-                       reg_mod_vals_tab[i].val[modulation]);
-               if (ret)
-                       goto err;
-       }
-
-       /* read guard interval */
-       ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03);
-       if (ret)
-               goto err;
-
-       /* read carrier mode */
-       ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04);
-       if (ret)
-               goto err;
-
-       dbg("%s: modulation=%d guard_interval=%d carrier=%d",
-               __func__, modulation, guard_interval, carrier);
-
-       if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
-               (guard_interval == HD29L2_PN945)) {
-               dbg("%s: C=3780 && QAM64 && PN945", __func__);
-
-               ret = hd29l2_wr_reg(priv, 0x42, 0x33);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg(priv, 0xdd, 0x01);
-               if (ret)
-                       goto err;
-       }
-
-       usleep_range(10000, 20000);
-
-       /* soft reset */
-       ret = hd29l2_soft_reset(priv);
-       if (ret)
-               goto err;
-
-       /* wait demod lock */
-       for (i = 30; i; i--) {
-               msleep(100);
-
-               /* read lock bit */
-               ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01);
-               if (ret)
-                       goto err;
-
-               if (tmp)
-                       break;
-       }
-
-       dbg("%s: loop=%d", __func__, i);
-
-       if (i == 0)
-               return DVBFE_ALGO_SEARCH_AGAIN;
-
-       return DVBFE_ALGO_SEARCH_SUCCESS;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return DVBFE_ALGO_SEARCH_ERROR;
-}
-
-static int hd29l2_get_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static int hd29l2_get_frontend(struct dvb_frontend *fe)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 buf[3];
-       u32 if_ctl;
-       char *str_constellation, *str_code_rate, *str_constellation_code_rate,
-               *str_guard_interval, *str_carrier, *str_guard_interval_carrier,
-               *str_interleave, *str_interleave_;
-
-       ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2);
-       if (ret)
-               goto err;
-
-       /* constellation, 0x7d[2:0] */
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0: /* QAM4NR */
-               str_constellation = "QAM4NR";
-               c->modulation = QAM_AUTO; /* FIXME */
-               break;
-       case 1: /* QAM4 */
-               str_constellation = "QAM4";
-               c->modulation = QPSK; /* FIXME */
-               break;
-       case 2:
-               str_constellation = "QAM16";
-               c->modulation = QAM_16;
-               break;
-       case 3:
-               str_constellation = "QAM32";
-               c->modulation = QAM_32;
-               break;
-       case 4:
-               str_constellation = "QAM64";
-               c->modulation = QAM_64;
-               break;
-       default:
-               str_constellation = "?";
-       }
-
-       /* LDPC code rate, 0x7d[4:3] */
-       switch ((buf[0] >> 3) & 0x03) {
-       case 0: /* 0.4 */
-               str_code_rate = "0.4";
-               c->fec_inner = FEC_AUTO; /* FIXME */
-               break;
-       case 1: /* 0.6 */
-               str_code_rate = "0.6";
-               c->fec_inner = FEC_3_5;
-               break;
-       case 2: /* 0.8 */
-               str_code_rate = "0.8";
-               c->fec_inner = FEC_4_5;
-               break;
-       default:
-               str_code_rate = "?";
-       }
-
-       /* constellation & code rate set, 0x7d[6] */
-       switch ((buf[0] >> 6) & 0x01) {
-       case 0:
-               str_constellation_code_rate = "manual";
-               break;
-       case 1:
-               str_constellation_code_rate = "auto";
-               break;
-       default:
-               str_constellation_code_rate = "?";
-       }
-
-       /* frame header, 0x81[1:0] */
-       switch ((buf[1] >> 0) & 0x03) {
-       case 0: /* PN945 */
-               str_guard_interval = "PN945";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       case 1: /* PN595 */
-               str_guard_interval = "PN595";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       case 2: /* PN420 */
-               str_guard_interval = "PN420";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       default:
-               str_guard_interval = "?";
-       }
-
-       /* carrier, 0x81[2] */
-       switch ((buf[1] >> 2) & 0x01) {
-       case 0:
-               str_carrier = "C=1";
-               break;
-       case 1:
-               str_carrier = "C=3780";
-               break;
-       default:
-               str_carrier = "?";
-       }
-
-       /* frame header & carrier set, 0x81[3] */
-       switch ((buf[1] >> 3) & 0x01) {
-       case 0:
-               str_guard_interval_carrier = "manual";
-               break;
-       case 1:
-               str_guard_interval_carrier = "auto";
-               break;
-       default:
-               str_guard_interval_carrier = "?";
-       }
-
-       /* interleave, 0x82[0] */
-       switch ((buf[2] >> 0) & 0x01) {
-       case 0:
-               str_interleave = "M=720";
-               break;
-       case 1:
-               str_interleave = "M=240";
-               break;
-       default:
-               str_interleave = "?";
-       }
-
-       /* interleave set, 0x82[1] */
-       switch ((buf[2] >> 1) & 0x01) {
-       case 0:
-               str_interleave_ = "manual";
-               break;
-       case 1:
-               str_interleave_ = "auto";
-               break;
-       default:
-               str_interleave_ = "?";
-       }
-
-       /*
-        * We can read out current detected NCO and use that value next
-        * time instead of calculating new value from targed IF.
-        * I think it will not effect receiver sensitivity but gaining lock
-        * after tune could be easier...
-        */
-       ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3);
-       if (ret)
-               goto err;
-
-       if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];
-
-       dbg("%s: %s %s %s | %s %s %s | %s %s | NCO=%06x", __func__,
-               str_constellation, str_code_rate, str_constellation_code_rate,
-               str_guard_interval, str_carrier, str_guard_interval_carrier,
-               str_interleave, str_interleave_, if_ctl);
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_init(struct dvb_frontend *fe)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 tmp;
-       static const struct reg_val tab[] = {
-               { 0x3a, 0x06 },
-               { 0x3b, 0x03 },
-               { 0x3c, 0x04 },
-               { 0xaf, 0x06 },
-               { 0xb0, 0x1b },
-               { 0x80, 0x64 },
-               { 0x10, 0x38 },
-       };
-
-       dbg("%s:", __func__);
-
-       /* reset demod */
-       /* it is recommended to HW reset chip using RST_N pin */
-       if (fe->callback) {
-               ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0);
-               if (ret)
-                       goto err;
-
-               /* reprogramming needed because HW reset clears registers */
-               priv->tuner_i2c_addr_programmed = false;
-       }
-
-       /* init */
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val);
-               if (ret)
-                       goto err;
-       }
-
-       /* TS params */
-       ret = hd29l2_rd_reg(priv, 0x36, &tmp);
-       if (ret)
-               goto err;
-
-       tmp &= 0x1b;
-       tmp |= priv->cfg.ts_mode;
-       ret = hd29l2_wr_reg(priv, 0x36, tmp);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_rd_reg(priv, 0x31, &tmp);
-       tmp &= 0xef;
-
-       if (!(priv->cfg.ts_mode >> 7))
-               /* set b4 for serial TS */
-               tmp |= 0x10;
-
-       ret = hd29l2_wr_reg(priv, 0x31, tmp);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static void hd29l2_release(struct dvb_frontend *fe)
-{
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       kfree(priv);
-}
-
-static struct dvb_frontend_ops hd29l2_ops;
-
-struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
-       struct i2c_adapter *i2c)
-{
-       int ret;
-       struct hd29l2_priv *priv = NULL;
-       u8 tmp;
-
-       /* allocate memory for the internal state */
-       priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL);
-       if (priv == NULL)
-               goto err;
-
-       /* setup the state */
-       priv->i2c = i2c;
-       memcpy(&priv->cfg, config, sizeof(struct hd29l2_config));
-
-
-       /* check if the demod is there */
-       ret = hd29l2_rd_reg(priv, 0x00, &tmp);
-       if (ret)
-               goto err;
-
-       /* create dvb_frontend */
-       memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-
-       return &priv->fe;
-err:
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(hd29l2_attach);
-
-static struct dvb_frontend_ops hd29l2_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "HDIC HD29L2 DMB-TH",
-               .frequency_min = 474000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 10000,
-               .caps = FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_32 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_BANDWIDTH_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER
-       },
-
-       .release = hd29l2_release,
-
-       .init = hd29l2_init,
-
-       .get_frontend_algo = hd29l2_get_frontend_algo,
-       .search = hd29l2_search,
-       .get_frontend = hd29l2_get_frontend,
-
-       .read_status = hd29l2_read_status,
-       .read_snr = hd29l2_read_snr,
-       .read_signal_strength = hd29l2_read_signal_strength,
-       .read_ber = hd29l2_read_ber,
-       .read_ucblocks = hd29l2_read_ucblocks,
-
-       .i2c_gate_ctrl = hd29l2_i2c_gate_ctrl,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/hd29l2.h b/drivers/media/dvb/frontends/hd29l2.h
deleted file mode 100644 (file)
index a7a6443..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef HD29L2_H
-#define HD29L2_H
-
-#include <linux/dvb/frontend.h>
-
-struct hd29l2_config {
-       /*
-        * demodulator I2C address
-        */
-       u8 i2c_addr;
-
-       /*
-        * tuner I2C address
-        * only needed when tuner is behind demod I2C-gate
-        */
-       u8 tuner_i2c_addr;
-
-       /*
-        * TS settings
-        */
-#define HD29L2_TS_SERIAL            0x00
-#define HD29L2_TS_PARALLEL          0x80
-#define HD29L2_TS_CLK_NORMAL        0x40
-#define HD29L2_TS_CLK_INVERTED      0x00
-#define HD29L2_TS_CLK_GATED         0x20
-#define HD29L2_TS_CLK_FREE          0x00
-       u8 ts_mode;
-};
-
-
-#if defined(CONFIG_DVB_HD29L2) || \
-       (defined(CONFIG_DVB_HD29L2_MODULE) && defined(MODULE))
-extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *hd29l2_attach(
-const struct hd29l2_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* HD29L2_H */
diff --git a/drivers/media/dvb/frontends/hd29l2_priv.h b/drivers/media/dvb/frontends/hd29l2_priv.h
deleted file mode 100644 (file)
index ba16dc3..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef HD29L2_PRIV
-#define HD29L2_PRIV
-
-#include <linux/dvb/version.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "hd29l2.h"
-
-#define LOG_PREFIX "hd29l2"
-
-#undef dbg
-#define dbg(f, arg...) \
-       if (hd29l2_debug) \
-               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#define HD29L2_XTAL 30400000 /* Hz */
-
-
-#define HD29L2_QAM4NR 0x00
-#define HD29L2_QAM4   0x01
-#define HD29L2_QAM16  0x02
-#define HD29L2_QAM32  0x03
-#define HD29L2_QAM64  0x04
-
-#define HD29L2_CODE_RATE_04 0x00
-#define HD29L2_CODE_RATE_06 0x08
-#define HD29L2_CODE_RATE_08 0x10
-
-#define HD29L2_PN945 0x00
-#define HD29L2_PN595 0x01
-#define HD29L2_PN420 0x02
-
-#define HD29L2_CARRIER_SINGLE 0x00
-#define HD29L2_CARRIER_MULTI  0x01
-
-#define HD29L2_INTERLEAVER_720 0x00
-#define HD29L2_INTERLEAVER_420 0x01
-
-struct reg_val {
-       u8 reg;
-       u8 val;
-};
-
-struct reg_mod_vals {
-       u8 reg;
-       u8 val[5];
-};
-
-struct hd29l2_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct hd29l2_config cfg;
-       u8 tuner_i2c_addr_programmed:1;
-
-       fe_status_t fe_status;
-};
-
-static const struct reg_mod_vals reg_mod_vals_tab[] = {
-       /* REG, QAM4NR, QAM4,QAM16,QAM32,QAM64 */
-       { 0x01, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x02, { 0x07, 0x07, 0x07, 0x07, 0x07 } },
-       { 0x03, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x04, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x05, { 0x61, 0x60, 0x60, 0x61, 0x60 } },
-       { 0x06, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x07, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x09, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x0a, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
-       { 0x0d, { 0x78, 0x78, 0x88, 0x78, 0x78 } },
-       { 0x0e, { 0xa0, 0x90, 0xa0, 0xa0, 0xa0 } },
-       { 0x0f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x10, { 0xa0, 0xa0, 0x58, 0x38, 0x38 } },
-       { 0x11, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x12, { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a } },
-       { 0x13, { 0xa2, 0xa2, 0xa2, 0xa2, 0xa2 } },
-       { 0x17, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
-       { 0x18, { 0x21, 0x21, 0x42, 0x52, 0x42 } },
-       { 0x19, { 0x21, 0x21, 0x62, 0x72, 0x62 } },
-       { 0x1a, { 0x32, 0x43, 0xa9, 0xb9, 0xa9 } },
-       { 0x1b, { 0x32, 0x43, 0xb9, 0xd8, 0xb9 } },
-       { 0x1c, { 0x02, 0x02, 0x03, 0x02, 0x03 } },
-       { 0x1d, { 0x0c, 0x0c, 0x01, 0x02, 0x02 } },
-       { 0x1e, { 0x02, 0x02, 0x02, 0x01, 0x02 } },
-       { 0x1f, { 0x02, 0x02, 0x01, 0x02, 0x04 } },
-       { 0x20, { 0x01, 0x02, 0x01, 0x01, 0x01 } },
-       { 0x21, { 0x08, 0x08, 0x0a, 0x0a, 0x0a } },
-       { 0x22, { 0x06, 0x06, 0x04, 0x05, 0x05 } },
-       { 0x23, { 0x06, 0x06, 0x05, 0x03, 0x05 } },
-       { 0x24, { 0x08, 0x08, 0x05, 0x07, 0x07 } },
-       { 0x25, { 0x16, 0x10, 0x10, 0x0a, 0x10 } },
-       { 0x26, { 0x14, 0x14, 0x04, 0x04, 0x04 } },
-       { 0x27, { 0x58, 0x58, 0x58, 0x5c, 0x58 } },
-       { 0x28, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x29, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x2a, { 0x08, 0x0a, 0x08, 0x08, 0x08 } },
-       { 0x2b, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
-       { 0x2c, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x2d, { 0x05, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x2e, { 0x21, 0x21, 0x21, 0x21, 0x21 } },
-       { 0x2f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x30, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
-       { 0x33, { 0xb7, 0xb7, 0xb7, 0xb7, 0xb7 } },
-       { 0x34, { 0x81, 0x81, 0x81, 0x81, 0x81 } },
-       { 0x35, { 0x80, 0x80, 0x80, 0x80, 0x80 } },
-       { 0x37, { 0x70, 0x70, 0x70, 0x70, 0x70 } },
-       { 0x38, { 0x04, 0x04, 0x02, 0x02, 0x02 } },
-       { 0x39, { 0x07, 0x07, 0x05, 0x05, 0x05 } },
-       { 0x3a, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x3b, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
-       { 0x3c, { 0x07, 0x06, 0x04, 0x04, 0x04 } },
-       { 0x3d, { 0xf0, 0xf0, 0xf0, 0xf0, 0x80 } },
-       { 0x3e, { 0x60, 0x60, 0x60, 0x60, 0xff } },
-       { 0x3f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x40, { 0x5b, 0x5b, 0x5b, 0x57, 0x50 } },
-       { 0x41, { 0x30, 0x30, 0x30, 0x30, 0x18 } },
-       { 0x42, { 0x20, 0x20, 0x20, 0x00, 0x30 } },
-       { 0x43, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x44, { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f } },
-       { 0x45, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x46, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x47, { 0x00, 0x00, 0x95, 0x00, 0x95 } },
-       { 0x48, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
-       { 0x49, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
-       { 0x4a, { 0x40, 0x40, 0x33, 0x11, 0x11 } },
-       { 0x4b, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x4c, { 0x40, 0x40, 0x99, 0x11, 0x11 } },
-       { 0x4d, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x4e, { 0x40, 0x40, 0x66, 0x77, 0x77 } },
-       { 0x4f, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x50, { 0x40, 0x40, 0x88, 0x33, 0x11 } },
-       { 0x51, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x52, { 0x40, 0x40, 0x88, 0x02, 0x02 } },
-       { 0x53, { 0x40, 0x40, 0x00, 0x02, 0x02 } },
-       { 0x54, { 0x00, 0x00, 0x88, 0x33, 0x33 } },
-       { 0x55, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x56, { 0x00, 0x00, 0x00, 0x0b, 0x00 } },
-       { 0x57, { 0x40, 0x40, 0x0a, 0x0b, 0x0a } },
-       { 0x58, { 0xaa, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x59, { 0x7a, 0x40, 0x02, 0x02, 0x02 } },
-       { 0x5a, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5b, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5c, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5d, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5e, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
-       { 0x5f, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
-       { 0x60, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
-       { 0x61, { 0x40, 0x40, 0x10, 0x30, 0x30 } },
-       { 0x62, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
-       { 0x63, { 0x40, 0x40, 0x05, 0x30, 0x30 } },
-       { 0x64, { 0x40, 0x40, 0x06, 0x00, 0x30 } },
-       { 0x65, { 0x40, 0x40, 0x06, 0x08, 0x30 } },
-       { 0x66, { 0x40, 0x40, 0x00, 0x00, 0x20 } },
-       { 0x67, { 0x40, 0x40, 0x01, 0x04, 0x20 } },
-       { 0x68, { 0x00, 0x00, 0x30, 0x00, 0x20 } },
-       { 0x69, { 0xa0, 0xa0, 0x00, 0x08, 0x20 } },
-       { 0x6a, { 0x00, 0x00, 0x30, 0x00, 0x25 } },
-       { 0x6b, { 0xa0, 0xa0, 0x00, 0x06, 0x25 } },
-       { 0x6c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x6d, { 0xa0, 0x60, 0x0c, 0x03, 0x0c } },
-       { 0x6e, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x6f, { 0xa0, 0x60, 0x04, 0x01, 0x04 } },
-       { 0x70, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
-       { 0x71, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
-       { 0x72, { 0x58, 0x58, 0xff, 0xff, 0xff } },
-       { 0x73, { 0x58, 0x58, 0xff, 0xff, 0xff } },
-       { 0x74, { 0x06, 0x06, 0x09, 0x05, 0x05 } },
-       { 0x75, { 0x06, 0x06, 0x0a, 0x10, 0x10 } },
-       { 0x76, { 0x10, 0x10, 0x06, 0x0a, 0x0a } },
-       { 0x77, { 0x12, 0x18, 0x28, 0x10, 0x28 } },
-       { 0x78, { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8 } },
-       { 0x79, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
-       { 0x7a, { 0x02, 0x02, 0x01, 0x04, 0x03 } },
-       { 0x7b, { 0x01, 0x02, 0x03, 0x03, 0x03 } },
-       { 0x7c, { 0x28, 0x28, 0x28, 0x28, 0x28 } },
-       { 0x7f, { 0x25, 0x92, 0x5f, 0x17, 0x2d } },
-       { 0x80, { 0x64, 0x64, 0x64, 0x74, 0x64 } },
-       { 0x83, { 0x06, 0x03, 0x04, 0x04, 0x04 } },
-       { 0x84, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x85, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0x86, { 0x00, 0x00, 0x11, 0x11, 0x11 } },
-       { 0x87, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
-       { 0x88, { 0x09, 0x09, 0x09, 0x09, 0x09 } },
-       { 0x89, { 0x20, 0x20, 0x30, 0x20, 0x20 } },
-       { 0x8a, { 0x03, 0x03, 0x02, 0x03, 0x02 } },
-       { 0x8b, { 0x00, 0x07, 0x09, 0x00, 0x09 } },
-       { 0x8c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x8d, { 0x4f, 0x4f, 0x4f, 0x3f, 0x4f } },
-       { 0x8e, { 0xf0, 0xf0, 0x60, 0xf0, 0xa0 } },
-       { 0x8f, { 0xe8, 0xe8, 0xe8, 0xe8, 0xe8 } },
-       { 0x90, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x91, { 0x40, 0x40, 0x70, 0x70, 0x10 } },
-       { 0x92, { 0x00, 0x00, 0x00, 0x00, 0x04 } },
-       { 0x93, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
-       { 0x94, { 0x00, 0x00, 0x00, 0x00, 0x03 } },
-       { 0x95, { 0x09, 0x09, 0x47, 0x47, 0x47 } },
-       { 0x96, { 0x80, 0xa0, 0xa0, 0x40, 0xa0 } },
-       { 0x97, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
-       { 0x98, { 0x50, 0x50, 0x50, 0x30, 0x50 } },
-       { 0x99, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x9a, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x9b, { 0x40, 0x40, 0x40, 0x30, 0x40 } },
-       { 0x9c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa0, { 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 } },
-       { 0xa1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa2, { 0x30, 0x30, 0x00, 0x30, 0x00 } },
-       { 0xa3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa5, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa8, { 0x77, 0x77, 0x77, 0x77, 0x77 } },
-       { 0xa9, { 0x02, 0x02, 0x02, 0x02, 0x02 } },
-       { 0xaa, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
-       { 0xac, { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f } },
-       { 0xad, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
-       { 0xae, { 0x78, 0x78, 0x78, 0x78, 0x78 } },
-       { 0xaf, { 0x06, 0x06, 0x06, 0x06, 0x07 } },
-       { 0xb0, { 0x1b, 0x1b, 0x1b, 0x19, 0x1b } },
-       { 0xb1, { 0x18, 0x17, 0x17, 0x18, 0x17 } },
-       { 0xb2, { 0x35, 0x82, 0x82, 0x38, 0x82 } },
-       { 0xb3, { 0xb6, 0xce, 0xc7, 0x5c, 0xb0 } },
-       { 0xb4, { 0x3f, 0x3e, 0x3e, 0x3f, 0x3e } },
-       { 0xb5, { 0x70, 0x58, 0x50, 0x68, 0x50 } },
-       { 0xb6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xb7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xb8, { 0x03, 0x03, 0x01, 0x01, 0x01 } },
-       { 0xb9, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xba, { 0x06, 0x06, 0x0a, 0x05, 0x0a } },
-       { 0xbb, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbc, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbd, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbe, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbf, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc3, { 0x00, 0x00, 0x88, 0x66, 0x88 } },
-       { 0xc4, { 0x10, 0x10, 0x00, 0x00, 0x00 } },
-       { 0xc5, { 0x00, 0x00, 0x44, 0x60, 0x44 } },
-       { 0xc6, { 0x10, 0x0a, 0x00, 0x00, 0x00 } },
-       { 0xc7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc8, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc9, { 0x90, 0x04, 0x00, 0x00, 0x00 } },
-       { 0xca, { 0x90, 0x08, 0x01, 0x01, 0x01 } },
-       { 0xcb, { 0xa0, 0x04, 0x00, 0x44, 0x00 } },
-       { 0xcc, { 0xa0, 0x10, 0x03, 0x00, 0x03 } },
-       { 0xcd, { 0x06, 0x06, 0x06, 0x05, 0x06 } },
-       { 0xce, { 0x05, 0x05, 0x01, 0x01, 0x01 } },
-       { 0xcf, { 0x40, 0x20, 0x18, 0x18, 0x18 } },
-       { 0xd0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd4, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0xd5, { 0x05, 0x05, 0x05, 0x03, 0x05 } },
-       { 0xd6, { 0xac, 0x22, 0xca, 0x8f, 0xca } },
-       { 0xd7, { 0x20, 0x20, 0x20, 0x20, 0x20 } },
-       { 0xd8, { 0x01, 0x01, 0x01, 0x01, 0x01 } },
-       { 0xd9, { 0x00, 0x00, 0x0f, 0x00, 0x0f } },
-       { 0xda, { 0x00, 0xff, 0xff, 0x0e, 0xff } },
-       { 0xdb, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdc, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdd, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0xde, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdf, { 0x42, 0x42, 0x44, 0x44, 0x04 } },
-       { 0xe0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe3, { 0x00, 0x00, 0x26, 0x06, 0x26 } },
-       { 0xe4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe5, { 0x01, 0x0a, 0x01, 0x01, 0x01 } },
-       { 0xe6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe7, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
-       { 0xe8, { 0x63, 0x63, 0x63, 0x63, 0x63 } },
-       { 0xe9, { 0x59, 0x59, 0x59, 0x59, 0x59 } },
-       { 0xea, { 0x80, 0x80, 0x20, 0x80, 0x80 } },
-       { 0xeb, { 0x37, 0x37, 0x78, 0x37, 0x77 } },
-       { 0xec, { 0x1f, 0x1f, 0x25, 0x25, 0x25 } },
-       { 0xed, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xee, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xef, { 0x70, 0x70, 0x58, 0x38, 0x58 } },
-       { 0xf0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-};
-
-#endif /* HD29L2_PRIV */
diff --git a/drivers/media/dvb/frontends/isl6405.c b/drivers/media/dvb/frontends/isl6405.c
deleted file mode 100644 (file)
index 33d33f4..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * isl6405.c - driver for dual lnb supply and control ic ISL6405
- *
- * Copyright (C) 2008 Hartmut Hackmann
- * Copyright (C) 2006 Oliver Endriss
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "isl6405.h"
-
-struct isl6405 {
-       u8                      config;
-       u8                      override_or;
-       u8                      override_and;
-       struct i2c_adapter      *i2c;
-       u8                      i2c_addr;
-};
-
-static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = isl6405->i2c_addr, .flags = 0,
-                               .buf = &isl6405->config,
-                               .len = sizeof(isl6405->config) };
-
-       if (isl6405->override_or & 0x80) {
-               isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2);
-               switch (voltage) {
-               case SEC_VOLTAGE_OFF:
-                       break;
-               case SEC_VOLTAGE_13:
-                       isl6405->config |= ISL6405_EN2;
-                       break;
-               case SEC_VOLTAGE_18:
-                       isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1);
-               switch (voltage) {
-               case SEC_VOLTAGE_OFF:
-                       break;
-               case SEC_VOLTAGE_13:
-                       isl6405->config |= ISL6405_EN1;
-                       break;
-               case SEC_VOLTAGE_18:
-                       isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1);
-                       break;
-               default:
-                       return -EINVAL;
-               };
-       }
-       isl6405->config |= isl6405->override_or;
-       isl6405->config &= isl6405->override_and;
-
-       return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
-{
-       struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = isl6405->i2c_addr, .flags = 0,
-                               .buf = &isl6405->config,
-                               .len = sizeof(isl6405->config) };
-
-       if (isl6405->override_or & 0x80) {
-               if (arg)
-                       isl6405->config |= ISL6405_LLC2;
-               else
-                       isl6405->config &= ~ISL6405_LLC2;
-       } else {
-               if (arg)
-                       isl6405->config |= ISL6405_LLC1;
-               else
-                       isl6405->config &= ~ISL6405_LLC1;
-       }
-       isl6405->config |= isl6405->override_or;
-       isl6405->config &= isl6405->override_and;
-
-       return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static void isl6405_release(struct dvb_frontend *fe)
-{
-       /* power off */
-       isl6405_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       /* free */
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
-                                   u8 i2c_addr, u8 override_set, u8 override_clear)
-{
-       struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL);
-       if (!isl6405)
-               return NULL;
-
-       /* default configuration */
-       if (override_set & 0x80)
-               isl6405->config = ISL6405_ISEL2;
-       else
-               isl6405->config = ISL6405_ISEL1;
-       isl6405->i2c = i2c;
-       isl6405->i2c_addr = i2c_addr;
-       fe->sec_priv = isl6405;
-
-       /* bits which should be forced to '1' */
-       isl6405->override_or = override_set;
-
-       /* bits which should be forced to '0' */
-       isl6405->override_and = ~override_clear;
-
-       /* detect if it is present or not */
-       if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) {
-               kfree(isl6405);
-               fe->sec_priv = NULL;
-               return NULL;
-       }
-
-       /* install release callback */
-       fe->ops.release_sec = isl6405_release;
-
-       /* override frontend ops */
-       fe->ops.set_voltage = isl6405_set_voltage;
-       fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage;
-
-       return fe;
-}
-EXPORT_SYMBOL(isl6405_attach);
-
-MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405");
-MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6405.h b/drivers/media/dvb/frontends/isl6405.h
deleted file mode 100644 (file)
index 1c793d3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * isl6405.h - driver for dual lnb supply and control ic ISL6405
- *
- * Copyright (C) 2008 Hartmut Hackmann
- * Copyright (C) 2006 Oliver Endriss
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef _ISL6405_H
-#define _ISL6405_H
-
-#include <linux/dvb/frontend.h>
-
-/* system register bits */
-
-/* this bit selects register (control) 1 or 2
-   note that the bit maps are different */
-
-#define ISL6405_SR     0x80
-
-/* SR = 0 */
-#define ISL6405_OLF1   0x01
-#define ISL6405_EN1    0x02
-#define ISL6405_VSEL1  0x04
-#define ISL6405_LLC1   0x08
-#define ISL6405_ENT1   0x10
-#define ISL6405_ISEL1  0x20
-#define ISL6405_DCL    0x40
-
-/* SR = 1 */
-#define ISL6405_OLF2   0x01
-#define ISL6405_OTF    0x02
-#define ISL6405_EN2    0x04
-#define ISL6405_VSEL2  0x08
-#define ISL6405_LLC2   0x10
-#define ISL6405_ENT2   0x20
-#define ISL6405_ISEL2  0x40
-
-#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE))
-/* override_set and override_clear control which system register bits (above)
- * to always set & clear
- */
-extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
-                                          u8 i2c_addr, u8 override_set, u8 override_clear);
-#else
-static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe,
-                                                 struct i2c_adapter *i2c, u8 i2c_addr,
-                                                 u8 override_set, u8 override_clear)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_ISL6405 */
-
-#endif
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
deleted file mode 100644 (file)
index 684c8ec..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * isl6421.h - driver for lnb supply and control ic ISL6421
- *
- * Copyright (C) 2006 Andrew de Quincey
- * Copyright (C) 2006 Oliver Endriss
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "isl6421.h"
-
-struct isl6421 {
-       u8                      config;
-       u8                      override_or;
-       u8                      override_and;
-       struct i2c_adapter      *i2c;
-       u8                      i2c_addr;
-};
-
-static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = isl6421->i2c_addr, .flags = 0,
-                               .buf = &isl6421->config,
-                               .len = sizeof(isl6421->config) };
-
-       isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
-
-       switch(voltage) {
-       case SEC_VOLTAGE_OFF:
-               break;
-       case SEC_VOLTAGE_13:
-               isl6421->config |= ISL6421_EN1;
-               break;
-       case SEC_VOLTAGE_18:
-               isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       isl6421->config |= isl6421->override_or;
-       isl6421->config &= isl6421->override_and;
-
-       return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
-{
-       struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = isl6421->i2c_addr, .flags = 0,
-                               .buf = &isl6421->config,
-                               .len = sizeof(isl6421->config) };
-
-       if (arg)
-               isl6421->config |= ISL6421_LLC1;
-       else
-               isl6421->config &= ~ISL6421_LLC1;
-
-       isl6421->config |= isl6421->override_or;
-       isl6421->config &= isl6421->override_and;
-
-       return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static void isl6421_release(struct dvb_frontend *fe)
-{
-       /* power off */
-       isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       /* free */
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
-                  u8 override_set, u8 override_clear)
-{
-       struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
-       if (!isl6421)
-               return NULL;
-
-       /* default configuration */
-       isl6421->config = ISL6421_ISEL1;
-       isl6421->i2c = i2c;
-       isl6421->i2c_addr = i2c_addr;
-       fe->sec_priv = isl6421;
-
-       /* bits which should be forced to '1' */
-       isl6421->override_or = override_set;
-
-       /* bits which should be forced to '0' */
-       isl6421->override_and = ~override_clear;
-
-       /* detect if it is present or not */
-       if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
-               kfree(isl6421);
-               fe->sec_priv = NULL;
-               return NULL;
-       }
-
-       /* install release callback */
-       fe->ops.release_sec = isl6421_release;
-
-       /* override frontend ops */
-       fe->ops.set_voltage = isl6421_set_voltage;
-       fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
-
-       return fe;
-}
-EXPORT_SYMBOL(isl6421_attach);
-
-MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
-MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
deleted file mode 100644 (file)
index 47e4518..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * isl6421.h - driver for lnb supply and control ic ISL6421
- *
- * Copyright (C) 2006 Andrew de Quincey
- * Copyright (C) 2006 Oliver Endriss
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef _ISL6421_H
-#define _ISL6421_H
-
-#include <linux/dvb/frontend.h>
-
-/* system register bits */
-#define ISL6421_OLF1   0x01
-#define ISL6421_EN1    0x02
-#define ISL6421_VSEL1  0x04
-#define ISL6421_LLC1   0x08
-#define ISL6421_ENT1   0x10
-#define ISL6421_ISEL1  0x20
-#define ISL6421_DCL    0x40
-
-#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE))
-/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
-                         u8 override_set, u8 override_clear);
-#else
-static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
-                                                 u8 override_set, u8 override_clear)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_ISL6421
-
-#endif
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c
deleted file mode 100644 (file)
index dca5beb..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
-       Intersil ISL6423 SEC and LNB Power supply controller
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "isl6423.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "Set Verbosity level");
-
-#define FE_ERROR                               0
-#define FE_NOTICE                              1
-#define FE_INFO                                        2
-#define FE_DEBUG                               3
-#define FE_DEBUGREG                            4
-
-#define dprintk(__y, __z, format, arg...) do {                                         \
-       if (__z) {                                                                      \
-               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
-               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((verbose > FE_INFO) && (verbose > __y))                        \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
-               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (verbose > __y)                                                      \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while (0)
-
-struct isl6423_dev {
-       const struct isl6423_config     *config;
-       struct i2c_adapter              *i2c;
-
-       u8 reg_3;
-       u8 reg_4;
-
-       unsigned int verbose;
-};
-
-static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
-{
-       struct i2c_adapter *i2c = isl6423->i2c;
-       u8 addr                 = isl6423->config->addr;
-       int err = 0;
-
-       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
-
-       dprintk(FE_DEBUG, 1, "write reg %02X", reg);
-       err = i2c_transfer(i2c, &msg, 1);
-       if (err < 0)
-               goto exit;
-       return 0;
-
-exit:
-       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
-       return err;
-}
-
-static int isl6423_set_modulation(struct dvb_frontend *fe)
-{
-       struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
-       const struct isl6423_config *config     = isl6423->config;
-       int err = 0;
-       u8 reg_2 = 0;
-
-       reg_2 = 0x01 << 5;
-
-       if (config->mod_extern)
-               reg_2 |= (1 << 3);
-       else
-               reg_2 |= (1 << 4);
-
-       err = isl6423_write(isl6423, reg_2);
-       if (err < 0)
-               goto exit;
-       return 0;
-
-exit:
-       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
-       return err;
-}
-
-static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
-{
-       struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
-       u8 reg_3 = isl6423->reg_3;
-       u8 reg_4 = isl6423->reg_4;
-       int err = 0;
-
-       if (arg) {
-               /* EN = 1, VSPEN = 1, VBOT = 1 */
-               reg_4 |= (1 << 4);
-               reg_4 |= 0x1;
-               reg_3 |= (1 << 3);
-       } else {
-               /* EN = 1, VSPEN = 1, VBOT = 0 */
-               reg_4 |= (1 << 4);
-               reg_4 &= ~0x1;
-               reg_3 |= (1 << 3);
-       }
-       err = isl6423_write(isl6423, reg_3);
-       if (err < 0)
-               goto exit;
-
-       err = isl6423_write(isl6423, reg_4);
-       if (err < 0)
-               goto exit;
-
-       isl6423->reg_3 = reg_3;
-       isl6423->reg_4 = reg_4;
-
-       return 0;
-exit:
-       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
-       return err;
-}
-
-
-static int isl6423_set_voltage(struct dvb_frontend *fe,
-                              enum fe_sec_voltage voltage)
-{
-       struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
-       u8 reg_3 = isl6423->reg_3;
-       u8 reg_4 = isl6423->reg_4;
-       int err = 0;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_OFF:
-               /* EN = 0 */
-               reg_4 &= ~(1 << 4);
-               break;
-
-       case SEC_VOLTAGE_13:
-               /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
-               reg_4 |= (1 << 4);
-               reg_4 &= ~0x3;
-               reg_3 |= (1 << 3);
-               break;
-
-       case SEC_VOLTAGE_18:
-               /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
-               reg_4 |= (1 << 4);
-               reg_4 |=  0x2;
-               reg_4 &= ~0x1;
-               reg_3 |= (1 << 3);
-               break;
-
-       default:
-               break;
-       }
-       err = isl6423_write(isl6423, reg_3);
-       if (err < 0)
-               goto exit;
-
-       err = isl6423_write(isl6423, reg_4);
-       if (err < 0)
-               goto exit;
-
-       isl6423->reg_3 = reg_3;
-       isl6423->reg_4 = reg_4;
-
-       return 0;
-exit:
-       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
-       return err;
-}
-
-static int isl6423_set_current(struct dvb_frontend *fe)
-{
-       struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
-       u8 reg_3 = isl6423->reg_3;
-       const struct isl6423_config *config     = isl6423->config;
-       int err = 0;
-
-       switch (config->current_max) {
-       case SEC_CURRENT_275m:
-               /* 275mA */
-               /* ISELH = 0, ISELL = 0 */
-               reg_3 &= ~0x3;
-               break;
-
-       case SEC_CURRENT_515m:
-               /* 515mA */
-               /* ISELH = 0, ISELL = 1 */
-               reg_3 &= ~0x2;
-               reg_3 |=  0x1;
-               break;
-
-       case SEC_CURRENT_635m:
-               /* 635mA */
-               /* ISELH = 1, ISELL = 0 */
-               reg_3 &= ~0x1;
-               reg_3 |=  0x2;
-               break;
-
-       case SEC_CURRENT_800m:
-               /* 800mA */
-               /* ISELH = 1, ISELL = 1 */
-               reg_3 |= 0x3;
-               break;
-       }
-
-       err = isl6423_write(isl6423, reg_3);
-       if (err < 0)
-               goto exit;
-
-       switch (config->curlim) {
-       case SEC_CURRENT_LIM_ON:
-               /* DCL = 0 */
-               reg_3 &= ~0x10;
-               break;
-
-       case SEC_CURRENT_LIM_OFF:
-               /* DCL = 1 */
-               reg_3 |= 0x10;
-               break;
-       }
-
-       err = isl6423_write(isl6423, reg_3);
-       if (err < 0)
-               goto exit;
-
-       isl6423->reg_3 = reg_3;
-
-       return 0;
-exit:
-       dprintk(FE_ERROR, 1, "I/O error <%d>", err);
-       return err;
-}
-
-static void isl6423_release(struct dvb_frontend *fe)
-{
-       isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c,
-                                   const struct isl6423_config *config)
-{
-       struct isl6423_dev *isl6423;
-
-       isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
-       if (!isl6423)
-               return NULL;
-
-       isl6423->config = config;
-       isl6423->i2c    = i2c;
-       fe->sec_priv    = isl6423;
-
-       /* SR3H = 0, SR3M = 1, SR3L = 0 */
-       isl6423->reg_3 = 0x02 << 5;
-       /* SR4H = 0, SR4M = 1, SR4L = 1 */
-       isl6423->reg_4 = 0x03 << 5;
-
-       if (isl6423_set_current(fe))
-               goto exit;
-
-       if (isl6423_set_modulation(fe))
-               goto exit;
-
-       fe->ops.release_sec             = isl6423_release;
-       fe->ops.set_voltage             = isl6423_set_voltage;
-       fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
-       isl6423->verbose                = verbose;
-
-       return fe;
-
-exit:
-       kfree(isl6423);
-       fe->sec_priv = NULL;
-       return NULL;
-}
-EXPORT_SYMBOL(isl6423_attach);
-
-MODULE_DESCRIPTION("ISL6423 SEC");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h
deleted file mode 100644 (file)
index e1a37fb..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-       Intersil ISL6423 SEC and LNB Power supply controller
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __ISL_6423_H
-#define __ISL_6423_H
-
-#include <linux/dvb/frontend.h>
-
-enum isl6423_current {
-       SEC_CURRENT_275m = 0,
-       SEC_CURRENT_515m,
-       SEC_CURRENT_635m,
-       SEC_CURRENT_800m,
-};
-
-enum isl6423_curlim {
-       SEC_CURRENT_LIM_ON = 1,
-       SEC_CURRENT_LIM_OFF
-};
-
-struct isl6423_config {
-       enum isl6423_current current_max;
-       enum isl6423_curlim curlim;
-       u8 addr;
-       u8 mod_extern;
-};
-
-#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE))
-
-
-extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
-                                          struct i2c_adapter *i2c,
-                                          const struct isl6423_config *config);
-
-#else
-static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
-                                                 struct i2c_adapter *i2c,
-                                                 const struct isl6423_config *config)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif /* CONFIG_DVB_ISL6423 */
-
-#endif /* __ISL_6423_H */
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h
deleted file mode 100644 (file)
index eb6fd8a..0000000
+++ /dev/null
@@ -1,1051 +0,0 @@
-
-struct it913xset {     u32 pro;
-                       u32 address;
-                       u8 reg[15];
-                       u8 count;
-};
-
-struct adctable {      u32 adcFrequency;
-                       u32 bandwidth;
-                       u32 coeff_1_2048;
-                       u32 coeff_1_4096;
-                       u32 coeff_1_8191;
-                       u32 coeff_1_8192;
-                       u32 coeff_1_8193;
-                       u32 coeff_2_2k;
-                       u32 coeff_2_4k;
-                       u32 coeff_2_8k;
-                       u16 bfsfcw_fftinx_ratio;
-                       u16 fftinx_bfsfcw_ratio;
-};
-
-/* clock and coeff tables only table 3 is used with IT9137*/
-/* TODO other tables relate AF9035 may be removed */
-static struct adctable tab1[] = {
-       {       20156250, 6000000,
-               0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b, 0x00ae292a,
-               0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c      },
-       {       20156250, 7000000,
-               0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660, 0x00cb3007,
-               0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196      },
-       {       20156250, 8000000,
-               0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25, 0x00e836e3,
-               0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0      },
-       {       20156250, 5000000,
-               0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7, 0x0091224e,
-               0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122      }
-};
-
-static struct adctable tab2[] = {
-       {       20187500, 6000000,
-               0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995, 0x00ade426,
-               0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c      },
-       {       20187500, 7000000,
-               0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8, 0x00cadf81,
-               0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196      },
-       {       20187500, 8000000,
-               0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c, 0x00e7dadd,
-               0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0      },
-       {       20187500, 5000000,
-               0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51, 0x0090e8ca,
-               0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122      }
-
-};
-
-static struct adctable tab3[] = {
-       {       20250000, 6000000,
-               0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b, 0x00ad5ac1,
-               0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b      },
-       {       20250000, 7000000,
-               0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588, 0x00ca3f36,
-               0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195      },
-       {       20250000, 8000000,
-               0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4, 0x00e723ab,
-               0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce      },
-       {       20250000, 5000000,
-               0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf, 0x0090764b,
-               0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121      }
-
-};
-
-static struct adctable tab4[] = {
-       {       20583333, 6000000,
-               0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166, 0x00aa8c12,
-               0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155      },
-       {       20583333, 7000000,
-               0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7, 0x00c6f8bf,
-               0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e      },
-       {       20583333, 8000000,
-               0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88, 0x00e3656d,
-               0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7      },
-       {       20583333, 5000000,
-               0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5, 0x008e1f64,
-               0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c      }
-
-};
-
-static struct adctable tab5[] = {
-       {       20416667, 6000000,
-               0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9, 0x00abf07a,
-               0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158      },
-       {       20416667, 7000000,
-               0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3, 0x00c8988e,
-               0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191      },
-       {       20416667, 8000000,
-               0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc, 0x00e540a2,
-               0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb      },
-       {       20416667, 5000000,
-               0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0, 0x008f4865,
-               0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f      }
-
-};
-
-static struct adctable tab6[] = {
-       {       20480000, 6000000,
-               0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7, 0x00ab685c,
-               0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157      },
-       {       20480000, 7000000,
-               0x03200000, 0x01900000, 0x00c80640, 0x00c80000, 0x00c7f9c0,
-               0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190      },
-       {       20480000, 8000000,
-               0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249, 0x00e48b25,
-               0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9      },
-       {       20480000, 5000000,
-               0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e, 0x008ed6f7,
-               0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e      }
-};
-
-static struct adctable tab7[] = {
-       {       20500000, 6000000,
-               0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6, 0x00ab3d8c,
-               0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157      },
-       {       20500000, 7000000,
-               0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c, 0x00c7c7ce,
-               0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190      },
-       {       20500000, 8000000,
-               0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933, 0x00e45210,
-               0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9      },
-       {       20500000, 5000000,
-               0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0, 0x008eb34a,
-               0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d      }
-
-};
-
-static struct adctable tab8[] = {
-       {       20625000, 6000000,
-               0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f, 0x00aa33de,
-               0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154      },
-       {       20625000, 7000000,
-               0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c, 0x00c691d8,
-               0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d      },
-       {       20625000, 8000000,
-               0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea, 0x00e2efd2,
-               0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6      },
-       {       20625000, 5000000,
-               0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52, 0x008dd5e3,
-               0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c      }
-
-};
-
-struct table {
-               u32 xtal;
-               struct adctable *table;
-};
-
-static struct table fe_clockTable[] = {
-               {12000000, tab3},       /* 12.00MHz */
-               {20480000, tab6},       /* 20.48MHz */
-               {36000000, tab3},       /* 36.00MHz */
-               {30000000, tab1},       /* 30.00MHz */
-               {26000000, tab4},       /* 26.00MHz */
-               {28000000, tab5},       /* 28.00MHz */
-               {32000000, tab7},       /* 32.00MHz */
-               {34000000, tab2},       /* 34.00MHz */
-               {24000000, tab1},       /* 24.00MHz */
-               {22000000, tab8},       /* 22.00MHz */
-};
-
-/* fe get */
-fe_code_rate_t fe_code[] = {
-       FEC_1_2,
-       FEC_2_3,
-       FEC_3_4,
-       FEC_5_6,
-       FEC_7_8,
-       FEC_NONE,
-};
-
-fe_guard_interval_t fe_gi[] = {
-       GUARD_INTERVAL_1_32,
-       GUARD_INTERVAL_1_16,
-       GUARD_INTERVAL_1_8,
-       GUARD_INTERVAL_1_4,
-};
-
-fe_hierarchy_t fe_hi[] = {
-       HIERARCHY_NONE,
-       HIERARCHY_1,
-       HIERARCHY_2,
-       HIERARCHY_4,
-};
-
-fe_transmit_mode_t fe_mode[] = {
-       TRANSMISSION_MODE_2K,
-       TRANSMISSION_MODE_8K,
-       TRANSMISSION_MODE_4K,
-};
-
-fe_modulation_t fe_con[] = {
-       QPSK,
-       QAM_16,
-       QAM_64,
-};
-
-enum {
-       PRIORITY_HIGH = 0,      /* High-priority stream */
-       PRIORITY_LOW,   /* Low-priority stream */
-};
-
-/* Standard demodulator functions */
-static struct it913xset set_solo_fe[] = {
-       {PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
-       {PRO_LINK, GPIOH5_ON, {0x01}, 0x01},
-       {PRO_LINK, GPIOH5_O, {0x00}, 0x01},
-       {PRO_LINK, GPIOH5_O, {0x01}, 0x01},
-       {PRO_LINK, DVBT_INTEN, {0x04}, 0x01},
-       {PRO_LINK, DVBT_ENABLE, {0x05}, 0x01},
-       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_MPEG_SER_MODE, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_DMOD, DCA_UPPER_CHIP, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_DCA_UPPER, {0x00}, 0x01},
-       {PRO_DMOD, DCA_LOWER_CHIP, {0x00}, 0x01},
-       {PRO_LINK, HOSTB_DCA_LOWER, {0x00}, 0x01},
-       {PRO_DMOD, DCA_PLATCH, {0x00}, 0x01},
-       {PRO_DMOD, DCA_FPGA_LATCH, {0x00}, 0x01},
-       {PRO_DMOD, DCA_STAND_ALONE, {0x01}, 0x01},
-       {PRO_DMOD, DCA_ENABLE, {0x00}, 0x01},
-       {PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
-       {PRO_DMOD, BFS_FCW, {0x00, 0x00, 0x00}, 0x03},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-
-static struct it913xset init_1[] = {
-       {PRO_LINK, LOCK3_OUT, {0x01}, 0x01},
-       {PRO_LINK, PADMISCDRSR, {0x01}, 0x01},
-       {PRO_LINK, PADMISCDR2, {0x00}, 0x01},
-       {PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02},
-       {PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */
-       {PRO_LINK, PADMISCDR8, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-
-/* Version 1 types */
-static struct it913xset it9135_v1[] = {
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
-       {PRO_DMOD, 0x008a, {0x01}, 0x01},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06}, 0x01},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
-       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
-       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
-       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10}, 0x01},
-       {PRO_DMOD, 0xf017, {0x04}, 0x01},
-       {PRO_DMOD, 0xf018, {0x05}, 0x01},
-       {PRO_DMOD, 0xf019, {0x04}, 0x01},
-       {PRO_DMOD, 0xf01a, {0x05}, 0x01},
-       {PRO_DMOD, 0xf021, {0x03}, 0x01},
-       {PRO_DMOD, 0xf022, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf023, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf02c, {0x01}, 0x01},
-       {PRO_DMOD, 0xf064, {0x03}, 0x01},
-       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
-       {PRO_DMOD, 0xf066, {0x03}, 0x01},
-       {PRO_DMOD, 0xf067, {0x01}, 0x01},
-       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
-       {PRO_DMOD, 0xf070, {0x03}, 0x01},
-       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf073, {0x03}, 0x01},
-       {PRO_DMOD, 0xf078, {0x00}, 0x01},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
-       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
-       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
-       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
-       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
-       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01}, 0x01},
-       {PRO_DMOD, 0xf167, {0x40}, 0x01},
-       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
-       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
-       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
-       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf410, {0x08}, 0x01},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15}, 0x01},
-       {PRO_DMOD, 0xf562, {0x20}, 0x01},
-       {PRO_DMOD, 0xf5df, {0xfb}, 0x01},
-       {PRO_DMOD, 0xf5e0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
-       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05}, 0x01},
-       {PRO_DMOD, 0xf601, {0x08}, 0x01},
-       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
-       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
-       {PRO_DMOD, 0xf604, {0x11}, 0x01},
-       {PRO_DMOD, 0xf605, {0x14}, 0x01},
-       {PRO_DMOD, 0xf606, {0x17}, 0x01},
-       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
-       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf610, {0x32}, 0x01},
-       {PRO_DMOD, 0xf611, {0x10}, 0x01},
-       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
-       {PRO_DMOD, 0xf708, {0x00}, 0x01},
-       {PRO_DMOD, 0xf709, {0x37}, 0x01},
-       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf810, {0x54}, 0x01},
-       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_38[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x38}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8,
-                               0xd0, 0xc3, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x32}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77,
-                               0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04},
-       {PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_51[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x51}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96,
-                               0xcf, 0xc3, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77,
-                               0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04},
-       {PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_52[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x52}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x10}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
-       {PRO_DMOD, 0x0081, {    0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97,
-                               0xc0, 0x9e, 0x01}, 0x0a},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
-       {PRO_DMOD, 0x00c4, {0x00}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
-       {PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77,
-                               0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
-       {PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04},
-       {PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03},
-       {PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05},
-       {PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf5f8, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5fd, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-/* Version 2 types */
-static struct it913xset it9135_v2[] = {
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a}, 0x01},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a}, 0x01},
-       {PRO_DMOD, 0x008a, {0x01}, 0x01},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06}, 0x01},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009f, {0xe1}, 0x01},
-       {PRO_DMOD, 0x00a0, {0xcf}, 0x01},
-       {PRO_DMOD, 0x00a3, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a5, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a6, {0x01}, 0x01},
-       {PRO_DMOD, 0x00a9, {0x00}, 0x01},
-       {PRO_DMOD, 0x00aa, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00c2, {0x05}, 0x01},
-       {PRO_DMOD, 0x00c6, {0x19}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf02b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf064, {0x03}, 0x01},
-       {PRO_DMOD, 0xf065, {0xf9}, 0x01},
-       {PRO_DMOD, 0xf066, {0x03}, 0x01},
-       {PRO_DMOD, 0xf067, {0x01}, 0x01},
-       {PRO_DMOD, 0xf06f, {0xe0}, 0x01},
-       {PRO_DMOD, 0xf070, {0x03}, 0x01},
-       {PRO_DMOD, 0xf072, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf073, {0x03}, 0x01},
-       {PRO_DMOD, 0xf078, {0x00}, 0x01},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f}, 0x01},
-       {PRO_DMOD, 0xf09c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09d, {0x20}, 0x01},
-       {PRO_DMOD, 0xf09e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09f, {0x0c}, 0x01},
-       {PRO_DMOD, 0xf0a0, {0x00}, 0x01},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14d, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf15b, {0x08}, 0x01},
-       {PRO_DMOD, 0xf15d, {0x03}, 0x01},
-       {PRO_DMOD, 0xf15e, {0x05}, 0x01},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01}, 0x01},
-       {PRO_DMOD, 0xf167, {0x40}, 0x01},
-       {PRO_DMOD, 0xf168, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf17a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf17b, {0x00}, 0x01},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36}, 0x01},
-       {PRO_DMOD, 0xf1bd, {0x00}, 0x01},
-       {PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
-       {PRO_DMOD, 0xf1cc, {0x01}, 0x01},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf40e, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf40f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf410, {0x08}, 0x01},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15}, 0x01},
-       {PRO_DMOD, 0xf562, {0x20}, 0x01},
-       {PRO_DMOD, 0xf5e3, {0x09}, 0x01},
-       {PRO_DMOD, 0xf5e4, {0x01}, 0x01},
-       {PRO_DMOD, 0xf5e5, {0x01}, 0x01},
-       {PRO_DMOD, 0xf600, {0x05}, 0x01},
-       {PRO_DMOD, 0xf601, {0x08}, 0x01},
-       {PRO_DMOD, 0xf602, {0x0b}, 0x01},
-       {PRO_DMOD, 0xf603, {0x0e}, 0x01},
-       {PRO_DMOD, 0xf604, {0x11}, 0x01},
-       {PRO_DMOD, 0xf605, {0x14}, 0x01},
-       {PRO_DMOD, 0xf606, {0x17}, 0x01},
-       {PRO_DMOD, 0xf607, {0x1f}, 0x01},
-       {PRO_DMOD, 0xf60e, {0x00}, 0x01},
-       {PRO_DMOD, 0xf60f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf610, {0x32}, 0x01},
-       {PRO_DMOD, 0xf611, {0x10}, 0x01},
-       {PRO_DMOD, 0xf707, {0xfc}, 0x01},
-       {PRO_DMOD, 0xf708, {0x00}, 0x01},
-       {PRO_DMOD, 0xf709, {0x37}, 0x01},
-       {PRO_DMOD, 0xf70a, {0x00}, 0x01},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40}, 0x01},
-       {PRO_DMOD, 0xf810, {0x54}, 0x01},
-       {PRO_DMOD, 0xf811, {0x5a}, 0x01},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_60[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x60}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c,
-                               0x00, 0x02, 0xbe, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xbe}, 0x01},
-       {PRO_DMOD, 0x0124, {0xae}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x08}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c,
-                               0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xbc}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02},
-       {PRO_DMOD, 0x0185, {0x24}, 0x01},
-       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17
-               , 0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_61[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x61}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x06}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c,
-                               0x01, 0x02, 0xc8, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xc6}, 0x01},
-       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x05}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c,
-                               0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xcc}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02},
-       {PRO_DMOD, 0x0185, {0x28}, 0x01},
-       {PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-static struct it913xset it9135_62[] = {
-       {PRO_DMOD, 0x0043, {0x00}, 0x01},
-       {PRO_DMOD, 0x0046, {0x62}, 0x01},
-       {PRO_DMOD, 0x0051, {0x01}, 0x01},
-       {PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0x0068, {0x0a}, 0x01},
-       {PRO_DMOD, 0x006a, {0x03}, 0x01},
-       {PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
-       {PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
-       {PRO_DMOD, 0x007e, {0x04}, 0x01},
-       {PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
-       {PRO_DMOD, 0x0084, {    0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01},
-                               0x07},
-       {PRO_DMOD, 0x008e, {0x01}, 0x01},
-       {PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
-       {PRO_DMOD, 0x0099, {0x01}, 0x01},
-       {PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
-       {PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
-       {PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
-       {PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
-       {PRO_DMOD, 0x00b0, {0x01}, 0x01},
-       {PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
-       {PRO_DMOD, 0x00b6, {0x14}, 0x01},
-       {PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
-       {PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
-       {PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
-       {PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
-       {PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
-       {PRO_DMOD, 0x00fc, {    0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c,
-                               0x02, 0x02, 0xc2, 0x00}, 0x0b},
-       {PRO_DMOD, 0x0109, {0x02}, 0x01},
-       {PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-       {PRO_DMOD, 0x011a, {0xb8}, 0x01},
-       {PRO_DMOD, 0x0124, {0xa8}, 0x01},
-       {PRO_DMOD, 0x0127, {0x00}, 0x01},
-       {PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
-       {PRO_DMOD, 0x0137, {0x00}, 0x01},
-       {PRO_DMOD, 0x013b, {0x05}, 0x01},
-       {PRO_DMOD, 0x013f, {0x5b}, 0x01},
-       {PRO_DMOD, 0x0141, {    0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c,
-                               0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0,
-                               0x33}, 0x0f},
-       {PRO_DMOD, 0x0151, {0x28}, 0x01},
-       {PRO_DMOD, 0x0153, {0xb2}, 0x01},
-       {PRO_DMOD, 0x0178, {0x09}, 0x01},
-       {PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02},
-       {PRO_DMOD, 0x0185, {0x24}, 0x01},
-       {PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05},
-       {PRO_DMOD, 0xed02, {0xff}, 0x01},
-       {PRO_DMOD, 0xee42, {0xff}, 0x01},
-       {PRO_DMOD, 0xee82, {0xff}, 0x01},
-       {PRO_DMOD, 0xf000, {0x0f}, 0x01},
-       {PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
-       {PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
-       {PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
-       {PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
-       {PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
-       {PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
-       {PRO_DMOD, 0xf087, {0x00}, 0x01},
-       {PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
-       {PRO_DMOD, 0xf130, {0x04}, 0x01},
-       {PRO_DMOD, 0xf132, {0x04}, 0x01},
-       {PRO_DMOD, 0xf144, {0x1a}, 0x01},
-       {PRO_DMOD, 0xf146, {0x00}, 0x01},
-       {PRO_DMOD, 0xf14a, {0x01}, 0x01},
-       {PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf14f, {0x04}, 0x01},
-       {PRO_DMOD, 0xf158, {0x7f}, 0x01},
-       {PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
-       {PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
-       {PRO_DMOD, 0xf163, {0x05}, 0x01},
-       {PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
-       {PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
-       {PRO_DMOD, 0xf183, {0x01}, 0x01},
-       {PRO_DMOD, 0xf19d, {0x40}, 0x01},
-       {PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
-       {PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
-       {PRO_DMOD, 0xf204, {0x10}, 0x01},
-       {PRO_DMOD, 0xf214, {0x00}, 0x01},
-       {PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
-       {PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
-       {PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
-       {PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
-       {PRO_DMOD, 0xf55f, {0x0a}, 0x01},
-       {PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
-       {PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
-       {PRO_DMOD, 0xf600, {    0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-                               0x1f}, 0x08},
-       {PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
-       {PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
-       {PRO_DMOD, 0xf78b, {0x01}, 0x01},
-       {PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
-       {PRO_DMOD, 0xf905, {0x01}, 0x01},
-       {PRO_DMOD, 0xfb06, {0x03}, 0x01},
-       {PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
-};
-
-/* Tuner setting scripts (still keeping it9137) */
-static struct it913xset it9137_tuner_off[] = {
-       {PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off  */
-       {PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */
-       {PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04},
-       {PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00}, 0x0c},
-       {PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04},
-       {PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00}, 0x09},
-       {PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00}, 0x0a},
-       {PRO_DMOD, 0xec20, {0x00}, 0x01},
-       {PRO_DMOD, 0xec3f, {0x01}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-static struct it913xset set_it9135_template[] = {
-       {PRO_DMOD, 0xee06, {0x00}, 0x01},
-       {PRO_DMOD, 0xec56, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
-       {PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */
-       {PRO_DMOD, 0x011f, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
-
-static struct it913xset set_it9137_template[] = {
-       {PRO_DMOD, 0xee06, {0x00}, 0x01},
-       {PRO_DMOD, 0xec56, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4c, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4d, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4e, {0x00}, 0x01},
-       {PRO_DMOD, 0xec4f, {0x00}, 0x01},
-       {PRO_DMOD, 0xec50, {0x00}, 0x01},
-       {0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
-};
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c
deleted file mode 100644 (file)
index 708cbf1..0000000
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- *  Driver for it913x-fe Frontend
- *
- *  with support for on chip it9137 integral tuner
- *
- *  Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
- *  IT9137 Copyright (C) ITE Tech Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include "dvb_frontend.h"
-#include "it913x-fe.h"
-#include "it913x-fe-priv.h"
-
-static int it913x_debug;
-
-module_param_named(debug, it913x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define dprintk(level, args...) do { \
-       if (level & it913x_debug) \
-               printk(KERN_DEBUG "it913x-fe: " args); \
-} while (0)
-
-#define deb_info(args...)  dprintk(0x01, args)
-#define debug_data_snipet(level, name, p) \
-         dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
-               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
-                       *(p+5), *(p+6), *(p+7));
-#define info(format, arg...) \
-       printk(KERN_INFO "it913x-fe: " format "\n" , ## arg)
-
-struct it913x_fe_state {
-       struct dvb_frontend frontend;
-       struct i2c_adapter *i2c_adap;
-       struct ite_config *config;
-       u8 i2c_addr;
-       u32 frequency;
-       fe_modulation_t constellation;
-       fe_transmit_mode_t transmission_mode;
-       u8 priority;
-       u32 crystalFrequency;
-       u32 adcFrequency;
-       u8 tuner_type;
-       struct adctable *table;
-       fe_status_t it913x_status;
-       u16 tun_xtal;
-       u8 tun_fdiv;
-       u8 tun_clk_mode;
-       u32 tun_fn_min;
-       u32 ucblocks;
-};
-
-static int it913x_read_reg(struct it913x_fe_state *state,
-               u32 reg, u8 *data, u8 count)
-{
-       int ret;
-       u8 pro = PRO_DMOD; /* All reads from demodulator */
-       u8 b[4];
-       struct i2c_msg msg[2] = {
-               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
-                       .buf = b, .len = sizeof(b) },
-               { .addr = state->i2c_addr + (pro << 1), .flags = I2C_M_RD,
-                       .buf = data, .len = count }
-       };
-       b[0] = (u8) reg >> 24;
-       b[1] = (u8)(reg >> 16) & 0xff;
-       b[2] = (u8)(reg >> 8) & 0xff;
-       b[3] = (u8) reg & 0xff;
-
-       ret = i2c_transfer(state->i2c_adap, msg, 2);
-
-       return ret;
-}
-
-static int it913x_read_reg_u8(struct it913x_fe_state *state, u32 reg)
-{
-       int ret;
-       u8 b[1];
-       ret = it913x_read_reg(state, reg, &b[0], sizeof(b));
-       return (ret < 0) ? -ENODEV : b[0];
-}
-
-static int it913x_write(struct it913x_fe_state *state,
-               u8 pro, u32 reg, u8 buf[], u8 count)
-{
-       u8 b[256];
-       struct i2c_msg msg[1] = {
-               { .addr = state->i2c_addr + (pro << 1), .flags = 0,
-                 .buf = b, .len = count + 4 }
-       };
-       int ret;
-
-       b[0] = (u8) reg >> 24;
-       b[1] = (u8)(reg >> 16) & 0xff;
-       b[2] = (u8)(reg >> 8) & 0xff;
-       b[3] = (u8) reg & 0xff;
-       memcpy(&b[4], buf, count);
-
-       ret = i2c_transfer(state->i2c_adap, msg, 1);
-
-       if (ret < 0)
-               return -EIO;
-
-       return 0;
-}
-
-static int it913x_write_reg(struct it913x_fe_state *state,
-               u8 pro, u32 reg, u32 data)
-{
-       int ret;
-       u8 b[4];
-       u8 s;
-
-       b[0] = data >> 24;
-       b[1] = (data >> 16) & 0xff;
-       b[2] = (data >> 8) & 0xff;
-       b[3] = data & 0xff;
-       /* expand write as needed */
-       if (data < 0x100)
-               s = 3;
-       else if (data < 0x1000)
-               s = 2;
-       else if (data < 0x100000)
-               s = 1;
-       else
-               s = 0;
-
-       ret = it913x_write(state, pro, reg, &b[s], sizeof(b) - s);
-
-       return ret;
-}
-
-static int it913x_fe_script_loader(struct it913x_fe_state *state,
-               struct it913xset *loadscript)
-{
-       int ret, i;
-       if (loadscript == NULL)
-               return -EINVAL;
-
-       for (i = 0; i < 1000; ++i) {
-               if (loadscript[i].pro == 0xff)
-                       break;
-               ret = it913x_write(state, loadscript[i].pro,
-                       loadscript[i].address,
-                       loadscript[i].reg, loadscript[i].count);
-               if (ret < 0)
-                       return -ENODEV;
-       }
-       return 0;
-}
-
-static int it913x_init_tuner(struct it913x_fe_state *state)
-{
-       int ret, i, reg;
-       u8 val, nv_val;
-       u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
-       u8 b[2];
-
-       reg = it913x_read_reg_u8(state, 0xec86);
-       switch (reg) {
-       case 0:
-               state->tun_clk_mode = reg;
-               state->tun_xtal = 2000;
-               state->tun_fdiv = 3;
-               val = 16;
-               break;
-       case -ENODEV:
-               return -ENODEV;
-       case 1:
-       default:
-               state->tun_clk_mode = reg;
-               state->tun_xtal = 640;
-               state->tun_fdiv = 1;
-               val = 6;
-               break;
-       }
-
-       reg = it913x_read_reg_u8(state, 0xed03);
-
-       if (reg < 0)
-               return -ENODEV;
-       else if (reg < sizeof(nv))
-               nv_val = nv[reg];
-       else
-               nv_val = 2;
-
-       for (i = 0; i < 50; i++) {
-               ret = it913x_read_reg(state, 0xed23, &b[0], sizeof(b));
-               reg = (b[1] << 8) + b[0];
-               if (reg > 0)
-                       break;
-               if (ret < 0)
-                       return -ENODEV;
-               udelay(2000);
-       }
-       state->tun_fn_min = state->tun_xtal * reg;
-       state->tun_fn_min /= (state->tun_fdiv * nv_val);
-       deb_info("Tuner fn_min %d", state->tun_fn_min);
-
-       if (state->config->chip_ver > 1)
-               msleep(50);
-       else {
-               for (i = 0; i < 50; i++) {
-                       reg = it913x_read_reg_u8(state, 0xec82);
-                       if (reg > 0)
-                               break;
-                       if (reg < 0)
-                               return -ENODEV;
-                       udelay(2000);
-               }
-       }
-
-       return it913x_write_reg(state, PRO_DMOD, 0xed81, val);
-}
-
-static int it9137_set_tuner(struct it913x_fe_state *state,
-               u32 bandwidth, u32 frequency_m)
-{
-       struct it913xset *set_tuner = set_it9137_template;
-       int ret, reg;
-       u32 frequency = frequency_m / 1000;
-       u32 freq, temp_f, tmp;
-       u16 iqik_m_cal;
-       u16 n_div;
-       u8 n;
-       u8 l_band;
-       u8 lna_band;
-       u8 bw;
-
-       if (state->config->firmware_ver == 1)
-               set_tuner = set_it9135_template;
-       else
-               set_tuner = set_it9137_template;
-
-       deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth);
-
-       if (frequency >= 51000 && frequency <= 440000) {
-               l_band = 0;
-               lna_band = 0;
-       } else if (frequency > 440000 && frequency <= 484000) {
-               l_band = 1;
-               lna_band = 1;
-       } else if (frequency > 484000 && frequency <= 533000) {
-               l_band = 1;
-               lna_band = 2;
-       } else if (frequency > 533000 && frequency <= 587000) {
-               l_band = 1;
-               lna_band = 3;
-       } else if (frequency > 587000 && frequency <= 645000) {
-               l_band = 1;
-               lna_band = 4;
-       } else if (frequency > 645000 && frequency <= 710000) {
-               l_band = 1;
-               lna_band = 5;
-       } else if (frequency > 710000 && frequency <= 782000) {
-               l_band = 1;
-               lna_band = 6;
-       } else if (frequency > 782000 && frequency <= 860000) {
-               l_band = 1;
-               lna_band = 7;
-       } else if (frequency > 1450000 && frequency <= 1492000) {
-               l_band = 1;
-               lna_band = 0;
-       } else if (frequency > 1660000 && frequency <= 1685000) {
-               l_band = 1;
-               lna_band = 1;
-       } else
-               return -EINVAL;
-       set_tuner[0].reg[0] = lna_band;
-
-       switch (bandwidth) {
-       case 5000000:
-               bw = 0;
-               break;
-       case 6000000:
-               bw = 2;
-               break;
-       case 7000000:
-               bw = 4;
-               break;
-       default:
-       case 8000000:
-               bw = 6;
-               break;
-       }
-
-       set_tuner[1].reg[0] = bw;
-       set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
-
-       if (frequency > 53000 && frequency <= 74000) {
-               n_div = 48;
-               n = 0;
-       } else if (frequency > 74000 && frequency <= 111000) {
-               n_div = 32;
-               n = 1;
-       } else if (frequency > 111000 && frequency <= 148000) {
-               n_div = 24;
-               n = 2;
-       } else if (frequency > 148000 && frequency <= 222000) {
-               n_div = 16;
-               n = 3;
-       } else if (frequency > 222000 && frequency <= 296000) {
-               n_div = 12;
-               n = 4;
-       } else if (frequency > 296000 && frequency <= 445000) {
-               n_div = 8;
-               n = 5;
-       } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
-               n_div = 6;
-               n = 6;
-       } else if (frequency > state->tun_fn_min && frequency <= 950000) {
-               n_div = 4;
-               n = 7;
-       } else if (frequency > 1450000 && frequency <= 1680000) {
-               n_div = 2;
-               n = 0;
-       } else
-               return -EINVAL;
-
-       reg = it913x_read_reg_u8(state, 0xed81);
-       iqik_m_cal = (u16)reg * n_div;
-
-       if (reg < 0x20) {
-               if (state->tun_clk_mode == 0)
-                       iqik_m_cal = (iqik_m_cal * 9) >> 5;
-               else
-                       iqik_m_cal >>= 1;
-       } else {
-               iqik_m_cal = 0x40 - iqik_m_cal;
-               if (state->tun_clk_mode == 0)
-                       iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
-               else
-                       iqik_m_cal = ~(iqik_m_cal >> 1);
-       }
-
-       temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
-       freq = temp_f / state->tun_xtal;
-       tmp = freq * state->tun_xtal;
-
-       if ((temp_f - tmp) >= (state->tun_xtal >> 1))
-               freq++;
-
-       freq += (u32) n << 13;
-       /* Frequency OMEGA_IQIK_M_CAL_MID*/
-       temp_f = freq + (u32)iqik_m_cal;
-
-       set_tuner[3].reg[0] =  temp_f & 0xff;
-       set_tuner[4].reg[0] =  (temp_f >> 8) & 0xff;
-
-       deb_info("High Frequency = %04x", temp_f);
-
-       /* Lower frequency */
-       set_tuner[5].reg[0] =  freq & 0xff;
-       set_tuner[6].reg[0] =  (freq >> 8) & 0xff;
-
-       deb_info("low Frequency = %04x", freq);
-
-       ret = it913x_fe_script_loader(state, set_tuner);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_select_bw(struct it913x_fe_state *state,
-                       u32 bandwidth, u32 adcFrequency)
-{
-       int ret, i;
-       u8 buffer[256];
-       u32 coeff[8];
-       u16 bfsfcw_fftinx_ratio;
-       u16 fftinx_bfsfcw_ratio;
-       u8 count;
-       u8 bw;
-       u8 adcmultiplier;
-
-       deb_info("Bandwidth %d Adc %d", bandwidth, adcFrequency);
-
-       switch (bandwidth) {
-       case 5000000:
-               bw = 3;
-               break;
-       case 6000000:
-               bw = 0;
-               break;
-       case 7000000:
-               bw = 1;
-               break;
-       default:
-       case 8000000:
-               bw = 2;
-               break;
-       }
-       ret = it913x_write_reg(state, PRO_DMOD, REG_BW, bw);
-
-       if (state->table == NULL)
-               return -EINVAL;
-
-       /* In write order */
-       coeff[0] = state->table[bw].coeff_1_2048;
-       coeff[1] = state->table[bw].coeff_2_2k;
-       coeff[2] = state->table[bw].coeff_1_8191;
-       coeff[3] = state->table[bw].coeff_1_8192;
-       coeff[4] = state->table[bw].coeff_1_8193;
-       coeff[5] = state->table[bw].coeff_2_8k;
-       coeff[6] = state->table[bw].coeff_1_4096;
-       coeff[7] = state->table[bw].coeff_2_4k;
-       bfsfcw_fftinx_ratio = state->table[bw].bfsfcw_fftinx_ratio;
-       fftinx_bfsfcw_ratio = state->table[bw].fftinx_bfsfcw_ratio;
-
-       /* ADC multiplier */
-       ret = it913x_read_reg_u8(state, ADC_X_2);
-       if (ret < 0)
-               return -EINVAL;
-
-       adcmultiplier = ret;
-
-       count = 0;
-
-       /*  Build Buffer for COEFF Registers */
-       for (i = 0; i < 8; i++) {
-               if (adcmultiplier == 1)
-                       coeff[i] /= 2;
-               buffer[count++] = (coeff[i] >> 24) & 0x3;
-               buffer[count++] = (coeff[i] >> 16) & 0xff;
-               buffer[count++] = (coeff[i] >> 8) & 0xff;
-               buffer[count++] = coeff[i] & 0xff;
-       }
-
-       /* bfsfcw_fftinx_ratio register 0x21-0x22 */
-       buffer[count++] = bfsfcw_fftinx_ratio & 0xff;
-       buffer[count++] = (bfsfcw_fftinx_ratio >> 8) & 0xff;
-       /* fftinx_bfsfcw_ratio register 0x23-0x24 */
-       buffer[count++] = fftinx_bfsfcw_ratio & 0xff;
-       buffer[count++] = (fftinx_bfsfcw_ratio >> 8) & 0xff;
-       /* start at COEFF_1_2048 and write through to fftinx_bfsfcw_ratio*/
-       ret = it913x_write(state, PRO_DMOD, COEFF_1_2048, buffer, count);
-
-       for (i = 0; i < 42; i += 8)
-               debug_data_snipet(0x1, "Buffer", &buffer[i]);
-
-       return ret;
-}
-
-
-
-static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret, i;
-       fe_status_t old_status = state->it913x_status;
-       *status = 0;
-
-       if (state->it913x_status == 0) {
-               ret = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
-               if (ret == 0x1) {
-                       *status |= FE_HAS_SIGNAL;
-                       for (i = 0; i < 40; i++) {
-                               ret = it913x_read_reg_u8(state, MP2IF_SYNC_LK);
-                               if (ret == 0x1)
-                                       break;
-                               msleep(25);
-                       }
-                       if (ret == 0x1)
-                               *status |= FE_HAS_CARRIER
-                                       | FE_HAS_VITERBI
-                                       | FE_HAS_SYNC;
-                       state->it913x_status = *status;
-               }
-       }
-
-       if (state->it913x_status & FE_HAS_SYNC) {
-               ret = it913x_read_reg_u8(state, TPSD_LOCK);
-               if (ret == 0x1)
-                       *status |= FE_HAS_LOCK
-                               | state->it913x_status;
-               else
-                       state->it913x_status = 0;
-               if (old_status != state->it913x_status)
-                       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, ret);
-       }
-
-       return 0;
-}
-
-/* FEC values based on fe_code_rate_t non supported values 0*/
-int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88};
-int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82};
-int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76};
-
-static int it913x_get_signal_strength(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 code_rate;
-       int ret, temp;
-       u8 lna_gain_os;
-
-       ret = it913x_read_reg_u8(state, VAR_P_INBAND);
-       if (ret < 0)
-               return ret;
-
-       /* VHF/UHF gain offset */
-       if (state->frequency < 300000000)
-               lna_gain_os = 7;
-       else
-               lna_gain_os = 14;
-
-       temp = (ret - 100) - lna_gain_os;
-
-       if (state->priority == PRIORITY_HIGH)
-               code_rate = p->code_rate_HP;
-       else
-               code_rate = p->code_rate_LP;
-
-       if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval))
-               return -EINVAL;
-
-       deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp);
-
-       /* Apply FEC offset values*/
-       switch (p->modulation) {
-       case QPSK:
-               temp -= it913x_qpsk_pval[code_rate];
-               break;
-       case QAM_16:
-               temp -= it913x_16qam_pval[code_rate];
-               break;
-       case QAM_64:
-               temp -= it913x_64qam_pval[code_rate];
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (temp < -15)
-               ret = 0;
-       else if ((-15 <= temp) && (temp < 0))
-               ret = (2 * (temp + 15)) / 3;
-       else if ((0 <= temp) && (temp < 20))
-               ret = 4 * temp + 10;
-       else if ((20 <= temp) && (temp < 35))
-               ret = (2 * (temp - 20)) / 3 + 90;
-       else if (temp >= 35)
-               ret = 100;
-
-       deb_info("Signal Strength :%d", ret);
-
-       return ret;
-}
-
-static int it913x_fe_read_signal_strength(struct dvb_frontend *fe,
-               u16 *strength)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret = 0;
-       if (state->config->read_slevel) {
-               if (state->it913x_status & FE_HAS_SIGNAL)
-                       ret = it913x_read_reg_u8(state, SIGNAL_LEVEL);
-       } else
-               ret = it913x_get_signal_strength(fe);
-
-       if (ret >= 0)
-               *strength = (u16)((u32)ret * 0xffff / 0x64);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 reg[3];
-       u32 snr_val, snr_min, snr_max;
-       u32 temp;
-
-       ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg));
-
-       snr_val = (u32)(reg[2] << 16) | (reg[1] << 8) | reg[0];
-
-       ret |= it913x_read_reg(state, 0xf78b, reg, 1);
-       if (reg[0])
-               snr_val /= reg[0];
-
-       if (state->transmission_mode == TRANSMISSION_MODE_2K)
-               snr_val *= 4;
-       else if (state->transmission_mode == TRANSMISSION_MODE_4K)
-               snr_val *= 2;
-
-       if (state->constellation == QPSK) {
-               snr_min = 0xb4711;
-               snr_max = 0x191451;
-       } else if (state->constellation == QAM_16) {
-               snr_min = 0x4f0d5;
-               snr_max = 0xc7925;
-       } else if (state->constellation == QAM_64) {
-               snr_min = 0x256d0;
-               snr_max = 0x626be;
-       } else
-               return -EINVAL;
-
-       if (snr_val < snr_min)
-               *snr = 0;
-       else if (snr_val < snr_max) {
-               temp = (snr_val - snr_min) >> 5;
-               temp *= 0xffff;
-               temp /= (snr_max - snr_min) >> 5;
-               *snr = (u16)temp;
-       } else
-               *snr = 0xffff;
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 reg[5];
-       /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */
-       it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
-       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
-       *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2];
-       return 0;
-}
-
-static int it913x_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret;
-       u8 reg[2];
-       /* Aborted Packets */
-       ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
-       state->ucblocks += (u32)(reg[1] << 8) | reg[0];
-       *ucblocks = state->ucblocks;
-       return ret;
-}
-
-static int it913x_fe_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       u8 reg[8];
-
-       it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg));
-
-       if (reg[3] < 3)
-               p->modulation = fe_con[reg[3]];
-
-       if (reg[0] < 3)
-               p->transmission_mode = fe_mode[reg[0]];
-
-       if (reg[1] < 4)
-               p->guard_interval = fe_gi[reg[1]];
-
-       if (reg[2] < 4)
-               p->hierarchy = fe_hi[reg[2]];
-
-       state->priority = reg[5];
-
-       p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE;
-       p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE;
-
-       /* Update internal state to reflect the autodetected props */
-       state->constellation = p->modulation;
-       state->transmission_mode = p->transmission_mode;
-
-       return 0;
-}
-
-static int it913x_fe_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int i;
-       u8 empty_ch, last_ch;
-
-       state->it913x_status = 0;
-
-       /* Set bw*/
-       it913x_fe_select_bw(state, p->bandwidth_hz,
-               state->adcFrequency);
-
-       /* Training Mode Off */
-       it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0);
-
-       /* Clear Empty Channel */
-       it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0);
-
-       /* Clear bits */
-       it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0);
-       /* LED on */
-       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
-       /* Select Band*/
-       if ((p->frequency >= 51000000) && (p->frequency <= 230000000))
-               i = 0;
-       else if ((p->frequency >= 350000000) && (p->frequency <= 900000000))
-                       i = 1;
-       else if ((p->frequency >= 1450000000) && (p->frequency <= 1680000000))
-                       i = 2;
-       else
-               return -EOPNOTSUPP;
-
-       it913x_write_reg(state, PRO_DMOD, FREE_BAND, i);
-
-       deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
-       switch (state->tuner_type) {
-       case IT9135_38:
-       case IT9135_51:
-       case IT9135_52:
-       case IT9135_60:
-       case IT9135_61:
-       case IT9135_62:
-               it9137_set_tuner(state,
-                       p->bandwidth_hz, p->frequency);
-               break;
-       default:
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               break;
-       }
-       /* LED off */
-       it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
-       /* Trigger ofsm */
-       it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
-       last_ch = 2;
-       for (i = 0; i < 40; ++i) {
-               empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
-               if (last_ch == 1 && empty_ch == 1)
-                       break;
-               if (last_ch == 2 && empty_ch == 2)
-                       return 0;
-               last_ch = empty_ch;
-               msleep(25);
-       }
-       for (i = 0; i < 40; ++i) {
-               if (it913x_read_reg_u8(state, D_TPSD_LOCK) == 1)
-                       break;
-               msleep(25);
-       }
-
-       state->frequency = p->frequency;
-       return 0;
-}
-
-static int it913x_fe_suspend(struct it913x_fe_state *state)
-{
-       int ret, i;
-       u8 b;
-
-       ret = it913x_write_reg(state, PRO_DMOD, SUSPEND_FLAG, 0x1);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
-
-       for (i = 0; i < 128; i++) {
-               ret = it913x_read_reg(state, SUSPEND_FLAG, &b, 1);
-               if (ret < 0)
-                       return -ENODEV;
-               if (b == 0)
-                       break;
-
-       }
-
-       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x8);
-       /* Turn LED off */
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
-
-       ret |= it913x_fe_script_loader(state, it9137_tuner_off);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-/* Power sequence */
-/* Power Up    Tuner on -> Frontend suspend off -> Tuner clk on */
-/* Power Down  Frontend suspend on -> Tuner clk off -> Tuner off */
-
-static int it913x_fe_sleep(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       return it913x_fe_suspend(state);
-}
-
-static u32 compute_div(u32 a, u32 b, u32 x)
-{
-       u32 res = 0;
-       u32 c = 0;
-       u32 i = 0;
-
-       if (a > b) {
-               c = a / b;
-               a = a - c * b;
-       }
-
-       for (i = 0; i < x; i++) {
-               if (a >= b) {
-                       res += 1;
-                       a -= b;
-               }
-               a <<= 1;
-               res <<= 1;
-       }
-
-       res = (c << x) + res;
-
-       return res;
-}
-
-static int it913x_fe_start(struct it913x_fe_state *state)
-{
-       struct it913xset *set_lna;
-       struct it913xset *set_mode;
-       int ret;
-       u8 adf = (state->config->adf & 0xf);
-       u32 adc, xtal;
-       u8 b[4];
-
-       if (state->config->chip_ver == 1)
-               ret = it913x_init_tuner(state);
-
-       info("ADF table value   :%02x", adf);
-
-       if (adf < 10) {
-               state->crystalFrequency = fe_clockTable[adf].xtal ;
-               state->table = fe_clockTable[adf].table;
-               state->adcFrequency = state->table->adcFrequency;
-
-               adc = compute_div(state->adcFrequency, 1000000ul, 19ul);
-               xtal = compute_div(state->crystalFrequency, 1000000ul, 19ul);
-
-       } else
-               return -EINVAL;
-
-       /* Set LED indicator on GPIOH3 */
-       ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1);
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
-       ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
-
-       ret |= it913x_write_reg(state, PRO_LINK, 0xf641, state->tuner_type);
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xf5ca, 0x01);
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xf715, 0x01);
-
-       b[0] = xtal & 0xff;
-       b[1] = (xtal >> 8) & 0xff;
-       b[2] = (xtal >> 16) & 0xff;
-       b[3] = (xtal >> 24);
-       ret |= it913x_write(state, PRO_DMOD, XTAL_CLK, b , 4);
-
-       b[0] = adc & 0xff;
-       b[1] = (adc >> 8) & 0xff;
-       b[2] = (adc >> 16) & 0xff;
-       ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3);
-
-       if (state->config->adc_x2)
-               ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01);
-       b[0] = 0;
-       b[1] = 0;
-       b[2] = 0;
-       ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3);
-
-       info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x",
-               state->crystalFrequency, state->adcFrequency,
-                       state->config->adc_x2);
-       deb_info("Xtal value :%04x Adc value :%04x", xtal, adc);
-
-       if (ret < 0)
-               return -ENODEV;
-
-       /* v1 or v2 tuner script */
-       if (state->config->chip_ver > 1)
-               ret = it913x_fe_script_loader(state, it9135_v2);
-       else
-               ret = it913x_fe_script_loader(state, it9135_v1);
-       if (ret < 0)
-               return ret;
-
-       /* LNA Scripts */
-       switch (state->tuner_type) {
-       case IT9135_51:
-               set_lna = it9135_51;
-               break;
-       case IT9135_52:
-               set_lna = it9135_52;
-               break;
-       case IT9135_60:
-               set_lna = it9135_60;
-               break;
-       case IT9135_61:
-               set_lna = it9135_61;
-               break;
-       case IT9135_62:
-               set_lna = it9135_62;
-               break;
-       case IT9135_38:
-       default:
-               set_lna = it9135_38;
-       }
-       info("Tuner LNA type :%02x", state->tuner_type);
-
-       ret = it913x_fe_script_loader(state, set_lna);
-       if (ret < 0)
-               return ret;
-
-       if (state->config->chip_ver == 2) {
-               ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1);
-               ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0);
-               ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0);
-               ret |= it913x_init_tuner(state);
-       }
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Always solo frontend */
-       set_mode = set_solo_fe;
-       ret |= it913x_fe_script_loader(state, set_mode);
-
-       ret |= it913x_fe_suspend(state);
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_fe_init(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       int ret = 0;
-       /* Power Up Tuner - common all versions */
-       ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1);
-
-       ret |= it913x_fe_script_loader(state, init_1);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
-
-       ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
-
-       return (ret < 0) ? -ENODEV : 0;
-}
-
-static void it913x_fe_release(struct dvb_frontend *fe)
-{
-       struct it913x_fe_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops it913x_fe_ofdm_ops;
-
-struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-               u8 i2c_addr, struct ite_config *config)
-{
-       struct it913x_fe_state *state = NULL;
-       int ret;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-       if (config == NULL)
-               goto error;
-
-       state->i2c_adap = i2c_adap;
-       state->i2c_addr = i2c_addr;
-       state->config = config;
-
-       switch (state->config->tuner_id_0) {
-       case IT9135_51:
-       case IT9135_52:
-       case IT9135_60:
-       case IT9135_61:
-       case IT9135_62:
-               state->tuner_type = state->config->tuner_id_0;
-               break;
-       default:
-       case IT9135_38:
-               state->tuner_type = IT9135_38;
-       }
-
-       ret = it913x_fe_start(state);
-       if (ret < 0)
-               goto error;
-
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &it913x_fe_ofdm_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(it913x_fe_attach);
-
-static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "it913x-fe DVB-T",
-               .frequency_min          = 51000000,
-               .frequency_max          = 1680000000,
-               .frequency_stepsize     = 62500,
-               .caps = 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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = it913x_fe_release,
-
-       .init = it913x_fe_init,
-       .sleep = it913x_fe_sleep,
-
-       .set_frontend = it913x_fe_set_frontend,
-       .get_frontend = it913x_fe_get_frontend,
-
-       .read_status = it913x_fe_read_status,
-       .read_signal_strength = it913x_fe_read_signal_strength,
-       .read_snr = it913x_fe_read_snr,
-       .read_ber = it913x_fe_read_ber,
-       .read_ucblocks = it913x_fe_read_ucblocks,
-};
-
-MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
-MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
-MODULE_VERSION("1.15");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h
deleted file mode 100644 (file)
index 07fa459..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  Driver for it913x Frontend
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef IT913X_FE_H
-#define IT913X_FE_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct ite_config {
-       u8 chip_ver;
-       u16 chip_type;
-       u32 firmware;
-       u8 firmware_ver;
-       u8 adc_x2;
-       u8 tuner_id_0;
-       u8 tuner_id_1;
-       u8 dual_mode;
-       u8 adf;
-       /* option to read SIGNAL_LEVEL */
-       u8 read_slevel;
-};
-
-#if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \
-defined(MODULE))
-extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-                       u8 i2c_addr, struct ite_config *config);
-#else
-static inline struct dvb_frontend *it913x_fe_attach(
-               struct i2c_adapter *i2c_adap,
-                       u8 i2c_addr, struct ite_config *config)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_IT913X_FE */
-#define I2C_BASE_ADDR          0x10
-#define DEV_0                  0x0
-#define DEV_1                  0x10
-#define PRO_LINK               0x0
-#define PRO_DMOD               0x1
-#define DEV_0_DMOD             (PRO_DMOD << 0x7)
-#define DEV_1_DMOD             (DEV_0_DMOD | DEV_1)
-#define CHIP2_I2C_ADDR         0x3a
-
-#define AFE_MEM0               0xfb24
-
-#define MP2_SW_RST             0xf99d
-#define MP2IF2_SW_RST          0xf9a4
-
-#define        PADODPU                 0xd827
-#define THIRDODPU              0xd828
-#define AGC_O_D                        0xd829
-
-#define EP0_TX_EN              0xdd11
-#define EP0_TX_NAK             0xdd13
-#define EP4_TX_LEN_LSB         0xdd88
-#define EP4_TX_LEN_MSB         0xdd89
-#define EP4_MAX_PKT            0xdd0c
-#define EP5_TX_LEN_LSB         0xdd8a
-#define EP5_TX_LEN_MSB         0xdd8b
-#define EP5_MAX_PKT            0xdd0d
-
-#define IO_MUX_POWER_CLK       0xd800
-#define CLK_O_EN               0xd81a
-#define I2C_CLK                        0xf103
-#define I2C_CLK_100            0x7
-#define I2C_CLK_400            0x1a
-
-#define D_TPSD_LOCK            0xf5a9
-#define MP2IF2_EN              0xf9a3
-#define MP2IF_SERIAL           0xf985
-#define TSIS_ENABLE            0xf9cd
-#define MP2IF2_HALF_PSB                0xf9a5
-#define MP2IF_STOP_EN          0xf9b5
-#define MPEG_FULL_SPEED                0xf990
-#define TOP_HOSTB_SER_MODE     0xd91c
-
-#define PID_RST                        0xf992
-#define PID_EN                 0xf993
-#define PID_INX_EN             0xf994
-#define PID_INX                        0xf995
-#define PID_LSB                        0xf996
-#define PID_MSB                        0xf997
-
-#define MP2IF_MPEG_PAR_MODE    0xf986
-#define DCA_UPPER_CHIP         0xf731
-#define DCA_LOWER_CHIP         0xf732
-#define DCA_PLATCH             0xf730
-#define DCA_FPGA_LATCH         0xf778
-#define DCA_STAND_ALONE                0xf73c
-#define DCA_ENABLE             0xf776
-
-#define DVBT_INTEN             0xf41f
-#define DVBT_ENABLE            0xf41a
-#define HOSTB_DCA_LOWER                0xd91f
-#define HOSTB_MPEG_PAR_MODE    0xd91b
-#define HOSTB_MPEG_SER_MODE    0xd91c
-#define HOSTB_MPEG_SER_DO7     0xd91d
-#define HOSTB_DCA_UPPER                0xd91e
-#define PADMISCDR2             0xd830
-#define PADMISCDR4             0xd831
-#define PADMISCDR8             0xd832
-#define PADMISCDRSR            0xd833
-#define LOCK3_OUT              0xd8fd
-
-#define GPIOH1_O               0xd8af
-#define GPIOH1_EN              0xd8b0
-#define GPIOH1_ON              0xd8b1
-#define GPIOH3_O               0xd8b3
-#define GPIOH3_EN              0xd8b4
-#define GPIOH3_ON              0xd8b5
-#define GPIOH5_O               0xd8bb
-#define GPIOH5_EN              0xd8bc
-#define GPIOH5_ON              0xd8bd
-
-#define AFE_MEM0               0xfb24
-
-#define REG_TPSD_TX_MODE       0xf900
-#define REG_TPSD_GI            0xf901
-#define REG_TPSD_HIER          0xf902
-#define REG_TPSD_CONST         0xf903
-#define REG_BW                 0xf904
-#define REG_PRIV               0xf905
-#define REG_TPSD_HP_CODE       0xf906
-#define REG_TPSD_LP_CODE       0xf907
-
-#define MP2IF_SYNC_LK          0xf999
-#define ADC_FREQ               0xf1cd
-
-#define TRIGGER_OFSM           0x0000
-/* COEFF Registers start at 0x0001 to 0x0020 */
-#define COEFF_1_2048           0x0001
-#define XTAL_CLK               0x0025
-#define BFS_FCW                        0x0029
-
-/* Error Regs */
-#define RSD_ABORT_PKT_LSB      0x0032
-#define RSD_ABORT_PKT_MSB      0x0033
-#define RSD_BIT_ERR_0_7                0x0034
-#define RSD_BIT_ERR_8_15       0x0035
-#define RSD_BIT_ERR_23_16      0x0036
-#define RSD_BIT_COUNT_LSB      0x0037
-#define RSD_BIT_COUNT_MSB      0x0038
-
-#define TPSD_LOCK              0x003c
-#define TRAINING_MODE          0x0040
-#define ADC_X_2                        0x0045
-#define TUNER_ID               0x0046
-#define EMPTY_CHANNEL_STATUS   0x0047
-#define SIGNAL_LEVEL           0x0048
-#define SIGNAL_QUALITY         0x0049
-#define EST_SIGNAL_LEVEL       0x004a
-#define FREE_BAND              0x004b
-#define SUSPEND_FLAG           0x004c
-#define VAR_P_INBAND           0x00f7
-
-/* Build in tuner types */
-#define IT9137 0x38
-#define IT9135_38 0x38
-#define IT9135_51 0x51
-#define IT9135_52 0x52
-#define IT9135_60 0x60
-#define IT9135_61 0x61
-#define IT9135_62 0x62
-
-enum {
-       CMD_DEMOD_READ = 0,
-       CMD_DEMOD_WRITE,
-       CMD_TUNER_READ,
-       CMD_TUNER_WRITE,
-       CMD_REG_EEPROM_READ,
-       CMD_REG_EEPROM_WRITE,
-       CMD_DATA_READ,
-       CMD_VAR_READ = 8,
-       CMD_VAR_WRITE,
-       CMD_PLATFORM_GET,
-       CMD_PLATFORM_SET,
-       CMD_IP_CACHE,
-       CMD_IP_ADD,
-       CMD_IP_REMOVE,
-       CMD_PID_ADD,
-       CMD_PID_REMOVE,
-       CMD_SIPSI_GET,
-       CMD_SIPSI_MPE_RESET,
-       CMD_H_PID_ADD = 0x15,
-       CMD_H_PID_REMOVE,
-       CMD_ABORT,
-       CMD_IR_GET,
-       CMD_IR_SET,
-       CMD_FW_DOWNLOAD = 0x21,
-       CMD_QUERYINFO,
-       CMD_BOOT,
-       CMD_FW_DOWNLOAD_BEGIN,
-       CMD_FW_DOWNLOAD_END,
-       CMD_RUN_CODE,
-       CMD_SCATTER_READ = 0x28,
-       CMD_SCATTER_WRITE,
-       CMD_GENERIC_READ,
-       CMD_GENERIC_WRITE
-};
-
-enum {
-       READ_LONG,
-       WRITE_LONG,
-       READ_SHORT,
-       WRITE_SHORT,
-       READ_DATA,
-       WRITE_DATA,
-       WRITE_CMD,
-};
-
-enum {
-       IT9135_AUTO = 0,
-       IT9137_FW,
-       IT9135_V1_FW,
-       IT9135_V2_FW,
-};
-
-#endif /* IT913X_FE_H */
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
deleted file mode 100644 (file)
index 3164575..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
- *
- *  Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "itd1000.h"
-#include "itd1000_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define itd_dbg(args...)  do { \
-       if (debug) { \
-               printk(KERN_DEBUG   "ITD1000: " args);\
-       } \
-} while (0)
-
-#define itd_warn(args...) do { \
-       printk(KERN_WARNING "ITD1000: " args); \
-} while (0)
-
-#define itd_info(args...) do { \
-       printk(KERN_INFO    "ITD1000: " args); \
-} while (0)
-
-/* don't write more than one byte with flexcop behind */
-static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len)
-{
-       u8 buf[1+len];
-       struct i2c_msg msg = {
-               .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1
-       };
-       buf[0] = reg;
-       memcpy(&buf[1], v, len);
-
-       /* itd_dbg("wr %02x: %02x\n", reg, v[0]); */
-
-       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "itd1000 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
-{
-       u8 val;
-       struct i2c_msg msg[2] = {
-               { .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-               { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 },
-       };
-
-       /* ugly flexcop workaround */
-       itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1);
-
-       if (i2c_transfer(state->i2c, msg, 2) != 2) {
-               itd_warn("itd1000 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return val;
-}
-
-static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
-{
-       int ret = itd1000_write_regs(state, r, &v, 1);
-       state->shadow[r] = v;
-       return ret;
-}
-
-
-static struct {
-       u32 symbol_rate;
-       u8  pgaext  : 4; /* PLLFH */
-       u8  bbgvmin : 4; /* BBGVMIN */
-} itd1000_lpf_pga[] = {
-       {        0, 0x8, 0x3 },
-       {  5200000, 0x8, 0x3 },
-       { 12200000, 0x4, 0x3 },
-       { 15400000, 0x2, 0x3 },
-       { 19800000, 0x2, 0x3 },
-       { 21500000, 0x2, 0x3 },
-       { 24500000, 0x2, 0x3 },
-       { 28400000, 0x2, 0x3 },
-       { 33400000, 0x2, 0x3 },
-       { 34400000, 0x1, 0x4 },
-       { 34400000, 0x1, 0x4 },
-       { 38400000, 0x1, 0x4 },
-       { 38400000, 0x1, 0x4 },
-       { 40400000, 0x1, 0x4 },
-       { 45400000, 0x1, 0x4 },
-};
-
-static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate)
-{
-       u8 i;
-       u8 con1    = itd1000_read_reg(state, CON1)    & 0xfd;
-       u8 pllfh   = itd1000_read_reg(state, PLLFH)   & 0x0f;
-       u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0;
-       u8 bw      = itd1000_read_reg(state, BW)      & 0xf0;
-
-       itd_dbg("symbol_rate = %d\n", symbol_rate);
-
-       /* not sure what is that ? - starting to download the table */
-       itd1000_write_reg(state, CON1, con1 | (1 << 1));
-
-       for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++)
-               if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) {
-                       itd_dbg("symrate: index: %d pgaext: %x, bbgvmin: %x\n", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin);
-                       itd1000_write_reg(state, PLLFH,   pllfh | (itd1000_lpf_pga[i].pgaext << 4));
-                       itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin));
-                       itd1000_write_reg(state, BW,      bw | (i & 0x0f));
-                       break;
-               }
-
-       itd1000_write_reg(state, CON1, con1 | (0 << 1));
-}
-
-static struct {
-       u8 vcorg;
-       u32 fmax_rg;
-} itd1000_vcorg[] = {
-       {  1,  920000 },
-       {  2,  971000 },
-       {  3, 1031000 },
-       {  4, 1091000 },
-       {  5, 1171000 },
-       {  6, 1281000 },
-       {  7, 1381000 },
-       {  8,  500000 },        /* this is intentional. */
-       {  9, 1451000 },
-       { 10, 1531000 },
-       { 11, 1631000 },
-       { 12, 1741000 },
-       { 13, 1891000 },
-       { 14, 2071000 },
-       { 15, 2250000 },
-};
-
-static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
-{
-       u8 i;
-       u8 gvbb_i2c     = itd1000_read_reg(state, GVBB_I2C) & 0xbf;
-       u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f;
-       u8 adcout;
-
-       /* reserved bit again (reset ?) */
-       itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6));
-
-       for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) {
-               if (freq_khz < itd1000_vcorg[i].fmax_rg) {
-                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4));
-                       msleep(1);
-
-                       adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f;
-
-                       itd_dbg("VCO: %dkHz: %d -> ADCOUT: %d %02x\n", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c);
-
-                       if (adcout > 13) {
-                               if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15))
-                                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4));
-                       } else if (adcout < 2) {
-                               if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9))
-                                       itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4));
-                       }
-                       break;
-               }
-       }
-}
-
-static const struct {
-       u32 freq;
-       u8 values[10]; /* RFTR, RFST1 - RFST9 */
-} itd1000_fre_values[] = {
-       { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
-       { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
-       { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
-       { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
-       { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
-       { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
-       { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
-       { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } },
-       { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } },
-       { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } }
-};
-
-
-#define FREF 16
-
-static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
-{
-       int i, j;
-       u32 plln, pllf;
-       u64 tmp;
-
-       plln = (freq_khz * 1000) / 2 / FREF;
-
-       /* Compute the factional part times 1000 */
-       tmp  = plln % 1000000;
-       plln /= 1000000;
-
-       tmp *= 1048576;
-       do_div(tmp, 1000000);
-       pllf = (u32) tmp;
-
-       state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
-       itd_dbg("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d\n", freq_khz, state->frequency, pllf, plln);
-
-       itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
-       itd1000_write_reg(state, PLLNL, plln & 0xff);
-       itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
-       itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
-       itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff);
-
-       for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) {
-               if (freq_khz <= itd1000_fre_values[i].freq) {
-                       itd_dbg("fre_values: %d\n", i);
-                       itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]);
-                       for (j = 0; j < 9; j++)
-                               itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]);
-                       break;
-               }
-       }
-
-       itd1000_set_vco(state, freq_khz);
-}
-
-static int itd1000_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct itd1000_state *state = fe->tuner_priv;
-       u8 pllcon1;
-
-       itd1000_set_lo(state, c->frequency);
-       itd1000_set_lpf_bw(state, c->symbol_rate);
-
-       pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f;
-       itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7));
-       itd1000_write_reg(state, PLLCON1, pllcon1);
-
-       return 0;
-}
-
-static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct itd1000_state *state = fe->tuner_priv;
-       *frequency = state->frequency;
-       return 0;
-}
-
-static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       return 0;
-}
-
-static u8 itd1000_init_tab[][2] = {
-       { PLLCON1,       0x65 }, /* Register does not change */
-       { PLLNH,         0x80 }, /* Bits [7:6] do not change */
-       { RESERVED_0X6D, 0x3b },
-       { VCO_CHP2_I2C,  0x12 },
-       { 0x72,          0xf9 }, /* No such regsister defined */
-       { RESERVED_0X73, 0xff },
-       { RESERVED_0X74, 0xb2 },
-       { RESERVED_0X75, 0xc7 },
-       { EXTGVBBRF,     0xf0 },
-       { DIVAGCCK,      0x80 },
-       { BBTR,          0xa0 },
-       { RESERVED_0X7E, 0x4f },
-       { 0x82,          0x88 }, /* No such regsister defined */
-       { 0x83,          0x80 }, /* No such regsister defined */
-       { 0x84,          0x80 }, /* No such regsister defined */
-       { RESERVED_0X85, 0x74 },
-       { RESERVED_0X86, 0xff },
-       { RESERVED_0X88, 0x02 },
-       { RESERVED_0X89, 0x16 },
-       { RFST0,         0x1f },
-       { RESERVED_0X94, 0x66 },
-       { RESERVED_0X95, 0x66 },
-       { RESERVED_0X96, 0x77 },
-       { RESERVED_0X97, 0x99 },
-       { RESERVED_0X98, 0xff },
-       { RESERVED_0X99, 0xfc },
-       { RESERVED_0X9A, 0xba },
-       { RESERVED_0X9B, 0xaa },
-};
-
-static u8 itd1000_reinit_tab[][2] = {
-       { VCO_CHP1_I2C, 0x8a },
-       { BW,           0x87 },
-       { GVBB_I2C,     0x03 },
-       { BBGVMIN,      0x03 },
-       { CON1,         0x2e },
-};
-
-
-static int itd1000_init(struct dvb_frontend *fe)
-{
-       struct itd1000_state *state = fe->tuner_priv;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++)
-               itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]);
-
-       for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++)
-               itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]);
-
-       return 0;
-}
-
-static int itd1000_sleep(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int itd1000_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops itd1000_tuner_ops = {
-       .info = {
-               .name           = "Integrant ITD1000",
-               .frequency_min  = 950000,
-               .frequency_max  = 2150000,
-               .frequency_step = 125,     /* kHz for QPSK frontends */
-       },
-
-       .release       = itd1000_release,
-
-       .init          = itd1000_init,
-       .sleep         = itd1000_sleep,
-
-       .set_params    = itd1000_set_parameters,
-       .get_frequency = itd1000_get_frequency,
-       .get_bandwidth = itd1000_get_bandwidth
-};
-
-
-struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
-{
-       struct itd1000_state *state = NULL;
-       u8 i = 0;
-
-       state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       state->cfg = cfg;
-       state->i2c = i2c;
-
-       i = itd1000_read_reg(state, 0);
-       if (i != 0) {
-               kfree(state);
-               return NULL;
-       }
-       itd_info("successfully identified (ID: %d)\n", i);
-
-       memset(state->shadow, 0xff, sizeof(state->shadow));
-       for (i = 0x65; i < 0x9c; i++)
-               state->shadow[i] = itd1000_read_reg(state, i);
-
-       memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = state;
-
-       return fe;
-}
-EXPORT_SYMBOL(itd1000_attach);
-
-MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
-MODULE_DESCRIPTION("Integrant ITD1000 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/itd1000.h b/drivers/media/dvb/frontends/itd1000.h
deleted file mode 100644 (file)
index 5e18df0..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
- *
- *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef ITD1000_H
-#define ITD1000_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct itd1000_config {
-       u8 i2c_address;
-};
-
-#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
-#else
-static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h
deleted file mode 100644 (file)
index 08ca851..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
- *
- *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef ITD1000_PRIV_H
-#define ITD1000_PRIV_H
-
-struct itd1000_state {
-       struct itd1000_config *cfg;
-       struct i2c_adapter    *i2c;
-
-       u32 frequency; /* contains the value resulting from the LO-setting */
-
-       /* ugly workaround for flexcop's incapable i2c-controller
-        * FIXME, if possible
-        */
-       u8 shadow[256];
-};
-
-enum itd1000_register {
-       VCO_CHP1 = 0x65,
-       VCO_CHP2,
-       PLLCON1,
-       PLLNH,
-       PLLNL,
-       PLLFH,
-       PLLFM,
-       PLLFL,
-       RESERVED_0X6D,
-       PLLLOCK,
-       VCO_CHP2_I2C,
-       VCO_CHP1_I2C,
-       BW,
-       RESERVED_0X73 = 0x73,
-       RESERVED_0X74,
-       RESERVED_0X75,
-       GVBB,
-       GVRF,
-       GVBB_I2C,
-       EXTGVBBRF,
-       DIVAGCCK,
-       BBTR,
-       RFTR,
-       BBGVMIN,
-       RESERVED_0X7E,
-       RESERVED_0X85 = 0x85,
-       RESERVED_0X86,
-       CON1,
-       RESERVED_0X88,
-       RESERVED_0X89,
-       RFST0,
-       RFST1,
-       RFST2,
-       RFST3,
-       RFST4,
-       RFST5,
-       RFST6,
-       RFST7,
-       RFST8,
-       RFST9,
-       RESERVED_0X94,
-       RESERVED_0X95,
-       RESERVED_0X96,
-       RESERVED_0X97,
-       RESERVED_0X98,
-       RESERVED_0X99,
-       RESERVED_0X9A,
-       RESERVED_0X9B,
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
deleted file mode 100644 (file)
index bc5a820..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/**
- * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
- *
- * Copyright (C) 2010 Malcolm Priestley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include "ix2505v.h"
-
-static int ix2505v_debug;
-#define dprintk(level, args...) do { \
-       if (ix2505v_debug & level) \
-               printk(KERN_DEBUG "ix2505v: " args); \
-} while (0)
-
-#define deb_info(args...)  dprintk(0x01, args)
-#define deb_i2c(args...)  dprintk(0x02, args)
-
-struct ix2505v_state {
-       struct i2c_adapter *i2c;
-       const struct ix2505v_config *config;
-       u32 frequency;
-};
-
-/**
- *  Data read format of the Sharp IX2505V B0017
- *
- *  byte1:   1   |   1   |   0   |   0   |   0   |  MA1  |  MA0  |  1
- *  byte2:  POR  |   FL  |  RD2  |  RD1  |  RD0  |   X   |   X   |  X
- *
- *  byte1 = address
- *  byte2;
- *     POR = Power on Reset (VCC H=<2.2v L=>2.2v)
- *     FL  = Phase Lock (H=lock L=unlock)
- *     RD0-2 = Reserved internal operations
- *
- * Only POR can be used to check the tuner is present
- *
- * Caution: after byte2 the I2C reverts to write mode continuing to read
- *          may corrupt tuning data.
- *
- */
-
-static int ix2505v_read_status_reg(struct ix2505v_state *state)
-{
-       u8 addr = state->config->tuner_address;
-       u8 b2[] = {0};
-       int ret;
-
-       struct i2c_msg msg[1] = {
-               { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 1);
-       deb_i2c("Read %s ", __func__);
-
-       return (ret == 1) ? (int) b2[0] : -1;
-}
-
-static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
-{
-       struct i2c_msg msg[1] = {
-               { .addr = state->config->tuner_address, .flags = 0,
-                 .buf = buf, .len = count },
-       };
-
-       int ret;
-
-       ret = i2c_transfer(state->i2c, msg, 1);
-
-       if (ret != 1) {
-               deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int ix2505v_release(struct dvb_frontend *fe)
-{
-       struct ix2505v_state *state = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-
-       return 0;
-}
-
-/**
- *  Data write format of the Sharp IX2505V B0017
- *
- *  byte1:   1   |   1   |   0   |   0   |   0   | 0(MA1)| 0(MA0)|  0
- *  byte2:   0   |  BG1  |  BG2  |   N8  |   N7  |   N6  |  N5   |  N4
- *  byte3:   N3  |   N2  |   N1  |   A5  |   A4  |   A3  |   A2  |  A1
- *  byte4:   1   | 1(C1) | 1(C0) |  PD5  |  PD4  |   TM  | 0(RTS)| 1(REF)
- *  byte5:   BA2 |   BA1 |  BA0  |  PSC  |  PD3  |PD2/TS2|DIV/TS1|PD0/TS0
- *
- *  byte1 = address
- *
- *  Write order
- *  1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
- *  2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
- *  3) byte1 -> byte2 -> byte3 -> byte4
- *  4) byte1 -> byte4 -> byte5 -> byte2
- *  5) byte1 -> byte2 -> byte3
- *  6) byte1 -> byte4 -> byte5
- *  7) byte1 -> byte2
- *  8) byte1 -> byte4
- *
- *  Recommended Setup
- *  1 -> 8 -> 6
- */
-
-static int ix2505v_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct ix2505v_state *state = fe->tuner_priv;
-       u32 frequency = c->frequency;
-       u32 b_w  = (c->symbol_rate * 27) / 32000;
-       u32 div_factor, N , A, x;
-       int ret = 0, len;
-       u8 gain, cc, ref, psc, local_osc, lpf;
-       u8 data[4] = {0};
-
-       if ((frequency < fe->ops.info.frequency_min)
-       ||  (frequency > fe->ops.info.frequency_max))
-               return -EINVAL;
-
-       if (state->config->tuner_gain)
-               gain = (state->config->tuner_gain < 4)
-                       ? state->config->tuner_gain : 0;
-       else
-               gain = 0x0;
-
-       if (state->config->tuner_chargepump)
-               cc = state->config->tuner_chargepump;
-       else
-               cc = 0x3;
-
-       ref = 8; /* REF =1 */
-       psc = 32; /* PSC = 0 */
-
-       div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
-       x = div_factor / psc;
-       N = x/100;
-       A = ((x - (N * 100)) * psc) / 100;
-
-       data[0] = ((gain & 0x3) << 5) | (N >> 3);
-       data[1] = (N << 5) | (A & 0x1f);
-       data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
-
-       deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
-
-       if (frequency <= 1065000)
-               local_osc = (6 << 5) | 2;
-       else if (frequency <= 1170000)
-               local_osc = (7 << 5) | 2;
-       else if (frequency <= 1300000)
-               local_osc = (1 << 5);
-       else if (frequency <= 1445000)
-               local_osc = (2 << 5);
-       else if (frequency <= 1607000)
-               local_osc = (3 << 5);
-       else if (frequency <= 1778000)
-               local_osc = (4 << 5);
-       else if (frequency <= 1942000)
-               local_osc = (5 << 5);
-       else            /*frequency up to 2150000*/
-               local_osc = (6 << 5);
-
-       data[3] = local_osc; /* all other bits set 0 */
-
-       if (b_w <= 10000)
-               lpf = 0xc;
-       else if (b_w <= 12000)
-               lpf = 0x2;
-       else if (b_w <= 14000)
-               lpf = 0xa;
-       else if (b_w <= 16000)
-               lpf = 0x6;
-       else if (b_w <= 18000)
-               lpf = 0xe;
-       else if (b_w <= 20000)
-               lpf = 0x1;
-       else if (b_w <= 22000)
-               lpf = 0x9;
-       else if (b_w <= 24000)
-               lpf = 0x5;
-       else if (b_w <= 26000)
-               lpf = 0xd;
-       else if (b_w <= 28000)
-               lpf = 0x3;
-               else
-               lpf = 0xb;
-
-       deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
-       deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       len = sizeof(data);
-       ret |= ix2505v_write(state, data, len);
-
-       data[2] |= 0x4; /* set TM = 1 other bits same */
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       len = 1;
-       ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
-
-       msleep(10);
-
-       data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
-       data[3] |= (lpf & 0x3) << 2;
-
-       deb_info("Data 2=[%x%x]\n", data[2], data[3]);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       len = 2;
-       ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
-
-       if (state->config->min_delay_ms)
-               msleep(state->config->min_delay_ms);
-
-       state->frequency = frequency;
-
-       return ret;
-}
-
-static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct ix2505v_state *state = fe->tuner_priv;
-
-       *frequency = state->frequency;
-
-       return 0;
-}
-
-static struct dvb_tuner_ops ix2505v_tuner_ops = {
-       .info = {
-               .name = "Sharp IX2505V (B0017)",
-               .frequency_min = 950000,
-               .frequency_max = 2175000
-       },
-       .release = ix2505v_release,
-       .set_params = ix2505v_set_params,
-       .get_frequency = ix2505v_get_frequency,
-};
-
-struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
-                                   const struct ix2505v_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct ix2505v_state *state = NULL;
-       int ret;
-
-       if (NULL == config) {
-               deb_i2c("%s: no config ", __func__);
-               goto error;
-       }
-
-       state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL);
-       if (NULL == state)
-               return NULL;
-
-       state->config = config;
-       state->i2c = i2c;
-
-       if (state->config->tuner_write_only) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = ix2505v_read_status_reg(state);
-
-               if (ret & 0x80) {
-                       deb_i2c("%s: No IX2505V found\n", __func__);
-                       goto error;
-               }
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       fe->tuner_priv = state;
-
-       memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-       deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
-               __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
-
-       return fe;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(ix2505v_attach);
-
-module_param_named(debug, ix2505v_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-MODULE_DESCRIPTION("DVB IX2505V tuner driver");
-MODULE_AUTHOR("Malcolm Priestley");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb/frontends/ix2505v.h
deleted file mode 100644 (file)
index 67e89d6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
- *
- * Copyright (C) 2010 Malcolm Priestley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef DVB_IX2505V_H
-#define DVB_IX2505V_H
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/**
- * Attach a ix2505v tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param config ix2505v_config structure
- * @return FE pointer on success, NULL on failure.
- */
-
-struct ix2505v_config {
-       u8 tuner_address;
-
-       /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
-       u8 tuner_gain;
-
-       /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
-       u8 tuner_chargepump;
-
-       /* delay after tune */
-       int min_delay_ms;
-
-       /* disables reads*/
-       u8 tuner_write_only;
-
-};
-
-#if defined(CONFIG_DVB_IX2505V) || \
-       (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
-extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
-       const struct ix2505v_config *config, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
-       const struct ix2505v_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* DVB_IX2505V_H */
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
deleted file mode 100644 (file)
index 36fcf55..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
-    driver for LSI L64781 COFDM demodulator
-
-    Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
-                      Marko Kohtala <marko.kohtala@luukku.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "dvb_frontend.h"
-#include "l64781.h"
-
-
-struct l64781_state {
-       struct i2c_adapter* i2c;
-       const struct l64781_config* config;
-       struct dvb_frontend frontend;
-
-       /* private demodulator data */
-       unsigned int first:1;
-};
-
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "l64781: " args); \
-       } while (0)
-
-static int debug;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-
-static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf [] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
-               dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
-                        __func__, reg, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static int l64781_readreg (struct l64781_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) return ret;
-
-       return b1[0];
-}
-
-static void apply_tps (struct l64781_state* state)
-{
-       l64781_writereg (state, 0x2a, 0x00);
-       l64781_writereg (state, 0x2a, 0x01);
-
-       /* This here is a little bit questionable because it enables
-          the automatic update of TPS registers. I think we'd need to
-          handle the IRQ from FE to update some other registers as
-          well, or at least implement some magic to tuning to correct
-          to the TPS received from transmission. */
-       l64781_writereg (state, 0x2a, 0x02);
-}
-
-
-static void reset_afc (struct l64781_state* state)
-{
-       /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
-          timing offset */
-       l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
-       l64781_writereg (state, 0x08, 0);    /* AFC INIT FREQ */
-       l64781_writereg (state, 0x09, 0);
-       l64781_writereg (state, 0x0a, 0);
-       l64781_writereg (state, 0x07, 0x8e);
-       l64781_writereg (state, 0x0e, 0);    /* AGC gain to zero in beginning */
-       l64781_writereg (state, 0x11, 0x80); /* stall TIM */
-       l64781_writereg (state, 0x10, 0);    /* TIM_OFFSET_LSB */
-       l64781_writereg (state, 0x12, 0);
-       l64781_writereg (state, 0x13, 0);
-       l64781_writereg (state, 0x11, 0x00);
-}
-
-static int reset_and_configure (struct l64781_state* state)
-{
-       u8 buf [] = { 0x06 };
-       struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
-       // NOTE: this is correct in writing to address 0x00
-
-       return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
-}
-
-static int apply_frontend_param(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct l64781_state* state = fe->demodulator_priv;
-       /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
-       static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
-       /* QPSK, QAM_16, QAM_64 */
-       static const u8 qam_tab [] = { 2, 4, 0, 6 };
-       static const u8 guard_tab [] = { 1, 2, 4, 8 };
-       /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
-       static const u32 ppm = 8000;
-       u32 ddfs_offset_fixed;
-/*     u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
-/*                     bw_tab[p->bandWidth]<<10)/15625; */
-       u32 init_freq;
-       u32 spi_bias;
-       u8 val0x04;
-       u8 val0x05;
-       u8 val0x06;
-       int bw;
-
-       switch (p->bandwidth_hz) {
-       case 8000000:
-               bw = 8;
-               break;
-       case 7000000:
-               bw = 7;
-               break;
-       case 6000000:
-               bw = 6;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       if (p->inversion != INVERSION_ON &&
-           p->inversion != INVERSION_OFF)
-               return -EINVAL;
-
-       if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
-           p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
-           p->code_rate_HP != FEC_7_8)
-               return -EINVAL;
-
-       if (p->hierarchy != HIERARCHY_NONE &&
-           (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
-            p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
-            p->code_rate_LP != FEC_7_8))
-               return -EINVAL;
-
-       if (p->modulation != QPSK && p->modulation != QAM_16 &&
-           p->modulation != QAM_64)
-               return -EINVAL;
-
-       if (p->transmission_mode != TRANSMISSION_MODE_2K &&
-           p->transmission_mode != TRANSMISSION_MODE_8K)
-               return -EINVAL;
-
-       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
-           p->guard_interval > GUARD_INTERVAL_1_4)
-               return -EINVAL;
-
-       if (p->hierarchy < HIERARCHY_NONE ||
-           p->hierarchy > HIERARCHY_4)
-               return -EINVAL;
-
-       ddfs_offset_fixed = 0x4000-(ppm<<16)/bw/1000000;
-
-       /* This works up to 20000 ppm, it overflows if too large ppm! */
-       init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
-                       bw & 0xFFFFFF);
-
-       /* SPI bias calculation is slightly modified to fit in 32bit */
-       /* will work for high ppm only... */
-       spi_bias = 378 * (1 << 10);
-       spi_bias *= 16;
-       spi_bias *= bw;
-       spi_bias *= qam_tab[p->modulation];
-       spi_bias /= p->code_rate_HP + 1;
-       spi_bias /= (guard_tab[p->guard_interval] + 32);
-       spi_bias *= 1000;
-       spi_bias /= 1000 + ppm/1000;
-       spi_bias *= p->code_rate_HP;
-
-       val0x04 = (p->transmission_mode << 2) | p->guard_interval;
-       val0x05 = fec_tab[p->code_rate_HP];
-
-       if (p->hierarchy != HIERARCHY_NONE)
-               val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
-
-       val0x06 = (p->hierarchy << 2) | p->modulation;
-
-       l64781_writereg (state, 0x04, val0x04);
-       l64781_writereg (state, 0x05, val0x05);
-       l64781_writereg (state, 0x06, val0x06);
-
-       reset_afc (state);
-
-       /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
-       l64781_writereg (state, 0x15,
-                        p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
-       l64781_writereg (state, 0x16, init_freq & 0xff);
-       l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
-       l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
-
-       l64781_writereg (state, 0x1b, spi_bias & 0xff);
-       l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
-       l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
-               (p->inversion == INVERSION_ON ? 0x80 : 0x00));
-
-       l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
-       l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
-
-       l64781_readreg (state, 0x00);  /*  clear interrupt registers... */
-       l64781_readreg (state, 0x01);  /*  dto. */
-
-       apply_tps (state);
-
-       return 0;
-}
-
-static int get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct l64781_state* state = fe->demodulator_priv;
-       int tmp;
-
-
-       tmp = l64781_readreg(state, 0x04);
-       switch(tmp & 3) {
-       case 0:
-               p->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               p->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               p->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               p->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-       switch((tmp >> 2) & 3) {
-       case 0:
-               p->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               p->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       default:
-               printk(KERN_WARNING "Unexpected value for transmission_mode\n");
-       }
-
-       tmp = l64781_readreg(state, 0x05);
-       switch(tmp & 7) {
-       case 0:
-               p->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_HP = FEC_7_8;
-               break;
-       default:
-               printk("Unexpected value for code_rate_HP\n");
-       }
-       switch((tmp >> 3) & 7) {
-       case 0:
-               p->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_LP = FEC_7_8;
-               break;
-       default:
-               printk("Unexpected value for code_rate_LP\n");
-       }
-
-       tmp = l64781_readreg(state, 0x06);
-       switch(tmp & 3) {
-       case 0:
-               p->modulation = QPSK;
-               break;
-       case 1:
-               p->modulation = QAM_16;
-               break;
-       case 2:
-               p->modulation = QAM_64;
-               break;
-       default:
-               printk(KERN_WARNING "Unexpected value for modulation\n");
-       }
-       switch((tmp >> 2) & 7) {
-       case 0:
-               p->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               p->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               p->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               p->hierarchy = HIERARCHY_4;
-               break;
-       default:
-               printk("Unexpected value for hierarchy\n");
-       }
-
-
-       tmp = l64781_readreg (state, 0x1d);
-       p->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
-
-       tmp = (int) (l64781_readreg (state, 0x08) |
-                    (l64781_readreg (state, 0x09) << 8) |
-                    (l64781_readreg (state, 0x0a) << 16));
-       p->frequency += tmp;
-
-       return 0;
-}
-
-static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-       int sync = l64781_readreg (state, 0x32);
-       int gain = l64781_readreg (state, 0x0e);
-
-       l64781_readreg (state, 0x00);  /*  clear interrupt registers... */
-       l64781_readreg (state, 0x01);  /*  dto. */
-
-       *status = 0;
-
-       if (gain > 5)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 0x02) /* VCXO locked, this criteria should be ok */
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 0x20)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 0x40)
-               *status |= FE_HAS_SYNC;
-
-       if (sync == 0x7f)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       /*   XXX FIXME: set up counting period (reg 0x26...0x28)
-        */
-       *ber = l64781_readreg (state, 0x39)
-           | (l64781_readreg (state, 0x3a) << 8);
-
-       return 0;
-}
-
-static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       u8 gain = l64781_readreg (state, 0x0e);
-       *signal_strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
-       *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
-
-       return 0;
-}
-
-static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       *ucblocks = l64781_readreg (state, 0x37)
-          | (l64781_readreg (state, 0x38) << 8);
-
-       return 0;
-}
-
-static int l64781_sleep(struct dvb_frontend* fe)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       /* Power down */
-       return l64781_writereg (state, 0x3e, 0x5a);
-}
-
-static int l64781_init(struct dvb_frontend* fe)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-
-       reset_and_configure (state);
-
-       /* Power up */
-       l64781_writereg (state, 0x3e, 0xa5);
-
-       /* Reset hard */
-       l64781_writereg (state, 0x2a, 0x04);
-       l64781_writereg (state, 0x2a, 0x00);
-
-       /* Set tuner specific things */
-       /* AFC_POL, set also in reset_afc */
-       l64781_writereg (state, 0x07, 0x8e);
-
-       /* Use internal ADC */
-       l64781_writereg (state, 0x0b, 0x81);
-
-       /* AGC loop gain, and polarity is positive */
-       l64781_writereg (state, 0x0c, 0x84);
-
-       /* Internal ADC outputs two's complement */
-       l64781_writereg (state, 0x0d, 0x8c);
-
-       /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
-          value of 2 with all possible bandwidths and guard
-          intervals, which is the initial value anyway. */
-       /*l64781_writereg (state, 0x19, 0x92);*/
-
-       /* Everything is two's complement, soft bit and CSI_OUT too */
-       l64781_writereg (state, 0x1e, 0x09);
-
-       /* delay a bit after first init attempt */
-       if (state->first) {
-               state->first = 0;
-               msleep(200);
-       }
-
-       return 0;
-}
-
-static int l64781_get_tune_settings(struct dvb_frontend* fe,
-                                   struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 4000;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void l64781_release(struct dvb_frontend* fe)
-{
-       struct l64781_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops l64781_ops;
-
-struct dvb_frontend* l64781_attach(const struct l64781_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct l64781_state* state = NULL;
-       int reg0x3e = -1;
-       u8 b0 [] = { 0x1a };
-       u8 b1 [] = { 0x00 };
-       struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                          { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->first = 1;
-
-       /**
-        *  the L64781 won't show up before we send the reset_and_configure()
-        *  broadcast. If nothing responds there is no L64781 on the bus...
-        */
-       if (reset_and_configure(state) < 0) {
-               dprintk("No response to reset and configure broadcast...\n");
-               goto error;
-       }
-
-       /* The chip always responds to reads */
-       if (i2c_transfer(state->i2c, msg, 2) != 2) {
-               dprintk("No response to read on I2C bus\n");
-               goto error;
-       }
-
-       /* Save current register contents for bailout */
-       reg0x3e = l64781_readreg(state, 0x3e);
-
-       /* Reading the POWER_DOWN register always returns 0 */
-       if (reg0x3e != 0) {
-               dprintk("Device doesn't look like L64781\n");
-               goto error;
-       }
-
-       /* Turn the chip off */
-       l64781_writereg (state, 0x3e, 0x5a);
-
-       /* Responds to all reads with 0 */
-       if (l64781_readreg(state, 0x1a) != 0) {
-               dprintk("Read 1 returned unexpcted value\n");
-               goto error;
-       }
-
-       /* Turn the chip on */
-       l64781_writereg (state, 0x3e, 0xa5);
-
-       /* Responds with register default value */
-       if (l64781_readreg(state, 0x1a) != 0xa1) {
-               dprintk("Read 2 returned unexpcted value\n");
-               goto error;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       if (reg0x3e >= 0)
-               l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops l64781_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "LSI L64781 DVB-T",
-       /*      .frequency_min = ???,*/
-       /*      .frequency_max = ???,*/
-               .frequency_stepsize = 166666,
-       /*      .frequency_tolerance = ???,*/
-       /*      .symbol_rate_tolerance = ???,*/
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                     FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                     FE_CAN_MUTE_TS
-       },
-
-       .release = l64781_release,
-
-       .init = l64781_init,
-       .sleep = l64781_sleep,
-
-       .set_frontend = apply_frontend_param,
-       .get_frontend = get_frontend,
-       .get_tune_settings = l64781_get_tune_settings,
-
-       .read_status = l64781_read_status,
-       .read_ber = l64781_read_ber,
-       .read_signal_strength = l64781_read_signal_strength,
-       .read_snr = l64781_read_snr,
-       .read_ucblocks = l64781_read_ucblocks,
-};
-
-MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
-MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
deleted file mode 100644 (file)
index 1305a9e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-    driver for LSI L64781 COFDM demodulator
-
-    Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
-                      Marko Kohtala <marko.kohtala@luukku.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef L64781_H
-#define L64781_H
-
-#include <linux/dvb/frontend.h>
-
-struct l64781_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE))
-extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
-                                         struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
-                                         struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_L64781
-
-#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c
deleted file mode 100644 (file)
index cc11260..0000000
+++ /dev/null
@@ -1,1468 +0,0 @@
-/*
- *    Support for LG2160 - ATSC/MH
- *
- *    Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/jiffies.h>
-#include <linux/dvb/frontend.h>
-#include "lg2160.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
-
-#define DBG_INFO 1
-#define DBG_REG  2
-
-#define lg_printk(kern, fmt, arg...)                                   \
-       printk(kern "%s: " fmt, __func__, ##arg)
-
-#define lg_info(fmt, arg...)   printk(KERN_INFO "lg2160: " fmt, ##arg)
-#define lg_warn(fmt, arg...)   lg_printk(KERN_WARNING,       fmt, ##arg)
-#define lg_err(fmt, arg...)    lg_printk(KERN_ERR,           fmt, ##arg)
-#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)                      \
-                               lg_printk(KERN_DEBUG,         fmt, ##arg)
-#define lg_reg(fmt, arg...) if (debug & DBG_REG)                       \
-                               lg_printk(KERN_DEBUG,         fmt, ##arg)
-
-#define lg_fail(ret)                                                   \
-({                                                                     \
-       int __ret;                                                      \
-       __ret = (ret < 0);                                              \
-       if (__ret)                                                      \
-               lg_err("error %d on line %d\n", ret, __LINE__);         \
-       __ret;                                                          \
-})
-
-struct lg216x_state {
-       struct i2c_adapter *i2c_adap;
-       const struct lg2160_config *cfg;
-
-       struct dvb_frontend frontend;
-
-       u32 current_frequency;
-       u8 parade_id;
-       u8 fic_ver;
-       unsigned int last_reset;
-};
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val)
-{
-       int ret;
-       u8 buf[] = { reg >> 8, reg & 0xff, val };
-       struct i2c_msg msg = {
-               .addr = state->cfg->i2c_addr, .flags = 0,
-               .buf = buf, .len = 3,
-       };
-
-       lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
-
-       ret = i2c_transfer(state->i2c_adap, &msg, 1);
-
-       if (ret != 1) {
-               lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
-                      msg.buf[0], msg.buf[1], msg.buf[2], ret);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val)
-{
-       int ret;
-       u8 reg_buf[] = { reg >> 8, reg & 0xff };
-       struct i2c_msg msg[] = {
-               { .addr = state->cfg->i2c_addr,
-                 .flags = 0, .buf = reg_buf, .len = 2 },
-               { .addr = state->cfg->i2c_addr,
-                 .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       lg_reg("reg: 0x%04x\n", reg);
-
-       ret = i2c_transfer(state->i2c_adap, msg, 2);
-
-       if (ret != 2) {
-               lg_err("error (addr %02x reg %04x error (ret == %i)\n",
-                      state->cfg->i2c_addr, reg, ret);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EREMOTEIO;
-       }
-       return 0;
-}
-
-struct lg216x_reg {
-       u16 reg;
-       u8 val;
-};
-
-static int lg216x_write_regs(struct lg216x_state *state,
-                            struct lg216x_reg *regs, int len)
-{
-       int i, ret;
-
-       lg_reg("writing %d registers...\n", len);
-
-       for (i = 0; i < len; i++) {
-               ret = lg216x_write_reg(state, regs[i].reg, regs[i].val);
-               if (lg_fail(ret))
-                       return ret;
-       }
-       return 0;
-}
-
-static int lg216x_set_reg_bit(struct lg216x_state *state,
-                             u16 reg, int bit, int onoff)
-{
-       u8 val;
-       int ret;
-
-       lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
-
-       ret = lg216x_read_reg(state, reg, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= ~(1 << bit);
-       val |= (onoff & 1) << bit;
-
-       ret = lg216x_write_reg(state, reg, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       int ret;
-
-       if (state->cfg->deny_i2c_rptr)
-               return 0;
-
-       lg_dbg("(%d)\n", enable);
-
-       ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1);
-
-       msleep(1);
-
-       return ret;
-}
-
-static int lg216x_soft_reset(struct lg216x_state *state)
-{
-       int ret;
-
-       lg_dbg("\n");
-
-       ret = lg216x_write_reg(state, 0x0002, 0x00);
-       if (lg_fail(ret))
-               goto fail;
-
-       msleep(20);
-       ret = lg216x_write_reg(state, 0x0002, 0x01);
-       if (lg_fail(ret))
-               goto fail;
-
-       state->last_reset = jiffies_to_msecs(jiffies);
-fail:
-       return ret;
-}
-
-static int lg216x_initialize(struct lg216x_state *state)
-{
-       int ret;
-
-       static struct lg216x_reg lg2160_init[] = {
-#if 0
-               { .reg = 0x0015, .val = 0xe6 },
-#else
-               { .reg = 0x0015, .val = 0xf7 },
-               { .reg = 0x001b, .val = 0x52 },
-               { .reg = 0x0208, .val = 0x00 },
-               { .reg = 0x0209, .val = 0x82 },
-               { .reg = 0x0210, .val = 0xf9 },
-               { .reg = 0x020a, .val = 0x00 },
-               { .reg = 0x020b, .val = 0x82 },
-               { .reg = 0x020d, .val = 0x28 },
-               { .reg = 0x020f, .val = 0x14 },
-#endif
-       };
-
-       static struct lg216x_reg lg2161_init[] = {
-               { .reg = 0x0000, .val = 0x41 },
-               { .reg = 0x0001, .val = 0xfb },
-               { .reg = 0x0216, .val = 0x00 },
-               { .reg = 0x0219, .val = 0x00 },
-               { .reg = 0x021b, .val = 0x55 },
-               { .reg = 0x0606, .val = 0x0a },
-       };
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_write_regs(state,
-                                       lg2160_init, ARRAY_SIZE(lg2160_init));
-               break;
-       case LG2161:
-               ret = lg216x_write_regs(state,
-                                       lg2161_init, ARRAY_SIZE(lg2161_init));
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_soft_reset(state);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_set_if(struct lg216x_state *state)
-{
-       u8 val;
-       int ret;
-
-       lg_dbg("%d KHz\n", state->cfg->if_khz);
-
-       ret = lg216x_read_reg(state, 0x0132, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xfb;
-       val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0132, val);
-       lg_fail(ret);
-
-       /* if NOT zero IF, 6 MHz is the default */
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg2160_agc_fix(struct lg216x_state *state,
-                         int if_agc_fix, int rf_agc_fix)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0100, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xf3;
-       val |= (if_agc_fix) ? 0x08 : 0x00;
-       val |= (rf_agc_fix) ? 0x04 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0100, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-#if 0
-static int lg2160_agc_freeze(struct lg216x_state *state,
-                            int if_agc_freeze, int rf_agc_freeze)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0100, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xcf;
-       val |= (if_agc_freeze) ? 0x20 : 0x00;
-       val |= (rf_agc_freeze) ? 0x10 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0100, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-#endif
-
-static int lg2160_agc_polarity(struct lg216x_state *state,
-                              int if_agc_polarity, int rf_agc_polarity)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0100, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xfc;
-       val |= (if_agc_polarity) ? 0x02 : 0x00;
-       val |= (rf_agc_polarity) ? 0x01 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0100, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state,
-                                         int polarity)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0008, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xfe;
-       val |= (polarity) ? 0x01 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0008, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg2160_spectrum_polarity(struct lg216x_state *state,
-                                   int inverted)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0132, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xfd;
-       val |= (inverted) ? 0x02 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0132, val);
-       lg_fail(ret);
-fail:
-       return lg216x_soft_reset(state);
-}
-
-static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0007, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xbf;
-       val |= (onoff) ? 0x40 : 0x00;
-
-       ret = lg216x_write_reg(state, 0x0007, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg216x_set_parade(struct lg216x_state *state, int id)
-{
-       int ret;
-
-       ret = lg216x_write_reg(state, 0x013e, id & 0x7f);
-       if (lg_fail(ret))
-               goto fail;
-
-       state->parade_id = id & 0x7f;
-fail:
-       return ret;
-}
-
-static int lg216x_set_ensemble(struct lg216x_state *state, int id)
-{
-       int ret;
-       u16 reg;
-       u8 val;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               reg = 0x0400;
-               break;
-       case LG2161:
-       default:
-               reg = 0x0500;
-               break;
-       }
-
-       ret = lg216x_read_reg(state, reg, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xfe;
-       val |= (id) ? 0x01 : 0x00;
-
-       ret = lg216x_write_reg(state, reg, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg2160_set_spi_clock(struct lg216x_state *state)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0014, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0xf3;
-       val |= (state->cfg->spi_clock << 2);
-
-       ret = lg216x_write_reg(state, 0x0014, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg2161_set_output_interface(struct lg216x_state *state)
-{
-       u8 val;
-       int ret;
-
-       ret = lg216x_read_reg(state, 0x0014, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= ~0x07;
-       val |= state->cfg->output_if; /* FIXME: needs sanity check */
-
-       ret = lg216x_write_reg(state, 0x0014, val);
-       lg_fail(ret);
-fail:
-       return ret;
-}
-
-static int lg216x_enable_fic(struct lg216x_state *state, int onoff)
-{
-       int ret;
-
-       ret = lg216x_write_reg(state, 0x0017, 0x23);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_write_reg(state, 0x0016, 0xfc);
-       if (lg_fail(ret))
-               goto fail;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_write_reg(state, 0x0016,
-                                      0xfc | ((onoff) ? 0x02 : 0x00));
-               break;
-       case LG2161:
-               ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00);
-               break;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_initialize(state);
-       if (lg_fail(ret))
-               goto fail;
-
-       if (onoff) {
-               ret = lg216x_write_reg(state, 0x0017, 0x03);
-               lg_fail(ret);
-       }
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver)
-{
-       u8 val;
-       int ret;
-
-       *ficver = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0128, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *ficver = (val >> 3) & 0x1f;
-fail:
-       return ret;
-}
-
-#if 0
-static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id)
-{
-       u8 val;
-       int ret;
-
-       *id = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0123, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *id = val & 0x7f;
-fail:
-       return ret;
-}
-#endif
-
-static int lg216x_get_nog(struct lg216x_state *state, u8 *nog)
-{
-       u8 val;
-       int ret;
-
-       *nog = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0124, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *nog = ((val >> 4) & 0x07) + 1;
-fail:
-       return ret;
-}
-
-static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog)
-{
-       u8 val;
-       int ret;
-
-       *tnog = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0125, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *tnog = val & 0x1f;
-fail:
-       return ret;
-}
-
-static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn)
-{
-       u8 val;
-       int ret;
-
-       *sgn = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0124, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *sgn = val & 0x0f;
-fail:
-       return ret;
-}
-
-static int lg216x_get_prc(struct lg216x_state *state, u8 *prc)
-{
-       u8 val;
-       int ret;
-
-       *prc = 0xff; /* invalid value */
-
-       ret = lg216x_read_reg(state, 0x0125, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *prc = ((val >> 5) & 0x07) + 1;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_get_rs_frame_mode(struct lg216x_state *state,
-                                   enum atscmh_rs_frame_mode *rs_framemode)
-{
-       u8 val;
-       int ret;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0410, &val);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x0513, &val);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       switch ((val >> 4) & 0x03) {
-#if 1
-       default:
-#endif
-       case 0x00:
-               *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY;
-               break;
-       case 0x01:
-               *rs_framemode = ATSCMH_RSFRAME_PRI_SEC;
-               break;
-#if 0
-       default:
-               *rs_framemode = ATSCMH_RSFRAME_RES;
-               break;
-#endif
-       }
-fail:
-       return ret;
-}
-
-static
-int lg216x_get_rs_frame_ensemble(struct lg216x_state *state,
-                                enum atscmh_rs_frame_ensemble *rs_frame_ens)
-{
-       u8 val;
-       int ret;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0400, &val);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x0500, &val);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= 0x01;
-       *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val;
-fail:
-       return ret;
-}
-
-static int lg216x_get_rs_code_mode(struct lg216x_state *state,
-                                  enum atscmh_rs_code_mode *rs_code_pri,
-                                  enum atscmh_rs_code_mode *rs_code_sec)
-{
-       u8 val;
-       int ret;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0410, &val);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x0513, &val);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03);
-       *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03);
-fail:
-       return ret;
-}
-
-static int lg216x_get_sccc_block_mode(struct lg216x_state *state,
-                                     enum atscmh_sccc_block_mode *sccc_block)
-{
-       u8 val;
-       int ret;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0315, &val);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x0511, &val);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       switch (val & 0x03) {
-       case 0x00:
-               *sccc_block = ATSCMH_SCCC_BLK_SEP;
-               break;
-       case 0x01:
-               *sccc_block = ATSCMH_SCCC_BLK_COMB;
-               break;
-       default:
-               *sccc_block = ATSCMH_SCCC_BLK_RES;
-               break;
-       }
-fail:
-       return ret;
-}
-
-static int lg216x_get_sccc_code_mode(struct lg216x_state *state,
-                                    enum atscmh_sccc_code_mode *mode_a,
-                                    enum atscmh_sccc_code_mode *mode_b,
-                                    enum atscmh_sccc_code_mode *mode_c,
-                                    enum atscmh_sccc_code_mode *mode_d)
-{
-       u8 val;
-       int ret;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0316, &val);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x0512, &val);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       switch ((val >> 6) & 0x03) {
-       case 0x00:
-               *mode_a = ATSCMH_SCCC_CODE_HLF;
-               break;
-       case 0x01:
-               *mode_a = ATSCMH_SCCC_CODE_QTR;
-               break;
-       default:
-               *mode_a = ATSCMH_SCCC_CODE_RES;
-               break;
-       }
-
-       switch ((val >> 4) & 0x03) {
-       case 0x00:
-               *mode_b = ATSCMH_SCCC_CODE_HLF;
-               break;
-       case 0x01:
-               *mode_b = ATSCMH_SCCC_CODE_QTR;
-               break;
-       default:
-               *mode_b = ATSCMH_SCCC_CODE_RES;
-               break;
-       }
-
-       switch ((val >> 2) & 0x03) {
-       case 0x00:
-               *mode_c = ATSCMH_SCCC_CODE_HLF;
-               break;
-       case 0x01:
-               *mode_c = ATSCMH_SCCC_CODE_QTR;
-               break;
-       default:
-               *mode_c = ATSCMH_SCCC_CODE_RES;
-               break;
-       }
-
-       switch (val & 0x03) {
-       case 0x00:
-               *mode_d = ATSCMH_SCCC_CODE_HLF;
-               break;
-       case 0x01:
-               *mode_d = ATSCMH_SCCC_CODE_QTR;
-               break;
-       default:
-               *mode_d = ATSCMH_SCCC_CODE_RES;
-               break;
-       }
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#if 0
-static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err)
-{
-       u8 fic_err;
-       int ret;
-
-       *err = 0;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg216x_read_reg(state, 0x0012, &fic_err);
-               break;
-       case LG2161:
-               ret = lg216x_read_reg(state, 0x001e, &fic_err);
-               break;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       *err = fic_err;
-fail:
-       return ret;
-}
-
-static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err)
-{
-       u8 crc_err1, crc_err2;
-       int ret;
-
-       *err = 0;
-
-       ret = lg216x_read_reg(state, 0x0411, &crc_err1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_read_reg(state, 0x0412, &crc_err2);
-       if (lg_fail(ret))
-               goto fail;
-
-       *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1);
-fail:
-       return ret;
-}
-
-static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err)
-{
-       u8 crc_err;
-       int ret;
-
-       *err = 0;
-
-       ret = lg216x_read_reg(state, 0x0612, &crc_err);
-       if (lg_fail(ret))
-               goto fail;
-
-       *err = (u16)crc_err;
-fail:
-       return ret;
-}
-
-static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err)
-{
-       int ret;
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg2160_read_crc_err_count(state, err);
-               break;
-       case LG2161:
-               ret = lg2161_read_crc_err_count(state, err);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err)
-{
-       u8 rs_err1, rs_err2;
-       int ret;
-
-       *err = 0;
-
-       ret = lg216x_read_reg(state, 0x0413, &rs_err1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_read_reg(state, 0x0414, &rs_err2);
-       if (lg_fail(ret))
-               goto fail;
-
-       *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1);
-fail:
-       return ret;
-}
-
-static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err)
-{
-       u8 rs_err1, rs_err2;
-       int ret;
-
-       *err = 0;
-
-       ret = lg216x_read_reg(state, 0x0613, &rs_err1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_read_reg(state, 0x0614, &rs_err2);
-       if (lg_fail(ret))
-               goto fail;
-
-       *err = (u16)((rs_err1 << 8) | rs_err2);
-fail:
-       return ret;
-}
-
-static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err)
-{
-       int ret;
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg2160_read_rs_err_count(state, err);
-               break;
-       case LG2161:
-               ret = lg2161_read_rs_err_count(state, err);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_get_frontend(struct dvb_frontend *fe)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       int ret;
-
-       lg_dbg("\n");
-
-       fe->dtv_property_cache.modulation = VSB_8;
-       fe->dtv_property_cache.frequency = state->current_frequency;
-       fe->dtv_property_cache.delivery_system = SYS_ATSCMH;
-
-       ret = lg216x_get_fic_version(state,
-                                    &fe->dtv_property_cache.atscmh_fic_ver);
-       if (lg_fail(ret))
-               goto fail;
-       if (state->fic_ver != fe->dtv_property_cache.atscmh_fic_ver) {
-               state->fic_ver = fe->dtv_property_cache.atscmh_fic_ver;
-
-#if 0
-               ret = lg2160_get_parade_id(state,
-                               &fe->dtv_property_cache.atscmh_parade_id);
-               if (lg_fail(ret))
-                       goto fail;
-/* #else */
-               fe->dtv_property_cache.atscmh_parade_id = state->parade_id;
-#endif
-               ret = lg216x_get_nog(state,
-                                    &fe->dtv_property_cache.atscmh_nog);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_tnog(state,
-                                     &fe->dtv_property_cache.atscmh_tnog);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_sgn(state,
-                                    &fe->dtv_property_cache.atscmh_sgn);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_prc(state,
-                                    &fe->dtv_property_cache.atscmh_prc);
-               if (lg_fail(ret))
-                       goto fail;
-
-               ret = lg216x_get_rs_frame_mode(state,
-                       (enum atscmh_rs_frame_mode *)
-                       &fe->dtv_property_cache.atscmh_rs_frame_mode);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_rs_frame_ensemble(state,
-                       (enum atscmh_rs_frame_ensemble *)
-                       &fe->dtv_property_cache.atscmh_rs_frame_ensemble);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_rs_code_mode(state,
-                       (enum atscmh_rs_code_mode *)
-                       &fe->dtv_property_cache.atscmh_rs_code_mode_pri,
-                       (enum atscmh_rs_code_mode *)
-                       &fe->dtv_property_cache.atscmh_rs_code_mode_sec);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_sccc_block_mode(state,
-                       (enum atscmh_sccc_block_mode *)
-                       &fe->dtv_property_cache.atscmh_sccc_block_mode);
-               if (lg_fail(ret))
-                       goto fail;
-               ret = lg216x_get_sccc_code_mode(state,
-                       (enum atscmh_sccc_code_mode *)
-                       &fe->dtv_property_cache.atscmh_sccc_code_mode_a,
-                       (enum atscmh_sccc_code_mode *)
-                       &fe->dtv_property_cache.atscmh_sccc_code_mode_b,
-                       (enum atscmh_sccc_code_mode *)
-                       &fe->dtv_property_cache.atscmh_sccc_code_mode_c,
-                       (enum atscmh_sccc_code_mode *)
-                       &fe->dtv_property_cache.atscmh_sccc_code_mode_d);
-               if (lg_fail(ret))
-                       goto fail;
-       }
-#if 0
-       ret = lg216x_read_fic_err_count(state,
-                               (u8 *)&fe->dtv_property_cache.atscmh_fic_err);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg216x_read_crc_err_count(state,
-                               &fe->dtv_property_cache.atscmh_crc_err);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg216x_read_rs_err_count(state,
-                               &fe->dtv_property_cache.atscmh_rs_err);
-       if (lg_fail(ret))
-               goto fail;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               if (((fe->dtv_property_cache.atscmh_rs_err >= 240) &&
-                    (fe->dtv_property_cache.atscmh_crc_err >= 240)) &&
-                   ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000))
-                       ret = lg216x_soft_reset(state);
-               break;
-       case LG2161:
-               /* no fix needed here (as far as we know) */
-               ret = 0;
-               break;
-       }
-       lg_fail(ret);
-#endif
-fail:
-       return ret;
-}
-
-static int lg216x_get_property(struct dvb_frontend *fe,
-                              struct dtv_property *tvp)
-{
-       return (DTV_ATSCMH_FIC_VER == tvp->cmd) ?
-               lg216x_get_frontend(fe) : 0;
-}
-
-
-static int lg2160_set_frontend(struct dvb_frontend *fe)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       int ret;
-
-       lg_dbg("(%d)\n", fe->dtv_property_cache.frequency);
-
-       if (fe->ops.tuner_ops.set_params) {
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-               if (lg_fail(ret))
-                       goto fail;
-               state->current_frequency = fe->dtv_property_cache.frequency;
-       }
-
-       ret = lg2160_agc_fix(state, 0, 0);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg2160_agc_polarity(state, 0, 0);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg2160_tuner_pwr_save_polarity(state, 1);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg216x_set_if(state);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion);
-       if (lg_fail(ret))
-               goto fail;
-
-       /* be tuned before this point */
-       ret = lg216x_soft_reset(state);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg2160_tuner_pwr_save(state, 0);
-       if (lg_fail(ret))
-               goto fail;
-
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg2160_set_spi_clock(state);
-               if (lg_fail(ret))
-                       goto fail;
-               break;
-       case LG2161:
-               ret = lg2161_set_output_interface(state);
-               if (lg_fail(ret))
-                       goto fail;
-               break;
-       }
-
-       ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_set_ensemble(state,
-                       fe->dtv_property_cache.atscmh_rs_frame_ensemble);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_initialize(state);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_enable_fic(state, 1);
-       lg_fail(ret);
-
-       lg216x_get_frontend(fe);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg2160_read_lock_status(struct lg216x_state *state,
-                                  int *acq_lock, int *sync_lock)
-{
-       u8 val;
-       int ret;
-
-       *acq_lock = 0;
-       *sync_lock = 0;
-
-       ret = lg216x_read_reg(state, 0x011b, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *sync_lock = (val & 0x20) ? 0 : 1;
-       *acq_lock  = (val & 0x40) ? 0 : 1;
-fail:
-       return ret;
-}
-
-#ifdef USE_LG2161_LOCK_BITS
-static int lg2161_read_lock_status(struct lg216x_state *state,
-                                  int *acq_lock, int *sync_lock)
-{
-       u8 val;
-       int ret;
-
-       *acq_lock = 0;
-       *sync_lock = 0;
-
-       ret = lg216x_read_reg(state, 0x0304, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *sync_lock = (val & 0x80) ? 0 : 1;
-
-       ret = lg216x_read_reg(state, 0x011b, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       *acq_lock  = (val & 0x40) ? 0 : 1;
-fail:
-       return ret;
-}
-#endif
-
-static int lg216x_read_lock_status(struct lg216x_state *state,
-                                  int *acq_lock, int *sync_lock)
-{
-#ifdef USE_LG2161_LOCK_BITS
-       int ret;
-       switch (state->cfg->lg_chip) {
-       case LG2160:
-               ret = lg2160_read_lock_status(state, acq_lock, sync_lock);
-               break;
-       case LG2161:
-               ret = lg2161_read_lock_status(state, acq_lock, sync_lock);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-#else
-       return lg2160_read_lock_status(state, acq_lock, sync_lock);
-#endif
-}
-
-static int lg216x_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       int ret, acq_lock, sync_lock;
-
-       *status = 0;
-
-       ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock);
-       if (lg_fail(ret))
-               goto fail;
-
-       lg_dbg("%s%s\n",
-              acq_lock  ? "SIGNALEXIST " : "",
-              sync_lock ? "SYNCLOCK"     : "");
-
-       if (acq_lock)
-               *status |= FE_HAS_SIGNAL;
-       if (sync_lock)
-               *status |= FE_HAS_SYNC;
-
-       if (*status)
-               *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
-
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       u8 snr1, snr2;
-       int ret;
-
-       *snr = 0;
-
-       ret = lg216x_read_reg(state, 0x0202, &snr1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_read_reg(state, 0x0203, &snr2);
-       if (lg_fail(ret))
-               goto fail;
-
-       if ((snr1 == 0xba) || (snr2 == 0xdf))
-               *snr = 0;
-       else
-#if 1
-       *snr =  ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4);
-#else /* BCD */
-       *snr =  (snr2 | (snr1 << 8));
-#endif
-fail:
-       return ret;
-}
-
-static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       u8 snr1, snr2;
-       int ret;
-
-       *snr = 0;
-
-       ret = lg216x_read_reg(state, 0x0302, &snr1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lg216x_read_reg(state, 0x0303, &snr2);
-       if (lg_fail(ret))
-               goto fail;
-
-       if ((snr1 == 0xba) || (snr2 == 0xfd))
-               *snr = 0;
-       else
-
-       *snr =  ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f);
-fail:
-       return ret;
-}
-
-static int lg216x_read_signal_strength(struct dvb_frontend *fe,
-                                      u16 *strength)
-{
-#if 0
-       /* borrowed from lgdt330x.c
-        *
-        * Calculate strength from SNR up to 35dB
-        * Even though the SNR can go higher than 35dB,
-        * there is some comfort factor in having a range of
-        * strong signals that can show at 100%
-        */
-       struct lg216x_state *state = fe->demodulator_priv;
-       u16 snr;
-       int ret;
-#endif
-       *strength = 0;
-#if 0
-       ret = fe->ops.read_snr(fe, &snr);
-       if (lg_fail(ret))
-               goto fail;
-       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
-       /* scale the range 0 - 35*2^24 into 0 - 65535 */
-       if (state->snr >= 8960 * 0x10000)
-               *strength = 0xffff;
-       else
-               *strength = state->snr / 8960;
-fail:
-       return ret;
-#else
-       return 0;
-#endif
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-#if 0
-       struct lg216x_state *state = fe->demodulator_priv;
-       int ret;
-
-       ret = lg216x_read_rs_err_count(state,
-                                      &fe->dtv_property_cache.atscmh_rs_err);
-       if (lg_fail(ret))
-               goto fail;
-
-       *ucblocks = fe->dtv_property_cache.atscmh_rs_err;
-fail:
-#else
-       *ucblocks = 0;
-#endif
-       return 0;
-}
-
-static int lg216x_get_tune_settings(struct dvb_frontend *fe,
-                                   struct dvb_frontend_tune_settings
-                                   *fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 500;
-       lg_dbg("\n");
-       return 0;
-}
-
-static void lg216x_release(struct dvb_frontend *fe)
-{
-       struct lg216x_state *state = fe->demodulator_priv;
-       lg_dbg("\n");
-       kfree(state);
-}
-
-static struct dvb_frontend_ops lg2160_ops = {
-       .delsys = { SYS_ATSCMH },
-       .info = {
-               .name = "LG Electronics LG2160 ATSC/MH Frontend",
-               .frequency_min      = 54000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 62500,
-       },
-       .i2c_gate_ctrl        = lg216x_i2c_gate_ctrl,
-#if 0
-       .init                 = lg216x_init,
-       .sleep                = lg216x_sleep,
-#endif
-       .get_property         = lg216x_get_property,
-
-       .set_frontend         = lg2160_set_frontend,
-       .get_frontend         = lg216x_get_frontend,
-       .get_tune_settings    = lg216x_get_tune_settings,
-       .read_status          = lg216x_read_status,
-#if 0
-       .read_ber             = lg216x_read_ber,
-#endif
-       .read_signal_strength = lg216x_read_signal_strength,
-       .read_snr             = lg2160_read_snr,
-       .read_ucblocks        = lg216x_read_ucblocks,
-       .release              = lg216x_release,
-};
-
-static struct dvb_frontend_ops lg2161_ops = {
-       .delsys = { SYS_ATSCMH },
-       .info = {
-               .name = "LG Electronics LG2161 ATSC/MH Frontend",
-               .frequency_min      = 54000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 62500,
-       },
-       .i2c_gate_ctrl        = lg216x_i2c_gate_ctrl,
-#if 0
-       .init                 = lg216x_init,
-       .sleep                = lg216x_sleep,
-#endif
-       .get_property         = lg216x_get_property,
-
-       .set_frontend         = lg2160_set_frontend,
-       .get_frontend         = lg216x_get_frontend,
-       .get_tune_settings    = lg216x_get_tune_settings,
-       .read_status          = lg216x_read_status,
-#if 0
-       .read_ber             = lg216x_read_ber,
-#endif
-       .read_signal_strength = lg216x_read_signal_strength,
-       .read_snr             = lg2161_read_snr,
-       .read_ucblocks        = lg216x_read_ucblocks,
-       .release              = lg216x_release,
-};
-
-struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
-                                  struct i2c_adapter *i2c_adap)
-{
-       struct lg216x_state *state = NULL;
-
-       lg_dbg("(%d-%04x)\n",
-              i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
-              config ? config->i2c_addr : 0);
-
-       state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL);
-       if (state == NULL)
-               goto fail;
-
-       state->cfg = config;
-       state->i2c_adap = i2c_adap;
-       state->fic_ver = 0xff;
-       state->parade_id = 0xff;
-
-       switch (config->lg_chip) {
-       default:
-               lg_warn("invalid chip requested, defaulting to LG2160");
-               /* fall-thru */
-       case LG2160:
-               memcpy(&state->frontend.ops, &lg2160_ops,
-                      sizeof(struct dvb_frontend_ops));
-               break;
-       case LG2161:
-               memcpy(&state->frontend.ops, &lg2161_ops,
-                      sizeof(struct dvb_frontend_ops));
-               break;
-       }
-
-       state->frontend.demodulator_priv = state;
-       state->current_frequency = -1;
-       /* parade 1 by default */
-       state->frontend.dtv_property_cache.atscmh_parade_id = 1;
-
-       return &state->frontend;
-fail:
-       lg_warn("unable to detect LG216x hardware\n");
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(lg2160_attach);
-
-MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.3");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/lg2160.h b/drivers/media/dvb/frontends/lg2160.h
deleted file mode 100644 (file)
index 9e2c0f4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *    Support for LG2160 - ATSC/MH
- *
- *    Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _LG2160_H_
-#define _LG2160_H_
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-enum lg_chip_type {
-       LG2160 = 0,
-       LG2161 = 1,
-};
-
-#define LG2161_1019 LG2161
-#define LG2161_1040 LG2161
-
-enum lg2160_spi_clock {
-       LG2160_SPI_3_125_MHZ = 0,
-       LG2160_SPI_6_25_MHZ = 1,
-       LG2160_SPI_12_5_MHZ = 2,
-};
-
-#if 0
-enum lg2161_oif {
-       LG2161_OIF_EBI2_SLA  = 1,
-       LG2161_OIF_SDIO_SLA  = 2,
-       LG2161_OIF_SPI_SLA   = 3,
-       LG2161_OIF_SPI_MAS   = 4,
-       LG2161_OIF_SERIAL_TS = 7,
-};
-#endif
-
-struct lg2160_config {
-       u8 i2c_addr;
-
-       /* user defined IF frequency in KHz */
-       u16 if_khz;
-
-       /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
-       int deny_i2c_rptr:1;
-
-       /* spectral inversion - 0:disabled 1:enabled */
-       int spectral_inversion:1;
-
-       unsigned int output_if;
-       enum lg2160_spi_clock spi_clock;
-       enum lg_chip_type lg_chip;
-};
-
-#if defined(CONFIG_DVB_LG2160) || (defined(CONFIG_DVB_LG2160_MODULE) && \
-                                    defined(MODULE))
-extern
-struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
-                                    struct i2c_adapter *i2c_adap);
-#else
-static inline
-struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
-                                    struct i2c_adapter *i2c_adap)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_LG2160 */
-
-#endif /* _LG2160_H_ */
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
deleted file mode 100644 (file)
index 1d2c473..0000000
+++ /dev/null
@@ -1,1222 +0,0 @@
-/*
- *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
- *
- *    Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
- *
- *    LGDT3304 support by Jarod Wilson <jarod@redhat.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <asm/div64.h>
-#include <linux/dvb/frontend.h>
-#include <linux/slab.h>
-#include "dvb_math.h"
-#include "lgdt3305.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
-
-#define DBG_INFO 1
-#define DBG_REG  2
-
-#define lg_printk(kern, fmt, arg...)                                   \
-       printk(kern "%s: " fmt, __func__, ##arg)
-
-#define lg_info(fmt, arg...)   printk(KERN_INFO "lgdt3305: " fmt, ##arg)
-#define lg_warn(fmt, arg...)   lg_printk(KERN_WARNING,       fmt, ##arg)
-#define lg_err(fmt, arg...)    lg_printk(KERN_ERR,           fmt, ##arg)
-#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)                      \
-                               lg_printk(KERN_DEBUG,         fmt, ##arg)
-#define lg_reg(fmt, arg...) if (debug & DBG_REG)                       \
-                               lg_printk(KERN_DEBUG,         fmt, ##arg)
-
-#define lg_fail(ret)                                                   \
-({                                                                     \
-       int __ret;                                                      \
-       __ret = (ret < 0);                                              \
-       if (__ret)                                                      \
-               lg_err("error %d on line %d\n", ret, __LINE__);         \
-       __ret;                                                          \
-})
-
-struct lgdt3305_state {
-       struct i2c_adapter *i2c_adap;
-       const struct lgdt3305_config *cfg;
-
-       struct dvb_frontend frontend;
-
-       fe_modulation_t current_modulation;
-       u32 current_frequency;
-       u32 snr;
-};
-
-/* ------------------------------------------------------------------------ */
-
-/* FIXME: verify & document the LGDT3304 registers */
-
-#define LGDT3305_GEN_CTRL_1                   0x0000
-#define LGDT3305_GEN_CTRL_2                   0x0001
-#define LGDT3305_GEN_CTRL_3                   0x0002
-#define LGDT3305_GEN_STATUS                   0x0003
-#define LGDT3305_GEN_CONTROL                  0x0007
-#define LGDT3305_GEN_CTRL_4                   0x000a
-#define LGDT3305_DGTL_AGC_REF_1               0x0012
-#define LGDT3305_DGTL_AGC_REF_2               0x0013
-#define LGDT3305_CR_CTR_FREQ_1                0x0106
-#define LGDT3305_CR_CTR_FREQ_2                0x0107
-#define LGDT3305_CR_CTR_FREQ_3                0x0108
-#define LGDT3305_CR_CTR_FREQ_4                0x0109
-#define LGDT3305_CR_MSE_1                     0x011b
-#define LGDT3305_CR_MSE_2                     0x011c
-#define LGDT3305_CR_LOCK_STATUS               0x011d
-#define LGDT3305_CR_CTRL_7                    0x0126
-#define LGDT3305_AGC_POWER_REF_1              0x0300
-#define LGDT3305_AGC_POWER_REF_2              0x0301
-#define LGDT3305_AGC_DELAY_PT_1               0x0302
-#define LGDT3305_AGC_DELAY_PT_2               0x0303
-#define LGDT3305_RFAGC_LOOP_FLTR_BW_1         0x0306
-#define LGDT3305_RFAGC_LOOP_FLTR_BW_2         0x0307
-#define LGDT3305_IFBW_1                       0x0308
-#define LGDT3305_IFBW_2                       0x0309
-#define LGDT3305_AGC_CTRL_1                   0x030c
-#define LGDT3305_AGC_CTRL_4                   0x0314
-#define LGDT3305_EQ_MSE_1                     0x0413
-#define LGDT3305_EQ_MSE_2                     0x0414
-#define LGDT3305_EQ_MSE_3                     0x0415
-#define LGDT3305_PT_MSE_1                     0x0417
-#define LGDT3305_PT_MSE_2                     0x0418
-#define LGDT3305_PT_MSE_3                     0x0419
-#define LGDT3305_FEC_BLOCK_CTRL               0x0504
-#define LGDT3305_FEC_LOCK_STATUS              0x050a
-#define LGDT3305_FEC_PKT_ERR_1                0x050c
-#define LGDT3305_FEC_PKT_ERR_2                0x050d
-#define LGDT3305_TP_CTRL_1                    0x050e
-#define LGDT3305_BERT_PERIOD                  0x0801
-#define LGDT3305_BERT_ERROR_COUNT_1           0x080a
-#define LGDT3305_BERT_ERROR_COUNT_2           0x080b
-#define LGDT3305_BERT_ERROR_COUNT_3           0x080c
-#define LGDT3305_BERT_ERROR_COUNT_4           0x080d
-
-static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
-{
-       int ret;
-       u8 buf[] = { reg >> 8, reg & 0xff, val };
-       struct i2c_msg msg = {
-               .addr = state->cfg->i2c_addr, .flags = 0,
-               .buf = buf, .len = 3,
-       };
-
-       lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
-
-       ret = i2c_transfer(state->i2c_adap, &msg, 1);
-
-       if (ret != 1) {
-               lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
-                      msg.buf[0], msg.buf[1], msg.buf[2], ret);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
-{
-       int ret;
-       u8 reg_buf[] = { reg >> 8, reg & 0xff };
-       struct i2c_msg msg[] = {
-               { .addr = state->cfg->i2c_addr,
-                 .flags = 0, .buf = reg_buf, .len = 2 },
-               { .addr = state->cfg->i2c_addr,
-                 .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       lg_reg("reg: 0x%04x\n", reg);
-
-       ret = i2c_transfer(state->i2c_adap, msg, 2);
-
-       if (ret != 2) {
-               lg_err("error (addr %02x reg %04x error (ret == %i)\n",
-                      state->cfg->i2c_addr, reg, ret);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EREMOTEIO;
-       }
-       return 0;
-}
-
-#define read_reg(state, reg)                                           \
-({                                                                     \
-       u8 __val;                                                       \
-       int ret = lgdt3305_read_reg(state, reg, &__val);                \
-       if (lg_fail(ret))                                               \
-               __val = 0;                                              \
-       __val;                                                          \
-})
-
-static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
-                               u16 reg, int bit, int onoff)
-{
-       u8 val;
-       int ret;
-
-       lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
-
-       ret = lgdt3305_read_reg(state, reg, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= ~(1 << bit);
-       val |= (onoff & 1) << bit;
-
-       ret = lgdt3305_write_reg(state, reg, val);
-fail:
-       return ret;
-}
-
-struct lgdt3305_reg {
-       u16 reg;
-       u8 val;
-};
-
-static int lgdt3305_write_regs(struct lgdt3305_state *state,
-                              struct lgdt3305_reg *regs, int len)
-{
-       int i, ret;
-
-       lg_reg("writing %d registers...\n", len);
-
-       for (i = 0; i < len - 1; i++) {
-               ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
-               if (lg_fail(ret))
-                       return ret;
-       }
-       return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_soft_reset(struct lgdt3305_state *state)
-{
-       int ret;
-
-       lg_dbg("\n");
-
-       ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
-       if (lg_fail(ret))
-               goto fail;
-
-       msleep(20);
-       ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
-fail:
-       return ret;
-}
-
-static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
-                                    enum lgdt3305_mpeg_mode mode)
-{
-       lg_dbg("(%d)\n", mode);
-       return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
-}
-
-static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
-                                      enum lgdt3305_tp_clock_edge edge,
-                                      enum lgdt3305_tp_valid_polarity valid)
-{
-       u8 val;
-       int ret;
-
-       lg_dbg("edge = %d, valid = %d\n", edge, valid);
-
-       ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       val &= ~0x09;
-
-       if (edge)
-               val |= 0x08;
-       if (valid)
-               val |= 0x01;
-
-       ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_soft_reset(state);
-fail:
-       return ret;
-}
-
-static int lgdt3305_set_modulation(struct lgdt3305_state *state,
-                                  struct dtv_frontend_properties *p)
-{
-       u8 opermode;
-       int ret;
-
-       lg_dbg("\n");
-
-       ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
-       if (lg_fail(ret))
-               goto fail;
-
-       opermode &= ~0x03;
-
-       switch (p->modulation) {
-       case VSB_8:
-               opermode |= 0x03;
-               break;
-       case QAM_64:
-               opermode |= 0x00;
-               break;
-       case QAM_256:
-               opermode |= 0x01;
-               break;
-       default:
-               return -EINVAL;
-       }
-       ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
-fail:
-       return ret;
-}
-
-static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
-                                        struct dtv_frontend_properties *p)
-{
-       int val;
-
-       switch (p->modulation) {
-       case VSB_8:
-               val = 0;
-               break;
-       case QAM_64:
-       case QAM_256:
-               val = 1;
-               break;
-       default:
-               return -EINVAL;
-       }
-       lg_dbg("val = %d\n", val);
-
-       return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
-                                        struct dtv_frontend_properties *p)
-{
-       u16 agc_ref;
-
-       switch (p->modulation) {
-       case VSB_8:
-               agc_ref = 0x32c4;
-               break;
-       case QAM_64:
-               agc_ref = 0x2a00;
-               break;
-       case QAM_256:
-               agc_ref = 0x2a80;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       lg_dbg("agc ref: 0x%04x\n", agc_ref);
-
-       lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
-       lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
-
-       return 0;
-}
-
-static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
-                              struct dtv_frontend_properties *p)
-{
-       u16 ifbw, rfbw, agcdelay;
-
-       switch (p->modulation) {
-       case VSB_8:
-               agcdelay = 0x04c0;
-               rfbw     = 0x8000;
-               ifbw     = 0x8000;
-               break;
-       case QAM_64:
-       case QAM_256:
-               agcdelay = 0x046b;
-               rfbw     = 0x8889;
-               /* FIXME: investigate optimal ifbw & rfbw values for the
-                *        DT3304 and re-write this switch..case block */
-               if (state->cfg->demod_chip == LGDT3304)
-                       ifbw = 0x6666;
-               else /* (state->cfg->demod_chip == LGDT3305) */
-                       ifbw = 0x8888;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (state->cfg->rf_agc_loop) {
-               lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
-
-               /* rf agc loop filter bandwidth */
-               lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
-                                  agcdelay >> 8);
-               lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
-                                  agcdelay & 0xff);
-
-               lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
-                                  rfbw >> 8);
-               lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
-                                  rfbw & 0xff);
-       } else {
-               lg_dbg("ifbw: 0x%04x\n", ifbw);
-
-               /* if agc loop filter bandwidth */
-               lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
-               lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
-       }
-
-       return 0;
-}
-
-static int lgdt3305_agc_setup(struct lgdt3305_state *state,
-                             struct dtv_frontend_properties *p)
-{
-       int lockdten, acqen;
-
-       switch (p->modulation) {
-       case VSB_8:
-               lockdten = 0;
-               acqen = 0;
-               break;
-       case QAM_64:
-       case QAM_256:
-               lockdten = 1;
-               acqen = 1;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
-
-       /* control agc function */
-       switch (state->cfg->demod_chip) {
-       case LGDT3304:
-               lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
-               lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
-               break;
-       case LGDT3305:
-               lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
-               lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return lgdt3305_rfagc_loop(state, p);
-}
-
-static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
-                                     struct dtv_frontend_properties *p)
-{
-       u16 usref = 0;
-
-       switch (p->modulation) {
-       case VSB_8:
-               if (state->cfg->usref_8vsb)
-                       usref = state->cfg->usref_8vsb;
-               break;
-       case QAM_64:
-               if (state->cfg->usref_qam64)
-                       usref = state->cfg->usref_qam64;
-               break;
-       case QAM_256:
-               if (state->cfg->usref_qam256)
-                       usref = state->cfg->usref_qam256;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (usref) {
-               lg_dbg("set manual mode: 0x%04x\n", usref);
-
-               lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
-
-               lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
-                                  0xff & (usref >> 8));
-               lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
-                                  0xff & (usref >> 0));
-       }
-       return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
-                                      struct dtv_frontend_properties *p,
-                                      int inversion)
-{
-       int ret;
-
-       lg_dbg("(%d)\n", inversion);
-
-       switch (p->modulation) {
-       case VSB_8:
-               ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
-                                        inversion ? 0xf9 : 0x79);
-               break;
-       case QAM_64:
-       case QAM_256:
-               ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
-                                        inversion ? 0xfd : 0xff);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       return ret;
-}
-
-static int lgdt3305_set_if(struct lgdt3305_state *state,
-                          struct dtv_frontend_properties *p)
-{
-       u16 if_freq_khz;
-       u8 nco1, nco2, nco3, nco4;
-       u64 nco;
-
-       switch (p->modulation) {
-       case VSB_8:
-               if_freq_khz = state->cfg->vsb_if_khz;
-               break;
-       case QAM_64:
-       case QAM_256:
-               if_freq_khz = state->cfg->qam_if_khz;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       nco = if_freq_khz / 10;
-
-       switch (p->modulation) {
-       case VSB_8:
-               nco <<= 24;
-               do_div(nco, 625);
-               break;
-       case QAM_64:
-       case QAM_256:
-               nco <<= 28;
-               do_div(nco, 625);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       nco1 = (nco >> 24) & 0x3f;
-       nco1 |= 0x40;
-       nco2 = (nco >> 16) & 0xff;
-       nco3 = (nco >> 8) & 0xff;
-       nco4 = nco & 0xff;
-
-       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
-       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
-       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
-       lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
-
-       lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
-              if_freq_khz, nco1, nco2, nco3, nco4);
-
-       return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-
-       if (state->cfg->deny_i2c_rptr)
-               return 0;
-
-       lg_dbg("(%d)\n", enable);
-
-       return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
-                                   enable ? 0 : 1);
-}
-
-static int lgdt3305_sleep(struct dvb_frontend *fe)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       u8 gen_ctrl_3, gen_ctrl_4;
-
-       lg_dbg("\n");
-
-       gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
-       gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
-
-       /* hold in software reset while sleeping */
-       gen_ctrl_3 &= ~0x01;
-       /* tristate the IF-AGC pin */
-       gen_ctrl_3 |=  0x02;
-       /* tristate the RF-AGC pin */
-       gen_ctrl_3 |=  0x04;
-
-       /* disable vsb/qam module */
-       gen_ctrl_4 &= ~0x01;
-       /* disable adc module */
-       gen_ctrl_4 &= ~0x02;
-
-       lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
-       lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
-
-       return 0;
-}
-
-static int lgdt3305_init(struct dvb_frontend *fe)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       int ret;
-
-       static struct lgdt3305_reg lgdt3304_init_data[] = {
-               { .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
-               { .reg = 0x000d,                        .val = 0x02, },
-               { .reg = 0x000e,                        .val = 0x02, },
-               { .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
-               { .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
-               { .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTRL_7,            .val = 0xf9, },
-               { .reg = 0x0112,                        .val = 0x17, },
-               { .reg = 0x0113,                        .val = 0x15, },
-               { .reg = 0x0114,                        .val = 0x18, },
-               { .reg = 0x0115,                        .val = 0xff, },
-               { .reg = 0x0116,                        .val = 0x3c, },
-               { .reg = 0x0214,                        .val = 0x67, },
-               { .reg = 0x0424,                        .val = 0x8d, },
-               { .reg = 0x0427,                        .val = 0x12, },
-               { .reg = 0x0428,                        .val = 0x4f, },
-               { .reg = LGDT3305_IFBW_1,               .val = 0x80, },
-               { .reg = LGDT3305_IFBW_2,               .val = 0x00, },
-               { .reg = 0x030a,                        .val = 0x08, },
-               { .reg = 0x030b,                        .val = 0x9b, },
-               { .reg = 0x030d,                        .val = 0x00, },
-               { .reg = 0x030e,                        .val = 0x1c, },
-               { .reg = 0x0314,                        .val = 0xe1, },
-               { .reg = 0x000d,                        .val = 0x82, },
-               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
-               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x5b, },
-       };
-
-       static struct lgdt3305_reg lgdt3305_init_data[] = {
-               { .reg = LGDT3305_GEN_CTRL_1,           .val = 0x03, },
-               { .reg = LGDT3305_GEN_CTRL_2,           .val = 0xb0, },
-               { .reg = LGDT3305_GEN_CTRL_3,           .val = 0x01, },
-               { .reg = LGDT3305_GEN_CONTROL,          .val = 0x6f, },
-               { .reg = LGDT3305_GEN_CTRL_4,           .val = 0x03, },
-               { .reg = LGDT3305_DGTL_AGC_REF_1,       .val = 0x32, },
-               { .reg = LGDT3305_DGTL_AGC_REF_2,       .val = 0xc4, },
-               { .reg = LGDT3305_CR_CTR_FREQ_1,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_2,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_3,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTR_FREQ_4,        .val = 0x00, },
-               { .reg = LGDT3305_CR_CTRL_7,            .val = 0x79, },
-               { .reg = LGDT3305_AGC_POWER_REF_1,      .val = 0x32, },
-               { .reg = LGDT3305_AGC_POWER_REF_2,      .val = 0xc4, },
-               { .reg = LGDT3305_AGC_DELAY_PT_1,       .val = 0x0d, },
-               { .reg = LGDT3305_AGC_DELAY_PT_2,       .val = 0x30, },
-               { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, },
-               { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, },
-               { .reg = LGDT3305_IFBW_1,               .val = 0x80, },
-               { .reg = LGDT3305_IFBW_2,               .val = 0x00, },
-               { .reg = LGDT3305_AGC_CTRL_1,           .val = 0x30, },
-               { .reg = LGDT3305_AGC_CTRL_4,           .val = 0x61, },
-               { .reg = LGDT3305_FEC_BLOCK_CTRL,       .val = 0xff, },
-               { .reg = LGDT3305_TP_CTRL_1,            .val = 0x1b, },
-       };
-
-       lg_dbg("\n");
-
-       switch (state->cfg->demod_chip) {
-       case LGDT3304:
-               ret = lgdt3305_write_regs(state, lgdt3304_init_data,
-                                         ARRAY_SIZE(lgdt3304_init_data));
-               break;
-       case LGDT3305:
-               ret = lgdt3305_write_regs(state, lgdt3305_init_data,
-                                         ARRAY_SIZE(lgdt3305_init_data));
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_soft_reset(state);
-fail:
-       return ret;
-}
-
-static int lgdt3304_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       int ret;
-
-       lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
-
-       if (fe->ops.tuner_ops.set_params) {
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-               if (lg_fail(ret))
-                       goto fail;
-               state->current_frequency = p->frequency;
-       }
-
-       ret = lgdt3305_set_modulation(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_passband_digital_agc(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_agc_setup(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
-       switch (p->modulation) {
-       case VSB_8:
-               lgdt3305_write_reg(state, 0x030d, 0x00);
-               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
-               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
-               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
-               lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
-               break;
-       case QAM_64:
-       case QAM_256:
-               lgdt3305_write_reg(state, 0x030d, 0x14);
-               ret = lgdt3305_set_if(state, p);
-               if (lg_fail(ret))
-                       goto fail;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-
-       ret = lgdt3305_spectral_inversion(state, p,
-                                         state->cfg->spectral_inversion
-                                         ? 1 : 0);
-       if (lg_fail(ret))
-               goto fail;
-
-       state->current_modulation = p->modulation;
-
-       ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
-       if (lg_fail(ret))
-               goto fail;
-
-       /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
-       ret = lgdt3305_mpeg_mode_polarity(state,
-                                         state->cfg->tpclk_edge,
-                                         state->cfg->tpvalid_polarity);
-fail:
-       return ret;
-}
-
-static int lgdt3305_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       int ret;
-
-       lg_dbg("(%d, %d)\n", p->frequency, p->modulation);
-
-       if (fe->ops.tuner_ops.set_params) {
-               ret = fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-               if (lg_fail(ret))
-                       goto fail;
-               state->current_frequency = p->frequency;
-       }
-
-       ret = lgdt3305_set_modulation(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_passband_digital_agc(state, p);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lgdt3305_set_agc_power_ref(state, p);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lgdt3305_agc_setup(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       /* low if */
-       ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_set_if(state, p);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lgdt3305_spectral_inversion(state, p,
-                                         state->cfg->spectral_inversion
-                                         ? 1 : 0);
-       if (lg_fail(ret))
-               goto fail;
-
-       ret = lgdt3305_set_filter_extension(state, p);
-       if (lg_fail(ret))
-               goto fail;
-
-       state->current_modulation = p->modulation;
-
-       ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
-       if (lg_fail(ret))
-               goto fail;
-
-       /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
-       ret = lgdt3305_mpeg_mode_polarity(state,
-                                         state->cfg->tpclk_edge,
-                                         state->cfg->tpvalid_polarity);
-fail:
-       return ret;
-}
-
-static int lgdt3305_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgdt3305_state *state = fe->demodulator_priv;
-
-       lg_dbg("\n");
-
-       p->modulation = state->current_modulation;
-       p->frequency = state->current_frequency;
-       return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
-                                       int *locked)
-{
-       u8 val;
-       int ret;
-       char *cr_lock_state = "";
-
-       *locked = 0;
-
-       ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       switch (state->current_modulation) {
-       case QAM_256:
-       case QAM_64:
-               if (val & (1 << 1))
-                       *locked = 1;
-
-               switch (val & 0x07) {
-               case 0:
-                       cr_lock_state = "QAM UNLOCK";
-                       break;
-               case 4:
-                       cr_lock_state = "QAM 1stLock";
-                       break;
-               case 6:
-                       cr_lock_state = "QAM 2ndLock";
-                       break;
-               case 7:
-                       cr_lock_state = "QAM FinalLock";
-                       break;
-               default:
-                       cr_lock_state = "CLOCKQAM-INVALID!";
-                       break;
-               }
-               break;
-       case VSB_8:
-               if (val & (1 << 7)) {
-                       *locked = 1;
-                       cr_lock_state = "CLOCKVSB";
-               }
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       lg_dbg("(%d) %s\n", *locked, cr_lock_state);
-fail:
-       return ret;
-}
-
-static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
-                                        int *locked)
-{
-       u8 val;
-       int ret, mpeg_lock, fec_lock, viterbi_lock;
-
-       *locked = 0;
-
-       switch (state->current_modulation) {
-       case QAM_256:
-       case QAM_64:
-               ret = lgdt3305_read_reg(state,
-                                       LGDT3305_FEC_LOCK_STATUS, &val);
-               if (lg_fail(ret))
-                       goto fail;
-
-               mpeg_lock    = (val & (1 << 0)) ? 1 : 0;
-               fec_lock     = (val & (1 << 2)) ? 1 : 0;
-               viterbi_lock = (val & (1 << 3)) ? 1 : 0;
-
-               *locked = mpeg_lock && fec_lock && viterbi_lock;
-
-               lg_dbg("(%d) %s%s%s\n", *locked,
-                      mpeg_lock    ? "mpeg lock  "  : "",
-                      fec_lock     ? "fec lock  "   : "",
-                      viterbi_lock ? "viterbi lock" : "");
-               break;
-       case VSB_8:
-       default:
-               ret = -EINVAL;
-       }
-fail:
-       return ret;
-}
-
-static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       u8 val;
-       int ret, signal, inlock, nofecerr, snrgood,
-               cr_lock, fec_lock, sync_lock;
-
-       *status = 0;
-
-       ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
-       if (lg_fail(ret))
-               goto fail;
-
-       signal    = (val & (1 << 4)) ? 1 : 0;
-       inlock    = (val & (1 << 3)) ? 0 : 1;
-       sync_lock = (val & (1 << 2)) ? 1 : 0;
-       nofecerr  = (val & (1 << 1)) ? 1 : 0;
-       snrgood   = (val & (1 << 0)) ? 1 : 0;
-
-       lg_dbg("%s%s%s%s%s\n",
-              signal    ? "SIGNALEXIST " : "",
-              inlock    ? "INLOCK "      : "",
-              sync_lock ? "SYNCLOCK "    : "",
-              nofecerr  ? "NOFECERR "    : "",
-              snrgood   ? "SNRGOOD "     : "");
-
-       ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
-       if (lg_fail(ret))
-               goto fail;
-
-       if (signal)
-               *status |= FE_HAS_SIGNAL;
-       if (cr_lock)
-               *status |= FE_HAS_CARRIER;
-       if (nofecerr)
-               *status |= FE_HAS_VITERBI;
-       if (sync_lock)
-               *status |= FE_HAS_SYNC;
-
-       switch (state->current_modulation) {
-       case QAM_256:
-       case QAM_64:
-               /* signal bit is unreliable on the DT3304 in QAM mode */
-               if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock))
-                       *status |= FE_HAS_SIGNAL;
-
-               ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
-               if (lg_fail(ret))
-                       goto fail;
-
-               if (fec_lock)
-                       *status |= FE_HAS_LOCK;
-               break;
-       case VSB_8:
-               if (inlock)
-                       *status |= FE_HAS_LOCK;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-/* borrowed from lgdt330x.c */
-static u32 calculate_snr(u32 mse, u32 c)
-{
-       if (mse == 0) /* no signal */
-               return 0;
-
-       mse = intlog10(mse);
-       if (mse > c) {
-               /* Negative SNR, which is possible, but realisticly the
-               demod will lose lock before the signal gets this bad.  The
-               API only allows for unsigned values, so just return 0 */
-               return 0;
-       }
-       return 10*(c - mse);
-}
-
-static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       u32 noise;      /* noise value */
-       u32 c;          /* per-modulation SNR calculation constant */
-
-       switch (state->current_modulation) {
-       case VSB_8:
-#ifdef USE_PTMSE
-               /* Use Phase Tracker Mean-Square Error Register */
-               /* SNR for ranges from -13.11 to +44.08 */
-               noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
-                       (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
-                       (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
-               c = 73957994; /* log10(25*32^2)*2^24 */
-#else
-               /* Use Equalizer Mean-Square Error Register */
-               /* SNR for ranges from -16.12 to +44.08 */
-               noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
-                       (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
-                       (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
-               c = 73957994; /* log10(25*32^2)*2^24 */
-#endif
-               break;
-       case QAM_64:
-       case QAM_256:
-               noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
-                       (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
-
-               c = (state->current_modulation == QAM_64) ?
-                       97939837 : 98026066;
-               /* log10(688128)*2^24 and log10(696320)*2^24 */
-               break;
-       default:
-               return -EINVAL;
-       }
-       state->snr = calculate_snr(noise, c);
-       /* report SNR in dB * 10 */
-       *snr = (state->snr / ((1 << 24) / 10));
-       lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
-              state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
-
-       return 0;
-}
-
-static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
-                                        u16 *strength)
-{
-       /* borrowed from lgdt330x.c
-        *
-        * Calculate strength from SNR up to 35dB
-        * Even though the SNR can go higher than 35dB,
-        * there is some comfort factor in having a range of
-        * strong signals that can show at 100%
-        */
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       u16 snr;
-       int ret;
-
-       *strength = 0;
-
-       ret = fe->ops.read_snr(fe, &snr);
-       if (lg_fail(ret))
-               goto fail;
-       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
-       /* scale the range 0 - 35*2^24 into 0 - 65535 */
-       if (state->snr >= 8960 * 0x10000)
-               *strength = 0xffff;
-       else
-               *strength = state->snr / 8960;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       *ber = 0;
-       return 0;
-}
-
-static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-
-       *ucblocks =
-               (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
-               (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
-
-       return 0;
-}
-
-static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
-                                     struct dvb_frontend_tune_settings
-                                       *fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 500;
-       lg_dbg("\n");
-       return 0;
-}
-
-static void lgdt3305_release(struct dvb_frontend *fe)
-{
-       struct lgdt3305_state *state = fe->demodulator_priv;
-       lg_dbg("\n");
-       kfree(state);
-}
-
-static struct dvb_frontend_ops lgdt3304_ops;
-static struct dvb_frontend_ops lgdt3305_ops;
-
-struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
-                                    struct i2c_adapter *i2c_adap)
-{
-       struct lgdt3305_state *state = NULL;
-       int ret;
-       u8 val;
-
-       lg_dbg("(%d-%04x)\n",
-              i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
-              config ? config->i2c_addr : 0);
-
-       state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
-       if (state == NULL)
-               goto fail;
-
-       state->cfg = config;
-       state->i2c_adap = i2c_adap;
-
-       switch (config->demod_chip) {
-       case LGDT3304:
-               memcpy(&state->frontend.ops, &lgdt3304_ops,
-                      sizeof(struct dvb_frontend_ops));
-               break;
-       case LGDT3305:
-               memcpy(&state->frontend.ops, &lgdt3305_ops,
-                      sizeof(struct dvb_frontend_ops));
-               break;
-       default:
-               goto fail;
-       }
-       state->frontend.demodulator_priv = state;
-
-       /* verify that we're talking to a lg dt3304/5 */
-       ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
-       if ((lg_fail(ret)) | (val == 0))
-               goto fail;
-       ret = lgdt3305_write_reg(state, 0x0808, 0x80);
-       if (lg_fail(ret))
-               goto fail;
-       ret = lgdt3305_read_reg(state, 0x0808, &val);
-       if ((lg_fail(ret)) | (val != 0x80))
-               goto fail;
-       ret = lgdt3305_write_reg(state, 0x0808, 0x00);
-       if (lg_fail(ret))
-               goto fail;
-
-       state->current_frequency = -1;
-       state->current_modulation = -1;
-
-       return &state->frontend;
-fail:
-       lg_warn("unable to detect %s hardware\n",
-               config->demod_chip ? "LGDT3304" : "LGDT3305");
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(lgdt3305_attach);
-
-static struct dvb_frontend_ops lgdt3304_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name = "LG Electronics LGDT3304 VSB/QAM Frontend",
-               .frequency_min      = 54000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 62500,
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-       .i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
-       .init                 = lgdt3305_init,
-       .set_frontend         = lgdt3304_set_parameters,
-       .get_frontend         = lgdt3305_get_frontend,
-       .get_tune_settings    = lgdt3305_get_tune_settings,
-       .read_status          = lgdt3305_read_status,
-       .read_ber             = lgdt3305_read_ber,
-       .read_signal_strength = lgdt3305_read_signal_strength,
-       .read_snr             = lgdt3305_read_snr,
-       .read_ucblocks        = lgdt3305_read_ucblocks,
-       .release              = lgdt3305_release,
-};
-
-static struct dvb_frontend_ops lgdt3305_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
-               .frequency_min      = 54000000,
-               .frequency_max      = 858000000,
-               .frequency_stepsize = 62500,
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-       .i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
-       .init                 = lgdt3305_init,
-       .sleep                = lgdt3305_sleep,
-       .set_frontend         = lgdt3305_set_parameters,
-       .get_frontend         = lgdt3305_get_frontend,
-       .get_tune_settings    = lgdt3305_get_tune_settings,
-       .read_status          = lgdt3305_read_status,
-       .read_ber             = lgdt3305_read_ber,
-       .read_signal_strength = lgdt3305_read_signal_strength,
-       .read_snr             = lgdt3305_read_snr,
-       .read_ucblocks        = lgdt3305_read_ucblocks,
-       .release              = lgdt3305_release,
-};
-
-MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.2");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
deleted file mode 100644 (file)
index 02172ec..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *    Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
- *
- *    Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _LGDT3305_H_
-#define _LGDT3305_H_
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-
-enum lgdt3305_mpeg_mode {
-       LGDT3305_MPEG_PARALLEL = 0,
-       LGDT3305_MPEG_SERIAL = 1,
-};
-
-enum lgdt3305_tp_clock_edge {
-       LGDT3305_TPCLK_RISING_EDGE = 0,
-       LGDT3305_TPCLK_FALLING_EDGE = 1,
-};
-
-enum lgdt3305_tp_valid_polarity {
-       LGDT3305_TP_VALID_LOW = 0,
-       LGDT3305_TP_VALID_HIGH = 1,
-};
-
-enum lgdt_demod_chip_type {
-       LGDT3305 = 0,
-       LGDT3304 = 1,
-};
-
-struct lgdt3305_config {
-       u8 i2c_addr;
-
-       /* user defined IF frequency in KHz */
-       u16 qam_if_khz;
-       u16 vsb_if_khz;
-
-       /* AGC Power reference - defaults are used if left unset */
-       u16 usref_8vsb;   /* default: 0x32c4 */
-       u16 usref_qam64;  /* default: 0x5400 */
-       u16 usref_qam256; /* default: 0x2a80 */
-
-       /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
-       unsigned int deny_i2c_rptr:1;
-
-       /* spectral inversion - 0:disabled 1:enabled */
-       unsigned int spectral_inversion:1;
-
-       /* use RF AGC loop - 0:disabled 1:enabled */
-       unsigned int rf_agc_loop:1;
-
-       enum lgdt3305_mpeg_mode mpeg_mode;
-       enum lgdt3305_tp_clock_edge tpclk_edge;
-       enum lgdt3305_tp_valid_polarity tpvalid_polarity;
-       enum lgdt_demod_chip_type demod_chip;
-};
-
-#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
-                                    defined(MODULE))
-extern
-struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
-                                    struct i2c_adapter *i2c_adap);
-#else
-static inline
-struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
-                                    struct i2c_adapter *i2c_adap)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_LGDT3305 */
-
-#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
deleted file mode 100644 (file)
index e046622..0000000
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- *    Support for LGDT3302 and LGDT3303 - VSB/QAM
- *
- *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- *                      NOTES ABOUT THIS DRIVER
- *
- * This Linux driver supports:
- *   DViCO FusionHDTV 3 Gold-Q
- *   DViCO FusionHDTV 3 Gold-T
- *   DViCO FusionHDTV 5 Gold
- *   DViCO FusionHDTV 5 Lite
- *   DViCO FusionHDTV 5 USB Gold
- *   Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
- *   pcHDTV HD5500
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "lgdt330x_priv.h"
-#include "lgdt330x.h"
-
-/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
-/* #define USE_EQMSE */
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
-#define dprintk(args...) \
-do { \
-if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
-} while (0)
-
-struct lgdt330x_state
-{
-       struct i2c_adapter* i2c;
-
-       /* Configuration settings */
-       const struct lgdt330x_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* Demodulator private data */
-       fe_modulation_t current_modulation;
-       u32 snr; /* Result of last SNR calculation */
-
-       /* Tuner private data */
-       u32 current_frequency;
-};
-
-static int i2c_write_demod_bytes (struct lgdt330x_state* state,
-                                 u8 *buf, /* data bytes to send */
-                                 int len  /* number of bytes to send */ )
-{
-       struct i2c_msg msg =
-               { .addr = state->config->demod_address,
-                 .flags = 0,
-                 .buf = buf,
-                 .len = 2 };
-       int i;
-       int err;
-
-       for (i=0; i<len-1; i+=2){
-               if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-                       printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err);
-                       if (err < 0)
-                               return err;
-                       else
-                               return -EREMOTEIO;
-               }
-               msg.buf += 2;
-       }
-       return 0;
-}
-
-/*
- * This routine writes the register (reg) to the demod bus
- * then reads the data returned for (len) bytes.
- */
-
-static int i2c_read_demod_bytes(struct lgdt330x_state *state,
-                               enum I2C_REG reg, u8 *buf, int len)
-{
-       u8 wr [] = { reg };
-       struct i2c_msg msg [] = {
-               { .addr = state->config->demod_address,
-                 .flags = 0, .buf = wr,  .len = 1 },
-               { .addr = state->config->demod_address,
-                 .flags = I2C_M_RD, .buf = buf, .len = len },
-       };
-       int ret;
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2) {
-               printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret);
-               if (ret >= 0)
-                       ret = -EIO;
-       } else {
-               ret = 0;
-       }
-       return ret;
-}
-
-/* Software reset */
-static int lgdt3302_SwReset(struct lgdt330x_state* state)
-{
-       u8 ret;
-       u8 reset[] = {
-               IRQ_MASK,
-               0x00 /* bit 6 is active low software reset
-                     * bits 5-0 are 1 to mask interrupts */
-       };
-
-       ret = i2c_write_demod_bytes(state,
-                                   reset, sizeof(reset));
-       if (ret == 0) {
-
-               /* force reset high (inactive) and unmask interrupts */
-               reset[1] = 0x7f;
-               ret = i2c_write_demod_bytes(state,
-                                           reset, sizeof(reset));
-       }
-       return ret;
-}
-
-static int lgdt3303_SwReset(struct lgdt330x_state* state)
-{
-       u8 ret;
-       u8 reset[] = {
-               0x02,
-               0x00 /* bit 0 is active low software reset */
-       };
-
-       ret = i2c_write_demod_bytes(state,
-                                   reset, sizeof(reset));
-       if (ret == 0) {
-
-               /* force reset high (inactive) */
-               reset[1] = 0x01;
-               ret = i2c_write_demod_bytes(state,
-                                           reset, sizeof(reset));
-       }
-       return ret;
-}
-
-static int lgdt330x_SwReset(struct lgdt330x_state* state)
-{
-       switch (state->config->demod_chip) {
-       case LGDT3302:
-               return lgdt3302_SwReset(state);
-       case LGDT3303:
-               return lgdt3303_SwReset(state);
-       default:
-               return -ENODEV;
-       }
-}
-
-static int lgdt330x_init(struct dvb_frontend* fe)
-{
-       /* Hardware reset is done using gpio[0] of cx23880x chip.
-        * I'd like to do it here, but don't know how to find chip address.
-        * cx88-cards.c arranges for the reset bit to be inactive (high).
-        * Maybe there needs to be a callable function in cx88-core or
-        * the caller of this function needs to do it. */
-
-       /*
-        * Array of byte pairs <address, value>
-        * to initialize each different chip
-        */
-       static u8 lgdt3302_init_data[] = {
-               /* Use 50MHz parameter values from spec sheet since xtal is 50 */
-               /* Change the value of NCOCTFV[25:0] of carrier
-                  recovery center frequency register */
-               VSB_CARRIER_FREQ0, 0x00,
-               VSB_CARRIER_FREQ1, 0x87,
-               VSB_CARRIER_FREQ2, 0x8e,
-               VSB_CARRIER_FREQ3, 0x01,
-               /* Change the TPCLK pin polarity
-                  data is valid on falling clock */
-               DEMUX_CONTROL, 0xfb,
-               /* Change the value of IFBW[11:0] of
-                  AGC IF/RF loop filter bandwidth register */
-               AGC_RF_BANDWIDTH0, 0x40,
-               AGC_RF_BANDWIDTH1, 0x93,
-               AGC_RF_BANDWIDTH2, 0x00,
-               /* Change the value of bit 6, 'nINAGCBY' and
-                  'NSSEL[1:0] of ACG function control register 2 */
-               AGC_FUNC_CTRL2, 0xc6,
-               /* Change the value of bit 6 'RFFIX'
-                  of AGC function control register 3 */
-               AGC_FUNC_CTRL3, 0x40,
-               /* Set the value of 'INLVTHD' register 0x2a/0x2c
-                  to 0x7fe */
-               AGC_DELAY0, 0x07,
-               AGC_DELAY2, 0xfe,
-               /* Change the value of IAGCBW[15:8]
-                  of inner AGC loop filter bandwidth */
-               AGC_LOOP_BANDWIDTH0, 0x08,
-               AGC_LOOP_BANDWIDTH1, 0x9a
-       };
-
-       static u8 lgdt3303_init_data[] = {
-               0x4c, 0x14
-       };
-
-       static u8 flip_1_lgdt3303_init_data[] = {
-               0x4c, 0x14,
-               0x87, 0xf3
-       };
-
-       static u8 flip_2_lgdt3303_init_data[] = {
-               0x4c, 0x14,
-               0x87, 0xda
-       };
-
-       struct lgdt330x_state* state = fe->demodulator_priv;
-       char  *chip_name;
-       int    err;
-
-       switch (state->config->demod_chip) {
-       case LGDT3302:
-               chip_name = "LGDT3302";
-               err = i2c_write_demod_bytes(state, lgdt3302_init_data,
-                                           sizeof(lgdt3302_init_data));
-               break;
-       case LGDT3303:
-               chip_name = "LGDT3303";
-               switch (state->config->clock_polarity_flip) {
-               case 2:
-                       err = i2c_write_demod_bytes(state,
-                                       flip_2_lgdt3303_init_data,
-                                       sizeof(flip_2_lgdt3303_init_data));
-                       break;
-               case 1:
-                       err = i2c_write_demod_bytes(state,
-                                       flip_1_lgdt3303_init_data,
-                                       sizeof(flip_1_lgdt3303_init_data));
-                       break;
-               case 0:
-               default:
-                       err = i2c_write_demod_bytes(state, lgdt3303_init_data,
-                                                   sizeof(lgdt3303_init_data));
-               }
-               break;
-       default:
-               chip_name = "undefined";
-               printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
-               err = -ENODEV;
-       }
-       dprintk("%s entered as %s\n", __func__, chip_name);
-       if (err < 0)
-               return err;
-       return lgdt330x_SwReset(state);
-}
-
-static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       *ber = 0; /* Not supplied by the demod chips */
-       return 0;
-}
-
-static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct lgdt330x_state* state = fe->demodulator_priv;
-       int err;
-       u8 buf[2];
-
-       *ucblocks = 0;
-
-       switch (state->config->demod_chip) {
-       case LGDT3302:
-               err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
-                                          buf, sizeof(buf));
-               break;
-       case LGDT3303:
-               err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
-                                          buf, sizeof(buf));
-               break;
-       default:
-               printk(KERN_WARNING
-                      "Only LGDT3302 and LGDT3303 are supported chips.\n");
-               err = -ENODEV;
-       }
-       if (err < 0)
-               return err;
-
-       *ucblocks = (buf[0] << 8) | buf[1];
-       return 0;
-}
-
-static int lgdt330x_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       /*
-        * Array of byte pairs <address, value>
-        * to initialize 8VSB for lgdt3303 chip 50 MHz IF
-        */
-       static u8 lgdt3303_8vsb_44_data[] = {
-               0x04, 0x00,
-               0x0d, 0x40,
-               0x0e, 0x87,
-               0x0f, 0x8e,
-               0x10, 0x01,
-               0x47, 0x8b };
-
-       /*
-        * Array of byte pairs <address, value>
-        * to initialize QAM for lgdt3303 chip
-        */
-       static u8 lgdt3303_qam_data[] = {
-               0x04, 0x00,
-               0x0d, 0x00,
-               0x0e, 0x00,
-               0x0f, 0x00,
-               0x10, 0x00,
-               0x51, 0x63,
-               0x47, 0x66,
-               0x48, 0x66,
-               0x4d, 0x1a,
-               0x49, 0x08,
-               0x4a, 0x9b };
-
-       struct lgdt330x_state* state = fe->demodulator_priv;
-
-       static u8 top_ctrl_cfg[]   = { TOP_CONTROL, 0x03 };
-
-       int err = 0;
-       /* Change only if we are actually changing the modulation */
-       if (state->current_modulation != p->modulation) {
-               switch (p->modulation) {
-               case VSB_8:
-                       dprintk("%s: VSB_8 MODE\n", __func__);
-
-                       /* Select VSB mode */
-                       top_ctrl_cfg[1] = 0x03;
-
-                       /* Select ANT connector if supported by card */
-                       if (state->config->pll_rf_set)
-                               state->config->pll_rf_set(fe, 1);
-
-                       if (state->config->demod_chip == LGDT3303) {
-                               err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
-                                                           sizeof(lgdt3303_8vsb_44_data));
-                       }
-                       break;
-
-               case QAM_64:
-                       dprintk("%s: QAM_64 MODE\n", __func__);
-
-                       /* Select QAM_64 mode */
-                       top_ctrl_cfg[1] = 0x00;
-
-                       /* Select CABLE connector if supported by card */
-                       if (state->config->pll_rf_set)
-                               state->config->pll_rf_set(fe, 0);
-
-                       if (state->config->demod_chip == LGDT3303) {
-                               err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
-                                                                                       sizeof(lgdt3303_qam_data));
-                       }
-                       break;
-
-               case QAM_256:
-                       dprintk("%s: QAM_256 MODE\n", __func__);
-
-                       /* Select QAM_256 mode */
-                       top_ctrl_cfg[1] = 0x01;
-
-                       /* Select CABLE connector if supported by card */
-                       if (state->config->pll_rf_set)
-                               state->config->pll_rf_set(fe, 0);
-
-                       if (state->config->demod_chip == LGDT3303) {
-                               err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
-                                                                                       sizeof(lgdt3303_qam_data));
-                       }
-                       break;
-               default:
-                       printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, p->modulation);
-                       return -1;
-               }
-               if (err < 0)
-                       printk(KERN_WARNING "lgdt330x: %s: error blasting "
-                              "bytes to lgdt3303 for modulation type(%d)\n",
-                              __func__, p->modulation);
-
-               /*
-                * select serial or parallel MPEG harware interface
-                * Serial:   0x04 for LGDT3302 or 0x40 for LGDT3303
-                * Parallel: 0x00
-                */
-               top_ctrl_cfg[1] |= state->config->serial_mpeg;
-
-               /* Select the requested mode */
-               i2c_write_demod_bytes(state, top_ctrl_cfg,
-                                     sizeof(top_ctrl_cfg));
-               if (state->config->set_ts_params)
-                       state->config->set_ts_params(fe, 0);
-               state->current_modulation = p->modulation;
-       }
-
-       /* Tune to the specified frequency */
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* Keep track of the new frequency */
-       /* FIXME this is the wrong way to do this...           */
-       /* The tuner is shared with the video4linux analog API */
-       state->current_frequency = p->frequency;
-
-       lgdt330x_SwReset(state);
-       return 0;
-}
-
-static int lgdt330x_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgdt330x_state *state = fe->demodulator_priv;
-       p->frequency = state->current_frequency;
-       return 0;
-}
-
-static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct lgdt330x_state* state = fe->demodulator_priv;
-       u8 buf[3];
-
-       *status = 0; /* Reset status result */
-
-       /* AGC status register */
-       i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
-       dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
-       if ((buf[0] & 0x0c) == 0x8){
-               /* Test signal does not exist flag */
-               /* as well as the AGC lock flag.   */
-               *status |= FE_HAS_SIGNAL;
-       }
-
-       /*
-        * You must set the Mask bits to 1 in the IRQ_MASK in order
-        * to see that status bit in the IRQ_STATUS register.
-        * This is done in SwReset();
-        */
-       /* signal status */
-       i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
-       dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]);
-
-
-       /* sync status */
-       if ((buf[2] & 0x03) == 0x01) {
-               *status |= FE_HAS_SYNC;
-       }
-
-       /* FEC error status */
-       if ((buf[2] & 0x0c) == 0x08) {
-               *status |= FE_HAS_LOCK;
-               *status |= FE_HAS_VITERBI;
-       }
-
-       /* Carrier Recovery Lock Status Register */
-       i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
-       dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
-       switch (state->current_modulation) {
-       case QAM_256:
-       case QAM_64:
-               /* Need to understand why there are 3 lock levels here */
-               if ((buf[0] & 0x07) == 0x07)
-                       *status |= FE_HAS_CARRIER;
-               break;
-       case VSB_8:
-               if ((buf[0] & 0x80) == 0x80)
-                       *status |= FE_HAS_CARRIER;
-               break;
-       default:
-               printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
-       }
-
-       return 0;
-}
-
-static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct lgdt330x_state* state = fe->demodulator_priv;
-       int err;
-       u8 buf[3];
-
-       *status = 0; /* Reset status result */
-
-       /* lgdt3303 AGC status register */
-       err = i2c_read_demod_bytes(state, 0x58, buf, 1);
-       if (err < 0)
-               return err;
-
-       dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
-       if ((buf[0] & 0x21) == 0x01){
-               /* Test input signal does not exist flag */
-               /* as well as the AGC lock flag.   */
-               *status |= FE_HAS_SIGNAL;
-       }
-
-       /* Carrier Recovery Lock Status Register */
-       i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
-       dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
-       switch (state->current_modulation) {
-       case QAM_256:
-       case QAM_64:
-               /* Need to understand why there are 3 lock levels here */
-               if ((buf[0] & 0x07) == 0x07)
-                       *status |= FE_HAS_CARRIER;
-               else
-                       break;
-               i2c_read_demod_bytes(state, 0x8a, buf, 1);
-               if ((buf[0] & 0x04) == 0x04)
-                       *status |= FE_HAS_SYNC;
-               if ((buf[0] & 0x01) == 0x01)
-                       *status |= FE_HAS_LOCK;
-               if ((buf[0] & 0x08) == 0x08)
-                       *status |= FE_HAS_VITERBI;
-               break;
-       case VSB_8:
-               if ((buf[0] & 0x80) == 0x80)
-                       *status |= FE_HAS_CARRIER;
-               else
-                       break;
-               i2c_read_demod_bytes(state, 0x38, buf, 1);
-               if ((buf[0] & 0x02) == 0x00)
-                       *status |= FE_HAS_SYNC;
-               if ((buf[0] & 0x01) == 0x01) {
-                       *status |= FE_HAS_LOCK;
-                       *status |= FE_HAS_VITERBI;
-               }
-               break;
-       default:
-               printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
-       }
-       return 0;
-}
-
-/* Calculate SNR estimation (scaled by 2^24)
-
-   8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
-   equations from LGDT3303 datasheet.  VSB is the same between the '02
-   and '03, so maybe QAM is too?  Perhaps someone with a newer datasheet
-   that has QAM information could verify?
-
-   For 8-VSB: (two ways, take your pick)
-   LGDT3302:
-     SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
-   LGDT3303:
-     SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
-   LGDT3302 & LGDT3303:
-     SNR_PT = 10 * log10(25 * 32^2 / PT_MSE)  (we use this one)
-   For 64-QAM:
-     SNR    = 10 * log10( 688128   / MSEQAM)
-   For 256-QAM:
-     SNR    = 10 * log10( 696320   / MSEQAM)
-
-   We re-write the snr equation as:
-     SNR * 2^24 = 10*(c - intlog10(MSE))
-   Where for 256-QAM, c = log10(696320) * 2^24, and so on. */
-
-static u32 calculate_snr(u32 mse, u32 c)
-{
-       if (mse == 0) /* No signal */
-               return 0;
-
-       mse = intlog10(mse);
-       if (mse > c) {
-               /* Negative SNR, which is possible, but realisticly the
-               demod will lose lock before the signal gets this bad.  The
-               API only allows for unsigned values, so just return 0 */
-               return 0;
-       }
-       return 10*(c - mse);
-}
-
-static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
-       u8 buf[5];      /* read data buffer */
-       u32 noise;      /* noise value */
-       u32 c;          /* per-modulation SNR calculation constant */
-
-       switch(state->current_modulation) {
-       case VSB_8:
-               i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
-#ifdef USE_EQMSE
-               /* Use Equalizer Mean-Square Error Register */
-               /* SNR for ranges from -15.61 to +41.58 */
-               noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
-               c = 69765745; /* log10(25*24^2)*2^24 */
-#else
-               /* Use Phase Tracker Mean-Square Error Register */
-               /* SNR for ranges from -13.11 to +44.08 */
-               noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
-               c = 73957994; /* log10(25*32^2)*2^24 */
-#endif
-               break;
-       case QAM_64:
-       case QAM_256:
-               i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
-               noise = ((buf[0] & 3) << 8) | buf[1];
-               c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
-               /* log10(688128)*2^24 and log10(696320)*2^24 */
-               break;
-       default:
-               printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
-                      __func__);
-               return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
-       }
-
-       state->snr = calculate_snr(noise, c);
-       *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
-
-       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
-               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
-
-       return 0;
-}
-
-static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
-       u8 buf[5];      /* read data buffer */
-       u32 noise;      /* noise value */
-       u32 c;          /* per-modulation SNR calculation constant */
-
-       switch(state->current_modulation) {
-       case VSB_8:
-               i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
-#ifdef USE_EQMSE
-               /* Use Equalizer Mean-Square Error Register */
-               /* SNR for ranges from -16.12 to +44.08 */
-               noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
-               c = 73957994; /* log10(25*32^2)*2^24 */
-#else
-               /* Use Phase Tracker Mean-Square Error Register */
-               /* SNR for ranges from -13.11 to +44.08 */
-               noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
-               c = 73957994; /* log10(25*32^2)*2^24 */
-#endif
-               break;
-       case QAM_64:
-       case QAM_256:
-               i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
-               noise = (buf[0] << 8) | buf[1];
-               c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
-               /* log10(688128)*2^24 and log10(696320)*2^24 */
-               break;
-       default:
-               printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
-                      __func__);
-               return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
-       }
-
-       state->snr = calculate_snr(noise, c);
-       *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
-
-       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
-               state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
-
-       return 0;
-}
-
-static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       /* Calculate Strength from SNR up to 35dB */
-       /* Even though the SNR can go higher than 35dB, there is some comfort */
-       /* factor in having a range of strong signals that can show at 100%   */
-       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
-       u16 snr;
-       int ret;
-
-       ret = fe->ops.read_snr(fe, &snr);
-       if (ret != 0)
-               return ret;
-       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
-       /* scale the range 0 - 35*2^24 into 0 - 65535 */
-       if (state->snr >= 8960 * 0x10000)
-               *strength = 0xffff;
-       else
-               *strength = state->snr / 8960;
-
-       return 0;
-}
-
-static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
-{
-       /* I have no idea about this - it may not be needed */
-       fe_tune_settings->min_delay_ms = 500;
-       fe_tune_settings->step_size = 0;
-       fe_tune_settings->max_drift = 0;
-       return 0;
-}
-
-static void lgdt330x_release(struct dvb_frontend* fe)
-{
-       struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops lgdt3302_ops;
-static struct dvb_frontend_ops lgdt3303_ops;
-
-struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct lgdt330x_state* state = NULL;
-       u8 buf[1];
-
-       /* Allocate memory for the internal state */
-       state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* Setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* Create dvb_frontend */
-       switch (config->demod_chip) {
-       case LGDT3302:
-               memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       case LGDT3303:
-               memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
-               break;
-       default:
-               goto error;
-       }
-       state->frontend.demodulator_priv = state;
-
-       /* Verify communication with demod chip */
-       if (i2c_read_demod_bytes(state, 2, buf, 1))
-               goto error;
-
-       state->current_frequency = -1;
-       state->current_modulation = -1;
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       dprintk("%s: ERROR\n",__func__);
-       return NULL;
-}
-
-static struct dvb_frontend_ops lgdt3302_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
-               .frequency_min= 54000000,
-               .frequency_max= 858000000,
-               .frequency_stepsize= 62500,
-               .symbol_rate_min    = 5056941,  /* QAM 64 */
-               .symbol_rate_max    = 10762000, /* VSB 8  */
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-       .init                 = lgdt330x_init,
-       .set_frontend         = lgdt330x_set_parameters,
-       .get_frontend         = lgdt330x_get_frontend,
-       .get_tune_settings    = lgdt330x_get_tune_settings,
-       .read_status          = lgdt3302_read_status,
-       .read_ber             = lgdt330x_read_ber,
-       .read_signal_strength = lgdt330x_read_signal_strength,
-       .read_snr             = lgdt3302_read_snr,
-       .read_ucblocks        = lgdt330x_read_ucblocks,
-       .release              = lgdt330x_release,
-};
-
-static struct dvb_frontend_ops lgdt3303_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
-               .frequency_min= 54000000,
-               .frequency_max= 858000000,
-               .frequency_stepsize= 62500,
-               .symbol_rate_min    = 5056941,  /* QAM 64 */
-               .symbol_rate_max    = 10762000, /* VSB 8  */
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-       .init                 = lgdt330x_init,
-       .set_frontend         = lgdt330x_set_parameters,
-       .get_frontend         = lgdt330x_get_frontend,
-       .get_tune_settings    = lgdt330x_get_tune_settings,
-       .read_status          = lgdt3303_read_status,
-       .read_ber             = lgdt330x_read_ber,
-       .read_signal_strength = lgdt330x_read_signal_strength,
-       .read_snr             = lgdt3303_read_snr,
-       .read_ucblocks        = lgdt330x_read_ucblocks,
-       .release              = lgdt330x_release,
-};
-
-MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
-MODULE_AUTHOR("Wilson Michaels");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(lgdt330x_attach);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
deleted file mode 100644 (file)
index 9012504..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *    Support for LGDT3302 and LGDT3303 - VSB/QAM
- *
- *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef LGDT330X_H
-#define LGDT330X_H
-
-#include <linux/dvb/frontend.h>
-
-typedef enum lg_chip_t {
-               UNDEFINED,
-               LGDT3302,
-               LGDT3303
-}lg_chip_type;
-
-struct lgdt330x_config
-{
-       /* The demodulator's i2c address */
-       u8 demod_address;
-
-       /* LG demodulator chip LGDT3302 or LGDT3303 */
-       lg_chip_type demod_chip;
-
-       /* MPEG hardware interface - 0:parallel 1:serial */
-       int serial_mpeg;
-
-       /* PLL interface */
-       int (*pll_rf_set) (struct dvb_frontend* fe, int index);
-
-       /* Need to set device param for start_dma */
-       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
-
-       /* Flip the polarity of the mpeg data transfer clock using alternate init data
-        * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
-       int clock_polarity_flip;
-};
-
-#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
-                                           struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
-                                           struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_LGDT330X
-
-#endif /* LGDT330X_H */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h
deleted file mode 100644 (file)
index 38c7669..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *    Support for LGDT3302 and LGDT3303 - VSB/QAM
- *
- *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _LGDT330X_PRIV_
-#define _LGDT330X_PRIV_
-
-/* i2c control register addresses */
-enum I2C_REG {
-       TOP_CONTROL= 0x00,
-       IRQ_MASK= 0x01,
-       IRQ_STATUS= 0x02,
-       VSB_CARRIER_FREQ0= 0x16,
-       VSB_CARRIER_FREQ1= 0x17,
-       VSB_CARRIER_FREQ2= 0x18,
-       VSB_CARRIER_FREQ3= 0x19,
-       CARRIER_MSEQAM1= 0x1a,
-       CARRIER_MSEQAM2= 0x1b,
-       CARRIER_LOCK= 0x1c,
-       TIMING_RECOVERY= 0x1d,
-       AGC_DELAY0= 0x2a,
-       AGC_DELAY1= 0x2b,
-       AGC_DELAY2= 0x2c,
-       AGC_RF_BANDWIDTH0= 0x2d,
-       AGC_RF_BANDWIDTH1= 0x2e,
-       AGC_RF_BANDWIDTH2= 0x2f,
-       AGC_LOOP_BANDWIDTH0= 0x30,
-       AGC_LOOP_BANDWIDTH1= 0x31,
-       AGC_FUNC_CTRL1= 0x32,
-       AGC_FUNC_CTRL2= 0x33,
-       AGC_FUNC_CTRL3= 0x34,
-       AGC_RFIF_ACC0= 0x39,
-       AGC_RFIF_ACC1= 0x3a,
-       AGC_RFIF_ACC2= 0x3b,
-       AGC_STATUS= 0x3f,
-       SYNC_STATUS_VSB= 0x43,
-       DEMUX_CONTROL= 0x66,
-       LGDT3302_EQPH_ERR0= 0x47,
-       LGDT3302_EQ_ERR1= 0x48,
-       LGDT3302_EQ_ERR2= 0x49,
-       LGDT3302_PH_ERR1= 0x4a,
-       LGDT3302_PH_ERR2= 0x4b,
-       LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
-       LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
-       LGDT3303_EQPH_ERR0= 0x6e,
-       LGDT3303_EQ_ERR1= 0x6f,
-       LGDT3303_EQ_ERR2= 0x70,
-       LGDT3303_PH_ERR1= 0x71,
-       LGDT3303_PH_ERR2= 0x72,
-       LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
-       LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
-};
-
-#endif /* _LGDT330X_PRIV_ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c
deleted file mode 100644 (file)
index 416cce3..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-    Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
-
-    Copyright (C) 2008 Sirius International (Hong Kong) Limited
-       Timothy Lee <timothy.lee@siriushk.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "dvb_frontend.h"
-#include "lgs8gl5.h"
-
-
-#define REG_RESET              0x02
-#define REG_RESET_OFF                  0x01
-#define REG_03                 0x03
-#define REG_04                 0x04
-#define REG_07                 0x07
-#define REG_09                 0x09
-#define REG_0A                 0x0a
-#define REG_0B                 0x0b
-#define REG_0C                 0x0c
-#define REG_37                 0x37
-#define REG_STRENGTH           0x4b
-#define REG_STRENGTH_MASK              0x7f
-#define REG_STRENGTH_CARRIER           0x80
-#define REG_INVERSION          0x7c
-#define REG_INVERSION_ON               0x80
-#define REG_7D                 0x7d
-#define REG_7E                 0x7e
-#define REG_A2                 0xa2
-#define REG_STATUS             0xa4
-#define REG_STATUS_SYNC                0x04
-#define REG_STATUS_LOCK                0x01
-
-
-struct lgs8gl5_state {
-       struct i2c_adapter *i2c;
-       const struct lgs8gl5_config *config;
-       struct dvb_frontend frontend;
-};
-
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "lgs8gl5: " args); \
-       } while (0)
-
-
-/* Writes into demod's register */
-static int
-lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = {reg, data};
-       struct i2c_msg msg = {
-               .addr  = state->config->demod_address,
-               .flags = 0,
-               .buf   = buf,
-               .len   = 2
-       };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-       if (ret != 1)
-               dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n",
-                       __func__, reg, data, ret);
-       return (ret != 1) ? -1 : 0;
-}
-
-
-/* Reads from demod's register */
-static int
-lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = {reg};
-       u8 b1[] = {0};
-       struct i2c_msg msg[2] = {
-               {
-                       .addr  = state->config->demod_address,
-                       .flags = 0,
-                       .buf   = b0,
-                       .len   = 1
-               },
-               {
-                       .addr  = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf   = b1,
-                       .len   = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2)
-               return -EIO;
-
-       return b1[0];
-}
-
-
-static int
-lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
-{
-       lgs8gl5_read_reg(state, reg);
-       lgs8gl5_write_reg(state, reg, data);
-       return 0;
-}
-
-
-/* Writes into alternate device's register */
-/* TODO:  Find out what that device is for! */
-static int
-lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 b0[] = {reg};
-       u8 b1[] = {0};
-       u8 b2[] = {reg, data};
-       struct i2c_msg msg[3] = {
-               {
-                       .addr  = state->config->demod_address + 2,
-                       .flags = 0,
-                       .buf   = b0,
-                       .len   = 1
-               },
-               {
-                       .addr  = state->config->demod_address + 2,
-                       .flags = I2C_M_RD,
-                       .buf   = b1,
-                       .len   = 1
-               },
-               {
-                       .addr  = state->config->demod_address + 2,
-                       .flags = 0,
-                       .buf   = b2,
-                       .len   = 2
-               },
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 3);
-       return (ret != 3) ? -1 : 0;
-}
-
-
-static void
-lgs8gl5_soft_reset(struct lgs8gl5_state *state)
-{
-       u8 val;
-
-       dprintk("%s\n", __func__);
-
-       val = lgs8gl5_read_reg(state, REG_RESET);
-       lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF);
-       lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF);
-       msleep(5);
-}
-
-
-/* Starts demodulation */
-static void
-lgs8gl5_start_demod(struct lgs8gl5_state *state)
-{
-       u8  val;
-       int n;
-
-       dprintk("%s\n", __func__);
-
-       lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
-       lgs8gl5_soft_reset(state);
-       lgs8gl5_update_reg(state, REG_07, 0x10);
-       lgs8gl5_update_reg(state, REG_07, 0x10);
-       lgs8gl5_write_reg(state, REG_09, 0x0e);
-       lgs8gl5_write_reg(state, REG_0A, 0xe5);
-       lgs8gl5_write_reg(state, REG_0B, 0x35);
-       lgs8gl5_write_reg(state, REG_0C, 0x30);
-
-       lgs8gl5_update_reg(state, REG_03, 0x00);
-       lgs8gl5_update_reg(state, REG_7E, 0x01);
-       lgs8gl5_update_alt_reg(state, 0xc5, 0x00);
-       lgs8gl5_update_reg(state, REG_04, 0x02);
-       lgs8gl5_update_reg(state, REG_37, 0x01);
-       lgs8gl5_soft_reset(state);
-
-       /* Wait for carrier */
-       for (n = 0;  n < 10;  n++) {
-               val = lgs8gl5_read_reg(state, REG_STRENGTH);
-               dprintk("Wait for carrier[%d] 0x%02X\n", n, val);
-               if (val & REG_STRENGTH_CARRIER)
-                       break;
-               msleep(4);
-       }
-       if (!(val & REG_STRENGTH_CARRIER))
-               return;
-
-       /* Wait for lock */
-       for (n = 0;  n < 20;  n++) {
-               val = lgs8gl5_read_reg(state, REG_STATUS);
-               dprintk("Wait for lock[%d] 0x%02X\n", n, val);
-               if (val & REG_STATUS_LOCK)
-                       break;
-               msleep(12);
-       }
-       if (!(val & REG_STATUS_LOCK))
-               return;
-
-       lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2));
-       lgs8gl5_soft_reset(state);
-}
-
-
-static int
-lgs8gl5_init(struct dvb_frontend *fe)
-{
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
-       lgs8gl5_soft_reset(state);
-       lgs8gl5_update_reg(state, REG_07, 0x10);
-       lgs8gl5_update_reg(state, REG_07, 0x10);
-       lgs8gl5_write_reg(state, REG_09, 0x0e);
-       lgs8gl5_write_reg(state, REG_0A, 0xe5);
-       lgs8gl5_write_reg(state, REG_0B, 0x35);
-       lgs8gl5_write_reg(state, REG_0C, 0x30);
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
-       u8 flags = lgs8gl5_read_reg(state, REG_STATUS);
-
-       *status = 0;
-
-       if ((level & REG_STRENGTH_MASK) > 0)
-               *status |= FE_HAS_SIGNAL;
-       if (level & REG_STRENGTH_CARRIER)
-               *status |= FE_HAS_CARRIER;
-       if (flags & REG_STATUS_SYNC)
-               *status |= FE_HAS_SYNC;
-       if (flags & REG_STATUS_LOCK)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       *ber = 0;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength)
-{
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
-       *signal_strength = (level & REG_STRENGTH_MASK) << 8;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-       u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
-       *snr = (level & REG_STRENGTH_MASK) << 8;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (p->bandwidth_hz != 8000000)
-               return -EINVAL;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* lgs8gl5_set_inversion(state, p->inversion); */
-
-       lgs8gl5_start_demod(state);
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-       u8 inv = lgs8gl5_read_reg(state, REG_INVERSION);
-
-       p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF;
-
-       p->code_rate_HP = FEC_1_2;
-       p->code_rate_LP = FEC_7_8;
-       p->guard_interval = GUARD_INTERVAL_1_32;
-       p->transmission_mode = TRANSMISSION_MODE_2K;
-       p->modulation = QAM_64;
-       p->hierarchy = HIERARCHY_NONE;
-       p->bandwidth_hz = 8000000;
-
-       return 0;
-}
-
-
-static int
-lgs8gl5_get_tune_settings(struct dvb_frontend *fe,
-               struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 240;
-       fesettings->step_size    = 0;
-       fesettings->max_drift    = 0;
-       return 0;
-}
-
-
-static void
-lgs8gl5_release(struct dvb_frontend *fe)
-{
-       struct lgs8gl5_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-
-static struct dvb_frontend_ops lgs8gl5_ops;
-
-
-struct dvb_frontend*
-lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
-{
-       struct lgs8gl5_state *state = NULL;
-
-       dprintk("%s\n", __func__);
-
-       /* Allocate memory for the internal state */
-       state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* Setup the state */
-       state->config = config;
-       state->i2c    = i2c;
-
-       /* Check if the demod is there */
-       if (lgs8gl5_read_reg(state, REG_RESET) < 0)
-               goto error;
-
-       /* Create dvb_frontend */
-       memcpy(&state->frontend.ops, &lgs8gl5_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(lgs8gl5_attach);
-
-
-static struct dvb_frontend_ops lgs8gl5_ops = {
-       .delsys = { SYS_DTMB },
-       .info = {
-               .name                   = "Legend Silicon LGS-8GL5 DMB-TH",
-               .frequency_min          = 474000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 10000,
-               .frequency_tolerance    = 0,
-               .caps = FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
-                       FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_BANDWIDTH_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER
-       },
-
-       .release = lgs8gl5_release,
-
-       .init = lgs8gl5_init,
-
-       .set_frontend = lgs8gl5_set_frontend,
-       .get_frontend = lgs8gl5_get_frontend,
-       .get_tune_settings = lgs8gl5_get_tune_settings,
-
-       .read_status = lgs8gl5_read_status,
-       .read_ber = lgs8gl5_read_ber,
-       .read_signal_strength = lgs8gl5_read_signal_strength,
-       .read_snr = lgs8gl5_read_snr,
-       .read_ucblocks = lgs8gl5_read_ucblocks,
-};
-
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver");
-MODULE_AUTHOR("Timothy Lee");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h
deleted file mode 100644 (file)
index d141767..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-    Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
-
-    Copyright (C) 2008 Sirius International (Hong Kong) Limited
-       Timothy Lee <timothy.lee@siriushk.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef LGS8GL5_H
-#define LGS8GL5_H
-
-#include <linux/dvb/frontend.h>
-
-struct lgs8gl5_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-#if defined(CONFIG_DVB_LGS8GL5) || \
-       (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
-extern struct dvb_frontend *lgs8gl5_attach(
-       const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *lgs8gl5_attach(
-       const struct lgs8gl5_config *config, struct i2c_adapter *i2c) {
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_LGS8GL5 */
-
-#endif /* LGS8GL5_H */
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
deleted file mode 100644 (file)
index 3c92f36..0000000
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
- *    LGS8913, LGS8GL5, LGS8G75
- *    experimental support LGS8G42, LGS8G52
- *
- *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
- *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
- *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <asm/div64.h>
-#include <linux/firmware.h>
-
-#include "dvb_frontend.h"
-
-#include "lgs8gxx.h"
-#include "lgs8gxx_priv.h"
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "lgs8gxx: " args); \
-       } while (0)
-
-static int debug;
-static int fake_signal_str = 1;
-
-#define LGS8GXX_FIRMWARE "lgs8g75.fw"
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-module_param(fake_signal_str, int, 0644);
-MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
-"Signal strength calculation is slow.(default:on).");
-
-/* LGS8GXX internal helper functions */
-
-static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
-
-       msg.addr = priv->config->demod_address;
-       if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
-               msg.addr += 0x02;
-
-       if (debug >= 2)
-               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
-
-       ret = i2c_transfer(priv->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
-                       __func__, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
-{
-       int ret;
-       u8 dev_addr;
-
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               { .flags = 0, .buf = b0, .len = 1 },
-               { .flags = I2C_M_RD, .buf = b1, .len = 1 },
-       };
-
-       dev_addr = priv->config->demod_address;
-       if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
-               dev_addr += 0x02;
-       msg[1].addr =  msg[0].addr = dev_addr;
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret != 2) {
-               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
-               return -1;
-       }
-
-       *p_data = b1[0];
-       if (debug >= 2)
-               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
-       return 0;
-}
-
-static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
-{
-       lgs8gxx_write_reg(priv, 0x02, 0x00);
-       msleep(1);
-       lgs8gxx_write_reg(priv, 0x02, 0x01);
-       msleep(100);
-
-       return 0;
-}
-
-static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
-       u8 val, u8 delay, u8 tries)
-{
-       u8 t;
-       int i;
-
-       for (i = 0; i < tries; i++) {
-               lgs8gxx_read_reg(priv, reg, &t);
-
-               if ((t & mask) == val)
-                       return 0;
-               msleep(delay);
-       }
-
-       return 1;
-}
-
-static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
-{
-       const struct lgs8gxx_config *config = priv->config;
-       u8 if_conf;
-
-       if_conf = 0x10; /* AGC output on, RF_AGC output off; */
-
-       if_conf |=
-               ((config->ext_adc) ? 0x80 : 0x00) |
-               ((config->if_neg_center) ? 0x04 : 0x00) |
-               ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
-               ((config->adc_signed) ? 0x02 : 0x00) |
-               ((config->if_neg_edge) ? 0x01 : 0x00);
-
-       if (config->ext_adc &&
-               (config->prod == LGS8GXX_PROD_LGS8G52)) {
-               lgs8gxx_write_reg(priv, 0xBA, 0x40);
-       }
-
-       lgs8gxx_write_reg(priv, 0x07, if_conf);
-
-       return 0;
-}
-
-static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
-{
-       u64 val;
-       u32 v32;
-       u32 if_clk;
-
-       if_clk = priv->config->if_clk_freq;
-
-       val = freq;
-       if (freq != 0) {
-               val <<= 32;
-               if (if_clk != 0)
-                       do_div(val, if_clk);
-               v32 = val & 0xFFFFFFFF;
-               dprintk("Set IF Freq to %dkHz\n", freq);
-       } else {
-               v32 = 0;
-               dprintk("Set IF Freq to baseband\n");
-       }
-       dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
-               lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
-               lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
-               lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
-       } else {
-               lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
-               lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
-               lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
-               lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
-       }
-
-       return 0;
-}
-
-static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
-{
-       u64 val;
-       u32 v32 = 0;
-       u8 reg_addr, t;
-       int i;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
-               reg_addr = 0x23;
-       else
-               reg_addr = 0x48;
-
-       for (i = 0; i < 4; i++) {
-               lgs8gxx_read_reg(priv, reg_addr, &t);
-               v32 <<= 8;
-               v32 |= t;
-               reg_addr--;
-       }
-
-       val = v32;
-       val *= priv->config->if_clk_freq;
-       val >>= 32;
-       dprintk("AFC = %u kHz\n", (u32)val);
-       return 0;
-}
-
-static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
-{
-       u8 t;
-       u8 prod = priv->config->prod;
-
-       if (prod == LGS8GXX_PROD_LGS8913)
-               lgs8gxx_write_reg(priv, 0xC6, 0x01);
-
-       if (prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_read_reg(priv, 0x0C, &t);
-               t &= (~0x04);
-               lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
-               lgs8gxx_write_reg(priv, 0x39, 0x00);
-               lgs8gxx_write_reg(priv, 0x3D, 0x04);
-       } else if (prod == LGS8GXX_PROD_LGS8913 ||
-               prod == LGS8GXX_PROD_LGS8GL5 ||
-               prod == LGS8GXX_PROD_LGS8G42 ||
-               prod == LGS8GXX_PROD_LGS8G52 ||
-               prod == LGS8GXX_PROD_LGS8G54) {
-               lgs8gxx_read_reg(priv, 0x7E, &t);
-               lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
-
-               /* clear FEC self reset */
-               lgs8gxx_read_reg(priv, 0xC5, &t);
-               lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
-       }
-
-       if (prod == LGS8GXX_PROD_LGS8913) {
-               /* FEC auto detect */
-               lgs8gxx_write_reg(priv, 0xC1, 0x03);
-
-               lgs8gxx_read_reg(priv, 0x7C, &t);
-               t = (t & 0x8C) | 0x03;
-               lgs8gxx_write_reg(priv, 0x7C, t);
-
-               /* BER test mode */
-               lgs8gxx_read_reg(priv, 0xC3, &t);
-               t = (t & 0xEF) |  0x10;
-               lgs8gxx_write_reg(priv, 0xC3, t);
-       }
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
-               lgs8gxx_write_reg(priv, 0xD9, 0x40);
-
-       return 0;
-}
-
-static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
-{
-       u8 t;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               u8 t2;
-               lgs8gxx_read_reg(priv, 0x0C, &t);
-               t &= (~0x80);
-               lgs8gxx_write_reg(priv, 0x0C, t);
-
-               lgs8gxx_read_reg(priv, 0x0C, &t);
-               lgs8gxx_read_reg(priv, 0x19, &t2);
-
-               if (((t&0x03) == 0x01) && (t2&0x01)) {
-                       lgs8gxx_write_reg(priv, 0x6E, 0x05);
-                       lgs8gxx_write_reg(priv, 0x39, 0x02);
-                       lgs8gxx_write_reg(priv, 0x39, 0x03);
-                       lgs8gxx_write_reg(priv, 0x3D, 0x05);
-                       lgs8gxx_write_reg(priv, 0x3E, 0x28);
-                       lgs8gxx_write_reg(priv, 0x53, 0x80);
-               } else {
-                       lgs8gxx_write_reg(priv, 0x6E, 0x3F);
-                       lgs8gxx_write_reg(priv, 0x39, 0x00);
-                       lgs8gxx_write_reg(priv, 0x3D, 0x04);
-               }
-
-               lgs8gxx_soft_reset(priv);
-               return 0;
-       }
-
-       /* turn off auto-detect; manual settings */
-       lgs8gxx_write_reg(priv, 0x7E, 0);
-       if (priv->config->prod == LGS8GXX_PROD_LGS8913)
-               lgs8gxx_write_reg(priv, 0xC1, 0);
-
-       lgs8gxx_read_reg(priv, 0xC5, &t);
-       t = (t & 0xE0) | 0x06;
-       lgs8gxx_write_reg(priv, 0xC5, t);
-
-       lgs8gxx_soft_reset(priv);
-
-       return 0;
-}
-
-static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
-{
-       int ret = 0;
-       u8 t;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
-               ret = lgs8gxx_read_reg(priv, 0x13, &t);
-       else
-               ret = lgs8gxx_read_reg(priv, 0x4B, &t);
-       if (ret != 0)
-               return ret;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
-               *locked = ((t & 0x80) == 0x80) ? 1 : 0;
-       else
-               *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
-       return 0;
-}
-
-/* Wait for Code Acquisition Lock */
-static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
-{
-       int ret = 0;
-       u8 reg, mask, val;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               reg = 0x13;
-               mask = 0x80;
-               val = 0x80;
-       } else {
-               reg = 0x4B;
-               mask = 0xC0;
-               val = 0xC0;
-       }
-
-       ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
-       *locked = (ret == 0) ? 1 : 0;
-
-       return 0;
-}
-
-static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
-                                         u8 *finished)
-{
-       int ret = 0;
-       u8 reg, mask, val;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               reg = 0x1f;
-               mask = 0xC0;
-               val = 0x80;
-       } else {
-               reg = 0xA4;
-               mask = 0x03;
-               val = 0x01;
-       }
-
-       ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
-       *finished = (ret == 0) ? 1 : 0;
-
-       return 0;
-}
-
-static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
-       u8 *locked)
-{
-       int err = 0;
-       u8 ad_fini = 0;
-       u8 t1, t2;
-
-       if (gi == GI_945)
-               dprintk("try GI 945\n");
-       else if (gi == GI_595)
-               dprintk("try GI 595\n");
-       else if (gi == GI_420)
-               dprintk("try GI 420\n");
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_read_reg(priv, 0x0C, &t1);
-               lgs8gxx_read_reg(priv, 0x18, &t2);
-               t1 &= ~(GI_MASK);
-               t1 |= gi;
-               t2 &= 0xFE;
-               t2 |= cpn ? 0x01 : 0x00;
-               lgs8gxx_write_reg(priv, 0x0C, t1);
-               lgs8gxx_write_reg(priv, 0x18, t2);
-       } else {
-               lgs8gxx_write_reg(priv, 0x04, gi);
-       }
-       lgs8gxx_soft_reset(priv);
-       err = lgs8gxx_wait_ca_lock(priv, locked);
-       if (err || !(*locked))
-               return err;
-       err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
-       if (err != 0)
-               return err;
-       if (ad_fini) {
-               dprintk("auto detect finished\n");
-       } else
-               *locked = 0;
-
-       return 0;
-}
-
-static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
-                              u8 *detected_param, u8 *gi)
-{
-       int i, j;
-       int err = 0;
-       u8 locked = 0, tmp_gi;
-
-       dprintk("%s\n", __func__);
-
-       lgs8gxx_set_mode_auto(priv);
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_write_reg(priv, 0x67, 0xAA);
-               lgs8gxx_write_reg(priv, 0x6E, 0x3F);
-       } else {
-               /* Guard Interval */
-               lgs8gxx_write_reg(priv, 0x03, 00);
-       }
-
-       for (i = 0; i < 2; i++) {
-               for (j = 0; j < 2; j++) {
-                       tmp_gi = GI_945;
-                       err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
-                       if (err)
-                               goto out;
-                       if (locked)
-                               goto locked;
-               }
-               for (j = 0; j < 2; j++) {
-                       tmp_gi = GI_420;
-                       err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
-                       if (err)
-                               goto out;
-                       if (locked)
-                               goto locked;
-               }
-               tmp_gi = GI_595;
-               err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
-               if (err)
-                       goto out;
-               if (locked)
-                       goto locked;
-       }
-
-locked:
-       if ((err == 0) && (locked == 1)) {
-               u8 t;
-
-               if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
-                       lgs8gxx_read_reg(priv, 0xA2, &t);
-                       *detected_param = t;
-               } else {
-                       lgs8gxx_read_reg(priv, 0x1F, &t);
-                       *detected_param = t & 0x3F;
-               }
-
-               if (tmp_gi == GI_945)
-                       dprintk("GI 945 locked\n");
-               else if (tmp_gi == GI_595)
-                       dprintk("GI 595 locked\n");
-               else if (tmp_gi == GI_420)
-                       dprintk("GI 420 locked\n");
-               *gi = tmp_gi;
-       }
-       if (!locked)
-               err = -1;
-
-out:
-       return err;
-}
-
-static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
-{
-       s8 err;
-       u8 gi = 0x2;
-       u8 detected_param = 0;
-
-       err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
-
-       if (err != 0) {
-               dprintk("lgs8gxx_auto_detect failed\n");
-       } else
-               dprintk("detected param = 0x%02X\n", detected_param);
-
-       /* Apply detected parameters */
-       if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
-               u8 inter_leave_len = detected_param & TIM_MASK ;
-               /* Fix 8913 time interleaver detection bug */
-               inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
-               detected_param &= CF_MASK | SC_MASK  | LGS_FEC_MASK;
-               detected_param |= inter_leave_len;
-       }
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               u8 t;
-               lgs8gxx_read_reg(priv, 0x19, &t);
-               t &= 0x81;
-               t |= detected_param << 1;
-               lgs8gxx_write_reg(priv, 0x19, t);
-       } else {
-               lgs8gxx_write_reg(priv, 0x7D, detected_param);
-               if (priv->config->prod == LGS8GXX_PROD_LGS8913)
-                       lgs8gxx_write_reg(priv, 0xC0, detected_param);
-       }
-       /* lgs8gxx_soft_reset(priv); */
-
-       /* Enter manual mode */
-       lgs8gxx_set_mode_manual(priv);
-
-       switch (gi) {
-       case GI_945:
-               priv->curr_gi = 945; break;
-       case GI_595:
-               priv->curr_gi = 595; break;
-       case GI_420:
-               priv->curr_gi = 420; break;
-       default:
-               priv->curr_gi = 945; break;
-       }
-}
-
-static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
-       u8 serial, u8 clk_pol, u8 clk_gated)
-{
-       int ret = 0;
-       u8 t, reg_addr;
-
-       reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
-       ret = lgs8gxx_read_reg(priv, reg_addr, &t);
-       if (ret != 0)
-               return ret;
-
-       t &= 0xF8;
-       t |= serial ? TS_SERIAL : TS_PARALLEL;
-       t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
-       t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
-
-       ret = lgs8gxx_write_reg(priv, reg_addr, t);
-       if (ret != 0)
-               return ret;
-
-       return 0;
-}
-
-/* A/D input peak-to-peak voltage range */
-static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
-       u8 sel)
-{
-       u8 r26 = 0x73, r27 = 0x90;
-
-       if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
-               return 0;
-
-       r26 |= (sel & 0x01) << 7;
-       r27 |= (sel & 0x02) >> 1;
-       lgs8gxx_write_reg(priv, 0x26, r26);
-       lgs8gxx_write_reg(priv, 0x27, r27);
-
-       return 0;
-}
-
-/* LGS8913 demod frontend functions */
-
-static int lgs8913_init(struct lgs8gxx_state *priv)
-{
-       u8 t;
-
-       /* LGS8913 specific */
-       lgs8gxx_write_reg(priv, 0xc1, 0x3);
-
-       lgs8gxx_read_reg(priv, 0x7c, &t);
-       lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
-
-       /* LGS8913 specific */
-       lgs8gxx_read_reg(priv, 0xc3, &t);
-       lgs8gxx_write_reg(priv, 0xc3, t&0x10);
-
-
-       return 0;
-}
-
-static int lgs8g75_init_data(struct lgs8gxx_state *priv)
-{
-       const struct firmware *fw;
-       int rc;
-       int i;
-
-       rc = request_firmware(&fw, LGS8GXX_FIRMWARE, &priv->i2c->dev);
-       if (rc)
-               return rc;
-
-       lgs8gxx_write_reg(priv, 0xC6, 0x40);
-
-       lgs8gxx_write_reg(priv, 0x3D, 0x04);
-       lgs8gxx_write_reg(priv, 0x39, 0x00);
-
-       lgs8gxx_write_reg(priv, 0x3A, 0x00);
-       lgs8gxx_write_reg(priv, 0x38, 0x00);
-       lgs8gxx_write_reg(priv, 0x3B, 0x00);
-       lgs8gxx_write_reg(priv, 0x38, 0x00);
-
-       for (i = 0; i < fw->size; i++) {
-               lgs8gxx_write_reg(priv, 0x38, 0x00);
-               lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
-               lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
-               lgs8gxx_write_reg(priv, 0x3C, fw->data[i]);
-       }
-
-       lgs8gxx_write_reg(priv, 0x38, 0x00);
-
-       release_firmware(fw);
-       return 0;
-}
-
-static int lgs8gxx_init(struct dvb_frontend *fe)
-{
-       struct lgs8gxx_state *priv =
-               (struct lgs8gxx_state *)fe->demodulator_priv;
-       const struct lgs8gxx_config *config = priv->config;
-       u8 data = 0;
-       s8 err;
-       dprintk("%s\n", __func__);
-
-       lgs8gxx_read_reg(priv, 0, &data);
-       dprintk("reg 0 = 0x%02X\n", data);
-
-       if (config->prod == LGS8GXX_PROD_LGS8G75)
-               lgs8g75_set_adc_vpp(priv, config->adc_vpp);
-
-       /* Setup MPEG output format */
-       err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
-                                   config->ts_clk_pol,
-                                   config->ts_clk_gated);
-       if (err != 0)
-               return -EIO;
-
-       if (config->prod == LGS8GXX_PROD_LGS8913)
-               lgs8913_init(priv);
-       lgs8gxx_set_if_freq(priv, priv->config->if_freq);
-       lgs8gxx_set_ad_mode(priv);
-
-       return 0;
-}
-
-static void lgs8gxx_release(struct dvb_frontend *fe)
-{
-       struct lgs8gxx_state *state = fe->demodulator_priv;
-       dprintk("%s\n", __func__);
-
-       kfree(state);
-}
-
-
-static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return lgs8gxx_write_reg(priv, buf[0], buf[1]);
-}
-
-static int lgs8gxx_set_fe(struct dvb_frontend *fe)
-{
-
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       /* set frequency */
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* start auto lock */
-       lgs8gxx_auto_lock(priv);
-
-       msleep(10);
-
-       return 0;
-}
-
-static int lgs8gxx_get_fe(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
-       dprintk("%s\n", __func__);
-
-       /* TODO: get real readings from device */
-       /* inversion status */
-       fe_params->inversion = INVERSION_OFF;
-
-       /* bandwidth */
-       fe_params->bandwidth_hz = 8000000;
-
-       fe_params->code_rate_HP = FEC_AUTO;
-       fe_params->code_rate_LP = FEC_AUTO;
-
-       fe_params->modulation = QAM_AUTO;
-
-       /* transmission mode */
-       fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
-
-       /* guard interval */
-       fe_params->guard_interval = GUARD_INTERVAL_AUTO;
-
-       /* hierarchy */
-       fe_params->hierarchy = HIERARCHY_NONE;
-
-       return 0;
-}
-
-static
-int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
-                             struct dvb_frontend_tune_settings *fesettings)
-{
-       /* FIXME: copy from tda1004x.c */
-       fesettings->min_delay_ms = 800;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-       s8 ret;
-       u8 t, locked = 0;
-
-       dprintk("%s\n", __func__);
-       *fe_status = 0;
-
-       lgs8gxx_get_afc_phase(priv);
-       lgs8gxx_is_locked(priv, &locked);
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               if (locked)
-                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-               return 0;
-       }
-
-       ret = lgs8gxx_read_reg(priv, 0x4B, &t);
-       if (ret != 0)
-               return -EIO;
-
-       dprintk("Reg 0x4B: 0x%02X\n", t);
-
-       *fe_status = 0;
-       if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
-               if ((t & 0x40) == 0x40)
-                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
-               if ((t & 0x80) == 0x80)
-                       *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
-                               FE_HAS_LOCK;
-       } else {
-               if ((t & 0x80) == 0x80)
-                       *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-       }
-
-       /* success */
-       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
-       return 0;
-}
-
-static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
-{
-       u16 v;
-       u8 agc_lvl[2], cat;
-
-       dprintk("%s()\n", __func__);
-       lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
-       lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
-
-       v = agc_lvl[0];
-       v <<= 8;
-       v |= agc_lvl[1];
-
-       dprintk("agc_lvl: 0x%04X\n", v);
-
-       if (v < 0x100)
-               cat = 0;
-       else if (v < 0x190)
-               cat = 5;
-       else if (v < 0x2A8)
-               cat = 4;
-       else if (v < 0x381)
-               cat = 3;
-       else if (v < 0x400)
-               cat = 2;
-       else if (v == 0x400)
-               cat = 1;
-       else
-               cat = 0;
-
-       *signal = cat * 65535 / 5;
-
-       return 0;
-}
-
-static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
-{
-       u8 t; s8 ret;
-       s16 max_strength = 0;
-       u8 str;
-       u16 i, gi = priv->curr_gi;
-
-       dprintk("%s\n", __func__);
-
-       ret = lgs8gxx_read_reg(priv, 0x4B, &t);
-       if (ret != 0)
-               return -EIO;
-
-       if (fake_signal_str) {
-               if ((t & 0xC0) == 0xC0) {
-                       dprintk("Fake signal strength\n");
-                       *signal = 0x7FFF;
-               } else
-                       *signal = 0;
-               return 0;
-       }
-
-       dprintk("gi = %d\n", gi);
-       for (i = 0; i < gi; i++) {
-
-               if ((i & 0xFF) == 0)
-                       lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
-               lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
-
-               lgs8gxx_read_reg(priv, 0x94, &str);
-               if (max_strength < str)
-                       max_strength = str;
-       }
-
-       *signal = max_strength;
-       dprintk("%s: signal=0x%02X\n", __func__, *signal);
-
-       lgs8gxx_read_reg(priv, 0x95, &t);
-       dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
-
-       return 0;
-}
-
-static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
-{
-       u8 t;
-       s16 v = 0;
-
-       dprintk("%s\n", __func__);
-
-       lgs8gxx_read_reg(priv, 0xB1, &t);
-       v |= t;
-       v <<= 8;
-       lgs8gxx_read_reg(priv, 0xB0, &t);
-       v |= t;
-
-       *signal = v;
-       dprintk("%s: signal=0x%02X\n", __func__, *signal);
-
-       return 0;
-}
-
-static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8913)
-               return lgs8913_read_signal_strength(priv, signal);
-       else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
-               return lgs8g75_read_signal_strength(priv, signal);
-       else
-               return lgs8gxx_read_signal_agc(priv, signal);
-}
-
-static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-       u8 t;
-       *snr = 0;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
-               lgs8gxx_read_reg(priv, 0x34, &t);
-       else
-               lgs8gxx_read_reg(priv, 0x95, &t);
-       dprintk("AVG Noise=0x%02X\n", t);
-       *snr = 256 - t;
-       *snr <<= 8;
-       dprintk("snr=0x%x\n", *snr);
-
-       return 0;
-}
-
-static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
-       return 0;
-}
-
-static void packet_counter_start(struct lgs8gxx_state *priv)
-{
-       u8 orig, t;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_read_reg(priv, 0x30, &orig);
-               orig &= 0xE7;
-               t = orig | 0x10;
-               lgs8gxx_write_reg(priv, 0x30, t);
-               t = orig | 0x18;
-               lgs8gxx_write_reg(priv, 0x30, t);
-               t = orig | 0x10;
-               lgs8gxx_write_reg(priv, 0x30, t);
-       } else {
-               lgs8gxx_write_reg(priv, 0xC6, 0x01);
-               lgs8gxx_write_reg(priv, 0xC6, 0x41);
-               lgs8gxx_write_reg(priv, 0xC6, 0x01);
-       }
-}
-
-static void packet_counter_stop(struct lgs8gxx_state *priv)
-{
-       u8 t;
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               lgs8gxx_read_reg(priv, 0x30, &t);
-               t &= 0xE7;
-               lgs8gxx_write_reg(priv, 0x30, t);
-       } else {
-               lgs8gxx_write_reg(priv, 0xC6, 0x81);
-       }
-}
-
-static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-       u8 reg_err, reg_total, t;
-       u32 total_cnt = 0, err_cnt = 0;
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       packet_counter_start(priv);
-       msleep(200);
-       packet_counter_stop(priv);
-
-       if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
-               reg_total = 0x28; reg_err = 0x2C;
-       } else {
-               reg_total = 0xD0; reg_err = 0xD4;
-       }
-
-       for (i = 0; i < 4; i++) {
-               total_cnt <<= 8;
-               lgs8gxx_read_reg(priv, reg_total+3-i, &t);
-               total_cnt |= t;
-       }
-       for (i = 0; i < 4; i++) {
-               err_cnt <<= 8;
-               lgs8gxx_read_reg(priv, reg_err+3-i, &t);
-               err_cnt |= t;
-       }
-       dprintk("error=%d total=%d\n", err_cnt, total_cnt);
-
-       if (total_cnt == 0)
-               *ber = 0;
-       else
-               *ber = err_cnt * 100 / total_cnt;
-
-       dprintk("%s: ber=0x%x\n", __func__, *ber);
-       return 0;
-}
-
-static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct lgs8gxx_state *priv = fe->demodulator_priv;
-
-       if (priv->config->tuner_address == 0)
-               return 0;
-       if (enable) {
-               u8 v = 0x80 | priv->config->tuner_address;
-               return lgs8gxx_write_reg(priv, 0x01, v);
-       }
-       return lgs8gxx_write_reg(priv, 0x01, 0);
-}
-
-static struct dvb_frontend_ops lgs8gxx_ops = {
-       .delsys = { SYS_DTMB },
-       .info = {
-               .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
-               .frequency_min = 474000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 10000,
-               .caps =
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO
-       },
-
-       .release = lgs8gxx_release,
-
-       .init = lgs8gxx_init,
-       .write = lgs8gxx_write,
-       .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
-
-       .set_frontend = lgs8gxx_set_fe,
-       .get_frontend = lgs8gxx_get_fe,
-       .get_tune_settings = lgs8gxx_get_tune_settings,
-
-       .read_status = lgs8gxx_read_status,
-       .read_ber = lgs8gxx_read_ber,
-       .read_signal_strength = lgs8gxx_read_signal_strength,
-       .read_snr = lgs8gxx_read_snr,
-       .read_ucblocks = lgs8gxx_read_ucblocks,
-};
-
-struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
-       struct i2c_adapter *i2c)
-{
-       struct lgs8gxx_state *priv = NULL;
-       u8 data = 0;
-
-       dprintk("%s()\n", __func__);
-
-       if (config == NULL || i2c == NULL)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
-       if (priv == NULL)
-               goto error_out;
-
-       priv->config = config;
-       priv->i2c = i2c;
-
-       /* check if the demod is there */
-       if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
-               dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
-                       __func__, priv->config->demod_address);
-               goto error_out;
-       }
-
-       lgs8gxx_read_reg(priv, 1, &data);
-
-       memcpy(&priv->frontend.ops, &lgs8gxx_ops,
-              sizeof(struct dvb_frontend_ops));
-       priv->frontend.demodulator_priv = priv;
-
-       if (config->prod == LGS8GXX_PROD_LGS8G75)
-               lgs8g75_init_data(priv);
-
-       return &priv->frontend;
-
-error_out:
-       dprintk("%s() error_out\n", __func__);
-       kfree(priv);
-       return NULL;
-
-}
-EXPORT_SYMBOL(lgs8gxx_attach);
-
-MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
-MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(LGS8GXX_FIRMWARE);
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h
deleted file mode 100644 (file)
index 33c3c5e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
- *    LGS8913, LGS8GL5, LGS8G75
- *    experimental support LGS8G42, LGS8G52
- *
- *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
- *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
- *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __LGS8GXX_H__
-#define __LGS8GXX_H__
-
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#define LGS8GXX_PROD_LGS8913 0
-#define LGS8GXX_PROD_LGS8GL5 1
-#define LGS8GXX_PROD_LGS8G42 3
-#define LGS8GXX_PROD_LGS8G52 4
-#define LGS8GXX_PROD_LGS8G54 5
-#define LGS8GXX_PROD_LGS8G75 6
-
-struct lgs8gxx_config {
-
-       /* product type */
-       u8 prod;
-
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* parallel or serial transport stream */
-       u8 serial_ts;
-
-       /* transport stream polarity*/
-       u8 ts_clk_pol;
-
-       /* transport stream clock gated by ts_valid */
-       u8 ts_clk_gated;
-
-       /* A/D Clock frequency */
-       u32 if_clk_freq; /* in kHz */
-
-       /* IF frequency */
-       u32 if_freq; /* in kHz */
-
-       /*Use External ADC*/
-       u8 ext_adc;
-
-       /*External ADC output two's complement*/
-       u8 adc_signed;
-
-       /*Sample IF data at falling edge of IF_CLK*/
-       u8 if_neg_edge;
-
-       /*IF use Negative center frequency*/
-       u8 if_neg_center;
-
-       /*8G75 internal ADC input range selection*/
-       /*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
-       u8 adc_vpp;
-
-       /* slave address and configuration of the tuner */
-       u8 tuner_address;
-};
-
-#if defined(CONFIG_DVB_LGS8GXX) || \
-       (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
-extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline
-struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
-                                   struct i2c_adapter *i2c) {
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_LGS8GXX */
-
-#endif /* __LGS8GXX_H__ */
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h
deleted file mode 100644 (file)
index 8ef376f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
- *    LGS8913, LGS8GL5, LGS8G75
- *    experimental support LGS8G42, LGS8G52
- *
- *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
- *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
- *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef LGS8913_PRIV_H
-#define LGS8913_PRIV_H
-
-struct lgs8gxx_state {
-       struct i2c_adapter *i2c;
-       /* configuration settings */
-       const struct lgs8gxx_config *config;
-       struct dvb_frontend frontend;
-       u16 curr_gi; /* current guard interval */
-};
-
-#define SC_MASK                0x1C    /* Sub-Carrier Modulation Mask */
-#define SC_QAM64       0x10    /* 64QAM modulation */
-#define SC_QAM32       0x0C    /* 32QAM modulation */
-#define SC_QAM16       0x08    /* 16QAM modulation */
-#define SC_QAM4NR      0x04    /* 4QAM-NR modulation */
-#define SC_QAM4                0x00    /* 4QAM modulation */
-
-#define LGS_FEC_MASK   0x03    /* FEC Rate Mask */
-#define LGS_FEC_0_4    0x00    /* FEC Rate 0.4 */
-#define LGS_FEC_0_6    0x01    /* FEC Rate 0.6 */
-#define LGS_FEC_0_8    0x02    /* FEC Rate 0.8 */
-
-#define TIM_MASK         0x20  /* Time Interleave Length Mask */
-#define TIM_LONG         0x20  /* Time Interleave Length = 720 */
-#define TIM_MIDDLE     0x00   /* Time Interleave Length = 240 */
-
-#define CF_MASK        0x80    /* Control Frame Mask */
-#define CF_EN  0x80    /* Control Frame On */
-
-#define GI_MASK        0x03    /* Guard Interval Mask */
-#define GI_420 0x00    /* 1/9 Guard Interval */
-#define GI_595 0x01    /* */
-#define GI_945 0x02    /* 1/4 Guard Interval */
-
-
-#define TS_PARALLEL    0x00    /* Parallel TS Output a.k.a. SPI */
-#define TS_SERIAL      0x01    /* Serial TS Output a.k.a. SSI */
-#define TS_CLK_NORMAL          0x00    /* MPEG Clock Normal */
-#define TS_CLK_INVERTED                0x02    /* MPEG Clock Inverted */
-#define TS_CLK_GATED           0x00    /* MPEG clock gated */
-#define TS_CLK_FREERUN         0x04    /* MPEG clock free running*/
-
-
-#endif
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h
deleted file mode 100644 (file)
index c059b16..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * lnbh24.h - driver for lnb supply and control ic lnbh24
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _LNBH24_H
-#define _LNBH24_H
-
-/* system register bits */
-#define LNBH24_OLF     0x01
-#define LNBH24_OTF     0x02
-#define LNBH24_EN      0x04
-#define LNBH24_VSEL    0x08
-#define LNBH24_LLC     0x10
-#define LNBH24_TEN     0x20
-#define LNBH24_TTX     0x40
-#define LNBH24_PCL     0x80
-
-#include <linux/dvb/frontend.h>
-
-#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
-                                                       && defined(MODULE))
-/* override_set and override_clear control which
-   system register bits (above) to always set & clear */
-extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear, u8 i2c_addr);
-#else
-static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear, u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
deleted file mode 100644 (file)
index 1343725..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * lnbp21.c - driver for lnb supply and control ic lnbp21
- *
- * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "lnbp21.h"
-#include "lnbh24.h"
-
-struct lnbp21 {
-       u8                      config;
-       u8                      override_or;
-       u8                      override_and;
-       struct i2c_adapter      *i2c;
-       u8                      i2c_addr;
-};
-
-static int lnbp21_set_voltage(struct dvb_frontend *fe,
-                                       fe_sec_voltage_t voltage)
-{
-       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
-                               .buf = &lnbp21->config,
-                               .len = sizeof(lnbp21->config) };
-
-       lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
-
-       switch(voltage) {
-       case SEC_VOLTAGE_OFF:
-               break;
-       case SEC_VOLTAGE_13:
-               lnbp21->config |= LNBP21_EN;
-               break;
-       case SEC_VOLTAGE_18:
-               lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       lnbp21->config |= lnbp21->override_or;
-       lnbp21->config &= lnbp21->override_and;
-
-       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
-{
-       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
-                               .buf = &lnbp21->config,
-                               .len = sizeof(lnbp21->config) };
-
-       if (arg)
-               lnbp21->config |= LNBP21_LLC;
-       else
-               lnbp21->config &= ~LNBP21_LLC;
-
-       lnbp21->config |= lnbp21->override_or;
-       lnbp21->config &= lnbp21->override_and;
-
-       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int lnbp21_set_tone(struct dvb_frontend *fe,
-                               fe_sec_tone_mode_t tone)
-{
-       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
-       struct i2c_msg msg = {  .addr = lnbp21->i2c_addr, .flags = 0,
-                               .buf = &lnbp21->config,
-                               .len = sizeof(lnbp21->config) };
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               lnbp21->config &= ~LNBP21_TEN;
-               break;
-       case SEC_TONE_ON:
-               lnbp21->config |= LNBP21_TEN;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       lnbp21->config |= lnbp21->override_or;
-       lnbp21->config &= lnbp21->override_and;
-
-       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static void lnbp21_release(struct dvb_frontend *fe)
-{
-       /* LNBP power off */
-       lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       /* free data */
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear, u8 i2c_addr, u8 config)
-{
-       struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
-       if (!lnbp21)
-               return NULL;
-
-       /* default configuration */
-       lnbp21->config = config;
-       lnbp21->i2c = i2c;
-       lnbp21->i2c_addr = i2c_addr;
-       fe->sec_priv = lnbp21;
-
-       /* bits which should be forced to '1' */
-       lnbp21->override_or = override_set;
-
-       /* bits which should be forced to '0' */
-       lnbp21->override_and = ~override_clear;
-
-       /* detect if it is present or not */
-       if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
-               kfree(lnbp21);
-               return NULL;
-       }
-
-       /* install release callback */
-       fe->ops.release_sec = lnbp21_release;
-
-       /* override frontend ops */
-       fe->ops.set_voltage = lnbp21_set_voltage;
-       fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
-       if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
-               fe->ops.set_tone = lnbp21_set_tone;
-       printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
-
-       return fe;
-}
-
-struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear, u8 i2c_addr)
-{
-       return lnbx2x_attach(fe, i2c, override_set, override_clear,
-                                                       i2c_addr, LNBH24_TTX);
-}
-EXPORT_SYMBOL(lnbh24_attach);
-
-struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear)
-{
-       return lnbx2x_attach(fe, i2c, override_set, override_clear,
-                                                       0x08, LNBP21_ISEL);
-}
-EXPORT_SYMBOL(lnbp21_attach);
-
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
-MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
deleted file mode 100644 (file)
index fcdf1c6..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * lnbp21.h - driver for lnb supply and control ic lnbp21
- *
- * Copyright (C) 2006 Oliver Endriss
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef _LNBP21_H
-#define _LNBP21_H
-
-/* system register bits */
-/* [RO] 0=OK; 1=over current limit flag */
-#define LNBP21_OLF     0x01
-/* [RO] 0=OK; 1=over temperature flag (150 C) */
-#define LNBP21_OTF     0x02
-/* [RW] 0=disable LNB power, enable loopthrough
-       1=enable LNB power, disable loopthrough */
-#define LNBP21_EN      0x04
-/* [RW] 0=low voltage (13/14V, vert pol)
-       1=high voltage (18/19V,horiz pol) */
-#define LNBP21_VSEL    0x08
-/* [RW] increase LNB voltage by 1V:
-       0=13/18V; 1=14/19V */
-#define LNBP21_LLC     0x10
-/* [RW] 0=tone controlled by DSQIN pin
-       1=tone enable, disable DSQIN */
-#define LNBP21_TEN     0x20
-/* [RW] current limit select:
-       0:Iout=500-650mA Isc=300mA
-       1:Iout=400-550mA Isc=200mA */
-#define LNBP21_ISEL    0x40
-/* [RW] short-circuit protect:
-       0=pulsed (dynamic) curr limiting
-       1=static curr limiting */
-#define LNBP21_PCL     0x80
-
-#include <linux/dvb/frontend.h>
-
-#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
-                                                       && defined(MODULE))
-/* override_set and override_clear control which
- system register bits (above) to always set & clear */
-extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear);
-#else
-static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
-                               struct i2c_adapter *i2c, u8 override_set,
-                               u8 override_clear)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/lnbp22.c b/drivers/media/dvb/frontends/lnbp22.c
deleted file mode 100644 (file)
index 84ad039..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * lnbp22.h - driver for lnb supply and control ic lnbp22
- *
- * Copyright (C) 2006 Dominik Kuhlen
- * Based on lnbp21 driver
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "lnbp22.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-
-#define dprintk(lvl, arg...) if (debug >= (lvl)) printk(arg)
-
-struct lnbp22 {
-       u8                  config[4];
-       struct i2c_adapter *i2c;
-};
-
-static int lnbp22_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct lnbp22 *lnbp22 = (struct lnbp22 *)fe->sec_priv;
-       struct i2c_msg msg = {
-               .addr = 0x08,
-               .flags = 0,
-               .buf = (char *)&lnbp22->config,
-               .len = sizeof(lnbp22->config),
-       };
-
-       dprintk(1, "%s: %d (18V=%d 13V=%d)\n", __func__, voltage,
-              SEC_VOLTAGE_18, SEC_VOLTAGE_13);
-
-       lnbp22->config[3] = 0x60; /* Power down */
-       switch (voltage) {
-       case SEC_VOLTAGE_OFF:
-               break;
-       case SEC_VOLTAGE_13:
-               lnbp22->config[3] |= LNBP22_EN;
-               break;
-       case SEC_VOLTAGE_18:
-               lnbp22->config[3] |= (LNBP22_EN | LNBP22_VSEL);
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       dprintk(1, "%s: 0x%02x)\n", __func__, lnbp22->config[3]);
-       return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static int lnbp22_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
-{
-       struct lnbp22 *lnbp22 = (struct lnbp22 *) fe->sec_priv;
-       struct i2c_msg msg = {
-               .addr = 0x08,
-               .flags = 0,
-               .buf = (char *)&lnbp22->config,
-               .len = sizeof(lnbp22->config),
-       };
-
-       dprintk(1, "%s: %d\n", __func__, (int)arg);
-       if (arg)
-               lnbp22->config[3] |= LNBP22_LLC;
-       else
-               lnbp22->config[3] &= ~LNBP22_LLC;
-
-       return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO;
-}
-
-static void lnbp22_release(struct dvb_frontend *fe)
-{
-       dprintk(1, "%s\n", __func__);
-       /* LNBP power off */
-       lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF);
-
-       /* free data */
-       kfree(fe->sec_priv);
-       fe->sec_priv = NULL;
-}
-
-struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
-                                       struct i2c_adapter *i2c)
-{
-       struct lnbp22 *lnbp22 = kmalloc(sizeof(struct lnbp22), GFP_KERNEL);
-       if (!lnbp22)
-               return NULL;
-
-       /* default configuration */
-       lnbp22->config[0] = 0x00; /* ? */
-       lnbp22->config[1] = 0x28; /* ? */
-       lnbp22->config[2] = 0x48; /* ? */
-       lnbp22->config[3] = 0x60; /* Power down */
-       lnbp22->i2c = i2c;
-       fe->sec_priv = lnbp22;
-
-       /* detect if it is present or not */
-       if (lnbp22_set_voltage(fe, SEC_VOLTAGE_OFF)) {
-               dprintk(0, "%s LNBP22 not found\n", __func__);
-               kfree(lnbp22);
-               fe->sec_priv = NULL;
-               return NULL;
-       }
-
-       /* install release callback */
-       fe->ops.release_sec = lnbp22_release;
-
-       /* override frontend ops */
-       fe->ops.set_voltage = lnbp22_set_voltage;
-       fe->ops.enable_high_lnb_voltage = lnbp22_enable_high_lnb_voltage;
-
-       return fe;
-}
-EXPORT_SYMBOL(lnbp22_attach);
-
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22");
-MODULE_AUTHOR("Dominik Kuhlen");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp22.h b/drivers/media/dvb/frontends/lnbp22.h
deleted file mode 100644 (file)
index 63e2dec..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * lnbp22.h - driver for lnb supply and control ic lnbp22
- *
- * Copyright (C) 2006 Dominik Kuhlen
- * Based on lnbp21.h
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * the project's page is at http://www.linuxtv.org
- */
-
-#ifndef _LNBP22_H
-#define _LNBP22_H
-
-/* Enable */
-#define LNBP22_EN        0x10
-/* Voltage selection */
-#define LNBP22_VSEL    0x02
-/* Plus 1 Volt Bit */
-#define LNBP22_LLC     0x01
-
-#include <linux/dvb/frontend.h>
-
-#if defined(CONFIG_DVB_LNBP22) || \
-               (defined(CONFIG_DVB_LNBP22_MODULE) && defined(MODULE))
-/*
- * override_set and override_clear control which system register bits (above)
- * to always set & clear
- */
-extern struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
-                                               struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe,
-                                               struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_LNBP22 */
-
-#endif /* _LNBP22_H */
diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
deleted file mode 100644 (file)
index 633815e..0000000
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
-       Driver for M88RS2000 demodulator and tuner
-
-       Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
-       Beta Driver
-
-       Include various calculation code from DS3000 driver.
-       Copyright (C) 2009 Konstantin Dimitrov.
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-
-#include "dvb_frontend.h"
-#include "m88rs2000.h"
-
-struct m88rs2000_state {
-       struct i2c_adapter *i2c;
-       const struct m88rs2000_config *config;
-       struct dvb_frontend frontend;
-       u8 no_lock_count;
-       u32 tuner_frequency;
-       u32 symbol_rate;
-       fe_code_rate_t fec_inner;
-       u8 tuner_level;
-       int errmode;
-};
-
-static int m88rs2000_debug;
-
-module_param_named(debug, m88rs2000_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
-
-#define dprintk(level, args...) do { \
-       if (level & m88rs2000_debug) \
-               printk(KERN_DEBUG "m88rs2000-fe: " args); \
-} while (0)
-
-#define deb_info(args...)  dprintk(0x01, args)
-#define info(format, arg...) \
-       printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)
-
-static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
-       u8 reg, u8 data)
-{
-       int ret;
-       u8 addr = (tuner == 0) ? state->config->tuner_addr :
-               state->config->demod_addr;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = addr,
-               .flags = 0,
-               .buf = buf,
-               .len = 2
-       };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
-                       "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data)
-{
-       return m88rs2000_writereg(state, 1, reg, data);
-}
-
-static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data)
-{
-       m88rs2000_demod_write(state, 0x81, 0x84);
-       udelay(10);
-       return m88rs2000_writereg(state, 0, reg, data);
-
-}
-
-static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return m88rs2000_writereg(state, 1, buf[0], buf[1]);
-}
-
-static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       u8 addr = (tuner == 0) ? state->config->tuner_addr :
-               state->config->demod_addr;
-       struct i2c_msg msg[] = {
-               {
-                       .addr = addr,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = addr,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n",
-                               __func__, reg, ret);
-
-       return b1[0];
-}
-
-static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
-{
-       return m88rs2000_readreg(state, 1, reg);
-}
-
-static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
-{
-       m88rs2000_demod_write(state, 0x81, 0x85);
-       udelay(10);
-       return m88rs2000_readreg(state, 0, reg);
-}
-
-static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       int ret;
-       u32 temp;
-       u8 b[3];
-
-       if ((srate < 1000000) || (srate > 45000000))
-               return -EINVAL;
-
-       temp = srate / 1000;
-       temp *= 11831;
-       temp /= 68;
-       temp -= 3;
-
-       b[0] = (u8) (temp >> 16) & 0xff;
-       b[1] = (u8) (temp >> 8) & 0xff;
-       b[2] = (u8) temp & 0xff;
-       ret = m88rs2000_demod_write(state, 0x93, b[2]);
-       ret |= m88rs2000_demod_write(state, 0x94, b[1]);
-       ret |= m88rs2000_demod_write(state, 0x95, b[0]);
-
-       deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
-       return ret;
-}
-
-static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-
-       int i;
-       u8 reg;
-       deb_info("%s\n", __func__);
-       m88rs2000_demod_write(state, 0x9a, 0x30);
-       reg = m88rs2000_demod_read(state, 0xb2);
-       reg &= 0x3f;
-       m88rs2000_demod_write(state, 0xb2, reg);
-       for (i = 0; i <  m->msg_len; i++)
-               m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]);
-
-       reg = m88rs2000_demod_read(state, 0xb1);
-       reg &= 0x87;
-       reg |= ((m->msg_len - 1) << 3) | 0x07;
-       reg &= 0x7f;
-       m88rs2000_demod_write(state, 0xb1, reg);
-
-       for (i = 0; i < 15; i++) {
-               if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0)
-                       break;
-               msleep(20);
-       }
-
-       reg = m88rs2000_demod_read(state, 0xb1);
-       if ((reg & 0x40) > 0x0) {
-               reg &= 0x7f;
-               reg |= 0x40;
-               m88rs2000_demod_write(state, 0xb1, reg);
-       }
-
-       reg = m88rs2000_demod_read(state, 0xb2);
-       reg &= 0x3f;
-       reg |= 0x80;
-       m88rs2000_demod_write(state, 0xb2, reg);
-       m88rs2000_demod_write(state, 0x9a, 0xb0);
-
-
-       return 0;
-}
-
-static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
-                                               fe_sec_mini_cmd_t burst)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       u8 reg0, reg1;
-       deb_info("%s\n", __func__);
-       m88rs2000_demod_write(state, 0x9a, 0x30);
-       msleep(50);
-       reg0 = m88rs2000_demod_read(state, 0xb1);
-       reg1 = m88rs2000_demod_read(state, 0xb2);
-       /* TODO complete this section */
-       m88rs2000_demod_write(state, 0xb2, reg1);
-       m88rs2000_demod_write(state, 0xb1, reg0);
-       m88rs2000_demod_write(state, 0x9a, 0xb0);
-
-       return 0;
-}
-
-static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       u8 reg0, reg1;
-       m88rs2000_demod_write(state, 0x9a, 0x30);
-       reg0 = m88rs2000_demod_read(state, 0xb1);
-       reg1 = m88rs2000_demod_read(state, 0xb2);
-
-       reg1 &= 0x3f;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               reg0 |= 0x4;
-               reg0 &= 0xbc;
-               break;
-       case SEC_TONE_OFF:
-               reg1 |= 0x80;
-               break;
-       default:
-               break;
-       }
-       m88rs2000_demod_write(state, 0xb2, reg1);
-       m88rs2000_demod_write(state, 0xb1, reg0);
-       m88rs2000_demod_write(state, 0x9a, 0xb0);
-       return 0;
-}
-
-struct inittab {
-       u8 cmd;
-       u8 reg;
-       u8 val;
-};
-
-struct inittab m88rs2000_setup[] = {
-       {DEMOD_WRITE, 0x9a, 0x30},
-       {DEMOD_WRITE, 0x00, 0x01},
-       {WRITE_DELAY, 0x19, 0x00},
-       {DEMOD_WRITE, 0x00, 0x00},
-       {DEMOD_WRITE, 0x9a, 0xb0},
-       {DEMOD_WRITE, 0x81, 0xc1},
-       {TUNER_WRITE, 0x42, 0x73},
-       {TUNER_WRITE, 0x05, 0x07},
-       {TUNER_WRITE, 0x20, 0x27},
-       {TUNER_WRITE, 0x07, 0x02},
-       {TUNER_WRITE, 0x11, 0xff},
-       {TUNER_WRITE, 0x60, 0xf9},
-       {TUNER_WRITE, 0x08, 0x01},
-       {TUNER_WRITE, 0x00, 0x41},
-       {DEMOD_WRITE, 0x81, 0x81},
-       {DEMOD_WRITE, 0x86, 0xc6},
-       {DEMOD_WRITE, 0x9a, 0x30},
-       {DEMOD_WRITE, 0xf0, 0x22},
-       {DEMOD_WRITE, 0xf1, 0xbf},
-       {DEMOD_WRITE, 0xb0, 0x45},
-       {DEMOD_WRITE, 0xb2, 0x01}, /* set voltage pin always set 1*/
-       {DEMOD_WRITE, 0x9a, 0xb0},
-       {0xff, 0xaa, 0xff}
-};
-
-struct inittab m88rs2000_shutdown[] = {
-       {DEMOD_WRITE, 0x9a, 0x30},
-       {DEMOD_WRITE, 0xb0, 0x00},
-       {DEMOD_WRITE, 0xf1, 0x89},
-       {DEMOD_WRITE, 0x00, 0x01},
-       {DEMOD_WRITE, 0x9a, 0xb0},
-       {TUNER_WRITE, 0x00, 0x40},
-       {DEMOD_WRITE, 0x81, 0x81},
-       {0xff, 0xaa, 0xff}
-};
-
-struct inittab tuner_reset[] = {
-       {TUNER_WRITE, 0x42, 0x73},
-       {TUNER_WRITE, 0x05, 0x07},
-       {TUNER_WRITE, 0x20, 0x27},
-       {TUNER_WRITE, 0x07, 0x02},
-       {TUNER_WRITE, 0x11, 0xff},
-       {TUNER_WRITE, 0x60, 0xf9},
-       {TUNER_WRITE, 0x08, 0x01},
-       {TUNER_WRITE, 0x00, 0x41},
-       {0xff, 0xaa, 0xff}
-};
-
-struct inittab fe_reset[] = {
-       {DEMOD_WRITE, 0x00, 0x01},
-       {DEMOD_WRITE, 0xf1, 0xbf},
-       {DEMOD_WRITE, 0x00, 0x01},
-       {DEMOD_WRITE, 0x20, 0x81},
-       {DEMOD_WRITE, 0x21, 0x80},
-       {DEMOD_WRITE, 0x10, 0x33},
-       {DEMOD_WRITE, 0x11, 0x44},
-       {DEMOD_WRITE, 0x12, 0x07},
-       {DEMOD_WRITE, 0x18, 0x20},
-       {DEMOD_WRITE, 0x28, 0x04},
-       {DEMOD_WRITE, 0x29, 0x8e},
-       {DEMOD_WRITE, 0x3b, 0xff},
-       {DEMOD_WRITE, 0x32, 0x10},
-       {DEMOD_WRITE, 0x33, 0x02},
-       {DEMOD_WRITE, 0x34, 0x30},
-       {DEMOD_WRITE, 0x35, 0xff},
-       {DEMOD_WRITE, 0x38, 0x50},
-       {DEMOD_WRITE, 0x39, 0x68},
-       {DEMOD_WRITE, 0x3c, 0x7f},
-       {DEMOD_WRITE, 0x3d, 0x0f},
-       {DEMOD_WRITE, 0x45, 0x20},
-       {DEMOD_WRITE, 0x46, 0x24},
-       {DEMOD_WRITE, 0x47, 0x7c},
-       {DEMOD_WRITE, 0x48, 0x16},
-       {DEMOD_WRITE, 0x49, 0x04},
-       {DEMOD_WRITE, 0x4a, 0x01},
-       {DEMOD_WRITE, 0x4b, 0x78},
-       {DEMOD_WRITE, 0X4d, 0xd2},
-       {DEMOD_WRITE, 0x4e, 0x6d},
-       {DEMOD_WRITE, 0x50, 0x30},
-       {DEMOD_WRITE, 0x51, 0x30},
-       {DEMOD_WRITE, 0x54, 0x7b},
-       {DEMOD_WRITE, 0x56, 0x09},
-       {DEMOD_WRITE, 0x58, 0x59},
-       {DEMOD_WRITE, 0x59, 0x37},
-       {DEMOD_WRITE, 0x63, 0xfa},
-       {0xff, 0xaa, 0xff}
-};
-
-struct inittab fe_trigger[] = {
-       {DEMOD_WRITE, 0x97, 0x04},
-       {DEMOD_WRITE, 0x99, 0x77},
-       {DEMOD_WRITE, 0x9b, 0x64},
-       {DEMOD_WRITE, 0x9e, 0x00},
-       {DEMOD_WRITE, 0x9f, 0xf8},
-       {DEMOD_WRITE, 0xa0, 0x20},
-       {DEMOD_WRITE, 0xa1, 0xe0},
-       {DEMOD_WRITE, 0xa3, 0x38},
-       {DEMOD_WRITE, 0x98, 0xff},
-       {DEMOD_WRITE, 0xc0, 0x0f},
-       {DEMOD_WRITE, 0x89, 0x01},
-       {DEMOD_WRITE, 0x00, 0x00},
-       {WRITE_DELAY, 0x0a, 0x00},
-       {DEMOD_WRITE, 0x00, 0x01},
-       {DEMOD_WRITE, 0x00, 0x00},
-       {DEMOD_WRITE, 0x9a, 0xb0},
-       {0xff, 0xaa, 0xff}
-};
-
-static int m88rs2000_tab_set(struct m88rs2000_state *state,
-               struct inittab *tab)
-{
-       int ret = 0;
-       u8 i;
-       if (tab == NULL)
-               return -EINVAL;
-
-       for (i = 0; i < 255; i++) {
-               switch (tab[i].cmd) {
-               case 0x01:
-                       ret = m88rs2000_demod_write(state, tab[i].reg,
-                               tab[i].val);
-                       break;
-               case 0x02:
-                       ret = m88rs2000_tuner_write(state, tab[i].reg,
-                               tab[i].val);
-                       break;
-               case 0x10:
-                       if (tab[i].reg > 0)
-                               mdelay(tab[i].reg);
-                       break;
-               case 0xff:
-                       if (tab[i].reg == 0xaa && tab[i].val == 0xff)
-                               return 0;
-               case 0x00:
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               if (ret < 0)
-                       return -ENODEV;
-       }
-       return 0;
-}
-
-static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       u8 data;
-
-       data = m88rs2000_demod_read(state, 0xb2);
-       data |= 0x03; /* bit0 V/H, bit1 off/on */
-
-       switch (volt) {
-       case SEC_VOLTAGE_18:
-               data &= ~0x03;
-               break;
-       case SEC_VOLTAGE_13:
-               data &= ~0x03;
-               data |= 0x01;
-               break;
-       case SEC_VOLTAGE_OFF:
-               break;
-       }
-
-       m88rs2000_demod_write(state, 0xb2, data);
-
-       return 0;
-}
-
-static int m88rs2000_startup(struct m88rs2000_state *state)
-{
-       int ret = 0;
-       u8 reg;
-
-       reg = m88rs2000_tuner_read(state, 0x00);
-       if ((reg & 0x40) == 0)
-               ret = -ENODEV;
-
-       return ret;
-}
-
-static int m88rs2000_init(struct dvb_frontend *fe)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       int ret;
-
-       deb_info("m88rs2000: init chip\n");
-       /* Setup frontend from shutdown/cold */
-       ret = m88rs2000_tab_set(state, m88rs2000_setup);
-
-       return ret;
-}
-
-static int m88rs2000_sleep(struct dvb_frontend *fe)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       int ret;
-       /* Shutdown the frondend */
-       ret = m88rs2000_tab_set(state, m88rs2000_shutdown);
-       return ret;
-}
-
-static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       u8 reg = m88rs2000_demod_read(state, 0x8c);
-
-       *status = 0;
-
-       if ((reg & 0x7) == 0x7) {
-               *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
-                       | FE_HAS_SYNC | FE_HAS_LOCK;
-               if (state->config->set_ts_params)
-                       state->config->set_ts_params(fe, CALL_IS_READ);
-       }
-       return 0;
-}
-
-/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
-
-static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       deb_info("m88rs2000_read_ber %d\n", *ber);
-       *ber = 0;
-       return 0;
-}
-
-static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
-       u16 *strength)
-{
-       *strength = 0;
-       return 0;
-}
-
-static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       deb_info("m88rs2000_read_snr %d\n", *snr);
-       *snr = 0;
-       return 0;
-}
-
-static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       deb_info("m88rs2000_read_ber %d\n", *ucblocks);
-       *ucblocks = 0;
-       return 0;
-}
-
-static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset)
-{
-       int ret;
-       ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset);
-       ret |= m88rs2000_tuner_write(state, 0x51, 0x1f);
-       ret |= m88rs2000_tuner_write(state, 0x50, offset);
-       ret |= m88rs2000_tuner_write(state, 0x50, 0x00);
-       msleep(20);
-       return ret;
-}
-
-static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       int reg;
-       reg = m88rs2000_tuner_read(state, 0x3d);
-       reg &= 0x7f;
-       if (reg < 0x16)
-               reg = 0xa1;
-       else if (reg == 0x16)
-               reg = 0x99;
-       else
-               reg = 0xf9;
-
-       m88rs2000_tuner_write(state, 0x60, reg);
-       reg = m88rs2000_tuner_gate_ctrl(state, 0x08);
-
-       if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       return reg;
-}
-
-static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       int ret;
-       u32 frequency = c->frequency;
-       s32 offset_khz;
-       s32 tmp;
-       u32 symbol_rate = (c->symbol_rate / 1000);
-       u32 f3db, gdiv28;
-       u16 value, ndiv, lpf_coeff;
-       u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
-       u8 lo = 0x01, div4 = 0x0;
-
-       /* Reset Tuner */
-       ret = m88rs2000_tab_set(state, tuner_reset);
-
-       /* Calculate frequency divider */
-       if (frequency < 1060000) {
-               lo |= 0x10;
-               div4 = 0x1;
-               ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ;
-       } else
-               ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ;
-       ndiv = ndiv + ndiv % 2;
-       ndiv = ndiv - 1024;
-
-       ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo);
-
-       /* Set frequency divider */
-       ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf);
-       ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff);
-
-       ret |= m88rs2000_tuner_write(state, 0x03, 0x06);
-       ret |= m88rs2000_tuner_gate_ctrl(state, 0x10);
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Tuner Frequency Range */
-       ret = m88rs2000_tuner_write(state, 0x10, lo);
-
-       ret |= m88rs2000_tuner_gate_ctrl(state, 0x08);
-
-       /* Tuner RF */
-       ret |= m88rs2000_set_tuner_rf(fe);
-
-       gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
-       ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff);
-       ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
-       if (ret < 0)
-               return -ENODEV;
-
-       value = m88rs2000_tuner_read(state, 0x26);
-
-       f3db = (symbol_rate * 135) / 200 + 2000;
-       f3db += FREQ_OFFSET_LOW_SYM_RATE;
-       if (f3db < 7000)
-               f3db = 7000;
-       if (f3db > 40000)
-               f3db = 40000;
-
-       gdiv28 = gdiv28 * 207 / (value * 2 + 151);
-       mlpf_max = gdiv28 * 135 / 100;
-       mlpf_min = gdiv28 * 78 / 100;
-       if (mlpf_max > 63)
-               mlpf_max = 63;
-
-       lpf_coeff = 2766;
-
-       nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
-               (FE_CRYSTAL_KHZ / 1000)  + 1) / 2;
-       if (nlpf > 23)
-               nlpf = 23;
-       if (nlpf < 1)
-               nlpf = 1;
-
-       lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
-               * lpf_coeff * 2  / f3db + 1) / 2;
-
-       if (lpf_mxdiv < mlpf_min) {
-               nlpf++;
-               lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
-                       * lpf_coeff * 2  / f3db + 1) / 2;
-       }
-
-       if (lpf_mxdiv > mlpf_max)
-               lpf_mxdiv = mlpf_max;
-
-       ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv);
-       ret |= m88rs2000_tuner_write(state, 0x06, nlpf);
-
-       ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
-
-       ret |= m88rs2000_tuner_gate_ctrl(state, 0x01);
-
-       msleep(80);
-       /* calculate offset assuming 96000kHz*/
-       offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ
-               / 14 / (div4 + 1) / 2;
-
-       offset_khz -= frequency;
-
-       tmp = offset_khz;
-       tmp *= 65536;
-
-       tmp = (2 * tmp + 96000) / (2 * 96000);
-       if (tmp < 0)
-               tmp += 65536;
-
-       *offset = tmp & 0xffff;
-
-       if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return (ret < 0) ? -EINVAL : 0;
-}
-
-static int m88rs2000_set_fec(struct m88rs2000_state *state,
-               fe_code_rate_t fec)
-{
-       u16 fec_set;
-       switch (fec) {
-       /* This is not confirmed kept for reference */
-/*     case FEC_1_2:
-               fec_set = 0x88;
-               break;
-       case FEC_2_3:
-               fec_set = 0x68;
-               break;
-       case FEC_3_4:
-               fec_set = 0x48;
-               break;
-       case FEC_5_6:
-               fec_set = 0x28;
-               break;
-       case FEC_7_8:
-               fec_set = 0x18;
-               break; */
-       case FEC_AUTO:
-       default:
-               fec_set = 0x08;
-       }
-       m88rs2000_demod_write(state, 0x76, fec_set);
-
-       return 0;
-}
-
-
-static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
-{
-       u8 reg;
-       m88rs2000_demod_write(state, 0x9a, 0x30);
-       reg = m88rs2000_demod_read(state, 0x76);
-       m88rs2000_demod_write(state, 0x9a, 0xb0);
-
-       switch (reg) {
-       case 0x88:
-               return FEC_1_2;
-       case 0x68:
-               return FEC_2_3;
-       case 0x48:
-               return FEC_3_4;
-       case 0x28:
-               return FEC_5_6;
-       case 0x18:
-               return FEC_7_8;
-       case 0x08:
-       default:
-               break;
-       }
-
-       return FEC_AUTO;
-}
-
-static int m88rs2000_set_frontend(struct dvb_frontend *fe)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       fe_status_t status;
-       int i, ret;
-       u16 offset = 0;
-       u8 reg;
-
-       state->no_lock_count = 0;
-
-       if (c->delivery_system != SYS_DVBS) {
-                       deb_info("%s: unsupported delivery "
-                               "system selected (%d)\n",
-                               __func__, c->delivery_system);
-                       return -EOPNOTSUPP;
-       }
-
-       /* Set Tuner */
-       ret = m88rs2000_set_tuner(fe, &offset);
-       if (ret < 0)
-               return -ENODEV;
-
-       ret = m88rs2000_demod_write(state, 0x9a, 0x30);
-       /* Unknown usually 0xc6 sometimes 0xc1 */
-       reg = m88rs2000_demod_read(state, 0x86);
-       ret |= m88rs2000_demod_write(state, 0x86, reg);
-       /* Offset lower nibble always 0 */
-       ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8));
-       ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0);
-
-
-       /* Reset Demod */
-       ret = m88rs2000_tab_set(state, fe_reset);
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Unknown */
-       reg = m88rs2000_demod_read(state, 0x70);
-       ret = m88rs2000_demod_write(state, 0x70, reg);
-
-       /* Set FEC */
-       ret |= m88rs2000_set_fec(state, c->fec_inner);
-       ret |= m88rs2000_demod_write(state, 0x85, 0x1);
-       ret |= m88rs2000_demod_write(state, 0x8a, 0xbf);
-       ret |= m88rs2000_demod_write(state, 0x8d, 0x1e);
-       ret |= m88rs2000_demod_write(state, 0x90, 0xf1);
-       ret |= m88rs2000_demod_write(state, 0x91, 0x08);
-
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Set Symbol Rate */
-       ret = m88rs2000_set_symbolrate(fe, c->symbol_rate);
-       if (ret < 0)
-               return -ENODEV;
-
-       /* Set up Demod */
-       ret = m88rs2000_tab_set(state, fe_trigger);
-       if (ret < 0)
-               return -ENODEV;
-
-       for (i = 0; i < 25; i++) {
-               reg = m88rs2000_demod_read(state, 0x8c);
-               if ((reg & 0x7) == 0x7) {
-                       status = FE_HAS_LOCK;
-                       break;
-               }
-               state->no_lock_count++;
-               if (state->no_lock_count == 15) {
-                       reg = m88rs2000_demod_read(state, 0x70);
-                       reg ^= 0x4;
-                       m88rs2000_demod_write(state, 0x70, reg);
-                       state->no_lock_count = 0;
-               }
-               if (state->no_lock_count == 20)
-                       m88rs2000_set_tuner_rf(fe);
-               msleep(20);
-       }
-
-       if (status & FE_HAS_LOCK) {
-               state->fec_inner = m88rs2000_get_fec(state);
-               /* Uknown suspect SNR level */
-               reg = m88rs2000_demod_read(state, 0x65);
-       }
-
-       state->tuner_frequency = c->frequency;
-       state->symbol_rate = c->symbol_rate;
-       return 0;
-}
-
-static int m88rs2000_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       c->fec_inner = state->fec_inner;
-       c->frequency = state->tuner_frequency;
-       c->symbol_rate = state->symbol_rate;
-       return 0;
-}
-
-static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-
-       if (enable)
-               m88rs2000_demod_write(state, 0x81, 0x84);
-       else
-               m88rs2000_demod_write(state, 0x81, 0x81);
-       udelay(10);
-       return 0;
-}
-
-static void m88rs2000_release(struct dvb_frontend *fe)
-{
-       struct m88rs2000_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops m88rs2000_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "M88RS2000 DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
-               .frequency_tolerance    = 5000,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,  /* ppm */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                     FE_CAN_QPSK |
-                     FE_CAN_FEC_AUTO
-       },
-
-       .release = m88rs2000_release,
-       .init = m88rs2000_init,
-       .sleep = m88rs2000_sleep,
-       .write = m88rs2000_write,
-       .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
-       .read_status = m88rs2000_read_status,
-       .read_ber = m88rs2000_read_ber,
-       .read_signal_strength = m88rs2000_read_signal_strength,
-       .read_snr = m88rs2000_read_snr,
-       .read_ucblocks = m88rs2000_read_ucblocks,
-       .diseqc_send_master_cmd = m88rs2000_send_diseqc_msg,
-       .diseqc_send_burst = m88rs2000_send_diseqc_burst,
-       .set_tone = m88rs2000_set_tone,
-       .set_voltage = m88rs2000_set_voltage,
-
-       .set_frontend = m88rs2000_set_frontend,
-       .get_frontend = m88rs2000_get_frontend,
-};
-
-struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct m88rs2000_state *state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->tuner_frequency = 0;
-       state->symbol_rate = 0;
-       state->fec_inner = 0;
-
-       if (m88rs2000_startup(state) < 0)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &m88rs2000_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-
-       return NULL;
-}
-EXPORT_SYMBOL(m88rs2000_attach);
-
-MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver");
-MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("1.13");
-
diff --git a/drivers/media/dvb/frontends/m88rs2000.h b/drivers/media/dvb/frontends/m88rs2000.h
deleted file mode 100644 (file)
index 59acdb6..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-       Driver for M88RS2000 demodulator
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef M88RS2000_H
-#define M88RS2000_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct m88rs2000_config {
-       /* Demodulator i2c address */
-       u8 demod_addr;
-       /* Tuner address */
-       u8 tuner_addr;
-
-       u8 *inittab;
-
-       /* minimum delay before retuning */
-       int min_delay_ms;
-
-       int (*set_ts_params)(struct dvb_frontend *, int);
-};
-
-enum {
-       CALL_IS_SET_FRONTEND = 0x0,
-       CALL_IS_READ,
-};
-
-#if defined(CONFIG_DVB_M88RS2000) || (defined(CONFIG_DVB_M88RS2000_MODULE) && \
-                                                       defined(MODULE))
-extern struct dvb_frontend *m88rs2000_attach(
-       const struct m88rs2000_config *config, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *m88rs2000_attach(
-       const struct m88rs2000_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_M88RS2000 */
-
-#define FE_CRYSTAL_KHZ 27000
-#define FREQ_OFFSET_LOW_SYM_RATE 3000
-
-enum {
-       DEMOD_WRITE = 0x1,
-       TUNER_WRITE,
-       WRITE_DELAY = 0x10,
-};
-#endif /* M88RS2000_H */
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c
deleted file mode 100644 (file)
index 9ae40ab..0000000
+++ /dev/null
@@ -1,1878 +0,0 @@
-/*
-       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
-
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "mb86a16.h"
-#include "mb86a16_priv.h"
-
-unsigned int verbose = 5;
-module_param(verbose, int, 0644);
-
-#define ABS(x)         ((x) < 0 ? (-x) : (x))
-
-struct mb86a16_state {
-       struct i2c_adapter              *i2c_adap;
-       const struct mb86a16_config     *config;
-       struct dvb_frontend             frontend;
-
-       /* tuning parameters */
-       int                             frequency;
-       int                             srate;
-
-       /* Internal stuff */
-       int                             master_clk;
-       int                             deci;
-       int                             csel;
-       int                             rsel;
-};
-
-#define MB86A16_ERROR          0
-#define MB86A16_NOTICE         1
-#define MB86A16_INFO           2
-#define MB86A16_DEBUG          3
-
-#define dprintk(x, y, z, format, arg...) do {                                          \
-       if (z) {                                                                        \
-               if      ((x > MB86A16_ERROR) && (x > y))                                \
-                       printk(KERN_ERR "%s: " format "\n", __func__, ##arg);           \
-               else if ((x > MB86A16_NOTICE) && (x > y))                               \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg);        \
-               else if ((x > MB86A16_INFO) && (x > y))                                 \
-                       printk(KERN_INFO "%s: " format "\n", __func__, ##arg);          \
-               else if ((x > MB86A16_DEBUG) && (x > y))                                \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg);         \
-       } else {                                                                        \
-               if (x > y)                                                              \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while (0)
-
-#define TRACE_IN       dprintk(verbose, MB86A16_DEBUG, 1, "-->()")
-#define TRACE_OUT      dprintk(verbose, MB86A16_DEBUG, 1, "()-->")
-
-static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val)
-{
-       int ret;
-       u8 buf[] = { reg, val };
-
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 2
-       };
-
-       dprintk(verbose, MB86A16_DEBUG, 1,
-               "writing to [0x%02x],Reg[0x%02x],Data[0x%02x]",
-               state->config->demod_address, buf[0], buf[1]);
-
-       ret = i2c_transfer(state->i2c_adap, &msg, 1);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-       ret = i2c_transfer(state->i2c_adap, msg, 2);
-       if (ret != 2) {
-               dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
-                       reg, ret);
-
-               return -EREMOTEIO;
-       }
-       *val = b1[0];
-
-       return ret;
-}
-
-static int CNTM_set(struct mb86a16_state *state,
-                   unsigned char timint1,
-                   unsigned char timint2,
-                   unsigned char cnext)
-{
-       unsigned char val;
-
-       val = (timint1 << 4) | (timint2 << 2) | cnext;
-       if (mb86a16_write(state, MB86A16_CNTMR, val) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int smrt_set(struct mb86a16_state *state, int rate)
-{
-       int tmp ;
-       int m ;
-       unsigned char STOFS0, STOFS1;
-
-       m = 1 << state->deci;
-       tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk;
-
-       STOFS0 = tmp & 0x0ff;
-       STOFS1 = (tmp & 0xf00) >> 8;
-
-       if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) |
-                                      (state->csel << 1) |
-                                       state->rsel) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -1;
-}
-
-static int srst(struct mb86a16_state *state)
-{
-       if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-
-}
-
-static int afcex_data_set(struct mb86a16_state *state,
-                         unsigned char AFCEX_L,
-                         unsigned char AFCEX_H)
-{
-       if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-
-       return -1;
-}
-
-static int afcofs_data_set(struct mb86a16_state *state,
-                          unsigned char AFCEX_L,
-                          unsigned char AFCEX_H)
-{
-       if (mb86a16_write(state, 0x58, AFCEX_L) < 0)
-               goto err;
-       if (mb86a16_write(state, 0x59, AFCEX_H) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int stlp_set(struct mb86a16_state *state,
-                   unsigned char STRAS,
-                   unsigned char STRBS)
-{
-       if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA)
-{
-       if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int initial_set(struct mb86a16_state *state)
-{
-       if (stlp_set(state, 5, 7))
-               goto err;
-
-       udelay(100);
-       if (afcex_data_set(state, 0, 0))
-               goto err;
-
-       udelay(100);
-       if (afcofs_data_set(state, 0, 0))
-               goto err;
-
-       udelay(100);
-       if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0)
-               goto err;
-       if (mb86a16_write(state, 0x2f, 0x21) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0)
-               goto err;
-       if (mb86a16_write(state, 0x54, 0xff) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int S01T_set(struct mb86a16_state *state,
-                   unsigned char s1t,
-                   unsigned s0t)
-{
-       if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-
-static int EN_set(struct mb86a16_state *state,
-                 int cren,
-                 int afcen)
-{
-       unsigned char val;
-
-       val = 0x7a | (cren << 7) | (afcen << 2);
-       if (mb86a16_write(state, 0x49, val) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int AFCEXEN_set(struct mb86a16_state *state,
-                      int afcexen,
-                      int smrt)
-{
-       unsigned char AFCA ;
-
-       if (smrt > 18875)
-               AFCA = 4;
-       else if (smrt > 9375)
-               AFCA = 3;
-       else if (smrt > 2250)
-               AFCA = 2;
-       else
-               AFCA = 1;
-
-       if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int DAGC_data_set(struct mb86a16_state *state,
-                        unsigned char DAGCA,
-                        unsigned char DAGCW)
-{
-       if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static void smrt_info_get(struct mb86a16_state *state, int rate)
-{
-       if (rate >= 37501) {
-               state->deci = 0; state->csel = 0; state->rsel = 0;
-       } else if (rate >= 30001) {
-               state->deci = 0; state->csel = 0; state->rsel = 1;
-       } else if (rate >= 26251) {
-               state->deci = 0; state->csel = 1; state->rsel = 0;
-       } else if (rate >= 22501) {
-               state->deci = 0; state->csel = 1; state->rsel = 1;
-       } else if (rate >= 18751) {
-               state->deci = 1; state->csel = 0; state->rsel = 0;
-       } else if (rate >= 15001) {
-               state->deci = 1; state->csel = 0; state->rsel = 1;
-       } else if (rate >= 13126) {
-               state->deci = 1; state->csel = 1; state->rsel = 0;
-       } else if (rate >= 11251) {
-               state->deci = 1; state->csel = 1; state->rsel = 1;
-       } else if (rate >= 9376) {
-               state->deci = 2; state->csel = 0; state->rsel = 0;
-       } else if (rate >= 7501) {
-               state->deci = 2; state->csel = 0; state->rsel = 1;
-       } else if (rate >= 6563) {
-               state->deci = 2; state->csel = 1; state->rsel = 0;
-       } else if (rate >= 5626) {
-               state->deci = 2; state->csel = 1; state->rsel = 1;
-       } else if (rate >= 4688) {
-               state->deci = 3; state->csel = 0; state->rsel = 0;
-       } else if (rate >= 3751) {
-               state->deci = 3; state->csel = 0; state->rsel = 1;
-       } else if (rate >= 3282) {
-               state->deci = 3; state->csel = 1; state->rsel = 0;
-       } else if (rate >= 2814) {
-               state->deci = 3; state->csel = 1; state->rsel = 1;
-       } else if (rate >= 2344) {
-               state->deci = 4; state->csel = 0; state->rsel = 0;
-       } else if (rate >= 1876) {
-               state->deci = 4; state->csel = 0; state->rsel = 1;
-       } else if (rate >= 1641) {
-               state->deci = 4; state->csel = 1; state->rsel = 0;
-       } else if (rate >= 1407) {
-               state->deci = 4; state->csel = 1; state->rsel = 1;
-       } else if (rate >= 1172) {
-               state->deci = 5; state->csel = 0; state->rsel = 0;
-       } else if (rate >=  939) {
-               state->deci = 5; state->csel = 0; state->rsel = 1;
-       } else if (rate >=  821) {
-               state->deci = 5; state->csel = 1; state->rsel = 0;
-       } else {
-               state->deci = 5; state->csel = 1; state->rsel = 1;
-       }
-
-       if (state->csel == 0)
-               state->master_clk = 92000;
-       else
-               state->master_clk = 61333;
-
-}
-
-static int signal_det(struct mb86a16_state *state,
-                     int smrt,
-                     unsigned char *SIG)
-{
-
-       int ret ;
-       int smrtd ;
-       int wait_sym ;
-
-       u32 wait_t;
-       unsigned char S[3] ;
-       int i ;
-
-       if (*SIG > 45) {
-               if (CNTM_set(state, 2, 1, 2) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
-                       return -1;
-               }
-               wait_sym = 40000;
-       } else {
-               if (CNTM_set(state, 3, 1, 2) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
-                       return -1;
-               }
-               wait_sym = 80000;
-       }
-       for (i = 0; i < 3; i++) {
-               if (i == 0)
-                       smrtd = smrt * 98 / 100;
-               else if (i == 1)
-                       smrtd = smrt;
-               else
-                       smrtd = smrt * 102 / 100;
-               smrt_info_get(state, smrtd);
-               smrt_set(state, smrtd);
-               srst(state);
-               wait_t = (wait_sym + 99 * smrtd / 100) / smrtd;
-               if (wait_t == 0)
-                       wait_t = 1;
-               msleep_interruptible(10);
-               if (mb86a16_read(state, 0x37, &(S[i])) != 2) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-                       return -EREMOTEIO;
-               }
-       }
-       if ((S[1] > S[0] * 112 / 100) &&
-           (S[1] > S[2] * 112 / 100)) {
-
-               ret = 1;
-       } else {
-               ret = 0;
-       }
-       *SIG = S[1];
-
-       if (CNTM_set(state, 0, 1, 2) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
-               return -1;
-       }
-
-       return ret;
-}
-
-static int rf_val_set(struct mb86a16_state *state,
-                     int f,
-                     int smrt,
-                     unsigned char R)
-{
-       unsigned char C, F, B;
-       int M;
-       unsigned char rf_val[5];
-       int ack = -1;
-
-       if (smrt > 37750)
-               C = 1;
-       else if (smrt > 18875)
-               C = 2;
-       else if (smrt > 5500)
-               C = 3;
-       else
-               C = 4;
-
-       if (smrt > 30500)
-               F = 3;
-       else if (smrt > 9375)
-               F = 1;
-       else if (smrt > 4625)
-               F = 0;
-       else
-               F = 2;
-
-       if (f < 1060)
-               B = 0;
-       else if (f < 1175)
-               B = 1;
-       else if (f < 1305)
-               B = 2;
-       else if (f < 1435)
-               B = 3;
-       else if (f < 1570)
-               B = 4;
-       else if (f < 1715)
-               B = 5;
-       else if (f < 1845)
-               B = 6;
-       else if (f < 1980)
-               B = 7;
-       else if (f < 2080)
-               B = 8;
-       else
-               B = 9;
-
-       M = f * (1 << R) / 2;
-
-       rf_val[0] = 0x01 | (C << 3) | (F << 1);
-       rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12);
-       rf_val[2] = (M & 0x00ff0) >> 4;
-       rf_val[3] = ((M & 0x0000f) << 4) | B;
-
-       /* Frequency Set */
-       if (mb86a16_write(state, 0x21, rf_val[0]) < 0)
-               ack = 0;
-       if (mb86a16_write(state, 0x22, rf_val[1]) < 0)
-               ack = 0;
-       if (mb86a16_write(state, 0x23, rf_val[2]) < 0)
-               ack = 0;
-       if (mb86a16_write(state, 0x24, rf_val[3]) < 0)
-               ack = 0;
-       if (mb86a16_write(state, 0x25, 0x01) < 0)
-               ack = 0;
-       if (ack == 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int afcerr_chk(struct mb86a16_state *state)
-{
-       unsigned char AFCM_L, AFCM_H ;
-       int AFCM ;
-       int afcm, afcerr ;
-
-       if (mb86a16_read(state, 0x0e, &AFCM_L) != 2)
-               goto err;
-       if (mb86a16_read(state, 0x0f, &AFCM_H) != 2)
-               goto err;
-
-       AFCM = (AFCM_H << 8) + AFCM_L;
-
-       if (AFCM > 2048)
-               afcm = AFCM - 4096;
-       else
-               afcm = AFCM;
-       afcerr = afcm * state->master_clk / 8192;
-
-       return afcerr;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int dagcm_val_get(struct mb86a16_state *state)
-{
-       int DAGCM;
-       unsigned char DAGCM_H, DAGCM_L;
-
-       if (mb86a16_read(state, 0x45, &DAGCM_L) != 2)
-               goto err;
-       if (mb86a16_read(state, 0x46, &DAGCM_H) != 2)
-               goto err;
-
-       DAGCM = (DAGCM_H << 8) + DAGCM_L;
-
-       return DAGCM;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       u8 stat, stat2;
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       *status = 0;
-
-       if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2)
-               goto err;
-       if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2)
-               goto err;
-       if ((stat > 25) && (stat2 > 25))
-               *status |= FE_HAS_SIGNAL;
-       if ((stat > 45) && (stat2 > 45))
-               *status |= FE_HAS_CARRIER;
-
-       if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2)
-               goto err;
-
-       if (stat & 0x01)
-               *status |= FE_HAS_SYNC;
-       if (stat & 0x01)
-               *status |= FE_HAS_VITERBI;
-
-       if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2)
-               goto err;
-
-       if ((stat & 0x0f) && (*status & FE_HAS_VITERBI))
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int sync_chk(struct mb86a16_state *state,
-                   unsigned char *VIRM)
-{
-       unsigned char val;
-       int sync;
-
-       if (mb86a16_read(state, 0x0d, &val) != 2)
-               goto err;
-
-       dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val);
-       sync = val & 0x01;
-       *VIRM = (val & 0x1c) >> 2;
-
-       return sync;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-
-}
-
-static int freqerr_chk(struct mb86a16_state *state,
-                      int fTP,
-                      int smrt,
-                      int unit)
-{
-       unsigned char CRM, AFCML, AFCMH;
-       unsigned char temp1, temp2, temp3;
-       int crm, afcm, AFCM;
-       int crrerr, afcerr;             /* kHz */
-       int frqerr;                     /* MHz */
-       int afcen, afcexen = 0;
-       int R, M, fOSC, fOSC_OFS;
-
-       if (mb86a16_read(state, 0x43, &CRM) != 2)
-               goto err;
-
-       if (CRM > 127)
-               crm = CRM - 256;
-       else
-               crm = CRM;
-
-       crrerr = smrt * crm / 256;
-       if (mb86a16_read(state, 0x49, &temp1) != 2)
-               goto err;
-
-       afcen = (temp1 & 0x04) >> 2;
-       if (afcen == 0) {
-               if (mb86a16_read(state, 0x2a, &temp1) != 2)
-                       goto err;
-               afcexen = (temp1 & 0x20) >> 5;
-       }
-
-       if (afcen == 1) {
-               if (mb86a16_read(state, 0x0e, &AFCML) != 2)
-                       goto err;
-               if (mb86a16_read(state, 0x0f, &AFCMH) != 2)
-                       goto err;
-       } else if (afcexen == 1) {
-               if (mb86a16_read(state, 0x2b, &AFCML) != 2)
-                       goto err;
-               if (mb86a16_read(state, 0x2c, &AFCMH) != 2)
-                       goto err;
-       }
-       if ((afcen == 1) || (afcexen == 1)) {
-               smrt_info_get(state, smrt);
-               AFCM = ((AFCMH & 0x01) << 8) + AFCML;
-               if (AFCM > 255)
-                       afcm = AFCM - 512;
-               else
-                       afcm = AFCM;
-
-               afcerr = afcm * state->master_clk / 8192;
-       } else
-               afcerr = 0;
-
-       if (mb86a16_read(state, 0x22, &temp1) != 2)
-               goto err;
-       if (mb86a16_read(state, 0x23, &temp2) != 2)
-               goto err;
-       if (mb86a16_read(state, 0x24, &temp3) != 2)
-               goto err;
-
-       R = (temp1 & 0xe0) >> 5;
-       M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4);
-       if (R == 0)
-               fOSC = 2 * M;
-       else
-               fOSC = M;
-
-       fOSC_OFS = fOSC - fTP;
-
-       if (unit == 0) {        /* MHz */
-               if (crrerr + afcerr + fOSC_OFS * 1000 >= 0)
-                       frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000;
-               else
-                       frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000;
-       } else {        /* kHz */
-               frqerr = crrerr + afcerr + fOSC_OFS * 1000;
-       }
-
-       return frqerr;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt)
-{
-       unsigned char R;
-
-       if (smrt > 9375)
-               R = 0;
-       else
-               R = 1;
-
-       return R;
-}
-
-static void swp_info_get(struct mb86a16_state *state,
-                        int fOSC_start,
-                        int smrt,
-                        int v, int R,
-                        int swp_ofs,
-                        int *fOSC,
-                        int *afcex_freq,
-                        unsigned char *AFCEX_L,
-                        unsigned char *AFCEX_H)
-{
-       int AFCEX ;
-       int crnt_swp_freq ;
-
-       crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs;
-
-       if (R == 0)
-               *fOSC = (crnt_swp_freq + 1000) / 2000 * 2;
-       else
-               *fOSC = (crnt_swp_freq + 500) / 1000;
-
-       if (*fOSC >= crnt_swp_freq)
-               *afcex_freq = *fOSC * 1000 - crnt_swp_freq;
-       else
-               *afcex_freq = crnt_swp_freq - *fOSC * 1000;
-
-       AFCEX = *afcex_freq * 8192 / state->master_clk;
-       *AFCEX_L =  AFCEX & 0x00ff;
-       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
-}
-
-
-static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V,  int vmax, int vmin,
-                              int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1)
-{
-       int swp_freq ;
-
-       if ((i % 2 == 1) && (v <= vmax)) {
-               /* positive v (case 1) */
-               if ((v - 1 == vmin)                             &&
-                   (*(V + 30 + v) >= 0)                        &&
-                   (*(V + 30 + v - 1) >= 0)                    &&
-                   (*(V + 30 + v - 1) > *(V + 30 + v))         &&
-                   (*(V + 30 + v - 1) > SIGMIN)) {
-
-                       swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
-                       *SIG1 = *(V + 30 + v - 1);
-               } else if ((v == vmax)                          &&
-                          (*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v - 1) >= 0)             &&
-                          (*(V + 30 + v) > *(V + 30 + v - 1))  &&
-                          (*(V + 30 + v) > SIGMIN)) {
-                       /* (case 2) */
-                       swp_freq = fOSC * 1000 + afcex_freq;
-                       *SIG1 = *(V + 30 + v);
-               } else if ((*(V + 30 + v) > 0)                  &&
-                          (*(V + 30 + v - 1) > 0)              &&
-                          (*(V + 30 + v - 2) > 0)              &&
-                          (*(V + 30 + v - 3) > 0)              &&
-                          (*(V + 30 + v - 1) > *(V + 30 + v))  &&
-                          (*(V + 30 + v - 2) > *(V + 30 + v - 3)) &&
-                          ((*(V + 30 + v - 1) > SIGMIN)        ||
-                          (*(V + 30 + v - 2) > SIGMIN))) {
-                       /* (case 3) */
-                       if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) {
-                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
-                               *SIG1 = *(V + 30 + v - 1);
-                       } else {
-                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2;
-                               *SIG1 = *(V + 30 + v - 2);
-                       }
-               } else if ((v == vmax)                          &&
-                          (*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v - 1) >= 0)             &&
-                          (*(V + 30 + v - 2) >= 0)             &&
-                          (*(V + 30 + v) > *(V + 30 + v - 2))  &&
-                          (*(V + 30 + v - 1) > *(V + 30 + v - 2)) &&
-                          ((*(V + 30 + v) > SIGMIN)            ||
-                          (*(V + 30 + v - 1) > SIGMIN))) {
-                       /* (case 4) */
-                       if (*(V + 30 + v) >= *(V + 30 + v - 1)) {
-                               swp_freq = fOSC * 1000 + afcex_freq;
-                               *SIG1 = *(V + 30 + v);
-                       } else {
-                               swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
-                               *SIG1 = *(V + 30 + v - 1);
-                       }
-               } else  {
-                       swp_freq = -1 ;
-               }
-       } else if ((i % 2 == 0) && (v >= vmin)) {
-               /* Negative v (case 1) */
-               if ((*(V + 30 + v) > 0)                         &&
-                   (*(V + 30 + v + 1) > 0)                     &&
-                   (*(V + 30 + v + 2) > 0)                     &&
-                   (*(V + 30 + v + 1) > *(V + 30 + v))         &&
-                   (*(V + 30 + v + 1) > *(V + 30 + v + 2))     &&
-                   (*(V + 30 + v + 1) > SIGMIN)) {
-
-                       swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
-                       *SIG1 = *(V + 30 + v + 1);
-               } else if ((v + 1 == vmax)                      &&
-                          (*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v + 1) >= 0)             &&
-                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
-                          (*(V + 30 + v + 1) > SIGMIN)) {
-                       /* (case 2) */
-                       swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
-                       *SIG1 = *(V + 30 + v);
-               } else if ((v == vmin)                          &&
-                          (*(V + 30 + v) > 0)                  &&
-                          (*(V + 30 + v + 1) > 0)              &&
-                          (*(V + 30 + v + 2) > 0)              &&
-                          (*(V + 30 + v) > *(V + 30 + v + 1))  &&
-                          (*(V + 30 + v) > *(V + 30 + v + 2))  &&
-                          (*(V + 30 + v) > SIGMIN)) {
-                       /* (case 3) */
-                       swp_freq = fOSC * 1000 + afcex_freq;
-                       *SIG1 = *(V + 30 + v);
-               } else if ((*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v + 1) >= 0)             &&
-                          (*(V + 30 + v + 2) >= 0)             &&
-                          (*(V + 30 + v + 3) >= 0)             &&
-                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
-                          (*(V + 30 + v + 2) > *(V + 30 + v + 3)) &&
-                          ((*(V + 30 + v + 1) > SIGMIN)        ||
-                           (*(V + 30 + v + 2) > SIGMIN))) {
-                       /* (case 4) */
-                       if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
-                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
-                               *SIG1 = *(V + 30 + v + 1);
-                       } else {
-                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
-                               *SIG1 = *(V + 30 + v + 2);
-                       }
-               } else if ((*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v + 1) >= 0)             &&
-                          (*(V + 30 + v + 2) >= 0)             &&
-                          (*(V + 30 + v + 3) >= 0)             &&
-                          (*(V + 30 + v) > *(V + 30 + v + 2))  &&
-                          (*(V + 30 + v + 1) > *(V + 30 + v + 2)) &&
-                          (*(V + 30 + v) > *(V + 30 + v + 3))  &&
-                          (*(V + 30 + v + 1) > *(V + 30 + v + 3)) &&
-                          ((*(V + 30 + v) > SIGMIN)            ||
-                           (*(V + 30 + v + 1) > SIGMIN))) {
-                       /* (case 5) */
-                       if (*(V + 30 + v) >= *(V + 30 + v + 1)) {
-                               swp_freq = fOSC * 1000 + afcex_freq;
-                               *SIG1 = *(V + 30 + v);
-                       } else {
-                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
-                               *SIG1 = *(V + 30 + v + 1);
-                       }
-               } else if ((v + 2 == vmin)                      &&
-                          (*(V + 30 + v) >= 0)                 &&
-                          (*(V + 30 + v + 1) >= 0)             &&
-                          (*(V + 30 + v + 2) >= 0)             &&
-                          (*(V + 30 + v + 1) > *(V + 30 + v))  &&
-                          (*(V + 30 + v + 2) > *(V + 30 + v))  &&
-                          ((*(V + 30 + v + 1) > SIGMIN)        ||
-                           (*(V + 30 + v + 2) > SIGMIN))) {
-                       /* (case 6) */
-                       if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
-                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
-                               *SIG1 = *(V + 30 + v + 1);
-                       } else {
-                               swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
-                               *SIG1 = *(V + 30 + v + 2);
-                       }
-               } else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) {
-                       swp_freq = fOSC * 1000;
-                       *SIG1 = *(V + 30 + v);
-               } else
-                       swp_freq = -1;
-       } else
-               swp_freq = -1;
-
-       return swp_freq;
-}
-
-static void swp_info_get2(struct mb86a16_state *state,
-                         int smrt,
-                         int R,
-                         int swp_freq,
-                         int *afcex_freq,
-                         int *fOSC,
-                         unsigned char *AFCEX_L,
-                         unsigned char *AFCEX_H)
-{
-       int AFCEX ;
-
-       if (R == 0)
-               *fOSC = (swp_freq + 1000) / 2000 * 2;
-       else
-               *fOSC = (swp_freq + 500) / 1000;
-
-       if (*fOSC >= swp_freq)
-               *afcex_freq = *fOSC * 1000 - swp_freq;
-       else
-               *afcex_freq = swp_freq - *fOSC * 1000;
-
-       AFCEX = *afcex_freq * 8192 / state->master_clk;
-       *AFCEX_L =  AFCEX & 0x00ff;
-       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
-}
-
-static void afcex_info_get(struct mb86a16_state *state,
-                          int afcex_freq,
-                          unsigned char *AFCEX_L,
-                          unsigned char *AFCEX_H)
-{
-       int AFCEX ;
-
-       AFCEX = afcex_freq * 8192 / state->master_clk;
-       *AFCEX_L =  AFCEX & 0x00ff;
-       *AFCEX_H = (AFCEX & 0x0f00) >> 8;
-}
-
-static int SEQ_set(struct mb86a16_state *state, unsigned char loop)
-{
-       /* SLOCK0 = 0 */
-       if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV)
-{
-       /* Viterbi Rate, IQ Settings */
-       if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int FEC_srst(struct mb86a16_state *state)
-{
-       if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int S2T_set(struct mb86a16_state *state, unsigned char S2T)
-{
-       if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T)
-{
-       if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-
-static int mb86a16_set_fe(struct mb86a16_state *state)
-{
-       u8 agcval, cnmval;
-
-       int i, j;
-       int fOSC = 0;
-       int fOSC_start = 0;
-       int wait_t;
-       int fcp;
-       int swp_ofs;
-       int V[60];
-       u8 SIG1MIN;
-
-       unsigned char CREN, AFCEN, AFCEXEN;
-       unsigned char SIG1;
-       unsigned char TIMINT1, TIMINT2, TIMEXT;
-       unsigned char S0T, S1T;
-       unsigned char S2T;
-/*     unsigned char S2T, S3T; */
-       unsigned char S4T, S5T;
-       unsigned char AFCEX_L, AFCEX_H;
-       unsigned char R;
-       unsigned char VIRM;
-       unsigned char ETH, VIA;
-       unsigned char junk;
-
-       int loop;
-       int ftemp;
-       int v, vmax, vmin;
-       int vmax_his, vmin_his;
-       int swp_freq, prev_swp_freq[20];
-       int prev_freq_num;
-       int signal_dupl;
-       int afcex_freq;
-       int signal;
-       int afcerr;
-       int temp_freq, delta_freq;
-       int dagcm[4];
-       int smrt_d;
-/*     int freq_err; */
-       int n;
-       int ret = -1;
-       int sync;
-
-       dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate);
-
-       fcp = 3000;
-       swp_ofs = state->srate / 4;
-
-       for (i = 0; i < 60; i++)
-               V[i] = -1;
-
-       for (i = 0; i < 20; i++)
-               prev_swp_freq[i] = 0;
-
-       SIG1MIN = 25;
-
-       for (n = 0; ((n < 3) && (ret == -1)); n++) {
-               SEQ_set(state, 0);
-               iq_vt_set(state, 0);
-
-               CREN = 0;
-               AFCEN = 0;
-               AFCEXEN = 1;
-               TIMINT1 = 0;
-               TIMINT2 = 1;
-               TIMEXT = 2;
-               S1T = 0;
-               S0T = 0;
-
-               if (initial_set(state) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "initial set failed");
-                       return -1;
-               }
-               if (DAGC_data_set(state, 3, 2) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
-                       return -1;
-               }
-               if (EN_set(state, CREN, AFCEN) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
-                       return -1; /* (0, 0) */
-               }
-               if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
-                       return -1; /* (1, smrt) = (1, symbolrate) */
-               }
-               if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error");
-                       return -1; /* (0, 1, 2) */
-               }
-               if (S01T_set(state, S1T, S0T) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
-                       return -1; /* (0, 0) */
-               }
-               smrt_info_get(state, state->srate);
-               if (smrt_set(state, state->srate) < 0) {
-                       dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error");
-                       return -1;
-               }
-
-               R = vco_dev_get(state, state->srate);
-               if (R == 1)
-                       fOSC_start = state->frequency;
-
-               else if (R == 0) {
-                       if (state->frequency % 2 == 0) {
-                               fOSC_start = state->frequency;
-                       } else {
-                               fOSC_start = state->frequency + 1;
-                               if (fOSC_start > 2150)
-                                       fOSC_start = state->frequency - 1;
-                       }
-               }
-               loop = 1;
-               ftemp = fOSC_start * 1000;
-               vmax = 0 ;
-               while (loop == 1) {
-                       ftemp = ftemp + swp_ofs;
-                       vmax++;
-
-                       /* Upper bound */
-                       if (ftemp > 2150000) {
-                               loop = 0;
-                               vmax--;
-                       } else {
-                               if ((ftemp == 2150000) ||
-                                   (ftemp - state->frequency * 1000 >= fcp + state->srate / 4))
-                                       loop = 0;
-                       }
-               }
-
-               loop = 1;
-               ftemp = fOSC_start * 1000;
-               vmin = 0 ;
-               while (loop == 1) {
-                       ftemp = ftemp - swp_ofs;
-                       vmin--;
-
-                       /* Lower bound */
-                       if (ftemp < 950000) {
-                               loop = 0;
-                               vmin++;
-                       } else {
-                               if ((ftemp == 950000) ||
-                                   (state->frequency * 1000 - ftemp >= fcp + state->srate / 4))
-                                       loop = 0;
-                       }
-               }
-
-               wait_t = (8000 + state->srate / 2) / state->srate;
-               if (wait_t == 0)
-                       wait_t = 1;
-
-               i = 0;
-               j = 0;
-               prev_freq_num = 0;
-               loop = 1;
-               signal = 0;
-               vmax_his = 0;
-               vmin_his = 0;
-               v = 0;
-
-               while (loop == 1) {
-                       swp_info_get(state, fOSC_start, state->srate,
-                                    v, R, swp_ofs, &fOSC,
-                                    &afcex_freq, &AFCEX_L, &AFCEX_H);
-
-                       udelay(100);
-                       if (rf_val_set(state, fOSC, state->srate, R) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
-                               return -1;
-                       }
-                       udelay(100);
-                       if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
-                               return -1;
-                       }
-                       if (srst(state) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "srst error");
-                               return -1;
-                       }
-                       msleep_interruptible(wait_t);
-
-                       if (mb86a16_read(state, 0x37, &SIG1) != 2) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-                               return -1;
-                       }
-                       V[30 + v] = SIG1 ;
-                       swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin,
-                                                     SIG1MIN, fOSC, afcex_freq,
-                                                     swp_ofs, &SIG1);  /* changed */
-
-                       signal_dupl = 0;
-                       for (j = 0; j < prev_freq_num; j++) {
-                               if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) {
-                                       signal_dupl = 1;
-                                       dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j);
-                               }
-                       }
-                       if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) {
-                               dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate);
-                               prev_swp_freq[prev_freq_num] = swp_freq;
-                               prev_freq_num++;
-                               swp_info_get2(state, state->srate, R, swp_freq,
-                                             &afcex_freq, &fOSC,
-                                             &AFCEX_L, &AFCEX_H);
-
-                               if (rf_val_set(state, fOSC, state->srate, R) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
-                                       return -1;
-                               }
-                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
-                                       return -1;
-                               }
-                               signal = signal_det(state, state->srate, &SIG1);
-                               if (signal == 1) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****");
-                                       loop = 0;
-                               } else {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again...");
-                                       smrt_info_get(state, state->srate);
-                                       if (smrt_set(state, state->srate) < 0) {
-                                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
-                                               return -1;
-                                       }
-                               }
-                       }
-                       if (v > vmax)
-                               vmax_his = 1 ;
-                       if (v < vmin)
-                               vmin_his = 1 ;
-                       i++;
-
-                       if ((i % 2 == 1) && (vmax_his == 1))
-                               i++;
-                       if ((i % 2 == 0) && (vmin_his == 1))
-                               i++;
-
-                       if (i % 2 == 1)
-                               v = (i + 1) / 2;
-                       else
-                               v = -i / 2;
-
-                       if ((vmax_his == 1) && (vmin_his == 1))
-                               loop = 0 ;
-               }
-
-               if (signal == 1) {
-                       dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check");
-                       S1T = 7 ;
-                       S0T = 1 ;
-                       CREN = 0 ;
-                       AFCEN = 1 ;
-                       AFCEXEN = 0 ;
-
-                       if (S01T_set(state, S1T, S0T) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
-                               return -1;
-                       }
-                       smrt_info_get(state, state->srate);
-                       if (smrt_set(state, state->srate) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
-                               return -1;
-                       }
-                       if (EN_set(state, CREN, AFCEN) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
-                               return -1;
-                       }
-                       if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
-                               return -1;
-                       }
-                       afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H);
-                       if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error");
-                               return -1;
-                       }
-                       if (srst(state) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "srst error");
-                               return -1;
-                       }
-                       /* delay 4~200 */
-                       wait_t = 200000 / state->master_clk + 200000 / state->srate;
-                       msleep(wait_t);
-                       afcerr = afcerr_chk(state);
-                       if (afcerr == -1)
-                               return -1;
-
-                       swp_freq = fOSC * 1000 + afcerr ;
-                       AFCEXEN = 1 ;
-                       if (state->srate >= 1500)
-                               smrt_d = state->srate / 3;
-                       else
-                               smrt_d = state->srate / 2;
-                       smrt_info_get(state, smrt_d);
-                       if (smrt_set(state, smrt_d) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
-                               return -1;
-                       }
-                       if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
-                               return -1;
-                       }
-                       R = vco_dev_get(state, smrt_d);
-                       if (DAGC_data_set(state, 2, 0) < 0) {
-                               dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
-                               return -1;
-                       }
-                       for (i = 0; i < 3; i++) {
-                               temp_freq = swp_freq + (i - 1) * state->srate / 8;
-                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
-                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
-                                       return -1;
-                               }
-                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
-                                       return -1;
-                               }
-                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
-                               msleep(wait_t);
-                               dagcm[i] = dagcm_val_get(state);
-                       }
-                       if ((dagcm[0] > dagcm[1]) &&
-                           (dagcm[0] > dagcm[2]) &&
-                           (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) {
-
-                               temp_freq = swp_freq - 2 * state->srate / 8;
-                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
-                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
-                                       return -1;
-                               }
-                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
-                                       return -1;
-                               }
-                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
-                               msleep(wait_t);
-                               dagcm[3] = dagcm_val_get(state);
-                               if (dagcm[3] > dagcm[1])
-                                       delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300;
-                               else
-                                       delta_freq = 0;
-                       } else if ((dagcm[2] > dagcm[1]) &&
-                                  (dagcm[2] > dagcm[0]) &&
-                                  (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) {
-
-                               temp_freq = swp_freq + 2 * state->srate / 8;
-                               swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
-                               if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set");
-                                       return -1;
-                               }
-                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
-                                       return -1;
-                               }
-                               wait_t = 200000 / state->master_clk + 40000 / smrt_d;
-                               msleep(wait_t);
-                               dagcm[3] = dagcm_val_get(state);
-                               if (dagcm[3] > dagcm[1])
-                                       delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300;
-                               else
-                                       delta_freq = 0 ;
-
-                       } else {
-                               delta_freq = 0 ;
-                       }
-                       dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq);
-                       swp_freq += delta_freq;
-                       dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq);
-                       if (ABS(state->frequency * 1000 - swp_freq) > 3800) {
-                               dprintk(verbose, MB86A16_INFO, 1, "NO  --  SIGNAL !");
-                       } else {
-
-                               S1T = 0;
-                               S0T = 3;
-                               CREN = 1;
-                               AFCEN = 0;
-                               AFCEXEN = 1;
-
-                               if (S01T_set(state, S1T, S0T) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
-                                       return -1;
-                               }
-                               if (DAGC_data_set(state, 0, 0) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
-                                       return -1;
-                               }
-                               R = vco_dev_get(state, state->srate);
-                               smrt_info_get(state, state->srate);
-                               if (smrt_set(state, state->srate) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
-                                       return -1;
-                               }
-                               if (EN_set(state, CREN, AFCEN) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
-                                       return -1;
-                               }
-                               if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
-                                       return -1;
-                               }
-                               swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
-                               if (rf_val_set(state, fOSC, state->srate, R) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
-                                       return -1;
-                               }
-                               if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
-                                       return -1;
-                               }
-                               if (srst(state) < 0) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "srst error");
-                                       return -1;
-                               }
-                               wait_t = 7 + (10000 + state->srate / 2) / state->srate;
-                               if (wait_t == 0)
-                                       wait_t = 1;
-                               msleep_interruptible(wait_t);
-                               if (mb86a16_read(state, 0x37, &SIG1) != 2) {
-                                       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-                                       return -EREMOTEIO;
-                               }
-
-                               if (SIG1 > 110) {
-                                       S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6;
-                                       wait_t = 7 + (917504 + state->srate / 2) / state->srate;
-                               } else if (SIG1 > 105) {
-                                       S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
-                                       wait_t = 7 + (1048576 + state->srate / 2) / state->srate;
-                               } else if (SIG1 > 85) {
-                                       S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
-                                       wait_t = 7 + (1310720 + state->srate / 2) / state->srate;
-                               } else if (SIG1 > 65) {
-                                       S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
-                                       wait_t = 7 + (1572864 + state->srate / 2) / state->srate;
-                               } else {
-                                       S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
-                                       wait_t = 7 + (2097152 + state->srate / 2) / state->srate;
-                               }
-                               wait_t *= 2; /* FOS */
-                               S2T_set(state, S2T);
-                               S45T_set(state, S4T, S5T);
-                               Vi_set(state, ETH, VIA);
-                               srst(state);
-                               msleep_interruptible(wait_t);
-                               sync = sync_chk(state, &VIRM);
-                               dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync);
-                               if (VIRM) {
-                                       if (VIRM == 4) {
-                                               /* 5/6 */
-                                               if (SIG1 > 110)
-                                                       wait_t = (786432 + state->srate / 2) / state->srate;
-                                               else
-                                                       wait_t = (1572864 + state->srate / 2) / state->srate;
-                                               if (state->srate < 5000)
-                                                       /* FIXME ! , should be a long wait ! */
-                                                       msleep_interruptible(wait_t);
-                                               else
-                                                       msleep_interruptible(wait_t);
-
-                                               if (sync_chk(state, &junk) == 0) {
-                                                       iq_vt_set(state, 1);
-                                                       FEC_srst(state);
-                                               }
-                                       }
-                                       /* 1/2, 2/3, 3/4, 7/8 */
-                                       if (SIG1 > 110)
-                                               wait_t = (786432 + state->srate / 2) / state->srate;
-                                       else
-                                               wait_t = (1572864 + state->srate / 2) / state->srate;
-                                       msleep_interruptible(wait_t);
-                                       SEQ_set(state, 1);
-                               } else {
-                                       dprintk(verbose, MB86A16_INFO, 1, "NO  -- SYNC");
-                                       SEQ_set(state, 1);
-                                       ret = -1;
-                               }
-                       }
-               } else {
-                       dprintk(verbose, MB86A16_INFO, 1, "NO  -- SIGNAL");
-                       ret = -1;
-               }
-
-               sync = sync_chk(state, &junk);
-               if (sync) {
-                       dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******");
-                       freqerr_chk(state, state->frequency, state->srate, 1);
-                       ret = 0;
-                       break;
-               }
-       }
-
-       mb86a16_read(state, 0x15, &agcval);
-       mb86a16_read(state, 0x26, &cnmval);
-       dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval);
-
-       return ret;
-}
-
-static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
-                                  struct dvb_diseqc_master_cmd *cmd)
-{
-       struct mb86a16_state *state = fe->demodulator_priv;
-       int i;
-       u8 regs;
-
-       if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
-               goto err;
-
-       regs = 0x18;
-
-       if (cmd->msg_len > 5 || cmd->msg_len < 4)
-               return -EINVAL;
-
-       for (i = 0; i < cmd->msg_len; i++) {
-               if (mb86a16_write(state, regs, cmd->msg[i]) < 0)
-                       goto err;
-
-               regs++;
-       }
-       i += 0x90;
-
-       msleep_interruptible(10);
-
-       if (mb86a16_write(state, MB86A16_DCC1, i) < 0)
-               goto err;
-       if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
-{
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       switch (burst) {
-       case SEC_MINI_A:
-               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
-                                                      MB86A16_DCC1_TBEN  |
-                                                      MB86A16_DCC1_TBO) < 0)
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
-                       goto err;
-               break;
-       case SEC_MINI_B:
-               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
-                                                      MB86A16_DCC1_TBEN) < 0)
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
-                       goto err;
-               break;
-       }
-
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0)
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
-                                                      MB86A16_DCC1_CTOE) < 0)
-
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
-                       goto err;
-               break;
-       case SEC_TONE_OFF:
-               if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
-                       goto err;
-               if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
-                       goto err;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       state->frequency = p->frequency / 1000;
-       state->srate = p->symbol_rate / 1000;
-
-       if (!mb86a16_set_fe(state)) {
-               dprintk(verbose, MB86A16_ERROR, 1, "Successfully acquired LOCK");
-               return DVBFE_ALGO_SEARCH_SUCCESS;
-       }
-
-       dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!");
-       return DVBFE_ALGO_SEARCH_FAILED;
-}
-
-static void mb86a16_release(struct dvb_frontend *fe)
-{
-       struct mb86a16_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static int mb86a16_init(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int mb86a16_sleep(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst;
-       u32 timer;
-
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       *ber = 0;
-       if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2)
-               goto err;
-       if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2)
-               goto err;
-       if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2)
-               goto err;
-       if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2)
-               goto err;
-       if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2)
-               goto err;
-       /* BER monitor invalid when BER_EN = 0  */
-       if (ber_mon & 0x04) {
-               /* coarse, fast calculation     */
-               *ber = ber_tab & 0x1f;
-               dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber);
-               if (ber_mon & 0x01) {
-                       /*
-                        * BER_SEL = 1, The monitored BER is the estimated
-                        * value with a Reed-Solomon decoder error amount at
-                        * the deinterleaver output.
-                        * monitored BER is expressed as a 20 bit output in total
-                        */
-                       ber_rst = ber_mon >> 3;
-                       *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
-                       if (ber_rst == 0)
-                               timer =  12500000;
-                       if (ber_rst == 1)
-                               timer =  25000000;
-                       if (ber_rst == 2)
-                               timer =  50000000;
-                       if (ber_rst == 3)
-                               timer = 100000000;
-
-                       *ber /= timer;
-                       dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
-               } else {
-                       /*
-                        * BER_SEL = 0, The monitored BER is the estimated
-                        * value with a Viterbi decoder error amount at the
-                        * QPSK demodulator output.
-                        * monitored BER is expressed as a 24 bit output in total
-                        */
-                       ber_tim = ber_mon >> 1;
-                       *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
-                       if (ber_tim == 0)
-                               timer = 16;
-                       if (ber_tim == 1)
-                               timer = 24;
-
-                       *ber /= 2 ^ timer;
-                       dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
-               }
-       }
-       return 0;
-err:
-       dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-       return -EREMOTEIO;
-}
-
-static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       u8 agcm = 0;
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       *strength = 0;
-       if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       *strength = ((0xff - agcm) * 100) / 256;
-       dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength);
-       *strength = (0xffff - 0xff) + agcm;
-
-       return 0;
-}
-
-struct cnr {
-       u8 cn_reg;
-       u8 cn_val;
-};
-
-static const struct cnr cnr_tab[] = {
-       {  35,  2 },
-       {  40,  3 },
-       {  50,  4 },
-       {  60,  5 },
-       {  70,  6 },
-       {  80,  7 },
-       {  92,  8 },
-       { 103,  9 },
-       { 115, 10 },
-       { 138, 12 },
-       { 162, 15 },
-       { 180, 18 },
-       { 185, 19 },
-       { 189, 20 },
-       { 195, 22 },
-       { 199, 24 },
-       { 201, 25 },
-       { 202, 26 },
-       { 203, 27 },
-       { 205, 28 },
-       { 208, 30 }
-};
-
-static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct mb86a16_state *state = fe->demodulator_priv;
-       int i = 0;
-       int low_tide = 2, high_tide = 30, q_level;
-       u8  cn;
-
-       *snr = 0;
-       if (mb86a16_read(state, 0x26, &cn) != 2) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) {
-               if (cn < cnr_tab[i].cn_reg) {
-                       *snr = cnr_tab[i].cn_val;
-                       break;
-               }
-       }
-       q_level = (*snr * 100) / (high_tide - low_tide);
-       dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level);
-       *snr = (0xffff - 0xff) + *snr;
-
-       return 0;
-}
-
-static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       u8 dist;
-       struct mb86a16_state *state = fe->demodulator_priv;
-
-       if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) {
-               dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
-               return -EREMOTEIO;
-       }
-       *ucblocks = dist;
-
-       return 0;
-}
-
-static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static struct dvb_frontend_ops mb86a16_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "Fujitsu MB86A16 DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 3000,
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,
-               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
-                                         FE_CAN_FEC_7_8 | FE_CAN_QPSK    |
-                                         FE_CAN_FEC_AUTO
-       },
-       .release                        = mb86a16_release,
-
-       .get_frontend_algo              = mb86a16_frontend_algo,
-       .search                         = mb86a16_search,
-       .init                           = mb86a16_init,
-       .sleep                          = mb86a16_sleep,
-       .read_status                    = mb86a16_read_status,
-
-       .read_ber                       = mb86a16_read_ber,
-       .read_signal_strength           = mb86a16_read_signal_strength,
-       .read_snr                       = mb86a16_read_snr,
-       .read_ucblocks                  = mb86a16_read_ucblocks,
-
-       .diseqc_send_master_cmd         = mb86a16_send_diseqc_msg,
-       .diseqc_send_burst              = mb86a16_send_diseqc_burst,
-       .set_tone                       = mb86a16_set_tone,
-};
-
-struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
-                                   struct i2c_adapter *i2c_adap)
-{
-       u8 dev_id = 0;
-       struct mb86a16_state *state = NULL;
-
-       state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->config = config;
-       state->i2c_adap = i2c_adap;
-
-       mb86a16_read(state, 0x7f, &dev_id);
-       if (dev_id != 0xfe)
-               goto error;
-
-       memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       state->frontend.ops.set_voltage = state->config->set_voltage;
-
-       return &state->frontend;
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(mb86a16_attach);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/dvb/frontends/mb86a16.h b/drivers/media/dvb/frontends/mb86a16.h
deleted file mode 100644 (file)
index 6ea8c37..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
-
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __MB86A16_H
-#define __MB86A16_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-
-struct mb86a16_config {
-       u8 demod_address;
-
-       int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-};
-
-
-
-#if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
-                                          struct i2c_adapter *i2c_adap);
-
-#else
-
-static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
-                                          struct i2c_adapter *i2c_adap)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif /* CONFIG_DVB_MB86A16 */
-
-#endif /* __MB86A16_H */
diff --git a/drivers/media/dvb/frontends/mb86a16_priv.h b/drivers/media/dvb/frontends/mb86a16_priv.h
deleted file mode 100644 (file)
index 360a35a..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-       Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
-
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __MB86A16_PRIV_H
-#define __MB86A16_PRIV_H
-
-#define MB86A16_TSOUT          0x00
-#define MB86A16_TSOUT_HIZSEL   (0x01 << 5)
-#define MB86A16_TSOUT_HIZCNTI  (0x01 << 4)
-#define MB86A16_TSOUT_MODE     (0x01 << 3)
-#define MB86A16_TSOUT_ORDER    (0x01 << 2)
-#define MB86A16_TSOUT_ERROR    (0x01 << 1)
-#define Mb86A16_TSOUT_EDGE     (0x01 << 0)
-
-#define MB86A16_FEC            0x01
-#define MB86A16_FEC_FSYNC      (0x01 << 5)
-#define MB86A16_FEC_PCKB8      (0x01 << 4)
-#define MB86A16_FEC_DVDS       (0x01 << 3)
-#define MB86A16_FEC_EREN       (0x01 << 2)
-#define Mb86A16_FEC_RSEN       (0x01 << 1)
-#define MB86A16_FEC_DIEN       (0x01 << 0)
-
-#define MB86A16_AGC            0x02
-#define MB86A16_AGC_AGMD       (0x01 << 6)
-#define MB86A16_AGC_AGCW       (0x0f << 2)
-#define MB86A16_AGC_AGCP       (0x01 << 1)
-#define MB86A16_AGC_AGCR       (0x01 << 0)
-
-#define MB86A16_SRATE1         0x03
-#define MB86A16_SRATE1_DECI    (0x07 << 2)
-#define MB86A16_SRATE1_CSEL    (0x01 << 1)
-#define MB86A16_SRATE1_RSEL    (0x01 << 0)
-
-#define MB86A16_SRATE2         0x04
-#define MB86A16_SRATE2_STOFSL  (0xff << 0)
-
-#define MB86A16_SRATE3         0x05
-#define MB86A16_SRATE2_STOFSH  (0xff << 0)
-
-#define MB86A16_VITERBI                0x06
-#define MB86A16_FRAMESYNC      0x07
-#define MB86A16_CRLFILTCOEF1   0x08
-#define MB86A16_CRLFILTCOEF2   0x09
-#define MB86A16_STRFILTCOEF1   0x0a
-#define MB86A16_STRFILTCOEF2   0x0b
-#define MB86A16_RESET          0x0c
-#define MB86A16_STATUS         0x0d
-#define MB86A16_AFCML          0x0e
-#define MB86A16_AFCMH          0x0f
-#define MB86A16_BERMON         0x10
-#define MB86A16_BERTAB         0x11
-#define MB86A16_BERLSB         0x12
-#define MB86A16_BERMID         0x13
-#define MB86A16_BERMSB         0x14
-#define MB86A16_AGCM           0x15
-
-#define MB86A16_DCC1           0x16
-#define MB86A16_DCC1_DISTA     (0x01 << 7)
-#define MB86A16_DCC1_PRTY      (0x01 << 6)
-#define MB86A16_DCC1_CTOE      (0x01 << 5)
-#define MB86A16_DCC1_TBEN      (0x01 << 4)
-#define MB86A16_DCC1_TBO       (0x01 << 3)
-#define MB86A16_DCC1_NUM       (0x07 << 0)
-
-#define MB86A16_DCC2           0x17
-#define MB86A16_DCC2_DCBST     (0x01 << 0)
-
-#define MB86A16_DCC3           0x18
-#define MB86A16_DCC3_CODE0     (0xff << 0)
-
-#define MB86A16_DCC4           0x19
-#define MB86A16_DCC4_CODE1     (0xff << 0)
-
-#define MB86A16_DCC5           0x1a
-#define MB86A16_DCC5_CODE2     (0xff << 0)
-
-#define MB86A16_DCC6           0x1b
-#define MB86A16_DCC6_CODE3     (0xff << 0)
-
-#define MB86A16_DCC7           0x1c
-#define MB86A16_DCC7_CODE4     (0xff << 0)
-
-#define MB86A16_DCC8           0x1d
-#define MB86A16_DCC8_CODE5     (0xff << 0)
-
-#define MB86A16_DCCOUT         0x1e
-#define MB86A16_DCCOUT_DISEN   (0x01 << 0)
-
-#define MB86A16_TONEOUT1       0x1f
-#define MB86A16_TONE_TDIVL     (0xff << 0)
-
-#define MB86A16_TONEOUT2       0x20
-#define MB86A16_TONE_TMD       (0x03 << 2)
-#define MB86A16_TONE_TDIVH     (0x03 << 0)
-
-#define MB86A16_FREQ1          0x21
-#define MB86A16_FREQ2          0x22
-#define MB86A16_FREQ3          0x23
-#define MB86A16_FREQ4          0x24
-#define MB86A16_FREQSET                0x25
-#define MB86A16_CNM            0x26
-#define MB86A16_PORT0          0x27
-#define MB86A16_PORT1          0x28
-#define MB86A16_DRCFILT                0x29
-#define MB86A16_AFC            0x2a
-#define MB86A16_AFCEXL         0x2b
-#define MB86A16_AFCEXH         0x2c
-#define MB86A16_DAGC           0x2d
-#define MB86A16_SEQMODE                0x32
-#define MB86A16_S0S1T          0x33
-#define MB86A16_S2S3T          0x34
-#define MB86A16_S4S5T          0x35
-#define MB86A16_CNTMR          0x36
-#define MB86A16_SIG1           0x37
-#define MB86A16_SIG2           0x38
-#define MB86A16_VIMAG          0x39
-#define MB86A16_VISET1         0x3a
-#define MB86A16_VISET2         0x3b
-#define MB86A16_VISET3         0x3c
-#define MB86A16_FAGCS1         0x3d
-#define MB86A16_FAGCS2         0x3e
-#define MB86A16_FAGCS3         0x3f
-#define MB86A16_FAGCS4         0x40
-#define MB86A16_FAGCS5         0x41
-#define MB86A16_FAGCS6         0x42
-#define MB86A16_CRM            0x43
-#define MB86A16_STRM           0x44
-#define MB86A16_DAGCML         0x45
-#define MB86A16_DAGCMH         0x46
-#define MB86A16_QPSKTST                0x49
-#define MB86A16_DISTMON                0x52
-#define MB86A16_VERSION                0x7f
-
-#endif /* __MB86A16_PRIV_H */
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c
deleted file mode 100644 (file)
index fade566..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- *   Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
- *
- *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
- *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
- *
- *   FIXME: Need to port to DVB v5.2 API
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License as
- *   published by the Free Software Foundation version 2.
- *
- *   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.
- */
-
-#include <linux/kernel.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "mb86a20s.h"
-
-static int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-#define rc(args...)  do {                                              \
-       printk(KERN_ERR  "mb86a20s: " args);                            \
-} while (0)
-
-#define dprintk(args...)                                               \
-       do {                                                            \
-               if (debug) {                                            \
-                       printk(KERN_DEBUG "mb86a20s: %s: ", __func__);  \
-                       printk(args);                                   \
-               }                                                       \
-       } while (0)
-
-struct mb86a20s_state {
-       struct i2c_adapter *i2c;
-       const struct mb86a20s_config *config;
-
-       struct dvb_frontend frontend;
-
-       bool need_init;
-};
-
-struct regdata {
-       u8 reg;
-       u8 data;
-};
-
-/*
- * Initialization sequence: Use whatevere default values that PV SBTVD
- * does on its initialisation, obtained via USB snoop
- */
-static struct regdata mb86a20s_init[] = {
-       { 0x70, 0x0f },
-       { 0x70, 0xff },
-       { 0x08, 0x01 },
-       { 0x09, 0x3e },
-       { 0x50, 0xd1 }, { 0x51, 0x22 },
-       { 0x39, 0x01 },
-       { 0x71, 0x00 },
-       { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
-       { 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 },
-       { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
-       { 0x3b, 0x21 },
-       { 0x3c, 0x3a },
-       { 0x01, 0x0d },
-       { 0x04, 0x08 }, { 0x05, 0x05 },
-       { 0x04, 0x0e }, { 0x05, 0x00 },
-       { 0x04, 0x0f }, { 0x05, 0x14 },
-       { 0x04, 0x0b }, { 0x05, 0x8c },
-       { 0x04, 0x00 }, { 0x05, 0x00 },
-       { 0x04, 0x01 }, { 0x05, 0x07 },
-       { 0x04, 0x02 }, { 0x05, 0x0f },
-       { 0x04, 0x03 }, { 0x05, 0xa0 },
-       { 0x04, 0x09 }, { 0x05, 0x00 },
-       { 0x04, 0x0a }, { 0x05, 0xff },
-       { 0x04, 0x27 }, { 0x05, 0x64 },
-       { 0x04, 0x28 }, { 0x05, 0x00 },
-       { 0x04, 0x1e }, { 0x05, 0xff },
-       { 0x04, 0x29 }, { 0x05, 0x0a },
-       { 0x04, 0x32 }, { 0x05, 0x0a },
-       { 0x04, 0x14 }, { 0x05, 0x02 },
-       { 0x04, 0x04 }, { 0x05, 0x00 },
-       { 0x04, 0x05 }, { 0x05, 0x22 },
-       { 0x04, 0x06 }, { 0x05, 0x0e },
-       { 0x04, 0x07 }, { 0x05, 0xd8 },
-       { 0x04, 0x12 }, { 0x05, 0x00 },
-       { 0x04, 0x13 }, { 0x05, 0xff },
-       { 0x04, 0x15 }, { 0x05, 0x4e },
-       { 0x04, 0x16 }, { 0x05, 0x20 },
-       { 0x52, 0x01 },
-       { 0x50, 0xa7 }, { 0x51, 0xff },
-       { 0x50, 0xa8 }, { 0x51, 0xff },
-       { 0x50, 0xa9 }, { 0x51, 0xff },
-       { 0x50, 0xaa }, { 0x51, 0xff },
-       { 0x50, 0xab }, { 0x51, 0xff },
-       { 0x50, 0xac }, { 0x51, 0xff },
-       { 0x50, 0xad }, { 0x51, 0xff },
-       { 0x50, 0xae }, { 0x51, 0xff },
-       { 0x50, 0xaf }, { 0x51, 0xff },
-       { 0x5e, 0x07 },
-       { 0x50, 0xdc }, { 0x51, 0x01 },
-       { 0x50, 0xdd }, { 0x51, 0xf4 },
-       { 0x50, 0xde }, { 0x51, 0x01 },
-       { 0x50, 0xdf }, { 0x51, 0xf4 },
-       { 0x50, 0xe0 }, { 0x51, 0x01 },
-       { 0x50, 0xe1 }, { 0x51, 0xf4 },
-       { 0x50, 0xb0 }, { 0x51, 0x07 },
-       { 0x50, 0xb2 }, { 0x51, 0xff },
-       { 0x50, 0xb3 }, { 0x51, 0xff },
-       { 0x50, 0xb4 }, { 0x51, 0xff },
-       { 0x50, 0xb5 }, { 0x51, 0xff },
-       { 0x50, 0xb6 }, { 0x51, 0xff },
-       { 0x50, 0xb7 }, { 0x51, 0xff },
-       { 0x50, 0x50 }, { 0x51, 0x02 },
-       { 0x50, 0x51 }, { 0x51, 0x04 },
-       { 0x45, 0x04 },
-       { 0x48, 0x04 },
-       { 0x50, 0xd5 }, { 0x51, 0x01 },         /* Serial */
-       { 0x50, 0xd6 }, { 0x51, 0x1f },
-       { 0x50, 0xd2 }, { 0x51, 0x03 },
-       { 0x50, 0xd7 }, { 0x51, 0x3f },
-       { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x28, 0x74 }, { 0x29, 0x40 },
-       { 0x28, 0x46 }, { 0x29, 0x2c }, { 0x28, 0x46 }, { 0x29, 0x0c },
-       { 0x04, 0x40 }, { 0x05, 0x01 },
-       { 0x28, 0x00 }, { 0x29, 0x10 },
-       { 0x28, 0x05 }, { 0x29, 0x02 },
-       { 0x1c, 0x01 },
-       { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
-       { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
-       { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
-       { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
-       { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
-       { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
-       { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
-       { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
-       { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
-       { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
-       { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
-       { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
-       { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
-       { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
-       { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
-       { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
-       { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
-       { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
-       { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
-       { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
-       { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
-       { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
-       { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
-       { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
-       { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
-       { 0x50, 0x1e }, { 0x51, 0x5d },
-       { 0x50, 0x22 }, { 0x51, 0x00 },
-       { 0x50, 0x23 }, { 0x51, 0xc8 },
-       { 0x50, 0x24 }, { 0x51, 0x00 },
-       { 0x50, 0x25 }, { 0x51, 0xf0 },
-       { 0x50, 0x26 }, { 0x51, 0x00 },
-       { 0x50, 0x27 }, { 0x51, 0xc3 },
-       { 0x50, 0x39 }, { 0x51, 0x02 },
-       { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
-       { 0xd0, 0x00 },
-};
-
-static struct regdata mb86a20s_reset_reception[] = {
-       { 0x70, 0xf0 },
-       { 0x70, 0xff },
-       { 0x08, 0x01 },
-       { 0x08, 0x00 },
-};
-
-static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
-                            u8 i2c_addr, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
-       };
-       int rc;
-
-       rc = i2c_transfer(state->i2c, &msg, 1);
-       if (rc != 1) {
-               printk("%s: writereg error (rc == %i, reg == 0x%02x,"
-                        " data == 0x%02x)\n", __func__, rc, reg, data);
-               return rc;
-       }
-
-       return 0;
-}
-
-static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
-                                    u8 i2c_addr, struct regdata *rd, int size)
-{
-       int i, rc;
-
-       for (i = 0; i < size; i++) {
-               rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
-                                          rd[i].data);
-               if (rc < 0)
-                       return rc;
-       }
-       return 0;
-}
-
-static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
-                               u8 i2c_addr, u8 reg)
-{
-       u8 val;
-       int rc;
-       struct i2c_msg msg[] = {
-               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-       };
-
-       rc = i2c_transfer(state->i2c, msg, 2);
-
-       if (rc != 2) {
-               rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc);
-               return rc;
-       }
-
-       return val;
-}
-
-#define mb86a20s_readreg(state, reg) \
-       mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
-#define mb86a20s_writereg(state, reg, val) \
-       mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
-#define mb86a20s_writeregdata(state, regdata) \
-       mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
-       regdata, ARRAY_SIZE(regdata))
-
-static int mb86a20s_initfe(struct dvb_frontend *fe)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-       int rc;
-       u8  regD5 = 1;
-
-       dprintk("\n");
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       /* Initialize the frontend */
-       rc = mb86a20s_writeregdata(state, mb86a20s_init);
-       if (rc < 0)
-               goto err;
-
-       if (!state->config->is_serial) {
-               regD5 &= ~1;
-
-               rc = mb86a20s_writereg(state, 0x50, 0xd5);
-               if (rc < 0)
-                       goto err;
-               rc = mb86a20s_writereg(state, 0x51, regD5);
-               if (rc < 0)
-                       goto err;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-err:
-       if (rc < 0) {
-               state->need_init = true;
-               printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
-       } else {
-               state->need_init = false;
-               dprintk("Initialization succeeded.\n");
-       }
-       return rc;
-}
-
-static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-       unsigned rf_max, rf_min, rf;
-       u8       val;
-
-       dprintk("\n");
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       /* Does a binary search to get RF strength */
-       rf_max = 0xfff;
-       rf_min = 0;
-       do {
-               rf = (rf_max + rf_min) / 2;
-               mb86a20s_writereg(state, 0x04, 0x1f);
-               mb86a20s_writereg(state, 0x05, rf >> 8);
-               mb86a20s_writereg(state, 0x04, 0x20);
-               mb86a20s_writereg(state, 0x04, rf);
-
-               val = mb86a20s_readreg(state, 0x02);
-               if (val & 0x08)
-                       rf_min = (rf_max + rf_min) / 2;
-               else
-                       rf_max = (rf_max + rf_min) / 2;
-               if (rf_max - rf_min < 4) {
-                       *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
-                       break;
-               }
-       } while (1);
-
-       dprintk("signal strength = %d\n", *strength);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       return 0;
-}
-
-static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("\n");
-       *status = 0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-       val = mb86a20s_readreg(state, 0x0a) & 0xf;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       if (val >= 2)
-               *status |= FE_HAS_SIGNAL;
-
-       if (val >= 4)
-               *status |= FE_HAS_CARRIER;
-
-       if (val >= 5)
-               *status |= FE_HAS_VITERBI;
-
-       if (val >= 7)
-               *status |= FE_HAS_SYNC;
-
-       if (val >= 8)                           /* Maybe 9? */
-               *status |= FE_HAS_LOCK;
-
-       dprintk("val = %d, status = 0x%02x\n", val, *status);
-
-       return 0;
-}
-
-static int mb86a20s_set_frontend(struct dvb_frontend *fe)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-       int rc;
-#if 0
-       /*
-        * FIXME: Properly implement the set frontend properties
-        */
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-#endif
-
-       dprintk("\n");
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       dprintk("Calling tuner set parameters\n");
-       fe->ops.tuner_ops.set_params(fe);
-
-       /*
-        * Make it more reliable: if, for some reason, the initial
-        * device initialization doesn't happen, initialize it when
-        * a SBTVD parameters are adjusted.
-        *
-        * Unfortunately, due to a hard to track bug at tda829x/tda18271,
-        * the agc callback logic is not called during DVB attach time,
-        * causing mb86a20s to not be initialized with Kworld SBTVD.
-        * So, this hack is needed, in order to make Kworld SBTVD to work.
-        */
-       if (state->need_init)
-               mb86a20s_initfe(fe);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-       rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       return rc;
-}
-
-static int mb86a20s_get_modulation(struct mb86a20s_state *state,
-                                  unsigned layer)
-{
-       int rc;
-       static unsigned char reg[] = {
-               [0] = 0x86,     /* Layer A */
-               [1] = 0x8a,     /* Layer B */
-               [2] = 0x8e,     /* Layer C */
-       };
-
-       if (layer >= ARRAY_SIZE(reg))
-               return -EINVAL;
-       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
-       if (rc < 0)
-               return rc;
-       rc = mb86a20s_readreg(state, 0x6e);
-       if (rc < 0)
-               return rc;
-       switch ((rc & 0x70) >> 4) {
-       case 0:
-               return DQPSK;
-       case 1:
-               return QPSK;
-       case 2:
-               return QAM_16;
-       case 3:
-               return QAM_64;
-       default:
-               return QAM_AUTO;
-       }
-}
-
-static int mb86a20s_get_fec(struct mb86a20s_state *state,
-                           unsigned layer)
-{
-       int rc;
-
-       static unsigned char reg[] = {
-               [0] = 0x87,     /* Layer A */
-               [1] = 0x8b,     /* Layer B */
-               [2] = 0x8f,     /* Layer C */
-       };
-
-       if (layer >= ARRAY_SIZE(reg))
-               return -EINVAL;
-       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
-       if (rc < 0)
-               return rc;
-       rc = mb86a20s_readreg(state, 0x6e);
-       if (rc < 0)
-               return rc;
-       switch (rc) {
-       case 0:
-               return FEC_1_2;
-       case 1:
-               return FEC_2_3;
-       case 2:
-               return FEC_3_4;
-       case 3:
-               return FEC_5_6;
-       case 4:
-               return FEC_7_8;
-       default:
-               return FEC_AUTO;
-       }
-}
-
-static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
-                                    unsigned layer)
-{
-       int rc;
-
-       static unsigned char reg[] = {
-               [0] = 0x88,     /* Layer A */
-               [1] = 0x8c,     /* Layer B */
-               [2] = 0x90,     /* Layer C */
-       };
-
-       if (layer >= ARRAY_SIZE(reg))
-               return -EINVAL;
-       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
-       if (rc < 0)
-               return rc;
-       rc = mb86a20s_readreg(state, 0x6e);
-       if (rc < 0)
-               return rc;
-       if (rc > 3)
-               return -EINVAL; /* Not used */
-       return rc;
-}
-
-static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
-                                     unsigned layer)
-{
-       int rc, count;
-
-       static unsigned char reg[] = {
-               [0] = 0x89,     /* Layer A */
-               [1] = 0x8d,     /* Layer B */
-               [2] = 0x91,     /* Layer C */
-       };
-
-       if (layer >= ARRAY_SIZE(reg))
-               return -EINVAL;
-       rc = mb86a20s_writereg(state, 0x6d, reg[layer]);
-       if (rc < 0)
-               return rc;
-       rc = mb86a20s_readreg(state, 0x6e);
-       if (rc < 0)
-               return rc;
-       count = (rc >> 4) & 0x0f;
-
-       return count;
-}
-
-static int mb86a20s_get_frontend(struct dvb_frontend *fe)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       int i, rc;
-
-       /* Fixed parameters */
-       p->delivery_system = SYS_ISDBT;
-       p->bandwidth_hz = 6000000;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       /* Check for partial reception */
-       rc = mb86a20s_writereg(state, 0x6d, 0x85);
-       if (rc >= 0)
-               rc = mb86a20s_readreg(state, 0x6e);
-       if (rc >= 0)
-               p->isdbt_partial_reception = (rc & 0x10) ? 1 : 0;
-
-       /* Get per-layer data */
-       p->isdbt_layer_enabled = 0;
-       for (i = 0; i < 3; i++) {
-               rc = mb86a20s_get_segment_count(state, i);
-                       if (rc >= 0 && rc < 14)
-                               p->layer[i].segment_count = rc;
-               if (rc == 0x0f)
-                       continue;
-               p->isdbt_layer_enabled |= 1 << i;
-               rc = mb86a20s_get_modulation(state, i);
-                       if (rc >= 0)
-                               p->layer[i].modulation = rc;
-               rc = mb86a20s_get_fec(state, i);
-                       if (rc >= 0)
-                               p->layer[i].fec = rc;
-               rc = mb86a20s_get_interleaving(state, i);
-                       if (rc >= 0)
-                               p->layer[i].interleaving = rc;
-       }
-
-       p->isdbt_sb_mode = 0;
-       rc = mb86a20s_writereg(state, 0x6d, 0x84);
-       if ((rc >= 0) && ((rc & 0x60) == 0x20)) {
-               p->isdbt_sb_mode = 1;
-               /* At least, one segment should exist */
-               if (!p->isdbt_sb_segment_count)
-                       p->isdbt_sb_segment_count = 1;
-       } else
-               p->isdbt_sb_segment_count = 0;
-
-       /* Get transmission mode and guard interval */
-       p->transmission_mode = TRANSMISSION_MODE_AUTO;
-       p->guard_interval = GUARD_INTERVAL_AUTO;
-       rc = mb86a20s_readreg(state, 0x07);
-       if (rc >= 0) {
-               if ((rc & 0x60) == 0x20) {
-                       switch (rc & 0x0c >> 2) {
-                       case 0:
-                               p->transmission_mode = TRANSMISSION_MODE_2K;
-                               break;
-                       case 1:
-                               p->transmission_mode = TRANSMISSION_MODE_4K;
-                               break;
-                       case 2:
-                               p->transmission_mode = TRANSMISSION_MODE_8K;
-                               break;
-                       }
-               }
-               if (!(rc & 0x10)) {
-                       switch (rc & 0x3) {
-                       case 0:
-                               p->guard_interval = GUARD_INTERVAL_1_4;
-                               break;
-                       case 1:
-                               p->guard_interval = GUARD_INTERVAL_1_8;
-                               break;
-                       case 2:
-                               p->guard_interval = GUARD_INTERVAL_1_16;
-                               break;
-                       }
-               }
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       return 0;
-}
-
-static int mb86a20s_tune(struct dvb_frontend *fe,
-                       bool re_tune,
-                       unsigned int mode_flags,
-                       unsigned int *delay,
-                       fe_status_t *status)
-{
-       int rc = 0;
-
-       dprintk("\n");
-
-       if (re_tune)
-               rc = mb86a20s_set_frontend(fe);
-
-       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
-               mb86a20s_read_status(fe, status);
-
-       return rc;
-}
-
-static void mb86a20s_release(struct dvb_frontend *fe)
-{
-       struct mb86a20s_state *state = fe->demodulator_priv;
-
-       dprintk("\n");
-
-       kfree(state);
-}
-
-static struct dvb_frontend_ops mb86a20s_ops;
-
-struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       u8      rev;
-
-       /* allocate memory for the internal state */
-       struct mb86a20s_state *state =
-               kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
-
-       dprintk("\n");
-       if (state == NULL) {
-               rc("Unable to kzalloc\n");
-               goto error;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &mb86a20s_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       /* Check if it is a mb86a20s frontend */
-       rev = mb86a20s_readreg(state, 0);
-
-       if (rev == 0x13) {
-               printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
-       } else {
-               printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
-                      rev);
-               goto error;
-       }
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(mb86a20s_attach);
-
-static struct dvb_frontend_ops mb86a20s_ops = {
-       .delsys = { SYS_ISDBT },
-       /* Use dib8000 values per default */
-       .info = {
-               .name = "Fujitsu mb86A20s",
-               .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
-                       FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK     | FE_CAN_QAM_16  | FE_CAN_QAM_64 |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO    | FE_CAN_HIERARCHY_AUTO,
-               /* Actually, those values depend on the used tuner */
-               .frequency_min = 45000000,
-               .frequency_max = 864000000,
-               .frequency_stepsize = 62500,
-       },
-
-       .release = mb86a20s_release,
-
-       .init = mb86a20s_initfe,
-       .set_frontend = mb86a20s_set_frontend,
-       .get_frontend = mb86a20s_get_frontend,
-       .read_status = mb86a20s_read_status,
-       .read_signal_strength = mb86a20s_read_signal_strength,
-       .tune = mb86a20s_tune,
-};
-
-MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb/frontends/mb86a20s.h
deleted file mode 100644 (file)
index bf22e77..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *   Fujitsu mb86a20s driver
- *
- *   Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License as
- *   published by the Free Software Foundation version 2.
- *
- *   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.
- */
-
-#ifndef MB86A20S_H
-#define MB86A20S_H
-
-#include <linux/dvb/frontend.h>
-
-/**
- * struct mb86a20s_config - Define the per-device attributes of the frontend
- *
- * @demod_address:     the demodulator's i2c address
- */
-
-struct mb86a20s_config {
-       u8 demod_address;
-       bool is_serial;
-};
-
-#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
-       && defined(MODULE))
-extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
-                                          struct i2c_adapter *i2c);
-extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
-#else
-static inline struct dvb_frontend *mb86a20s_attach(
-       const struct mb86a20s_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static struct i2c_adapter *
-       mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* MB86A20S */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
deleted file mode 100644 (file)
index e20bf13..0000000
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
-    Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder
-
-    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
-    Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    References:
-    http://products.zarlink.com/product_profiles/MT312.htm
-    http://products.zarlink.com/product_profiles/SL1935.htm
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "mt312_priv.h"
-#include "mt312.h"
-
-
-struct mt312_state {
-       struct i2c_adapter *i2c;
-       /* configuration settings */
-       const struct mt312_config *config;
-       struct dvb_frontend frontend;
-
-       u8 id;
-       unsigned long xtal;
-       u8 freq_mult;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "mt312: " args); \
-       } while (0)
-
-#define MT312_PLL_CLK          10000000UL      /* 10 MHz */
-#define MT312_PLL_CLK_10_111   10111000UL      /* 10.111 MHz */
-
-static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
-                     u8 *buf, const size_t count)
-{
-       int ret;
-       struct i2c_msg msg[2];
-       u8 regbuf[1] = { reg };
-
-       msg[0].addr = state->config->demod_address;
-       msg[0].flags = 0;
-       msg[0].buf = regbuf;
-       msg[0].len = 1;
-       msg[1].addr = state->config->demod_address;
-       msg[1].flags = I2C_M_RD;
-       msg[1].buf = buf;
-       msg[1].len = count;
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-
-       if (debug) {
-               int i;
-               dprintk("R(%d):", reg & 0x7f);
-               for (i = 0; i < count; i++)
-                       printk(KERN_CONT " %02x", buf[i]);
-               printk("\n");
-       }
-
-       return 0;
-}
-
-static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
-                      const u8 *src, const size_t count)
-{
-       int ret;
-       u8 buf[count + 1];
-       struct i2c_msg msg;
-
-       if (debug) {
-               int i;
-               dprintk("W(%d):", reg & 0x7f);
-               for (i = 0; i < count; i++)
-                       printk(KERN_CONT " %02x", src[i]);
-               printk("\n");
-       }
-
-       buf[0] = reg;
-       memcpy(&buf[1], src, count);
-
-       msg.addr = state->config->demod_address;
-       msg.flags = 0;
-       msg.buf = buf;
-       msg.len = count + 1;
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1) {
-               dprintk("%s: ret == %d\n", __func__, ret);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static inline int mt312_readreg(struct mt312_state *state,
-                               const enum mt312_reg_addr reg, u8 *val)
-{
-       return mt312_read(state, reg, val, 1);
-}
-
-static inline int mt312_writereg(struct mt312_state *state,
-                                const enum mt312_reg_addr reg, const u8 val)
-{
-       return mt312_write(state, reg, &val, 1);
-}
-
-static inline u32 mt312_div(u32 a, u32 b)
-{
-       return (a + (b / 2)) / b;
-}
-
-static int mt312_reset(struct mt312_state *state, const u8 full)
-{
-       return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
-}
-
-static int mt312_get_inversion(struct mt312_state *state,
-                              fe_spectral_inversion_t *i)
-{
-       int ret;
-       u8 vit_mode;
-
-       ret = mt312_readreg(state, VIT_MODE, &vit_mode);
-       if (ret < 0)
-               return ret;
-
-       if (vit_mode & 0x80)    /* auto inversion was used */
-               *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
-
-       return 0;
-}
-
-static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr)
-{
-       int ret;
-       u8 sym_rate_h;
-       u8 dec_ratio;
-       u16 sym_rat_op;
-       u16 monitor;
-       u8 buf[2];
-
-       ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h);
-       if (ret < 0)
-               return ret;
-
-       if (sym_rate_h & 0x80) {
-               /* symbol rate search was used */
-               ret = mt312_writereg(state, MON_CTRL, 0x03);
-               if (ret < 0)
-                       return ret;
-
-               ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
-               if (ret < 0)
-                       return ret;
-
-               monitor = (buf[0] << 8) | buf[1];
-
-               dprintk("sr(auto) = %u\n",
-                      mt312_div(monitor * 15625, 4));
-       } else {
-               ret = mt312_writereg(state, MON_CTRL, 0x05);
-               if (ret < 0)
-                       return ret;
-
-               ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
-               if (ret < 0)
-                       return ret;
-
-               dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
-
-               ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf));
-               if (ret < 0)
-                       return ret;
-
-               sym_rat_op = (buf[0] << 8) | buf[1];
-
-               dprintk("sym_rat_op=%d dec_ratio=%d\n",
-                      sym_rat_op, dec_ratio);
-               dprintk("*sr(manual) = %lu\n",
-                      (((state->xtal * 8192) / (sym_rat_op + 8192)) *
-                       2) - dec_ratio);
-       }
-
-       return 0;
-}
-
-static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr)
-{
-       const fe_code_rate_t fec_tab[8] =
-           { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
-               FEC_AUTO, FEC_AUTO };
-
-       int ret;
-       u8 fec_status;
-
-       ret = mt312_readreg(state, FEC_STATUS, &fec_status);
-       if (ret < 0)
-               return ret;
-
-       *cr = fec_tab[(fec_status >> 4) & 0x07];
-
-       return 0;
-}
-
-static int mt312_initfe(struct dvb_frontend *fe)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-
-       /* wake up */
-       ret = mt312_writereg(state, CONFIG,
-                       (state->freq_mult == 6 ? 0x88 : 0x8c));
-       if (ret < 0)
-               return ret;
-
-       /* wait at least 150 usec */
-       udelay(150);
-
-       /* full reset */
-       ret = mt312_reset(state, 1);
-       if (ret < 0)
-               return ret;
-
-/* Per datasheet, write correct values. 09/28/03 ACCJr.
- * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */
-       {
-               u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02,
-                                 0x01, 0x00, 0x00, 0x00 };
-
-               ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def));
-               if (ret < 0)
-                       return ret;
-       }
-
-       switch (state->id) {
-       case ID_ZL10313:
-               /* enable ADC */
-               ret = mt312_writereg(state, GPP_CTRL, 0x80);
-               if (ret < 0)
-                       return ret;
-
-               /* configure ZL10313 for optimal ADC performance */
-               buf[0] = 0x80;
-               buf[1] = 0xB0;
-               ret = mt312_write(state, HW_CTRL, buf, 2);
-               if (ret < 0)
-                       return ret;
-
-               /* enable MPEG output and ADCs */
-               ret = mt312_writereg(state, HW_CTRL, 0x00);
-               if (ret < 0)
-                       return ret;
-
-               ret = mt312_writereg(state, MPEG_CTRL, 0x00);
-               if (ret < 0)
-                       return ret;
-
-               break;
-       }
-
-       /* SYS_CLK */
-       buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
-
-       /* DISEQC_RATIO */
-       buf[1] = mt312_div(state->xtal, 22000 * 4);
-
-       ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_writereg(state, SNR_THS_HIGH, 0x32);
-       if (ret < 0)
-               return ret;
-
-       /* different MOCLK polarity */
-       switch (state->id) {
-       case ID_ZL10313:
-               buf[0] = 0x33;
-               break;
-       default:
-               buf[0] = 0x53;
-               break;
-       }
-
-       ret = mt312_writereg(state, OP_CTRL, buf[0]);
-       if (ret < 0)
-               return ret;
-
-       /* TS_SW_LIM */
-       buf[0] = 0x8c;
-       buf[1] = 0x98;
-
-       ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_writereg(state, CS_SW_LIM, 0x69);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int mt312_send_master_cmd(struct dvb_frontend *fe,
-                                struct dvb_diseqc_master_cmd *c)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 diseqc_mode;
-
-       if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
-               return -EINVAL;
-
-       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_writereg(state, DISEQC_MODE,
-                            (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
-                            | 0x04);
-       if (ret < 0)
-               return ret;
-
-       /* is there a better way to wait for message to be transmitted */
-       msleep(100);
-
-       /* set DISEQC_MODE[2:0] to zero if a return message is expected */
-       if (c->msg[0] & 0x02) {
-               ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       const u8 mini_tab[2] = { 0x02, 0x03 };
-
-       int ret;
-       u8 diseqc_mode;
-
-       if (c > SEC_MINI_B)
-               return -EINVAL;
-
-       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_writereg(state, DISEQC_MODE,
-                            (diseqc_mode & 0x40) | mini_tab[c]);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       const u8 tone_tab[2] = { 0x01, 0x00 };
-
-       int ret;
-       u8 diseqc_mode;
-
-       if (t > SEC_TONE_OFF)
-               return -EINVAL;
-
-       ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_writereg(state, DISEQC_MODE,
-                            (diseqc_mode & 0x40) | tone_tab[t]);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
-       u8 val;
-
-       if (v > SEC_VOLTAGE_OFF)
-               return -EINVAL;
-
-       val = volt_tab[v];
-       if (state->config->voltage_inverted)
-               val ^= 0x40;
-
-       return mt312_writereg(state, DISEQC_MODE, val);
-}
-
-static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 status[3];
-
-       *s = 0;
-
-       ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status));
-       if (ret < 0)
-               return ret;
-
-       dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x,"
-               " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
-
-       if (status[0] & 0xc0)
-               *s |= FE_HAS_SIGNAL;    /* signal noise ratio */
-       if (status[0] & 0x04)
-               *s |= FE_HAS_CARRIER;   /* qpsk carrier lock */
-       if (status[2] & 0x02)
-               *s |= FE_HAS_VITERBI;   /* viterbi lock */
-       if (status[2] & 0x04)
-               *s |= FE_HAS_SYNC;      /* byte align lock */
-       if (status[0] & 0x01)
-               *s |= FE_HAS_LOCK;      /* qpsk lock */
-
-       return 0;
-}
-
-static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-
-       ret = mt312_read(state, RS_BERCNT_H, buf, 3);
-       if (ret < 0)
-               return ret;
-
-       *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
-
-       return 0;
-}
-
-static int mt312_read_signal_strength(struct dvb_frontend *fe,
-                                     u16 *signal_strength)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-       u16 agc;
-       s16 err_db;
-
-       ret = mt312_read(state, AGC_H, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       agc = (buf[0] << 6) | (buf[1] >> 2);
-       err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
-
-       *signal_strength = agc;
-
-       dprintk("agc=%08x err_db=%hd\n", agc, err_db);
-
-       return 0;
-}
-
-static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-
-       ret = mt312_read(state, M_SNR_H, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
-
-       return 0;
-}
-
-static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-
-       ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       *ubc = (buf[0] << 8) | buf[1];
-
-       return 0;
-}
-
-static int mt312_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 buf[5], config_val;
-       u16 sr;
-
-       const u8 fec_tab[10] =
-           { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
-       const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
-
-       dprintk("%s: Freq %d\n", __func__, p->frequency);
-
-       if ((p->frequency < fe->ops.info.frequency_min)
-           || (p->frequency > fe->ops.info.frequency_max))
-               return -EINVAL;
-
-       if ((p->inversion < INVERSION_OFF)
-           || (p->inversion > INVERSION_ON))
-               return -EINVAL;
-
-       if ((p->symbol_rate < fe->ops.info.symbol_rate_min)
-           || (p->symbol_rate > fe->ops.info.symbol_rate_max))
-               return -EINVAL;
-
-       if ((p->fec_inner < FEC_NONE)
-           || (p->fec_inner > FEC_AUTO))
-               return -EINVAL;
-
-       if ((p->fec_inner == FEC_4_5)
-           || (p->fec_inner == FEC_8_9))
-               return -EINVAL;
-
-       switch (state->id) {
-       case ID_VP310:
-       /* For now we will do this only for the VP310.
-        * It should be better for the mt312 as well,
-        * but tuning will be slower. ACCJr 09/29/03
-        */
-               ret = mt312_readreg(state, CONFIG, &config_val);
-               if (ret < 0)
-                       return ret;
-               if (p->symbol_rate >= 30000000) {
-                       /* Note that 30MS/s should use 90MHz */
-                       if (state->freq_mult == 6) {
-                               /* We are running 60MHz */
-                               state->freq_mult = 9;
-                               ret = mt312_initfe(fe);
-                               if (ret < 0)
-                                       return ret;
-                       }
-               } else {
-                       if (state->freq_mult == 9) {
-                               /* We are running 90MHz */
-                               state->freq_mult = 6;
-                               ret = mt312_initfe(fe);
-                               if (ret < 0)
-                                       return ret;
-                       }
-               }
-               break;
-
-       case ID_MT312:
-       case ID_ZL10313:
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* sr = (u16)(sr * 256.0 / 1000000.0) */
-       sr = mt312_div(p->symbol_rate * 4, 15625);
-
-       /* SYM_RATE */
-       buf[0] = (sr >> 8) & 0x3f;
-       buf[1] = (sr >> 0) & 0xff;
-
-       /* VIT_MODE */
-       buf[2] = inv_tab[p->inversion] | fec_tab[p->fec_inner];
-
-       /* QPSK_CTRL */
-       buf[3] = 0x40;          /* swap I and Q before QPSK demodulation */
-
-       if (p->symbol_rate < 10000000)
-               buf[3] |= 0x04; /* use afc mode */
-
-       /* GO */
-       buf[4] = 0x01;
-
-       ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-
-       mt312_reset(state, 0);
-
-       return 0;
-}
-
-static int mt312_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-
-       ret = mt312_get_inversion(state, &p->inversion);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_get_symbol_rate(state, &p->symbol_rate);
-       if (ret < 0)
-               return ret;
-
-       ret = mt312_get_code_rate(state, &p->fec_inner);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-
-       u8 val = 0x00;
-       int ret;
-
-       switch (state->id) {
-       case ID_ZL10313:
-               ret = mt312_readreg(state, GPP_CTRL, &val);
-               if (ret < 0)
-                       goto error;
-
-               /* preserve this bit to not accidentally shutdown ADC */
-               val &= 0x80;
-               break;
-       }
-
-       if (enable)
-               val |= 0x40;
-       else
-               val &= ~0x40;
-
-       ret = mt312_writereg(state, GPP_CTRL, val);
-
-error:
-       return ret;
-}
-
-static int mt312_sleep(struct dvb_frontend *fe)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       int ret;
-       u8 config;
-
-       /* reset all registers to defaults */
-       ret = mt312_reset(state, 1);
-       if (ret < 0)
-               return ret;
-
-       if (state->id == ID_ZL10313) {
-               /* reset ADC */
-               ret = mt312_writereg(state, GPP_CTRL, 0x00);
-               if (ret < 0)
-                       return ret;
-
-               /* full shutdown of ADCs, mpeg bus tristated */
-               ret = mt312_writereg(state, HW_CTRL, 0x0d);
-               if (ret < 0)
-                       return ret;
-       }
-
-       ret = mt312_readreg(state, CONFIG, &config);
-       if (ret < 0)
-               return ret;
-
-       /* enter standby */
-       ret = mt312_writereg(state, CONFIG, config & 0x7f);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int mt312_get_tune_settings(struct dvb_frontend *fe,
-               struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 50;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void mt312_release(struct dvb_frontend *fe)
-{
-       struct mt312_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-#define MT312_SYS_CLK          90000000UL      /* 90 MHz */
-static struct dvb_frontend_ops mt312_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name = "Zarlink ???? DVB-S",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               /* FIXME: adjust freq to real used xtal */
-               .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
-               .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
-               .symbol_rate_max = MT312_SYS_CLK / 2,
-               .caps =
-                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                   FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                   FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
-                   FE_CAN_RECOVER
-       },
-
-       .release = mt312_release,
-
-       .init = mt312_initfe,
-       .sleep = mt312_sleep,
-       .i2c_gate_ctrl = mt312_i2c_gate_ctrl,
-
-       .set_frontend = mt312_set_frontend,
-       .get_frontend = mt312_get_frontend,
-       .get_tune_settings = mt312_get_tune_settings,
-
-       .read_status = mt312_read_status,
-       .read_ber = mt312_read_ber,
-       .read_signal_strength = mt312_read_signal_strength,
-       .read_snr = mt312_read_snr,
-       .read_ucblocks = mt312_read_ucblocks,
-
-       .diseqc_send_master_cmd = mt312_send_master_cmd,
-       .diseqc_send_burst = mt312_send_burst,
-       .set_tone = mt312_set_tone,
-       .set_voltage = mt312_set_voltage,
-};
-
-struct dvb_frontend *mt312_attach(const struct mt312_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       struct mt312_state *state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if (mt312_readreg(state, ID, &state->id) < 0)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &mt312_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       switch (state->id) {
-       case ID_VP310:
-               strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
-               state->xtal = MT312_PLL_CLK;
-               state->freq_mult = 9;
-               break;
-       case ID_MT312:
-               strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
-               state->xtal = MT312_PLL_CLK;
-               state->freq_mult = 6;
-               break;
-       case ID_ZL10313:
-               strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
-               state->xtal = MT312_PLL_CLK_10_111;
-               state->freq_mult = 9;
-               break;
-       default:
-               printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313"
-                       " are supported chips.\n");
-               goto error;
-       }
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(mt312_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
-MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
-MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
deleted file mode 100644 (file)
index 29e3bb5..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-    Driver for Zarlink MT312 Satellite Channel Decoder
-
-    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    References:
-    http://products.zarlink.com/product_profiles/MT312.htm
-    http://products.zarlink.com/product_profiles/SL1935.htm
-*/
-
-#ifndef MT312_H
-#define MT312_H
-
-#include <linux/dvb/frontend.h>
-
-struct mt312_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* inverted voltage setting */
-       unsigned int voltage_inverted:1;
-};
-
-#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
-struct dvb_frontend *mt312_attach(const struct mt312_config *config,
-                                       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *mt312_attach(
-       const struct mt312_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_MT312 */
-
-#endif /* MT312_H */
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h
deleted file mode 100644 (file)
index a3959f9..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-    Driver for Zarlink MT312 QPSK Frontend
-
-    Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef _DVB_FRONTENDS_MT312_PRIV
-#define _DVB_FRONTENDS_MT312_PRIV
-
-enum mt312_reg_addr {
-       QPSK_INT_H = 0,
-       QPSK_INT_M = 1,
-       QPSK_INT_L = 2,
-       FEC_INT = 3,
-       QPSK_STAT_H = 4,
-       QPSK_STAT_L = 5,
-       FEC_STATUS = 6,
-       LNB_FREQ_H = 7,
-       LNB_FREQ_L = 8,
-       M_SNR_H = 9,
-       M_SNR_L = 10,
-       VIT_ERRCNT_H = 11,
-       VIT_ERRCNT_M = 12,
-       VIT_ERRCNT_L = 13,
-       RS_BERCNT_H = 14,
-       RS_BERCNT_M = 15,
-       RS_BERCNT_L = 16,
-       RS_UBC_H = 17,
-       RS_UBC_L = 18,
-       SIG_LEVEL = 19,
-       GPP_CTRL = 20,
-       RESET = 21,
-       DISEQC_MODE = 22,
-       SYM_RATE_H = 23,
-       SYM_RATE_L = 24,
-       VIT_MODE = 25,
-       QPSK_CTRL = 26,
-       GO = 27,
-       IE_QPSK_H = 28,
-       IE_QPSK_M = 29,
-       IE_QPSK_L = 30,
-       IE_FEC = 31,
-       QPSK_STAT_EN = 32,
-       FEC_STAT_EN = 33,
-       SYS_CLK = 34,
-       DISEQC_RATIO = 35,
-       DISEQC_INSTR = 36,
-       FR_LIM = 37,
-       FR_OFF = 38,
-       AGC_CTRL = 39,
-       AGC_INIT = 40,
-       AGC_REF = 41,
-       AGC_MAX = 42,
-       AGC_MIN = 43,
-       AGC_LK_TH = 44,
-       TS_AGC_LK_TH = 45,
-       AGC_PWR_SET = 46,
-       QPSK_MISC = 47,
-       SNR_THS_LOW = 48,
-       SNR_THS_HIGH = 49,
-       TS_SW_RATE = 50,
-       TS_SW_LIM_L = 51,
-       TS_SW_LIM_H = 52,
-       CS_SW_RATE_1 = 53,
-       CS_SW_RATE_2 = 54,
-       CS_SW_RATE_3 = 55,
-       CS_SW_RATE_4 = 56,
-       CS_SW_LIM = 57,
-       TS_LPK = 58,
-       TS_LPK_M = 59,
-       TS_LPK_L = 60,
-       CS_KPROP_H = 61,
-       CS_KPROP_L = 62,
-       CS_KINT_H = 63,
-       CS_KINT_L = 64,
-       QPSK_SCALE = 65,
-       TLD_OUTCLK_TH = 66,
-       TLD_INCLK_TH = 67,
-       FLD_TH = 68,
-       PLD_OUTLK3 = 69,
-       PLD_OUTLK2 = 70,
-       PLD_OUTLK1 = 71,
-       PLD_OUTLK0 = 72,
-       PLD_INLK3 = 73,
-       PLD_INLK2 = 74,
-       PLD_INLK1 = 75,
-       PLD_INLK0 = 76,
-       PLD_ACC_TIME = 77,
-       SWEEP_PAR = 78,
-       STARTUP_TIME = 79,
-       LOSSLOCK_TH = 80,
-       FEC_LOCK_TM = 81,
-       LOSSLOCK_TM = 82,
-       VIT_ERRPER_H = 83,
-       VIT_ERRPER_M = 84,
-       VIT_ERRPER_L = 85,
-       HW_CTRL = 84,   /* ZL10313 only */
-       MPEG_CTRL = 85, /* ZL10313 only */
-       VIT_SETUP = 86,
-       VIT_REF0 = 87,
-       VIT_REF1 = 88,
-       VIT_REF2 = 89,
-       VIT_REF3 = 90,
-       VIT_REF4 = 91,
-       VIT_REF5 = 92,
-       VIT_REF6 = 93,
-       VIT_MAXERR = 94,
-       BA_SETUPT = 95,
-       OP_CTRL = 96,
-       FEC_SETUP = 97,
-       PROG_SYNC = 98,
-       AFC_SEAR_TH = 99,
-       CSACC_DIF_TH = 100,
-       QPSK_LK_CT = 101,
-       QPSK_ST_CT = 102,
-       MON_CTRL = 103,
-       QPSK_RESET = 104,
-       QPSK_TST_CT = 105,
-       QPSK_TST_ST = 106,
-       TEST_R = 107,
-       AGC_H = 108,
-       AGC_M = 109,
-       AGC_L = 110,
-       FREQ_ERR1_H = 111,
-       FREQ_ERR1_M = 112,
-       FREQ_ERR1_L = 113,
-       FREQ_ERR2_H = 114,
-       FREQ_ERR2_L = 115,
-       SYM_RAT_OP_H = 116,
-       SYM_RAT_OP_L = 117,
-       DESEQC2_INT = 118,
-       DISEQC2_STAT = 119,
-       DISEQC2_FIFO = 120,
-       DISEQC2_CTRL1 = 121,
-       DISEQC2_CTRL2 = 122,
-       MONITOR_H = 123,
-       MONITOR_L = 124,
-       TEST_MODE = 125,
-       ID = 126,
-       CONFIG = 127
-};
-
-enum mt312_model_id {
-       ID_VP310 = 1,
-       ID_MT312 = 3,
-       ID_ZL10313 = 5,
-};
-
-#endif                         /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
deleted file mode 100644 (file)
index 2c3b50e..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- *  Driver for Zarlink DVB-T MT352 demodulator
- *
- *  Written by Holger Waechtler <holger@qanu.de>
- *      and Daniel Mack <daniel@qanu.de>
- *
- *  AVerMedia AVerTV DVB-T 771 support by
- *       Wolfram Joost <dbox2@frokaschwei.de>
- *
- *  Support for Samsung TDTC9251DH01C(M) tuner
- *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
- *                     Amauri  Celani  <acelani@essegi.net>
- *
- *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
- *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "mt352_priv.h"
-#include "mt352.h"
-
-struct mt352_state {
-       struct i2c_adapter* i2c;
-       struct dvb_frontend frontend;
-
-       /* configuration settings */
-       struct mt352_config config;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "mt352: " args); \
-       } while (0)
-
-static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
-                              .buf = buf, .len = 2 };
-       int err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
-               return err;
-       }
-       return 0;
-}
-
-static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
-{
-       int err,i;
-       for (i=0; i < ilen-1; i++)
-               if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
-                       return err;
-
-       return 0;
-}
-
-static int mt352_read_register(struct mt352_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config.demod_address,
-                                   .flags = 0,
-                                   .buf = b0, .len = 1 },
-                                 { .addr = state->config.demod_address,
-                                   .flags = I2C_M_RD,
-                                   .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk("%s: readreg error (reg=%d, ret==%i)\n",
-                      __func__, reg, ret);
-               return ret;
-       }
-
-       return b1[0];
-}
-
-static int mt352_sleep(struct dvb_frontend* fe)
-{
-       static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
-
-       _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
-       return 0;
-}
-
-static void mt352_calc_nominal_rate(struct mt352_state* state,
-                                   u32 bandwidth,
-                                   unsigned char *buf)
-{
-       u32 adc_clock = 20480; /* 20.340 MHz */
-       u32 bw,value;
-
-       switch (bandwidth) {
-       case 6000000:
-               bw = 6;
-               break;
-       case 7000000:
-               bw = 7;
-               break;
-       case 8000000:
-       default:
-               bw = 8;
-               break;
-       }
-       if (state->config.adc_clock)
-               adc_clock = state->config.adc_clock;
-
-       value = 64 * bw * (1<<16) / (7 * 8);
-       value = value * 1000 / adc_clock;
-       dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
-               __func__, bw, adc_clock, value);
-       buf[0] = msb(value);
-       buf[1] = lsb(value);
-}
-
-static void mt352_calc_input_freq(struct mt352_state* state,
-                                 unsigned char *buf)
-{
-       int adc_clock = 20480; /* 20.480000 MHz */
-       int if2       = 36167; /* 36.166667 MHz */
-       int ife,value;
-
-       if (state->config.adc_clock)
-               adc_clock = state->config.adc_clock;
-       if (state->config.if2)
-               if2 = state->config.if2;
-
-       if (adc_clock >= if2 * 2)
-               ife = if2;
-       else {
-               ife = adc_clock - (if2 % adc_clock);
-               if (ife > adc_clock / 2)
-                       ife = adc_clock - ife;
-       }
-       value = -16374 * ife / adc_clock;
-       dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
-               __func__, if2, ife, adc_clock, value, value & 0x3fff);
-       buf[0] = msb(value);
-       buf[1] = lsb(value);
-}
-
-static int mt352_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *op = &fe->dtv_property_cache;
-       struct mt352_state* state = fe->demodulator_priv;
-       unsigned char buf[13];
-       static unsigned char tuner_go[] = { 0x5d, 0x01 };
-       static unsigned char fsm_go[]   = { 0x5e, 0x01 };
-       unsigned int tps = 0;
-
-       switch (op->code_rate_HP) {
-               case FEC_2_3:
-                       tps |= (1 << 7);
-                       break;
-               case FEC_3_4:
-                       tps |= (2 << 7);
-                       break;
-               case FEC_5_6:
-                       tps |= (3 << 7);
-                       break;
-               case FEC_7_8:
-                       tps |= (4 << 7);
-                       break;
-               case FEC_1_2:
-               case FEC_AUTO:
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (op->code_rate_LP) {
-               case FEC_2_3:
-                       tps |= (1 << 4);
-                       break;
-               case FEC_3_4:
-                       tps |= (2 << 4);
-                       break;
-               case FEC_5_6:
-                       tps |= (3 << 4);
-                       break;
-               case FEC_7_8:
-                       tps |= (4 << 4);
-                       break;
-               case FEC_1_2:
-               case FEC_AUTO:
-                       break;
-               case FEC_NONE:
-                       if (op->hierarchy == HIERARCHY_AUTO ||
-                           op->hierarchy == HIERARCHY_NONE)
-                               break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (op->modulation) {
-               case QPSK:
-                       break;
-               case QAM_AUTO:
-               case QAM_16:
-                       tps |= (1 << 13);
-                       break;
-               case QAM_64:
-                       tps |= (2 << 13);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (op->transmission_mode) {
-               case TRANSMISSION_MODE_2K:
-               case TRANSMISSION_MODE_AUTO:
-                       break;
-               case TRANSMISSION_MODE_8K:
-                       tps |= (1 << 0);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (op->guard_interval) {
-               case GUARD_INTERVAL_1_32:
-               case GUARD_INTERVAL_AUTO:
-                       break;
-               case GUARD_INTERVAL_1_16:
-                       tps |= (1 << 2);
-                       break;
-               case GUARD_INTERVAL_1_8:
-                       tps |= (2 << 2);
-                       break;
-               case GUARD_INTERVAL_1_4:
-                       tps |= (3 << 2);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (op->hierarchy) {
-               case HIERARCHY_AUTO:
-               case HIERARCHY_NONE:
-                       break;
-               case HIERARCHY_1:
-                       tps |= (1 << 10);
-                       break;
-               case HIERARCHY_2:
-                       tps |= (2 << 10);
-                       break;
-               case HIERARCHY_4:
-                       tps |= (3 << 10);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-
-       buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
-
-       buf[1] = msb(tps);      /* TPS_GIVEN_(1|0) */
-       buf[2] = lsb(tps);
-
-       buf[3] = 0x50;  // old
-//     buf[3] = 0xf4;  // pinnacle
-
-       mt352_calc_nominal_rate(state, op->bandwidth_hz, buf+4);
-       mt352_calc_input_freq(state, buf+6);
-
-       if (state->config.no_tuner) {
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-
-               _mt352_write(fe, buf, 8);
-               _mt352_write(fe, fsm_go, 2);
-       } else {
-               if (fe->ops.tuner_ops.calc_regs) {
-                       fe->ops.tuner_ops.calc_regs(fe, buf+8, 5);
-                       buf[8] <<= 1;
-                       _mt352_write(fe, buf, sizeof(buf));
-                       _mt352_write(fe, tuner_go, 2);
-               }
-       }
-
-       return 0;
-}
-
-static int mt352_get_parameters(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *op = &fe->dtv_property_cache;
-       struct mt352_state* state = fe->demodulator_priv;
-       u16 tps;
-       u16 div;
-       u8 trl;
-       static const u8 tps_fec_to_api[8] =
-       {
-               FEC_1_2,
-               FEC_2_3,
-               FEC_3_4,
-               FEC_5_6,
-               FEC_7_8,
-               FEC_AUTO,
-               FEC_AUTO,
-               FEC_AUTO
-       };
-
-       if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
-               return -EINVAL;
-
-       /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
-        * the mt352 sometimes works with the wrong parameters
-        */
-       tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
-       div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
-       trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
-
-       op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
-       op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
-
-       switch ( (tps >> 13) & 3)
-       {
-               case 0:
-                       op->modulation = QPSK;
-                       break;
-               case 1:
-                       op->modulation = QAM_16;
-                       break;
-               case 2:
-                       op->modulation = QAM_64;
-                       break;
-               default:
-                       op->modulation = QAM_AUTO;
-                       break;
-       }
-
-       op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
-
-       switch ( (tps >> 2) & 3)
-       {
-               case 0:
-                       op->guard_interval = GUARD_INTERVAL_1_32;
-                       break;
-               case 1:
-                       op->guard_interval = GUARD_INTERVAL_1_16;
-                       break;
-               case 2:
-                       op->guard_interval = GUARD_INTERVAL_1_8;
-                       break;
-               case 3:
-                       op->guard_interval = GUARD_INTERVAL_1_4;
-                       break;
-               default:
-                       op->guard_interval = GUARD_INTERVAL_AUTO;
-                       break;
-       }
-
-       switch ( (tps >> 10) & 7)
-       {
-               case 0:
-                       op->hierarchy = HIERARCHY_NONE;
-                       break;
-               case 1:
-                       op->hierarchy = HIERARCHY_1;
-                       break;
-               case 2:
-                       op->hierarchy = HIERARCHY_2;
-                       break;
-               case 3:
-                       op->hierarchy = HIERARCHY_4;
-                       break;
-               default:
-                       op->hierarchy = HIERARCHY_AUTO;
-                       break;
-       }
-
-       op->frequency = (500 * (div - IF_FREQUENCYx6)) / 3 * 1000;
-
-       if (trl == 0x72)
-               op->bandwidth_hz = 8000000;
-       else if (trl == 0x64)
-               op->bandwidth_hz = 7000000;
-       else
-               op->bandwidth_hz = 6000000;
-
-
-       if (mt352_read_register(state, STATUS_2) & 0x02)
-               op->inversion = INVERSION_OFF;
-       else
-               op->inversion = INVERSION_ON;
-
-       return 0;
-}
-
-static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-       int s0, s1, s3;
-
-       /* FIXME:
-        *
-        * The MT352 design manual from Zarlink states (page 46-47):
-        *
-        * Notes about the TUNER_GO register:
-        *
-        * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
-        * byte is copied from the tuner to the STATUS_3 register and
-        * completion of the read operation is indicated by bit-5 of the
-        * INTERRUPT_3 register.
-        */
-
-       if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
-               return -EREMOTEIO;
-       if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
-               return -EREMOTEIO;
-       if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
-               return -EREMOTEIO;
-
-       *status = 0;
-       if (s0 & (1 << 4))
-               *status |= FE_HAS_CARRIER;
-       if (s0 & (1 << 1))
-               *status |= FE_HAS_VITERBI;
-       if (s0 & (1 << 5))
-               *status |= FE_HAS_LOCK;
-       if (s1 & (1 << 1))
-               *status |= FE_HAS_SYNC;
-       if (s3 & (1 << 6))
-               *status |= FE_HAS_SIGNAL;
-
-       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
-                     (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
-               *status &= ~FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-
-       *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
-              (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
-              (mt352_read_register (state, RS_ERR_CNT_0));
-
-       return 0;
-}
-
-static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-
-       /* align the 12 bit AGC gain with the most significant bits */
-       u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
-               (mt352_read_register(state, AGC_GAIN_0) << 4);
-
-       /* inverse of gain is signal strength */
-       *strength = ~signal;
-       return 0;
-}
-
-static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-
-       u8 _snr = mt352_read_register (state, SNR);
-       *snr = (_snr << 8) | _snr;
-
-       return 0;
-}
-
-static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-
-       *ucblocks = (mt352_read_register (state,  RS_UBC_1) << 8) |
-                   (mt352_read_register (state,  RS_UBC_0));
-
-       return 0;
-}
-
-static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 800;
-       fe_tune_settings->step_size = 0;
-       fe_tune_settings->max_drift = 0;
-
-       return 0;
-}
-
-static int mt352_init(struct dvb_frontend* fe)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-
-       static u8 mt352_reset_attach [] = { RESET, 0xC0 };
-
-       dprintk("%s: hello\n",__func__);
-
-       if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
-           (mt352_read_register(state, CONFIG) & 0x20) == 0) {
-
-               /* Do a "hard" reset */
-               _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
-               return state->config.demod_init(fe);
-       }
-
-       return 0;
-}
-
-static void mt352_release(struct dvb_frontend* fe)
-{
-       struct mt352_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops mt352_ops;
-
-struct dvb_frontend* mt352_attach(const struct mt352_config* config,
-                                 struct i2c_adapter* i2c)
-{
-       struct mt352_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->config,config,sizeof(struct mt352_config));
-
-       /* check if the demod is there */
-       if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops mt352_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Zarlink MT352 DVB-T",
-               .frequency_min          = 174000000,
-               .frequency_max          = 862000000,
-               .frequency_stepsize     = 166667,
-               .frequency_tolerance    = 0,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = mt352_release,
-
-       .init = mt352_init,
-       .sleep = mt352_sleep,
-       .write = _mt352_write,
-
-       .set_frontend = mt352_set_parameters,
-       .get_frontend = mt352_get_parameters,
-       .get_tune_settings = mt352_get_tune_settings,
-
-       .read_status = mt352_read_status,
-       .read_ber = mt352_read_ber,
-       .read_signal_strength = mt352_read_signal_strength,
-       .read_snr = mt352_read_snr,
-       .read_ucblocks = mt352_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
-MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(mt352_attach);
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
deleted file mode 100644 (file)
index ca2562d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  Driver for Zarlink DVB-T MT352 demodulator
- *
- *  Written by Holger Waechtler <holger@qanu.de>
- *      and Daniel Mack <daniel@qanu.de>
- *
- *  AVerMedia AVerTV DVB-T 771 support by
- *       Wolfram Joost <dbox2@frokaschwei.de>
- *
- *  Support for Samsung TDTC9251DH01C(M) tuner
- *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
- *                     Amauri  Celani  <acelani@essegi.net>
- *
- *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
- *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef MT352_H
-#define MT352_H
-
-#include <linux/dvb/frontend.h>
-
-struct mt352_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* frequencies in kHz */
-       int adc_clock;  // default: 20480
-       int if2;        // default: 36166
-
-       /* set if no pll is connected to the secondary i2c bus */
-       int no_tuner;
-
-       /* Initialise the demodulator and PLL. Cannot be NULL */
-       int (*demod_init)(struct dvb_frontend* fe);
-};
-
-#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE))
-extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
-                                        struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
-                                        struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_MT352
-
-static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) {
-       int r = 0;
-       if (fe->ops.write)
-               r = fe->ops.write(fe, buf, len);
-       return r;
-}
-
-#endif // MT352_H
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h
deleted file mode 100644 (file)
index 44ad0d4..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- *  Driver for Zarlink DVB-T MT352 demodulator
- *
- *  Written by Holger Waechtler <holger@qanu.de>
- *      and Daniel Mack <daniel@qanu.de>
- *
- *  AVerMedia AVerTV DVB-T 771 support by
- *       Wolfram Joost <dbox2@frokaschwei.de>
- *
- *  Support for Samsung TDTC9251DH01C(M) tuner
- *  Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
- *                     Amauri  Celani  <acelani@essegi.net>
- *
- *  DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
- *       Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef _MT352_PRIV_
-#define _MT352_PRIV_
-
-#define ID_MT352        0x13
-
-#define msb(x) (((x) >> 8) & 0xff)
-#define lsb(x) ((x) & 0xff)
-
-enum mt352_reg_addr {
-       STATUS_0           = 0x00,
-       STATUS_1           = 0x01,
-       STATUS_2           = 0x02,
-       STATUS_3           = 0x03,
-       STATUS_4           = 0x04,
-       INTERRUPT_0        = 0x05,
-       INTERRUPT_1        = 0x06,
-       INTERRUPT_2        = 0x07,
-       INTERRUPT_3        = 0x08,
-       SNR                = 0x09,
-       VIT_ERR_CNT_2      = 0x0A,
-       VIT_ERR_CNT_1      = 0x0B,
-       VIT_ERR_CNT_0      = 0x0C,
-       RS_ERR_CNT_2       = 0x0D,
-       RS_ERR_CNT_1       = 0x0E,
-       RS_ERR_CNT_0       = 0x0F,
-       RS_UBC_1           = 0x10,
-       RS_UBC_0           = 0x11,
-       AGC_GAIN_3         = 0x12,
-       AGC_GAIN_2         = 0x13,
-       AGC_GAIN_1         = 0x14,
-       AGC_GAIN_0         = 0x15,
-       FREQ_OFFSET_2      = 0x17,
-       FREQ_OFFSET_1      = 0x18,
-       FREQ_OFFSET_0      = 0x19,
-       TIMING_OFFSET_1    = 0x1A,
-       TIMING_OFFSET_0    = 0x1B,
-       CHAN_FREQ_1        = 0x1C,
-       CHAN_FREQ_0        = 0x1D,
-       TPS_RECEIVED_1     = 0x1E,
-       TPS_RECEIVED_0     = 0x1F,
-       TPS_CURRENT_1      = 0x20,
-       TPS_CURRENT_0      = 0x21,
-       TPS_CELL_ID_1      = 0x22,
-       TPS_CELL_ID_0      = 0x23,
-       TPS_MISC_DATA_2    = 0x24,
-       TPS_MISC_DATA_1    = 0x25,
-       TPS_MISC_DATA_0    = 0x26,
-       RESET              = 0x50,
-       TPS_GIVEN_1        = 0x51,
-       TPS_GIVEN_0        = 0x52,
-       ACQ_CTL            = 0x53,
-       TRL_NOMINAL_RATE_1 = 0x54,
-       TRL_NOMINAL_RATE_0 = 0x55,
-       INPUT_FREQ_1       = 0x56,
-       INPUT_FREQ_0       = 0x57,
-       TUNER_ADDR         = 0x58,
-       CHAN_START_1       = 0x59,
-       CHAN_START_0       = 0x5A,
-       CONT_1             = 0x5B,
-       CONT_0             = 0x5C,
-       TUNER_GO           = 0x5D,
-       STATUS_EN_0        = 0x5F,
-       STATUS_EN_1        = 0x60,
-       INTERRUPT_EN_0     = 0x61,
-       INTERRUPT_EN_1     = 0x62,
-       INTERRUPT_EN_2     = 0x63,
-       INTERRUPT_EN_3     = 0x64,
-       AGC_TARGET         = 0x67,
-       AGC_CTL            = 0x68,
-       CAPT_RANGE         = 0x75,
-       SNR_SELECT_1       = 0x79,
-       SNR_SELECT_0       = 0x7A,
-       RS_ERR_PER_1       = 0x7C,
-       RS_ERR_PER_0       = 0x7D,
-       CHIP_ID            = 0x7F,
-       CHAN_STOP_1        = 0x80,
-       CHAN_STOP_0        = 0x81,
-       CHAN_STEP_1        = 0x82,
-       CHAN_STEP_0        = 0x83,
-       FEC_LOCK_TIME      = 0x85,
-       OFDM_LOCK_TIME     = 0x86,
-       ACQ_DELAY          = 0x87,
-       SCAN_CTL           = 0x88,
-       CLOCK_CTL          = 0x89,
-       CONFIG             = 0x8A,
-       MCLK_RATIO         = 0x8B,
-       GPP_CTL            = 0x8C,
-       ADC_CTL_1          = 0x8E,
-       ADC_CTL_0          = 0x8F
-};
-
-/* here we assume 1/6MHz == 166.66kHz stepsize */
-#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-
-#endif                          /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
deleted file mode 100644 (file)
index 8e28894..0000000
+++ /dev/null
@@ -1,1242 +0,0 @@
-/*
- *    Support for NXT2002 and NXT2004 - VSB/QAM
- *
- *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
- *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
- *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
- *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-/*
- *                      NOTES ABOUT THIS DRIVER
- *
- * This Linux driver supports:
- *   B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
- *   AverTVHD MCE A180 (NXT2004)
- *   ATI HDTV Wonder (NXT2004)
- *
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
- * download/extract the appropriate firmware, and then copy it to
- * /usr/lib/hotplug/firmware/ or /lib/firmware/
- * (depending on configuration of firmware hotplug).
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
-#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
-#define CRC_CCIT_MASK 0x1021
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "dvb_frontend.h"
-#include "nxt200x.h"
-
-struct nxt200x_state {
-
-       struct i2c_adapter* i2c;
-       const struct nxt200x_config* config;
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       nxt_chip_type demod_chip;
-       u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...)       do { if (debug) pr_debug(args); } while (0)
-
-static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
-{
-       int err;
-       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
-                       __func__, addr, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
-{
-       int err;
-       struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
-                       __func__, addr, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
-                              const u8 *buf, u8 len)
-{
-       u8 buf2 [len+1];
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
-
-       buf2[0] = reg;
-       memcpy(&buf2[1], buf, len);
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
-                       __func__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
-{
-       u8 reg2 [] = { reg };
-
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
-                       { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
-               pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
-                       __func__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static u16 nxt200x_crc(u16 crc, u8 c)
-{
-       u8 i;
-       u16 input = (u16) c & 0xFF;
-
-       input<<=8;
-       for(i=0; i<8; i++) {
-               if((crc^input) & 0x8000)
-                       crc=(crc<<1)^CRC_CCIT_MASK;
-               else
-                       crc<<=1;
-               input<<=1;
-       }
-       return crc;
-}
-
-static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
-{
-       u8 attr, len2, buf;
-       dprintk("%s\n", __func__);
-
-       /* set mutli register register */
-       nxt200x_writebytes(state, 0x35, &reg, 1);
-
-       /* send the actual data */
-       nxt200x_writebytes(state, 0x36, data, len);
-
-       switch (state->demod_chip) {
-               case NXT2002:
-                       len2 = len;
-                       buf = 0x02;
-                       break;
-               case NXT2004:
-                       /* probably not right, but gives correct values */
-                       attr = 0x02;
-                       if (reg & 0x80) {
-                               attr = attr << 1;
-                               if (reg & 0x04)
-                                       attr = attr >> 1;
-                       }
-                       /* set write bit */
-                       len2 = ((attr << 4) | 0x10) | len;
-                       buf = 0x80;
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       /* set multi register length */
-       nxt200x_writebytes(state, 0x34, &len2, 1);
-
-       /* toggle the multireg write bit */
-       nxt200x_writebytes(state, 0x21, &buf, 1);
-
-       nxt200x_readbytes(state, 0x21, &buf, 1);
-
-       switch (state->demod_chip) {
-               case NXT2002:
-                       if ((buf & 0x02) == 0)
-                               return 0;
-                       break;
-               case NXT2004:
-                       if (buf == 0)
-                               return 0;
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       pr_warn("Error writing multireg register 0x%02X\n", reg);
-
-       return 0;
-}
-
-static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
-{
-       int i;
-       u8 buf, len2, attr;
-       dprintk("%s\n", __func__);
-
-       /* set mutli register register */
-       nxt200x_writebytes(state, 0x35, &reg, 1);
-
-       switch (state->demod_chip) {
-               case NXT2002:
-                       /* set multi register length */
-                       len2 = len & 0x80;
-                       nxt200x_writebytes(state, 0x34, &len2, 1);
-
-                       /* read the actual data */
-                       nxt200x_readbytes(state, reg, data, len);
-                       return 0;
-                       break;
-               case NXT2004:
-                       /* probably not right, but gives correct values */
-                       attr = 0x02;
-                       if (reg & 0x80) {
-                               attr = attr << 1;
-                               if (reg & 0x04)
-                                       attr = attr >> 1;
-                       }
-
-                       /* set multi register length */
-                       len2 = (attr << 4) | len;
-                       nxt200x_writebytes(state, 0x34, &len2, 1);
-
-                       /* toggle the multireg bit*/
-                       buf = 0x80;
-                       nxt200x_writebytes(state, 0x21, &buf, 1);
-
-                       /* read the actual data */
-                       for(i = 0; i < len; i++) {
-                               nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
-                       }
-                       return 0;
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-}
-
-static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
-{
-       u8 buf, stopval, counter = 0;
-       dprintk("%s\n", __func__);
-
-       /* set correct stop value */
-       switch (state->demod_chip) {
-               case NXT2002:
-                       stopval = 0x40;
-                       break;
-               case NXT2004:
-                       stopval = 0x10;
-                       break;
-               default:
-                       stopval = 0;
-                       break;
-       }
-
-       buf = 0x80;
-       nxt200x_writebytes(state, 0x22, &buf, 1);
-
-       while (counter < 20) {
-               nxt200x_readbytes(state, 0x31, &buf, 1);
-               if (buf & stopval)
-                       return;
-               msleep(10);
-               counter++;
-       }
-
-       pr_warn("Timeout waiting for nxt200x to stop. This is ok after "
-               "firmware upload.\n");
-       return;
-}
-
-static void nxt200x_microcontroller_start (struct nxt200x_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __func__);
-
-       buf = 0x00;
-       nxt200x_writebytes(state, 0x22, &buf, 1);
-}
-
-static void nxt2004_microcontroller_init (struct nxt200x_state* state)
-{
-       u8 buf[9];
-       u8 counter = 0;
-       dprintk("%s\n", __func__);
-
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x2b, buf, 1);
-       buf[0] = 0x70;
-       nxt200x_writebytes(state, 0x34, buf, 1);
-       buf[0] = 0x04;
-       nxt200x_writebytes(state, 0x35, buf, 1);
-       buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
-       buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
-       nxt200x_writebytes(state, 0x36, buf, 9);
-       buf[0] = 0x80;
-       nxt200x_writebytes(state, 0x21, buf, 1);
-
-       while (counter < 20) {
-               nxt200x_readbytes(state, 0x21, buf, 1);
-               if (buf[0] == 0)
-                       return;
-               msleep(10);
-               counter++;
-       }
-
-       pr_warn("Timeout waiting for nxt2004 to init.\n");
-
-       return;
-}
-
-static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
-{
-       u8 buf, count = 0;
-
-       dprintk("%s\n", __func__);
-
-       dprintk("Tuner Bytes: %*ph\n", 4, data + 1);
-
-       /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
-        * direct write is required for Philips TUV1236D and ALPS TDHU2 */
-       switch (state->demod_chip) {
-               case NXT2004:
-                       if (i2c_writebytes(state, data[0], data+1, 4))
-                               pr_warn("error writing to tuner\n");
-                       /* wait until we have a lock */
-                       while (count < 20) {
-                               i2c_readbytes(state, data[0], &buf, 1);
-                               if (buf & 0x40)
-                                       return 0;
-                               msleep(100);
-                               count++;
-                       }
-                       pr_warn("timeout waiting for tuner lock\n");
-                       break;
-               case NXT2002:
-                       /* set the i2c transfer speed to the tuner */
-                       buf = 0x03;
-                       nxt200x_writebytes(state, 0x20, &buf, 1);
-
-                       /* setup to transfer 4 bytes via i2c */
-                       buf = 0x04;
-                       nxt200x_writebytes(state, 0x34, &buf, 1);
-
-                       /* write actual tuner bytes */
-                       nxt200x_writebytes(state, 0x36, data+1, 4);
-
-                       /* set tuner i2c address */
-                       buf = data[0] << 1;
-                       nxt200x_writebytes(state, 0x35, &buf, 1);
-
-                       /* write UC Opmode to begin transfer */
-                       buf = 0x80;
-                       nxt200x_writebytes(state, 0x21, &buf, 1);
-
-                       while (count < 20) {
-                               nxt200x_readbytes(state, 0x21, &buf, 1);
-                               if ((buf & 0x80)== 0x00)
-                                       return 0;
-                               msleep(100);
-                               count++;
-                       }
-                       pr_warn("timeout error writing to tuner\n");
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-       return 0;
-}
-
-static void nxt200x_agc_reset(struct nxt200x_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __func__);
-
-       switch (state->demod_chip) {
-               case NXT2002:
-                       buf = 0x08;
-                       nxt200x_writebytes(state, 0x08, &buf, 1);
-                       buf = 0x00;
-                       nxt200x_writebytes(state, 0x08, &buf, 1);
-                       break;
-               case NXT2004:
-                       nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
-                       buf = 0x08;
-                       nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
-                       buf = 0x00;
-                       nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
-                       break;
-               default:
-                       break;
-       }
-       return;
-}
-
-static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 buf[3], written = 0, chunkpos = 0;
-       u16 rambase, position, crc = 0;
-
-       dprintk("%s\n", __func__);
-       dprintk("Firmware is %zu bytes\n", fw->size);
-
-       /* Get the RAM base for this nxt2002 */
-       nxt200x_readbytes(state, 0x10, buf, 1);
-
-       if (buf[0] & 0x10)
-               rambase = 0x1000;
-       else
-               rambase = 0x0000;
-
-       dprintk("rambase on this nxt2002 is %04X\n", rambase);
-
-       /* Hold the micro in reset while loading firmware */
-       buf[0] = 0x80;
-       nxt200x_writebytes(state, 0x2B, buf, 1);
-
-       for (position = 0; position < fw->size; position++) {
-               if (written == 0) {
-                       crc = 0;
-                       chunkpos = 0x28;
-                       buf[0] = ((rambase + position) >> 8);
-                       buf[1] = (rambase + position) & 0xFF;
-                       buf[2] = 0x81;
-                       /* write starting address */
-                       nxt200x_writebytes(state, 0x29, buf, 3);
-               }
-               written++;
-               chunkpos++;
-
-               if ((written % 4) == 0)
-                       nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
-
-               crc = nxt200x_crc(crc, fw->data[position]);
-
-               if ((written == 255) || (position+1 == fw->size)) {
-                       /* write remaining bytes of firmware */
-                       nxt200x_writebytes(state, chunkpos+4-(written %4),
-                               &fw->data[position-(written %4) + 1],
-                               written %4);
-                       buf[0] = crc << 8;
-                       buf[1] = crc & 0xFF;
-
-                       /* write crc */
-                       nxt200x_writebytes(state, 0x2C, buf, 2);
-
-                       /* do a read to stop things */
-                       nxt200x_readbytes(state, 0x2A, buf, 1);
-
-                       /* set transfer mode to complete */
-                       buf[0] = 0x80;
-                       nxt200x_writebytes(state, 0x2B, buf, 1);
-
-                       written = 0;
-               }
-       }
-
-       return 0;
-};
-
-static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 buf[3];
-       u16 rambase, position, crc=0;
-
-       dprintk("%s\n", __func__);
-       dprintk("Firmware is %zu bytes\n", fw->size);
-
-       /* set rambase */
-       rambase = 0x1000;
-
-       /* hold the micro in reset while loading firmware */
-       buf[0] = 0x80;
-       nxt200x_writebytes(state, 0x2B, buf,1);
-
-       /* calculate firmware CRC */
-       for (position = 0; position < fw->size; position++) {
-               crc = nxt200x_crc(crc, fw->data[position]);
-       }
-
-       buf[0] = rambase >> 8;
-       buf[1] = rambase & 0xFF;
-       buf[2] = 0x81;
-       /* write starting address */
-       nxt200x_writebytes(state,0x29,buf,3);
-
-       for (position = 0; position < fw->size;) {
-               nxt200x_writebytes(state, 0x2C, &fw->data[position],
-                       fw->size-position > 255 ? 255 : fw->size-position);
-               position += (fw->size-position > 255 ? 255 : fw->size-position);
-       }
-       buf[0] = crc >> 8;
-       buf[1] = crc & 0xFF;
-
-       dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
-
-       /* write crc */
-       nxt200x_writebytes(state, 0x2C, buf,2);
-
-       /* do a read to stop things */
-       nxt200x_readbytes(state, 0x2C, buf, 1);
-
-       /* set transfer mode to complete */
-       buf[0] = 0x80;
-       nxt200x_writebytes(state, 0x2B, buf,1);
-
-       return 0;
-};
-
-static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 buf[5];
-
-       /* stop the micro first */
-       nxt200x_microcontroller_stop(state);
-
-       if (state->demod_chip == NXT2004) {
-               /* make sure demod is set to digital */
-               buf[0] = 0x04;
-               nxt200x_writebytes(state, 0x14, buf, 1);
-               buf[0] = 0x00;
-               nxt200x_writebytes(state, 0x17, buf, 1);
-       }
-
-       /* set additional params */
-       switch (p->modulation) {
-               case QAM_64:
-               case QAM_256:
-                       /* Set punctured clock for QAM */
-                       /* This is just a guess since I am unable to test it */
-                       if (state->config->set_ts_params)
-                               state->config->set_ts_params(fe, 1);
-                       break;
-               case VSB_8:
-                       /* Set non-punctured clock for VSB */
-                       if (state->config->set_ts_params)
-                               state->config->set_ts_params(fe, 0);
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       if (fe->ops.tuner_ops.calc_regs) {
-               /* get tuning information */
-               fe->ops.tuner_ops.calc_regs(fe, buf, 5);
-
-               /* write frequency information */
-               nxt200x_writetuner(state, buf);
-       }
-
-       /* reset the agc now that tuning has been completed */
-       nxt200x_agc_reset(state);
-
-       /* set target power level */
-       switch (p->modulation) {
-               case QAM_64:
-               case QAM_256:
-                       buf[0] = 0x74;
-                       break;
-               case VSB_8:
-                       buf[0] = 0x70;
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-       nxt200x_writebytes(state, 0x42, buf, 1);
-
-       /* configure sdm */
-       switch (state->demod_chip) {
-               case NXT2002:
-                       buf[0] = 0x87;
-                       break;
-               case NXT2004:
-                       buf[0] = 0x07;
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-       nxt200x_writebytes(state, 0x57, buf, 1);
-
-       /* write sdm1 input */
-       buf[0] = 0x10;
-       buf[1] = 0x00;
-       switch (state->demod_chip) {
-               case NXT2002:
-                       nxt200x_writereg_multibyte(state, 0x58, buf, 2);
-                       break;
-               case NXT2004:
-                       nxt200x_writebytes(state, 0x58, buf, 2);
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       /* write sdmx input */
-       switch (p->modulation) {
-               case QAM_64:
-                               buf[0] = 0x68;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x64;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x60;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       buf[1] = 0x00;
-       switch (state->demod_chip) {
-               case NXT2002:
-                       nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
-                       break;
-               case NXT2004:
-                       nxt200x_writebytes(state, 0x5C, buf, 2);
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       /* write adc power lpf fc */
-       buf[0] = 0x05;
-       nxt200x_writebytes(state, 0x43, buf, 1);
-
-       if (state->demod_chip == NXT2004) {
-               /* write ??? */
-               buf[0] = 0x00;
-               buf[1] = 0x00;
-               nxt200x_writebytes(state, 0x46, buf, 2);
-       }
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       switch (state->demod_chip) {
-               case NXT2002:
-                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
-                       break;
-               case NXT2004:
-                       nxt200x_writebytes(state, 0x4B, buf, 2);
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       /* write kg1 */
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x4D, buf, 1);
-
-       /* write sdm12 lpf fc */
-       buf[0] = 0x44;
-       nxt200x_writebytes(state, 0x55, buf, 1);
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       nxt200x_writebytes(state, 0x41, buf, 1);
-
-       if (state->demod_chip == NXT2004) {
-               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-               buf[0] = 0x24;
-               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-               /* soft reset? */
-               nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-               buf[0] = 0x10;
-               nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-               nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-               buf[0] = 0x00;
-               nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-
-               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-               buf[0] = 0x04;
-               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-               buf[0] = 0x00;
-               nxt200x_writereg_multibyte(state, 0x81, buf, 1);
-               buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
-               nxt200x_writereg_multibyte(state, 0x82, buf, 3);
-               nxt200x_readreg_multibyte(state, 0x88, buf, 1);
-               buf[0] = 0x11;
-               nxt200x_writereg_multibyte(state, 0x88, buf, 1);
-               nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-               buf[0] = 0x44;
-               nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-       }
-
-       /* write agc ucgp0 */
-       switch (p->modulation) {
-               case QAM_64:
-                               buf[0] = 0x02;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x03;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x00;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       nxt200x_writebytes(state, 0x30, buf, 1);
-
-       /* write agc control reg */
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x41, buf, 1);
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       switch (state->demod_chip) {
-               case NXT2002:
-                       nxt200x_writereg_multibyte(state, 0x49, buf, 2);
-                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
-                       break;
-               case NXT2004:
-                       nxt200x_writebytes(state, 0x49, buf, 2);
-                       nxt200x_writebytes(state, 0x4B, buf, 2);
-                       break;
-               default:
-                       return -EINVAL;
-                       break;
-       }
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       nxt200x_writebytes(state, 0x41, buf, 1);
-
-       nxt200x_microcontroller_start(state);
-
-       if (state->demod_chip == NXT2004) {
-               nxt2004_microcontroller_init(state);
-
-               /* ???? */
-               buf[0] = 0xF0;
-               buf[1] = 0x00;
-               nxt200x_writebytes(state, 0x5C, buf, 2);
-       }
-
-       /* adjacent channel detection should be done here, but I don't
-       have any stations with this need so I cannot test it */
-
-       return 0;
-}
-
-static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 lock;
-       nxt200x_readbytes(state, 0x31, &lock, 1);
-
-       *status = 0;
-       if (lock & 0x20) {
-               *status |= FE_HAS_SIGNAL;
-               *status |= FE_HAS_CARRIER;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-               *status |= FE_HAS_LOCK;
-       }
-       return 0;
-}
-
-static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt200x_readreg_multibyte(state, 0xE6, b, 3);
-
-       *ber = ((b[0] << 8) + b[1]) * 8;
-
-       return 0;
-}
-
-static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       nxt200x_writebytes(state, 0xA1, b, 1);
-
-       /* get multreg val */
-       nxt200x_readreg_multibyte(state, 0xA6, b, 2);
-
-       temp = (b[0] << 8) | b[1];
-       *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
-
-       return 0;
-}
-
-static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0, temp2;
-       u32 snrdb = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       nxt200x_writebytes(state, 0xA1, b, 1);
-
-       /* get multreg val from 0xA6 */
-       nxt200x_readreg_multibyte(state, 0xA6, b, 2);
-
-       temp = (b[0] << 8) | b[1];
-       temp2 = 0x7FFF - temp;
-
-       /* snr will be in db */
-       if (temp2 > 0x7F00)
-               snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
-       else if (temp2 > 0x7EC0)
-               snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
-       else if (temp2 > 0x7C00)
-               snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
-       else
-               snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
-
-       /* the value reported back from the frontend will be FFFF=32db 0000=0db */
-       *snr = snrdb * (0xFFFF/32000);
-
-       return 0;
-}
-
-static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt200x_readreg_multibyte(state, 0xE6, b, 3);
-       *ucblocks = b[2];
-
-       return 0;
-}
-
-static int nxt200x_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int nxt2002_init(struct dvb_frontend* fe)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret;
-       u8 buf[2];
-
-       /* request the firmware, this will block until someone uploads it */
-       pr_debug("%s: Waiting for firmware upload (%s)...\n",
-                __func__, NXT2002_DEFAULT_FIRMWARE);
-       ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
-                              state->i2c->dev.parent);
-       pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
-       if (ret) {
-               pr_err("%s: No firmware uploaded (timeout or file not found?)"
-                      "\n", __func__);
-               return ret;
-       }
-
-       ret = nxt2002_load_firmware(fe, fw);
-       release_firmware(fw);
-       if (ret) {
-               pr_err("%s: Writing firmware to device failed\n", __func__);
-               return ret;
-       }
-       pr_info("%s: Firmware upload complete\n", __func__);
-
-       /* Put the micro into reset */
-       nxt200x_microcontroller_stop(state);
-
-       /* ensure transfer is complete */
-       buf[0]=0x00;
-       nxt200x_writebytes(state, 0x2B, buf, 1);
-
-       /* Put the micro into reset for real this time */
-       nxt200x_microcontroller_stop(state);
-
-       /* soft reset everything (agc,frontend,eq,fec)*/
-       buf[0] = 0x0F;
-       nxt200x_writebytes(state, 0x08, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x08, buf, 1);
-
-       /* write agc sdm configure */
-       buf[0] = 0xF1;
-       nxt200x_writebytes(state, 0x57, buf, 1);
-
-       /* write mod output format */
-       buf[0] = 0x20;
-       nxt200x_writebytes(state, 0x09, buf, 1);
-
-       /* write fec mpeg mode */
-       buf[0] = 0x7E;
-       buf[1] = 0x00;
-       nxt200x_writebytes(state, 0xE9, buf, 2);
-
-       /* write mux selection */
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0xCC, buf, 1);
-
-       return 0;
-}
-
-static int nxt2004_init(struct dvb_frontend* fe)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret;
-       u8 buf[3];
-
-       /* ??? */
-       buf[0]=0x00;
-       nxt200x_writebytes(state, 0x1E, buf, 1);
-
-       /* request the firmware, this will block until someone uploads it */
-       pr_debug("%s: Waiting for firmware upload (%s)...\n",
-                __func__, NXT2004_DEFAULT_FIRMWARE);
-       ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
-                              state->i2c->dev.parent);
-       pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
-       if (ret) {
-               pr_err("%s: No firmware uploaded (timeout or file not found?)"
-                      "\n", __func__);
-               return ret;
-       }
-
-       ret = nxt2004_load_firmware(fe, fw);
-       release_firmware(fw);
-       if (ret) {
-               pr_err("%s: Writing firmware to device failed\n", __func__);
-               return ret;
-       }
-       pr_info("%s: Firmware upload complete\n", __func__);
-
-       /* ensure transfer is complete */
-       buf[0] = 0x01;
-       nxt200x_writebytes(state, 0x19, buf, 1);
-
-       nxt2004_microcontroller_init(state);
-       nxt200x_microcontroller_stop(state);
-       nxt200x_microcontroller_stop(state);
-       nxt2004_microcontroller_init(state);
-       nxt200x_microcontroller_stop(state);
-
-       /* soft reset everything (agc,frontend,eq,fec)*/
-       buf[0] = 0xFF;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-
-       /* write agc sdm configure */
-       buf[0] = 0xD7;
-       nxt200x_writebytes(state, 0x57, buf, 1);
-
-       /* ???*/
-       buf[0] = 0x07;
-       buf[1] = 0xfe;
-       nxt200x_writebytes(state, 0x35, buf, 2);
-       buf[0] = 0x12;
-       nxt200x_writebytes(state, 0x34, buf, 1);
-       buf[0] = 0x80;
-       nxt200x_writebytes(state, 0x21, buf, 1);
-
-       /* ???*/
-       buf[0] = 0x21;
-       nxt200x_writebytes(state, 0x0A, buf, 1);
-
-       /* ???*/
-       buf[0] = 0x01;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-       /* write fec mpeg mode */
-       buf[0] = 0x7E;
-       buf[1] = 0x00;
-       nxt200x_writebytes(state, 0xE9, buf, 2);
-
-       /* write mux selection */
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0xCC, buf, 1);
-
-       /* ???*/
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-       /* soft reset? */
-       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-       buf[0] = 0x10;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-
-       /* ???*/
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x01;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x70;
-       nxt200x_writereg_multibyte(state, 0x81, buf, 1);
-       buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
-       nxt200x_writereg_multibyte(state, 0x82, buf, 3);
-
-       nxt200x_readreg_multibyte(state, 0x88, buf, 1);
-       buf[0] = 0x11;
-       nxt200x_writereg_multibyte(state, 0x88, buf, 1);
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x40;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-       nxt200x_readbytes(state, 0x10, buf, 1);
-       buf[0] = 0x10;
-       nxt200x_writebytes(state, 0x10, buf, 1);
-       nxt200x_readbytes(state, 0x0A, buf, 1);
-       buf[0] = 0x21;
-       nxt200x_writebytes(state, 0x0A, buf, 1);
-
-       nxt2004_microcontroller_init(state);
-
-       buf[0] = 0x21;
-       nxt200x_writebytes(state, 0x0A, buf, 1);
-       buf[0] = 0x7E;
-       nxt200x_writebytes(state, 0xE9, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0xEA, buf, 1);
-
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-       /* soft reset? */
-       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-       buf[0] = 0x10;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-       nxt200x_readreg_multibyte(state, 0x08, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x08, buf, 1);
-
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x04;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x81, buf, 1);
-       buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
-       nxt200x_writereg_multibyte(state, 0x82, buf, 3);
-
-       nxt200x_readreg_multibyte(state, 0x88, buf, 1);
-       buf[0] = 0x11;
-       nxt200x_writereg_multibyte(state, 0x88, buf, 1);
-
-       nxt200x_readreg_multibyte(state, 0x80, buf, 1);
-       buf[0] = 0x44;
-       nxt200x_writereg_multibyte(state, 0x80, buf, 1);
-
-       /* initialize tuner */
-       nxt200x_readbytes(state, 0x10, buf, 1);
-       buf[0] = 0x12;
-       nxt200x_writebytes(state, 0x10, buf, 1);
-       buf[0] = 0x04;
-       nxt200x_writebytes(state, 0x13, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x16, buf, 1);
-       buf[0] = 0x04;
-       nxt200x_writebytes(state, 0x14, buf, 1);
-       buf[0] = 0x00;
-       nxt200x_writebytes(state, 0x14, buf, 1);
-       nxt200x_writebytes(state, 0x17, buf, 1);
-       nxt200x_writebytes(state, 0x14, buf, 1);
-       nxt200x_writebytes(state, 0x17, buf, 1);
-
-       return 0;
-}
-
-static int nxt200x_init(struct dvb_frontend* fe)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       int ret = 0;
-
-       if (!state->initialised) {
-               switch (state->demod_chip) {
-                       case NXT2002:
-                               ret = nxt2002_init(fe);
-                               break;
-                       case NXT2004:
-                               ret = nxt2004_init(fe);
-                               break;
-                       default:
-                               return -EINVAL;
-                               break;
-               }
-               state->initialised = 1;
-       }
-       return ret;
-}
-
-static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 500;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void nxt200x_release(struct dvb_frontend* fe)
-{
-       struct nxt200x_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops nxt200x_ops;
-
-struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct nxt200x_state* state = NULL;
-       u8 buf [] = {0,0,0,0,0};
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-
-       /* read card id */
-       nxt200x_readbytes(state, 0x00, buf, 5);
-       dprintk("NXT info: %*ph\n", 5, buf);
-
-       /* set demod chip */
-       switch (buf[0]) {
-               case 0x04:
-                       state->demod_chip = NXT2002;
-                       pr_info("NXT2002 Detected\n");
-                       break;
-               case 0x05:
-                       state->demod_chip = NXT2004;
-                       pr_info("NXT2004 Detected\n");
-                       break;
-               default:
-                       goto error;
-       }
-
-       /* make sure demod chip is supported */
-       switch (state->demod_chip) {
-               case NXT2002:
-                       if (buf[0] != 0x04) goto error;         /* device id */
-                       if (buf[1] != 0x02) goto error;         /* fab id */
-                       if (buf[2] != 0x11) goto error;         /* month */
-                       if (buf[3] != 0x20) goto error;         /* year msb */
-                       if (buf[4] != 0x00) goto error;         /* year lsb */
-                       break;
-               case NXT2004:
-                       if (buf[0] != 0x05) goto error;         /* device id */
-                       break;
-               default:
-                       goto error;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       pr_err("Unknown/Unsupported NXT chip: %*ph\n", 5, buf);
-       return NULL;
-}
-
-static struct dvb_frontend_ops nxt200x_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name = "Nextwave NXT200X VSB/QAM frontend",
-               .frequency_min =  54000000,
-               .frequency_max = 860000000,
-               .frequency_stepsize = 166666,   /* stepsize is just a guess */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
-       },
-
-       .release = nxt200x_release,
-
-       .init = nxt200x_init,
-       .sleep = nxt200x_sleep,
-
-       .set_frontend = nxt200x_setup_frontend_parameters,
-       .get_tune_settings = nxt200x_get_tune_settings,
-
-       .read_status = nxt200x_read_status,
-       .read_ber = nxt200x_read_ber,
-       .read_signal_strength = nxt200x_read_signal_strength,
-       .read_snr = nxt200x_read_snr,
-       .read_ucblocks = nxt200x_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(nxt200x_attach);
-
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
deleted file mode 100644 (file)
index f3c8458..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *    Support for NXT2002 and NXT2004 - VSB/QAM
- *
- *    Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
- *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
- *    and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-#ifndef NXT200X_H
-#define NXT200X_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-typedef enum nxt_chip_t {
-               NXTUNDEFINED,
-               NXT2002,
-               NXT2004
-}nxt_chip_type;
-
-struct nxt200x_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* need to set device param for start_dma */
-       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
-};
-
-#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_NXT200X
-
-#endif /* NXT200X_H */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
deleted file mode 100644 (file)
index 90ae6c7..0000000
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
-       NxtWave Communications - NXT6000 demodulator driver
-
-    Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
-    Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "nxt6000_priv.h"
-#include "nxt6000.h"
-
-
-
-struct nxt6000_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct nxt6000_config* config;
-       struct dvb_frontend frontend;
-};
-
-static int debug;
-#define dprintk if (debug) printk
-
-static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
-       int ret;
-
-       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
-               dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
-
-       return (ret != 1) ? -EIO : 0;
-}
-
-static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msgs[] = {
-               {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
-               {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
-       };
-
-       ret = i2c_transfer(state->i2c, msgs, 2);
-
-       if (ret != 2)
-               dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
-
-       return b1[0];
-}
-
-static void nxt6000_reset(struct nxt6000_state* state)
-{
-       u8 val;
-
-       val = nxt6000_readreg(state, OFDM_COR_CTL);
-
-       nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
-       nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
-}
-
-static int nxt6000_set_bandwidth(struct nxt6000_state *state, u32 bandwidth)
-{
-       u16 nominal_rate;
-       int result;
-
-       switch (bandwidth) {
-       case 6000000:
-               nominal_rate = 0x55B7;
-               break;
-
-       case 7000000:
-               nominal_rate = 0x6400;
-               break;
-
-       case 8000000:
-               nominal_rate = 0x7249;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
-               return result;
-
-       return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
-}
-
-static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
-{
-       switch (guard_interval) {
-
-       case GUARD_INTERVAL_1_32:
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
-
-       case GUARD_INTERVAL_1_16:
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
-
-       case GUARD_INTERVAL_AUTO:
-       case GUARD_INTERVAL_1_8:
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
-
-       case GUARD_INTERVAL_1_4:
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
-{
-       switch (inversion) {
-
-       case INVERSION_OFF:
-               return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
-
-       case INVERSION_ON:
-               return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
-
-       default:
-               return -EINVAL;
-
-       }
-}
-
-static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
-{
-       int result;
-
-       switch (transmission_mode) {
-
-       case TRANSMISSION_MODE_2K:
-               if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
-                       return result;
-
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
-
-       case TRANSMISSION_MODE_8K:
-       case TRANSMISSION_MODE_AUTO:
-               if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
-                       return result;
-
-               return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
-
-       default:
-               return -EINVAL;
-
-       }
-}
-
-static void nxt6000_setup(struct dvb_frontend* fe)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
-       nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
-       nxt6000_writereg(state, VIT_BERTIME_2, 0x00);  // BER Timer = 0x000200 * 256 = 131072 bits
-       nxt6000_writereg(state, VIT_BERTIME_1, 0x02);  //
-       nxt6000_writereg(state, VIT_BERTIME_0, 0x00);  //
-       nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
-       nxt6000_writereg(state, VIT_COR_CTL, 0x82);   // Enable BER measurement
-       nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
-       nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
-       nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
-       nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
-       nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
-       nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
-       nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
-       nxt6000_writereg(state, CAS_FREQ, 0xBB);        /* CHECKME */
-       nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
-       nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
-       nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
-       nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
-       nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
-       nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
-       nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
-
-       if (state->config->clock_inversion)
-               nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
-       else
-               nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
-
-       nxt6000_writereg(state, TS_FORMAT, 0);
-}
-
-static void nxt6000_dump_status(struct nxt6000_state *state)
-{
-       u8 val;
-
-/*
-       printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
-       printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
-       printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
-       printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
-       printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
-       printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
-       printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
-       printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
-       printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
-       printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
-*/
-       printk("NXT6000 status:");
-
-       val = nxt6000_readreg(state, RS_COR_STAT);
-
-       printk(" DATA DESCR LOCK: %d,", val & 0x01);
-       printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
-
-       val = nxt6000_readreg(state, VIT_SYNC_STATUS);
-
-       printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
-
-       switch ((val >> 4) & 0x07) {
-
-       case 0x00:
-               printk(" VITERBI CODERATE: 1/2,");
-               break;
-
-       case 0x01:
-               printk(" VITERBI CODERATE: 2/3,");
-               break;
-
-       case 0x02:
-               printk(" VITERBI CODERATE: 3/4,");
-               break;
-
-       case 0x03:
-               printk(" VITERBI CODERATE: 5/6,");
-               break;
-
-       case 0x04:
-               printk(" VITERBI CODERATE: 7/8,");
-               break;
-
-       default:
-               printk(" VITERBI CODERATE: Reserved,");
-
-       }
-
-       val = nxt6000_readreg(state, OFDM_COR_STAT);
-
-       printk(" CHCTrack: %d,", (val >> 7) & 0x01);
-       printk(" TPSLock: %d,", (val >> 6) & 0x01);
-       printk(" SYRLock: %d,", (val >> 5) & 0x01);
-       printk(" AGCLock: %d,", (val >> 4) & 0x01);
-
-       switch (val & 0x0F) {
-
-       case 0x00:
-               printk(" CoreState: IDLE,");
-               break;
-
-       case 0x02:
-               printk(" CoreState: WAIT_AGC,");
-               break;
-
-       case 0x03:
-               printk(" CoreState: WAIT_SYR,");
-               break;
-
-       case 0x04:
-               printk(" CoreState: WAIT_PPM,");
-               break;
-
-       case 0x01:
-               printk(" CoreState: WAIT_TRL,");
-               break;
-
-       case 0x05:
-               printk(" CoreState: WAIT_TPS,");
-               break;
-
-       case 0x06:
-               printk(" CoreState: MONITOR_TPS,");
-               break;
-
-       default:
-               printk(" CoreState: Reserved,");
-
-       }
-
-       val = nxt6000_readreg(state, OFDM_SYR_STAT);
-
-       printk(" SYRLock: %d,", (val >> 4) & 0x01);
-       printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
-
-       switch ((val >> 4) & 0x03) {
-
-       case 0x00:
-               printk(" SYRGuard: 1/32,");
-               break;
-
-       case 0x01:
-               printk(" SYRGuard: 1/16,");
-               break;
-
-       case 0x02:
-               printk(" SYRGuard: 1/8,");
-               break;
-
-       case 0x03:
-               printk(" SYRGuard: 1/4,");
-               break;
-       }
-
-       val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
-
-       switch ((val >> 4) & 0x07) {
-
-       case 0x00:
-               printk(" TPSLP: 1/2,");
-               break;
-
-       case 0x01:
-               printk(" TPSLP: 2/3,");
-               break;
-
-       case 0x02:
-               printk(" TPSLP: 3/4,");
-               break;
-
-       case 0x03:
-               printk(" TPSLP: 5/6,");
-               break;
-
-       case 0x04:
-               printk(" TPSLP: 7/8,");
-               break;
-
-       default:
-               printk(" TPSLP: Reserved,");
-
-       }
-
-       switch (val & 0x07) {
-
-       case 0x00:
-               printk(" TPSHP: 1/2,");
-               break;
-
-       case 0x01:
-               printk(" TPSHP: 2/3,");
-               break;
-
-       case 0x02:
-               printk(" TPSHP: 3/4,");
-               break;
-
-       case 0x03:
-               printk(" TPSHP: 5/6,");
-               break;
-
-       case 0x04:
-               printk(" TPSHP: 7/8,");
-               break;
-
-       default:
-               printk(" TPSHP: Reserved,");
-
-       }
-
-       val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
-
-       printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
-
-       switch ((val >> 4) & 0x03) {
-
-       case 0x00:
-               printk(" TPSGuard: 1/32,");
-               break;
-
-       case 0x01:
-               printk(" TPSGuard: 1/16,");
-               break;
-
-       case 0x02:
-               printk(" TPSGuard: 1/8,");
-               break;
-
-       case 0x03:
-               printk(" TPSGuard: 1/4,");
-               break;
-
-       }
-
-       /* Strange magic required to gain access to RF_AGC_STATUS */
-       nxt6000_readreg(state, RF_AGC_VAL_1);
-       val = nxt6000_readreg(state, RF_AGC_STATUS);
-       val = nxt6000_readreg(state, RF_AGC_STATUS);
-
-       printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
-       printk("\n");
-}
-
-static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       u8 core_status;
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       *status = 0;
-
-       core_status = nxt6000_readreg(state, OFDM_COR_STAT);
-
-       if (core_status & AGCLOCKED)
-               *status |= FE_HAS_SIGNAL;
-
-       if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
-               *status |= FE_HAS_CARRIER;
-
-       if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
-               *status |= FE_HAS_VITERBI;
-
-       if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
-               *status |= FE_HAS_SYNC;
-
-       if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
-               *status |= FE_HAS_LOCK;
-
-       if (debug)
-               nxt6000_dump_status(state);
-
-       return 0;
-}
-
-static int nxt6000_init(struct dvb_frontend* fe)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       nxt6000_reset(state);
-       nxt6000_setup(fe);
-
-       return 0;
-}
-
-static int nxt6000_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct nxt6000_state* state = fe->demodulator_priv;
-       int result;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       result = nxt6000_set_bandwidth(state, p->bandwidth_hz);
-       if (result < 0)
-               return result;
-
-       result = nxt6000_set_guard_interval(state, p->guard_interval);
-       if (result < 0)
-               return result;
-
-       result = nxt6000_set_transmission_mode(state, p->transmission_mode);
-       if (result < 0)
-               return result;
-
-       result = nxt6000_set_inversion(state, p->inversion);
-       if (result < 0)
-               return result;
-
-       msleep(500);
-       return 0;
-}
-
-static void nxt6000_release(struct dvb_frontend* fe)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
-
-       return 0;
-}
-
-static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
-
-       *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
-               nxt6000_readreg( state, VIT_BER_0 );
-
-       nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
-
-       return 0;
-}
-
-static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       *signal_strength = (short) (511 -
-               (nxt6000_readreg(state, AGC_GAIN_1) +
-               ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
-
-       return 0;
-}
-
-static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 500;
-       return 0;
-}
-
-static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct nxt6000_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);
-       } else {
-               return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);
-       }
-}
-
-static struct dvb_frontend_ops nxt6000_ops;
-
-struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct nxt6000_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops nxt6000_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "NxtWave NXT6000 DVB-T",
-               .frequency_min = 0,
-               .frequency_max = 863250000,
-               .frequency_stepsize = 62500,
-               /*.frequency_tolerance = *//* FIXME: 12% of SR */
-               .symbol_rate_min = 0,   /* FIXME */
-               .symbol_rate_max = 9360000,     /* FIXME */
-               .symbol_rate_tolerance = 4000,
-               .caps = 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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = nxt6000_release,
-
-       .init = nxt6000_init,
-       .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl,
-
-       .get_tune_settings = nxt6000_fe_get_tune_settings,
-
-       .set_frontend = nxt6000_set_frontend,
-
-       .read_status = nxt6000_read_status,
-       .read_ber = nxt6000_read_ber,
-       .read_signal_strength = nxt6000_read_signal_strength,
-       .read_snr = nxt6000_read_snr,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
-MODULE_AUTHOR("Florian Schirmer");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
deleted file mode 100644 (file)
index 878eb38..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-       NxtWave Communications - NXT6000 demodulator driver
-
-    Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
-    Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef NXT6000_H
-#define NXT6000_H
-
-#include <linux/dvb/frontend.h>
-
-struct nxt6000_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* should clock inversion be used? */
-       u8 clock_inversion:1;
-};
-
-#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE))
-extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_NXT6000
-
-#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
deleted file mode 100644 (file)
index 0422e58..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Public Include File for DRV6000 users
- * (ie. NxtWave Communications - NXT6000 demodulator driver)
- *
- * Copyright (C) 2001 NxtWave Communications, Inc.
- *
- */
-
-/*  Nxt6000 Register Addresses and Bit Masks */
-
-/* Maximum Register Number */
-#define MAXNXT6000REG          (0x9A)
-
-/* 0x1B A_VIT_BER_0  aka 0x3A */
-#define A_VIT_BER_0            (0x1B)
-
-/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
-#define A_VIT_BER_TIMER_0      (0x1D)
-
-/* 0x21 RS_COR_STAT */
-#define RS_COR_STAT            (0x21)
-#define RSCORESTATUS           (0x03)
-
-/* 0x22 RS_COR_INTEN */
-#define RS_COR_INTEN           (0x22)
-
-/* 0x23 RS_COR_INSTAT */
-#define RS_COR_INSTAT          (0x23)
-#define INSTAT_ERROR           (0x04)
-#define LOCK_LOSS_BITS         (0x03)
-
-/* 0x24 RS_COR_SYNC_PARAM */
-#define RS_COR_SYNC_PARAM      (0x24)
-#define SYNC_PARAM             (0x03)
-
-/* 0x25 BER_CTRL */
-#define BER_CTRL               (0x25)
-#define BER_ENABLE             (0x02)
-#define BER_RESET              (0x01)
-
-/* 0x26 BER_PAY */
-#define BER_PAY                (0x26)
-
-/* 0x27 BER_PKT_L */
-#define BER_PKT_L              (0x27)
-#define BER_PKTOVERFLOW        (0x80)
-
-/* 0x30 VIT_COR_CTL */
-#define VIT_COR_CTL            (0x30)
-#define BER_CONTROL            (0x02)
-#define VIT_COR_MASK           (0x82)
-#define VIT_COR_RESYNC         (0x80)
-
-
-/* 0x32 VIT_SYNC_STATUS */
-#define VIT_SYNC_STATUS        (0x32)
-#define VITINSYNC              (0x80)
-
-/* 0x33 VIT_COR_INTEN */
-#define VIT_COR_INTEN          (0x33)
-#define GLOBAL_ENABLE          (0x80)
-
-/* 0x34 VIT_COR_INTSTAT */
-#define VIT_COR_INTSTAT        (0x34)
-#define BER_DONE               (0x08)
-#define BER_OVERFLOW           (0x10)
-
-/* 0x38 VIT_BERTIME_2 */
-#define VIT_BERTIME_2      (0x38)
-
-/* 0x39 VIT_BERTIME_1 */
-#define VIT_BERTIME_1      (0x39)
-
-/* 0x3A VIT_BERTIME_0 */
-#define VIT_BERTIME_0      (0x3a)
-
-                            /* 0x38 OFDM_BERTimer *//* Use the alias registers */
-#define A_VIT_BER_TIMER_0      (0x1D)
-
-                            /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
-#define A_VIT_BER_0            (0x1B)
-
-/* 0x3B VIT_BER_1 */
-#define VIT_BER_1              (0x3b)
-
-/* 0x3C VIT_BER_0 */
-#define VIT_BER_0              (0x3c)
-
-/* 0x40 OFDM_COR_CTL */
-#define OFDM_COR_CTL           (0x40)
-#define COREACT                (0x20)
-#define HOLDSM                 (0x10)
-#define WAIT_AGC               (0x02)
-#define WAIT_SYR               (0x03)
-
-/* 0x41 OFDM_COR_STAT */
-#define OFDM_COR_STAT          (0x41)
-#define COR_STATUS             (0x0F)
-#define MONITOR_TPS            (0x06)
-#define TPSLOCKED              (0x40)
-#define AGCLOCKED              (0x10)
-
-/* 0x42 OFDM_COR_INTEN */
-#define OFDM_COR_INTEN         (0x42)
-#define TPSRCVBAD              (0x04)
-#define TPSRCVCHANGED         (0x02)
-#define TPSRCVUPDATE           (0x01)
-
-/* 0x43 OFDM_COR_INSTAT */
-#define OFDM_COR_INSTAT        (0x43)
-
-/* 0x44 OFDM_COR_MODEGUARD */
-#define OFDM_COR_MODEGUARD     (0x44)
-#define FORCEMODE              (0x08)
-#define FORCEMODE8K                       (0x04)
-
-/* 0x45 OFDM_AGC_CTL */
-#define OFDM_AGC_CTL           (0x45)
-#define INITIAL_AGC_BW            (0x08)
-#define AGCNEG                 (0x02)
-#define AGCLAST                                   (0x10)
-
-/* 0x48 OFDM_AGC_TARGET */
-#define OFDM_AGC_TARGET                   (0x48)
-#define OFDM_AGC_TARGET_DEFAULT (0x28)
-#define OFDM_AGC_TARGET_IMPULSE (0x38)
-
-/* 0x49 OFDM_AGC_GAIN_1 */
-#define OFDM_AGC_GAIN_1        (0x49)
-
-/* 0x4B OFDM_ITB_CTL */
-#define OFDM_ITB_CTL           (0x4B)
-#define ITBINV                 (0x01)
-
-/* 0x49 AGC_GAIN_1 */
-#define AGC_GAIN_1             (0x49)
-
-/* 0x4A AGC_GAIN_2 */
-#define AGC_GAIN_2             (0x4A)
-
-/* 0x4C OFDM_ITB_FREQ_1 */
-#define OFDM_ITB_FREQ_1        (0x4C)
-
-/* 0x4D OFDM_ITB_FREQ_2 */
-#define OFDM_ITB_FREQ_2        (0x4D)
-
-/* 0x4E  OFDM_CAS_CTL */
-#define OFDM_CAS_CTL           (0x4E)
-#define ACSDIS                 (0x40)
-#define CCSEN                  (0x80)
-
-/* 0x4F CAS_FREQ */
-#define CAS_FREQ               (0x4F)
-
-/* 0x51 OFDM_SYR_CTL */
-#define OFDM_SYR_CTL           (0x51)
-#define SIXTH_ENABLE           (0x80)
-#define SYR_TRACKING_DISABLE   (0x01)
-
-/* 0x52 OFDM_SYR_STAT */
-#define OFDM_SYR_STAT             (0x52)
-#define GI14_2K_SYR_LOCK          (0x13)
-#define GI14_8K_SYR_LOCK          (0x17)
-#define GI14_SYR_LOCK             (0x10)
-
-/* 0x55 OFDM_SYR_OFFSET_1 */
-#define OFDM_SYR_OFFSET_1      (0x55)
-
-/* 0x56 OFDM_SYR_OFFSET_2 */
-#define OFDM_SYR_OFFSET_2      (0x56)
-
-/* 0x58 OFDM_SCR_CTL */
-#define OFDM_SCR_CTL           (0x58)
-#define SYR_ADJ_DECAY_MASK     (0x70)
-#define SYR_ADJ_DECAY          (0x30)
-
-/* 0x59 OFDM_PPM_CTL_1 */
-#define OFDM_PPM_CTL_1         (0x59)
-#define PPMMAX_MASK            (0x30)
-#define PPM256                            (0x30)
-
-/* 0x5B OFDM_TRL_NOMINALRATE_1 */
-#define OFDM_TRL_NOMINALRATE_1 (0x5B)
-
-/* 0x5C OFDM_TRL_NOMINALRATE_2 */
-#define OFDM_TRL_NOMINALRATE_2 (0x5C)
-
-/* 0x5D OFDM_TRL_TIME_1 */
-#define OFDM_TRL_TIME_1        (0x5D)
-
-/* 0x60 OFDM_CRL_FREQ_1 */
-#define OFDM_CRL_FREQ_1        (0x60)
-
-/* 0x63 OFDM_CHC_CTL_1 */
-#define OFDM_CHC_CTL_1         (0x63)
-#define MANMEAN1               (0xF0);
-#define CHCFIR                 (0x01)
-
-/* 0x64 OFDM_CHC_SNR */
-#define OFDM_CHC_SNR           (0x64)
-
-/* 0x65 OFDM_BDI_CTL */
-#define OFDM_BDI_CTL           (0x65)
-#define LP_SELECT              (0x02)
-
-/* 0x67 OFDM_TPS_RCVD_1 */
-#define OFDM_TPS_RCVD_1        (0x67)
-#define TPSFRAME               (0x03)
-
-/* 0x68 OFDM_TPS_RCVD_2 */
-#define OFDM_TPS_RCVD_2        (0x68)
-
-/* 0x69 OFDM_TPS_RCVD_3 */
-#define OFDM_TPS_RCVD_3        (0x69)
-
-/* 0x6A OFDM_TPS_RCVD_4 */
-#define OFDM_TPS_RCVD_4        (0x6A)
-
-/* 0x6B OFDM_TPS_RESERVED_1 */
-#define OFDM_TPS_RESERVED_1    (0x6B)
-
-/* 0x6C OFDM_TPS_RESERVED_2 */
-#define OFDM_TPS_RESERVED_2    (0x6C)
-
-/* 0x73 OFDM_MSC_REV */
-#define OFDM_MSC_REV           (0x73)
-
-/* 0x76 OFDM_SNR_CARRIER_2 */
-#define OFDM_SNR_CARRIER_2     (0x76)
-#define MEAN_MASK              (0x80)
-#define MEANBIT                (0x80)
-
-/* 0x80 ANALOG_CONTROL_0 */
-#define ANALOG_CONTROL_0       (0x80)
-#define POWER_DOWN_ADC         (0x40)
-
-/* 0x81 ENABLE_TUNER_IIC */
-#define ENABLE_TUNER_IIC       (0x81)
-#define ENABLE_TUNER_BIT       (0x01)
-
-/* 0x82 EN_DMD_RACQ */
-#define EN_DMD_RACQ            (0x82)
-#define EN_DMD_RACQ_REG_VAL    (0x81)
-#define EN_DMD_RACQ_REG_VAL_14 (0x01)
-
-/* 0x84 SNR_COMMAND */
-#define SNR_COMMAND            (0x84)
-#define SNRStat                (0x80)
-
-/* 0x85 SNRCARRIERNUMBER_LSB */
-#define SNRCARRIERNUMBER_LSB   (0x85)
-
-/* 0x87 SNRMINTHRESHOLD_LSB */
-#define SNRMINTHRESHOLD_LSB    (0x87)
-
-/* 0x89 SNR_PER_CARRIER_LSB */
-#define SNR_PER_CARRIER_LSB    (0x89)
-
-/* 0x8B SNRBELOWTHRESHOLD_LSB */
-#define SNRBELOWTHRESHOLD_LSB  (0x8B)
-
-/* 0x91 RF_AGC_VAL_1 */
-#define RF_AGC_VAL_1           (0x91)
-
-/* 0x92 RF_AGC_STATUS */
-#define RF_AGC_STATUS          (0x92)
-
-/* 0x98 DIAG_CONFIG */
-#define DIAG_CONFIG            (0x98)
-#define DIAG_MASK              (0x70)
-#define TB_SET                 (0x10)
-#define TRAN_SELECT            (0x07)
-#define SERIAL_SELECT          (0x01)
-
-/* 0x99 SUB_DIAG_MODE_SEL */
-#define SUB_DIAG_MODE_SEL      (0x99)
-#define CLKINVERSION           (0x01)
-
-/* 0x9A TS_FORMAT */
-#define TS_FORMAT              (0x9A)
-#define ERROR_SENSE            (0x08)
-#define VALID_SENSE            (0x04)
-#define SYNC_SENSE             (0x02)
-#define GATED_CLOCK            (0x01)
-
-#define NXT6000ASICDEVICE      (0x0b)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
deleted file mode 100644 (file)
index 5ef9218..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
- *
- *
- *    Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org>
- *
- *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
- *
- *    Based on code from Jack Kelliher (kelliher@xmission.com)
- *                           Copyright (C) 2002 & pcHDTV, inc.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-/*
- * This driver needs two external firmware files. Please copy
- * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
- * /usr/lib/hotplug/firmware/ or /lib/firmware/
- * (depending on configuration of firmware hotplug).
- */
-#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
-#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include "dvb_math.h"
-#include "dvb_frontend.h"
-#include "or51132.h"
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "or51132: " args); \
-       } while (0)
-
-
-struct or51132_state
-{
-       struct i2c_adapter* i2c;
-
-       /* Configuration settings */
-       const struct or51132_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* Demodulator private data */
-       fe_modulation_t current_modulation;
-       u32 snr; /* Result of last SNR calculation */
-
-       /* Tuner private data */
-       u32 current_frequency;
-};
-
-
-/* Write buffer to demod */
-static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
-{
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-                              .flags = 0, .buf = (u8*)buf, .len = len };
-
-       /* msleep(20); */ /* doesn't appear to be necessary */
-       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-               printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",
-                      msg.addr, msg.len, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);
-   Less code and more efficient that loading a buffer on the stack with
-   the bytes to send and then calling or51132_writebuf() on that. */
-#define or51132_writebytes(state, data...)  \
-       ({ static const u8 _data[] = {data}; \
-       or51132_writebuf(state, _data, sizeof(_data)); })
-
-/* Read data from demod into buffer.  Returns 0 on success. */
-static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len)
-{
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-                              .flags = I2C_M_RD, .buf = buf, .len = len };
-
-       /* msleep(20); */ /* doesn't appear to be necessary */
-       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-               printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",
-                      msg.addr, msg.len, err);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* Reads a 16-bit demod register.  Returns <0 on error. */
-static int or51132_readreg(struct or51132_state *state, u8 reg)
-{
-       u8 buf[2] = { 0x04, reg };
-       struct i2c_msg msg[2] = {
-               {.addr = state->config->demod_address, .flags = 0,
-                .buf = buf, .len = 2 },
-               {.addr = state->config->demod_address, .flags = I2C_M_RD,
-                .buf = buf, .len = 2 }};
-       int err;
-
-       if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {
-               printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",
-                      reg, err);
-               return -EREMOTEIO;
-       }
-       return buf[0] | (buf[1] << 8);
-}
-
-static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-       struct or51132_state* state = fe->demodulator_priv;
-       static const u8 run_buf[] = {0x7F,0x01};
-       u8 rec_buf[8];
-       u32 firmwareAsize, firmwareBsize;
-       int i,ret;
-
-       dprintk("Firmware is %Zd bytes\n",fw->size);
-
-       /* Get size of firmware A and B */
-       firmwareAsize = le32_to_cpu(*((__le32*)fw->data));
-       dprintk("FirmwareA is %i bytes\n",firmwareAsize);
-       firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));
-       dprintk("FirmwareB is %i bytes\n",firmwareBsize);
-
-       /* Upload firmware */
-       if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
-               printk(KERN_WARNING "or51132: load_firmware error 1\n");
-               return ret;
-       }
-       if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
-                                   firmwareBsize))) {
-               printk(KERN_WARNING "or51132: load_firmware error 2\n");
-               return ret;
-       }
-
-       if ((ret = or51132_writebuf(state, run_buf, 2))) {
-               printk(KERN_WARNING "or51132: load_firmware error 3\n");
-               return ret;
-       }
-       if ((ret = or51132_writebuf(state, run_buf, 2))) {
-               printk(KERN_WARNING "or51132: load_firmware error 4\n");
-               return ret;
-       }
-
-       /* 50ms for operation to begin */
-       msleep(50);
-
-       /* Read back ucode version to besure we loaded correctly and are really up and running */
-       /* Get uCode version */
-       if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {
-               printk(KERN_WARNING "or51132: load_firmware error a\n");
-               return ret;
-       }
-       if ((ret = or51132_writebytes(state, 0x04, 0x17))) {
-               printk(KERN_WARNING "or51132: load_firmware error b\n");
-               return ret;
-       }
-       if ((ret = or51132_writebytes(state, 0x00, 0x00))) {
-               printk(KERN_WARNING "or51132: load_firmware error c\n");
-               return ret;
-       }
-       for (i=0;i<4;i++) {
-               /* Once upon a time, this command might have had something
-                  to do with getting the firmware version, but it's
-                  not used anymore:
-                  {0x04,0x00,0x30,0x00,i+1} */
-               /* Read 8 bytes, two bytes at a time */
-               if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {
-                       printk(KERN_WARNING
-                              "or51132: load_firmware error d - %d\n",i);
-                       return ret;
-               }
-       }
-
-       printk(KERN_WARNING
-              "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
-              rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
-              rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
-              rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
-              rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
-
-       if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {
-               printk(KERN_WARNING "or51132: load_firmware error e\n");
-               return ret;
-       }
-       return 0;
-};
-
-static int or51132_init(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       *ber = 0;
-       return 0;
-}
-
-static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-static int or51132_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int or51132_setmode(struct dvb_frontend* fe)
-{
-       struct or51132_state* state = fe->demodulator_priv;
-       u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};
-       u8 cmd_buf2[3] = {0x1c, 0x00, 0 };
-
-       dprintk("setmode %d\n",(int)state->current_modulation);
-
-       switch (state->current_modulation) {
-       case VSB_8:
-               /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */
-               cmd_buf1[2] = 0x50;
-               /* REC MODE inv IF spectrum, Normal */
-               cmd_buf2[1] = 0x03;
-               /* Channel MODE ATSC/VSB8 */
-               cmd_buf2[2] = 0x06;
-               break;
-       /* All QAM modes are:
-          Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high
-          REC MODE Normal Carrier Lock */
-       case QAM_AUTO:
-               /* Channel MODE Auto QAM64/256 */
-               cmd_buf2[2] = 0x4f;
-               break;
-       case QAM_256:
-               /* Channel MODE QAM256 */
-               cmd_buf2[2] = 0x45;
-               break;
-       case QAM_64:
-               /* Channel MODE QAM64 */
-               cmd_buf2[2] = 0x43;
-               break;
-       default:
-               printk(KERN_WARNING
-                      "or51132: setmode: Modulation set to unsupported value (%d)\n",
-                      state->current_modulation);
-               return -EINVAL;
-       }
-
-       /* Set Receiver 1 register */
-       if (or51132_writebuf(state, cmd_buf1, 3)) {
-               printk(KERN_WARNING "or51132: set_mode error 1\n");
-               return -EREMOTEIO;
-       }
-       dprintk("set #1 to %02x\n", cmd_buf1[2]);
-
-       /* Set operation mode in Receiver 6 register */
-       if (or51132_writebuf(state, cmd_buf2, 3)) {
-               printk(KERN_WARNING "or51132: set_mode error 2\n");
-               return -EREMOTEIO;
-       }
-       dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);
-
-       return 0;
-}
-
-/* Some modulations use the same firmware.  This classifies modulations
-   by the firmware they use. */
-#define MOD_FWCLASS_UNKNOWN    0
-#define MOD_FWCLASS_VSB                1
-#define MOD_FWCLASS_QAM                2
-static int modulation_fw_class(fe_modulation_t modulation)
-{
-       switch(modulation) {
-       case VSB_8:
-               return MOD_FWCLASS_VSB;
-       case QAM_AUTO:
-       case QAM_64:
-       case QAM_256:
-               return MOD_FWCLASS_QAM;
-       default:
-               return MOD_FWCLASS_UNKNOWN;
-       }
-}
-
-static int or51132_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       int ret;
-       struct or51132_state* state = fe->demodulator_priv;
-       const struct firmware *fw;
-       const char *fwname;
-       int clock_mode;
-
-       /* Upload new firmware only if we need a different one */
-       if (modulation_fw_class(state->current_modulation) !=
-           modulation_fw_class(p->modulation)) {
-               switch (modulation_fw_class(p->modulation)) {
-               case MOD_FWCLASS_VSB:
-                       dprintk("set_parameters VSB MODE\n");
-                       fwname = OR51132_VSB_FIRMWARE;
-
-                       /* Set non-punctured clock for VSB */
-                       clock_mode = 0;
-                       break;
-               case MOD_FWCLASS_QAM:
-                       dprintk("set_parameters QAM MODE\n");
-                       fwname = OR51132_QAM_FIRMWARE;
-
-                       /* Set punctured clock for QAM */
-                       clock_mode = 1;
-                       break;
-               default:
-                       printk("or51132: Modulation type(%d) UNSUPPORTED\n",
-                              p->modulation);
-                       return -1;
-               }
-               printk("or51132: Waiting for firmware upload(%s)...\n",
-                      fwname);
-               ret = request_firmware(&fw, fwname, state->i2c->dev.parent);
-               if (ret) {
-                       printk(KERN_WARNING "or51132: No firmware up"
-                              "loaded(timeout or file not found?)\n");
-                       return ret;
-               }
-               ret = or51132_load_firmware(fe, fw);
-               release_firmware(fw);
-               if (ret) {
-                       printk(KERN_WARNING "or51132: Writing firmware to "
-                              "device failed!\n");
-                       return ret;
-               }
-               printk("or51132: Firmware upload complete.\n");
-               state->config->set_ts_params(fe, clock_mode);
-       }
-       /* Change only if we are actually changing the modulation */
-       if (state->current_modulation != p->modulation) {
-               state->current_modulation = p->modulation;
-               or51132_setmode(fe);
-       }
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* Set to current mode */
-       or51132_setmode(fe);
-
-       /* Update current frequency */
-       state->current_frequency = p->frequency;
-       return 0;
-}
-
-static int or51132_get_parameters(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct or51132_state* state = fe->demodulator_priv;
-       int status;
-       int retry = 1;
-
-start:
-       /* Receiver Status */
-       if ((status = or51132_readreg(state, 0x00)) < 0) {
-               printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n");
-               return -EREMOTEIO;
-       }
-       switch(status&0xff) {
-       case 0x06:
-               p->modulation = VSB_8;
-               break;
-       case 0x43:
-               p->modulation = QAM_64;
-               break;
-       case 0x45:
-               p->modulation = QAM_256;
-               break;
-       default:
-               if (retry--)
-                       goto start;
-               printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
-                      status&0xff);
-               return -EREMOTEIO;
-       }
-
-       /* FIXME: Read frequency from frontend, take AFC into account */
-       p->frequency = state->current_frequency;
-
-       /* FIXME: How to read inversion setting? Receiver 6 register? */
-       p->inversion = INVERSION_AUTO;
-
-       return 0;
-}
-
-static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct or51132_state* state = fe->demodulator_priv;
-       int reg;
-
-       /* Receiver Status */
-       if ((reg = or51132_readreg(state, 0x00)) < 0) {
-               printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg);
-               *status = 0;
-               return -EREMOTEIO;
-       }
-       dprintk("%s: read_status %04x\n", __func__, reg);
-
-       if (reg & 0x0100) /* Receiver Lock */
-               *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
-                         FE_HAS_SYNC|FE_HAS_LOCK;
-       else
-               *status = 0;
-       return 0;
-}
-
-/* Calculate SNR estimation (scaled by 2^24)
-
-   8-VSB SNR and QAM equations from Oren datasheets
-
-   For 8-VSB:
-     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K
-
-     Where K = 0 if NTSC rejection filter is OFF; and
-          K = 3 if NTSC rejection filter is ON
-
-   For QAM64:
-     SNR[dB] = 10 * log10(897152044.8282 / MSE^2 )
-
-   For QAM256:
-     SNR[dB] = 10 * log10(907832426.314266  / MSE^2 )
-
-   We re-write the snr equation as:
-     SNR * 2^24 = 10*(c - 2*intlog10(MSE))
-   Where for QAM256, c = log10(907832426.314266) * 2^24
-   and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */
-
-static u32 calculate_snr(u32 mse, u32 c)
-{
-       if (mse == 0) /* No signal */
-               return 0;
-
-       mse = 2*intlog10(mse);
-       if (mse > c) {
-               /* Negative SNR, which is possible, but realisticly the
-               demod will lose lock before the signal gets this bad.  The
-               API only allows for unsigned values, so just return 0 */
-               return 0;
-       }
-       return 10*(c - mse);
-}
-
-static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct or51132_state* state = fe->demodulator_priv;
-       int noise, reg;
-       u32 c, usK = 0;
-       int retry = 1;
-
-start:
-       /* SNR after Equalizer */
-       noise = or51132_readreg(state, 0x02);
-       if (noise < 0) {
-               printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n");
-               return -EREMOTEIO;
-       }
-       dprintk("read_snr noise (%d)\n", noise);
-
-       /* Read status, contains modulation type for QAM_AUTO and
-          NTSC filter for VSB */
-       reg = or51132_readreg(state, 0x00);
-       if (reg < 0) {
-               printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n");
-               return -EREMOTEIO;
-       }
-
-       switch (reg&0xff) {
-       case 0x06:
-               if (reg & 0x1000) usK = 3 << 24;
-               /* Fall through to QAM64 case */
-       case 0x43:
-               c = 150204167;
-               break;
-       case 0x45:
-               c = 150290396;
-               break;
-       default:
-               printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff);
-               if (retry--) goto start;
-               return -EREMOTEIO;
-       }
-       dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__,
-               reg&0xff, reg&0x1000?"n":"ff");
-
-       /* Calculate SNR using noise, c, and NTSC rejection correction */
-       state->snr = calculate_snr(noise, c) - usK;
-       *snr = (state->snr) >> 16;
-
-       dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
-               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
-
-       return 0;
-}
-
-static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       /* Calculate Strength from SNR up to 35dB */
-       /* Even though the SNR can go higher than 35dB, there is some comfort */
-       /* factor in having a range of strong signals that can show at 100%   */
-       struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
-       u16 snr;
-       int ret;
-
-       ret = fe->ops.read_snr(fe, &snr);
-       if (ret != 0)
-               return ret;
-       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
-       /* scale the range 0 - 35*2^24 into 0 - 65535 */
-       if (state->snr >= 8960 * 0x10000)
-               *strength = 0xffff;
-       else
-               *strength = state->snr / 8960;
-
-       return 0;
-}
-
-static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 500;
-       fe_tune_settings->step_size = 0;
-       fe_tune_settings->max_drift = 0;
-
-       return 0;
-}
-
-static void or51132_release(struct dvb_frontend* fe)
-{
-       struct or51132_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops or51132_ops;
-
-struct dvb_frontend* or51132_attach(const struct or51132_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct or51132_state* state = NULL;
-
-       /* Allocate memory for the internal state */
-       state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       /* Setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->current_frequency = -1;
-       state->current_modulation = -1;
-
-       /* Create dvb_frontend */
-       memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-static struct dvb_frontend_ops or51132_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name                   = "Oren OR51132 VSB/QAM Frontend",
-               .frequency_min          = 44000000,
-               .frequency_max          = 958000000,
-               .frequency_stepsize     = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
-                       FE_CAN_8VSB
-       },
-
-       .release = or51132_release,
-
-       .init = or51132_init,
-       .sleep = or51132_sleep,
-
-       .set_frontend = or51132_set_parameters,
-       .get_frontend = or51132_get_parameters,
-       .get_tune_settings = or51132_get_tune_settings,
-
-       .read_status = or51132_read_status,
-       .read_ber = or51132_read_ber,
-       .read_signal_strength = or51132_read_signal_strength,
-       .read_snr = or51132_read_snr,
-       .read_ucblocks = or51132_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray");
-MODULE_AUTHOR("Trent Piepho");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(or51132_attach);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
deleted file mode 100644 (file)
index 1b8e04d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
- *
- *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-#ifndef OR51132_H
-#define OR51132_H
-
-#include <linux/firmware.h>
-#include <linux/dvb/frontend.h>
-
-struct or51132_config
-{
-       /* The demodulator's i2c address */
-       u8 demod_address;
-
-       /* Need to set device param for start_dma */
-       int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
-};
-
-#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE))
-extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_OR51132
-
-#endif // OR51132_H
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
deleted file mode 100644 (file)
index c625b57..0000000
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- *    Support for OR51211 (pcHDTV HD-2000) - VSB
- *
- *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
- *
- *    Based on code from Jack Kelliher (kelliher@xmission.com)
- *                           Copyright (C) 2002 & pcHDTV, inc.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include "dvb_math.h"
-#include "dvb_frontend.h"
-#include "or51211.h"
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "or51211: " args); \
-       } while (0)
-
-static u8 run_buf[] = {0x7f,0x01};
-static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
-
-struct or51211_state {
-
-       struct i2c_adapter* i2c;
-
-       /* Configuration settings */
-       const struct or51211_config* config;
-
-       struct dvb_frontend frontend;
-       struct bt878* bt;
-
-       /* Demodulator private data */
-       u8 initialized:1;
-       u32 snr; /* Result of last SNR claculation */
-
-       /* Tuner private data */
-       u32 current_frequency;
-};
-
-static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
-                          int len)
-{
-       int err;
-       struct i2c_msg msg;
-       msg.addr        = reg;
-       msg.flags       = 0;
-       msg.len         = len;
-       msg.buf         = (u8 *)buf;
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               printk(KERN_WARNING "or51211: i2c_writebytes error "
-                      "(addr %02x, err == %i)\n", reg, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len)
-{
-       int err;
-       struct i2c_msg msg;
-       msg.addr        = reg;
-       msg.flags       = I2C_M_RD;
-       msg.len         = len;
-       msg.buf         = buf;
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               printk(KERN_WARNING "or51211: i2c_readbytes error "
-                      "(addr %02x, err == %i)\n", reg, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int or51211_load_firmware (struct dvb_frontend* fe,
-                                 const struct firmware *fw)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       u8 tudata[585];
-       int i;
-
-       dprintk("Firmware is %zd bytes\n",fw->size);
-
-       /* Get eprom data */
-       tudata[0] = 17;
-       if (i2c_writebytes(state,0x50,tudata,1)) {
-               printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
-               return -1;
-       }
-       if (i2c_readbytes(state,0x50,&tudata[145],192)) {
-               printk(KERN_WARNING "or51211: load_firmware error eprom\n");
-               return -1;
-       }
-
-       /* Create firmware buffer */
-       for (i = 0; i < 145; i++)
-               tudata[i] = fw->data[i];
-
-       for (i = 0; i < 248; i++)
-               tudata[i+337] = fw->data[145+i];
-
-       state->config->reset(fe);
-
-       if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
-               printk(KERN_WARNING "or51211: load_firmware error 1\n");
-               return -1;
-       }
-       msleep(1);
-
-       if (i2c_writebytes(state,state->config->demod_address,
-                          &fw->data[393],8125)) {
-               printk(KERN_WARNING "or51211: load_firmware error 2\n");
-               return -1;
-       }
-       msleep(1);
-
-       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
-               printk(KERN_WARNING "or51211: load_firmware error 3\n");
-               return -1;
-       }
-
-       /* Wait at least 5 msec */
-       msleep(10);
-       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
-               printk(KERN_WARNING "or51211: load_firmware error 4\n");
-               return -1;
-       }
-       msleep(10);
-
-       printk("or51211: Done.\n");
-       return 0;
-};
-
-static int or51211_setmode(struct dvb_frontend* fe, int mode)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       u8 rec_buf[14];
-
-       state->config->setmode(fe, mode);
-
-       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
-               printk(KERN_WARNING "or51211: setmode error 1\n");
-               return -1;
-       }
-
-       /* Wait at least 5 msec */
-       msleep(10);
-       if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
-               printk(KERN_WARNING "or51211: setmode error 2\n");
-               return -1;
-       }
-
-       msleep(10);
-
-       /* Set operation mode in Receiver 1 register;
-        * type 1:
-        * data 0x50h  Automatic sets receiver channel conditions
-        *             Automatic NTSC rejection filter
-        *             Enable  MPEG serial data output
-        *             MPEG2tr
-        *             High tuner phase noise
-        *             normal +/-150kHz Carrier acquisition range
-        */
-       if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
-               printk(KERN_WARNING "or51211: setmode error 3\n");
-               return -1;
-       }
-
-       rec_buf[0] = 0x04;
-       rec_buf[1] = 0x00;
-       rec_buf[2] = 0x03;
-       rec_buf[3] = 0x00;
-       msleep(20);
-       if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
-               printk(KERN_WARNING "or51211: setmode error 5\n");
-       }
-       msleep(3);
-       if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
-               printk(KERN_WARNING "or51211: setmode error 6");
-               return -1;
-       }
-       dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
-
-       return 0;
-}
-
-static int or51211_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct or51211_state* state = fe->demodulator_priv;
-
-       /* Change only if we are actually changing the channel */
-       if (state->current_frequency != p->frequency) {
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-
-               /* Set to ATSC mode */
-               or51211_setmode(fe,0);
-
-               /* Update current frequency */
-               state->current_frequency = p->frequency;
-       }
-       return 0;
-}
-
-static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       unsigned char rec_buf[2];
-       unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
-       *status = 0;
-
-       /* Receiver Status */
-       if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
-               printk(KERN_WARNING "or51132: read_status write error\n");
-               return -1;
-       }
-       msleep(3);
-       if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
-               printk(KERN_WARNING "or51132: read_status read error\n");
-               return -1;
-       }
-       dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
-
-       if (rec_buf[0] &  0x01) { /* Receiver Lock */
-               *status |= FE_HAS_SIGNAL;
-               *status |= FE_HAS_CARRIER;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-               *status |= FE_HAS_LOCK;
-       }
-       return 0;
-}
-
-/* Calculate SNR estimation (scaled by 2^24)
-
-   8-VSB SNR equation from Oren datasheets
-
-   For 8-VSB:
-     SNR[dB] = 10 * log10(219037.9454 / MSE^2 )
-
-   We re-write the snr equation as:
-     SNR * 2^24 = 10*(c - 2*intlog10(MSE))
-   Where for 8-VSB, c = log10(219037.9454) * 2^24 */
-
-static u32 calculate_snr(u32 mse, u32 c)
-{
-       if (mse == 0) /* No signal */
-               return 0;
-
-       mse = 2*intlog10(mse);
-       if (mse > c) {
-               /* Negative SNR, which is possible, but realisticly the
-               demod will lose lock before the signal gets this bad.  The
-               API only allows for unsigned values, so just return 0 */
-               return 0;
-       }
-       return 10*(c - mse);
-}
-
-static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       u8 rec_buf[2];
-       u8 snd_buf[3];
-
-       /* SNR after Equalizer */
-       snd_buf[0] = 0x04;
-       snd_buf[1] = 0x00;
-       snd_buf[2] = 0x04;
-
-       if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
-               printk(KERN_WARNING "%s: error writing snr reg\n",
-                      __func__);
-               return -1;
-       }
-       if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
-               printk(KERN_WARNING "%s: read_status read error\n",
-                      __func__);
-               return -1;
-       }
-
-       state->snr = calculate_snr(rec_buf[0], 89599047);
-       *snr = (state->snr) >> 16;
-
-       dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0],
-               state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
-
-       return 0;
-}
-
-static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       /* Calculate Strength from SNR up to 35dB */
-       /* Even though the SNR can go higher than 35dB, there is some comfort */
-       /* factor in having a range of strong signals that can show at 100%   */
-       struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv;
-       u16 snr;
-       int ret;
-
-       ret = fe->ops.read_snr(fe, &snr);
-       if (ret != 0)
-               return ret;
-       /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
-       /* scale the range 0 - 35*2^24 into 0 - 65535 */
-       if (state->snr >= 8960 * 0x10000)
-               *strength = 0xffff;
-       else
-               *strength = state->snr / 8960;
-
-       return 0;
-}
-
-static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       *ber = -ENOSYS;
-       return 0;
-}
-
-static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       *ucblocks = -ENOSYS;
-       return 0;
-}
-
-static int or51211_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int or51211_init(struct dvb_frontend* fe)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       const struct or51211_config* config = state->config;
-       const struct firmware* fw;
-       unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
-       unsigned char rec_buf[14];
-       int ret,i;
-
-       if (!state->initialized) {
-               /* Request the firmware, this will block until it uploads */
-               printk(KERN_INFO "or51211: Waiting for firmware upload "
-                      "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
-               ret = config->request_firmware(fe, &fw,
-                                              OR51211_DEFAULT_FIRMWARE);
-               printk(KERN_INFO "or51211:Got Hotplug firmware\n");
-               if (ret) {
-                       printk(KERN_WARNING "or51211: No firmware uploaded "
-                              "(timeout or file not found?)\n");
-                       return ret;
-               }
-
-               ret = or51211_load_firmware(fe, fw);
-               release_firmware(fw);
-               if (ret) {
-                       printk(KERN_WARNING "or51211: Writing firmware to "
-                              "device failed!\n");
-                       return ret;
-               }
-               printk(KERN_INFO "or51211: Firmware upload complete.\n");
-
-               /* Set operation mode in Receiver 1 register;
-                * type 1:
-                * data 0x50h  Automatic sets receiver channel conditions
-                *             Automatic NTSC rejection filter
-                *             Enable  MPEG serial data output
-                *             MPEG2tr
-                *             High tuner phase noise
-                *             normal +/-150kHz Carrier acquisition range
-                */
-               if (i2c_writebytes(state,state->config->demod_address,
-                                  cmd_buf,3)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error 5\n");
-                       return -1;
-               }
-
-               /* Read back ucode version to besure we loaded correctly */
-               /* and are really up and running */
-               rec_buf[0] = 0x04;
-               rec_buf[1] = 0x00;
-               rec_buf[2] = 0x03;
-               rec_buf[3] = 0x00;
-               msleep(30);
-               if (i2c_writebytes(state,state->config->demod_address,
-                                  rec_buf,3)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error A\n");
-                       return -1;
-               }
-               msleep(3);
-               if (i2c_readbytes(state,state->config->demod_address,
-                                 &rec_buf[10],2)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error B\n");
-                       return -1;
-               }
-
-               rec_buf[0] = 0x04;
-               rec_buf[1] = 0x00;
-               rec_buf[2] = 0x01;
-               rec_buf[3] = 0x00;
-               msleep(20);
-               if (i2c_writebytes(state,state->config->demod_address,
-                                  rec_buf,3)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error C\n");
-                       return -1;
-               }
-               msleep(3);
-               if (i2c_readbytes(state,state->config->demod_address,
-                                 &rec_buf[12],2)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error D\n");
-                       return -1;
-               }
-
-               for (i = 0; i < 8; i++)
-                       rec_buf[i]=0xed;
-
-               for (i = 0; i < 5; i++) {
-                       msleep(30);
-                       get_ver_buf[4] = i+1;
-                       if (i2c_writebytes(state,state->config->demod_address,
-                                          get_ver_buf,5)) {
-                               printk(KERN_WARNING "or51211:Load DVR Error 6"
-                                      " - %d\n",i);
-                               return -1;
-                       }
-                       msleep(3);
-
-                       if (i2c_readbytes(state,state->config->demod_address,
-                                         &rec_buf[i*2],2)) {
-                               printk(KERN_WARNING "or51211:Load DVR Error 7"
-                                      " - %d\n",i);
-                               return -1;
-                       }
-                       /* If we didn't receive the right index, try again */
-                       if ((int)rec_buf[i*2+1]!=i+1){
-                         i--;
-                       }
-               }
-               dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
-                       rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
-                       rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
-                       rec_buf[8], rec_buf[9]);
-
-               printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
-                      " Status %02x\n",
-                      rec_buf[2], rec_buf[4],rec_buf[6],
-                      rec_buf[12],rec_buf[10]);
-
-               rec_buf[0] = 0x04;
-               rec_buf[1] = 0x00;
-               rec_buf[2] = 0x03;
-               rec_buf[3] = 0x00;
-               msleep(20);
-               if (i2c_writebytes(state,state->config->demod_address,
-                                  rec_buf,3)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error 8\n");
-                       return -1;
-               }
-               msleep(20);
-               if (i2c_readbytes(state,state->config->demod_address,
-                                 &rec_buf[8],2)) {
-                       printk(KERN_WARNING "or51211: Load DVR Error 9\n");
-                       return -1;
-               }
-               state->initialized = 1;
-       }
-
-       return 0;
-}
-
-static int or51211_get_tune_settings(struct dvb_frontend* fe,
-                                    struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 500;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void or51211_release(struct dvb_frontend* fe)
-{
-       struct or51211_state* state = fe->demodulator_priv;
-       state->config->sleep(fe);
-       kfree(state);
-}
-
-static struct dvb_frontend_ops or51211_ops;
-
-struct dvb_frontend* or51211_attach(const struct or51211_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct or51211_state* state = NULL;
-
-       /* Allocate memory for the internal state */
-       state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL);
-       if (state == NULL)
-               return NULL;
-
-       /* Setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialized = 0;
-       state->current_frequency = 0;
-
-       /* Create dvb_frontend */
-       memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-static struct dvb_frontend_ops or51211_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name               = "Oren OR51211 VSB Frontend",
-               .frequency_min      = 44000000,
-               .frequency_max      = 958000000,
-               .frequency_stepsize = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_8VSB
-       },
-
-       .release = or51211_release,
-
-       .init = or51211_init,
-       .sleep = or51211_sleep,
-
-       .set_frontend = or51211_set_parameters,
-       .get_tune_settings = or51211_get_tune_settings,
-
-       .read_status = or51211_read_status,
-       .read_ber = or51211_read_ber,
-       .read_signal_strength = or51211_read_signal_strength,
-       .read_snr = or51211_read_snr,
-       .read_ucblocks = or51211_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(or51211_attach);
-
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
deleted file mode 100644 (file)
index 3ce0508..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *    Support for OR51211 (pcHDTV HD-2000) - VSB
- *
- *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-*/
-
-#ifndef OR51211_H
-#define OR51211_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct or51211_config
-{
-       /* The demodulator's i2c address */
-       u8 demod_address;
-
-       /* Request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-       void (*setmode)(struct dvb_frontend * fe, int mode);
-       void (*reset)(struct dvb_frontend * fe);
-       void (*sleep)(struct dvb_frontend * fe);
-};
-
-#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE))
-extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_OR51211
-
-#endif // OR51211_H
-
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb/frontends/rtl2830.c
deleted file mode 100644 (file)
index 8fa8b08..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * Realtek RTL2830 DVB-T demodulator driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-
-/*
- * Driver implements own I2C-adapter for tuner I2C access. That's since chip
- * have unusual I2C-gate control which closes gate automatically after each
- * I2C transfer. Using own I2C adapter we can workaround that.
- */
-
-#include "rtl2830_priv.h"
-
-int rtl2830_debug;
-module_param_named(debug, rtl2830_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-/* write multiple hardware registers */
-static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[1+len];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 1+len,
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple hardware registers */
-static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* write multiple registers */
-static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
-{
-       int ret;
-       u8 reg2 = (reg >> 0) & 0xff;
-       u8 page = (reg >> 8) & 0xff;
-
-       /* switch bank if needed */
-       if (page != priv->page) {
-               ret = rtl2830_wr(priv, 0x00, &page, 1);
-               if (ret)
-                       return ret;
-
-               priv->page = page;
-       }
-
-       return rtl2830_wr(priv, reg2, val, len);
-}
-
-/* read multiple registers */
-static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
-{
-       int ret;
-       u8 reg2 = (reg >> 0) & 0xff;
-       u8 page = (reg >> 8) & 0xff;
-
-       /* switch bank if needed */
-       if (page != priv->page) {
-               ret = rtl2830_wr(priv, 0x00, &page, 1);
-               if (ret)
-                       return ret;
-
-               priv->page = page;
-       }
-
-       return rtl2830_rd(priv, reg2, val, len);
-}
-
-#if 0 /* currently not used */
-/* write single register */
-static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
-{
-       return rtl2830_wr_regs(priv, reg, &val, 1);
-}
-#endif
-
-/* read single register */
-static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
-{
-       return rtl2830_rd_regs(priv, reg, val, 1);
-}
-
-/* write single register with mask */
-int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return rtl2830_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register with mask */
-int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static int rtl2830_init(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       int ret, i;
-       u64 num;
-       u8 buf[3], tmp;
-       u32 if_ctl;
-       struct rtl2830_reg_val_mask tab[] = {
-               { 0x00d, 0x01, 0x03 },
-               { 0x00d, 0x10, 0x10 },
-               { 0x104, 0x00, 0x1e },
-               { 0x105, 0x80, 0x80 },
-               { 0x110, 0x02, 0x03 },
-               { 0x110, 0x08, 0x0c },
-               { 0x17b, 0x00, 0x40 },
-               { 0x17d, 0x05, 0x0f },
-               { 0x17d, 0x50, 0xf0 },
-               { 0x18c, 0x08, 0x0f },
-               { 0x18d, 0x00, 0xc0 },
-               { 0x188, 0x05, 0x0f },
-               { 0x189, 0x00, 0xfc },
-               { 0x2d5, 0x02, 0x02 },
-               { 0x2f1, 0x02, 0x06 },
-               { 0x2f1, 0x20, 0xf8 },
-               { 0x16d, 0x00, 0x01 },
-               { 0x1a6, 0x00, 0x80 },
-               { 0x106, priv->cfg.vtop, 0x3f },
-               { 0x107, priv->cfg.krf, 0x3f },
-               { 0x112, 0x28, 0xff },
-               { 0x103, priv->cfg.agc_targ_val, 0xff },
-               { 0x00a, 0x02, 0x07 },
-               { 0x140, 0x0c, 0x3c },
-               { 0x140, 0x40, 0xc0 },
-               { 0x15b, 0x05, 0x07 },
-               { 0x15b, 0x28, 0x38 },
-               { 0x15c, 0x05, 0x07 },
-               { 0x15c, 0x28, 0x38 },
-               { 0x115, priv->cfg.spec_inv, 0x01 },
-               { 0x16f, 0x01, 0x07 },
-               { 0x170, 0x18, 0x38 },
-               { 0x172, 0x0f, 0x0f },
-               { 0x173, 0x08, 0x38 },
-               { 0x175, 0x01, 0x07 },
-               { 0x176, 0x00, 0xc0 },
-       };
-
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val,
-                       tab[i].mask);
-               if (ret)
-                       goto err;
-       }
-
-       ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2);
-       if (ret)
-               goto err;
-
-       ret = rtl2830_wr_regs(priv, 0x195,
-               "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
-       if (ret)
-               goto err;
-
-       num = priv->cfg.if_dvbt % priv->cfg.xtal;
-       num *= 0x400000;
-       num = div_u64(num, priv->cfg.xtal);
-       num = -num;
-       if_ctl = num & 0x3fffff;
-       dbg("%s: if_ctl=%08x", __func__, if_ctl);
-
-       ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
-       if (ret)
-               goto err;
-
-       buf[0] = tmp << 6;
-       buf[0] = (if_ctl >> 16) & 0x3f;
-       buf[1] = (if_ctl >>  8) & 0xff;
-       buf[2] = (if_ctl >>  0) & 0xff;
-
-       ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
-       if (ret)
-               goto err;
-
-       /* TODO: spec init */
-
-       /* soft reset */
-       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04);
-       if (ret)
-               goto err;
-
-       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04);
-       if (ret)
-               goto err;
-
-       priv->sleeping = false;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_sleep(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       priv->sleeping = true;
-       return 0;
-}
-
-int rtl2830_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 500;
-       s->step_size = fe->ops.info.frequency_stepsize * 2;
-       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
-
-       return 0;
-}
-
-static int rtl2830_set_frontend(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       static u8 bw_params1[3][34] = {
-               {
-               0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
-               0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
-               0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
-               0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
-               }, {
-               0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
-               0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
-               0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
-               0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
-               }, {
-               0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
-               0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
-               0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
-               0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
-               },
-       };
-       static u8 bw_params2[3][6] = {
-               {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
-               {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
-               {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
-       };
-
-
-       dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
-               c->frequency, c->bandwidth_hz, c->inversion);
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               i = 0;
-               break;
-       case 7000000:
-               i = 1;
-               break;
-       case 8000000:
-               i = 2;
-               break;
-       default:
-               dbg("invalid bandwidth");
-               return -EINVAL;
-       }
-
-       ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06);
-       if (ret)
-               goto err;
-
-       /* 1/2 split I2C write */
-       ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
-       if (ret)
-               goto err;
-
-       /* 2/2 split I2C write */
-       ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17);
-       if (ret)
-               goto err;
-
-       ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_get_frontend(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-       u8 buf[3];
-
-       if (priv->sleeping)
-               return 0;
-
-       ret = rtl2830_rd_regs(priv, 0x33c, buf, 2);
-       if (ret)
-               goto err;
-
-       ret = rtl2830_rd_reg(priv, 0x351, &buf[2]);
-       if (ret)
-               goto err;
-
-       dbg("%s: TPS=%*ph", __func__, 3, buf);
-
-       switch ((buf[0] >> 2) & 3) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       }
-
-       switch ((buf[2] >> 2) & 1) {
-       case 0:
-               c->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               c->transmission_mode = TRANSMISSION_MODE_8K;
-       }
-
-       switch ((buf[2] >> 0) & 3) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       switch ((buf[0] >> 4) & 7) {
-       case 0:
-               c->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               c->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               c->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               c->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-       switch ((buf[1] >> 3) & 7) {
-       case 0:
-               c->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_HP = FEC_7_8;
-               break;
-       }
-
-       switch ((buf[1] >> 0) & 7) {
-       case 0:
-               c->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               c->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               c->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               c->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               c->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-       *status = 0;
-
-       if (priv->sleeping)
-               return 0;
-
-       ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */
-       if (ret)
-               goto err;
-
-       if (tmp == 11) {
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                       FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-       } else if (tmp == 10) {
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                       FE_HAS_VITERBI;
-       }
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       int ret, hierarchy, constellation;
-       u8 buf[2], tmp;
-       u16 tmp16;
-#define CONSTELLATION_NUM 3
-#define HIERARCHY_NUM 4
-       static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
-               { 70705899, 70705899, 70705899, 70705899 },
-               { 82433173, 82433173, 87483115, 94445660 },
-               { 92888734, 92888734, 95487525, 99770748 },
-       };
-
-       if (priv->sleeping)
-               return 0;
-
-       /* reports SNR in resolution of 0.1 dB */
-
-       ret = rtl2830_rd_reg(priv, 0x33c, &tmp);
-       if (ret)
-               goto err;
-
-       constellation = (tmp >> 2) & 0x03; /* [3:2] */
-       if (constellation > CONSTELLATION_NUM - 1)
-               goto err;
-
-       hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
-       if (hierarchy > HIERARCHY_NUM - 1)
-               goto err;
-
-       ret = rtl2830_rd_regs(priv, 0x40c, buf, 2);
-       if (ret)
-               goto err;
-
-       tmp16 = buf[0] << 8 | buf[1];
-
-       if (tmp16)
-               *snr = (snr_constant[constellation][hierarchy] -
-                               intlog10(tmp16)) / ((1 << 24) / 100);
-       else
-               *snr = 0;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-
-       if (priv->sleeping)
-               return 0;
-
-       ret = rtl2830_rd_regs(priv, 0x34e, buf, 2);
-       if (ret)
-               goto err;
-
-       *ber = buf[0] << 8 | buf[1];
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-       u16 if_agc_raw, if_agc;
-
-       if (priv->sleeping)
-               return 0;
-
-       ret = rtl2830_rd_regs(priv, 0x359, buf, 2);
-       if (ret)
-               goto err;
-
-       if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff;
-
-       if (if_agc_raw & (1 << 9))
-               if_agc = -(~(if_agc_raw - 1) & 0x1ff);
-       else
-               if_agc = if_agc_raw;
-
-       *strength = (u8) (55 - if_agc / 182);
-       *strength |= *strength << 8;
-
-       return 0;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static struct dvb_frontend_ops rtl2830_ops;
-
-static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
-       struct i2c_msg msg[], int num)
-{
-       struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap);
-       int ret;
-
-       /* open i2c-gate */
-       ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08);
-       if (ret)
-               goto err;
-
-       ret = i2c_transfer(priv->i2c, msg, num);
-       if (ret < 0)
-               warn("tuner i2c failed=%d", ret);
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static struct i2c_algorithm rtl2830_tuner_i2c_algo = {
-       .master_xfer   = rtl2830_tuner_i2c_xfer,
-       .functionality = rtl2830_tuner_i2c_func,
-};
-
-struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-       return &priv->tuner_i2c_adapter;
-}
-EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter);
-
-static void rtl2830_release(struct dvb_frontend *fe)
-{
-       struct rtl2830_priv *priv = fe->demodulator_priv;
-
-       i2c_del_adapter(&priv->tuner_i2c_adapter);
-       kfree(priv);
-}
-
-struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
-       struct i2c_adapter *i2c)
-{
-       struct rtl2830_priv *priv = NULL;
-       int ret = 0;
-       u8 tmp;
-
-       /* allocate memory for the internal state */
-       priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL);
-       if (priv == NULL)
-               goto err;
-
-       /* setup the priv */
-       priv->i2c = i2c;
-       memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config));
-
-       /* check if the demod is there */
-       ret = rtl2830_rd_reg(priv, 0x000, &tmp);
-       if (ret)
-               goto err;
-
-       /* create dvb_frontend */
-       memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-
-       /* create tuner i2c adapter */
-       strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter",
-               sizeof(priv->tuner_i2c_adapter.name));
-       priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
-       priv->tuner_i2c_adapter.algo_data = NULL;
-       i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
-       if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
-               err("tuner I2C bus could not be initialized");
-               goto err;
-       }
-
-       priv->sleeping = true;
-
-       return &priv->fe;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(rtl2830_attach);
-
-static struct dvb_frontend_ops rtl2830_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Realtek RTL2830 (DVB-T)",
-               .caps = FE_CAN_FEC_1_2 |
-                       FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 |
-                       FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = rtl2830_release,
-
-       .init = rtl2830_init,
-       .sleep = rtl2830_sleep,
-
-       .get_tune_settings = rtl2830_get_tune_settings,
-
-       .set_frontend = rtl2830_set_frontend,
-       .get_frontend = rtl2830_get_frontend,
-
-       .read_status = rtl2830_read_status,
-       .read_snr = rtl2830_read_snr,
-       .read_ber = rtl2830_read_ber,
-       .read_ucblocks = rtl2830_read_ucblocks,
-       .read_signal_strength = rtl2830_read_signal_strength,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/rtl2830.h b/drivers/media/dvb/frontends/rtl2830.h
deleted file mode 100644 (file)
index 1c6ee91..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Realtek RTL2830 DVB-T demodulator driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef RTL2830_H
-#define RTL2830_H
-
-#include <linux/dvb/frontend.h>
-
-struct rtl2830_config {
-       /*
-        * Demodulator I2C address.
-        */
-       u8 i2c_addr;
-
-       /*
-        * Xtal frequency.
-        * Hz
-        * 4000000, 16000000, 25000000, 28800000
-        */
-       u32 xtal;
-
-       /*
-        * TS output mode.
-        */
-       u8 ts_mode;
-
-       /*
-        * Spectrum inversion.
-        */
-       bool spec_inv;
-
-       /*
-        * IFs for all used modes.
-        * Hz
-        * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
-        */
-       u32 if_dvbt;
-
-       /*
-        */
-       u8 vtop;
-
-       /*
-        */
-       u8 krf;
-
-       /*
-        */
-       u8 agc_targ_val;
-};
-
-#if defined(CONFIG_DVB_RTL2830) || \
-       (defined(CONFIG_DVB_RTL2830_MODULE) && defined(MODULE))
-extern struct dvb_frontend *rtl2830_attach(
-       const struct rtl2830_config *config,
-       struct i2c_adapter *i2c
-);
-
-extern struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
-       struct dvb_frontend *fe
-);
-#else
-static inline struct dvb_frontend *rtl2830_attach(
-       const struct rtl2830_config *config,
-       struct i2c_adapter *i2c
-)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
-       struct dvb_frontend *fe
-)
-{
-       return NULL;
-}
-#endif
-
-#endif /* RTL2830_H */
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb/frontends/rtl2830_priv.h
deleted file mode 100644 (file)
index 9b20557..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Realtek RTL2830 DVB-T demodulator driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef RTL2830_PRIV_H
-#define RTL2830_PRIV_H
-
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "rtl2830.h"
-
-#define LOG_PREFIX "rtl2830"
-
-#undef dbg
-#define dbg(f, arg...) \
-       if (rtl2830_debug) \
-               printk(KERN_INFO            LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-struct rtl2830_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct rtl2830_config cfg;
-       struct i2c_adapter tuner_i2c_adapter;
-
-       bool sleeping;
-
-       u8 page; /* active register page */
-};
-
-struct rtl2830_reg_val_mask {
-       u16 reg;
-       u8  val;
-       u8  mask;
-};
-
-#endif /* RTL2830_PRIV_H */
diff --git a/drivers/media/dvb/frontends/rtl2832.c b/drivers/media/dvb/frontends/rtl2832.c
deleted file mode 100644 (file)
index 28269cc..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Realtek RTL2832 DVB-T demodulator driver
- *
- * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
- *
- *     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.
- */
-
-#include "rtl2832_priv.h"
-#include <linux/bitops.h>
-
-int rtl2832_debug;
-module_param_named(debug, rtl2832_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-#define REG_MASK(b) (BIT(b + 1) - 1)
-
-static const struct rtl2832_reg_entry registers[] = {
-       [DVBT_SOFT_RST]         = {0x1, 0x1,   2, 2},
-       [DVBT_IIC_REPEAT]       = {0x1, 0x1,   3, 3},
-       [DVBT_TR_WAIT_MIN_8K]   = {0x1, 0x88, 11, 2},
-       [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
-       [DVBT_EN_BK_TRK]        = {0x1, 0xa6,  7, 7},
-       [DVBT_AD_EN_REG]        = {0x0, 0x8,   7, 7},
-       [DVBT_AD_EN_REG1]       = {0x0, 0x8,   6, 6},
-       [DVBT_EN_BBIN]          = {0x1, 0xb1,  0, 0},
-       [DVBT_MGD_THD0]         = {0x1, 0x95,  7, 0},
-       [DVBT_MGD_THD1]         = {0x1, 0x96,  7, 0},
-       [DVBT_MGD_THD2]         = {0x1, 0x97,  7, 0},
-       [DVBT_MGD_THD3]         = {0x1, 0x98,  7, 0},
-       [DVBT_MGD_THD4]         = {0x1, 0x99,  7, 0},
-       [DVBT_MGD_THD5]         = {0x1, 0x9a,  7, 0},
-       [DVBT_MGD_THD6]         = {0x1, 0x9b,  7, 0},
-       [DVBT_MGD_THD7]         = {0x1, 0x9c,  7, 0},
-       [DVBT_EN_CACQ_NOTCH]    = {0x1, 0x61,  4, 4},
-       [DVBT_AD_AV_REF]        = {0x0, 0x9,   6, 0},
-       [DVBT_REG_PI]           = {0x0, 0xa,   2, 0},
-       [DVBT_PIP_ON]           = {0x0, 0x21,  3, 3},
-       [DVBT_SCALE1_B92]       = {0x2, 0x92,  7, 0},
-       [DVBT_SCALE1_B93]       = {0x2, 0x93,  7, 0},
-       [DVBT_SCALE1_BA7]       = {0x2, 0xa7,  7, 0},
-       [DVBT_SCALE1_BA9]       = {0x2, 0xa9,  7, 0},
-       [DVBT_SCALE1_BAA]       = {0x2, 0xaa,  7, 0},
-       [DVBT_SCALE1_BAB]       = {0x2, 0xab,  7, 0},
-       [DVBT_SCALE1_BAC]       = {0x2, 0xac,  7, 0},
-       [DVBT_SCALE1_BB0]       = {0x2, 0xb0,  7, 0},
-       [DVBT_SCALE1_BB1]       = {0x2, 0xb1,  7, 0},
-       [DVBT_KB_P1]            = {0x1, 0x64,  3, 1},
-       [DVBT_KB_P2]            = {0x1, 0x64,  6, 4},
-       [DVBT_KB_P3]            = {0x1, 0x65,  2, 0},
-       [DVBT_OPT_ADC_IQ]       = {0x0, 0x6,   5, 4},
-       [DVBT_AD_AVI]           = {0x0, 0x9,   1, 0},
-       [DVBT_AD_AVQ]           = {0x0, 0x9,   3, 2},
-       [DVBT_K1_CR_STEP12]     = {0x2, 0xad,  9, 4},
-       [DVBT_TRK_KS_P2]        = {0x1, 0x6f,  2, 0},
-       [DVBT_TRK_KS_I2]        = {0x1, 0x70,  5, 3},
-       [DVBT_TR_THD_SET2]      = {0x1, 0x72,  3, 0},
-       [DVBT_TRK_KC_P2]        = {0x1, 0x73,  5, 3},
-       [DVBT_TRK_KC_I2]        = {0x1, 0x75,  2, 0},
-       [DVBT_CR_THD_SET2]      = {0x1, 0x76,  7, 6},
-       [DVBT_PSET_IFFREQ]      = {0x1, 0x19, 21, 0},
-       [DVBT_SPEC_INV]         = {0x1, 0x15,  0, 0},
-       [DVBT_RSAMP_RATIO]      = {0x1, 0x9f, 27, 2},
-       [DVBT_CFREQ_OFF_RATIO]  = {0x1, 0x9d, 23, 4},
-       [DVBT_FSM_STAGE]        = {0x3, 0x51,  6, 3},
-       [DVBT_RX_CONSTEL]       = {0x3, 0x3c,  3, 2},
-       [DVBT_RX_HIER]          = {0x3, 0x3c,  6, 4},
-       [DVBT_RX_C_RATE_LP]     = {0x3, 0x3d,  2, 0},
-       [DVBT_RX_C_RATE_HP]     = {0x3, 0x3d,  5, 3},
-       [DVBT_GI_IDX]           = {0x3, 0x51,  1, 0},
-       [DVBT_FFT_MODE_IDX]     = {0x3, 0x51,  2, 2},
-       [DVBT_RSD_BER_EST]      = {0x3, 0x4e, 15, 0},
-       [DVBT_CE_EST_EVM]       = {0x4, 0xc,  15, 0},
-       [DVBT_RF_AGC_VAL]       = {0x3, 0x5b, 13, 0},
-       [DVBT_IF_AGC_VAL]       = {0x3, 0x59, 13, 0},
-       [DVBT_DAGC_VAL]         = {0x3, 0x5,   7, 0},
-       [DVBT_SFREQ_OFF]        = {0x3, 0x18, 13, 0},
-       [DVBT_CFREQ_OFF]        = {0x3, 0x5f, 17, 0},
-       [DVBT_POLAR_RF_AGC]     = {0x0, 0xe,   1, 1},
-       [DVBT_POLAR_IF_AGC]     = {0x0, 0xe,   0, 0},
-       [DVBT_AAGC_HOLD]        = {0x1, 0x4,   5, 5},
-       [DVBT_EN_RF_AGC]        = {0x1, 0x4,   6, 6},
-       [DVBT_EN_IF_AGC]        = {0x1, 0x4,   7, 7},
-       [DVBT_IF_AGC_MIN]       = {0x1, 0x8,   7, 0},
-       [DVBT_IF_AGC_MAX]       = {0x1, 0x9,   7, 0},
-       [DVBT_RF_AGC_MIN]       = {0x1, 0xa,   7, 0},
-       [DVBT_RF_AGC_MAX]       = {0x1, 0xb,   7, 0},
-       [DVBT_IF_AGC_MAN]       = {0x1, 0xc,   6, 6},
-       [DVBT_IF_AGC_MAN_VAL]   = {0x1, 0xc,  13, 0},
-       [DVBT_RF_AGC_MAN]       = {0x1, 0xe,   6, 6},
-       [DVBT_RF_AGC_MAN_VAL]   = {0x1, 0xe,  13, 0},
-       [DVBT_DAGC_TRG_VAL]     = {0x1, 0x12,  7, 0},
-       [DVBT_AGC_TARG_VAL_0]   = {0x1, 0x2,   0, 0},
-       [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3,   7, 0},
-       [DVBT_AAGC_LOOP_GAIN]   = {0x1, 0xc7,  5, 1},
-       [DVBT_LOOP_GAIN2_3_0]   = {0x1, 0x4,   4, 1},
-       [DVBT_LOOP_GAIN2_4]     = {0x1, 0x5,   7, 7},
-       [DVBT_LOOP_GAIN3]       = {0x1, 0xc8,  4, 0},
-       [DVBT_VTOP1]            = {0x1, 0x6,   5, 0},
-       [DVBT_VTOP2]            = {0x1, 0xc9,  5, 0},
-       [DVBT_VTOP3]            = {0x1, 0xca,  5, 0},
-       [DVBT_KRF1]             = {0x1, 0xcb,  7, 0},
-       [DVBT_KRF2]             = {0x1, 0x7,   7, 0},
-       [DVBT_KRF3]             = {0x1, 0xcd,  7, 0},
-       [DVBT_KRF4]             = {0x1, 0xce,  7, 0},
-       [DVBT_EN_GI_PGA]        = {0x1, 0xe5,  0, 0},
-       [DVBT_THD_LOCK_UP]      = {0x1, 0xd9,  8, 0},
-       [DVBT_THD_LOCK_DW]      = {0x1, 0xdb,  8, 0},
-       [DVBT_THD_UP1]          = {0x1, 0xdd,  7, 0},
-       [DVBT_THD_DW1]          = {0x1, 0xde,  7, 0},
-       [DVBT_INTER_CNT_LEN]    = {0x1, 0xd8,  3, 0},
-       [DVBT_GI_PGA_STATE]     = {0x1, 0xe6,  3, 3},
-       [DVBT_EN_AGC_PGA]       = {0x1, 0xd7,  0, 0},
-       [DVBT_CKOUTPAR]         = {0x1, 0x7b,  5, 5},
-       [DVBT_CKOUT_PWR]        = {0x1, 0x7b,  6, 6},
-       [DVBT_SYNC_DUR]         = {0x1, 0x7b,  7, 7},
-       [DVBT_ERR_DUR]          = {0x1, 0x7c,  0, 0},
-       [DVBT_SYNC_LVL]         = {0x1, 0x7c,  1, 1},
-       [DVBT_ERR_LVL]          = {0x1, 0x7c,  2, 2},
-       [DVBT_VAL_LVL]          = {0x1, 0x7c,  3, 3},
-       [DVBT_SERIAL]           = {0x1, 0x7c,  4, 4},
-       [DVBT_SER_LSB]          = {0x1, 0x7c,  5, 5},
-       [DVBT_CDIV_PH0]         = {0x1, 0x7d,  3, 0},
-       [DVBT_CDIV_PH1]         = {0x1, 0x7d,  7, 4},
-       [DVBT_MPEG_IO_OPT_2_2]  = {0x0, 0x6,   7, 7},
-       [DVBT_MPEG_IO_OPT_1_0]  = {0x0, 0x7,   7, 6},
-       [DVBT_CKOUTPAR_PIP]     = {0x0, 0xb7,  4, 4},
-       [DVBT_CKOUT_PWR_PIP]    = {0x0, 0xb7,  3, 3},
-       [DVBT_SYNC_LVL_PIP]     = {0x0, 0xb7,  2, 2},
-       [DVBT_ERR_LVL_PIP]      = {0x0, 0xb7,  1, 1},
-       [DVBT_VAL_LVL_PIP]      = {0x0, 0xb7,  0, 0},
-       [DVBT_CKOUTPAR_PID]     = {0x0, 0xb9,  4, 4},
-       [DVBT_CKOUT_PWR_PID]    = {0x0, 0xb9,  3, 3},
-       [DVBT_SYNC_LVL_PID]     = {0x0, 0xb9,  2, 2},
-       [DVBT_ERR_LVL_PID]      = {0x0, 0xb9,  1, 1},
-       [DVBT_VAL_LVL_PID]      = {0x0, 0xb9,  0, 0},
-       [DVBT_SM_PASS]          = {0x1, 0x93, 11, 0},
-       [DVBT_AD7_SETTING]      = {0x0, 0x11, 15, 0},
-       [DVBT_RSSI_R]           = {0x3, 0x1,   6, 0},
-       [DVBT_ACI_DET_IND]      = {0x3, 0x12,  0, 0},
-       [DVBT_REG_MON]          = {0x0, 0xd,   1, 0},
-       [DVBT_REG_MONSEL]       = {0x0, 0xd,   2, 2},
-       [DVBT_REG_GPE]          = {0x0, 0xd,   7, 7},
-       [DVBT_REG_GPO]          = {0x0, 0x10,  0, 0},
-       [DVBT_REG_4MSEL]        = {0x0, 0x13,  0, 0},
-};
-
-/* write multiple hardware registers */
-static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[1+len];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 1+len,
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple hardware registers */
-static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
-               ret = -EREMOTEIO;
-}
-return ret;
-}
-
-/* write multiple registers */
-static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
-       int len)
-{
-       int ret;
-
-
-       /* switch bank if needed */
-       if (page != priv->page) {
-               ret = rtl2832_wr(priv, 0x00, &page, 1);
-               if (ret)
-                       return ret;
-
-               priv->page = page;
-}
-
-return rtl2832_wr(priv, reg, val, len);
-}
-
-/* read multiple registers */
-static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
-       int len)
-{
-       int ret;
-
-       /* switch bank if needed */
-       if (page != priv->page) {
-               ret = rtl2832_wr(priv, 0x00, &page, 1);
-               if (ret)
-                       return ret;
-
-               priv->page = page;
-       }
-
-       return rtl2832_rd(priv, reg, val, len);
-}
-
-#if 0 /* currently not used */
-/* write single register */
-static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
-{
-       return rtl2832_wr_regs(priv, reg, page, &val, 1);
-}
-#endif
-
-/* read single register */
-static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
-{
-       return rtl2832_rd_regs(priv, reg, page, val, 1);
-}
-
-int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
-{
-       int ret;
-
-       u8 reg_start_addr;
-       u8 msb, lsb;
-       u8 page;
-       u8 reading[4];
-       u32 reading_tmp;
-       int i;
-
-       u8 len;
-       u32 mask;
-
-       reg_start_addr = registers[reg].start_address;
-       msb = registers[reg].msb;
-       lsb = registers[reg].lsb;
-       page = registers[reg].page;
-
-       len = (msb >> 3) + 1;
-       mask = REG_MASK(msb - lsb);
-
-       ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
-       if (ret)
-               goto err;
-
-       reading_tmp = 0;
-       for (i = 0; i < len; i++)
-               reading_tmp |= reading[i] << ((len - 1 - i) * 8);
-
-       *val = (reading_tmp >> lsb) & mask;
-
-       return ret;
-
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-
-}
-
-int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
-{
-       int ret, i;
-       u8 len;
-       u8 reg_start_addr;
-       u8 msb, lsb;
-       u8 page;
-       u32 mask;
-
-
-       u8 reading[4];
-       u8 writing[4];
-       u32 reading_tmp;
-       u32 writing_tmp;
-
-
-       reg_start_addr = registers[reg].start_address;
-       msb = registers[reg].msb;
-       lsb = registers[reg].lsb;
-       page = registers[reg].page;
-
-       len = (msb >> 3) + 1;
-       mask = REG_MASK(msb - lsb);
-
-
-       ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
-       if (ret)
-               goto err;
-
-       reading_tmp = 0;
-       for (i = 0; i < len; i++)
-               reading_tmp |= reading[i] << ((len - 1 - i) * 8);
-
-       writing_tmp = reading_tmp & ~(mask << lsb);
-       writing_tmp |= ((val & mask) << lsb);
-
-
-       for (i = 0; i < len; i++)
-               writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
-
-       ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
-       if (ret)
-               goto err;
-
-       return ret;
-
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-
-}
-
-
-static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       int ret;
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-
-       dbg("%s: enable=%d", __func__, enable);
-
-       /* gate already open or close */
-       if (priv->i2c_gate_state == enable)
-               return 0;
-
-       ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
-       if (ret)
-               goto err;
-
-       priv->i2c_gate_state = enable;
-
-       return ret;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-
-
-static int rtl2832_init(struct dvb_frontend *fe)
-{
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-       int i, ret;
-
-       u8 en_bbin;
-       u64 pset_iffreq;
-
-       /* initialization values for the demodulator registers */
-       struct rtl2832_reg_value rtl2832_initial_regs[] = {
-               {DVBT_AD_EN_REG,                0x1},
-               {DVBT_AD_EN_REG1,               0x1},
-               {DVBT_RSD_BER_FAIL_VAL,         0x2800},
-               {DVBT_MGD_THD0,                 0x10},
-               {DVBT_MGD_THD1,                 0x20},
-               {DVBT_MGD_THD2,                 0x20},
-               {DVBT_MGD_THD3,                 0x40},
-               {DVBT_MGD_THD4,                 0x22},
-               {DVBT_MGD_THD5,                 0x32},
-               {DVBT_MGD_THD6,                 0x37},
-               {DVBT_MGD_THD7,                 0x39},
-               {DVBT_EN_BK_TRK,                0x0},
-               {DVBT_EN_CACQ_NOTCH,            0x0},
-               {DVBT_AD_AV_REF,                0x2a},
-               {DVBT_REG_PI,                   0x6},
-               {DVBT_PIP_ON,                   0x0},
-               {DVBT_CDIV_PH0,                 0x8},
-               {DVBT_CDIV_PH1,                 0x8},
-               {DVBT_SCALE1_B92,               0x4},
-               {DVBT_SCALE1_B93,               0xb0},
-               {DVBT_SCALE1_BA7,               0x78},
-               {DVBT_SCALE1_BA9,               0x28},
-               {DVBT_SCALE1_BAA,               0x59},
-               {DVBT_SCALE1_BAB,               0x83},
-               {DVBT_SCALE1_BAC,               0xd4},
-               {DVBT_SCALE1_BB0,               0x65},
-               {DVBT_SCALE1_BB1,               0x43},
-               {DVBT_KB_P1,                    0x1},
-               {DVBT_KB_P2,                    0x4},
-               {DVBT_KB_P3,                    0x7},
-               {DVBT_K1_CR_STEP12,             0xa},
-               {DVBT_REG_GPE,                  0x1},
-               {DVBT_SERIAL,                   0x0},
-               {DVBT_CDIV_PH0,                 0x9},
-               {DVBT_CDIV_PH1,                 0x9},
-               {DVBT_MPEG_IO_OPT_2_2,          0x0},
-               {DVBT_MPEG_IO_OPT_1_0,          0x0},
-               {DVBT_TRK_KS_P2,                0x4},
-               {DVBT_TRK_KS_I2,                0x7},
-               {DVBT_TR_THD_SET2,              0x6},
-               {DVBT_TRK_KC_I2,                0x5},
-               {DVBT_CR_THD_SET2,              0x1},
-               {DVBT_SPEC_INV,                 0x0},
-               {DVBT_DAGC_TRG_VAL,             0x5a},
-               {DVBT_AGC_TARG_VAL_0,           0x0},
-               {DVBT_AGC_TARG_VAL_8_1,         0x5a},
-               {DVBT_AAGC_LOOP_GAIN,           0x16},
-               {DVBT_LOOP_GAIN2_3_0,           0x6},
-               {DVBT_LOOP_GAIN2_4,             0x1},
-               {DVBT_LOOP_GAIN3,               0x16},
-               {DVBT_VTOP1,                    0x35},
-               {DVBT_VTOP2,                    0x21},
-               {DVBT_VTOP3,                    0x21},
-               {DVBT_KRF1,                     0x0},
-               {DVBT_KRF2,                     0x40},
-               {DVBT_KRF3,                     0x10},
-               {DVBT_KRF4,                     0x10},
-               {DVBT_IF_AGC_MIN,               0x80},
-               {DVBT_IF_AGC_MAX,               0x7f},
-               {DVBT_RF_AGC_MIN,               0x80},
-               {DVBT_RF_AGC_MAX,               0x7f},
-               {DVBT_POLAR_RF_AGC,             0x0},
-               {DVBT_POLAR_IF_AGC,             0x0},
-               {DVBT_AD7_SETTING,              0xe9bf},
-               {DVBT_EN_GI_PGA,                0x0},
-               {DVBT_THD_LOCK_UP,              0x0},
-               {DVBT_THD_LOCK_DW,              0x0},
-               {DVBT_THD_UP1,                  0x11},
-               {DVBT_THD_DW1,                  0xef},
-               {DVBT_INTER_CNT_LEN,            0xc},
-               {DVBT_GI_PGA_STATE,             0x0},
-               {DVBT_EN_AGC_PGA,               0x1},
-               {DVBT_IF_AGC_MAN,               0x0},
-       };
-
-
-       dbg("%s", __func__);
-
-       en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
-
-       /*
-       * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
-       *               / CrystalFreqHz)
-       */
-       pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
-       pset_iffreq *= 0x400000;
-       pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
-       pset_iffreq = pset_iffreq & 0x3fffff;
-
-
-
-       for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
-               ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
-                       rtl2832_initial_regs[i].value);
-               if (ret)
-                       goto err;
-       }
-
-       /* if frequency settings */
-       ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
-               if (ret)
-                       goto err;
-
-       ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
-               if (ret)
-                       goto err;
-
-       priv->sleeping = false;
-
-       return ret;
-
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2832_sleep(struct dvb_frontend *fe)
-{
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-
-       dbg("%s", __func__);
-       priv->sleeping = true;
-       return 0;
-}
-
-int rtl2832_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       dbg("%s", __func__);
-       s->min_delay_ms = 1000;
-       s->step_size = fe->ops.info.frequency_stepsize * 2;
-       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
-       return 0;
-}
-
-static int rtl2832_set_frontend(struct dvb_frontend *fe)
-{
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, j;
-       u64 bw_mode, num, num2;
-       u32 resamp_ratio, cfreq_off_ratio;
-
-
-       static u8 bw_params[3][32] = {
-       /* 6 MHz bandwidth */
-               {
-               0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
-               0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
-               0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
-               0x19, 0xe0,
-               },
-
-       /*  7 MHz bandwidth */
-               {
-               0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
-               0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
-               0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
-               0x19, 0x10,
-               },
-
-       /*  8 MHz bandwidth */
-               {
-               0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
-               0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
-               0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
-               0x19, 0xe0,
-               },
-       };
-
-
-       dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
-               c->frequency, c->bandwidth_hz, c->inversion);
-
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               i = 0;
-               bw_mode = 48000000;
-               break;
-       case 7000000:
-               i = 1;
-               bw_mode = 56000000;
-               break;
-       case 8000000:
-               i = 2;
-               bw_mode = 64000000;
-               break;
-       default:
-               dbg("invalid bandwidth");
-               return -EINVAL;
-       }
-
-       for (j = 0; j < sizeof(bw_params[0]); j++) {
-               ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
-               if (ret)
-                       goto err;
-       }
-
-       /* calculate and set resample ratio
-       * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
-       *       / ConstWithBandwidthMode)
-       */
-       num = priv->cfg.xtal * 7;
-       num *= 0x400000;
-       num = div_u64(num, bw_mode);
-       resamp_ratio =  num & 0x3ffffff;
-       ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
-       if (ret)
-               goto err;
-
-       /* calculate and set cfreq off ratio
-       * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
-       *       / (CrystalFreqHz * 7))
-       */
-       num = bw_mode << 20;
-       num2 = priv->cfg.xtal * 7;
-       num = div_u64(num, num2);
-       num = -num;
-       cfreq_off_ratio = num & 0xfffff;
-       ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
-       if (ret)
-               goto err;
-
-
-       /* soft reset */
-       ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
-       if (ret)
-               goto err;
-
-       ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       info("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-       int ret;
-       u32 tmp;
-       *status = 0;
-
-
-       dbg("%s", __func__);
-       if (priv->sleeping)
-               return 0;
-
-       ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
-       if (ret)
-               goto err;
-
-       if (tmp == 11) {
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-       }
-       /* TODO find out if this is also true for rtl2832? */
-       /*else if (tmp == 10) {
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI;
-       }*/
-
-       return ret;
-err:
-       info("%s: failed=%d", __func__, ret);
-       return ret;
-}
-
-static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       *snr = 0;
-       return 0;
-}
-
-static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       *ber = 0;
-       return 0;
-}
-
-static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       *ucblocks = 0;
-       return 0;
-}
-
-
-static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       *strength = 0;
-       return 0;
-}
-
-static struct dvb_frontend_ops rtl2832_ops;
-
-static void rtl2832_release(struct dvb_frontend *fe)
-{
-       struct rtl2832_priv *priv = fe->demodulator_priv;
-
-       dbg("%s", __func__);
-       kfree(priv);
-}
-
-struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
-       struct i2c_adapter *i2c)
-{
-       struct rtl2832_priv *priv = NULL;
-       int ret = 0;
-       u8 tmp;
-
-       dbg("%s", __func__);
-
-       /* allocate memory for the internal state */
-       priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
-       if (priv == NULL)
-               goto err;
-
-       /* setup the priv */
-       priv->i2c = i2c;
-       priv->tuner = cfg->tuner;
-       memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
-
-       /* check if the demod is there */
-       ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
-       if (ret)
-               goto err;
-
-       /* create dvb_frontend */
-       memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-
-       /* TODO implement sleep mode */
-       priv->sleeping = true;
-
-       return &priv->fe;
-err:
-       dbg("%s: failed=%d", __func__, ret);
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(rtl2832_attach);
-
-static struct dvb_frontend_ops rtl2832_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Realtek RTL2832 (DVB-T)",
-               .frequency_min    = 174000000,
-               .frequency_max    = 862000000,
-               .frequency_stepsize = 166667,
-               .caps = FE_CAN_FEC_1_2 |
-                       FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 |
-                       FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-        },
-
-       .release = rtl2832_release,
-
-       .init = rtl2832_init,
-       .sleep = rtl2832_sleep,
-
-       .get_tune_settings = rtl2832_get_tune_settings,
-
-       .set_frontend = rtl2832_set_frontend,
-
-       .read_status = rtl2832_read_status,
-       .read_snr = rtl2832_read_snr,
-       .read_ber = rtl2832_read_ber,
-       .read_ucblocks = rtl2832_read_ucblocks,
-       .read_signal_strength = rtl2832_read_signal_strength,
-       .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
-};
-
-MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
-MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.5");
diff --git a/drivers/media/dvb/frontends/rtl2832.h b/drivers/media/dvb/frontends/rtl2832.h
deleted file mode 100644 (file)
index d94dc9a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Realtek RTL2832 DVB-T demodulator driver
- *
- * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
- *
- *     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.
- */
-
-#ifndef RTL2832_H
-#define RTL2832_H
-
-#include <linux/dvb/frontend.h>
-
-struct rtl2832_config {
-       /*
-        * Demodulator I2C address.
-        */
-       u8 i2c_addr;
-
-       /*
-        * Xtal frequency.
-        * Hz
-        * 4000000, 16000000, 25000000, 28800000
-        */
-       u32 xtal;
-
-       /*
-        * IFs for all used modes.
-        * Hz
-        * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
-        */
-       u32 if_dvbt;
-
-       /*
-        */
-       u8 tuner;
-};
-
-
-#if defined(CONFIG_DVB_RTL2832) || \
-       (defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE))
-extern struct dvb_frontend *rtl2832_attach(
-       const struct rtl2832_config *cfg,
-       struct i2c_adapter *i2c
-);
-
-extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
-       struct dvb_frontend *fe
-);
-#else
-static inline struct dvb_frontend *rtl2832_attach(
-       const struct rtl2832_config *config,
-       struct i2c_adapter *i2c
-)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-
-#endif /* RTL2832_H */
diff --git a/drivers/media/dvb/frontends/rtl2832_priv.h b/drivers/media/dvb/frontends/rtl2832_priv.h
deleted file mode 100644 (file)
index 0ce9502..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Realtek RTL2832 DVB-T demodulator driver
- *
- * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
- *
- *     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.
- */
-
-#ifndef RTL2832_PRIV_H
-#define RTL2832_PRIV_H
-
-#include "dvb_frontend.h"
-#include "rtl2832.h"
-
-#define LOG_PREFIX "rtl2832"
-
-#undef dbg
-#define dbg(f, arg...) \
-do { \
-       if (rtl2832_debug)  \
-               printk(KERN_INFO     LOG_PREFIX": " f "\n" , ## arg); \
-} while (0)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-struct rtl2832_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct rtl2832_config cfg;
-
-       bool i2c_gate_state;
-       bool sleeping;
-
-       u8 tuner;
-       u8 page; /* active register page */
-};
-
-struct rtl2832_reg_entry {
-       u8 page;
-       u8 start_address;
-       u8 msb;
-       u8 lsb;
-};
-
-struct rtl2832_reg_value {
-       int reg;
-       u32 value;
-};
-
-
-/* Demod register bit names */
-enum DVBT_REG_BIT_NAME {
-       DVBT_SOFT_RST,
-       DVBT_IIC_REPEAT,
-       DVBT_TR_WAIT_MIN_8K,
-       DVBT_RSD_BER_FAIL_VAL,
-       DVBT_EN_BK_TRK,
-       DVBT_REG_PI,
-       DVBT_REG_PFREQ_1_0,
-       DVBT_PD_DA8,
-       DVBT_LOCK_TH,
-       DVBT_BER_PASS_SCAL,
-       DVBT_CE_FFSM_BYPASS,
-       DVBT_ALPHAIIR_N,
-       DVBT_ALPHAIIR_DIF,
-       DVBT_EN_TRK_SPAN,
-       DVBT_LOCK_TH_LEN,
-       DVBT_CCI_THRE,
-       DVBT_CCI_MON_SCAL,
-       DVBT_CCI_M0,
-       DVBT_CCI_M1,
-       DVBT_CCI_M2,
-       DVBT_CCI_M3,
-       DVBT_SPEC_INIT_0,
-       DVBT_SPEC_INIT_1,
-       DVBT_SPEC_INIT_2,
-       DVBT_AD_EN_REG,
-       DVBT_AD_EN_REG1,
-       DVBT_EN_BBIN,
-       DVBT_MGD_THD0,
-       DVBT_MGD_THD1,
-       DVBT_MGD_THD2,
-       DVBT_MGD_THD3,
-       DVBT_MGD_THD4,
-       DVBT_MGD_THD5,
-       DVBT_MGD_THD6,
-       DVBT_MGD_THD7,
-       DVBT_EN_CACQ_NOTCH,
-       DVBT_AD_AV_REF,
-       DVBT_PIP_ON,
-       DVBT_SCALE1_B92,
-       DVBT_SCALE1_B93,
-       DVBT_SCALE1_BA7,
-       DVBT_SCALE1_BA9,
-       DVBT_SCALE1_BAA,
-       DVBT_SCALE1_BAB,
-       DVBT_SCALE1_BAC,
-       DVBT_SCALE1_BB0,
-       DVBT_SCALE1_BB1,
-       DVBT_KB_P1,
-       DVBT_KB_P2,
-       DVBT_KB_P3,
-       DVBT_OPT_ADC_IQ,
-       DVBT_AD_AVI,
-       DVBT_AD_AVQ,
-       DVBT_K1_CR_STEP12,
-       DVBT_TRK_KS_P2,
-       DVBT_TRK_KS_I2,
-       DVBT_TR_THD_SET2,
-       DVBT_TRK_KC_P2,
-       DVBT_TRK_KC_I2,
-       DVBT_CR_THD_SET2,
-       DVBT_PSET_IFFREQ,
-       DVBT_SPEC_INV,
-       DVBT_BW_INDEX,
-       DVBT_RSAMP_RATIO,
-       DVBT_CFREQ_OFF_RATIO,
-       DVBT_FSM_STAGE,
-       DVBT_RX_CONSTEL,
-       DVBT_RX_HIER,
-       DVBT_RX_C_RATE_LP,
-       DVBT_RX_C_RATE_HP,
-       DVBT_GI_IDX,
-       DVBT_FFT_MODE_IDX,
-       DVBT_RSD_BER_EST,
-       DVBT_CE_EST_EVM,
-       DVBT_RF_AGC_VAL,
-       DVBT_IF_AGC_VAL,
-       DVBT_DAGC_VAL,
-       DVBT_SFREQ_OFF,
-       DVBT_CFREQ_OFF,
-       DVBT_POLAR_RF_AGC,
-       DVBT_POLAR_IF_AGC,
-       DVBT_AAGC_HOLD,
-       DVBT_EN_RF_AGC,
-       DVBT_EN_IF_AGC,
-       DVBT_IF_AGC_MIN,
-       DVBT_IF_AGC_MAX,
-       DVBT_RF_AGC_MIN,
-       DVBT_RF_AGC_MAX,
-       DVBT_IF_AGC_MAN,
-       DVBT_IF_AGC_MAN_VAL,
-       DVBT_RF_AGC_MAN,
-       DVBT_RF_AGC_MAN_VAL,
-       DVBT_DAGC_TRG_VAL,
-       DVBT_AGC_TARG_VAL,
-       DVBT_LOOP_GAIN_3_0,
-       DVBT_LOOP_GAIN_4,
-       DVBT_VTOP,
-       DVBT_KRF,
-       DVBT_AGC_TARG_VAL_0,
-       DVBT_AGC_TARG_VAL_8_1,
-       DVBT_AAGC_LOOP_GAIN,
-       DVBT_LOOP_GAIN2_3_0,
-       DVBT_LOOP_GAIN2_4,
-       DVBT_LOOP_GAIN3,
-       DVBT_VTOP1,
-       DVBT_VTOP2,
-       DVBT_VTOP3,
-       DVBT_KRF1,
-       DVBT_KRF2,
-       DVBT_KRF3,
-       DVBT_KRF4,
-       DVBT_EN_GI_PGA,
-       DVBT_THD_LOCK_UP,
-       DVBT_THD_LOCK_DW,
-       DVBT_THD_UP1,
-       DVBT_THD_DW1,
-       DVBT_INTER_CNT_LEN,
-       DVBT_GI_PGA_STATE,
-       DVBT_EN_AGC_PGA,
-       DVBT_CKOUTPAR,
-       DVBT_CKOUT_PWR,
-       DVBT_SYNC_DUR,
-       DVBT_ERR_DUR,
-       DVBT_SYNC_LVL,
-       DVBT_ERR_LVL,
-       DVBT_VAL_LVL,
-       DVBT_SERIAL,
-       DVBT_SER_LSB,
-       DVBT_CDIV_PH0,
-       DVBT_CDIV_PH1,
-       DVBT_MPEG_IO_OPT_2_2,
-       DVBT_MPEG_IO_OPT_1_0,
-       DVBT_CKOUTPAR_PIP,
-       DVBT_CKOUT_PWR_PIP,
-       DVBT_SYNC_LVL_PIP,
-       DVBT_ERR_LVL_PIP,
-       DVBT_VAL_LVL_PIP,
-       DVBT_CKOUTPAR_PID,
-       DVBT_CKOUT_PWR_PID,
-       DVBT_SYNC_LVL_PID,
-       DVBT_ERR_LVL_PID,
-       DVBT_VAL_LVL_PID,
-       DVBT_SM_PASS,
-       DVBT_UPDATE_REG_2,
-       DVBT_BTHD_P3,
-       DVBT_BTHD_D3,
-       DVBT_FUNC4_REG0,
-       DVBT_FUNC4_REG1,
-       DVBT_FUNC4_REG2,
-       DVBT_FUNC4_REG3,
-       DVBT_FUNC4_REG4,
-       DVBT_FUNC4_REG5,
-       DVBT_FUNC4_REG6,
-       DVBT_FUNC4_REG7,
-       DVBT_FUNC4_REG8,
-       DVBT_FUNC4_REG9,
-       DVBT_FUNC4_REG10,
-       DVBT_FUNC5_REG0,
-       DVBT_FUNC5_REG1,
-       DVBT_FUNC5_REG2,
-       DVBT_FUNC5_REG3,
-       DVBT_FUNC5_REG4,
-       DVBT_FUNC5_REG5,
-       DVBT_FUNC5_REG6,
-       DVBT_FUNC5_REG7,
-       DVBT_FUNC5_REG8,
-       DVBT_FUNC5_REG9,
-       DVBT_FUNC5_REG10,
-       DVBT_FUNC5_REG11,
-       DVBT_FUNC5_REG12,
-       DVBT_FUNC5_REG13,
-       DVBT_FUNC5_REG14,
-       DVBT_FUNC5_REG15,
-       DVBT_FUNC5_REG16,
-       DVBT_FUNC5_REG17,
-       DVBT_FUNC5_REG18,
-       DVBT_AD7_SETTING,
-       DVBT_RSSI_R,
-       DVBT_ACI_DET_IND,
-       DVBT_REG_MON,
-       DVBT_REG_MONSEL,
-       DVBT_REG_GPE,
-       DVBT_REG_GPO,
-       DVBT_REG_4MSEL,
-       DVBT_TEST_REG_1,
-       DVBT_TEST_REG_2,
-       DVBT_TEST_REG_3,
-       DVBT_TEST_REG_4,
-       DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
-};
-
-#endif /* RTL2832_PRIV_H */
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
deleted file mode 100644 (file)
index f71b062..0000000
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
-    Samsung S5H1409 VSB/QAM demodulator driver
-
-    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "s5h1409.h"
-
-struct s5h1409_state {
-
-       struct i2c_adapter *i2c;
-
-       /* configuration settings */
-       const struct s5h1409_config *config;
-
-       struct dvb_frontend frontend;
-
-       /* previous uncorrected block counter */
-       fe_modulation_t current_modulation;
-
-       u32 current_frequency;
-       int if_freq;
-
-       u32 is_qam_locked;
-
-       /* QAM tuning state goes through the following state transitions */
-#define QAM_STATE_UNTUNED 0
-#define QAM_STATE_TUNING_STARTED 1
-#define QAM_STATE_INTERLEAVE_SET 2
-#define QAM_STATE_QAM_OPTIMIZED_L1 3
-#define QAM_STATE_QAM_OPTIMIZED_L2 4
-#define QAM_STATE_QAM_OPTIMIZED_L3 5
-       u8  qam_state;
-};
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-#define dprintk        if (debug) printk
-
-/* Register values to initialise the demod, this will set VSB by default */
-static struct init_tab {
-       u8      reg;
-       u16     data;
-} init_tab[] = {
-       { 0x00, 0x0071, },
-       { 0x01, 0x3213, },
-       { 0x09, 0x0025, },
-       { 0x1c, 0x001d, },
-       { 0x1f, 0x002d, },
-       { 0x20, 0x001d, },
-       { 0x22, 0x0022, },
-       { 0x23, 0x0020, },
-       { 0x29, 0x110f, },
-       { 0x2a, 0x10b4, },
-       { 0x2b, 0x10ae, },
-       { 0x2c, 0x0031, },
-       { 0x31, 0x010d, },
-       { 0x32, 0x0100, },
-       { 0x44, 0x0510, },
-       { 0x54, 0x0104, },
-       { 0x58, 0x2222, },
-       { 0x59, 0x1162, },
-       { 0x5a, 0x3211, },
-       { 0x5d, 0x0370, },
-       { 0x5e, 0x0296, },
-       { 0x61, 0x0010, },
-       { 0x63, 0x4a00, },
-       { 0x65, 0x0800, },
-       { 0x71, 0x0003, },
-       { 0x72, 0x0470, },
-       { 0x81, 0x0002, },
-       { 0x82, 0x0600, },
-       { 0x86, 0x0002, },
-       { 0x8a, 0x2c38, },
-       { 0x8b, 0x2a37, },
-       { 0x92, 0x302f, },
-       { 0x93, 0x3332, },
-       { 0x96, 0x000c, },
-       { 0x99, 0x0101, },
-       { 0x9c, 0x2e37, },
-       { 0x9d, 0x2c37, },
-       { 0x9e, 0x2c37, },
-       { 0xab, 0x0100, },
-       { 0xac, 0x1003, },
-       { 0xad, 0x103f, },
-       { 0xe2, 0x0100, },
-       { 0xe3, 0x1000, },
-       { 0x28, 0x1010, },
-       { 0xb1, 0x000e, },
-};
-
-/* VSB SNR lookup table */
-static struct vsb_snr_tab {
-       u16     val;
-       u16     data;
-} vsb_snr_tab[] = {
-       {  924, 300, },
-       {  923, 300, },
-       {  918, 295, },
-       {  915, 290, },
-       {  911, 285, },
-       {  906, 280, },
-       {  901, 275, },
-       {  896, 270, },
-       {  891, 265, },
-       {  885, 260, },
-       {  879, 255, },
-       {  873, 250, },
-       {  864, 245, },
-       {  858, 240, },
-       {  850, 235, },
-       {  841, 230, },
-       {  832, 225, },
-       {  823, 220, },
-       {  812, 215, },
-       {  802, 210, },
-       {  788, 205, },
-       {  778, 200, },
-       {  767, 195, },
-       {  753, 190, },
-       {  740, 185, },
-       {  725, 180, },
-       {  707, 175, },
-       {  689, 170, },
-       {  671, 165, },
-       {  656, 160, },
-       {  637, 155, },
-       {  616, 150, },
-       {  542, 145, },
-       {  519, 140, },
-       {  507, 135, },
-       {  497, 130, },
-       {  492, 125, },
-       {  474, 120, },
-       {  300, 111, },
-       {    0,   0, },
-};
-
-/* QAM64 SNR lookup table */
-static struct qam64_snr_tab {
-       u16     val;
-       u16     data;
-} qam64_snr_tab[] = {
-       {    1,   0, },
-       {   12, 300, },
-       {   15, 290, },
-       {   18, 280, },
-       {   22, 270, },
-       {   23, 268, },
-       {   24, 266, },
-       {   25, 264, },
-       {   27, 262, },
-       {   28, 260, },
-       {   29, 258, },
-       {   30, 256, },
-       {   32, 254, },
-       {   33, 252, },
-       {   34, 250, },
-       {   35, 249, },
-       {   36, 248, },
-       {   37, 247, },
-       {   38, 246, },
-       {   39, 245, },
-       {   40, 244, },
-       {   41, 243, },
-       {   42, 241, },
-       {   43, 240, },
-       {   44, 239, },
-       {   45, 238, },
-       {   46, 237, },
-       {   47, 236, },
-       {   48, 235, },
-       {   49, 234, },
-       {   50, 233, },
-       {   51, 232, },
-       {   52, 231, },
-       {   53, 230, },
-       {   55, 229, },
-       {   56, 228, },
-       {   57, 227, },
-       {   58, 226, },
-       {   59, 225, },
-       {   60, 224, },
-       {   62, 223, },
-       {   63, 222, },
-       {   65, 221, },
-       {   66, 220, },
-       {   68, 219, },
-       {   69, 218, },
-       {   70, 217, },
-       {   72, 216, },
-       {   73, 215, },
-       {   75, 214, },
-       {   76, 213, },
-       {   78, 212, },
-       {   80, 211, },
-       {   81, 210, },
-       {   83, 209, },
-       {   84, 208, },
-       {   85, 207, },
-       {   87, 206, },
-       {   89, 205, },
-       {   91, 204, },
-       {   93, 203, },
-       {   95, 202, },
-       {   96, 201, },
-       {  104, 200, },
-       {  255,   0, },
-};
-
-/* QAM256 SNR lookup table */
-static struct qam256_snr_tab {
-       u16     val;
-       u16     data;
-} qam256_snr_tab[] = {
-       {    1,   0, },
-       {   12, 400, },
-       {   13, 390, },
-       {   15, 380, },
-       {   17, 360, },
-       {   19, 350, },
-       {   22, 348, },
-       {   23, 346, },
-       {   24, 344, },
-       {   25, 342, },
-       {   26, 340, },
-       {   27, 336, },
-       {   28, 334, },
-       {   29, 332, },
-       {   30, 330, },
-       {   31, 328, },
-       {   32, 326, },
-       {   33, 325, },
-       {   34, 322, },
-       {   35, 320, },
-       {   37, 318, },
-       {   39, 316, },
-       {   40, 314, },
-       {   41, 312, },
-       {   42, 310, },
-       {   43, 308, },
-       {   46, 306, },
-       {   47, 304, },
-       {   49, 302, },
-       {   51, 300, },
-       {   53, 298, },
-       {   54, 297, },
-       {   55, 296, },
-       {   56, 295, },
-       {   57, 294, },
-       {   59, 293, },
-       {   60, 292, },
-       {   61, 291, },
-       {   63, 290, },
-       {   64, 289, },
-       {   65, 288, },
-       {   66, 287, },
-       {   68, 286, },
-       {   69, 285, },
-       {   71, 284, },
-       {   72, 283, },
-       {   74, 282, },
-       {   75, 281, },
-       {   76, 280, },
-       {   77, 279, },
-       {   78, 278, },
-       {   81, 277, },
-       {   83, 276, },
-       {   84, 275, },
-       {   86, 274, },
-       {   87, 273, },
-       {   89, 272, },
-       {   90, 271, },
-       {   92, 270, },
-       {   93, 269, },
-       {   95, 268, },
-       {   96, 267, },
-       {   98, 266, },
-       {  100, 265, },
-       {  102, 264, },
-       {  104, 263, },
-       {  105, 262, },
-       {  106, 261, },
-       {  110, 260, },
-       {  255,   0, },
-};
-
-/* 8 bit registers, 16 bit values */
-static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data)
-{
-       int ret;
-       u8 buf[] = { reg, data >> 8,  data & 0xff };
-
-       struct i2c_msg msg = { .addr = state->config->demod_address,
-                              .flags = 0, .buf = buf, .len = 3 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "
-                      "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0, 0 };
-
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0,
-                 .buf = b0, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD,
-                 .buf = b1, .len = 2 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk("%s: readreg error (ret == %i)\n", __func__, ret);
-       return (b1[0] << 8) | b1[1];
-}
-
-static int s5h1409_softreset(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       s5h1409_writereg(state, 0xf5, 0);
-       s5h1409_writereg(state, 0xf5, 1);
-       state->is_qam_locked = 0;
-       state->qam_state = QAM_STATE_UNTUNED;
-       return 0;
-}
-
-#define S5H1409_VSB_IF_FREQ 5380
-#define S5H1409_QAM_IF_FREQ (state->config->qam_if)
-
-static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d KHz)\n", __func__, KHz);
-
-       switch (KHz) {
-       case 4000:
-               s5h1409_writereg(state, 0x87, 0x014b);
-               s5h1409_writereg(state, 0x88, 0x0cb5);
-               s5h1409_writereg(state, 0x89, 0x03e2);
-               break;
-       case 5380:
-       case 44000:
-       default:
-               s5h1409_writereg(state, 0x87, 0x01be);
-               s5h1409_writereg(state, 0x88, 0x0436);
-               s5h1409_writereg(state, 0x89, 0x054d);
-               break;
-       }
-       state->if_freq = KHz;
-
-       return 0;
-}
-
-static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, inverted);
-
-       if (inverted == 1)
-               return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
-       else
-               return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
-}
-
-static int s5h1409_enable_modulation(struct dvb_frontend *fe,
-                                    fe_modulation_t m)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(0x%08x)\n", __func__, m);
-
-       switch (m) {
-       case VSB_8:
-               dprintk("%s() VSB_8\n", __func__);
-               if (state->if_freq != S5H1409_VSB_IF_FREQ)
-                       s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);
-               s5h1409_writereg(state, 0xf4, 0);
-               break;
-       case QAM_64:
-       case QAM_256:
-       case QAM_AUTO:
-               dprintk("%s() QAM_AUTO (64/256)\n", __func__);
-               if (state->if_freq != S5H1409_QAM_IF_FREQ)
-                       s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
-               s5h1409_writereg(state, 0xf4, 1);
-               s5h1409_writereg(state, 0x85, 0x110);
-               break;
-       default:
-               dprintk("%s() Invalid modulation\n", __func__);
-               return -EINVAL;
-       }
-
-       state->current_modulation = m;
-       s5h1409_softreset(fe);
-
-       return 0;
-}
-
-static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (enable)
-               return s5h1409_writereg(state, 0xf3, 1);
-       else
-               return s5h1409_writereg(state, 0xf3, 0);
-}
-
-static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (enable)
-               return s5h1409_writereg(state, 0xe3,
-                       s5h1409_readreg(state, 0xe3) | 0x1100);
-       else
-               return s5h1409_writereg(state, 0xe3,
-                       s5h1409_readreg(state, 0xe3) & 0xfeff);
-}
-
-static int s5h1409_sleep(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       return s5h1409_writereg(state, 0xf2, enable);
-}
-
-static int s5h1409_register_reset(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       return s5h1409_writereg(state, 0xfa, 0);
-}
-
-static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg;
-
-       if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
-               /* We should not perform amhum optimization until
-                  the interleave mode has been configured */
-               return;
-       }
-
-       if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
-               /* We've already reached the maximum optimization level, so
-                  dont bother banging on the status registers */
-               return;
-       }
-
-       /* QAM EQ lock check */
-       reg = s5h1409_readreg(state, 0xf0);
-
-       if ((reg >> 13) & 0x1) {
-               reg &= 0xff;
-
-               s5h1409_writereg(state, 0x96, 0x000c);
-               if (reg < 0x68) {
-                       if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
-                               dprintk("%s() setting QAM state to OPT_L3\n",
-                                       __func__);
-                               s5h1409_writereg(state, 0x93, 0x3130);
-                               s5h1409_writereg(state, 0x9e, 0x2836);
-                               state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
-                       }
-               } else {
-                       if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
-                               dprintk("%s() setting QAM state to OPT_L2\n",
-                                       __func__);
-                               s5h1409_writereg(state, 0x93, 0x3332);
-                               s5h1409_writereg(state, 0x9e, 0x2c37);
-                               state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
-                       }
-               }
-
-       } else {
-               if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
-                       dprintk("%s() setting QAM state to OPT_L1\n", __func__);
-                       s5h1409_writereg(state, 0x96, 0x0008);
-                       s5h1409_writereg(state, 0x93, 0x3332);
-                       s5h1409_writereg(state, 0x9e, 0x2c37);
-                       state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
-               }
-       }
-}
-
-static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg;
-
-       if (state->is_qam_locked)
-               return;
-
-       /* QAM EQ lock check */
-       reg = s5h1409_readreg(state, 0xf0);
-
-       if ((reg >> 13) & 0x1) {
-
-               state->is_qam_locked = 1;
-               reg &= 0xff;
-
-               s5h1409_writereg(state, 0x96, 0x00c);
-               if ((reg < 0x38) || (reg > 0x68)) {
-                       s5h1409_writereg(state, 0x93, 0x3332);
-                       s5h1409_writereg(state, 0x9e, 0x2c37);
-               } else {
-                       s5h1409_writereg(state, 0x93, 0x3130);
-                       s5h1409_writereg(state, 0x9e, 0x2836);
-               }
-
-       } else {
-               s5h1409_writereg(state, 0x96, 0x0008);
-               s5h1409_writereg(state, 0x93, 0x3332);
-               s5h1409_writereg(state, 0x9e, 0x2c37);
-       }
-}
-
-static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg, reg1, reg2;
-
-       if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
-               /* We've done the optimization already */
-               return;
-       }
-
-       reg = s5h1409_readreg(state, 0xf1);
-
-       /* Master lock */
-       if ((reg >> 15) & 0x1) {
-               if (state->qam_state == QAM_STATE_UNTUNED ||
-                   state->qam_state == QAM_STATE_TUNING_STARTED) {
-                       dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
-                               __func__);
-                       reg1 = s5h1409_readreg(state, 0xb2);
-                       reg2 = s5h1409_readreg(state, 0xad);
-
-                       s5h1409_writereg(state, 0x96, 0x0020);
-                       s5h1409_writereg(state, 0xad,
-                               (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
-                       state->qam_state = QAM_STATE_INTERLEAVE_SET;
-               }
-       } else {
-               if (state->qam_state == QAM_STATE_UNTUNED) {
-                       dprintk("%s() setting QAM state to TUNING_STARTED\n",
-                               __func__);
-                       s5h1409_writereg(state, 0x96, 0x08);
-                       s5h1409_writereg(state, 0xab,
-                               s5h1409_readreg(state, 0xab) | 0x1001);
-                       state->qam_state = QAM_STATE_TUNING_STARTED;
-               }
-       }
-}
-
-static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg, reg1, reg2;
-
-       reg = s5h1409_readreg(state, 0xf1);
-
-       /* Master lock */
-       if ((reg >> 15) & 0x1) {
-               if (state->qam_state != 2) {
-                       state->qam_state = 2;
-                       reg1 = s5h1409_readreg(state, 0xb2);
-                       reg2 = s5h1409_readreg(state, 0xad);
-
-                       s5h1409_writereg(state, 0x96, 0x20);
-                       s5h1409_writereg(state, 0xad,
-                               (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
-                       s5h1409_writereg(state, 0xab,
-                               s5h1409_readreg(state, 0xab) & 0xeffe);
-               }
-       } else {
-               if (state->qam_state != 1) {
-                       state->qam_state = 1;
-                       s5h1409_writereg(state, 0x96, 0x08);
-                       s5h1409_writereg(state, 0xab,
-                               s5h1409_readreg(state, 0xab) | 0x1001);
-               }
-       }
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int s5h1409_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       dprintk("%s(frequency=%d)\n", __func__, p->frequency);
-
-       s5h1409_softreset(fe);
-
-       state->current_frequency = p->frequency;
-
-       s5h1409_enable_modulation(fe, p->modulation);
-
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* Issue a reset to the demod so it knows to resync against the
-          newly tuned frequency */
-       s5h1409_softreset(fe);
-
-       /* Optimize the demod for QAM */
-       if (state->current_modulation != VSB_8) {
-               /* This almost certainly applies to all boards, but for now
-                  only do it for the HVR-1600.  Once the other boards are
-                  tested, the "legacy" versions can just go away */
-               if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
-                       s5h1409_set_qam_interleave_mode(fe);
-                       s5h1409_set_qam_amhum_mode(fe);
-               } else {
-                       s5h1409_set_qam_amhum_mode_legacy(fe);
-                       s5h1409_set_qam_interleave_mode_legacy(fe);
-               }
-       }
-
-       return 0;
-}
-
-static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 val;
-
-       dprintk("%s(%d)\n", __func__, mode);
-
-       val = s5h1409_readreg(state, 0xac) & 0xcfff;
-       switch (mode) {
-       case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
-               val |= 0x0000;
-               break;
-       case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
-               dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
-               val |= 0x1000;
-               break;
-       case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
-               val |= 0x2000;
-               break;
-       case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
-               val |= 0x3000;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Configure MPEG Signal Timing charactistics */
-       return s5h1409_writereg(state, 0xac, val);
-}
-
-/* Reset the demod hardware and reset all of the configuration registers
-   to a default state. */
-static int s5h1409_init(struct dvb_frontend *fe)
-{
-       int i;
-
-       struct s5h1409_state *state = fe->demodulator_priv;
-       dprintk("%s()\n", __func__);
-
-       s5h1409_sleep(fe, 0);
-       s5h1409_register_reset(fe);
-
-       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
-               s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
-
-       /* The datasheet says that after initialisation, VSB is default */
-       state->current_modulation = VSB_8;
-
-       /* Optimize for the HVR-1600 if appropriate.  Note that some of these
-          may get folded into the generic case after testing with other
-          devices */
-       if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
-               /* VSB AGC REF */
-               s5h1409_writereg(state, 0x09, 0x0050);
-
-               /* Unknown but Windows driver does it... */
-               s5h1409_writereg(state, 0x21, 0x0001);
-               s5h1409_writereg(state, 0x50, 0x030e);
-
-               /* QAM AGC REF */
-               s5h1409_writereg(state, 0x82, 0x0800);
-       }
-
-       if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
-               s5h1409_writereg(state, 0xab,
-                       s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
-       else
-               s5h1409_writereg(state, 0xab,
-                       s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */
-
-       s5h1409_set_spectralinversion(fe, state->config->inversion);
-       s5h1409_set_if_freq(fe, state->if_freq);
-       s5h1409_set_gpio(fe, state->config->gpio);
-       s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing);
-       s5h1409_softreset(fe);
-
-       /* Note: Leaving the I2C gate closed. */
-       s5h1409_i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg;
-       u32 tuner_status = 0;
-
-       *status = 0;
-
-       /* Optimize the demod for QAM */
-       if (state->current_modulation != VSB_8) {
-               /* This almost certainly applies to all boards, but for now
-                  only do it for the HVR-1600.  Once the other boards are
-                  tested, the "legacy" versions can just go away */
-               if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
-                       s5h1409_set_qam_interleave_mode(fe);
-                       s5h1409_set_qam_amhum_mode(fe);
-               }
-       }
-
-       /* Get the demodulator status */
-       reg = s5h1409_readreg(state, 0xf1);
-       if (reg & 0x1000)
-               *status |= FE_HAS_VITERBI;
-       if (reg & 0x8000)
-               *status |= FE_HAS_LOCK | FE_HAS_SYNC;
-
-       switch (state->config->status_mode) {
-       case S5H1409_DEMODLOCKING:
-               if (*status & FE_HAS_VITERBI)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       case S5H1409_TUNERLOCKING:
-               /* Get the tuner status */
-               if (fe->ops.tuner_ops.get_status) {
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 1);
-
-                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
-
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               if (tuner_status)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       }
-
-       dprintk("%s() status 0x%08x\n", __func__, *status);
-
-       return 0;
-}
-
-static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
-               if (v < qam256_snr_tab[i].val) {
-                       *snr = qam256_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       return ret;
-}
-
-static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
-               if (v < qam64_snr_tab[i].val) {
-                       *snr = qam64_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       return ret;
-}
-
-static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
-               if (v > vsb_snr_tab[i].val) {
-                       *snr = vsb_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       dprintk("%s() snr=%d\n", __func__, *snr);
-       return ret;
-}
-
-static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       u16 reg;
-       dprintk("%s()\n", __func__);
-
-       switch (state->current_modulation) {
-       case QAM_64:
-               reg = s5h1409_readreg(state, 0xf0) & 0xff;
-               return s5h1409_qam64_lookup_snr(fe, snr, reg);
-       case QAM_256:
-               reg = s5h1409_readreg(state, 0xf0) & 0xff;
-               return s5h1409_qam256_lookup_snr(fe, snr, reg);
-       case VSB_8:
-               reg = s5h1409_readreg(state, 0xf1) & 0x3ff;
-               return s5h1409_vsb_lookup_snr(fe, snr, reg);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
-                                       u16 *signal_strength)
-{
-       /* borrowed from lgdt330x.c
-        *
-        * Calculate strength from SNR up to 35dB
-        * Even though the SNR can go higher than 35dB,
-        * there is some comfort factor in having a range of
-        * strong signals that can show at 100%
-        */
-       u16 snr;
-       u32 tmp;
-       int ret = s5h1409_read_snr(fe, &snr);
-
-       *signal_strength = 0;
-
-       if (0 == ret) {
-               /* The following calculation method was chosen
-                * purely for the sake of code re-use from the
-                * other demod drivers that use this method */
-
-               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
-               tmp = (snr * ((1 << 24) / 10));
-
-               /* Convert from 8.24 fixed-point to
-                * scale the range 0 - 35*2^24 into 0 - 65535*/
-               if (tmp >= 8960 * 0x10000)
-                       *signal_strength = 0xffff;
-               else
-                       *signal_strength = tmp / 8960;
-       }
-
-       return ret;
-}
-
-static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       *ucblocks = s5h1409_readreg(state, 0xb5);
-
-       return 0;
-}
-
-static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       return s5h1409_read_ucblocks(fe, ber);
-}
-
-static int s5h1409_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1409_state *state = fe->demodulator_priv;
-
-       p->frequency = state->current_frequency;
-       p->modulation = state->current_modulation;
-
-       return 0;
-}
-
-static int s5h1409_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void s5h1409_release(struct dvb_frontend *fe)
-{
-       struct s5h1409_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops s5h1409_ops;
-
-struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct s5h1409_state *state = NULL;
-       u16 reg;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->current_modulation = 0;
-       state->if_freq = S5H1409_VSB_IF_FREQ;
-
-       /* check if the demod exists */
-       reg = s5h1409_readreg(state, 0x04);
-       if ((reg != 0x0066) && (reg != 0x007f))
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &s5h1409_ops,
-              sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       if (s5h1409_init(&state->frontend) != 0) {
-               printk(KERN_ERR "%s: Failed to initialize correctly\n",
-                       __func__);
-               goto error;
-       }
-
-       /* Note: Leaving the I2C gate open here. */
-       s5h1409_i2c_gate_ctrl(&state->frontend, 1);
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(s5h1409_attach);
-
-static struct dvb_frontend_ops s5h1409_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name                   = "Samsung S5H1409 QAM/8VSB Frontend",
-               .frequency_min          = 54000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-
-       .init                 = s5h1409_init,
-       .i2c_gate_ctrl        = s5h1409_i2c_gate_ctrl,
-       .set_frontend         = s5h1409_set_frontend,
-       .get_frontend         = s5h1409_get_frontend,
-       .get_tune_settings    = s5h1409_get_tune_settings,
-       .read_status          = s5h1409_read_status,
-       .read_ber             = s5h1409_read_ber,
-       .read_signal_strength = s5h1409_read_signal_strength,
-       .read_snr             = s5h1409_read_snr,
-       .read_ucblocks        = s5h1409_read_ucblocks,
-       .release              = s5h1409_release,
-};
-
-MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
deleted file mode 100644 (file)
index 91f2ebd..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-    Samsung S5H1409 VSB/QAM demodulator driver
-
-    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef __S5H1409_H__
-#define __S5H1409_H__
-
-#include <linux/dvb/frontend.h>
-
-struct s5h1409_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* serial/parallel output */
-#define S5H1409_PARALLEL_OUTPUT 0
-#define S5H1409_SERIAL_OUTPUT   1
-       u8 output_mode;
-
-       /* GPIO Setting */
-#define S5H1409_GPIO_OFF 0
-#define S5H1409_GPIO_ON  1
-       u8 gpio;
-
-       /* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */
-       u16 qam_if;
-
-       /* Spectral Inversion */
-#define S5H1409_INVERSION_OFF 0
-#define S5H1409_INVERSION_ON  1
-       u8 inversion;
-
-       /* Return lock status based on tuner lock, or demod lock */
-#define S5H1409_TUNERLOCKING 0
-#define S5H1409_DEMODLOCKING 1
-       u8 status_mode;
-
-       /* MPEG signal timing */
-#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
-#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
-#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
-#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
-       u16 mpeg_timing;
-
-       /* HVR-1600 optimizations (to better work with MXL5005s)
-          Note: some of these are likely to be folded into the generic driver
-          after being regression tested with other boards */
-#define S5H1409_HVR1600_NOOPTIMIZE 0
-#define S5H1409_HVR1600_OPTIMIZE   1
-       u8 hvr1600_opt;
-};
-
-#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
-       && defined(MODULE))
-extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *s5h1409_attach(
-       const struct s5h1409_config *config,
-       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_S5H1409 */
-
-#endif /* __S5H1409_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
deleted file mode 100644 (file)
index 6cc4b7a..0000000
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
-    Samsung S5H1411 VSB/QAM demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "s5h1411.h"
-
-struct s5h1411_state {
-
-       struct i2c_adapter *i2c;
-
-       /* configuration settings */
-       const struct s5h1411_config *config;
-
-       struct dvb_frontend frontend;
-
-       fe_modulation_t current_modulation;
-       unsigned int first_tune:1;
-
-       u32 current_frequency;
-       int if_freq;
-
-       u8 inversion;
-};
-
-static int debug;
-
-#define dprintk(arg...) do {   \
-       if (debug)              \
-               printk(arg);    \
-       } while (0)
-
-/* Register values to initialise the demod, defaults to VSB */
-static struct init_tab {
-       u8      addr;
-       u8      reg;
-       u16     data;
-} init_tab[] = {
-       { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, },
-       { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
-       { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
-       { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
-       { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, },
-       { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
-       { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
-       { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
-       { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, },
-       { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, },
-       { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, },
-       { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, },
-       { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, },
-       { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, },
-       { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, },
-       { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, },
-       { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, },
-       { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, },
-       { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, },
-       { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, },
-       { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, },
-       { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, },
-       { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, },
-       { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, },
-       { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, },
-       { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, },
-       { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, },
-       { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, },
-       { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, },
-       { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, },
-       { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, },
-       { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, },
-       { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, },
-       { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, },
-       { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, },
-       { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, },
-       { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, },
-       { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, },
-       { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, },
-       { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
-       { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
-       { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
-       { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
-       { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
-       { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
-       { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, },
-       { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, },
-       { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, },
-       { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, },
-       { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, },
-       { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, },
-       { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, },
-       { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, },
-       { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, },
-       { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, },
-       { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, },
-       { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, },
-       { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, },
-       { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, },
-       { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, },
-       { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, },
-       { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, },
-       { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, },
-       { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, },
-       { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, },
-       { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, },
-       { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, },
-       { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, },
-       { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, },
-       { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, },
-       { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, },
-       { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, },
-       { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, },
-       { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, },
-       { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, },
-       { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, },
-       { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, },
-       { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, },
-       { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, },
-       { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, },
-};
-
-/* VSB SNR lookup table */
-static struct vsb_snr_tab {
-       u16     val;
-       u16     data;
-} vsb_snr_tab[] = {
-       {  0x39f, 300, },
-       {  0x39b, 295, },
-       {  0x397, 290, },
-       {  0x394, 285, },
-       {  0x38f, 280, },
-       {  0x38b, 275, },
-       {  0x387, 270, },
-       {  0x382, 265, },
-       {  0x37d, 260, },
-       {  0x377, 255, },
-       {  0x370, 250, },
-       {  0x36a, 245, },
-       {  0x364, 240, },
-       {  0x35b, 235, },
-       {  0x353, 230, },
-       {  0x349, 225, },
-       {  0x340, 320, },
-       {  0x337, 215, },
-       {  0x327, 210, },
-       {  0x31b, 205, },
-       {  0x310, 200, },
-       {  0x302, 195, },
-       {  0x2f3, 190, },
-       {  0x2e4, 185, },
-       {  0x2d7, 180, },
-       {  0x2cd, 175, },
-       {  0x2bb, 170, },
-       {  0x2a9, 165, },
-       {  0x29e, 160, },
-       {  0x284, 155, },
-       {  0x27a, 150, },
-       {  0x260, 145, },
-       {  0x23a, 140, },
-       {  0x224, 135, },
-       {  0x213, 130, },
-       {  0x204, 125, },
-       {  0x1fe, 120, },
-       {      0,   0, },
-};
-
-/* QAM64 SNR lookup table */
-static struct qam64_snr_tab {
-       u16     val;
-       u16     data;
-} qam64_snr_tab[] = {
-       {  0x0001,   0, },
-       {  0x0af0, 300, },
-       {  0x0d80, 290, },
-       {  0x10a0, 280, },
-       {  0x14b5, 270, },
-       {  0x1590, 268, },
-       {  0x1680, 266, },
-       {  0x17b0, 264, },
-       {  0x18c0, 262, },
-       {  0x19b0, 260, },
-       {  0x1ad0, 258, },
-       {  0x1d00, 256, },
-       {  0x1da0, 254, },
-       {  0x1ef0, 252, },
-       {  0x2050, 250, },
-       {  0x20f0, 249, },
-       {  0x21d0, 248, },
-       {  0x22b0, 247, },
-       {  0x23a0, 246, },
-       {  0x2470, 245, },
-       {  0x24f0, 244, },
-       {  0x25a0, 243, },
-       {  0x26c0, 242, },
-       {  0x27b0, 241, },
-       {  0x28d0, 240, },
-       {  0x29b0, 239, },
-       {  0x2ad0, 238, },
-       {  0x2ba0, 237, },
-       {  0x2c80, 236, },
-       {  0x2d20, 235, },
-       {  0x2e00, 234, },
-       {  0x2f10, 233, },
-       {  0x3050, 232, },
-       {  0x3190, 231, },
-       {  0x3300, 230, },
-       {  0x3340, 229, },
-       {  0x3200, 228, },
-       {  0x3550, 227, },
-       {  0x3610, 226, },
-       {  0x3600, 225, },
-       {  0x3700, 224, },
-       {  0x3800, 223, },
-       {  0x3920, 222, },
-       {  0x3a20, 221, },
-       {  0x3b30, 220, },
-       {  0x3d00, 219, },
-       {  0x3e00, 218, },
-       {  0x4000, 217, },
-       {  0x4100, 216, },
-       {  0x4300, 215, },
-       {  0x4400, 214, },
-       {  0x4600, 213, },
-       {  0x4700, 212, },
-       {  0x4800, 211, },
-       {  0x4a00, 210, },
-       {  0x4b00, 209, },
-       {  0x4d00, 208, },
-       {  0x4f00, 207, },
-       {  0x5050, 206, },
-       {  0x5200, 205, },
-       {  0x53c0, 204, },
-       {  0x5450, 203, },
-       {  0x5650, 202, },
-       {  0x5820, 201, },
-       {  0x6000, 200, },
-       {  0xffff,   0, },
-};
-
-/* QAM256 SNR lookup table */
-static struct qam256_snr_tab {
-       u16     val;
-       u16     data;
-} qam256_snr_tab[] = {
-       {  0x0001,   0, },
-       {  0x0970, 400, },
-       {  0x0a90, 390, },
-       {  0x0b90, 380, },
-       {  0x0d90, 370, },
-       {  0x0ff0, 360, },
-       {  0x1240, 350, },
-       {  0x1345, 348, },
-       {  0x13c0, 346, },
-       {  0x14c0, 344, },
-       {  0x1500, 342, },
-       {  0x1610, 340, },
-       {  0x1700, 338, },
-       {  0x1800, 336, },
-       {  0x18b0, 334, },
-       {  0x1900, 332, },
-       {  0x1ab0, 330, },
-       {  0x1bc0, 328, },
-       {  0x1cb0, 326, },
-       {  0x1db0, 324, },
-       {  0x1eb0, 322, },
-       {  0x2030, 320, },
-       {  0x2200, 318, },
-       {  0x2280, 316, },
-       {  0x2410, 314, },
-       {  0x25b0, 312, },
-       {  0x27a0, 310, },
-       {  0x2840, 308, },
-       {  0x29d0, 306, },
-       {  0x2b10, 304, },
-       {  0x2d30, 302, },
-       {  0x2f20, 300, },
-       {  0x30c0, 298, },
-       {  0x3260, 297, },
-       {  0x32c0, 296, },
-       {  0x3300, 295, },
-       {  0x33b0, 294, },
-       {  0x34b0, 293, },
-       {  0x35a0, 292, },
-       {  0x3650, 291, },
-       {  0x3800, 290, },
-       {  0x3900, 289, },
-       {  0x3a50, 288, },
-       {  0x3b30, 287, },
-       {  0x3cb0, 286, },
-       {  0x3e20, 285, },
-       {  0x3fa0, 284, },
-       {  0x40a0, 283, },
-       {  0x41c0, 282, },
-       {  0x42f0, 281, },
-       {  0x44a0, 280, },
-       {  0x4600, 279, },
-       {  0x47b0, 278, },
-       {  0x4900, 277, },
-       {  0x4a00, 276, },
-       {  0x4ba0, 275, },
-       {  0x4d00, 274, },
-       {  0x4f00, 273, },
-       {  0x5000, 272, },
-       {  0x51f0, 272, },
-       {  0x53a0, 270, },
-       {  0x5520, 269, },
-       {  0x5700, 268, },
-       {  0x5800, 267, },
-       {  0x5a00, 266, },
-       {  0x5c00, 265, },
-       {  0x5d00, 264, },
-       {  0x5f00, 263, },
-       {  0x6000, 262, },
-       {  0x6200, 261, },
-       {  0x6400, 260, },
-       {  0xffff,   0, },
-};
-
-/* 8 bit registers, 16 bit values */
-static int s5h1411_writereg(struct s5h1411_state *state,
-       u8 addr, u8 reg, u16 data)
-{
-       int ret;
-       u8 buf[] = { reg, data >> 8,  data & 0xff };
-
-       struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
-                      "ret == %i)\n", __func__, addr, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0, 0 };
-
-       struct i2c_msg msg[] = {
-               { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
-               { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
-                       __func__, ret);
-       return (b1[0] << 8) | b1[1];
-}
-
-static int s5h1411_softreset(struct dvb_frontend *fe)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0);
-       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1);
-       return 0;
-}
-
-static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d KHz)\n", __func__, KHz);
-
-       switch (KHz) {
-       case 3250:
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
-               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
-               break;
-       case 3500:
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96);
-               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225);
-               break;
-       case 4000:
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e);
-               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd);
-               break;
-       default:
-               dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
-                       __func__, KHz);
-               /* no break, need to continue */
-       case 5380:
-       case 44000:
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655);
-               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4);
-               break;
-       }
-
-       state->if_freq = KHz;
-
-       return 0;
-}
-
-static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 val;
-
-       dprintk("%s(%d)\n", __func__, mode);
-
-       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff;
-       switch (mode) {
-       case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
-               val |= 0x0000;
-               break;
-       case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
-               dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
-               val |= 0x1000;
-               break;
-       case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
-               val |= 0x2000;
-               break;
-       case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
-               val |= 0x3000;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Configure MPEG Signal Timing charactistics */
-       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val);
-}
-
-static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 val;
-
-       dprintk("%s(%d)\n", __func__, inversion);
-       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000;
-
-       if (inversion == 1)
-               val |= 0x1000; /* Inverted */
-
-       state->inversion = inversion;
-       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
-}
-
-static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 val;
-
-       dprintk("%s(%d)\n", __func__, serial);
-       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
-
-       if (serial == 1)
-               val |= 0x100;
-
-       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
-}
-
-static int s5h1411_enable_modulation(struct dvb_frontend *fe,
-                                    fe_modulation_t m)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s(0x%08x)\n", __func__, m);
-
-       if ((state->first_tune == 0) && (m == state->current_modulation)) {
-               dprintk("%s() Already at desired modulation.  Skipping...\n",
-                       __func__);
-               return 0;
-       }
-
-       switch (m) {
-       case VSB_8:
-               dprintk("%s() VSB_8\n", __func__);
-               s5h1411_set_if_freq(fe, state->config->vsb_if);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1);
-               break;
-       case QAM_64:
-       case QAM_256:
-       case QAM_AUTO:
-               dprintk("%s() QAM_AUTO (64/256)\n", __func__);
-               s5h1411_set_if_freq(fe, state->config->qam_if);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001);
-               s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101);
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0);
-               break;
-       default:
-               dprintk("%s() Invalid modulation\n", __func__);
-               return -EINVAL;
-       }
-
-       state->current_modulation = m;
-       state->first_tune = 0;
-       s5h1411_softreset(fe);
-
-       return 0;
-}
-
-static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (enable)
-               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
-       else
-               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0);
-}
-
-static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 val;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02;
-
-       if (enable)
-               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0,
-                               val | 0x02);
-       else
-               return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
-}
-
-static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s(%d)\n", __func__, enable);
-
-       if (enable)
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1);
-       else {
-               s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0);
-               s5h1411_softreset(fe);
-       }
-
-       return 0;
-}
-
-static int s5h1411_sleep(struct dvb_frontend *fe)
-{
-       return s5h1411_set_powerstate(fe, 1);
-}
-
-static int s5h1411_register_reset(struct dvb_frontend *fe)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s()\n", __func__);
-
-       return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0);
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int s5h1411_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       dprintk("%s(frequency=%d)\n", __func__, p->frequency);
-
-       s5h1411_softreset(fe);
-
-       state->current_frequency = p->frequency;
-
-       s5h1411_enable_modulation(fe, p->modulation);
-
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               fe->ops.tuner_ops.set_params(fe);
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* Issue a reset to the demod so it knows to resync against the
-          newly tuned frequency */
-       s5h1411_softreset(fe);
-
-       return 0;
-}
-
-/* Reset the demod hardware and reset all of the configuration registers
-   to a default state. */
-static int s5h1411_init(struct dvb_frontend *fe)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       int i;
-
-       dprintk("%s()\n", __func__);
-
-       s5h1411_set_powerstate(fe, 0);
-       s5h1411_register_reset(fe);
-
-       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
-               s5h1411_writereg(state, init_tab[i].addr,
-                       init_tab[i].reg,
-                       init_tab[i].data);
-
-       /* The datasheet says that after initialisation, VSB is default */
-       state->current_modulation = VSB_8;
-
-       /* Although the datasheet says it's in VSB, empirical evidence
-          shows problems getting lock on the first tuning request.  Make
-          sure we call enable_modulation the first time around */
-       state->first_tune = 1;
-
-       if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
-               /* Serial */
-               s5h1411_set_serialmode(fe, 1);
-       else
-               /* Parallel */
-               s5h1411_set_serialmode(fe, 0);
-
-       s5h1411_set_spectralinversion(fe, state->config->inversion);
-       s5h1411_set_if_freq(fe, state->config->vsb_if);
-       s5h1411_set_gpio(fe, state->config->gpio);
-       s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing);
-       s5h1411_softreset(fe);
-
-       /* Note: Leaving the I2C gate closed. */
-       s5h1411_i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 reg;
-       u32 tuner_status = 0;
-
-       *status = 0;
-
-       /* Register F2 bit 15 = Master Lock, removed */
-
-       switch (state->current_modulation) {
-       case QAM_64:
-       case QAM_256:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
-               if (reg & 0x10) /* QAM FEC Lock */
-                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-               if (reg & 0x100) /* QAM EQ Lock */
-                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
-
-               break;
-       case VSB_8:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
-               if (reg & 0x1000) /* FEC Lock */
-                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-               if (reg & 0x2000) /* EQ Lock */
-                       *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
-
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53);
-               if (reg & 0x1) /* AFC Lock */
-                       *status |= FE_HAS_SIGNAL;
-
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (state->config->status_mode) {
-       case S5H1411_DEMODLOCKING:
-               if (*status & FE_HAS_VITERBI)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       case S5H1411_TUNERLOCKING:
-               /* Get the tuner status */
-               if (fe->ops.tuner_ops.get_status) {
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 1);
-
-                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
-
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               if (tuner_status)
-                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-               break;
-       }
-
-       dprintk("%s() status 0x%08x\n", __func__, *status);
-
-       return 0;
-}
-
-static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
-               if (v < qam256_snr_tab[i].val) {
-                       *snr = qam256_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       return ret;
-}
-
-static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
-               if (v < qam64_snr_tab[i].val) {
-                       *snr = qam64_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       return ret;
-}
-
-static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
-               if (v > vsb_snr_tab[i].val) {
-                       *snr = vsb_snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       dprintk("%s() snr=%d\n", __func__, *snr);
-       return ret;
-}
-
-static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       u16 reg;
-       dprintk("%s()\n", __func__);
-
-       switch (state->current_modulation) {
-       case QAM_64:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
-               return s5h1411_qam64_lookup_snr(fe, snr, reg);
-       case QAM_256:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
-               return s5h1411_qam256_lookup_snr(fe, snr, reg);
-       case VSB_8:
-               reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR,
-                       0xf2) & 0x3ff;
-               return s5h1411_vsb_lookup_snr(fe, snr, reg);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
-       u16 *signal_strength)
-{
-       /* borrowed from lgdt330x.c
-        *
-        * Calculate strength from SNR up to 35dB
-        * Even though the SNR can go higher than 35dB,
-        * there is some comfort factor in having a range of
-        * strong signals that can show at 100%
-        */
-       u16 snr;
-       u32 tmp;
-       int ret = s5h1411_read_snr(fe, &snr);
-
-       *signal_strength = 0;
-
-       if (0 == ret) {
-               /* The following calculation method was chosen
-                * purely for the sake of code re-use from the
-                * other demod drivers that use this method */
-
-               /* Convert from SNR in dB * 10 to 8.24 fixed-point */
-               tmp = (snr * ((1 << 24) / 10));
-
-               /* Convert from 8.24 fixed-point to
-                * scale the range 0 - 35*2^24 into 0 - 65535*/
-               if (tmp >= 8960 * 0x10000)
-                       *signal_strength = 0xffff;
-               else
-                       *signal_strength = tmp / 8960;
-       }
-
-       return ret;
-}
-
-static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9);
-
-       return 0;
-}
-
-static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       return s5h1411_read_ucblocks(fe, ber);
-}
-
-static int s5h1411_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1411_state *state = fe->demodulator_priv;
-
-       p->frequency = state->current_frequency;
-       p->modulation = state->current_modulation;
-
-       return 0;
-}
-
-static int s5h1411_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void s5h1411_release(struct dvb_frontend *fe)
-{
-       struct s5h1411_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops s5h1411_ops;
-
-struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct s5h1411_state *state = NULL;
-       u16 reg;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->current_modulation = VSB_8;
-       state->inversion = state->config->inversion;
-
-       /* check if the demod exists */
-       reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05);
-       if (reg != 0x0066)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &s5h1411_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       state->frontend.demodulator_priv = state;
-
-       if (s5h1411_init(&state->frontend) != 0) {
-               printk(KERN_ERR "%s: Failed to initialize correctly\n",
-                       __func__);
-               goto error;
-       }
-
-       /* Note: Leaving the I2C gate open here. */
-       s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
-
-       /* Put the device into low-power mode until first use */
-       s5h1411_set_powerstate(&state->frontend, 1);
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(s5h1411_attach);
-
-static struct dvb_frontend_ops s5h1411_ops = {
-       .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
-       .info = {
-               .name                   = "Samsung S5H1411 QAM/8VSB Frontend",
-               .frequency_min          = 54000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 62500,
-               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-       },
-
-       .init                 = s5h1411_init,
-       .sleep                = s5h1411_sleep,
-       .i2c_gate_ctrl        = s5h1411_i2c_gate_ctrl,
-       .set_frontend         = s5h1411_set_frontend,
-       .get_frontend         = s5h1411_get_frontend,
-       .get_tune_settings    = s5h1411_get_tune_settings,
-       .read_status          = s5h1411_read_status,
-       .read_ber             = s5h1411_read_ber,
-       .read_signal_strength = s5h1411_read_signal_strength,
-       .read_snr             = s5h1411_read_snr,
-       .read_ucblocks        = s5h1411_read_ucblocks,
-       .release              = s5h1411_release,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h
deleted file mode 100644 (file)
index 45ec0f8..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-    Samsung S5H1411 VSB/QAM demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef __S5H1411_H__
-#define __S5H1411_H__
-
-#include <linux/dvb/frontend.h>
-
-#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
-#define S5H1411_I2C_QAM_ADDR (0x34 >> 1)
-
-struct s5h1411_config {
-
-       /* serial/parallel output */
-#define S5H1411_PARALLEL_OUTPUT 0
-#define S5H1411_SERIAL_OUTPUT   1
-       u8 output_mode;
-
-       /* GPIO Setting */
-#define S5H1411_GPIO_OFF 0
-#define S5H1411_GPIO_ON  1
-       u8 gpio;
-
-       /* MPEG signal timing */
-#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
-#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
-#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
-#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
-       u16 mpeg_timing;
-
-       /* IF Freq for QAM and VSB in KHz */
-#define S5H1411_IF_3250  3250
-#define S5H1411_IF_3500  3500
-#define S5H1411_IF_4000  4000
-#define S5H1411_IF_5380  5380
-#define S5H1411_IF_44000 44000
-#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000
-#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000
-       u16 qam_if;
-       u16 vsb_if;
-
-       /* Spectral Inversion */
-#define S5H1411_INVERSION_OFF 0
-#define S5H1411_INVERSION_ON  1
-       u8 inversion;
-
-       /* Return lock status based on tuner lock, or demod lock */
-#define S5H1411_TUNERLOCKING 0
-#define S5H1411_DEMODLOCKING 1
-       u8 status_mode;
-};
-
-#if defined(CONFIG_DVB_S5H1411) || \
-       (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
-extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *s5h1411_attach(
-       const struct s5h1411_config *config,
-       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_S5H1411 */
-
-#endif /* __S5H1411_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
deleted file mode 100644 (file)
index e2fec9e..0000000
+++ /dev/null
@@ -1,960 +0,0 @@
-/*
- * Driver for
- *    Samsung S5H1420 and
- *    PnpNetwork PN1010 QPSK Demodulator
- *
- * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
- * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <asm/div64.h>
-
-#include <linux/i2c.h>
-
-
-#include "dvb_frontend.h"
-#include "s5h1420.h"
-#include "s5h1420_priv.h"
-
-#define TONE_FREQ 22000
-
-struct s5h1420_state {
-       struct i2c_adapter* i2c;
-       const struct s5h1420_config* config;
-
-       struct dvb_frontend frontend;
-       struct i2c_adapter tuner_i2c_adapter;
-
-       u8 CON_1_val;
-
-       u8 postlocked:1;
-       u32 fclk;
-       u32 tunedfreq;
-       fe_code_rate_t fec_inner;
-       u32 symbol_rate;
-
-       /* FIXME: ugly workaround for flexcop's incapable i2c-controller
-        * it does not support repeated-start, workaround: write addr-1
-        * and then read
-        */
-       u8 shadow[256];
-};
-
-static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
-                                    struct dvb_frontend_tune_settings* fesettings);
-
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debugging");
-
-#define dprintk(x...) do { \
-       if (debug) \
-               printk(KERN_DEBUG "S5H1420: " x); \
-} while (0)
-
-static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
-{
-       int ret;
-       u8 b[2];
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 },
-               { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 },
-       };
-
-       b[0] = (reg - 1) & 0xff;
-       b[1] = state->shadow[(reg - 1) & 0xff];
-
-       if (state->config->repeated_start_workaround) {
-               ret = i2c_transfer(state->i2c, msg, 3);
-               if (ret != 3)
-                       return ret;
-       } else {
-               ret = i2c_transfer(state->i2c, &msg[1], 1);
-               if (ret != 1)
-                       return ret;
-               ret = i2c_transfer(state->i2c, &msg[2], 1);
-               if (ret != 1)
-                       return ret;
-       }
-
-       /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */
-
-       return b[0];
-}
-
-static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-       int err;
-
-       /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-       state->shadow[reg] = data;
-
-       return 0;
-}
-
-static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       dprintk("enter %s\n", __func__);
-
-       switch(voltage) {
-       case SEC_VOLTAGE_13:
-               s5h1420_writereg(state, 0x3c,
-                                (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
-               break;
-
-       case SEC_VOLTAGE_18:
-               s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
-               break;
-
-       case SEC_VOLTAGE_OFF:
-               s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
-               break;
-       }
-
-       dprintk("leave %s\n", __func__);
-       return 0;
-}
-
-static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       dprintk("enter %s\n", __func__);
-       switch(tone) {
-       case SEC_TONE_ON:
-               s5h1420_writereg(state, 0x3b,
-                                (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
-               break;
-
-       case SEC_TONE_OFF:
-               s5h1420_writereg(state, 0x3b,
-                                (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
-               break;
-       }
-       dprintk("leave %s\n", __func__);
-
-       return 0;
-}
-
-static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd* cmd)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       u8 val;
-       int i;
-       unsigned long timeout;
-       int result = 0;
-
-       dprintk("enter %s\n", __func__);
-       if (cmd->msg_len > 8)
-               return -EINVAL;
-
-       /* setup for DISEQC */
-       val = s5h1420_readreg(state, 0x3b);
-       s5h1420_writereg(state, 0x3b, 0x02);
-       msleep(15);
-
-       /* write the DISEQC command bytes */
-       for(i=0; i< cmd->msg_len; i++) {
-               s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
-       }
-
-       /* kick off transmission */
-       s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
-                                     ((cmd->msg_len-1) << 4) | 0x08);
-
-       /* wait for transmission to complete */
-       timeout = jiffies + ((100*HZ) / 1000);
-       while(time_before(jiffies, timeout)) {
-               if (!(s5h1420_readreg(state, 0x3b) & 0x08))
-                       break;
-
-               msleep(5);
-       }
-       if (time_after(jiffies, timeout))
-               result = -ETIMEDOUT;
-
-       /* restore original settings */
-       s5h1420_writereg(state, 0x3b, val);
-       msleep(15);
-       dprintk("leave %s\n", __func__);
-       return result;
-}
-
-static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
-                                    struct dvb_diseqc_slave_reply* reply)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       u8 val;
-       int i;
-       int length;
-       unsigned long timeout;
-       int result = 0;
-
-       /* setup for DISEQC receive */
-       val = s5h1420_readreg(state, 0x3b);
-       s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
-       msleep(15);
-
-       /* wait for reception to complete */
-       timeout = jiffies + ((reply->timeout*HZ) / 1000);
-       while(time_before(jiffies, timeout)) {
-               if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
-                       break;
-
-               msleep(5);
-       }
-       if (time_after(jiffies, timeout)) {
-               result = -ETIMEDOUT;
-               goto exit;
-       }
-
-       /* check error flag - FIXME: not sure what this does - docs do not describe
-        * beyond "error flag for diseqc receive data :( */
-       if (s5h1420_readreg(state, 0x49)) {
-               result = -EIO;
-               goto exit;
-       }
-
-       /* check length */
-       length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
-       if (length > sizeof(reply->msg)) {
-               result = -EOVERFLOW;
-               goto exit;
-       }
-       reply->msg_len = length;
-
-       /* extract data */
-       for(i=0; i< length; i++) {
-               reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
-       }
-
-exit:
-       /* restore original settings */
-       s5h1420_writereg(state, 0x3b, val);
-       msleep(15);
-       return result;
-}
-
-static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       u8 val;
-       int result = 0;
-       unsigned long timeout;
-
-       /* setup for tone burst */
-       val = s5h1420_readreg(state, 0x3b);
-       s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
-
-       /* set value for B position if requested */
-       if (minicmd == SEC_MINI_B) {
-               s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
-       }
-       msleep(15);
-
-       /* start transmission */
-       s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
-
-       /* wait for transmission to complete */
-       timeout = jiffies + ((100*HZ) / 1000);
-       while(time_before(jiffies, timeout)) {
-               if (!(s5h1420_readreg(state, 0x3b) & 0x08))
-                       break;
-
-               msleep(5);
-       }
-       if (time_after(jiffies, timeout))
-               result = -ETIMEDOUT;
-
-       /* restore original settings */
-       s5h1420_writereg(state, 0x3b, val);
-       msleep(15);
-       return result;
-}
-
-static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
-{
-       u8 val;
-       fe_status_t status = 0;
-
-       val = s5h1420_readreg(state, 0x14);
-       if (val & 0x02)
-               status |=  FE_HAS_SIGNAL;
-       if (val & 0x01)
-               status |=  FE_HAS_CARRIER;
-       val = s5h1420_readreg(state, 0x36);
-       if (val & 0x01)
-               status |=  FE_HAS_VITERBI;
-       if (val & 0x20)
-               status |=  FE_HAS_SYNC;
-       if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
-               status |=  FE_HAS_LOCK;
-
-       return status;
-}
-
-static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("enter %s\n", __func__);
-
-       if (status == NULL)
-               return -EINVAL;
-
-       /* determine lock state */
-       *status = s5h1420_get_status_bits(state);
-
-       /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
-       the inversion, wait a bit and check again */
-       if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) {
-               val = s5h1420_readreg(state, Vit10);
-               if ((val & 0x07) == 0x03) {
-                       if (val & 0x08)
-                               s5h1420_writereg(state, Vit09, 0x13);
-                       else
-                               s5h1420_writereg(state, Vit09, 0x1b);
-
-                       /* wait a bit then update lock status */
-                       mdelay(200);
-                       *status = s5h1420_get_status_bits(state);
-               }
-       }
-
-       /* perform post lock setup */
-       if ((*status & FE_HAS_LOCK) && !state->postlocked) {
-
-               /* calculate the data rate */
-               u32 tmp = s5h1420_getsymbolrate(state);
-               switch (s5h1420_readreg(state, Vit10) & 0x07) {
-               case 0: tmp = (tmp * 2 * 1) / 2; break;
-               case 1: tmp = (tmp * 2 * 2) / 3; break;
-               case 2: tmp = (tmp * 2 * 3) / 4; break;
-               case 3: tmp = (tmp * 2 * 5) / 6; break;
-               case 4: tmp = (tmp * 2 * 6) / 7; break;
-               case 5: tmp = (tmp * 2 * 7) / 8; break;
-               }
-
-               if (tmp == 0) {
-                       printk(KERN_ERR "s5h1420: avoided division by 0\n");
-                       tmp = 1;
-               }
-               tmp = state->fclk / tmp;
-
-
-               /* set the MPEG_CLK_INTL for the calculated data rate */
-               if (tmp < 2)
-                       val = 0x00;
-               else if (tmp < 5)
-                       val = 0x01;
-               else if (tmp < 9)
-                       val = 0x02;
-               else if (tmp < 13)
-                       val = 0x03;
-               else if (tmp < 17)
-                       val = 0x04;
-               else if (tmp < 25)
-                       val = 0x05;
-               else if (tmp < 33)
-                       val = 0x06;
-               else
-                       val = 0x07;
-               dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val);
-
-               s5h1420_writereg(state, FEC01, 0x18);
-               s5h1420_writereg(state, FEC01, 0x10);
-               s5h1420_writereg(state, FEC01, val);
-
-               /* Enable "MPEG_Out" */
-               val = s5h1420_readreg(state, Mpeg02);
-               s5h1420_writereg(state, Mpeg02, val | (1 << 6));
-
-               /* kicker disable */
-               val = s5h1420_readreg(state, QPSK01) & 0x7f;
-               s5h1420_writereg(state, QPSK01, val);
-
-               /* DC freeze TODO it was never activated by default or it can stay activated */
-
-               if (s5h1420_getsymbolrate(state) >= 20000000) {
-                       s5h1420_writereg(state, Loop04, 0x8a);
-                       s5h1420_writereg(state, Loop05, 0x6a);
-               } else {
-                       s5h1420_writereg(state, Loop04, 0x58);
-                       s5h1420_writereg(state, Loop05, 0x27);
-               }
-
-               /* post-lock processing has been done! */
-               state->postlocked = 1;
-       }
-
-       dprintk("leave %s\n", __func__);
-
-       return 0;
-}
-
-static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       s5h1420_writereg(state, 0x46, 0x1d);
-       mdelay(25);
-
-       *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
-
-       return 0;
-}
-
-static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       u8 val = s5h1420_readreg(state, 0x15);
-
-       *strength =  (u16) ((val << 8) | val);
-
-       return 0;
-}
-
-static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       s5h1420_writereg(state, 0x46, 0x1f);
-       mdelay(25);
-
-       *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
-
-       return 0;
-}
-
-static void s5h1420_reset(struct s5h1420_state* state)
-{
-       dprintk("%s\n", __func__);
-       s5h1420_writereg (state, 0x01, 0x08);
-       s5h1420_writereg (state, 0x01, 0x00);
-       udelay(10);
-}
-
-static void s5h1420_setsymbolrate(struct s5h1420_state* state,
-                                 struct dtv_frontend_properties *p)
-{
-       u8 v;
-       u64 val;
-
-       dprintk("enter %s\n", __func__);
-
-       val = ((u64) p->symbol_rate / 1000ULL) * (1ULL<<24);
-       if (p->symbol_rate < 29000000)
-               val *= 2;
-       do_div(val, (state->fclk / 1000));
-
-       dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
-
-       v = s5h1420_readreg(state, Loop01);
-       s5h1420_writereg(state, Loop01, v & 0x7f);
-       s5h1420_writereg(state, Tnco01, val >> 16);
-       s5h1420_writereg(state, Tnco02, val >> 8);
-       s5h1420_writereg(state, Tnco03, val & 0xff);
-       s5h1420_writereg(state, Loop01,  v | 0x80);
-       dprintk("leave %s\n", __func__);
-}
-
-static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
-{
-       return state->symbol_rate;
-}
-
-static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
-{
-       int val;
-       u8 v;
-
-       dprintk("enter %s\n", __func__);
-
-       /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
-        * divide fclk by 1000000 to get the correct value. */
-       val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
-
-       dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val);
-
-       v = s5h1420_readreg(state, Loop01);
-       s5h1420_writereg(state, Loop01, v & 0xbf);
-       s5h1420_writereg(state, Pnco01, val >> 16);
-       s5h1420_writereg(state, Pnco02, val >> 8);
-       s5h1420_writereg(state, Pnco03, val & 0xff);
-       s5h1420_writereg(state, Loop01, v | 0x40);
-       dprintk("leave %s\n", __func__);
-}
-
-static int s5h1420_getfreqoffset(struct s5h1420_state* state)
-{
-       int val;
-
-       s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
-       val  = s5h1420_readreg(state, 0x0e) << 16;
-       val |= s5h1420_readreg(state, 0x0f) << 8;
-       val |= s5h1420_readreg(state, 0x10);
-       s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
-
-       if (val & 0x800000)
-               val |= 0xff000000;
-
-       /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
-        * divide fclk by 1000000 to get the correct value. */
-       val = (((-val) * (state->fclk/1000000)) / (1<<24));
-
-       return val;
-}
-
-static void s5h1420_setfec_inversion(struct s5h1420_state* state,
-                                    struct dtv_frontend_properties *p)
-{
-       u8 inversion = 0;
-       u8 vit08, vit09;
-
-       dprintk("enter %s\n", __func__);
-
-       if (p->inversion == INVERSION_OFF)
-               inversion = state->config->invert ? 0x08 : 0;
-       else if (p->inversion == INVERSION_ON)
-               inversion = state->config->invert ? 0 : 0x08;
-
-       if ((p->fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
-               vit08 = 0x3f;
-               vit09 = 0;
-       } else {
-               switch (p->fec_inner) {
-               case FEC_1_2:
-                       vit08 = 0x01; vit09 = 0x10;
-                       break;
-
-               case FEC_2_3:
-                       vit08 = 0x02; vit09 = 0x11;
-                       break;
-
-               case FEC_3_4:
-                       vit08 = 0x04; vit09 = 0x12;
-                       break;
-
-               case FEC_5_6:
-                       vit08 = 0x08; vit09 = 0x13;
-                       break;
-
-               case FEC_6_7:
-                       vit08 = 0x10; vit09 = 0x14;
-                       break;
-
-               case FEC_7_8:
-                       vit08 = 0x20; vit09 = 0x15;
-                       break;
-
-               default:
-                       return;
-               }
-       }
-       vit09 |= inversion;
-       dprintk("fec: %02x %02x\n", vit08, vit09);
-       s5h1420_writereg(state, Vit08, vit08);
-       s5h1420_writereg(state, Vit09, vit09);
-       dprintk("leave %s\n", __func__);
-}
-
-static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
-{
-       switch(s5h1420_readreg(state, 0x32) & 0x07) {
-       case 0:
-               return FEC_1_2;
-
-       case 1:
-               return FEC_2_3;
-
-       case 2:
-               return FEC_3_4;
-
-       case 3:
-               return FEC_5_6;
-
-       case 4:
-               return FEC_6_7;
-
-       case 5:
-               return FEC_7_8;
-       }
-
-       return FEC_NONE;
-}
-
-static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
-{
-       if (s5h1420_readreg(state, 0x32) & 0x08)
-               return INVERSION_ON;
-
-       return INVERSION_OFF;
-}
-
-static int s5h1420_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1420_state* state = fe->demodulator_priv;
-       int frequency_delta;
-       struct dvb_frontend_tune_settings fesettings;
-
-       dprintk("enter %s\n", __func__);
-
-       /* check if we should do a fast-tune */
-       s5h1420_get_tune_settings(fe, &fesettings);
-       frequency_delta = p->frequency - state->tunedfreq;
-       if ((frequency_delta > -fesettings.max_drift) &&
-                       (frequency_delta < fesettings.max_drift) &&
-                       (frequency_delta != 0) &&
-                       (state->fec_inner == p->fec_inner) &&
-                       (state->symbol_rate == p->symbol_rate)) {
-
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-               if (fe->ops.tuner_ops.get_frequency) {
-                       u32 tmp;
-                       fe->ops.tuner_ops.get_frequency(fe, &tmp);
-                       if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-                       s5h1420_setfreqoffset(state, p->frequency - tmp);
-               } else {
-                       s5h1420_setfreqoffset(state, 0);
-               }
-               dprintk("simple tune\n");
-               return 0;
-       }
-       dprintk("tuning demod\n");
-
-       /* first of all, software reset */
-       s5h1420_reset(state);
-
-       /* set s5h1420 fclk PLL according to desired symbol rate */
-       if (p->symbol_rate > 33000000)
-               state->fclk = 80000000;
-       else if (p->symbol_rate > 28500000)
-               state->fclk = 59000000;
-       else if (p->symbol_rate > 25000000)
-               state->fclk = 86000000;
-       else if (p->symbol_rate > 1900000)
-               state->fclk = 88000000;
-       else
-               state->fclk = 44000000;
-
-       dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
-       s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8);
-       s5h1420_writereg(state, PLL02, 0x40);
-       s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
-
-       /* TODO DC offset removal, config parameter ? */
-       if (p->symbol_rate > 29000000)
-               s5h1420_writereg(state, QPSK01, 0xae | 0x10);
-       else
-               s5h1420_writereg(state, QPSK01, 0xac | 0x10);
-
-       /* set misc registers */
-       s5h1420_writereg(state, CON_1, 0x00);
-       s5h1420_writereg(state, QPSK02, 0x00);
-       s5h1420_writereg(state, Pre01, 0xb0);
-
-       s5h1420_writereg(state, Loop01, 0xF0);
-       s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */
-       s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */
-       if (p->symbol_rate > 20000000)
-               s5h1420_writereg(state, Loop04, 0x79);
-       else
-               s5h1420_writereg(state, Loop04, 0x58);
-       s5h1420_writereg(state, Loop05, 0x6b);
-
-       if (p->symbol_rate >= 8000000)
-               s5h1420_writereg(state, Post01, (0 << 6) | 0x10);
-       else if (p->symbol_rate >= 4000000)
-               s5h1420_writereg(state, Post01, (1 << 6) | 0x10);
-       else
-               s5h1420_writereg(state, Post01, (3 << 6) | 0x10);
-
-       s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */
-
-       s5h1420_writereg(state, Sync01, 0x33);
-       s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity);
-       s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */
-       s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */
-
-       s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */
-       s5h1420_writereg(state, DiS03, 0x00);
-       s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */
-
-       /* set tuner PLL */
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-               s5h1420_setfreqoffset(state, 0);
-       }
-
-       /* set the reset of the parameters */
-       s5h1420_setsymbolrate(state, p);
-       s5h1420_setfec_inversion(state, p);
-
-       /* start QPSK */
-       s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1);
-
-       state->fec_inner = p->fec_inner;
-       state->symbol_rate = p->symbol_rate;
-       state->postlocked = 0;
-       state->tunedfreq = p->frequency;
-
-       dprintk("leave %s\n", __func__);
-       return 0;
-}
-
-static int s5h1420_get_frontend(struct dvb_frontend* fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
-       p->inversion = s5h1420_getinversion(state);
-       p->symbol_rate = s5h1420_getsymbolrate(state);
-       p->fec_inner = s5h1420_getfec(state);
-
-       return 0;
-}
-
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
-                                    struct dvb_frontend_tune_settings* fesettings)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       if (p->symbol_rate > 20000000) {
-               fesettings->min_delay_ms = 50;
-               fesettings->step_size = 2000;
-               fesettings->max_drift = 8000;
-       } else if (p->symbol_rate > 12000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 1500;
-               fesettings->max_drift = 9000;
-       } else if (p->symbol_rate > 8000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 1000;
-               fesettings->max_drift = 8000;
-       } else if (p->symbol_rate > 4000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 500;
-               fesettings->max_drift = 7000;
-       } else if (p->symbol_rate > 2000000) {
-               fesettings->min_delay_ms = 200;
-               fesettings->step_size = (p->symbol_rate / 8000);
-               fesettings->max_drift = 14 * fesettings->step_size;
-       } else {
-               fesettings->min_delay_ms = 200;
-               fesettings->step_size = (p->symbol_rate / 8000);
-               fesettings->max_drift = 18 * fesettings->step_size;
-       }
-
-       return 0;
-}
-
-static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       if (enable)
-               return s5h1420_writereg(state, 0x02, state->CON_1_val | 1);
-       else
-               return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe);
-}
-
-static int s5h1420_init (struct dvb_frontend* fe)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-
-       /* disable power down and do reset */
-       state->CON_1_val = state->config->serial_mpeg << 4;
-       s5h1420_writereg(state, 0x02, state->CON_1_val);
-       msleep(10);
-       s5h1420_reset(state);
-
-       return 0;
-}
-
-static int s5h1420_sleep(struct dvb_frontend* fe)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       state->CON_1_val = 0x12;
-       return s5h1420_writereg(state, 0x02, state->CON_1_val);
-}
-
-static void s5h1420_release(struct dvb_frontend* fe)
-{
-       struct s5h1420_state* state = fe->demodulator_priv;
-       i2c_del_adapter(&state->tuner_i2c_adapter);
-       kfree(state);
-}
-
-static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_I2C;
-}
-
-static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
-{
-       struct s5h1420_state *state = i2c_get_adapdata(i2c_adap);
-       struct i2c_msg m[1 + num];
-       u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */
-
-       memset(m, 0, sizeof(struct i2c_msg) * (1 + num));
-
-       m[0].addr = state->config->demod_address;
-       m[0].buf  = tx_open;
-       m[0].len  = 2;
-
-       memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
-
-       return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO;
-}
-
-static struct i2c_algorithm s5h1420_tuner_i2c_algo = {
-       .master_xfer   = s5h1420_tuner_i2c_tuner_xfer,
-       .functionality = s5h1420_tuner_i2c_func,
-};
-
-struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       struct s5h1420_state *state = fe->demodulator_priv;
-       return &state->tuner_i2c_adapter;
-}
-EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter);
-
-static struct dvb_frontend_ops s5h1420_ops;
-
-struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       /* allocate memory for the internal state */
-       struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
-       u8 i;
-
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->postlocked = 0;
-       state->fclk = 88000000;
-       state->tunedfreq = 0;
-       state->fec_inner = FEC_NONE;
-       state->symbol_rate = 0;
-
-       /* check if the demod is there + identify it */
-       i = s5h1420_readreg(state, ID01);
-       if (i != 0x03)
-               goto error;
-
-       memset(state->shadow, 0xff, sizeof(state->shadow));
-
-       for (i = 0; i < 0x50; i++)
-               state->shadow[i] = s5h1420_readreg(state, i);
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       /* create tuner i2c adapter */
-       strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
-               sizeof(state->tuner_i2c_adapter.name));
-       state->tuner_i2c_adapter.algo      = &s5h1420_tuner_i2c_algo;
-       state->tuner_i2c_adapter.algo_data = NULL;
-       i2c_set_adapdata(&state->tuner_i2c_adapter, state);
-       if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
-               printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n");
-               goto error;
-       }
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(s5h1420_attach);
-
-static struct dvb_frontend_ops s5h1420_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name     = "Samsung S5H1420/PnpNetwork PN1010 DVB-S",
-               .frequency_min    = 950000,
-               .frequency_max    = 2150000,
-               .frequency_stepsize = 125,     /* kHz for QPSK frontends */
-               .frequency_tolerance  = 29500,
-               .symbol_rate_min  = 1000000,
-               .symbol_rate_max  = 45000000,
-               /*  .symbol_rate_tolerance  = ???,*/
-               .caps = FE_CAN_INVERSION_AUTO |
-               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-               FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-               FE_CAN_QPSK
-       },
-
-       .release = s5h1420_release,
-
-       .init = s5h1420_init,
-       .sleep = s5h1420_sleep,
-       .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl,
-
-       .set_frontend = s5h1420_set_frontend,
-       .get_frontend = s5h1420_get_frontend,
-       .get_tune_settings = s5h1420_get_tune_settings,
-
-       .read_status = s5h1420_read_status,
-       .read_ber = s5h1420_read_ber,
-       .read_signal_strength = s5h1420_read_signal_strength,
-       .read_ucblocks = s5h1420_read_ucblocks,
-
-       .diseqc_send_master_cmd = s5h1420_send_master_cmd,
-       .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
-       .diseqc_send_burst = s5h1420_send_burst,
-       .set_tone = s5h1420_set_tone,
-       .set_voltage = s5h1420_set_voltage,
-};
-
-MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver");
-MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
deleted file mode 100644 (file)
index ff30813..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Driver for
- *    Samsung S5H1420 and
- *    PnpNetwork PN1010 QPSK Demodulator
- *
- * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
- * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef S5H1420_H
-#define S5H1420_H
-
-#include <linux/dvb/frontend.h>
-
-struct s5h1420_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* does the inversion require inversion? */
-       u8 invert:1;
-
-       u8 repeated_start_workaround:1;
-       u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */
-
-       u8 serial_mpeg:1;
-};
-
-#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
-extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
-            struct i2c_adapter *i2c);
-extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe);
-#else
-static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
-                                          struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       return NULL;
-}
-#endif // CONFIG_DVB_S5H1420
-
-#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/s5h1420_priv.h b/drivers/media/dvb/frontends/s5h1420_priv.h
deleted file mode 100644 (file)
index d9c58d2..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Driver for
- *    Samsung S5H1420 and
- *    PnpNetwork PN1010 QPSK Demodulator
- *
- * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
- * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
- * Ave, Cambridge, MA 02139, USA.
- */
-#ifndef S5H1420_PRIV
-#define S5H1420_PRIV
-
-#include <asm/types.h>
-
-enum s5h1420_register {
-       ID01      = 0x00,
-       CON_0     = 0x01,
-       CON_1     = 0x02,
-       PLL01     = 0x03,
-       PLL02     = 0x04,
-       QPSK01    = 0x05,
-       QPSK02    = 0x06,
-       Pre01     = 0x07,
-       Post01    = 0x08,
-       Loop01    = 0x09,
-       Loop02    = 0x0a,
-       Loop03    = 0x0b,
-       Loop04    = 0x0c,
-       Loop05    = 0x0d,
-       Pnco01    = 0x0e,
-       Pnco02    = 0x0f,
-       Pnco03    = 0x10,
-       Tnco01    = 0x11,
-       Tnco02    = 0x12,
-       Tnco03    = 0x13,
-       Monitor01 = 0x14,
-       Monitor02 = 0x15,
-       Monitor03 = 0x16,
-       Monitor04 = 0x17,
-       Monitor05 = 0x18,
-       Monitor06 = 0x19,
-       Monitor07 = 0x1a,
-       Monitor12 = 0x1f,
-
-       FEC01     = 0x22,
-       Soft01    = 0x23,
-       Soft02    = 0x24,
-       Soft03    = 0x25,
-       Soft04    = 0x26,
-       Soft05    = 0x27,
-       Soft06    = 0x28,
-       Vit01     = 0x29,
-       Vit02     = 0x2a,
-       Vit03     = 0x2b,
-       Vit04     = 0x2c,
-       Vit05     = 0x2d,
-       Vit06     = 0x2e,
-       Vit07     = 0x2f,
-       Vit08     = 0x30,
-       Vit09     = 0x31,
-       Vit10     = 0x32,
-       Vit11     = 0x33,
-       Vit12     = 0x34,
-       Sync01    = 0x35,
-       Sync02    = 0x36,
-       Rs01      = 0x37,
-       Mpeg01    = 0x38,
-       Mpeg02    = 0x39,
-       DiS01     = 0x3a,
-       DiS02     = 0x3b,
-       DiS03     = 0x3c,
-       DiS04     = 0x3d,
-       DiS05     = 0x3e,
-       DiS06     = 0x3f,
-       DiS07     = 0x40,
-       DiS08     = 0x41,
-       DiS09     = 0x42,
-       DiS10     = 0x43,
-       DiS11     = 0x44,
-       Rf01      = 0x45,
-       Err01     = 0x46,
-       Err02     = 0x47,
-       Err03     = 0x48,
-       Err04     = 0x49,
-};
-
-
-#endif
diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb/frontends/s5h1432.c
deleted file mode 100644 (file)
index 8352ce1..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- *  Samsung s5h1432 DVB-T demodulator driver
- *
- *  Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "s5h1432.h"
-
-struct s5h1432_state {
-
-       struct i2c_adapter *i2c;
-
-       /* configuration settings */
-       const struct s5h1432_config *config;
-
-       struct dvb_frontend frontend;
-
-       fe_modulation_t current_modulation;
-       unsigned int first_tune:1;
-
-       u32 current_frequency;
-       int if_freq;
-
-       u8 inversion;
-};
-
-static int debug;
-
-#define dprintk(arg...) do {   \
-       if (debug)              \
-               printk(arg);    \
-       } while (0)
-
-static int s5h1432_writereg(struct s5h1432_state *state,
-                           u8 addr, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-
-       struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
-                      "ret == %i)\n", __func__, addr, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-
-       struct i2c_msg msg[] = {
-               {.addr = addr, .flags = 0, .buf = b0, .len = 1},
-               {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1}
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
-                      __func__, ret);
-       return b1[0];
-}
-
-static int s5h1432_sleep(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe,
-                                        u32 bandwidth)
-{
-       struct s5h1432_state *state = fe->demodulator_priv;
-
-       u8 reg = 0;
-
-       /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */
-       reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E);
-       reg &= ~(0x0C);
-       switch (bandwidth) {
-       case 6:
-               reg |= 0x08;
-               break;
-       case 7:
-               reg |= 0x04;
-               break;
-       case 8:
-               reg |= 0x00;
-               break;
-       default:
-               return 0;
-       }
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg);
-       return 1;
-}
-
-static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz)
-{
-       struct s5h1432_state *state = fe->demodulator_priv;
-
-       switch (ifFreqHz) {
-       case TAIWAN_HI_IF_FREQ_44_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15);
-               break;
-       case EUROPE_HI_IF_FREQ_36_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40);
-               break;
-       case IF_FREQ_6_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0);
-               break;
-       case IF_FREQ_3point3_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
-               break;
-       case IF_FREQ_3point5_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED);
-               break;
-       case IF_FREQ_4_MHZ:
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA);
-               break;
-       default:
-               {
-                       u32 value = 0;
-                       value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 *
-                                       (u32) 32768) / (48 * 1000));
-                       printk(KERN_INFO
-                              "Default IFFreq %d :reg value = 0x%x\n",
-                              ifFreqHz, value);
-                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4,
-                                        (u8) value & 0xFF);
-                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5,
-                                        (u8) (value >> 8) & 0xFF);
-                       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7,
-                                        (u8) (value >> 16) & 0xFF);
-                       break;
-               }
-
-       }
-
-       return 1;
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int s5h1432_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u32 dvb_bandwidth = 8;
-       struct s5h1432_state *state = fe->demodulator_priv;
-
-       if (p->frequency == state->current_frequency) {
-               /*current_frequency = p->frequency; */
-               /*state->current_frequency = p->frequency; */
-       } else {
-               fe->ops.tuner_ops.set_params(fe);
-               msleep(300);
-               s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
-               switch (p->bandwidth_hz) {
-               case 6000000:
-                       dvb_bandwidth = 6;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               case 7000000:
-                       dvb_bandwidth = 7;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               case 8000000:
-                       dvb_bandwidth = 8;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               default:
-                       return 0;
-               }
-               /*fe->ops.tuner_ops.set_params(fe); */
-/*Soft Reset chip*/
-               msleep(30);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
-               msleep(30);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
-
-               s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
-               switch (p->bandwidth_hz) {
-               case 6000000:
-                       dvb_bandwidth = 6;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               case 7000000:
-                       dvb_bandwidth = 7;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               case 8000000:
-                       dvb_bandwidth = 8;
-                       s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
-                       break;
-               default:
-                       return 0;
-               }
-               /*fe->ops.tuner_ops.set_params(fe); */
-               /*Soft Reset chip*/
-               msleep(30);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
-               msleep(30);
-               s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
-
-       }
-
-       state->current_frequency = p->frequency;
-
-       return 0;
-}
-
-static int s5h1432_init(struct dvb_frontend *fe)
-{
-       struct s5h1432_state *state = fe->demodulator_priv;
-
-       u8 reg = 0;
-       state->current_frequency = 0;
-       printk(KERN_INFO " s5h1432_init().\n");
-
-       /*Set VSB mode as default, this also does a soft reset */
-       /*Initialize registers */
-
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94);
-       /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00);
-
-       /*For NXP tuner*/
-
-       /*Set 3.3MHz as default IF frequency */
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
-       /* Set reg 0x1E to get the full dynamic range */
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31);
-
-       /* Mode setting in demod */
-       reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42);
-       reg |= 0x80;
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg);
-       /* Serial mode */
-
-       /* Soft Reset chip */
-
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
-       msleep(30);
-       s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
-
-
-       return 0;
-}
-
-static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       return 0;
-}
-
-static int s5h1432_read_signal_strength(struct dvb_frontend *fe,
-                                       u16 *signal_strength)
-{
-       return 0;
-}
-
-static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       return 0;
-}
-
-static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-
-       return 0;
-}
-
-static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       return 0;
-}
-
-static int s5h1432_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings *tune)
-{
-       return 0;
-}
-
-static void s5h1432_release(struct dvb_frontend *fe)
-{
-       struct s5h1432_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops s5h1432_ops;
-
-struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct s5h1432_state *state = NULL;
-
-       printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->current_modulation = QAM_16;
-       state->inversion = state->config->inversion;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &s5h1432_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(s5h1432_attach);
-
-static struct dvb_frontend_ops s5h1432_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-                .name = "Samsung s5h1432 DVB-T Frontend",
-                .frequency_min = 177000000,
-                .frequency_max = 858000000,
-                .frequency_stepsize = 166666,
-                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER},
-
-       .init = s5h1432_init,
-       .sleep = s5h1432_sleep,
-       .set_frontend = s5h1432_set_frontend,
-       .get_tune_settings = s5h1432_get_tune_settings,
-       .read_status = s5h1432_read_status,
-       .read_ber = s5h1432_read_ber,
-       .read_signal_strength = s5h1432_read_signal_strength,
-       .read_snr = s5h1432_read_snr,
-       .read_ucblocks = s5h1432_read_ucblocks,
-       .release = s5h1432_release,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver");
-MODULE_AUTHOR("Bill Liu");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s5h1432.h b/drivers/media/dvb/frontends/s5h1432.h
deleted file mode 100644 (file)
index b57438c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  Samsung s5h1432 VSB/QAM demodulator driver
- *
- *  Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __S5H1432_H__
-#define __S5H1432_H__
-
-#include <linux/dvb/frontend.h>
-
-#define S5H1432_I2C_TOP_ADDR (0x02 >> 1)
-
-#define TAIWAN_HI_IF_FREQ_44_MHZ 44000000
-#define EUROPE_HI_IF_FREQ_36_MHZ 36000000
-#define IF_FREQ_6_MHZ             6000000
-#define IF_FREQ_3point3_MHZ       3300000
-#define IF_FREQ_3point5_MHZ       3500000
-#define IF_FREQ_4_MHZ             4000000
-
-struct s5h1432_config {
-
-       /* serial/parallel output */
-#define S5H1432_PARALLEL_OUTPUT 0
-#define S5H1432_SERIAL_OUTPUT   1
-       u8 output_mode;
-
-       /* GPIO Setting */
-#define S5H1432_GPIO_OFF 0
-#define S5H1432_GPIO_ON  1
-       u8 gpio;
-
-       /* MPEG signal timing */
-#define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK       0
-#define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK    1
-#define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK    2
-#define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
-       u16 mpeg_timing;
-
-       /* IF Freq for QAM and VSB in KHz */
-#define S5H1432_IF_3250  3250
-#define S5H1432_IF_3500  3500
-#define S5H1432_IF_4000  4000
-#define S5H1432_IF_5380  5380
-#define S5H1432_IF_44000 44000
-#define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000
-#define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000
-       u16 qam_if;
-       u16 vsb_if;
-
-       /* Spectral Inversion */
-#define S5H1432_INVERSION_OFF 0
-#define S5H1432_INVERSION_ON  1
-       u8 inversion;
-
-       /* Return lock status based on tuner lock, or demod lock */
-#define S5H1432_TUNERLOCKING 0
-#define S5H1432_DEMODLOCKING 1
-       u8 status_mode;
-};
-
-#if defined(CONFIG_DVB_S5H1432) || \
-       (defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE))
-extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config
-                                                 *config,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_s5h1432 */
-
-#endif /* __s5h1432_H__ */
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c
deleted file mode 100644 (file)
index cd2288c..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- *   Sharp VA3A5JZ921 One Seg Broadcast Module driver
- *   This device is labeled as just S. 921 at the top of the frontend can
- *
- *   Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
- *   Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
- *
- *   Developed for Leadership SBTVD 1seg device sold in Brazil
- *
- *   Frontend module based on cx24123 driver, getting some info from
- *     the old s921 driver.
- *
- *   FIXME: Need to port to DVB v5.2 API
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License as
- *   published by the Free Software Foundation version 2.
- *
- *   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.
- */
-
-#include <linux/kernel.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "s921.h"
-
-static int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-#define rc(args...)  do {                                              \
-       printk(KERN_ERR  "s921: " args);                                \
-} while (0)
-
-#define dprintk(args...)                                               \
-       do {                                                            \
-               if (debug) {                                            \
-                       printk(KERN_DEBUG "s921: %s: ", __func__);      \
-                       printk(args);                                   \
-               }                                                       \
-       } while (0)
-
-struct s921_state {
-       struct i2c_adapter *i2c;
-       const struct s921_config *config;
-
-       struct dvb_frontend frontend;
-
-       /* The Demod can't easily provide these, we cache them */
-       u32 currentfreq;
-};
-
-/*
- * Various tuner defaults need to be established for a given frequency kHz.
- * fixme: The bounds on the bands do not match the doc in real life.
- * fixme: Some of them have been moved, other might need adjustment.
- */
-static struct s921_bandselect_val {
-       u32 freq_low;
-       u8  band_reg;
-} s921_bandselect[] = {
-       {         0, 0x7b },
-       { 485140000, 0x5b },
-       { 515140000, 0x3b },
-       { 545140000, 0x1b },
-       { 599140000, 0xfb },
-       { 623140000, 0xdb },
-       { 659140000, 0xbb },
-       { 713140000, 0x9b },
-};
-
-struct regdata {
-       u8 reg;
-       u8 data;
-};
-
-static struct regdata s921_init[] = {
-       { 0x01, 0x80 },         /* Probably, a reset sequence */
-       { 0x01, 0x40 },
-       { 0x01, 0x80 },
-       { 0x01, 0x40 },
-
-       { 0x02, 0x00 },
-       { 0x03, 0x40 },
-       { 0x04, 0x01 },
-       { 0x05, 0x00 },
-       { 0x06, 0x00 },
-       { 0x07, 0x00 },
-       { 0x08, 0x00 },
-       { 0x09, 0x00 },
-       { 0x0a, 0x00 },
-       { 0x0b, 0x5a },
-       { 0x0c, 0x00 },
-       { 0x0d, 0x00 },
-       { 0x0f, 0x00 },
-       { 0x13, 0x1b },
-       { 0x14, 0x80 },
-       { 0x15, 0x40 },
-       { 0x17, 0x70 },
-       { 0x18, 0x01 },
-       { 0x19, 0x12 },
-       { 0x1a, 0x01 },
-       { 0x1b, 0x12 },
-       { 0x1c, 0xa0 },
-       { 0x1d, 0x00 },
-       { 0x1e, 0x0a },
-       { 0x1f, 0x08 },
-       { 0x20, 0x40 },
-       { 0x21, 0xff },
-       { 0x22, 0x4c },
-       { 0x23, 0x4e },
-       { 0x24, 0x4c },
-       { 0x25, 0x00 },
-       { 0x26, 0x00 },
-       { 0x27, 0xf4 },
-       { 0x28, 0x60 },
-       { 0x29, 0x88 },
-       { 0x2a, 0x40 },
-       { 0x2b, 0x40 },
-       { 0x2c, 0xff },
-       { 0x2d, 0x00 },
-       { 0x2e, 0xff },
-       { 0x2f, 0x00 },
-       { 0x30, 0x20 },
-       { 0x31, 0x06 },
-       { 0x32, 0x0c },
-       { 0x34, 0x0f },
-       { 0x37, 0xfe },
-       { 0x38, 0x00 },
-       { 0x39, 0x63 },
-       { 0x3a, 0x10 },
-       { 0x3b, 0x10 },
-       { 0x47, 0x00 },
-       { 0x49, 0xe5 },
-       { 0x4b, 0x00 },
-       { 0x50, 0xc0 },
-       { 0x52, 0x20 },
-       { 0x54, 0x5a },
-       { 0x55, 0x5b },
-       { 0x56, 0x40 },
-       { 0x57, 0x70 },
-       { 0x5c, 0x50 },
-       { 0x5d, 0x00 },
-       { 0x62, 0x17 },
-       { 0x63, 0x2f },
-       { 0x64, 0x6f },
-       { 0x68, 0x00 },
-       { 0x69, 0x89 },
-       { 0x6a, 0x00 },
-       { 0x6b, 0x00 },
-       { 0x6c, 0x00 },
-       { 0x6d, 0x00 },
-       { 0x6e, 0x00 },
-       { 0x70, 0x10 },
-       { 0x71, 0x00 },
-       { 0x75, 0x00 },
-       { 0x76, 0x30 },
-       { 0x77, 0x01 },
-       { 0xaf, 0x00 },
-       { 0xb0, 0xa0 },
-       { 0xb2, 0x3d },
-       { 0xb3, 0x25 },
-       { 0xb4, 0x8b },
-       { 0xb5, 0x4b },
-       { 0xb6, 0x3f },
-       { 0xb7, 0xff },
-       { 0xb8, 0xff },
-       { 0xb9, 0xfc },
-       { 0xba, 0x00 },
-       { 0xbb, 0x00 },
-       { 0xbc, 0x00 },
-       { 0xd0, 0x30 },
-       { 0xe4, 0x84 },
-       { 0xf0, 0x48 },
-       { 0xf1, 0x19 },
-       { 0xf2, 0x5a },
-       { 0xf3, 0x8e },
-       { 0xf4, 0x2d },
-       { 0xf5, 0x07 },
-       { 0xf6, 0x5a },
-       { 0xf7, 0xba },
-       { 0xf8, 0xd7 },
-};
-
-static struct regdata s921_prefreq[] = {
-       { 0x47, 0x60 },
-       { 0x68, 0x00 },
-       { 0x69, 0x89 },
-       { 0xf0, 0x48 },
-       { 0xf1, 0x19 },
-};
-
-static struct regdata s921_postfreq[] = {
-       { 0xf5, 0xae },
-       { 0xf6, 0xb7 },
-       { 0xf7, 0xba },
-       { 0xf8, 0xd7 },
-       { 0x68, 0x0a },
-       { 0x69, 0x09 },
-};
-
-static int s921_i2c_writereg(struct s921_state *state,
-                            u8 i2c_addr, int reg, int data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
-       };
-       int rc;
-
-       rc = i2c_transfer(state->i2c, &msg, 1);
-       if (rc != 1) {
-               printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
-                        " data == 0x%02x)\n", __func__, rc, reg, data);
-               return rc;
-       }
-
-       return 0;
-}
-
-static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
-                                struct regdata *rd, int size)
-{
-       int i, rc;
-
-       for (i = 0; i < size; i++) {
-               rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
-               if (rc < 0)
-                       return rc;
-       }
-       return 0;
-}
-
-static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
-{
-       u8 val;
-       int rc;
-       struct i2c_msg msg[] = {
-               { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-       };
-
-       rc = i2c_transfer(state->i2c, msg, 2);
-
-       if (rc != 2) {
-               rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
-               return rc;
-       }
-
-       return val;
-}
-
-#define s921_readreg(state, reg) \
-       s921_i2c_readreg(state, state->config->demod_address, reg)
-#define s921_writereg(state, reg, val) \
-       s921_i2c_writereg(state, state->config->demod_address, reg, val)
-#define s921_writeregdata(state, regdata) \
-       s921_i2c_writeregdata(state, state->config->demod_address, \
-       regdata, ARRAY_SIZE(regdata))
-
-static int s921_pll_tune(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s921_state *state = fe->demodulator_priv;
-       int band, rc, i;
-       unsigned long f_offset;
-       u8 f_switch;
-       u64 offset;
-
-       dprintk("frequency=%i\n", p->frequency);
-
-       for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
-               if (p->frequency < s921_bandselect[band].freq_low)
-                       break;
-       band--;
-
-       if (band < 0) {
-               rc("%s: frequency out of range\n", __func__);
-               return -EINVAL;
-       }
-
-       f_switch = s921_bandselect[band].band_reg;
-
-       offset = ((u64)p->frequency) * 258;
-       do_div(offset, 6000000);
-       f_offset = ((unsigned long)offset) + 2321;
-
-       rc = s921_writeregdata(state, s921_prefreq);
-       if (rc < 0)
-               return rc;
-
-       rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
-       if (rc < 0)
-               return rc;
-
-       rc = s921_writereg(state, 0xf3, f_offset & 0xff);
-       if (rc < 0)
-               return rc;
-
-       rc = s921_writereg(state, 0xf4, f_switch);
-       if (rc < 0)
-               return rc;
-
-       rc = s921_writeregdata(state, s921_postfreq);
-       if (rc < 0)
-               return rc;
-
-       for (i = 0 ; i < 6; i++) {
-               rc = s921_readreg(state, 0x80);
-               dprintk("status 0x80: %02x\n", rc);
-       }
-       rc = s921_writereg(state, 0x01, 0x40);
-       if (rc < 0)
-               return rc;
-
-       rc = s921_readreg(state, 0x01);
-       dprintk("status 0x01: %02x\n", rc);
-
-       rc = s921_readreg(state, 0x80);
-       dprintk("status 0x80: %02x\n", rc);
-
-       rc = s921_readreg(state, 0x80);
-       dprintk("status 0x80: %02x\n", rc);
-
-       rc = s921_readreg(state, 0x32);
-       dprintk("status 0x32: %02x\n", rc);
-
-       dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
-
-       return 0;
-}
-
-static int s921_initfe(struct dvb_frontend *fe)
-{
-       struct s921_state *state = fe->demodulator_priv;
-       int rc;
-
-       dprintk("\n");
-
-       rc = s921_writeregdata(state, s921_init);
-       if (rc < 0)
-               return rc;
-
-       return 0;
-}
-
-static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct s921_state *state = fe->demodulator_priv;
-       int regstatus, rc;
-
-       *status = 0;
-
-       rc = s921_readreg(state, 0x81);
-       if (rc < 0)
-               return rc;
-
-       regstatus = rc << 8;
-
-       rc = s921_readreg(state, 0x82);
-       if (rc < 0)
-               return rc;
-
-       regstatus |= rc;
-
-       dprintk("status = %04x\n", regstatus);
-
-       /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
-       if ((regstatus & 0xff) == 0x40) {
-               *status = FE_HAS_SIGNAL  |
-                         FE_HAS_CARRIER |
-                         FE_HAS_VITERBI |
-                         FE_HAS_SYNC    |
-                         FE_HAS_LOCK;
-       } else if (regstatus & 0x40) {
-               /* This is close to Full Sync, but not enough to get useful info */
-               *status = FE_HAS_SIGNAL  |
-                         FE_HAS_CARRIER |
-                         FE_HAS_VITERBI |
-                         FE_HAS_SYNC;
-       }
-
-       return 0;
-}
-
-static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       fe_status_t     status;
-       struct s921_state *state = fe->demodulator_priv;
-       int rc;
-
-       /* FIXME: Use the proper register for it... 0x80? */
-       rc = s921_read_status(fe, &status);
-       if (rc < 0)
-               return rc;
-
-       *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
-
-       dprintk("strength = 0x%04x\n", *strength);
-
-       rc = s921_readreg(state, 0x01);
-       dprintk("status 0x01: %02x\n", rc);
-
-       rc = s921_readreg(state, 0x80);
-       dprintk("status 0x80: %02x\n", rc);
-
-       rc = s921_readreg(state, 0x32);
-       dprintk("status 0x32: %02x\n", rc);
-
-       return 0;
-}
-
-static int s921_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s921_state *state = fe->demodulator_priv;
-       int rc;
-
-       dprintk("\n");
-
-       /* FIXME: We don't know how to use non-auto mode */
-
-       rc = s921_pll_tune(fe);
-       if (rc < 0)
-               return rc;
-
-       state->currentfreq = p->frequency;
-
-       return 0;
-}
-
-static int s921_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct s921_state *state = fe->demodulator_priv;
-
-       /* FIXME: Probably it is possible to get it from regs f1 and f2 */
-       p->frequency = state->currentfreq;
-       p->delivery_system = SYS_ISDBT;
-
-       return 0;
-}
-
-static int s921_tune(struct dvb_frontend *fe,
-                       bool re_tune,
-                       unsigned int mode_flags,
-                       unsigned int *delay,
-                       fe_status_t *status)
-{
-       int rc = 0;
-
-       dprintk("\n");
-
-       if (re_tune)
-               rc = s921_set_frontend(fe);
-
-       if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
-               s921_read_status(fe, status);
-
-       return rc;
-}
-
-static int s921_get_algo(struct dvb_frontend *fe)
-{
-       return 1; /* FE_ALGO_HW */
-}
-
-static void s921_release(struct dvb_frontend *fe)
-{
-       struct s921_state *state = fe->demodulator_priv;
-
-       dprintk("\n");
-       kfree(state);
-}
-
-static struct dvb_frontend_ops s921_ops;
-
-struct dvb_frontend *s921_attach(const struct s921_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       /* allocate memory for the internal state */
-       struct s921_state *state =
-               kzalloc(sizeof(struct s921_state), GFP_KERNEL);
-
-       dprintk("\n");
-       if (state == NULL) {
-               rc("Unable to kzalloc\n");
-               goto rcor;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &s921_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-
-rcor:
-       kfree(state);
-
-       return NULL;
-}
-EXPORT_SYMBOL(s921_attach);
-
-static struct dvb_frontend_ops s921_ops = {
-       .delsys = { SYS_ISDBT },
-       /* Use dib8000 values per default */
-       .info = {
-               .name = "Sharp S921",
-               .frequency_min = 470000000,
-               /*
-                * Max should be 770MHz instead, according with Sharp docs,
-                * but Leadership doc says it works up to 806 MHz. This is
-                * required to get channel 69, used in Brazil
-                */
-               .frequency_max = 806000000,
-               .frequency_tolerance = 0,
-                .caps = FE_CAN_INVERSION_AUTO |
-                        FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                        FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                        FE_CAN_QPSK     | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                        FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                        FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
-                        FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = s921_release,
-
-       .init = s921_initfe,
-       .set_frontend = s921_set_frontend,
-       .get_frontend = s921_get_frontend,
-       .read_status = s921_read_status,
-       .read_signal_strength = s921_read_signal_strength,
-       .tune = s921_tune,
-       .get_frontend_algo = s921_get_algo,
-};
-
-MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb/frontends/s921.h
deleted file mode 100644 (file)
index f220d82..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *   Sharp s921 driver
- *
- *   Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
- *   Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License as
- *   published by the Free Software Foundation version 2.
- *
- *   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.
- */
-
-#ifndef S921_H
-#define S921_H
-
-#include <linux/dvb/frontend.h>
-
-struct s921_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
-       && defined(MODULE))
-extern struct dvb_frontend *s921_attach(const struct s921_config *config,
-                                          struct i2c_adapter *i2c);
-extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
-#else
-static inline struct dvb_frontend *s921_attach(
-       const struct s921_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static struct i2c_adapter *
-       s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
deleted file mode 100644 (file)
index a68a648..0000000
+++ /dev/null
@@ -1,951 +0,0 @@
-/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
-*
-* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*/
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "si21xx.h"
-
-#define        REVISION_REG                    0x00
-#define        SYSTEM_MODE_REG                 0x01
-#define        TS_CTRL_REG_1                   0x02
-#define        TS_CTRL_REG_2                   0x03
-#define        PIN_CTRL_REG_1                  0x04
-#define        PIN_CTRL_REG_2                  0x05
-#define        LOCK_STATUS_REG_1               0x0f
-#define        LOCK_STATUS_REG_2               0x10
-#define        ACQ_STATUS_REG                  0x11
-#define        ACQ_CTRL_REG_1                  0x13
-#define        ACQ_CTRL_REG_2                  0x14
-#define        PLL_DIVISOR_REG                 0x15
-#define        COARSE_TUNE_REG                 0x16
-#define        FINE_TUNE_REG_L                 0x17
-#define        FINE_TUNE_REG_H                 0x18
-
-#define        ANALOG_AGC_POWER_LEVEL_REG      0x28
-#define        CFO_ESTIMATOR_CTRL_REG_1        0x29
-#define        CFO_ESTIMATOR_CTRL_REG_2        0x2a
-#define        CFO_ESTIMATOR_CTRL_REG_3        0x2b
-
-#define        SYM_RATE_ESTIMATE_REG_L         0x31
-#define        SYM_RATE_ESTIMATE_REG_M         0x32
-#define        SYM_RATE_ESTIMATE_REG_H         0x33
-
-#define        CFO_ESTIMATOR_OFFSET_REG_L      0x36
-#define        CFO_ESTIMATOR_OFFSET_REG_H      0x37
-#define        CFO_ERROR_REG_L                 0x38
-#define        CFO_ERROR_REG_H                 0x39
-#define        SYM_RATE_ESTIMATOR_CTRL_REG     0x3a
-
-#define        SYM_RATE_REG_L                  0x3f
-#define        SYM_RATE_REG_M                  0x40
-#define        SYM_RATE_REG_H                  0x41
-#define        SYM_RATE_ESTIMATOR_MAXIMUM_REG  0x42
-#define        SYM_RATE_ESTIMATOR_MINIMUM_REG  0x43
-
-#define        C_N_ESTIMATOR_CTRL_REG          0x7c
-#define        C_N_ESTIMATOR_THRSHLD_REG       0x7d
-#define        C_N_ESTIMATOR_LEVEL_REG_L       0x7e
-#define        C_N_ESTIMATOR_LEVEL_REG_H       0x7f
-
-#define        BLIND_SCAN_CTRL_REG             0x80
-
-#define        LSA_CTRL_REG_1                  0x8D
-#define        SPCTRM_TILT_CORR_THRSHLD_REG    0x8f
-#define        ONE_DB_BNDWDTH_THRSHLD_REG      0x90
-#define        TWO_DB_BNDWDTH_THRSHLD_REG      0x91
-#define        THREE_DB_BNDWDTH_THRSHLD_REG    0x92
-#define        INBAND_POWER_THRSHLD_REG        0x93
-#define        REF_NOISE_LVL_MRGN_THRSHLD_REG  0x94
-
-#define        VIT_SRCH_CTRL_REG_1             0xa0
-#define        VIT_SRCH_CTRL_REG_2             0xa1
-#define        VIT_SRCH_CTRL_REG_3             0xa2
-#define        VIT_SRCH_STATUS_REG             0xa3
-#define        VITERBI_BER_COUNT_REG_L         0xab
-#define        REED_SOLOMON_CTRL_REG           0xb0
-#define        REED_SOLOMON_ERROR_COUNT_REG_L  0xb1
-#define        PRBS_CTRL_REG                   0xb5
-
-#define        LNB_CTRL_REG_1                  0xc0
-#define        LNB_CTRL_REG_2                  0xc1
-#define        LNB_CTRL_REG_3                  0xc2
-#define        LNB_CTRL_REG_4                  0xc3
-#define        LNB_CTRL_STATUS_REG             0xc4
-#define        LNB_FIFO_REGS_0                 0xc5
-#define        LNB_FIFO_REGS_1                 0xc6
-#define        LNB_FIFO_REGS_2                 0xc7
-#define        LNB_FIFO_REGS_3                 0xc8
-#define        LNB_FIFO_REGS_4                 0xc9
-#define        LNB_FIFO_REGS_5                 0xca
-#define        LNB_SUPPLY_CTRL_REG_1           0xcb
-#define        LNB_SUPPLY_CTRL_REG_2           0xcc
-#define        LNB_SUPPLY_CTRL_REG_3           0xcd
-#define        LNB_SUPPLY_CTRL_REG_4           0xce
-#define        LNB_SUPPLY_STATUS_REG           0xcf
-
-#define FAIL   -1
-#define PASS   0
-
-#define ALLOWABLE_FS_COUNT     10
-#define STATUS_BER             0
-#define STATUS_UCBLOCKS                1
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "si21xx: " args); \
-       } while (0)
-
-enum {
-       ACTIVE_HIGH,
-       ACTIVE_LOW
-};
-enum {
-       BYTE_WIDE,
-       BIT_WIDE
-};
-enum {
-       CLK_GAPPED_MODE,
-       CLK_CONTINUOUS_MODE
-};
-enum {
-       RISING_EDGE,
-       FALLING_EDGE
-};
-enum {
-       MSB_FIRST,
-       LSB_FIRST
-};
-enum {
-       SERIAL,
-       PARALLEL
-};
-
-struct si21xx_state {
-       struct i2c_adapter *i2c;
-       const struct si21xx_config *config;
-       struct dvb_frontend frontend;
-       u8 initialised:1;
-       int errmode;
-       int fs;                 /*Sampling rate of the ADC in MHz*/
-};
-
-/*     register default initialization */
-static u8 serit_sp1511lhb_inittab[] = {
-       0x01, 0x28,     /* set i2c_inc_disable */
-       0x20, 0x03,
-       0x27, 0x20,
-       0xe0, 0x45,
-       0xe1, 0x08,
-       0xfe, 0x01,
-       0x01, 0x28,
-       0x89, 0x09,
-       0x04, 0x80,
-       0x05, 0x01,
-       0x06, 0x00,
-       0x20, 0x03,
-       0x24, 0x88,
-       0x29, 0x09,
-       0x2a, 0x0f,
-       0x2c, 0x10,
-       0x2d, 0x19,
-       0x2e, 0x08,
-       0x2f, 0x10,
-       0x30, 0x19,
-       0x34, 0x20,
-       0x35, 0x03,
-       0x45, 0x02,
-       0x46, 0x45,
-       0x47, 0xd0,
-       0x48, 0x00,
-       0x49, 0x40,
-       0x4a, 0x03,
-       0x4c, 0xfd,
-       0x4f, 0x2e,
-       0x50, 0x2e,
-       0x51, 0x10,
-       0x52, 0x10,
-       0x56, 0x92,
-       0x59, 0x00,
-       0x5a, 0x2d,
-       0x5b, 0x33,
-       0x5c, 0x1f,
-       0x5f, 0x76,
-       0x62, 0xc0,
-       0x63, 0xc0,
-       0x64, 0xf3,
-       0x65, 0xf3,
-       0x79, 0x40,
-       0x6a, 0x40,
-       0x6b, 0x0a,
-       0x6c, 0x80,
-       0x6d, 0x27,
-       0x71, 0x06,
-       0x75, 0x60,
-       0x78, 0x00,
-       0x79, 0xb5,
-       0x7c, 0x05,
-       0x7d, 0x1a,
-       0x87, 0x55,
-       0x88, 0x72,
-       0x8f, 0x08,
-       0x90, 0xe0,
-       0x94, 0x40,
-       0xa0, 0x3f,
-       0xa1, 0xc0,
-       0xa4, 0xcc,
-       0xa5, 0x66,
-       0xa6, 0x66,
-       0xa7, 0x7b,
-       0xa8, 0x7b,
-       0xa9, 0x7b,
-       0xaa, 0x9a,
-       0xed, 0x04,
-       0xad, 0x00,
-       0xae, 0x03,
-       0xcc, 0xab,
-       0x01, 0x08,
-       0xff, 0xff
-};
-
-/*     low level read/writes */
-static int si21_writeregs(struct si21xx_state *state, u8 reg1,
-                                                       u8 *data, int len)
-{
-       int ret;
-       u8 buf[60];/* = { reg1, data };*/
-       struct i2c_msg msg = {
-                               .addr = state->config->demod_address,
-                               .flags = 0,
-                               .buf = buf,
-                               .len = len + 1
-       };
-
-       msg.buf[0] =  reg1;
-       memcpy(msg.buf + 1, data, len);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
-                       "ret == %i)\n", __func__, reg1, data[0], ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-                               .addr = state->config->demod_address,
-                               .flags = 0,
-                               .buf = buf,
-                               .len = 2
-       };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
-                       "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return si21_writereg(state, buf[0], buf[1]);
-}
-
-static u8 si21_readreg(struct si21xx_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
-                       __func__, reg, ret);
-
-       return b1[0];
-}
-
-static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
-{
-       int ret;
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = &reg1,
-                       .len = 1
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b,
-                       .len = len
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
-
-       return ret == 2 ? 0 : -1;
-}
-
-static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
-{
-       unsigned long start = jiffies;
-
-       dprintk("%s\n", __func__);
-
-       while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
-               if (jiffies - start > timeout) {
-                       dprintk("%s: timeout!!\n", __func__);
-                       return -ETIMEDOUT;
-               }
-               msleep(10);
-       };
-
-       return 0;
-}
-
-static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u32 sym_rate, data_rate;
-       int i;
-       u8 sym_rate_bytes[3];
-
-       dprintk("%s : srate = %i\n", __func__ , srate);
-
-       if ((srate < 1000000) || (srate > 45000000))
-               return -EINVAL;
-
-       data_rate = srate;
-       sym_rate = 0;
-
-       for (i = 0; i < 4; ++i) {
-               sym_rate /= 100;
-               sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
-                                                               state->fs;
-               data_rate /= 100;
-       }
-       for (i = 0; i < 3; ++i)
-               sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
-
-       si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
-
-       return 0;
-}
-
-static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
-                                       struct dvb_diseqc_master_cmd *m)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 lnb_status;
-       u8 LNB_CTRL_1;
-       int status;
-
-       dprintk("%s\n", __func__);
-
-       status = PASS;
-       LNB_CTRL_1 = 0;
-
-       status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
-       status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
-
-       /*fill the FIFO*/
-       status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
-
-       LNB_CTRL_1 = (lnb_status & 0x70);
-       LNB_CTRL_1 |= m->msg_len;
-
-       LNB_CTRL_1 |= 0x80;     /* begin LNB signaling */
-
-       status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
-
-       return status;
-}
-
-static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
-                                               fe_sec_mini_cmd_t burst)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("%s\n", __func__);
-
-       if (si21xx_wait_diseqc_idle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       val = (0x80 | si21_readreg(state, 0xc1));
-       if (si21_writereg(state, LNB_CTRL_REG_1,
-                       burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
-               return -EREMOTEIO;
-
-       if (si21xx_wait_diseqc_idle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       if (si21_writereg(state, LNB_CTRL_REG_1, val))
-               return -EREMOTEIO;
-
-       return 0;
-}
-/*     30.06.2008 */
-static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk("%s\n", __func__);
-       val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
-
-       case SEC_TONE_OFF:
-               return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       u8 val;
-       dprintk("%s: %s\n", __func__,
-               volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
-               volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
-
-
-       val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
-
-       switch (volt) {
-       case SEC_VOLTAGE_18:
-               return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
-               break;
-       case SEC_VOLTAGE_13:
-               return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
-               break;
-       default:
-               return -EINVAL;
-       };
-}
-
-static int si21xx_init(struct dvb_frontend *fe)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       int i;
-       int status = 0;
-       u8 reg1;
-       u8 val;
-       u8 reg2[2];
-
-       dprintk("%s\n", __func__);
-
-       for (i = 0; ; i += 2) {
-               reg1 = serit_sp1511lhb_inittab[i];
-               val = serit_sp1511lhb_inittab[i+1];
-               if (reg1 == 0xff && val == 0xff)
-                       break;
-               si21_writeregs(state, reg1, &val, 1);
-       }
-
-       /*DVB QPSK SYSTEM MODE REG*/
-       reg1 = 0x08;
-       si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
-
-       /*transport stream config*/
-       /*
-       mode = PARALLEL;
-       sdata_form = LSB_FIRST;
-       clk_edge = FALLING_EDGE;
-       clk_mode = CLK_GAPPED_MODE;
-       strt_len = BYTE_WIDE;
-       sync_pol = ACTIVE_HIGH;
-       val_pol = ACTIVE_HIGH;
-       err_pol = ACTIVE_HIGH;
-       sclk_rate = 0x00;
-       parity = 0x00 ;
-       data_delay = 0x00;
-       clk_delay = 0x00;
-       pclk_smooth = 0x00;
-       */
-       reg2[0] =
-               PARALLEL + (LSB_FIRST << 1)
-               + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
-               + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
-               + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
-
-       reg2[1] = 0;
-       /*      sclk_rate + (parity << 2)
-               + (data_delay << 3) + (clk_delay << 4)
-               + (pclk_smooth << 5);
-       */
-       status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
-       if (status != 0)
-               dprintk(" %s : TS Set Error\n", __func__);
-
-       return 0;
-
-}
-
-static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 regs_read[2];
-       u8 reg_read;
-       u8 i;
-       u8 lock;
-       u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
-
-       si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
-       reg_read = 0;
-
-       for (i = 0; i < 7; ++i)
-               reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
-
-       lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
-
-       dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
-       *status = 0;
-
-       if (signal > 10)
-               *status |= FE_HAS_SIGNAL;
-
-       if (lock & 0x2)
-               *status |= FE_HAS_CARRIER;
-
-       if (lock & 0x20)
-               *status |= FE_HAS_VITERBI;
-
-       if (lock & 0x40)
-               *status |= FE_HAS_SYNC;
-
-       if ((lock & 0x7b) == 0x7b)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
-                                               (u8*)agclevel, 0x01);*/
-
-       u16 signal = (3 * si21_readreg(state, 0x27) *
-                                       si21_readreg(state, 0x28));
-
-       dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
-               si21_readreg(state, 0x27),
-               si21_readreg(state, 0x28), (int) signal);
-
-       signal  <<= 4;
-       *strength = signal;
-
-       return 0;
-}
-
-static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (state->errmode != STATUS_BER)
-               return 0;
-
-       *ber = (si21_readreg(state, 0x1d) << 8) |
-                               si21_readreg(state, 0x1e);
-
-       return 0;
-}
-
-static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
-                                       si21_readreg(state, 0x25));
-       xsnr = 3 * (xsnr - 0xa100);
-       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
-
-       dprintk("%s\n", __func__);
-
-       return 0;
-}
-
-static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (state->errmode != STATUS_UCBLOCKS)
-               *ucblocks = 0;
-       else
-               *ucblocks = (si21_readreg(state, 0x1d) << 8) |
-                                       si21_readreg(state, 0x1e);
-
-       return 0;
-}
-
-/*     initiates a channel acquisition sequence
-       using the specified symbol rate and code rate */
-static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
-                                               fe_code_rate_t crate)
-{
-
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 coderates[] = {
-                               0x0, 0x01, 0x02, 0x04, 0x00,
-                               0x8, 0x10, 0x20, 0x00, 0x3f
-       };
-
-       u8 coderate_ptr;
-       int status;
-       u8 start_acq = 0x80;
-       u8 reg, regs[3];
-
-       dprintk("%s\n", __func__);
-
-       status = PASS;
-       coderate_ptr = coderates[crate];
-
-       si21xx_set_symbolrate(fe, symbrate);
-
-       /* write code rates to use in the Viterbi search */
-       status |= si21_writeregs(state,
-                               VIT_SRCH_CTRL_REG_1,
-                               &coderate_ptr, 0x01);
-
-       /* clear acq_start bit */
-       status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
-       reg &= ~start_acq;
-       status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
-
-       /* use new Carrier Frequency Offset Estimator (QuickLock) */
-       regs[0] = 0xCB;
-       regs[1] = 0x40;
-       regs[2] = 0xCB;
-
-       status |= si21_writeregs(state,
-                               TWO_DB_BNDWDTH_THRSHLD_REG,
-                               &regs[0], 0x03);
-       reg = 0x56;
-       status |= si21_writeregs(state,
-                               LSA_CTRL_REG_1, &reg, 1);
-       reg = 0x05;
-       status |= si21_writeregs(state,
-                               BLIND_SCAN_CTRL_REG, &reg, 1);
-       /* start automatic acq */
-       status |= si21_writeregs(state,
-                               ACQ_CTRL_REG_2, &start_acq, 0x01);
-
-       return status;
-}
-
-static int si21xx_set_frontend(struct dvb_frontend *fe)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-       /* freq         Channel carrier frequency in KHz (i.e. 1550000 KHz)
-        datarate       Channel symbol rate in Sps (i.e. 22500000 Sps)*/
-
-       /* in MHz */
-       unsigned char coarse_tune_freq;
-       int fine_tune_freq;
-       unsigned char sample_rate = 0;
-       /* boolean */
-       bool inband_interferer_ind;
-
-       /* INTERMEDIATE VALUES */
-       int icoarse_tune_freq; /* MHz */
-       int ifine_tune_freq; /* MHz */
-       unsigned int band_high;
-       unsigned int band_low;
-       unsigned int x1;
-       unsigned int x2;
-       int i;
-       bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
-       bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
-       int status;
-
-       /* allowable sample rates for ADC in MHz */
-       int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
-                                       196, 204, 205, 206, 207
-       };
-       /* in MHz */
-       int if_limit_high;
-       int if_limit_low;
-       int lnb_lo;
-       int lnb_uncertanity;
-
-       int rf_freq;
-       int data_rate;
-       unsigned char regs[4];
-
-       dprintk("%s : FE_SET_FRONTEND\n", __func__);
-
-       if (c->delivery_system != SYS_DVBS) {
-                       dprintk("%s: unsupported delivery system selected (%d)\n",
-                               __func__, c->delivery_system);
-                       return -EOPNOTSUPP;
-       }
-
-       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
-               inband_interferer_div2[i] = inband_interferer_div4[i] = false;
-
-       if_limit_high = -700000;
-       if_limit_low = -100000;
-       /* in MHz */
-       lnb_lo = 0;
-       lnb_uncertanity = 0;
-
-       rf_freq = 10 * c->frequency ;
-       data_rate = c->symbol_rate / 100;
-
-       status = PASS;
-
-       band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
-                                       + (data_rate * 135)) / 200;
-
-       band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
-                                       + (data_rate * 135)) / 200;
-
-
-       icoarse_tune_freq = 100000 *
-                               (((rf_freq - lnb_lo) -
-                                       (if_limit_low + if_limit_high) / 2)
-                                                               / 100000);
-
-       ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
-
-       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-               x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
-                                       (afs[i] * 2500) + afs[i] * 2500;
-
-               x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
-                                                       (afs[i] * 2500);
-
-               if (((band_low < x1) && (x1 < band_high)) ||
-                                       ((band_low < x2) && (x2 < band_high)))
-                                       inband_interferer_div4[i] = true;
-
-       }
-
-       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-               x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
-                                       (afs[i] * 5000) + afs[i] * 5000;
-
-               x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
-                                       (afs[i] * 5000);
-
-               if (((band_low < x1) && (x1 < band_high)) ||
-                                       ((band_low < x2) && (x2 < band_high)))
-                                       inband_interferer_div2[i] = true;
-       }
-
-       inband_interferer_ind = true;
-       for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-               if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
-                       inband_interferer_ind = false;
-                       break;
-               }
-       }
-
-       if (inband_interferer_ind) {
-               for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-                       if (!inband_interferer_div2[i]) {
-                               sample_rate = (u8) afs[i];
-                               break;
-                       }
-               }
-       } else {
-               for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
-                       if ((inband_interferer_div2[i] ||
-                            !inband_interferer_div4[i])) {
-                               sample_rate = (u8) afs[i];
-                               break;
-                       }
-               }
-
-       }
-
-       if (sample_rate > 207 || sample_rate < 192)
-               sample_rate = 200;
-
-       fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
-                                       ((sample_rate) * 1000));
-
-       coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
-
-       regs[0] = sample_rate;
-       regs[1] = coarse_tune_freq;
-       regs[2] = fine_tune_freq & 0xFF;
-       regs[3] = fine_tune_freq >> 8 & 0xFF;
-
-       status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
-
-       state->fs = sample_rate;/*ADC MHz*/
-       si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
-
-       return 0;
-}
-
-static int si21xx_sleep(struct dvb_frontend *fe)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-       u8 regdata;
-
-       dprintk("%s\n", __func__);
-
-       si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
-       regdata |= 1 << 6;
-       si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
-       state->initialised = 0;
-
-       return 0;
-}
-
-static void si21xx_release(struct dvb_frontend *fe)
-{
-       struct si21xx_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       kfree(state);
-}
-
-static struct dvb_frontend_ops si21xx_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "SL SI21XX DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,  /* ppm */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-               FE_CAN_QPSK |
-               FE_CAN_FEC_AUTO
-       },
-
-       .release = si21xx_release,
-       .init = si21xx_init,
-       .sleep = si21xx_sleep,
-       .write = si21_write,
-       .read_status = si21_read_status,
-       .read_ber = si21_read_ber,
-       .read_signal_strength = si21_read_signal_strength,
-       .read_snr = si21_read_snr,
-       .read_ucblocks = si21_read_ucblocks,
-       .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
-       .diseqc_send_burst = si21xx_send_diseqc_burst,
-       .set_tone = si21xx_set_tone,
-       .set_voltage = si21xx_set_voltage,
-
-       .set_frontend = si21xx_set_frontend,
-};
-
-struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
-                                               struct i2c_adapter *i2c)
-{
-       struct si21xx_state *state = NULL;
-       int id;
-
-       dprintk("%s\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-       state->errmode = STATUS_BER;
-
-       /* check if the demod is there */
-       id = si21_readreg(state, SYSTEM_MODE_REG);
-       si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
-       msleep(200);
-       id = si21_readreg(state, 0x00);
-
-       /* register 0x00 contains:
-               0x34 for SI2107
-               0x24 for SI2108
-               0x14 for SI2109
-               0x04 for SI2110
-       */
-       if (id != 0x04 && id != 0x14)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &si21xx_ops,
-                                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(si21xx_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
-MODULE_AUTHOR("Igor M. Liplianin");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h
deleted file mode 100644 (file)
index 141b5b8..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef SI21XX_H
-#define SI21XX_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct si21xx_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* minimum delay before retuning */
-       int min_delay_ms;
-};
-
-#if defined(CONFIG_DVB_SI21XX) || \
-               (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
-extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
-                                               struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *si21xx_attach(
-               const struct si21xx_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val)
-{
-       int r = 0;
-       u8 buf[] = {reg, val};
-       if (fe->ops.write)
-               r = fe->ops.write(fe, buf, 2);
-       return r;
-}
-
-#endif
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
deleted file mode 100644 (file)
index e37274c..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-    Driver for Spase SP8870 demodulator
-
-    Copyright (C) 1999 Juergen Peitz
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "sp8870.h"
-
-
-struct sp8870_state {
-
-       struct i2c_adapter* i2c;
-
-       const struct sp8870_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "sp8870: " args); \
-       } while (0)
-
-/* firmware size for sp8870 */
-#define SP8870_FIRMWARE_SIZE 16382
-
-/* starting point for firmware in file 'Sc_main.mc' */
-#define SP8870_FIRMWARE_OFFSET 0x0A
-
-static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
-{
-       u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int sp8870_readreg (struct sp8870_state* state, u16 reg)
-{
-       int ret;
-       u8 b0 [] = { reg >> 8 , reg & 0xff };
-       u8 b1 [] = { 0, 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-
-       if (ret != 2) {
-               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
-               return -1;
-       }
-
-       return (b1[0] << 8 | b1[1]);
-}
-
-static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
-{
-       struct i2c_msg msg;
-       const char *fw_buf = fw->data;
-       int fw_pos;
-       u8 tx_buf[255];
-       int tx_len;
-       int err = 0;
-
-       dprintk ("%s: ...\n", __func__);
-
-       if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
-               return -EINVAL;
-
-       // system controller stop
-       sp8870_writereg(state, 0x0F00, 0x0000);
-
-       // instruction RAM register hiword
-       sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
-
-       // instruction RAM MWR
-       sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
-
-       // do firmware upload
-       fw_pos = SP8870_FIRMWARE_OFFSET;
-       while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
-               tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
-               // write register 0xCF0A
-               tx_buf[0] = 0xCF;
-               tx_buf[1] = 0x0A;
-               memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
-               msg.addr = state->config->demod_address;
-               msg.flags = 0;
-               msg.buf = tx_buf;
-               msg.len = tx_len + 2;
-               if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-                       printk("%s: firmware upload failed!\n", __func__);
-                       printk ("%s: i2c error (err == %i)\n", __func__, err);
-                       return err;
-               }
-               fw_pos += tx_len;
-       }
-
-       dprintk ("%s: done!\n", __func__);
-       return 0;
-};
-
-static void sp8870_microcontroller_stop (struct sp8870_state* state)
-{
-       sp8870_writereg(state, 0x0F08, 0x000);
-       sp8870_writereg(state, 0x0F09, 0x000);
-
-       // microcontroller STOP
-       sp8870_writereg(state, 0x0F00, 0x000);
-}
-
-static void sp8870_microcontroller_start (struct sp8870_state* state)
-{
-       sp8870_writereg(state, 0x0F08, 0x000);
-       sp8870_writereg(state, 0x0F09, 0x000);
-
-       // microcontroller START
-       sp8870_writereg(state, 0x0F00, 0x001);
-       // not documented but if we don't read 0x0D01 out here
-       // we don't get a correct data valid signal
-       sp8870_readreg(state, 0x0D01);
-}
-
-static int sp8870_read_data_valid_signal(struct sp8870_state* state)
-{
-       return (sp8870_readreg(state, 0x0D02) > 0);
-}
-
-static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
-{
-       int known_parameters = 1;
-
-       *reg0xc05 = 0x000;
-
-       switch (p->modulation) {
-       case QPSK:
-               break;
-       case QAM_16:
-               *reg0xc05 |= (1 << 10);
-               break;
-       case QAM_64:
-               *reg0xc05 |= (2 << 10);
-               break;
-       case QAM_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       switch (p->hierarchy) {
-       case HIERARCHY_NONE:
-               break;
-       case HIERARCHY_1:
-               *reg0xc05 |= (1 << 7);
-               break;
-       case HIERARCHY_2:
-               *reg0xc05 |= (2 << 7);
-               break;
-       case HIERARCHY_4:
-               *reg0xc05 |= (3 << 7);
-               break;
-       case HIERARCHY_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       switch (p->code_rate_HP) {
-       case FEC_1_2:
-               break;
-       case FEC_2_3:
-               *reg0xc05 |= (1 << 3);
-               break;
-       case FEC_3_4:
-               *reg0xc05 |= (2 << 3);
-               break;
-       case FEC_5_6:
-               *reg0xc05 |= (3 << 3);
-               break;
-       case FEC_7_8:
-               *reg0xc05 |= (4 << 3);
-               break;
-       case FEC_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       if (known_parameters)
-               *reg0xc05 |= (2 << 1);  /* use specified parameters */
-       else
-               *reg0xc05 |= (1 << 1);  /* enable autoprobing */
-
-       return 0;
-}
-
-static int sp8870_wake_up(struct sp8870_state* state)
-{
-       // enable TS output and interface pins
-       return sp8870_writereg(state, 0xC18, 0x00D);
-}
-
-static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct sp8870_state* state = fe->demodulator_priv;
-       int  err;
-       u16 reg0xc05;
-
-       if ((err = configure_reg0xc05(p, &reg0xc05)))
-               return err;
-
-       // system controller stop
-       sp8870_microcontroller_stop(state);
-
-       // set tuner parameters
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       // sample rate correction bit [23..17]
-       sp8870_writereg(state, 0x0319, 0x000A);
-
-       // sample rate correction bit [16..0]
-       sp8870_writereg(state, 0x031A, 0x0AAB);
-
-       // integer carrier offset
-       sp8870_writereg(state, 0x0309, 0x0400);
-
-       // fractional carrier offset
-       sp8870_writereg(state, 0x030A, 0x0000);
-
-       // filter for 6/7/8 Mhz channel
-       if (p->bandwidth_hz == 6000000)
-               sp8870_writereg(state, 0x0311, 0x0002);
-       else if (p->bandwidth_hz == 7000000)
-               sp8870_writereg(state, 0x0311, 0x0001);
-       else
-               sp8870_writereg(state, 0x0311, 0x0000);
-
-       // scan order: 2k first = 0x0000, 8k first = 0x0001
-       if (p->transmission_mode == TRANSMISSION_MODE_2K)
-               sp8870_writereg(state, 0x0338, 0x0000);
-       else
-               sp8870_writereg(state, 0x0338, 0x0001);
-
-       sp8870_writereg(state, 0xc05, reg0xc05);
-
-       // read status reg in order to clear pending irqs
-       sp8870_readreg(state, 0x200);
-
-       // system controller start
-       sp8870_microcontroller_start(state);
-
-       return 0;
-}
-
-static int sp8870_init (struct dvb_frontend* fe)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       const struct firmware *fw = NULL;
-
-       sp8870_wake_up(state);
-       if (state->initialised) return 0;
-       state->initialised = 1;
-
-       dprintk ("%s\n", __func__);
-
-
-       /* request the firmware, this will block until someone uploads it */
-       printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
-       if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
-               printk("sp8870: no firmware upload (timeout or file not found?)\n");
-               return -EIO;
-       }
-
-       if (sp8870_firmware_upload(state, fw)) {
-               printk("sp8870: writing firmware to device failed\n");
-               release_firmware(fw);
-               return -EIO;
-       }
-       release_firmware(fw);
-       printk("sp8870: firmware upload complete\n");
-
-       /* enable TS output and interface pins */
-       sp8870_writereg(state, 0xc18, 0x00d);
-
-       // system controller stop
-       sp8870_microcontroller_stop(state);
-
-       // ADC mode
-       sp8870_writereg(state, 0x0301, 0x0003);
-
-       // Reed Solomon parity bytes passed to output
-       sp8870_writereg(state, 0x0C13, 0x0001);
-
-       // MPEG clock is suppressed if no valid data
-       sp8870_writereg(state, 0x0C14, 0x0001);
-
-       /* bit 0x010: enable data valid signal */
-       sp8870_writereg(state, 0x0D00, 0x010);
-       sp8870_writereg(state, 0x0D01, 0x000);
-
-       return 0;
-}
-
-static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       int status;
-       int signal;
-
-       *fe_status = 0;
-
-       status = sp8870_readreg (state, 0x0200);
-       if (status < 0)
-               return -EIO;
-
-       signal = sp8870_readreg (state, 0x0303);
-       if (signal < 0)
-               return -EIO;
-
-       if (signal > 0x0F)
-               *fe_status |= FE_HAS_SIGNAL;
-       if (status & 0x08)
-               *fe_status |= FE_HAS_SYNC;
-       if (status & 0x04)
-               *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
-
-       return 0;
-}
-
-static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       int ret;
-       u32 tmp;
-
-       *ber = 0;
-
-       ret = sp8870_readreg(state, 0xC08);
-       if (ret < 0)
-               return -EIO;
-
-       tmp = ret & 0x3F;
-
-       ret = sp8870_readreg(state, 0xC07);
-       if (ret < 0)
-               return -EIO;
-
-        tmp = ret << 6;
-
-       if (tmp >= 0x3FFF0)
-               tmp = ~0;
-
-       *ber = tmp;
-
-       return 0;
-}
-
-static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       int ret;
-       u16 tmp;
-
-       *signal = 0;
-
-       ret = sp8870_readreg (state, 0x306);
-       if (ret < 0)
-               return -EIO;
-
-       tmp = ret << 8;
-
-       ret = sp8870_readreg (state, 0x303);
-       if (ret < 0)
-               return -EIO;
-
-       tmp |= ret;
-
-       if (tmp)
-               *signal = 0xFFFF - tmp;
-
-       return 0;
-}
-
-static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       int ret;
-
-       *ublocks = 0;
-
-       ret = sp8870_readreg(state, 0xC0C);
-       if (ret < 0)
-               return -EIO;
-
-       if (ret == 0xFFFF)
-               ret = ~0;
-
-       *ublocks = ret;
-
-       return 0;
-}
-
-/* number of trials to recover from lockup */
-#define MAXTRIALS 5
-/* maximum checks for data valid signal */
-#define MAXCHECKS 100
-
-/* only for debugging: counter for detected lockups */
-static int lockups;
-/* only for debugging: counter for channel switches */
-static int switches;
-
-static int sp8870_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct sp8870_state* state = fe->demodulator_priv;
-
-       /*
-           The firmware of the sp8870 sometimes locks up after setting frontend parameters.
-           We try to detect this by checking the data valid signal.
-           If it is not set after MAXCHECKS we try to recover the lockup by setting
-           the frontend parameters again.
-       */
-
-       int err = 0;
-       int valid = 0;
-       int trials = 0;
-       int check_count = 0;
-
-       dprintk("%s: frequency = %i\n", __func__, p->frequency);
-
-       for (trials = 1; trials <= MAXTRIALS; trials++) {
-
-               err = sp8870_set_frontend_parameters(fe);
-               if (err)
-                       return err;
-
-               for (check_count = 0; check_count < MAXCHECKS; check_count++) {
-//                     valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
-                       valid = sp8870_read_data_valid_signal(state);
-                       if (valid) {
-                               dprintk("%s: delay = %i usec\n",
-                                       __func__, check_count * 10);
-                               break;
-                       }
-                       udelay(10);
-               }
-               if (valid)
-                       break;
-       }
-
-       if (!valid) {
-               printk("%s: firmware crash!!!!!!\n", __func__);
-               return -EIO;
-       }
-
-       if (debug) {
-               if (valid) {
-                       if (trials > 1) {
-                               printk("%s: firmware lockup!!!\n", __func__);
-                               printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
-                               lockups++;
-                       }
-               }
-               switches++;
-               printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
-       }
-
-       return 0;
-}
-
-static int sp8870_sleep(struct dvb_frontend* fe)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-
-       // tristate TS output and disable interface pins
-       return sp8870_writereg(state, 0xC18, 0x000);
-}
-
-static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 350;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return sp8870_writereg(state, 0x206, 0x001);
-       } else {
-               return sp8870_writereg(state, 0x206, 0x000);
-       }
-}
-
-static void sp8870_release(struct dvb_frontend* fe)
-{
-       struct sp8870_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops sp8870_ops;
-
-struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct sp8870_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-
-       /* check if the demod is there */
-       if (sp8870_readreg(state, 0x0200) < 0) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops sp8870_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Spase SP8870 DVB-T",
-               .frequency_min          = 470000000,
-               .frequency_max          = 860000000,
-               .frequency_stepsize     = 166666,
-               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
-                                         FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                                         FE_CAN_QPSK | FE_CAN_QAM_16 |
-                                         FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                                         FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
-       },
-
-       .release = sp8870_release,
-
-       .init = sp8870_init,
-       .sleep = sp8870_sleep,
-       .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
-
-       .set_frontend = sp8870_set_frontend,
-       .get_tune_settings = sp8870_get_tune_settings,
-
-       .read_status = sp8870_read_status,
-       .read_ber = sp8870_read_ber,
-       .read_signal_strength = sp8870_read_signal_strength,
-       .read_ucblocks = sp8870_read_uncorrected_blocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
-MODULE_AUTHOR("Juergen Peitz");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
deleted file mode 100644 (file)
index a764a79..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-    Driver for Spase SP8870 demodulator
-
-    Copyright (C) 1999 Juergen Peitz
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef SP8870_H
-#define SP8870_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct sp8870_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE))
-extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
-                                         struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
-                                         struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_SP8870
-
-#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
deleted file mode 100644 (file)
index f4096cc..0000000
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
-   Driver for the Spase sp887x demodulator
-*/
-
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "sp887x.h"
-
-
-struct sp887x_state {
-       struct i2c_adapter* i2c;
-       const struct sp887x_config* config;
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "sp887x: " args); \
-       } while (0)
-
-static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
-{
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               printk ("%s: i2c write error (addr %02x, err == %i)\n",
-                       __func__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
-{
-       u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
-       int ret;
-
-       if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
-               /**
-                *  in case of soft reset we ignore ACK errors...
-                */
-               if (!(reg == 0xf1a && data == 0x000 &&
-                       (ret == -EREMOTEIO || ret == -EFAULT)))
-               {
-                       printk("%s: writereg error "
-                              "(reg %03x, data %03x, ret == %i)\n",
-                              __func__, reg & 0xffff, data & 0xffff, ret);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static int sp887x_readreg (struct sp887x_state* state, u16 reg)
-{
-       u8 b0 [] = { reg >> 8 , reg & 0xff };
-       u8 b1 [2];
-       int ret;
-       struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
-                        { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
-
-       if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
-               printk("%s: readreg error (ret == %i)\n", __func__, ret);
-               return -1;
-       }
-
-       return (((b1[0] << 8) | b1[1]) & 0xfff);
-}
-
-static void sp887x_microcontroller_stop (struct sp887x_state* state)
-{
-       dprintk("%s\n", __func__);
-       sp887x_writereg(state, 0xf08, 0x000);
-       sp887x_writereg(state, 0xf09, 0x000);
-
-       /* microcontroller STOP */
-       sp887x_writereg(state, 0xf00, 0x000);
-}
-
-static void sp887x_microcontroller_start (struct sp887x_state* state)
-{
-       dprintk("%s\n", __func__);
-       sp887x_writereg(state, 0xf08, 0x000);
-       sp887x_writereg(state, 0xf09, 0x000);
-
-       /* microcontroller START */
-       sp887x_writereg(state, 0xf00, 0x001);
-}
-
-static void sp887x_setup_agc (struct sp887x_state* state)
-{
-       /* setup AGC parameters */
-       dprintk("%s\n", __func__);
-       sp887x_writereg(state, 0x33c, 0x054);
-       sp887x_writereg(state, 0x33b, 0x04c);
-       sp887x_writereg(state, 0x328, 0x000);
-       sp887x_writereg(state, 0x327, 0x005);
-       sp887x_writereg(state, 0x326, 0x001);
-       sp887x_writereg(state, 0x325, 0x001);
-       sp887x_writereg(state, 0x324, 0x001);
-       sp887x_writereg(state, 0x318, 0x050);
-       sp887x_writereg(state, 0x317, 0x3fe);
-       sp887x_writereg(state, 0x316, 0x001);
-       sp887x_writereg(state, 0x313, 0x005);
-       sp887x_writereg(state, 0x312, 0x002);
-       sp887x_writereg(state, 0x306, 0x000);
-       sp887x_writereg(state, 0x303, 0x000);
-}
-
-#define BLOCKSIZE 30
-#define FW_SIZE 0x4000
-/**
- *  load firmware and setup MPEG interface...
- */
-static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-       u8 buf [BLOCKSIZE+2];
-       int i;
-       int fw_size = fw->size;
-       const unsigned char *mem = fw->data;
-
-       dprintk("%s\n", __func__);
-
-       /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
-       if (fw_size < FW_SIZE+10)
-               return -ENODEV;
-
-       mem = fw->data + 10;
-
-       /* soft reset */
-       sp887x_writereg(state, 0xf1a, 0x000);
-
-       sp887x_microcontroller_stop (state);
-
-       printk ("%s: firmware upload... ", __func__);
-
-       /* setup write pointer to -1 (end of memory) */
-       /* bit 0x8000 in address is set to enable 13bit mode */
-       sp887x_writereg(state, 0x8f08, 0x1fff);
-
-       /* dummy write (wrap around to start of memory) */
-       sp887x_writereg(state, 0x8f0a, 0x0000);
-
-       for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
-               int c = BLOCKSIZE;
-               int err;
-
-               if (i+c > FW_SIZE)
-                       c = FW_SIZE - i;
-
-               /* bit 0x8000 in address is set to enable 13bit mode */
-               /* bit 0x4000 enables multibyte read/write transfers */
-               /* write register is 0xf0a */
-               buf[0] = 0xcf;
-               buf[1] = 0x0a;
-
-               memcpy(&buf[2], mem + i, c);
-
-               if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
-                       printk ("failed.\n");
-                       printk ("%s: i2c error (err == %i)\n", __func__, err);
-                       return err;
-               }
-       }
-
-       /* don't write RS bytes between packets */
-       sp887x_writereg(state, 0xc13, 0x001);
-
-       /* suppress clock if (!data_valid) */
-       sp887x_writereg(state, 0xc14, 0x000);
-
-       /* setup MPEG interface... */
-       sp887x_writereg(state, 0xc1a, 0x872);
-       sp887x_writereg(state, 0xc1b, 0x001);
-       sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
-       sp887x_writereg(state, 0xc1a, 0x871);
-
-       /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
-       sp887x_writereg(state, 0x301, 0x002);
-
-       sp887x_setup_agc(state);
-
-       /* bit 0x010: enable data valid signal */
-       sp887x_writereg(state, 0xd00, 0x010);
-       sp887x_writereg(state, 0x0d1, 0x000);
-       return 0;
-};
-
-static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
-{
-       int known_parameters = 1;
-
-       *reg0xc05 = 0x000;
-
-       switch (p->modulation) {
-       case QPSK:
-               break;
-       case QAM_16:
-               *reg0xc05 |= (1 << 10);
-               break;
-       case QAM_64:
-               *reg0xc05 |= (2 << 10);
-               break;
-       case QAM_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       switch (p->hierarchy) {
-       case HIERARCHY_NONE:
-               break;
-       case HIERARCHY_1:
-               *reg0xc05 |= (1 << 7);
-               break;
-       case HIERARCHY_2:
-               *reg0xc05 |= (2 << 7);
-               break;
-       case HIERARCHY_4:
-               *reg0xc05 |= (3 << 7);
-               break;
-       case HIERARCHY_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       switch (p->code_rate_HP) {
-       case FEC_1_2:
-               break;
-       case FEC_2_3:
-               *reg0xc05 |= (1 << 3);
-               break;
-       case FEC_3_4:
-               *reg0xc05 |= (2 << 3);
-               break;
-       case FEC_5_6:
-               *reg0xc05 |= (3 << 3);
-               break;
-       case FEC_7_8:
-               *reg0xc05 |= (4 << 3);
-               break;
-       case FEC_AUTO:
-               known_parameters = 0;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       if (known_parameters)
-               *reg0xc05 |= (2 << 1);  /* use specified parameters */
-       else
-               *reg0xc05 |= (1 << 1);  /* enable autoprobing */
-
-       return 0;
-}
-
-/**
- *  estimates division of two 24bit numbers,
- *  derived from the ves1820/stv0299 driver code
- */
-static void divide (int n, int d, int *quotient_i, int *quotient_f)
-{
-       unsigned int q, r;
-
-       r = (n % d) << 8;
-       q = (r / d);
-
-       if (quotient_i)
-               *quotient_i = q;
-
-       if (quotient_f) {
-               r = (r % d) << 8;
-               q = (q << 8) | (r / d);
-               r = (r % d) << 8;
-               *quotient_f = (q << 8) | (r / d);
-       }
-}
-
-static void sp887x_correct_offsets (struct sp887x_state* state,
-                                   struct dtv_frontend_properties *p,
-                                   int actual_freq)
-{
-       static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
-       int bw_index;
-       int freq_offset = actual_freq - p->frequency;
-       int sysclock = 61003; //[kHz]
-       int ifreq = 36000000;
-       int freq;
-       int frequency_shift;
-
-       switch (p->bandwidth_hz) {
-       default:
-       case 8000000:
-               bw_index = 0;
-               break;
-       case 7000000:
-               bw_index = 1;
-               break;
-       case 6000000:
-               bw_index = 2;
-               break;
-       }
-
-       if (p->inversion == INVERSION_ON)
-               freq = ifreq - freq_offset;
-       else
-               freq = ifreq + freq_offset;
-
-       divide(freq / 333, sysclock, NULL, &frequency_shift);
-
-       if (p->inversion == INVERSION_ON)
-               frequency_shift = -frequency_shift;
-
-       /* sample rate correction */
-       sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
-       sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
-
-       /* carrier offset correction */
-       sp887x_writereg(state, 0x309, frequency_shift >> 12);
-       sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
-}
-
-static int sp887x_setup_frontend_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct sp887x_state* state = fe->demodulator_priv;
-       unsigned actual_freq;
-       int err;
-       u16 val, reg0xc05;
-
-       if (p->bandwidth_hz != 8000000 &&
-           p->bandwidth_hz != 7000000 &&
-           p->bandwidth_hz != 6000000)
-               return -EINVAL;
-
-       if ((err = configure_reg0xc05(p, &reg0xc05)))
-               return err;
-
-       sp887x_microcontroller_stop(state);
-
-       /* setup the PLL */
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-       if (fe->ops.tuner_ops.get_frequency) {
-               fe->ops.tuner_ops.get_frequency(fe, &actual_freq);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       } else {
-               actual_freq = p->frequency;
-       }
-
-       /* read status reg in order to clear <pending irqs */
-       sp887x_readreg(state, 0x200);
-
-       sp887x_correct_offsets(state, p, actual_freq);
-
-       /* filter for 6/7/8 Mhz channel */
-       if (p->bandwidth_hz == 6000000)
-               val = 2;
-       else if (p->bandwidth_hz == 7000000)
-               val = 1;
-       else
-               val = 0;
-
-       sp887x_writereg(state, 0x311, val);
-
-       /* scan order: 2k first = 0, 8k first = 1 */
-       if (p->transmission_mode == TRANSMISSION_MODE_2K)
-               sp887x_writereg(state, 0x338, 0x000);
-       else
-               sp887x_writereg(state, 0x338, 0x001);
-
-       sp887x_writereg(state, 0xc05, reg0xc05);
-
-       if (p->bandwidth_hz == 6000000)
-               val = 2 << 3;
-       else if (p->bandwidth_hz == 7000000)
-               val = 3 << 3;
-       else
-               val = 0 << 3;
-
-       /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
-        * optimize algorithm for given bandwidth...
-        */
-       sp887x_writereg(state, 0xf14, 0x160 | val);
-       sp887x_writereg(state, 0xf15, 0x000);
-
-       sp887x_microcontroller_start(state);
-       return 0;
-}
-
-static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-       u16 snr12 = sp887x_readreg(state, 0xf16);
-       u16 sync0x200 = sp887x_readreg(state, 0x200);
-       u16 sync0xf17 = sp887x_readreg(state, 0xf17);
-
-       *status = 0;
-
-       if (snr12 > 0x00f)
-               *status |= FE_HAS_SIGNAL;
-
-       //if (sync0x200 & 0x004)
-       //      *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
-
-       //if (sync0x200 & 0x008)
-       //      *status |= FE_HAS_VITERBI;
-
-       if ((sync0xf17 & 0x00f) == 0x002) {
-               *status |= FE_HAS_LOCK;
-               *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
-       }
-
-       if (sync0x200 & 0x001) {        /* tuner adjustment requested...*/
-               int steps = (sync0x200 >> 4) & 0x00f;
-               if (steps & 0x008)
-                       steps = -steps;
-               dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
-                      steps);
-       }
-
-       return 0;
-}
-
-static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
-              (sp887x_readreg(state, 0xc07) << 6);
-       sp887x_writereg(state, 0xc08, 0x000);
-       sp887x_writereg(state, 0xc07, 0x000);
-       if (*ber >= 0x3fff0)
-               *ber = ~0;
-
-       return 0;
-}
-
-static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       u16 snr12 = sp887x_readreg(state, 0xf16);
-       u32 signal = 3 * (snr12 << 4);
-       *strength = (signal < 0xffff) ? signal : 0xffff;
-
-       return 0;
-}
-
-static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       u16 snr12 = sp887x_readreg(state, 0xf16);
-       *snr = (snr12 << 4) | (snr12 >> 8);
-
-       return 0;
-}
-
-static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       *ucblocks = sp887x_readreg(state, 0xc0c);
-       if (*ucblocks == 0xfff)
-               *ucblocks = ~0;
-
-       return 0;
-}
-
-static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return sp887x_writereg(state, 0x206, 0x001);
-       } else {
-               return sp887x_writereg(state, 0x206, 0x000);
-       }
-}
-
-static int sp887x_sleep(struct dvb_frontend* fe)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-
-       /* tristate TS output and disable interface pins */
-       sp887x_writereg(state, 0xc18, 0x000);
-
-       return 0;
-}
-
-static int sp887x_init(struct dvb_frontend* fe)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-       const struct firmware *fw = NULL;
-       int ret;
-
-       if (!state->initialised) {
-               /* request the firmware, this will block until someone uploads it */
-               printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
-               ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
-               if (ret) {
-                       printk("sp887x: no firmware upload (timeout or file not found?)\n");
-                       return ret;
-               }
-
-               ret = sp887x_initial_setup(fe, fw);
-               release_firmware(fw);
-               if (ret) {
-                       printk("sp887x: writing firmware to device failed\n");
-                       return ret;
-               }
-               printk("sp887x: firmware upload complete\n");
-               state->initialised = 1;
-       }
-
-       /* enable TS output and interface pins */
-       sp887x_writereg(state, 0xc18, 0x00d);
-
-       return 0;
-}
-
-static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 350;
-       fesettings->step_size = 166666*2;
-       fesettings->max_drift = (166666*2)+1;
-       return 0;
-}
-
-static void sp887x_release(struct dvb_frontend* fe)
-{
-       struct sp887x_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops sp887x_ops;
-
-struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct sp887x_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-
-       /* check if the demod is there */
-       if (sp887x_readreg(state, 0x0200) < 0) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops sp887x_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Spase SP887x DVB-T",
-               .frequency_min =  50500000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                       FE_CAN_RECOVER
-       },
-
-       .release = sp887x_release,
-
-       .init = sp887x_init,
-       .sleep = sp887x_sleep,
-       .i2c_gate_ctrl = sp887x_i2c_gate_ctrl,
-
-       .set_frontend = sp887x_setup_frontend_parameters,
-       .get_tune_settings = sp887x_get_tune_settings,
-
-       .read_status = sp887x_read_status,
-       .read_ber = sp887x_read_ber,
-       .read_signal_strength = sp887x_read_signal_strength,
-       .read_snr = sp887x_read_snr,
-       .read_ucblocks = sp887x_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
deleted file mode 100644 (file)
index 04eff6e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-   Driver for the Spase sp887x demodulator
-*/
-
-#ifndef SP887X_H
-#define SP887X_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct sp887x_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
-                                         struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
-                                         struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_SP887X
-
-#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
deleted file mode 100644 (file)
index 117a569..0000000
+++ /dev/null
@@ -1,1525 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "stb0899_drv.h"
-#include "stb0899_priv.h"
-#include "stb0899_reg.h"
-
-static inline u32 stb0899_do_div(u64 n, u32 d)
-{
-       /* wrap do_div() for ease of use */
-
-       do_div(n, d);
-       return n;
-}
-
-#if 0
-/* These functions are currently unused */
-/*
- * stb0899_calc_srate
- * Compute symbol rate
- */
-static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
-{
-       u64 tmp;
-
-       /* srate = (SFR * master_clk) >> 20 */
-
-       /* sfr is of size 20 bit, stored with an offset of 4 bit */
-       tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
-       tmp &= ~0xf;
-       tmp *= master_clk;
-       tmp >>= 24;
-
-       return tmp;
-}
-
-/*
- * stb0899_get_srate
- * Get the current symbol rate
- */
-static u32 stb0899_get_srate(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       u8 sfr[3];
-
-       stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
-
-       return stb0899_calc_srate(internal->master_clk, sfr);
-}
-#endif
-
-/*
- * stb0899_set_srate
- * Set symbol frequency
- * MasterClock: master clock frequency (hz)
- * SymbolRate: symbol rate (bauds)
- * return symbol frequency
- */
-static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
-{
-       u32 tmp;
-       u8 sfr[3];
-
-       dprintk(state->verbose, FE_DEBUG, 1, "-->");
-       /*
-        * in order to have the maximum precision, the symbol rate entered into
-        * the chip is computed as the closest value of the "true value".
-        * In this purpose, the symbol rate value is rounded (1 is added on the bit
-        * below the LSB )
-        *
-        * srate = (SFR * master_clk) >> 20
-        *      <=>
-        *   SFR = srate << 20 / master_clk
-        *
-        * rounded:
-        *   SFR = (srate << 21 + master_clk) / (2 * master_clk)
-        *
-        * stored as 20 bit number with an offset of 4 bit:
-        *   sfr = SFR << 4;
-        */
-
-       tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
-       tmp <<= 4;
-
-       sfr[0] = tmp >> 16;
-       sfr[1] = tmp >>  8;
-       sfr[2] = tmp;
-
-       stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
-
-       return srate;
-}
-
-/*
- * stb0899_calc_derot_time
- * Compute the amount of time needed by the derotator to lock
- * SymbolRate: Symbol rate
- * return: derotator time constant (ms)
- */
-static long stb0899_calc_derot_time(long srate)
-{
-       if (srate > 0)
-               return (100000 / (srate / 1000));
-       else
-               return 0;
-}
-
-/*
- * stb0899_carr_width
- * Compute the width of the carrier
- * return: width of carrier (kHz or Mhz)
- */
-long stb0899_carr_width(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-
-       return (internal->srate + (internal->srate * internal->rolloff) / 100);
-}
-
-/*
- * stb0899_first_subrange
- * Compute the first subrange of the search
- */
-static void stb0899_first_subrange(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal       = &state->internal;
-       struct stb0899_params *params           = &state->params;
-       struct stb0899_config *config           =  state->config;
-
-       int range = 0;
-       u32 bandwidth = 0;
-
-       if (config->tuner_get_bandwidth) {
-               stb0899_i2c_gate_ctrl(&state->frontend, 1);
-               config->tuner_get_bandwidth(&state->frontend, &bandwidth);
-               stb0899_i2c_gate_ctrl(&state->frontend, 0);
-               range = bandwidth - stb0899_carr_width(state) / 2;
-       }
-
-       if (range > 0)
-               internal->sub_range = min(internal->srch_range, range);
-       else
-               internal->sub_range = 0;
-
-       internal->freq = params->freq;
-       internal->tuner_offst = 0L;
-       internal->sub_dir = 1;
-}
-
-/*
- * stb0899_check_tmg
- * check for timing lock
- * internal.Ttiming: time to wait for loop lock
- */
-static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       int lock;
-       u8 reg;
-       s8 timing;
-
-       msleep(internal->t_derot);
-
-       stb0899_write_reg(state, STB0899_RTF, 0xf2);
-       reg = stb0899_read_reg(state, STB0899_TLIR);
-       lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
-       timing = stb0899_read_reg(state, STB0899_RTF);
-
-       if (lock >= 42) {
-               if ((lock > 48) && (abs(timing) >= 110)) {
-                       internal->status = ANALOGCARRIER;
-                       dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
-               } else {
-                       internal->status = TIMINGOK;
-                       dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
-               }
-       } else {
-               internal->status = NOTIMING;
-               dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
-       }
-       return internal->status;
-}
-
-/*
- * stb0899_search_tmg
- * perform a fs/2 zig-zag to find timing
- */
-static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_params *params = &state->params;
-
-       short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
-       int index = 0;
-       u8 cfr[2];
-
-       internal->status = NOTIMING;
-
-       /* timing loop computation & symbol rate optimisation   */
-       derot_limit = (internal->sub_range / 2L) / internal->mclk;
-       derot_step = (params->srate / 2L) / internal->mclk;
-
-       while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
-               index++;
-               derot_freq += index * internal->direction * derot_step; /* next derot zig zag position  */
-
-               if (abs(derot_freq) > derot_limit)
-                       next_loop--;
-
-               if (next_loop) {
-                       STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-                       STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
-                       stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency         */
-               }
-               internal->direction = -internal->direction;     /* Change zigzag direction              */
-       }
-
-       if (internal->status == TIMINGOK) {
-               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency              */
-               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
-               dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_check_carrier
- * Check for carrier found
- */
-static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       u8 reg;
-
-       msleep(internal->t_derot); /* wait for derotator ok     */
-
-       reg = stb0899_read_reg(state, STB0899_CFD);
-       STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
-       stb0899_write_reg(state, STB0899_CFD, reg);
-
-       reg = stb0899_read_reg(state, STB0899_DSTATUS);
-       dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
-       if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
-               internal->status = CARRIEROK;
-               dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
-       } else {
-               internal->status = NOCARRIER;
-               dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_search_carrier
- * Search for a QPSK carrier with the derotator
- */
-static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-
-       short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
-       int index = 0;
-       u8 cfr[2];
-       u8 reg;
-
-       internal->status = NOCARRIER;
-       derot_limit = (internal->sub_range / 2L) / internal->mclk;
-       derot_freq = internal->derot_freq;
-
-       reg = stb0899_read_reg(state, STB0899_CFD);
-       STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
-       stb0899_write_reg(state, STB0899_CFD, reg);
-
-       do {
-               dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
-               if (stb0899_check_carrier(state) == NOCARRIER) {
-                       index++;
-                       last_derot_freq = derot_freq;
-                       derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
-
-                       if(abs(derot_freq) > derot_limit)
-                               next_loop--;
-
-                       if (next_loop) {
-                               reg = stb0899_read_reg(state, STB0899_CFD);
-                               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
-                               stb0899_write_reg(state, STB0899_CFD, reg);
-
-                               STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-                               STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
-                               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
-                       }
-               }
-
-               internal->direction = -internal->direction; /* Change zigzag direction */
-       } while ((internal->status != CARRIEROK) && next_loop);
-
-       if (internal->status == CARRIEROK) {
-               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
-               dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
-       } else {
-               internal->derot_freq = last_derot_freq;
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_check_data
- * Check for data found
- */
-static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_params *params = &state->params;
-
-       int lock = 0, index = 0, dataTime = 500, loop;
-       u8 reg;
-
-       internal->status = NODATA;
-
-       /* RESET FEC    */
-       reg = stb0899_read_reg(state, STB0899_TSTRES);
-       STB0899_SETFIELD_VAL(FRESACS, reg, 1);
-       stb0899_write_reg(state, STB0899_TSTRES, reg);
-       msleep(1);
-       reg = stb0899_read_reg(state, STB0899_TSTRES);
-       STB0899_SETFIELD_VAL(FRESACS, reg, 0);
-       stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-       if (params->srate <= 2000000)
-               dataTime = 2000;
-       else if (params->srate <= 5000000)
-               dataTime = 1500;
-       else if (params->srate <= 15000000)
-               dataTime = 1000;
-       else
-               dataTime = 500;
-
-       /* clear previous failed END_LOOPVIT */
-       stb0899_read_reg(state, STB0899_VSTATUS);
-
-       stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop  */
-       while (1) {
-               /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP    */
-               reg = stb0899_read_reg(state, STB0899_VSTATUS);
-               lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
-               loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
-
-               if (lock || loop || (index > dataTime))
-                       break;
-               index++;
-       }
-
-       if (lock) {     /* DATA LOCK indicator  */
-               internal->status = DATAOK;
-               dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_search_data
- * Search for a QPSK carrier with the derotator
- */
-static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
-{
-       short int derot_freq, derot_step, derot_limit, next_loop = 3;
-       u8 cfr[2];
-       u8 reg;
-       int index = 1;
-
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_params *params = &state->params;
-
-       derot_step = (params->srate / 4L) / internal->mclk;
-       derot_limit = (internal->sub_range / 2L) / internal->mclk;
-       derot_freq = internal->derot_freq;
-
-       do {
-               if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
-
-                       derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
-                       if (abs(derot_freq) > derot_limit)
-                               next_loop--;
-
-                       if (next_loop) {
-                               dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
-                               reg = stb0899_read_reg(state, STB0899_CFD);
-                               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
-                               stb0899_write_reg(state, STB0899_CFD, reg);
-
-                               STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-                               STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
-                               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
-
-                               stb0899_check_carrier(state);
-                               index++;
-                       }
-               }
-               internal->direction = -internal->direction; /* change zig zag direction */
-       } while ((internal->status != DATAOK) && next_loop);
-
-       if (internal->status == DATAOK) {
-               stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-               internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
-               dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_check_range
- * check if the found frequency is in the correct range
- */
-static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_params *params = &state->params;
-
-       int range_offst, tp_freq;
-
-       range_offst = internal->srch_range / 2000;
-       tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
-
-       if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
-               internal->status = RANGEOK;
-               dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
-       } else {
-               internal->status = OUTOFRANGE;
-               dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
-       }
-
-       return internal->status;
-}
-
-/*
- * NextSubRange
- * Compute the next subrange of the search
- */
-static void next_sub_range(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_params *params = &state->params;
-
-       long old_sub_range;
-
-       if (internal->sub_dir > 0) {
-               old_sub_range = internal->sub_range;
-               internal->sub_range = min((internal->srch_range / 2) -
-                                         (internal->tuner_offst + internal->sub_range / 2),
-                                          internal->sub_range);
-
-               if (internal->sub_range < 0)
-                       internal->sub_range = 0;
-
-               internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
-       }
-
-       internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
-       internal->sub_dir = -internal->sub_dir;
-}
-
-/*
- * stb0899_dvbs_algo
- * Search for a signal, timing, carrier and data for a
- * given frequency in a given range
- */
-enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
-{
-       struct stb0899_params *params           = &state->params;
-       struct stb0899_internal *internal       = &state->internal;
-       struct stb0899_config *config           = state->config;
-
-       u8 bclc, reg;
-       u8 cfr[2];
-       u8 eq_const[10];
-       s32 clnI = 3;
-       u32 bandwidth = 0;
-
-       /* BETA values rated @ 99MHz    */
-       s32 betaTab[5][4] = {
-              /*  5   10   20   30MBps */
-               { 37,  34,  32,  31 }, /* QPSK 1/2      */
-               { 37,  35,  33,  31 }, /* QPSK 2/3      */
-               { 37,  35,  33,  31 }, /* QPSK 3/4      */
-               { 37,  36,  33,  32 }, /* QPSK 5/6      */
-               { 37,  36,  33,  32 }  /* QPSK 7/8      */
-       };
-
-       internal->direction = 1;
-
-       stb0899_set_srate(state, internal->master_clk, params->srate);
-       /* Carrier loop optimization versus symbol rate for acquisition*/
-       if (params->srate <= 5000000) {
-               stb0899_write_reg(state, STB0899_ACLC, 0x89);
-               bclc = stb0899_read_reg(state, STB0899_BCLC);
-               STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
-               stb0899_write_reg(state, STB0899_BCLC, bclc);
-               clnI = 0;
-       } else if (params->srate <= 15000000) {
-               stb0899_write_reg(state, STB0899_ACLC, 0xc9);
-               bclc = stb0899_read_reg(state, STB0899_BCLC);
-               STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
-               stb0899_write_reg(state, STB0899_BCLC, bclc);
-               clnI = 1;
-       } else if(params->srate <= 25000000) {
-               stb0899_write_reg(state, STB0899_ACLC, 0x89);
-               bclc = stb0899_read_reg(state, STB0899_BCLC);
-               STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
-               stb0899_write_reg(state, STB0899_BCLC, bclc);
-               clnI = 2;
-       } else {
-               stb0899_write_reg(state, STB0899_ACLC, 0xc8);
-               bclc = stb0899_read_reg(state, STB0899_BCLC);
-               STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
-               stb0899_write_reg(state, STB0899_BCLC, bclc);
-               clnI = 3;
-       }
-
-       dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
-       /* Set the timing loop to acquisition   */
-       stb0899_write_reg(state, STB0899_RTC, 0x46);
-       stb0899_write_reg(state, STB0899_CFD, 0xee);
-
-       /* !! WARNING !!
-        * Do not read any status variables while acquisition,
-        * If any needed, read before the acquisition starts
-        * querying status while acquiring causes the
-        * acquisition to go bad and hence no locks.
-        */
-       dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
-               internal->derot_percent, params->srate, internal->mclk);
-
-       /* Initial calculations */
-       internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol  */
-       internal->t_derot = stb0899_calc_derot_time(params->srate);
-       internal->t_data = 500;
-
-       dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
-       /* RESET Stream merger  */
-       reg = stb0899_read_reg(state, STB0899_TSTRES);
-       STB0899_SETFIELD_VAL(FRESRS, reg, 1);
-       stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-       /*
-        * Set KDIVIDER to an intermediate value between
-        * 1/2 and 7/8 for acquisition
-        */
-       reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
-       STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
-       stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
-
-       stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
-       stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
-
-       stb0899_first_subrange(state);
-       do {
-               /* Initialisations */
-               cfr[0] = cfr[1] = 0;
-               stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency   */
-
-               stb0899_write_reg(state, STB0899_RTF, 0);
-               reg = stb0899_read_reg(state, STB0899_CFD);
-               STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
-               stb0899_write_reg(state, STB0899_CFD, reg);
-
-               internal->derot_freq = 0;
-               internal->status = NOAGC1;
-
-               /* enable tuner I/O */
-               stb0899_i2c_gate_ctrl(&state->frontend, 1);
-
-               /* Move tuner to frequency */
-               dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
-               if (state->config->tuner_set_frequency)
-                       state->config->tuner_set_frequency(&state->frontend, internal->freq);
-
-               if (state->config->tuner_get_frequency)
-                       state->config->tuner_get_frequency(&state->frontend, &internal->freq);
-
-               msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop  */
-               dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
-               internal->status = AGC1OK;
-
-               /* There is signal in the band  */
-               if (config->tuner_get_bandwidth)
-                       config->tuner_get_bandwidth(&state->frontend, &bandwidth);
-
-               /* disable tuner I/O */
-               stb0899_i2c_gate_ctrl(&state->frontend, 0);
-
-               if (params->srate <= bandwidth / 2)
-                       stb0899_search_tmg(state); /* For low rates (SCPC)      */
-               else
-                       stb0899_check_tmg(state); /* For high rates (MCPC)      */
-
-               if (internal->status == TIMINGOK) {
-                       dprintk(state->verbose, FE_DEBUG, 1,
-                               "TIMING OK ! Derot freq=%d, mclk=%d",
-                               internal->derot_freq, internal->mclk);
-
-                       if (stb0899_search_carrier(state) == CARRIEROK) {       /* Search for carrier   */
-                               dprintk(state->verbose, FE_DEBUG, 1,
-                                       "CARRIER OK ! Derot freq=%d, mclk=%d",
-                                       internal->derot_freq, internal->mclk);
-
-                               if (stb0899_search_data(state) == DATAOK) {     /* Check for data       */
-                                       dprintk(state->verbose, FE_DEBUG, 1,
-                                               "DATA OK ! Derot freq=%d, mclk=%d",
-                                               internal->derot_freq, internal->mclk);
-
-                                       if (stb0899_check_range(state) == RANGEOK) {
-                                               dprintk(state->verbose, FE_DEBUG, 1,
-                                                       "RANGE OK ! derot freq=%d, mclk=%d",
-                                                       internal->derot_freq, internal->mclk);
-
-                                               internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
-                                               reg = stb0899_read_reg(state, STB0899_PLPARM);
-                                               internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
-                                               dprintk(state->verbose, FE_DEBUG, 1,
-                                                       "freq=%d, internal resultant freq=%d",
-                                                       params->freq, internal->freq);
-
-                                               dprintk(state->verbose, FE_DEBUG, 1,
-                                                       "internal puncture rate=%d",
-                                                       internal->fecrate);
-                                       }
-                               }
-                       }
-               }
-               if (internal->status != RANGEOK)
-                       next_sub_range(state);
-
-       } while (internal->sub_range && internal->status != RANGEOK);
-
-       /* Set the timing loop to tracking      */
-       stb0899_write_reg(state, STB0899_RTC, 0x33);
-       stb0899_write_reg(state, STB0899_CFD, 0xf7);
-       /* if locked and range ok, set Kdiv     */
-       if (internal->status == RANGEOK) {
-               dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
-               stb0899_write_reg(state, STB0899_EQON, 0x41);           /* Equalizer OFF while acquiring        */
-               stb0899_write_reg(state, STB0899_VITSYNC, 0x39);        /* SN to b'11 for acquisition           */
-
-               /*
-                * Carrier loop optimization versus
-                * symbol Rate/Puncture Rate for Tracking
-                */
-               reg = stb0899_read_reg(state, STB0899_BCLC);
-               switch (internal->fecrate) {
-               case STB0899_FEC_1_2:           /* 13   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
-                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
-                       stb0899_write_reg(state, STB0899_BCLC, reg);
-                       break;
-               case STB0899_FEC_2_3:           /* 18   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
-                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
-                       stb0899_write_reg(state, STB0899_BCLC, reg);
-                       break;
-               case STB0899_FEC_3_4:           /* 21   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
-                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
-                       stb0899_write_reg(state, STB0899_BCLC, reg);
-                       break;
-               case STB0899_FEC_5_6:           /* 24   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
-                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
-                       stb0899_write_reg(state, STB0899_BCLC, reg);
-                       break;
-               case STB0899_FEC_6_7:           /* 25   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
-                       stb0899_write_reg(state, STB0899_ACLC, 0x88);
-                       stb0899_write_reg(state, STB0899_BCLC, 0x9a);
-                       break;
-               case STB0899_FEC_7_8:           /* 26   */
-                       stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
-                       STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
-                       stb0899_write_reg(state, STB0899_BCLC, reg);
-                       break;
-               default:
-                       dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
-                       break;
-               }
-               /* release stream merger RESET  */
-               reg = stb0899_read_reg(state, STB0899_TSTRES);
-               STB0899_SETFIELD_VAL(FRESRS, reg, 0);
-               stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-               /* disable carrier detector     */
-               reg = stb0899_read_reg(state, STB0899_CFD);
-               STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
-               stb0899_write_reg(state, STB0899_CFD, reg);
-
-               stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
-       }
-
-       return internal->status;
-}
-
-/*
- * stb0899_dvbs2_config_uwp
- * Configure UWP state machine
- */
-static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_config *config = state->config;
-       u32 uwp1, uwp2, uwp3, reg;
-
-       uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
-       uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
-       uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
-
-       STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
-       STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
-       STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
-
-       STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
-       STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
-       STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
-
-       STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
-       STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
-
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
-       STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
-}
-
-/*
- * stb0899_dvbs2_config_csm_auto
- * Set CSM to AUTO mode
- */
-static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
-{
-       u32 reg;
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
-       STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
-}
-
-static long Log2Int(int number)
-{
-       int i;
-
-       i = 0;
-       while ((1 << i) <= abs(number))
-               i++;
-
-       if (number == 0)
-               i = 1;
-
-       return i - 1;
-}
-
-/*
- * stb0899_dvbs2_calc_srate
- * compute BTR_NOM_FREQ for the symbol rate
- */
-static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal       = &state->internal;
-       struct stb0899_config *config           = state->config;
-
-       u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
-       u32 master_clk, srate;
-
-       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
-       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
-       dec_rate = Log2Int(dec_ratio);
-       decim = 1 << dec_rate;
-       master_clk = internal->master_clk / 1000;
-       srate = internal->srate / 1000;
-
-       if (decim <= 4) {
-               intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
-               remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
-       } else {
-               intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
-               remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
-       }
-       btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
-
-       return btr_nom_freq;
-}
-
-/*
- * stb0899_dvbs2_calc_dev
- * compute the correction to be applied to symbol rate
- */
-static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       u32 dec_ratio, correction, master_clk, srate;
-
-       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
-       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
-
-       master_clk = internal->master_clk / 1000;       /* for integer Caculation*/
-       srate = internal->srate / 1000; /* for integer Caculation*/
-       correction = (512 * master_clk) / (2 * dec_ratio * srate);
-
-       return  correction;
-}
-
-/*
- * stb0899_dvbs2_set_srate
- * Set DVBS2 symbol rate
- */
-static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-
-       u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
-       u32 correction, freq_adj, band_lim, decim_cntrl, reg;
-       u8 anti_alias;
-
-       /*set decimation to 1*/
-       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
-       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
-       dec_rate = Log2Int(dec_ratio);
-
-       win_sel = 0;
-       if (dec_rate >= 5)
-               win_sel = dec_rate - 4;
-
-       decim = (1 << dec_rate);
-       /* (FSamp/Fsymbol *100) for integer Caculation */
-       f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
-
-       if (f_sym <= 2250)      /* don't band limit signal going into btr block*/
-               band_lim = 1;
-       else
-               band_lim = 0;   /* band limit signal going into btr block*/
-
-       decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
-
-       if (f_sym <= 3450)
-               anti_alias = 0;
-       else if (f_sym <= 4250)
-               anti_alias = 1;
-       else
-               anti_alias = 2;
-
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
-       btr_nom_freq = stb0899_dvbs2_calc_srate(state);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
-
-       correction = stb0899_dvbs2_calc_dev(state);
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
-       STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
-
-       /* scale UWP+CSM frequency to sample rate*/
-       freq_adj =  internal->srate / (internal->master_clk / 4096);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
-}
-
-/*
- * stb0899_dvbs2_set_btr_loopbw
- * set bit timing loop bandwidth as a percentage of the symbol rate
- */
-static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal       = &state->internal;
-       struct stb0899_config *config           = state->config;
-
-       u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
-       s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
-       s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
-       u32 decim, K, wn, k_direct, k_indirect;
-       u32 reg;
-
-       dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
-       dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
-       dec_rate = Log2Int(dec_ratio);
-       decim = (1 << dec_rate);
-
-       sym_peak *= 576000;
-       K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
-       K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
-
-       if (K != 0) {
-               K = sym_peak / K;
-               wn = (4 * zeta * zeta) + 1000000;
-               wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn;  /*wn =wn 10^-8*/
-
-               k_indirect = (wn * wn) / K;
-               k_indirect = k_indirect;          /*kindirect = kindirect 10^-6*/
-               k_direct   = (2 * wn * zeta) / K;       /*kDirect = kDirect 10^-2*/
-               k_direct  *= 100;
-
-               k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
-               k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
-               k_btr1 = k_direct / (1 << k_direct_shift);
-               k_btr1 /= 10000;
-
-               k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
-               k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
-               k_btr0 = k_indirect * (1 << (-k_indirect_shift));
-               k_btr0 /= 1000000;
-
-               k_btr2_rshft = 0;
-               if (k_btr0_rshft > 15) {
-                       k_btr2_rshft = k_btr0_rshft - 15;
-                       k_btr0_rshft = 15;
-               }
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
-               STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
-               STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
-               STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
-               STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
-               STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
-       } else
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
-}
-
-/*
- * stb0899_dvbs2_set_carr_freq
- * set nominal frequency for carrier search
- */
-static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
-{
-       struct stb0899_config *config = state->config;
-       s32 crl_nom_freq;
-       u32 reg;
-
-       crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
-       crl_nom_freq *= carr_freq;
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
-       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
-}
-
-/*
- * stb0899_dvbs2_init_calc
- * Initialize DVBS2 UWP, CSM, carrier and timing loops
- */
-static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       s32 steps, step_size;
-       u32 range, reg;
-
-       /* config uwp and csm */
-       stb0899_dvbs2_config_uwp(state);
-       stb0899_dvbs2_config_csm_auto(state);
-
-       /* initialize BTR       */
-       stb0899_dvbs2_set_srate(state);
-       stb0899_dvbs2_set_btr_loopbw(state);
-
-       if (internal->srate / 1000000 >= 15)
-               step_size = (1 << 17) / 5;
-       else if (internal->srate / 1000000 >= 10)
-               step_size = (1 << 17) / 7;
-       else if (internal->srate / 1000000 >= 5)
-               step_size = (1 << 17) / 10;
-       else
-               step_size = (1 << 17) / 4;
-
-       range = internal->srch_range / 1000000;
-       steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
-       steps = (steps + 6) / 10;
-       steps = (steps == 0) ? 1 : steps;
-       if (steps % 2 == 0)
-               stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
-                                          (internal->step_size * (internal->srate / 20000000)),
-                                          (internal->master_clk) / 1000000);
-       else
-               stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
-
-       /*Set Carrier Search params (zigzag, num steps and freq step size*/
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
-       STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
-       STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
-       STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
-}
-
-/*
- * stb0899_dvbs2_btr_init
- * initialize the timing loop
- */
-static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
-{
-       u32 reg;
-
-       /* set enable BTR loopback      */
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
-       STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
-       STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
-
-       /* fix btr freq accum at 0      */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
-
-       /* fix btr freq accum at 0      */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
-}
-
-/*
- * stb0899_dvbs2_reacquire
- * trigger a DVB-S2 acquisition
- */
-static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
-{
-       u32 reg = 0;
-
-       /* demod soft reset     */
-       STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
-
-       /*Reset Timing Loop     */
-       stb0899_dvbs2_btr_init(state);
-
-       /* reset Carrier loop   */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
-
-       /*release demod soft reset      */
-       reg = 0;
-       STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
-
-       /* start acquisition process    */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
-
-       /* equalizer Init       */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
-
-       /*Start equilizer       */
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
-       STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
-       STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
-       STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
-       STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
-
-       /* RESET Packet delineator      */
-       stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
-}
-
-/*
- * stb0899_dvbs2_get_dmd_status
- * get DVB-S2 Demod LOCK status
- */
-static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
-{
-       int time = -10, lock = 0, uwp, csm;
-       u32 reg;
-
-       do {
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
-               dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
-               if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
-                       dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
-               dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
-               uwp = STB0899_GETFIELD(UWP_LOCK, reg);
-               csm = STB0899_GETFIELD(CSM_LOCK, reg);
-               if (uwp && csm)
-                       lock = 1;
-
-               time += 10;
-               msleep(10);
-
-       } while ((!lock) && (time <= timeout));
-
-       if (lock) {
-               dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
-               return DVBS2_DEMOD_LOCK;
-       } else {
-               return DVBS2_DEMOD_NOLOCK;
-       }
-}
-
-/*
- * stb0899_dvbs2_get_data_lock
- * get FEC status
- */
-static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
-{
-       int time = 0, lock = 0;
-       u8 reg;
-
-       while ((!lock) && (time < timeout)) {
-               reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
-               dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
-               lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
-               time++;
-       }
-
-       return lock;
-}
-
-/*
- * stb0899_dvbs2_get_fec_status
- * get DVB-S2 FEC LOCK status
- */
-static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
-{
-       int time = 0, Locked;
-
-       do {
-               Locked = stb0899_dvbs2_get_data_lock(state, 1);
-               time++;
-               msleep(1);
-
-       } while ((!Locked) && (time < timeout));
-
-       if (Locked) {
-               dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
-               return DVBS2_FEC_LOCK;
-       } else {
-               return DVBS2_FEC_NOLOCK;
-       }
-}
-
-
-/*
- * stb0899_dvbs2_init_csm
- * set parameters for manual mode
- */
-static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
-{
-       struct stb0899_internal *internal = &state->internal;
-
-       s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
-       s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
-       u32 csm1, csm2, csm3, csm4;
-
-       if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
-               switch (modcod) {
-               case STB0899_QPSK_12:
-                       gamma_acq               = 25;
-                       gamma_rho_acq           = 2700;
-                       gamma_trk               = 12;
-                       gamma_rho_trk           = 180;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_35:
-                       gamma_acq               = 38;
-                       gamma_rho_acq           = 7182;
-                       gamma_trk               = 14;
-                       gamma_rho_trk           = 308;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_23:
-                       gamma_acq               = 42;
-                       gamma_rho_acq           = 9408;
-                       gamma_trk               = 17;
-                       gamma_rho_trk           = 476;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_34:
-                       gamma_acq               = 53;
-                       gamma_rho_acq           = 16642;
-                       gamma_trk               = 19;
-                       gamma_rho_trk           = 646;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_45:
-                       gamma_acq               = 53;
-                       gamma_rho_acq           = 17119;
-                       gamma_trk               = 22;
-                       gamma_rho_trk           = 880;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_56:
-                       gamma_acq               = 55;
-                       gamma_rho_acq           = 19250;
-                       gamma_trk               = 23;
-                       gamma_rho_trk           = 989;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_89:
-                       gamma_acq               = 60;
-                       gamma_rho_acq           = 24240;
-                       gamma_trk               = 24;
-                       gamma_rho_trk           = 1176;
-                       lock_count_thr          = 8;
-                       break;
-               case STB0899_QPSK_910:
-                       gamma_acq               = 66;
-                       gamma_rho_acq           = 29634;
-                       gamma_trk               = 24;
-                       gamma_rho_trk           = 1176;
-                       lock_count_thr          = 8;
-                       break;
-               default:
-                       gamma_acq               = 66;
-                       gamma_rho_acq           = 29634;
-                       gamma_trk               = 24;
-                       gamma_rho_trk           = 1176;
-                       lock_count_thr          = 8;
-                       break;
-               }
-
-               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
-               STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
-
-               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
-               csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
-               csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
-               csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
-
-               STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
-               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
-               STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
-               STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
-               STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
-               STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
-               STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
-               STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
-               STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
-               STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
-               STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
-
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
-       }
-}
-
-/*
- * stb0899_dvbs2_get_srate
- * get DVB-S2 Symbol Rate
- */
-static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_config *config = state->config;
-
-       u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
-       int div1, div2, rem1, rem2;
-
-       div1 = config->btr_nco_bits / 2;
-       div2 = config->btr_nco_bits - div1 - 1;
-
-       bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
-       decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
-       decimRate = (1 << decimRate);
-
-       intval1 = internal->master_clk / (1 << div1);
-       intval2 = bTrNomFreq / (1 << div2);
-
-       rem1 = internal->master_clk % (1 << div1);
-       rem2 = bTrNomFreq % (1 << div2);
-       /* only for integer calculation */
-       srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
-       srate /= decimRate;     /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
-
-       return  srate;
-}
-
-/*
- * stb0899_dvbs2_algo
- * Search for signal, timing, carrier and data for a given
- * frequency in a given range
- */
-enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       enum stb0899_modcod modcod;
-
-       s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
-       int i = 0;
-       u32 reg, csm1;
-
-       if (internal->srate <= 2000000) {
-               searchTime      = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs           */
-               FecLockTime     = 350;  /* 350  ms max time to lock FEC, SYMB <= 2Mbs                   */
-       } else if (internal->srate <= 5000000) {
-               searchTime      = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs    */
-               FecLockTime     = 170;  /* 170  ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs             */
-       } else if (internal->srate <= 10000000) {
-               searchTime      = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs    */
-               FecLockTime     = 80;   /* 80  ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs             */
-       } else if (internal->srate <= 15000000) {
-               searchTime      = 500;  /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs    */
-               FecLockTime     = 50;   /* 50  ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs            */
-       } else if (internal->srate <= 20000000) {
-               searchTime      = 300;  /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs   */
-               FecLockTime     = 30;   /* 50  ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs            */
-       } else if (internal->srate <= 25000000) {
-               searchTime      = 250;  /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs  */
-               FecLockTime     = 25;   /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs             */
-       } else {
-               searchTime      = 150;  /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs            */
-               FecLockTime     = 20;   /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs             */
-       }
-
-       /* Maintain Stream Merger in reset during acquisition   */
-       reg = stb0899_read_reg(state, STB0899_TSTRES);
-       STB0899_SETFIELD_VAL(FRESRS, reg, 1);
-       stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-       /* enable tuner I/O */
-       stb0899_i2c_gate_ctrl(&state->frontend, 1);
-
-       /* Move tuner to frequency      */
-       if (state->config->tuner_set_frequency)
-               state->config->tuner_set_frequency(&state->frontend, internal->freq);
-       if (state->config->tuner_get_frequency)
-               state->config->tuner_get_frequency(&state->frontend, &internal->freq);
-
-       /* disable tuner I/O */
-       stb0899_i2c_gate_ctrl(&state->frontend, 0);
-
-       /* Set IF AGC to acquisition    */
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
-       STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  4);
-       STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
-       STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
-
-       /* Initialisation       */
-       stb0899_dvbs2_init_calc(state);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
-       switch (internal->inversion) {
-       case IQ_SWAP_OFF:
-               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
-               break;
-       case IQ_SWAP_ON:
-               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
-               break;
-       case IQ_SWAP_AUTO:      /* use last successful search first     */
-               STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
-               break;
-       }
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
-       stb0899_dvbs2_reacquire(state);
-
-       /* Wait for demod lock (UWP and CSM)    */
-       internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
-
-       if (internal->status == DVBS2_DEMOD_LOCK) {
-               dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
-               i = 0;
-               /* Demod Locked, check FEC status       */
-               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-
-               /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
-               while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
-                       /*      Read the frequency offset*/
-                       offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
-
-                       /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
-                       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
-                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
-                       stb0899_dvbs2_reacquire(state);
-                       internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
-                       i++;
-               }
-       }
-
-       if (internal->status != DVBS2_FEC_LOCK) {
-               if (internal->inversion == IQ_SWAP_AUTO) {
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
-                       iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
-                       /* IQ Spectrum Inversion        */
-                       STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
-                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
-                       /* start acquistion process     */
-                       stb0899_dvbs2_reacquire(state);
-
-                       /* Wait for demod lock (UWP and CSM)    */
-                       internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
-                       if (internal->status == DVBS2_DEMOD_LOCK) {
-                               i = 0;
-                               /* Demod Locked, check FEC      */
-                               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-                               /*try thrice for false locks, (UWP and CSM Locked but no FEC)   */
-                               while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
-                                       /*      Read the frequency offset*/
-                                       offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
-
-                                       /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
-                                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
-                                       STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
-                                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
-
-                                       stb0899_dvbs2_reacquire(state);
-                                       internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
-                                       i++;
-                               }
-                       }
-/*
-                       if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
-                               pParams->IQLocked = !iqSpectrum;
-*/
-               }
-       }
-       if (internal->status == DVBS2_FEC_LOCK) {
-               dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
-               modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
-               pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
-
-               if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
-                     (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
-                     (pilots == 1)) {
-
-                       stb0899_dvbs2_init_csm(state, pilots, modcod);
-                       /* Wait for UWP,CSM and data LOCK 20ms max      */
-                       internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-
-                       i = 0;
-                       while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
-                               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
-                               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
-                               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
-                               csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
-                               STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
-                               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
-
-                               internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-                               i++;
-                       }
-               }
-
-               if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
-                     (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
-                     (pilots == 1)) {
-
-                       /* Equalizer Disable update      */
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
-                       STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
-                       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
-               }
-
-               /* slow down the Equalizer once locked  */
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
-               STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
-
-               /* Store signal parameters      */
-               offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
-
-               offsetfreq = offsetfreq / ((1 << 30) / 1000);
-               offsetfreq *= (internal->master_clk / 1000000);
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
-               if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
-                       offsetfreq *= -1;
-
-               internal->freq = internal->freq - offsetfreq;
-               internal->srate = stb0899_dvbs2_get_srate(state);
-
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
-               internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
-               internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
-               internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
-
-                /* Set IF AGC to tracking      */
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
-               STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg,  3);
-
-               /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
-               if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
-                       STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
-
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
-
-               reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
-               STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
-               stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
-       }
-
-       /* Release Stream Merger Reset          */
-       reg = stb0899_read_reg(state, STB0899_TSTRES);
-       STB0899_SETFIELD_VAL(FRESRS, reg, 0);
-       stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-       return internal->status;
-}
diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h
deleted file mode 100644 (file)
index 0867906..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STB0899_CFG_H
-#define __STB0899_CFG_H
-
-static const struct stb0899_s2_reg  stb0899_s2_init_2[] = {
-
-       { STB0899_OFF0_DMD_STATUS       , STB0899_BASE_DMD_STATUS       , 0x00000103 }, /* DMDSTATUS    */
-       { STB0899_OFF0_CRL_FREQ         , STB0899_BASE_CRL_FREQ         , 0x3ed1da56 }, /* CRLFREQ      */
-       { STB0899_OFF0_BTR_FREQ         , STB0899_BASE_BTR_FREQ         , 0x00004000 }, /* BTRFREQ      */
-       { STB0899_OFF0_IF_AGC_GAIN      , STB0899_BASE_IF_AGC_GAIN      , 0x00002ade }, /* IFAGCGAIN    */
-       { STB0899_OFF0_BB_AGC_GAIN      , STB0899_BASE_BB_AGC_GAIN      , 0x000001bc }, /* BBAGCGAIN    */
-       { STB0899_OFF0_DC_OFFSET        , STB0899_BASE_DC_OFFSET        , 0x00000200 }, /* DCOFFSET     */
-       { STB0899_OFF0_DMD_CNTRL        , STB0899_BASE_DMD_CNTRL        , 0x0000000f }, /* DMDCNTRL     */
-
-       { STB0899_OFF0_IF_AGC_CNTRL     , STB0899_BASE_IF_AGC_CNTRL     , 0x03fb4a20 }, /* IFAGCCNTRL   */
-       { STB0899_OFF0_BB_AGC_CNTRL     , STB0899_BASE_BB_AGC_CNTRL     , 0x00200c97 }, /* BBAGCCNTRL   */
-
-       { STB0899_OFF0_CRL_CNTRL        , STB0899_BASE_CRL_CNTRL        , 0x00000016 }, /* CRLCNTRL     */
-       { STB0899_OFF0_CRL_PHS_INIT     , STB0899_BASE_CRL_PHS_INIT     , 0x00000000 }, /* CRLPHSINIT   */
-       { STB0899_OFF0_CRL_FREQ_INIT    , STB0899_BASE_CRL_FREQ_INIT    , 0x00000000 }, /* CRLFREQINIT  */
-       { STB0899_OFF0_CRL_LOOP_GAIN    , STB0899_BASE_CRL_LOOP_GAIN    , 0x00000000 }, /* CRLLOOPGAIN  */
-       { STB0899_OFF0_CRL_NOM_FREQ     , STB0899_BASE_CRL_NOM_FREQ     , 0x3ed097b6 }, /* CRLNOMFREQ   */
-       { STB0899_OFF0_CRL_SWP_RATE     , STB0899_BASE_CRL_SWP_RATE     , 0x00000000 }, /* CRLSWPRATE   */
-       { STB0899_OFF0_CRL_MAX_SWP      , STB0899_BASE_CRL_MAX_SWP      , 0x00000000 }, /* CRLMAXSWP    */
-       { STB0899_OFF0_CRL_LK_CNTRL     , STB0899_BASE_CRL_LK_CNTRL     , 0x0f6cdc01 }, /* CRLLKCNTRL   */
-       { STB0899_OFF0_DECIM_CNTRL      , STB0899_BASE_DECIM_CNTRL      , 0x00000000 }, /* DECIMCNTRL   */
-       { STB0899_OFF0_BTR_CNTRL        , STB0899_BASE_BTR_CNTRL        , 0x00003993 }, /* BTRCNTRL     */
-       { STB0899_OFF0_BTR_LOOP_GAIN    , STB0899_BASE_BTR_LOOP_GAIN    , 0x000d3c6f }, /* BTRLOOPGAIN  */
-       { STB0899_OFF0_BTR_PHS_INIT     , STB0899_BASE_BTR_PHS_INIT     , 0x00000000 }, /* BTRPHSINIT   */
-       { STB0899_OFF0_BTR_FREQ_INIT    , STB0899_BASE_BTR_FREQ_INIT    , 0x00000000 }, /* BTRFREQINIT  */
-       { STB0899_OFF0_BTR_NOM_FREQ     , STB0899_BASE_BTR_NOM_FREQ     , 0x0238e38e }, /* BTRNOMFREQ   */
-       { STB0899_OFF0_BTR_LK_CNTRL     , STB0899_BASE_BTR_LK_CNTRL     , 0x00000000 }, /* BTRLKCNTRL   */
-       { STB0899_OFF0_DECN_CNTRL       , STB0899_BASE_DECN_CNTRL       , 0x00000000 }, /* DECNCNTRL    */
-       { STB0899_OFF0_TP_CNTRL         , STB0899_BASE_TP_CNTRL         , 0x00000000 }, /* TPCNTRL      */
-       { STB0899_OFF0_TP_BUF_STATUS    , STB0899_BASE_TP_BUF_STATUS    , 0x00000000 }, /* TPBUFSTATUS  */
-       { STB0899_OFF0_DC_ESTIM         , STB0899_BASE_DC_ESTIM         , 0x00000000 }, /* DCESTIM      */
-       { STB0899_OFF0_FLL_CNTRL        , STB0899_BASE_FLL_CNTRL        , 0x00000000 }, /* FLLCNTRL     */
-       { STB0899_OFF0_FLL_FREQ_WD      , STB0899_BASE_FLL_FREQ_WD      , 0x40070000 }, /* FLLFREQWD    */
-       { STB0899_OFF0_ANTI_ALIAS_SEL   , STB0899_BASE_ANTI_ALIAS_SEL   , 0x00000001 }, /* ANTIALIASSEL */
-       { STB0899_OFF0_RRC_ALPHA        , STB0899_BASE_RRC_ALPHA        , 0x00000002 }, /* RRCALPHA     */
-       { STB0899_OFF0_DC_ADAPT_LSHFT   , STB0899_BASE_DC_ADAPT_LSHFT   , 0x00000000 }, /* DCADAPTISHFT */
-       { STB0899_OFF0_IMB_OFFSET       , STB0899_BASE_IMB_OFFSET       , 0x0000fe01 }, /* IMBOFFSET    */
-       { STB0899_OFF0_IMB_ESTIMATE     , STB0899_BASE_IMB_ESTIMATE     , 0x00000000 }, /* IMBESTIMATE  */
-       { STB0899_OFF0_IMB_CNTRL        , STB0899_BASE_IMB_CNTRL        , 0x00000001 }, /* IMBCNTRL     */
-       { STB0899_OFF0_IF_AGC_CNTRL2    , STB0899_BASE_IF_AGC_CNTRL2    , 0x00005007 }, /* IFAGCCNTRL2  */
-       { STB0899_OFF0_DMD_CNTRL2       , STB0899_BASE_DMD_CNTRL2       , 0x00000002 }, /* DMDCNTRL2    */
-       { STB0899_OFF0_TP_BUFFER        , STB0899_BASE_TP_BUFFER        , 0x00000000 }, /* TPBUFFER     */
-       { STB0899_OFF0_TP_BUFFER1       , STB0899_BASE_TP_BUFFER1       , 0x00000000 }, /* TPBUFFER1    */
-       { STB0899_OFF0_TP_BUFFER2       , STB0899_BASE_TP_BUFFER2       , 0x00000000 }, /* TPBUFFER2    */
-       { STB0899_OFF0_TP_BUFFER3       , STB0899_BASE_TP_BUFFER3       , 0x00000000 }, /* TPBUFFER3    */
-       { STB0899_OFF0_TP_BUFFER4       , STB0899_BASE_TP_BUFFER4       , 0x00000000 }, /* TPBUFFER4    */
-       { STB0899_OFF0_TP_BUFFER5       , STB0899_BASE_TP_BUFFER5       , 0x00000000 }, /* TPBUFFER5    */
-       { STB0899_OFF0_TP_BUFFER6       , STB0899_BASE_TP_BUFFER6       , 0x00000000 }, /* TPBUFFER6    */
-       { STB0899_OFF0_TP_BUFFER7       , STB0899_BASE_TP_BUFFER7       , 0x00000000 }, /* TPBUFFER7    */
-       { STB0899_OFF0_TP_BUFFER8       , STB0899_BASE_TP_BUFFER8       , 0x00000000 }, /* TPBUFFER8    */
-       { STB0899_OFF0_TP_BUFFER9       , STB0899_BASE_TP_BUFFER9       , 0x00000000 }, /* TPBUFFER9    */
-       { STB0899_OFF0_TP_BUFFER10      , STB0899_BASE_TP_BUFFER10      , 0x00000000 }, /* TPBUFFER10   */
-       { STB0899_OFF0_TP_BUFFER11      , STB0899_BASE_TP_BUFFER11      , 0x00000000 }, /* TPBUFFER11   */
-       { STB0899_OFF0_TP_BUFFER12      , STB0899_BASE_TP_BUFFER12      , 0x00000000 }, /* TPBUFFER12   */
-       { STB0899_OFF0_TP_BUFFER13      , STB0899_BASE_TP_BUFFER13      , 0x00000000 }, /* TPBUFFER13   */
-       { STB0899_OFF0_TP_BUFFER14      , STB0899_BASE_TP_BUFFER14      , 0x00000000 }, /* TPBUFFER14   */
-       { STB0899_OFF0_TP_BUFFER15      , STB0899_BASE_TP_BUFFER15      , 0x00000000 }, /* TPBUFFER15   */
-       { STB0899_OFF0_TP_BUFFER16      , STB0899_BASE_TP_BUFFER16      , 0x0000ff00 }, /* TPBUFFER16   */
-       { STB0899_OFF0_TP_BUFFER17      , STB0899_BASE_TP_BUFFER17      , 0x00000100 }, /* TPBUFFER17   */
-       { STB0899_OFF0_TP_BUFFER18      , STB0899_BASE_TP_BUFFER18      , 0x0000fe01 }, /* TPBUFFER18   */
-       { STB0899_OFF0_TP_BUFFER19      , STB0899_BASE_TP_BUFFER19      , 0x000004fe }, /* TPBUFFER19   */
-       { STB0899_OFF0_TP_BUFFER20      , STB0899_BASE_TP_BUFFER20      , 0x0000cfe7 }, /* TPBUFFER20   */
-       { STB0899_OFF0_TP_BUFFER21      , STB0899_BASE_TP_BUFFER21      , 0x0000bec6 }, /* TPBUFFER21   */
-       { STB0899_OFF0_TP_BUFFER22      , STB0899_BASE_TP_BUFFER22      , 0x0000c2bf }, /* TPBUFFER22   */
-       { STB0899_OFF0_TP_BUFFER23      , STB0899_BASE_TP_BUFFER23      , 0x0000c1c1 }, /* TPBUFFER23   */
-       { STB0899_OFF0_TP_BUFFER24      , STB0899_BASE_TP_BUFFER24      , 0x0000c1c1 }, /* TPBUFFER24   */
-       { STB0899_OFF0_TP_BUFFER25      , STB0899_BASE_TP_BUFFER25      , 0x0000c1c1 }, /* TPBUFFER25   */
-       { STB0899_OFF0_TP_BUFFER26      , STB0899_BASE_TP_BUFFER26      , 0x0000c1c1 }, /* TPBUFFER26   */
-       { STB0899_OFF0_TP_BUFFER27      , STB0899_BASE_TP_BUFFER27      , 0x0000c1c0 }, /* TPBUFFER27   */
-       { STB0899_OFF0_TP_BUFFER28      , STB0899_BASE_TP_BUFFER28      , 0x0000c0c0 }, /* TPBUFFER28   */
-       { STB0899_OFF0_TP_BUFFER29      , STB0899_BASE_TP_BUFFER29      , 0x0000c1c1 }, /* TPBUFFER29   */
-       { STB0899_OFF0_TP_BUFFER30      , STB0899_BASE_TP_BUFFER30      , 0x0000c1c1 }, /* TPBUFFER30   */
-       { STB0899_OFF0_TP_BUFFER31      , STB0899_BASE_TP_BUFFER31      , 0x0000c0c1 }, /* TPBUFFER31   */
-       { STB0899_OFF0_TP_BUFFER32      , STB0899_BASE_TP_BUFFER32      , 0x0000c0c1 }, /* TPBUFFER32   */
-       { STB0899_OFF0_TP_BUFFER33      , STB0899_BASE_TP_BUFFER33      , 0x0000c1c1 }, /* TPBUFFER33   */
-       { STB0899_OFF0_TP_BUFFER34      , STB0899_BASE_TP_BUFFER34      , 0x0000c1c1 }, /* TPBUFFER34   */
-       { STB0899_OFF0_TP_BUFFER35      , STB0899_BASE_TP_BUFFER35      , 0x0000c0c1 }, /* TPBUFFER35   */
-       { STB0899_OFF0_TP_BUFFER36      , STB0899_BASE_TP_BUFFER36      , 0x0000c1c1 }, /* TPBUFFER36   */
-       { STB0899_OFF0_TP_BUFFER37      , STB0899_BASE_TP_BUFFER37      , 0x0000c0c1 }, /* TPBUFFER37   */
-       { STB0899_OFF0_TP_BUFFER38      , STB0899_BASE_TP_BUFFER38      , 0x0000c1c1 }, /* TPBUFFER38   */
-       { STB0899_OFF0_TP_BUFFER39      , STB0899_BASE_TP_BUFFER39      , 0x0000c0c0 }, /* TPBUFFER39   */
-       { STB0899_OFF0_TP_BUFFER40      , STB0899_BASE_TP_BUFFER40      , 0x0000c1c0 }, /* TPBUFFER40   */
-       { STB0899_OFF0_TP_BUFFER41      , STB0899_BASE_TP_BUFFER41      , 0x0000c1c1 }, /* TPBUFFER41   */
-       { STB0899_OFF0_TP_BUFFER42      , STB0899_BASE_TP_BUFFER42      , 0x0000c0c0 }, /* TPBUFFER42   */
-       { STB0899_OFF0_TP_BUFFER43      , STB0899_BASE_TP_BUFFER43      , 0x0000c1c0 }, /* TPBUFFER43   */
-       { STB0899_OFF0_TP_BUFFER44      , STB0899_BASE_TP_BUFFER44      , 0x0000c0c1 }, /* TPBUFFER44   */
-       { STB0899_OFF0_TP_BUFFER45      , STB0899_BASE_TP_BUFFER45      , 0x0000c1be }, /* TPBUFFER45   */
-       { STB0899_OFF0_TP_BUFFER46      , STB0899_BASE_TP_BUFFER46      , 0x0000c1c9 }, /* TPBUFFER46   */
-       { STB0899_OFF0_TP_BUFFER47      , STB0899_BASE_TP_BUFFER47      , 0x0000c0da }, /* TPBUFFER47   */
-       { STB0899_OFF0_TP_BUFFER48      , STB0899_BASE_TP_BUFFER48      , 0x0000c0ba }, /* TPBUFFER48   */
-       { STB0899_OFF0_TP_BUFFER49      , STB0899_BASE_TP_BUFFER49      , 0x0000c1c4 }, /* TPBUFFER49   */
-       { STB0899_OFF0_TP_BUFFER50      , STB0899_BASE_TP_BUFFER50      , 0x0000c1bf }, /* TPBUFFER50   */
-       { STB0899_OFF0_TP_BUFFER51      , STB0899_BASE_TP_BUFFER51      , 0x0000c0c1 }, /* TPBUFFER51   */
-       { STB0899_OFF0_TP_BUFFER52      , STB0899_BASE_TP_BUFFER52      , 0x0000c1c0 }, /* TPBUFFER52   */
-       { STB0899_OFF0_TP_BUFFER53      , STB0899_BASE_TP_BUFFER53      , 0x0000c0c1 }, /* TPBUFFER53   */
-       { STB0899_OFF0_TP_BUFFER54      , STB0899_BASE_TP_BUFFER54      , 0x0000c1c1 }, /* TPBUFFER54   */
-       { STB0899_OFF0_TP_BUFFER55      , STB0899_BASE_TP_BUFFER55      , 0x0000c1c1 }, /* TPBUFFER55   */
-       { STB0899_OFF0_TP_BUFFER56      , STB0899_BASE_TP_BUFFER56      , 0x0000c1c1 }, /* TPBUFFER56   */
-       { STB0899_OFF0_TP_BUFFER57      , STB0899_BASE_TP_BUFFER57      , 0x0000c1c1 }, /* TPBUFFER57   */
-       { STB0899_OFF0_TP_BUFFER58      , STB0899_BASE_TP_BUFFER58      , 0x0000c1c1 }, /* TPBUFFER58   */
-       { STB0899_OFF0_TP_BUFFER59      , STB0899_BASE_TP_BUFFER59      , 0x0000c1c1 }, /* TPBUFFER59   */
-       { STB0899_OFF0_TP_BUFFER60      , STB0899_BASE_TP_BUFFER60      , 0x0000c1c1 }, /* TPBUFFER60   */
-       { STB0899_OFF0_TP_BUFFER61      , STB0899_BASE_TP_BUFFER61      , 0x0000c1c1 }, /* TPBUFFER61   */
-       { STB0899_OFF0_TP_BUFFER62      , STB0899_BASE_TP_BUFFER62      , 0x0000c1c1 }, /* TPBUFFER62   */
-       { STB0899_OFF0_TP_BUFFER63      , STB0899_BASE_TP_BUFFER63      , 0x0000c1c0 }, /* TPBUFFER63   */
-       { STB0899_OFF0_RESET_CNTRL      , STB0899_BASE_RESET_CNTRL      , 0x00000001 }, /* RESETCNTRL   */
-       { STB0899_OFF0_ACM_ENABLE       , STB0899_BASE_ACM_ENABLE       , 0x00005654 }, /* ACMENABLE    */
-       { STB0899_OFF0_DESCR_CNTRL      , STB0899_BASE_DESCR_CNTRL      , 0x00000000 }, /* DESCRCNTRL   */
-       { STB0899_OFF0_CSM_CNTRL1       , STB0899_BASE_CSM_CNTRL1       , 0x00020019 }, /* CSMCNTRL1    */
-       { STB0899_OFF0_CSM_CNTRL2       , STB0899_BASE_CSM_CNTRL2       , 0x004b3237 }, /* CSMCNTRL2    */
-       { STB0899_OFF0_CSM_CNTRL3       , STB0899_BASE_CSM_CNTRL3       , 0x0003dd17 }, /* CSMCNTRL3    */
-       { STB0899_OFF0_CSM_CNTRL4       , STB0899_BASE_CSM_CNTRL4       , 0x00008008 }, /* CSMCNTRL4    */
-       { STB0899_OFF0_UWP_CNTRL1       , STB0899_BASE_UWP_CNTRL1       , 0x002a3106 }, /* UWPCNTRL1    */
-       { STB0899_OFF0_UWP_CNTRL2       , STB0899_BASE_UWP_CNTRL2       , 0x0006140a }, /* UWPCNTRL2    */
-       { STB0899_OFF0_UWP_STAT1        , STB0899_BASE_UWP_STAT1        , 0x00008000 }, /* UWPSTAT1     */
-       { STB0899_OFF0_UWP_STAT2        , STB0899_BASE_UWP_STAT2        , 0x00000000 }, /* UWPSTAT2     */
-       { STB0899_OFF0_DMD_STAT2        , STB0899_BASE_DMD_STAT2        , 0x00000000 }, /* DMDSTAT2     */
-       { STB0899_OFF0_FREQ_ADJ_SCALE   , STB0899_BASE_FREQ_ADJ_SCALE   , 0x00000471 }, /* FREQADJSCALE */
-       { STB0899_OFF0_UWP_CNTRL3       , STB0899_BASE_UWP_CNTRL3       , 0x017b0465 }, /* UWPCNTRL3    */
-       { STB0899_OFF0_SYM_CLK_SEL      , STB0899_BASE_SYM_CLK_SEL      , 0x00000002 }, /* SYMCLKSEL    */
-       { STB0899_OFF0_SOF_SRCH_TO      , STB0899_BASE_SOF_SRCH_TO      , 0x00196464 }, /* SOFSRCHTO    */
-       { STB0899_OFF0_ACQ_CNTRL1       , STB0899_BASE_ACQ_CNTRL1       , 0x00000603 }, /* ACQCNTRL1    */
-       { STB0899_OFF0_ACQ_CNTRL2       , STB0899_BASE_ACQ_CNTRL2       , 0x02046666 }, /* ACQCNTRL2    */
-       { STB0899_OFF0_ACQ_CNTRL3       , STB0899_BASE_ACQ_CNTRL3       , 0x10046583 }, /* ACQCNTRL3    */
-       { STB0899_OFF0_FE_SETTLE        , STB0899_BASE_FE_SETTLE        , 0x00010404 }, /* FESETTLE     */
-       { STB0899_OFF0_AC_DWELL         , STB0899_BASE_AC_DWELL         , 0x0002aa8a }, /* ACDWELL      */
-       { STB0899_OFF0_ACQUIRE_TRIG     , STB0899_BASE_ACQUIRE_TRIG     , 0x00000000 }, /* ACQUIRETRIG  */
-       { STB0899_OFF0_LOCK_LOST        , STB0899_BASE_LOCK_LOST        , 0x00000001 }, /* LOCKLOST     */
-       { STB0899_OFF0_ACQ_STAT1        , STB0899_BASE_ACQ_STAT1        , 0x00000500 }, /* ACQSTAT1     */
-       { STB0899_OFF0_ACQ_TIMEOUT      , STB0899_BASE_ACQ_TIMEOUT      , 0x0028a0a0 }, /* ACQTIMEOUT   */
-       { STB0899_OFF0_ACQ_TIME         , STB0899_BASE_ACQ_TIME         , 0x00000000 }, /* ACQTIME      */
-       { STB0899_OFF0_FINAL_AGC_CNTRL  , STB0899_BASE_FINAL_AGC_CNTRL  , 0x00800c17 }, /* FINALAGCCNTRL*/
-       { STB0899_OFF0_FINAL_AGC_GAIN   , STB0899_BASE_FINAL_AGC_GAIN   , 0x00000000 }, /* FINALAGCCGAIN*/
-       { STB0899_OFF0_EQUALIZER_INIT   , STB0899_BASE_EQUALIZER_INIT   , 0x00000000 }, /* EQUILIZERINIT*/
-       { STB0899_OFF0_EQ_CNTRL         , STB0899_BASE_EQ_CNTRL         , 0x00054802 }, /* EQCNTL       */
-       { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
-       { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
-       { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
-       { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
-       { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
-       { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
-       { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
-       { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
-       { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
-       { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
-       { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
-       { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
-       { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
-       { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
-       { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
-       { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
-       { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
-       { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
-       { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
-       { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
-       { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
-       { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
-       { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
-       { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
-       { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
-       { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
-       { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
-       { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
-       { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
-       { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
-       { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
-       { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
-       { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N  , 0x00000000 }, /* EQICOEFFSOUT10*/
-       { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
-       { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
-       { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
-       { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
-       { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
-       { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
-       { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
-       { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
-       { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
-       { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
-       { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
-       { 0xffff                        , 0xffffffff                    , 0xffffffff },
-};
-static const struct stb0899_s2_reg stb0899_s2_init_4[] = {
-       { STB0899_OFF0_BLOCK_LNGTH      , STB0899_BASE_BLOCK_LNGTH      , 0x00000008 }, /* BLOCKLNGTH   */
-       { STB0899_OFF0_ROW_STR          , STB0899_BASE_ROW_STR          , 0x000000b4 }, /* ROWSTR       */
-       { STB0899_OFF0_BN_END_ADDR      , STB0899_BASE_BN_END_ADDR      , 0x000004b5 }, /* BNANDADDR    */
-       { STB0899_OFF0_CN_END_ADDR      , STB0899_BASE_CN_END_ADDR      , 0x00000b4b }, /* CNANDADDR    */
-       { STB0899_OFF0_INFO_LENGTH      , STB0899_BASE_INFO_LENGTH      , 0x00000078 }, /* INFOLENGTH   */
-       { STB0899_OFF0_BOT_ADDR         , STB0899_BASE_BOT_ADDR         , 0x000001e0 }, /* BOT_ADDR     */
-       { STB0899_OFF0_BCH_BLK_LN       , STB0899_BASE_BCH_BLK_LN       , 0x0000a8c0 }, /* BCHBLKLN     */
-       { STB0899_OFF0_BCH_T            , STB0899_BASE_BCH_T            , 0x0000000c }, /* BCHT         */
-       { STB0899_OFF0_CNFG_MODE        , STB0899_BASE_CNFG_MODE        , 0x00000001 }, /* CNFGMODE     */
-       { STB0899_OFF0_LDPC_STAT        , STB0899_BASE_LDPC_STAT        , 0x0000000d }, /* LDPCSTAT     */
-       { STB0899_OFF0_ITER_SCALE       , STB0899_BASE_ITER_SCALE       , 0x00000040 }, /* ITERSCALE    */
-       { STB0899_OFF0_INPUT_MODE       , STB0899_BASE_INPUT_MODE       , 0x00000000 }, /* INPUTMODE    */
-       { STB0899_OFF0_LDPCDECRST       , STB0899_BASE_LDPCDECRST       , 0x00000000 }, /* LDPCDECRST   */
-       { STB0899_OFF0_CLK_PER_BYTE_RW  , STB0899_BASE_CLK_PER_BYTE_RW  , 0x00000008 }, /* CLKPERBYTE   */
-       { STB0899_OFF0_BCH_ERRORS       , STB0899_BASE_BCH_ERRORS       , 0x00000000 }, /* BCHERRORS    */
-       { STB0899_OFF0_LDPC_ERRORS      , STB0899_BASE_LDPC_ERRORS      , 0x00000000 }, /* LDPCERRORS   */
-       { STB0899_OFF0_BCH_MODE         , STB0899_BASE_BCH_MODE         , 0x00000000 }, /* BCHMODE      */
-       { STB0899_OFF0_ERR_ACC_PER      , STB0899_BASE_ERR_ACC_PER      , 0x00000008 }, /* ERRACCPER    */
-       { STB0899_OFF0_BCH_ERR_ACC      , STB0899_BASE_BCH_ERR_ACC      , 0x00000000 }, /* BCHERRACC    */
-       { STB0899_OFF0_FEC_TP_SEL       , STB0899_BASE_FEC_TP_SEL       , 0x00000000 }, /* FECTPSEL     */
-       { 0xffff                        , 0xffffffff                    , 0xffffffff },
-};
-
-static const struct stb0899_s1_reg stb0899_s1_init_5[] = {
-       { STB0899_TSTCK         , 0x00 },
-       { STB0899_TSTRES        , 0x00 },
-       { STB0899_TSTOUT        , 0x00 },
-       { STB0899_TSTIN         , 0x00 },
-       { STB0899_TSTSYS        , 0x00 },
-       { STB0899_TSTCHIP       , 0x00 },
-       { STB0899_TSTFREE       , 0x00 },
-       { STB0899_TSTI2C        , 0x00 },
-       { STB0899_BITSPEEDM     , 0x00 },
-       { STB0899_BITSPEEDL     , 0x00 },
-       { STB0899_TBUSBIT       , 0x00 },
-       { STB0899_TSTDIS        , 0x00 },
-       { STB0899_TSTDISRX      , 0x00 },
-       { STB0899_TSTJETON      , 0x00 },
-       { STB0899_TSTDCADJ      , 0x00 },
-       { STB0899_TSTAGC1       , 0x00 },
-       { STB0899_TSTAGC1N      , 0x00 },
-       { STB0899_TSTPOLYPH     , 0x00 },
-       { STB0899_TSTR          , 0x00 },
-       { STB0899_TSTAGC2       , 0x00 },
-       { STB0899_TSTCTL1       , 0x00 },
-       { STB0899_TSTCTL2       , 0x00 },
-       { STB0899_TSTCTL3       , 0x00 },
-       { STB0899_TSTDEMAP      , 0x00 },
-       { STB0899_TSTDEMAP2     , 0x00 },
-       { STB0899_TSTDEMMON     , 0x00 },
-       { STB0899_TSTRATE       , 0x00 },
-       { STB0899_TSTSELOUT     , 0x00 },
-       { STB0899_TSYNC         , 0x00 },
-       { STB0899_TSTERR        , 0x00 },
-       { STB0899_TSTRAM1       , 0x00 },
-       { STB0899_TSTVSELOUT    , 0x00 },
-       { STB0899_TSTFORCEIN    , 0x00 },
-       { STB0899_TSTRS1        , 0x00 },
-       { STB0899_TSTRS2        , 0x00 },
-       { STB0899_TSTRS3        , 0x00 },
-       { STB0899_GHOSTREG      , 0x81 },
-       { 0xffff                , 0xff },
-};
-
-#define STB0899_DVBS2_ESNO_AVE                 3
-#define STB0899_DVBS2_ESNO_QUANT               32
-#define STB0899_DVBS2_AVFRAMES_COARSE          10
-#define STB0899_DVBS2_AVFRAMES_FINE            20
-#define STB0899_DVBS2_MISS_THRESHOLD           6
-#define STB0899_DVBS2_UWP_THRESHOLD_ACQ                1125
-#define STB0899_DVBS2_UWP_THRESHOLD_TRACK      758
-#define STB0899_DVBS2_UWP_THRESHOLD_SOF                1350
-#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT       1664100
-
-#define STB0899_DVBS2_BTR_NCO_BITS             28
-#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET    15
-#define STB0899_DVBS2_CRL_NCO_BITS             30
-#define STB0899_DVBS2_LDPC_MAX_ITER            70
-
-#endif //__STB0899_CFG_H
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
deleted file mode 100644 (file)
index 5d7f8a9..0000000
+++ /dev/null
@@ -1,1651 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-#include "stb0899_drv.h"
-#include "stb0899_priv.h"
-#include "stb0899_reg.h"
-
-static unsigned int verbose = 0;//1;
-module_param(verbose, int, 0644);
-
-/* C/N in dB/10, NIRM/NIRL */
-static const struct stb0899_tab stb0899_cn_tab[] = {
-       { 200,  2600 },
-       { 190,  2700 },
-       { 180,  2860 },
-       { 170,  3020 },
-       { 160,  3210 },
-       { 150,  3440 },
-       { 140,  3710 },
-       { 130,  4010 },
-       { 120,  4360 },
-       { 110,  4740 },
-       { 100,  5190 },
-       { 90,   5670 },
-       { 80,   6200 },
-       { 70,   6770 },
-       { 60,   7360 },
-       { 50,   7970 },
-       { 40,   8250 },
-       { 30,   9000 },
-       { 20,   9450 },
-       { 15,   9600 },
-};
-
-/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
- * As measured, connected to a modulator.
- * -8.0 to -50.0 dBm directly connected,
- * -52.0 to -74.8 with extra attenuation.
- * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
- * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
- */
-static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
-       { -750, -128 },
-       { -748,  -94 },
-       { -745,  -92 },
-       { -735,  -90 },
-       { -720,  -87 },
-       { -670,  -77 },
-       { -640,  -70 },
-       { -610,  -62 },
-       { -600,  -60 },
-       { -590,  -56 },
-       { -560,  -41 },
-       { -540,  -25 },
-       { -530,  -17 },
-       { -520,  -11 },
-       { -500,    1 },
-       { -490,    6 },
-       { -480,   10 },
-       { -440,   22 },
-       { -420,   27 },
-       { -400,   31 },
-       { -380,   34 },
-       { -340,   40 },
-       { -320,   43 },
-       { -280,   48 },
-       { -250,   52 },
-       { -230,   55 },
-       { -180,   61 },
-       { -140,   66 },
-       {  -90,   73 },
-       {  -80,   74 },
-       {  500,  127 }
-};
-
-/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
- * As measured, connected to a modulator.
- * -8.0 to -50.1 dBm directly connected,
- * -53.0 to -76.6 with extra attenuation.
- * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
- * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
- */
-static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
-       {  700,     0 },
-       {  -80,  3217 },
-       { -150,  3893 },
-       { -190,  4217 },
-       { -240,  4621 },
-       { -280,  4945 },
-       { -320,  5273 },
-       { -350,  5545 },
-       { -370,  5741 },
-       { -410,  6147 },
-       { -450,  6671 },
-       { -490,  7413 },
-       { -501,  7665 },
-       { -530,  8767 },
-       { -560, 10219 },
-       { -580, 10939 },
-       { -590, 11518 },
-       { -600, 11723 },
-       { -650, 12659 },
-       { -690, 13219 },
-       { -730, 13645 },
-       { -750, 13909 },
-       { -766, 14153 },
-       { -950, 16383 }
-};
-
-/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
-static struct stb0899_tab stb0899_quant_tab[] = {
-       {    0,     0 },
-       {    0,   100 },
-       {  600,   200 },
-       {  950,   299 },
-       { 1200,   398 },
-       { 1400,   501 },
-       { 1560,   603 },
-       { 1690,   700 },
-       { 1810,   804 },
-       { 1910,   902 },
-       { 2000,  1000 },
-       { 2080,  1096 },
-       { 2160,  1202 },
-       { 2230,  1303 },
-       { 2350,  1496 },
-       { 2410,  1603 },
-       { 2460,  1698 },
-       { 2510,  1799 },
-       { 2600,  1995 },
-       { 2650,  2113 },
-       { 2690,  2213 },
-       { 2720,  2291 },
-       { 2760,  2399 },
-       { 2800,  2512 },
-       { 2860,  2692 },
-       { 2930,  2917 },
-       { 2960,  3020 },
-       { 3010,  3199 },
-       { 3040,  3311 },
-       { 3060,  3388 },
-       { 3120,  3631 },
-       { 3190,  3936 },
-       { 3400,  5012 },
-       { 3610,  6383 },
-       { 3800,  7943 },
-       { 4210, 12735 },
-       { 4500, 17783 },
-       { 4690, 22131 },
-       { 4810, 25410 }
-};
-
-/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
-static struct stb0899_tab stb0899_est_tab[] = {
-       {    0,      0 },
-       {    0,      1 },
-       {  301,      2 },
-       { 1204,     16 },
-       { 1806,     64 },
-       { 2408,    256 },
-       { 2709,    512 },
-       { 3010,   1023 },
-       { 3311,   2046 },
-       { 3612,   4093 },
-       { 3823,   6653 },
-       { 3913,   8185 },
-       { 4010,  10233 },
-       { 4107,  12794 },
-       { 4214,  16368 },
-       { 4266,  18450 },
-       { 4311,  20464 },
-       { 4353,  22542 },
-       { 4391,  24604 },
-       { 4425,  26607 },
-       { 4457,  28642 },
-       { 4487,  30690 },
-       { 4515,  32734 },
-       { 4612,  40926 },
-       { 4692,  49204 },
-       { 4816,  65464 },
-       { 4913,  81846 },
-       { 4993,  98401 },
-       { 5060, 114815 },
-       { 5118, 131220 },
-       { 5200, 158489 },
-       { 5300, 199526 },
-       { 5400, 251189 },
-       { 5500, 316228 },
-       { 5600, 398107 },
-       { 5720, 524807 },
-       { 5721, 526017 },
-};
-
-static int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
-{
-       int ret;
-
-       u8 b0[] = { reg >> 8, reg & 0xff };
-       u8 buf;
-
-       struct i2c_msg msg[] = {
-               {
-                       .addr   = state->config->demod_address,
-                       .flags  = 0,
-                       .buf    = b0,
-                       .len    = 2
-               },{
-                       .addr   = state->config->demod_address,
-                       .flags  = I2C_M_RD,
-                       .buf    = &buf,
-                       .len    = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2) {
-               if (ret != -ERESTARTSYS)
-                       dprintk(state->verbose, FE_ERROR, 1,
-                               "Read error, Reg=[0x%02x], Status=%d",
-                               reg, ret);
-
-               return ret < 0 ? ret : -EREMOTEIO;
-       }
-       if (unlikely(*state->verbose >= FE_DEBUGREG))
-               dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
-                       reg, buf);
-
-       return (unsigned int)buf;
-}
-
-int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
-{
-       int result;
-
-       result = _stb0899_read_reg(state, reg);
-       /*
-        * Bug ID 9:
-        * access to 0xf2xx/0xf6xx
-        * must be followed by read from 0xf2ff/0xf6ff.
-        */
-       if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
-           (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
-               _stb0899_read_reg(state, (reg | 0x00ff));
-
-       return result;
-}
-
-u32 _stb0899_read_s2reg(struct stb0899_state *state,
-                       u32 stb0899_i2cdev,
-                       u32 stb0899_base_addr,
-                       u16 stb0899_reg_offset)
-{
-       int status;
-       u32 data;
-       u8 buf[7] = { 0 };
-       u16 tmpaddr;
-
-       u8 buf_0[] = {
-               GETBYTE(stb0899_i2cdev, BYTE1),         /* 0xf3 S2 Base Address (MSB)   */
-               GETBYTE(stb0899_i2cdev, BYTE0),         /* 0xfc S2 Base Address (LSB)   */
-               GETBYTE(stb0899_base_addr, BYTE0),      /* 0x00 Base Address (LSB)      */
-               GETBYTE(stb0899_base_addr, BYTE1),      /* 0x04 Base Address (LSB)      */
-               GETBYTE(stb0899_base_addr, BYTE2),      /* 0x00 Base Address (MSB)      */
-               GETBYTE(stb0899_base_addr, BYTE3),      /* 0x00 Base Address (MSB)      */
-       };
-       u8 buf_1[] = {
-               0x00,   /* 0xf3 Reg Offset      */
-               0x00,   /* 0x44 Reg Offset      */
-       };
-
-       struct i2c_msg msg_0 = {
-               .addr   = state->config->demod_address,
-               .flags  = 0,
-               .buf    = buf_0,
-               .len    = 6
-       };
-
-       struct i2c_msg msg_1 = {
-               .addr   = state->config->demod_address,
-               .flags  = 0,
-               .buf    = buf_1,
-               .len    = 2
-       };
-
-       struct i2c_msg msg_r = {
-               .addr   = state->config->demod_address,
-               .flags  = I2C_M_RD,
-               .buf    = buf,
-               .len    = 4
-       };
-
-       tmpaddr = stb0899_reg_offset & 0xff00;
-       if (!(stb0899_reg_offset & 0x8))
-               tmpaddr = stb0899_reg_offset | 0x20;
-
-       buf_1[0] = GETBYTE(tmpaddr, BYTE1);
-       buf_1[1] = GETBYTE(tmpaddr, BYTE0);
-
-       status = i2c_transfer(state->i2c, &msg_0, 1);
-       if (status < 1) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
-                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
-
-               goto err;
-       }
-
-       /* Dummy        */
-       status = i2c_transfer(state->i2c, &msg_1, 1);
-       if (status < 1)
-               goto err;
-
-       status = i2c_transfer(state->i2c, &msg_r, 1);
-       if (status < 1)
-               goto err;
-
-       buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
-       buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
-
-       /* Actual       */
-       status = i2c_transfer(state->i2c, &msg_1, 1);
-       if (status < 1) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
-                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
-               goto err;
-       }
-
-       status = i2c_transfer(state->i2c, &msg_r, 1);
-       if (status < 1) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
-                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
-               return status < 0 ? status : -EREMOTEIO;
-       }
-
-       data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
-       if (unlikely(*state->verbose >= FE_DEBUGREG))
-               printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
-                      __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
-
-       return data;
-
-err:
-       return status < 0 ? status : -EREMOTEIO;
-}
-
-int stb0899_write_s2reg(struct stb0899_state *state,
-                       u32 stb0899_i2cdev,
-                       u32 stb0899_base_addr,
-                       u16 stb0899_reg_offset,
-                       u32 stb0899_data)
-{
-       int status;
-
-       /* Base Address Setup   */
-       u8 buf_0[] = {
-               GETBYTE(stb0899_i2cdev, BYTE1),         /* 0xf3 S2 Base Address (MSB)   */
-               GETBYTE(stb0899_i2cdev, BYTE0),         /* 0xfc S2 Base Address (LSB)   */
-               GETBYTE(stb0899_base_addr, BYTE0),      /* 0x00 Base Address (LSB)      */
-               GETBYTE(stb0899_base_addr, BYTE1),      /* 0x04 Base Address (LSB)      */
-               GETBYTE(stb0899_base_addr, BYTE2),      /* 0x00 Base Address (MSB)      */
-               GETBYTE(stb0899_base_addr, BYTE3),      /* 0x00 Base Address (MSB)      */
-       };
-       u8 buf_1[] = {
-               0x00,   /* 0xf3 Reg Offset      */
-               0x00,   /* 0x44 Reg Offset      */
-               0x00,   /* data                 */
-               0x00,   /* data                 */
-               0x00,   /* data                 */
-               0x00,   /* data                 */
-       };
-
-       struct i2c_msg msg_0 = {
-               .addr   = state->config->demod_address,
-               .flags  = 0,
-               .buf    = buf_0,
-               .len    = 6
-       };
-
-       struct i2c_msg msg_1 = {
-               .addr   = state->config->demod_address,
-               .flags  = 0,
-               .buf    = buf_1,
-               .len    = 6
-       };
-
-       buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
-       buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
-       buf_1[2] = GETBYTE(stb0899_data, BYTE0);
-       buf_1[3] = GETBYTE(stb0899_data, BYTE1);
-       buf_1[4] = GETBYTE(stb0899_data, BYTE2);
-       buf_1[5] = GETBYTE(stb0899_data, BYTE3);
-
-       if (unlikely(*state->verbose >= FE_DEBUGREG))
-               printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
-                      __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
-
-       status = i2c_transfer(state->i2c, &msg_0, 1);
-       if (unlikely(status < 1)) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
-                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
-               goto err;
-       }
-       status = i2c_transfer(state->i2c, &msg_1, 1);
-       if (unlikely(status < 1)) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
-                              __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
-
-               return status < 0 ? status : -EREMOTEIO;
-       }
-
-       return 0;
-
-err:
-       return status < 0 ? status : -EREMOTEIO;
-}
-
-int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count)
-{
-       int status;
-
-       u8 b0[] = { reg >> 8, reg & 0xff };
-
-       struct i2c_msg msg[] = {
-               {
-                       .addr   = state->config->demod_address,
-                       .flags  = 0,
-                       .buf    = b0,
-                       .len    = 2
-               },{
-                       .addr   = state->config->demod_address,
-                       .flags  = I2C_M_RD,
-                       .buf    = buf,
-                       .len    = count
-               }
-       };
-
-       status = i2c_transfer(state->i2c, msg, 2);
-       if (status != 2) {
-               if (status != -ERESTARTSYS)
-                       printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
-                              __func__, reg, count, status);
-               goto err;
-       }
-       /*
-        * Bug ID 9:
-        * access to 0xf2xx/0xf6xx
-        * must be followed by read from 0xf2ff/0xf6ff.
-        */
-       if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
-           (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
-               _stb0899_read_reg(state, (reg | 0x00ff));
-
-       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
-               int i;
-
-               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
-               for (i = 0; i < count; i++) {
-                       printk(" %02x", buf[i]);
-               }
-               printk("\n");
-       }
-
-       return 0;
-err:
-       return status < 0 ? status : -EREMOTEIO;
-}
-
-int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count)
-{
-       int ret;
-       u8 buf[2 + count];
-       struct i2c_msg i2c_msg = {
-               .addr   = state->config->demod_address,
-               .flags  = 0,
-               .buf    = buf,
-               .len    = 2 + count
-       };
-
-       buf[0] = reg >> 8;
-       buf[1] = reg & 0xff;
-       memcpy(&buf[2], data, count);
-
-       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
-               int i;
-
-               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
-               for (i = 0; i < count; i++)
-                       printk(" %02x", data[i]);
-               printk("\n");
-       }
-       ret = i2c_transfer(state->i2c, &i2c_msg, 1);
-
-       /*
-        * Bug ID 9:
-        * access to 0xf2xx/0xf6xx
-        * must be followed by read from 0xf2ff/0xf6ff.
-        */
-       if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
-               stb0899_read_reg(state, (reg | 0x00ff));
-
-       if (ret != 1) {
-               if (ret != -ERESTARTSYS)
-                       dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
-                               reg, data[0], count, ret);
-               return ret < 0 ? ret : -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
-{
-       return stb0899_write_regs(state, reg, &data, 1);
-}
-
-/*
- * stb0899_get_mclk
- * Get STB0899 master clock frequency
- * ExtClk: external clock frequency (Hz)
- */
-static u32 stb0899_get_mclk(struct stb0899_state *state)
-{
-       u32 mclk = 0, div = 0;
-
-       div = stb0899_read_reg(state, STB0899_NCOARSE);
-       mclk = (div + 1) * state->config->xtal_freq / 6;
-       dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
-
-       return mclk;
-}
-
-/*
- * stb0899_set_mclk
- * Set STB0899 master Clock frequency
- * Mclk: demodulator master clock
- * ExtClk: external clock frequency (Hz)
- */
-static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
-{
-       struct stb0899_internal *internal = &state->internal;
-       u8 mdiv = 0;
-
-       dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config);
-       mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
-       dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
-
-       stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
-       internal->master_clk = stb0899_get_mclk(state);
-
-       dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
-}
-
-static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
-{
-       struct stb0899_config *config           = state->config;
-       const struct stb0899_postproc *postproc = config->postproc;
-
-       /* post process event */
-       if (postproc) {
-               if (enable) {
-                       if (postproc[ctl].level == STB0899_GPIOPULLUP)
-                               stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
-                       else
-                               stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
-               } else {
-                       if (postproc[ctl].level == STB0899_GPIOPULLUP)
-                               stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
-                       else
-                               stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
-               }
-       }
-       return 0;
-}
-
-static void stb0899_release(struct dvb_frontend *fe)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-
-       dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
-       /* post process event */
-       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
-       kfree(state);
-}
-
-/*
- * stb0899_get_alpha
- * return: rolloff
- */
-static int stb0899_get_alpha(struct stb0899_state *state)
-{
-       u8 mode_coeff;
-
-       mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
-
-       if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
-               return 20;
-       else
-               return 35;
-}
-
-/*
- * stb0899_init_calc
- */
-static void stb0899_init_calc(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       int master_clk;
-       u8 agc[2];
-       u32 reg;
-
-       /* Read registers (in burst mode)       */
-       stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O   */
-
-       /* Initial calculations */
-       master_clk                      = stb0899_get_mclk(state);
-       internal->t_agc1                = 0;
-       internal->t_agc2                = 0;
-       internal->master_clk            = master_clk;
-       internal->mclk                  = master_clk / 65536L;
-       internal->rolloff               = stb0899_get_alpha(state);
-
-       /* DVBS2 Initial calculations   */
-       /* Set AGC value to the middle  */
-       internal->agc_gain              = 8154;
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
-       STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
-       stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
-
-       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
-       internal->rrc_alpha             = STB0899_GETFIELD(RRC_ALPHA, reg);
-
-       internal->center_freq           = 0;
-       internal->av_frame_coarse       = 10;
-       internal->av_frame_fine         = 20;
-       internal->step_size             = 2;
-/*
-       if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
-               pParams->IQLocked = 0;
-       else
-               pParams->IQLocked = 1;
-*/
-}
-
-static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
-{
-       u8 reg = 0;
-       unsigned long start = jiffies;
-
-       while (1) {
-               reg = stb0899_read_reg(state, STB0899_DISSTATUS);
-               if (!STB0899_GETFIELD(FIFOFULL, reg))
-                       break;
-               if ((jiffies - start) > timeout) {
-                       dprintk(state->verbose, FE_ERROR, 1, "timed out !!");
-                       return -ETIMEDOUT;
-               }
-       }
-
-       return 0;
-}
-
-static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-       u8 reg, i;
-
-       if (cmd->msg_len > 8)
-               return -EINVAL;
-
-       /* enable FIFO precharge        */
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-       for (i = 0; i < cmd->msg_len; i++) {
-               /* wait for FIFO empty  */
-               if (stb0899_wait_diseqc_fifo_empty(state, 100) < 0)
-                       return -ETIMEDOUT;
-
-               stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
-       }
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-       msleep(100);
-       return 0;
-}
-
-static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
-{
-       u8 reg = 0;
-       unsigned long start = jiffies;
-
-       while (!STB0899_GETFIELD(RXEND, reg)) {
-               reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
-               if (jiffies - start > timeout) {
-                       dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
-                       return -ETIMEDOUT;
-               }
-               msleep(10);
-       }
-
-       return 0;
-}
-
-static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-       u8 reg, length = 0, i;
-       int result;
-
-       if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
-       if (STB0899_GETFIELD(RXEND, reg)) {
-
-               reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
-               length = STB0899_GETFIELD(FIFOBYTENBR, reg);
-
-               if (length > sizeof (reply->msg)) {
-                       result = -EOVERFLOW;
-                       goto exit;
-               }
-               reply->msg_len = length;
-
-               /* extract data */
-               for (i = 0; i < length; i++)
-                       reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
-       }
-
-       return 0;
-exit:
-
-       return result;
-}
-
-static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
-{
-       u8 reg = 0;
-       unsigned long start = jiffies;
-
-       while (!STB0899_GETFIELD(TXIDLE, reg)) {
-               reg = stb0899_read_reg(state, STB0899_DISSTATUS);
-               if (jiffies - start > timeout) {
-                       dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
-                       return -ETIMEDOUT;
-               }
-               msleep(10);
-       }
-       return 0;
-}
-
-static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-       u8 reg, old_state;
-
-       /* wait for diseqc idle */
-       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       old_state = reg;
-       /* set to burst mode    */
-       STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03);
-       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-       switch (burst) {
-       case SEC_MINI_A:
-               /* unmodulated  */
-               stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
-               break;
-       case SEC_MINI_B:
-               /* modulated    */
-               stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
-               break;
-       }
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-       /* wait for diseqc idle */
-       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       /* restore state        */
-       stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
-
-       return 0;
-}
-
-static int stb0899_diseqc_init(struct stb0899_state *state)
-{
-/*
-       struct dvb_diseqc_slave_reply rx_data;
-*/
-       u8 f22_tx, reg;
-
-       u32 mclk, tx_freq = 22000;/* count = 0, i; */
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
-       STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
-       stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
-
-       /* disable Tx spy       */
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-
-       reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
-       STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
-       stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-
-       mclk = stb0899_get_mclk(state);
-       f22_tx = mclk / (tx_freq * 32);
-       stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq     */
-       state->rx_freq = 20000;
-
-       return 0;
-}
-
-static int stb0899_sleep(struct dvb_frontend *fe)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-/*
-       u8 reg;
-*/
-       dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
-       /* post process event */
-       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
-
-       return 0;
-}
-
-static int stb0899_wakeup(struct dvb_frontend *fe)
-{
-       int rc;
-       struct stb0899_state *state = fe->demodulator_priv;
-
-       if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
-               return rc;
-       /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
-       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
-               return rc;
-       if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
-               return rc;
-
-       /* post process event */
-       stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1);
-
-       return 0;
-}
-
-static int stb0899_init(struct dvb_frontend *fe)
-{
-       int i;
-       struct stb0899_state *state = fe->demodulator_priv;
-       struct stb0899_config *config = state->config;
-
-       dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
-
-       /* init device          */
-       dprintk(state->verbose, FE_DEBUG, 1, "init device");
-       for (i = 0; config->init_dev[i].address != 0xffff; i++)
-               stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
-
-       dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod");
-       /* init S2 demod        */
-       for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
-               stb0899_write_s2reg(state, STB0899_S2DEMOD,
-                                   config->init_s2_demod[i].base_address,
-                                   config->init_s2_demod[i].offset,
-                                   config->init_s2_demod[i].data);
-
-       dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod");
-       /* init S1 demod        */
-       for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
-               stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
-
-       dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC");
-       /* init S2 fec          */
-       for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
-               stb0899_write_s2reg(state, STB0899_S2FEC,
-                                   config->init_s2_fec[i].base_address,
-                                   config->init_s2_fec[i].offset,
-                                   config->init_s2_fec[i].data);
-
-       dprintk(state->verbose, FE_DEBUG, 1, "init TST");
-       /* init test            */
-       for (i = 0; config->init_tst[i].address != 0xffff; i++)
-               stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
-
-       stb0899_init_calc(state);
-       stb0899_diseqc_init(state);
-
-       return 0;
-}
-
-static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
-{
-       int res = 0;
-       int min = 0, med;
-
-       if (val < tab[min].read)
-               res = tab[min].real;
-       else if (val >= tab[max].read)
-               res = tab[max].real;
-       else {
-               while ((max - min) > 1) {
-                       med = (max + min) / 2;
-                       if (val >= tab[min].read && val < tab[med].read)
-                               max = med;
-                       else
-                               min = med;
-               }
-               res = ((val - tab[min].read) *
-                      (tab[max].real - tab[min].real) /
-                      (tab[max].read - tab[min].read)) +
-                       tab[min].real;
-       }
-
-       return res;
-}
-
-static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct stb0899_state *state             = fe->demodulator_priv;
-       struct stb0899_internal *internal       = &state->internal;
-
-       int val;
-       u32 reg;
-       *strength = 0;
-       switch (state->delsys) {
-       case SYS_DVBS:
-       case SYS_DSS:
-               if (internal->lock) {
-                       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
-                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
-
-                               reg = stb0899_read_reg(state, STB0899_AGCIQIN);
-                               val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
-
-                               *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
-                               *strength += 750;
-                               dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
-                                       val & 0xff, *strength);
-                       }
-               }
-               break;
-       case SYS_DVBS2:
-               if (internal->lock) {
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_GAIN);
-                       val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
-
-                       *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
-                       *strength += 950;
-                       dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
-                               val & 0x3fff, *strength);
-               }
-               break;
-       default:
-               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct stb0899_state *state             = fe->demodulator_priv;
-       struct stb0899_internal *internal       = &state->internal;
-
-       unsigned int val, quant, quantn = -1, est, estn = -1;
-       u8 buf[2];
-       u32 reg;
-
-       *snr = 0;
-       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
-       switch (state->delsys) {
-       case SYS_DVBS:
-       case SYS_DSS:
-               if (internal->lock) {
-                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
-
-                               stb0899_read_regs(state, STB0899_NIRM, buf, 2);
-                               val = MAKEWORD16(buf[0], buf[1]);
-
-                               *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
-                               dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
-                                       buf[0], buf[1], val, *snr);
-                       }
-               }
-               break;
-       case SYS_DVBS2:
-               if (internal->lock) {
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
-                       quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
-                       est = STB0899_GETFIELD(ESN0_EST, reg);
-                       if (est == 1)
-                               val = 301; /* C/N = 30.1 dB */
-                       else if (est == 2)
-                               val = 270; /* C/N = 27.0 dB */
-                       else {
-                               /* quantn = 100 * log(quant^2) */
-                               quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
-                               /* estn = 100 * log(est) */
-                               estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
-                               /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
-                               val = (quantn - estn) / 10;
-                       }
-                       *snr = val;
-                       dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
-                               quant, quantn, est, estn, val);
-               }
-               break;
-       default:
-               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
-       struct stb0899_state *state             = fe->demodulator_priv;
-       struct stb0899_internal *internal       = &state->internal;
-       u8 reg;
-       *status = 0;
-
-       switch (state->delsys) {
-       case SYS_DVBS:
-       case SYS_DSS:
-               dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
-               if (internal->lock) {
-                       reg  = stb0899_read_reg(state, STB0899_VSTATUS);
-                       if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
-                               dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
-                               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
-
-                               reg = stb0899_read_reg(state, STB0899_PLPARM);
-                               if (STB0899_GETFIELD(VITCURPUN, reg)) {
-                                       dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
-                                       *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
-                                       /* post process event */
-                                       stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
-                               }
-                       }
-               }
-               break;
-       case SYS_DVBS2:
-               dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
-               if (internal->lock) {
-                       reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
-                       if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
-                               *status |= FE_HAS_CARRIER;
-                               dprintk(state->verbose, FE_DEBUG, 1,
-                                       "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
-
-                               reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
-                               if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
-                                       *status |= FE_HAS_LOCK;
-                                       dprintk(state->verbose, FE_DEBUG, 1,
-                                               "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
-
-                               }
-                               if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
-                                       *status |= FE_HAS_VITERBI;
-                                       dprintk(state->verbose, FE_DEBUG, 1,
-                                               "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
-                               }
-                               if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
-                                       *status |= FE_HAS_SYNC;
-                                       dprintk(state->verbose, FE_DEBUG, 1,
-                                               "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
-                                       /* post process event */
-                                       stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
-                               }
-                       }
-               }
-               break;
-       default:
-               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-/*
- * stb0899_get_error
- * viterbi error for DVB-S/DSS
- * packet error for DVB-S2
- * Bit Error Rate or Packet Error Rate * 10 ^ 7
- */
-static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct stb0899_state *state             = fe->demodulator_priv;
-       struct stb0899_internal *internal       = &state->internal;
-
-       u8  lsb, msb;
-
-       *ber = 0;
-
-       switch (state->delsys) {
-       case SYS_DVBS:
-       case SYS_DSS:
-               if (internal->lock) {
-                       lsb = stb0899_read_reg(state, STB0899_ECNT1L);
-                       msb = stb0899_read_reg(state, STB0899_ECNT1M);
-                       *ber = MAKEWORD16(msb, lsb);
-                       /* Viterbi Check        */
-                       if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
-                               /* Error Rate           */
-                               *ber *= 9766;
-                               /* ber = ber * 10 ^ 7   */
-                               *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
-                               *ber /= 8;
-                       }
-               }
-               break;
-       case SYS_DVBS2:
-               if (internal->lock) {
-                       lsb = stb0899_read_reg(state, STB0899_ECNT1L);
-                       msb = stb0899_read_reg(state, STB0899_ECNT1M);
-                       *ber = MAKEWORD16(msb, lsb);
-                       /* ber = ber * 10 ^ 7   */
-                       *ber *= 10000000;
-                       *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
-               }
-               break;
-       default:
-               dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
-               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
-               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
-               break;
-       case SEC_VOLTAGE_18:
-               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
-               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
-               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
-               break;
-       case SEC_VOLTAGE_OFF:
-               stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
-               stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
-               stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-       struct stb0899_internal *internal = &state->internal;
-
-       u8 div, reg;
-
-       /* wait for diseqc idle */
-       if (stb0899_wait_diseqc_txidle(state, 100) < 0)
-               return -ETIMEDOUT;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               div = (internal->master_clk / 100) / 5632;
-               div = (div + 5) / 10;
-               stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
-               reg = stb0899_read_reg(state, STB0899_ACRPRESC);
-               STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
-               stb0899_write_reg(state, STB0899_ACRPRESC, reg);
-               stb0899_write_reg(state, STB0899_ACRDIV1, div);
-               break;
-       case SEC_TONE_OFF:
-               stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       int i2c_stat;
-       struct stb0899_state *state = fe->demodulator_priv;
-
-       i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
-       if (i2c_stat < 0)
-               goto err;
-
-       if (enable) {
-               dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
-               i2c_stat |=  STB0899_I2CTON;
-               if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
-                       goto err;
-       } else {
-               dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
-               i2c_stat &= ~STB0899_I2CTON;
-               if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
-                       goto err;
-       }
-       return 0;
-err:
-       dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
-       return -EREMOTEIO;
-}
-
-
-static inline void CONVERT32(u32 x, char *str)
-{
-       *str++  = (x >> 24) & 0xff;
-       *str++  = (x >> 16) & 0xff;
-       *str++  = (x >>  8) & 0xff;
-       *str++  = (x >>  0) & 0xff;
-       *str    = '\0';
-}
-
-int stb0899_get_dev_id(struct stb0899_state *state)
-{
-       u8 chip_id, release;
-       u16 id;
-       u32 demod_ver = 0, fec_ver = 0;
-       char demod_str[5] = { 0 };
-       char fec_str[5] = { 0 };
-
-       id = stb0899_read_reg(state, STB0899_DEV_ID);
-       dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
-       chip_id = STB0899_GETFIELD(CHIP_ID, id);
-       release = STB0899_GETFIELD(CHIP_REL, id);
-
-       dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
-               chip_id, release);
-
-       CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
-
-       demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
-       dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
-       CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
-       fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
-       if (! (chip_id > 0)) {
-               dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
-
-               return -ENODEV;
-       }
-       dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
-
-       return 0;
-}
-
-static void stb0899_set_delivery(struct stb0899_state *state)
-{
-       u8 reg;
-       u8 stop_clk[2];
-
-       stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
-       stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
-
-       switch (state->delsys) {
-       case SYS_DVBS:
-               dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
-               /* FECM/Viterbi ON      */
-               reg = stb0899_read_reg(state, STB0899_FECM);
-               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
-               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
-               stb0899_write_reg(state, STB0899_FECM, reg);
-
-               stb0899_write_reg(state, STB0899_RSULC, 0xb1);
-               stb0899_write_reg(state, STB0899_TSULC, 0x40);
-               stb0899_write_reg(state, STB0899_RSLLC, 0x42);
-               stb0899_write_reg(state, STB0899_TSLPL, 0x12);
-
-               reg = stb0899_read_reg(state, STB0899_TSTRES);
-               STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
-               stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
-
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
-
-               STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
-
-               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
-               break;
-       case SYS_DVBS2:
-               /* FECM/Viterbi OFF     */
-               reg = stb0899_read_reg(state, STB0899_FECM);
-               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
-               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
-               stb0899_write_reg(state, STB0899_FECM, reg);
-
-               stb0899_write_reg(state, STB0899_RSULC, 0xb1);
-               stb0899_write_reg(state, STB0899_TSULC, 0x42);
-               stb0899_write_reg(state, STB0899_RSLLC, 0x40);
-               stb0899_write_reg(state, STB0899_TSLPL, 0x02);
-
-               reg = stb0899_read_reg(state, STB0899_TSTRES);
-               STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
-               stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
-               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
-
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
-
-               STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
-               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
-
-               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
-               break;
-       case SYS_DSS:
-               /* FECM/Viterbi ON      */
-               reg = stb0899_read_reg(state, STB0899_FECM);
-               STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
-               STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
-               stb0899_write_reg(state, STB0899_FECM, reg);
-
-               stb0899_write_reg(state, STB0899_RSULC, 0xa1);
-               stb0899_write_reg(state, STB0899_TSULC, 0x61);
-               stb0899_write_reg(state, STB0899_RSLLC, 0x42);
-
-               reg = stb0899_read_reg(state, STB0899_TSTRES);
-               STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
-               stb0899_write_reg(state, STB0899_TSTRES, reg);
-
-               STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
-               STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
-
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
-               STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
-
-               STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
-
-               STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
-               break;
-       default:
-               dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
-               break;
-       }
-       STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
-       stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
-}
-
-/*
- * stb0899_set_iterations
- * set the LDPC iteration scale function
- */
-static void stb0899_set_iterations(struct stb0899_state *state)
-{
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_config *config = state->config;
-
-       s32 iter_scale;
-       u32 reg;
-
-       iter_scale = 17 * (internal->master_clk / 1000);
-       iter_scale += 410000;
-       iter_scale /= (internal->srate / 1000000);
-       iter_scale /= 1000;
-
-       if (iter_scale > config->ldpc_max_iter)
-               iter_scale = config->ldpc_max_iter;
-
-       reg = STB0899_READ_S2REG(STB0899_S2FEC, MAX_ITER);
-       STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
-       stb0899_write_s2reg(state, STB0899_S2FEC, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
-}
-
-static enum dvbfe_search stb0899_search(struct dvb_frontend *fe)
-{
-       struct stb0899_state *state = fe->demodulator_priv;
-       struct stb0899_params *i_params = &state->params;
-       struct stb0899_internal *internal = &state->internal;
-       struct stb0899_config *config = state->config;
-       struct dtv_frontend_properties *props = &fe->dtv_property_cache;
-
-       u32 SearchRange, gain;
-
-       i_params->freq  = props->frequency;
-       i_params->srate = props->symbol_rate;
-       state->delsys = props->delivery_system;
-       dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
-
-       SearchRange = 10000000;
-       dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
-       /* checking Search Range is meaningless for a fixed 3 Mhz                       */
-       if (INRANGE(i_params->srate, 1000000, 45000000)) {
-               dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE");
-               stb0899_set_delivery(state);
-
-               if (state->config->tuner_set_rfsiggain) {
-                       if (internal->srate > 15000000)
-                               gain =  8; /* 15Mb < srate < 45Mb, gain = 8dB   */
-                       else if (internal->srate > 5000000)
-                               gain = 12; /*  5Mb < srate < 15Mb, gain = 12dB  */
-                       else
-                               gain = 14; /*  1Mb < srate <  5Mb, gain = 14db  */
-                       state->config->tuner_set_rfsiggain(fe, gain);
-               }
-
-               if (i_params->srate <= 5000000)
-                       stb0899_set_mclk(state, config->lo_clk);
-               else
-                       stb0899_set_mclk(state, config->hi_clk);
-
-               switch (state->delsys) {
-               case SYS_DVBS:
-               case SYS_DSS:
-                       dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system");
-                       internal->freq  = i_params->freq;
-                       internal->srate = i_params->srate;
-                       /*
-                        * search = user search range +
-                        *          500Khz +
-                        *          2 * Tuner_step_size +
-                        *          10% of the symbol rate
-                        */
-                       internal->srch_range    = SearchRange + 1500000 + (i_params->srate / 5);
-                       internal->derot_percent = 30;
-
-                       /* What to do for tuners having no bandwidth setup ?    */
-                       /* enable tuner I/O */
-                       stb0899_i2c_gate_ctrl(&state->frontend, 1);
-
-                       if (state->config->tuner_set_bandwidth)
-                               state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
-                       if (state->config->tuner_get_bandwidth)
-                               state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
-
-                       /* disable tuner I/O */
-                       stb0899_i2c_gate_ctrl(&state->frontend, 0);
-
-                       /* Set DVB-S1 AGC               */
-                       stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
-
-                       /* Run the search algorithm     */
-                       dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
-                       if (stb0899_dvbs_algo(state)    == RANGEOK) {
-                               internal->lock          = 1;
-                               dprintk(state->verbose, FE_DEBUG, 1,
-                                       "-------------------------------------> DVB-S LOCK !");
-
-//                             stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors     */
-//                             internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
-//                             internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
-//                             dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
-//                             dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
-
-                               return DVBFE_ALGO_SEARCH_SUCCESS;
-                       } else {
-                               internal->lock          = 0;
-
-                               return DVBFE_ALGO_SEARCH_FAILED;
-                       }
-                       break;
-               case SYS_DVBS2:
-                       internal->freq                  = i_params->freq;
-                       internal->srate                 = i_params->srate;
-                       internal->srch_range            = SearchRange;
-
-                       /* enable tuner I/O */
-                       stb0899_i2c_gate_ctrl(&state->frontend, 1);
-
-                       if (state->config->tuner_set_bandwidth)
-                               state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
-                       if (state->config->tuner_get_bandwidth)
-                               state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
-
-                       /* disable tuner I/O */
-                       stb0899_i2c_gate_ctrl(&state->frontend, 0);
-
-//                     pParams->SpectralInv            = pSearch->IQ_Inversion;
-
-                       /* Set DVB-S2 AGC               */
-                       stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
-
-                       /* Set IterScale =f(MCLK,SYMB)  */
-                       stb0899_set_iterations(state);
-
-                       /* Run the search algorithm     */
-                       dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
-                       if (stb0899_dvbs2_algo(state)   == DVBS2_FEC_LOCK) {
-                               internal->lock          = 1;
-                               dprintk(state->verbose, FE_DEBUG, 1,
-                                       "-------------------------------------> DVB-S2 LOCK !");
-
-//                             stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors      */
-//                             internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
-//                             internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
-
-                               return DVBFE_ALGO_SEARCH_SUCCESS;
-                       } else {
-                               internal->lock          = 0;
-
-                               return DVBFE_ALGO_SEARCH_FAILED;
-                       }
-                       break;
-               default:
-                       dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
-                       return DVBFE_ALGO_SEARCH_INVALID;
-               }
-       }
-
-       return DVBFE_ALGO_SEARCH_ERROR;
-}
-
-static int stb0899_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stb0899_state *state             = fe->demodulator_priv;
-       struct stb0899_internal *internal       = &state->internal;
-
-       dprintk(state->verbose, FE_DEBUG, 1, "Get params");
-       p->symbol_rate = internal->srate;
-
-       return 0;
-}
-
-static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static struct dvb_frontend_ops stb0899_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
-       .info = {
-               .name                   = "STB0899 Multistandard",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 0,
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        =  5000000,
-               .symbol_rate_max        = 45000000,
-
-               .caps                   = FE_CAN_INVERSION_AUTO |
-                                         FE_CAN_FEC_AUTO       |
-                                         FE_CAN_2G_MODULATION  |
-                                         FE_CAN_QPSK
-       },
-
-       .release                        = stb0899_release,
-       .init                           = stb0899_init,
-       .sleep                          = stb0899_sleep,
-//     .wakeup                         = stb0899_wakeup,
-
-       .i2c_gate_ctrl                  = stb0899_i2c_gate_ctrl,
-
-       .get_frontend_algo              = stb0899_frontend_algo,
-       .search                         = stb0899_search,
-       .get_frontend                   = stb0899_get_frontend,
-
-
-       .read_status                    = stb0899_read_status,
-       .read_snr                       = stb0899_read_snr,
-       .read_signal_strength           = stb0899_read_signal_strength,
-       .read_ber                       = stb0899_read_ber,
-
-       .set_voltage                    = stb0899_set_voltage,
-       .set_tone                       = stb0899_set_tone,
-
-       .diseqc_send_master_cmd         = stb0899_send_diseqc_msg,
-       .diseqc_recv_slave_reply        = stb0899_recv_slave_reply,
-       .diseqc_send_burst              = stb0899_send_diseqc_burst,
-};
-
-struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
-{
-       struct stb0899_state *state = NULL;
-       enum stb0899_inversion inversion;
-
-       state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       inversion                               = config->inversion;
-       state->verbose                          = &verbose;
-       state->config                           = config;
-       state->i2c                              = i2c;
-       state->frontend.ops                     = stb0899_ops;
-       state->frontend.demodulator_priv        = state;
-       state->internal.inversion               = inversion;
-
-       stb0899_wakeup(&state->frontend);
-       if (stb0899_get_dev_id(state) == -ENODEV) {
-               printk("%s: Exiting .. !\n", __func__);
-               goto error;
-       }
-
-       printk("%s: Attaching STB0899 \n", __func__);
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(stb0899_attach);
-MODULE_PARM_DESC(verbose, "Set Verbosity level");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h
deleted file mode 100644 (file)
index 98b200c..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STB0899_DRV_H
-#define __STB0899_DRV_H
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "dvb_frontend.h"
-
-#define STB0899_TSMODE_SERIAL          1
-#define STB0899_CLKPOL_FALLING         2
-#define STB0899_CLKNULL_PARITY         3
-#define STB0899_SYNC_FORCED            4
-#define STB0899_FECMODE_DSS            5
-
-struct stb0899_s1_reg {
-       u16     address;
-       u8      data;
-};
-
-struct stb0899_s2_reg {
-       u16     offset;
-       u32     base_address;
-       u32     data;
-};
-
-enum stb0899_inversion {
-       IQ_SWAP_OFF     = 0,
-       IQ_SWAP_ON,
-       IQ_SWAP_AUTO
-};
-
-#define STB0899_GPIO00                         0xf140
-#define STB0899_GPIO01                         0xf141
-#define STB0899_GPIO02                         0xf142
-#define STB0899_GPIO03                         0xf143
-#define STB0899_GPIO04                         0xf144
-#define STB0899_GPIO05                         0xf145
-#define STB0899_GPIO06                         0xf146
-#define STB0899_GPIO07                         0xf147
-#define STB0899_GPIO08                         0xf148
-#define STB0899_GPIO09                         0xf149
-#define STB0899_GPIO10                         0xf14a
-#define STB0899_GPIO11                         0xf14b
-#define STB0899_GPIO12                         0xf14c
-#define STB0899_GPIO13                         0xf14d
-#define STB0899_GPIO14                         0xf14e
-#define STB0899_GPIO15                         0xf14f
-#define STB0899_GPIO16                         0xf150
-#define STB0899_GPIO17                         0xf151
-#define STB0899_GPIO18                         0xf152
-#define STB0899_GPIO19                         0xf153
-#define STB0899_GPIO20                         0xf154
-
-#define STB0899_GPIOPULLUP                     0x01 /* Output device is connected to Vdd */
-#define STB0899_GPIOPULLDN                     0x00 /* Output device is connected to Vss */
-
-#define STB0899_POSTPROC_GPIO_POWER            0x00
-#define STB0899_POSTPROC_GPIO_LOCK             0x01
-
-/*
- * Post process output configuration control
- * 1. POWER ON/OFF             (index 0)
- * 2. FE_HAS_LOCK/LOCK_LOSS    (index 1)
- *
- * @gpio       = one of the above listed GPIO's
- * @level      = output state: pulled up or low
- */
-struct stb0899_postproc {
-       u16     gpio;
-       u8      level;
-};
-
-struct stb0899_config {
-       const struct stb0899_s1_reg     *init_dev;
-       const struct stb0899_s2_reg     *init_s2_demod;
-       const struct stb0899_s1_reg     *init_s1_demod;
-       const struct stb0899_s2_reg     *init_s2_fec;
-       const struct stb0899_s1_reg     *init_tst;
-
-       const struct stb0899_postproc   *postproc;
-
-       enum stb0899_inversion          inversion;
-
-       u32     xtal_freq;
-
-       u8      demod_address;
-       u8      ts_output_mode;
-       u8      block_sync_mode;
-       u8      ts_pfbit_toggle;
-
-       u8      clock_polarity;
-       u8      data_clk_parity;
-       u8      fec_mode;
-       u8      data_output_ctl;
-       u8      data_fifo_mode;
-       u8      out_rate_comp;
-       u8      i2c_repeater;
-//     int     inversion;
-       int     lo_clk;
-       int     hi_clk;
-
-       u32     esno_ave;
-       u32     esno_quant;
-       u32     avframes_coarse;
-       u32     avframes_fine;
-       u32     miss_threshold;
-       u32     uwp_threshold_acq;
-       u32     uwp_threshold_track;
-       u32     uwp_threshold_sof;
-       u32     sof_search_timeout;
-
-       u32     btr_nco_bits;
-       u32     btr_gain_shift_offset;
-       u32     crl_nco_bits;
-       u32     ldpc_max_iter;
-
-       int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
-       int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
-       int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
-       int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
-       int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
-};
-
-#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
-                                          struct i2c_adapter *i2c);
-
-#else
-
-static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif //CONFIG_DVB_STB0899
-
-
-#endif
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
deleted file mode 100644 (file)
index 82395b9..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STB0899_PRIV_H
-#define __STB0899_PRIV_H
-
-#include "dvb_frontend.h"
-#include "stb0899_drv.h"
-
-#define FE_ERROR                               0
-#define FE_NOTICE                              1
-#define FE_INFO                                        2
-#define FE_DEBUG                               3
-#define FE_DEBUGREG                            4
-
-#define dprintk(x, y, z, format, arg...) do {                                          \
-       if (z) {                                                                        \
-               if      ((*x > FE_ERROR) && (*x > y))                                   \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
-               else if ((*x > FE_NOTICE) && (*x > y))                                  \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((*x > FE_INFO) && (*x > y))                                    \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
-               else if ((*x > FE_DEBUG) && (*x > y))                                   \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (*x > y)                                                             \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while(0)
-
-#define INRANGE(val, x, y)                     (((x <= val) && (val <= y)) ||          \
-                                                ((y <= val) && (val <= x)) ? 1 : 0)
-
-#define BYTE0                                  0
-#define BYTE1                                  8
-#define BYTE2                                  16
-#define BYTE3                                  24
-
-#define GETBYTE(x, y)                          (((x) >> (y)) & 0xff)
-#define MAKEWORD32(a, b, c, d)                 (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
-#define MAKEWORD16(a, b)                       (((a) << 8) | (b))
-
-#define LSB(x)                                 ((x & 0xff))
-#define MSB(y)                                 ((y >> 8) & 0xff)
-
-
-#define STB0899_GETFIELD(bitf, val)            ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
-
-
-#define STB0899_SETFIELD(mask, val, width, offset)      (mask & (~(((1 << width) - 1) <<       \
-                                                        offset))) | ((val &                    \
-                                                        ((1 << width) - 1)) << offset)
-
-#define STB0899_SETFIELD_VAL(bitf, mask, val)  (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
-                                                        STB0899_OFFST_##bitf))) | \
-                                                        (val << STB0899_OFFST_##bitf))
-
-
-enum stb0899_status {
-       NOAGC1  = 0,
-       AGC1OK,
-       NOTIMING,
-       ANALOGCARRIER,
-       TIMINGOK,
-       NOAGC2,
-       AGC2OK,
-       NOCARRIER,
-       CARRIEROK,
-       NODATA,
-       FALSELOCK,
-       DATAOK,
-       OUTOFRANGE,
-       RANGEOK,
-       DVBS2_DEMOD_LOCK,
-       DVBS2_DEMOD_NOLOCK,
-       DVBS2_FEC_LOCK,
-       DVBS2_FEC_NOLOCK
-};
-
-enum stb0899_modcod {
-       STB0899_DUMMY_PLF,
-       STB0899_QPSK_14,
-       STB0899_QPSK_13,
-       STB0899_QPSK_25,
-       STB0899_QPSK_12,
-       STB0899_QPSK_35,
-       STB0899_QPSK_23,
-       STB0899_QPSK_34,
-       STB0899_QPSK_45,
-       STB0899_QPSK_56,
-       STB0899_QPSK_89,
-       STB0899_QPSK_910,
-       STB0899_8PSK_35,
-       STB0899_8PSK_23,
-       STB0899_8PSK_34,
-       STB0899_8PSK_56,
-       STB0899_8PSK_89,
-       STB0899_8PSK_910,
-       STB0899_16APSK_23,
-       STB0899_16APSK_34,
-       STB0899_16APSK_45,
-       STB0899_16APSK_56,
-       STB0899_16APSK_89,
-       STB0899_16APSK_910,
-       STB0899_32APSK_34,
-       STB0899_32APSK_45,
-       STB0899_32APSK_56,
-       STB0899_32APSK_89,
-       STB0899_32APSK_910
-};
-
-enum stb0899_frame {
-       STB0899_LONG_FRAME,
-       STB0899_SHORT_FRAME
-};
-
-enum stb0899_alpha {
-       RRC_20,
-       RRC_25,
-       RRC_35
-};
-
-struct stb0899_tab {
-       s32 real;
-       s32 read;
-};
-
-enum stb0899_fec {
-       STB0899_FEC_1_2                 = 13,
-       STB0899_FEC_2_3                 = 18,
-       STB0899_FEC_3_4                 = 21,
-       STB0899_FEC_5_6                 = 24,
-       STB0899_FEC_6_7                 = 25,
-       STB0899_FEC_7_8                 = 26
-};
-
-struct stb0899_params {
-       u32     freq;                                   /* Frequency    */
-       u32     srate;                                  /* Symbol rate  */
-       enum fe_code_rate fecrate;
-};
-
-struct stb0899_internal {
-       u32                     master_clk;
-       u32                     freq;                   /* Demod internal Frequency             */
-       u32                     srate;                  /* Demod internal Symbol rate           */
-       enum stb0899_fec        fecrate;                /* Demod internal FEC rate              */
-       s32                     srch_range;             /* Demod internal Search Range          */
-       s32                     sub_range;              /* Demod current sub range (Hz)         */
-       s32                     tuner_step;             /* Tuner step (Hz)                      */
-       s32                     tuner_offst;            /* Relative offset to carrier (Hz)      */
-       u32                     tuner_bw;               /* Current bandwidth of the tuner (Hz)  */
-
-       s32                     mclk;                   /* Masterclock Divider factor (binary)  */
-       s32                     rolloff;                /* Current RollOff of the filter (x100) */
-
-       s16                     derot_freq;             /* Current derotator frequency (Hz)     */
-       s16                     derot_percent;
-
-       s16                     direction;              /* Current derotator search direction   */
-       s16                     derot_step;             /* Derotator step (binary value)        */
-       s16                     t_derot;                /* Derotator time constant (ms)         */
-       s16                     t_data;                 /* Data recovery time constant (ms)     */
-       s16                     sub_dir;                /* Direction of the next sub range      */
-
-       s16                     t_agc1;                 /* Agc1 time constant (ms)              */
-       s16                     t_agc2;                 /* Agc2 time constant (ms)              */
-
-       u32                     lock;                   /* Demod internal lock state            */
-       enum stb0899_status     status;                 /* Demod internal status                */
-
-       /* DVB-S2 */
-       s32                     agc_gain;               /* RF AGC Gain                          */
-       s32                     center_freq;            /* Nominal carrier frequency            */
-       s32                     av_frame_coarse;        /* Coarse carrier freq search frames    */
-       s32                     av_frame_fine;          /* Fine carrier freq search frames      */
-
-       s16                     step_size;              /* Carrier frequency search step size   */
-
-       enum stb0899_alpha      rrc_alpha;
-       enum stb0899_inversion  inversion;
-       enum stb0899_modcod     modcod;
-       u8                      pilots;                 /* Pilots found                         */
-
-       enum stb0899_frame      frame_length;
-       u8                      v_status;               /* VSTATUS                              */
-       u8                      err_ctrl;               /* ERRCTRLn                             */
-};
-
-struct stb0899_state {
-       struct i2c_adapter              *i2c;
-       struct stb0899_config           *config;
-       struct dvb_frontend             frontend;
-
-       u32                             *verbose;       /* Cached module verbosity level        */
-
-       struct stb0899_internal         internal;       /* Device internal parameters           */
-
-       /*      cached params from API  */
-       enum fe_delivery_system         delsys;
-       struct stb0899_params           params;
-
-       u32                             rx_freq;        /* DiSEqC 2.0 receiver freq             */
-       struct mutex                    search_lock;
-};
-/* stb0899.c           */
-extern int stb0899_read_reg(struct stb0899_state *state,
-                           unsigned int reg);
-
-extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
-                              u32 stb0899_i2cdev,
-                              u32 stb0899_base_addr,
-                              u16 stb0899_reg_offset);
-
-extern int stb0899_read_regs(struct stb0899_state *state,
-                            unsigned int reg, u8 *buf,
-                            u32 count);
-
-extern int stb0899_write_regs(struct stb0899_state *state,
-                             unsigned int reg, u8 *data,
-                             u32 count);
-
-extern int stb0899_write_reg(struct stb0899_state *state,
-                            unsigned int reg,
-                            u8 data);
-
-extern int stb0899_write_s2reg(struct stb0899_state *state,
-                              u32 stb0899_i2cdev,
-                              u32 stb0899_base_addr,
-                              u16 stb0899_reg_offset,
-                              u32 stb0899_data);
-
-extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
-
-
-#define STB0899_READ_S2REG(DEVICE, REG)        (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
-//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA)       (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
-
-/* stb0899_algo.c      */
-extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
-extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
-extern long stb0899_carr_width(struct stb0899_state *state);
-
-#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h
deleted file mode 100644 (file)
index ba1ed56..0000000
+++ /dev/null
@@ -1,2027 +0,0 @@
-/*
-       STB0899 Multistandard Frontend driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STB0899_REG_H
-#define __STB0899_REG_H
-
-/*     S1      */
-#define STB0899_DEV_ID                         0xf000
-#define STB0899_CHIP_ID                                (0x0f << 4)
-#define STB0899_OFFST_CHIP_ID                  4
-#define STB0899_WIDTH_CHIP_ID                  4
-#define STB0899_CHIP_REL                       (0x0f << 0)
-#define STB0899_OFFST_CHIP_REL                 0
-#define STB0899_WIDTH_CHIP_REL                 4
-
-#define STB0899_DEMOD                          0xf40e
-#define STB0899_MODECOEFF                      (0x01 << 0)
-#define STB0899_OFFST_MODECOEFF                        0
-#define STB0899_WIDTH_MODECOEFF                        1
-
-#define STB0899_RCOMPC                         0xf410
-#define STB0899_AGC1CN                         0xf412
-#define STB0899_AGC1REF                                0xf413
-#define STB0899_RTC                            0xf417
-#define STB0899_TMGCFG                         0xf418
-#define STB0899_AGC2REF                                0xf419
-#define STB0899_TLSR                           0xf41a
-
-#define STB0899_CFD                            0xf41b
-#define STB0899_CFD_ON                         (0x01 << 7)
-#define STB0899_OFFST_CFD_ON                   7
-#define STB0899_WIDTH_CFD_ON                   1
-
-#define STB0899_ACLC                           0xf41c
-
-#define STB0899_BCLC                           0xf41d
-#define STB0899_OFFST_ALGO                     6
-#define STB0899_WIDTH_ALGO_QPSK2               2
-#define STB0899_ALGO_QPSK2                     (2 << 6)
-#define STB0899_ALGO_QPSK1                     (1 << 6)
-#define STB0899_ALGO_BPSK                      (0 << 6)
-#define STB0899_OFFST_BETA                     0
-#define STB0899_WIDTH_BETA                     6
-
-#define STB0899_EQON                           0xf41e
-#define STB0899_LDT                            0xf41f
-#define STB0899_LDT2                           0xf420
-#define STB0899_EQUALREF                       0xf425
-#define STB0899_TMGRAMP                                0xf426
-#define STB0899_TMGTHD                         0xf427
-#define STB0899_IDCCOMP                                0xf428
-#define STB0899_QDCCOMP                                0xf429
-#define STB0899_POWERI                         0xf42a
-#define STB0899_POWERQ                         0xf42b
-#define STB0899_RCOMP                          0xf42c
-
-#define STB0899_AGCIQIN                                0xf42e
-#define STB0899_AGCIQVALUE                     (0xff << 0)
-#define STB0899_OFFST_AGCIQVALUE               0
-#define STB0899_WIDTH_AGCIQVALUE               8
-
-#define STB0899_AGC2I1                         0xf436
-#define STB0899_AGC2I2                         0xf437
-
-#define STB0899_TLIR                           0xf438
-#define STB0899_TLIR_TMG_LOCK_IND              (0xff << 0)
-#define STB0899_OFFST_TLIR_TMG_LOCK_IND                0
-#define STB0899_WIDTH_TLIR_TMG_LOCK_IND                8
-
-#define STB0899_RTF                            0xf439
-#define STB0899_RTF_TIMING_LOOP_FREQ           (0xff << 0)
-#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ     0
-#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ     8
-
-#define STB0899_DSTATUS                                0xf43a
-#define STB0899_CARRIER_FOUND                  (0x01 << 7)
-#define STB0899_OFFST_CARRIER_FOUND            7
-#define STB0899_WIDTH_CARRIER_FOUND            1
-#define STB0899_TMG_LOCK                       (0x01 << 6)
-#define STB0899_OFFST_TMG_LOCK                 6
-#define STB0899_WIDTH_TMG_LOCK                 1
-#define STB0899_DEMOD_LOCK                     (0x01 << 5)
-#define STB0899_OFFST_DEMOD_LOCK               5
-#define STB0899_WIDTH_DEMOD_LOCK               1
-#define STB0899_TMG_AUTO                       (0x01 << 4)
-#define STB0899_OFFST_TMG_AUTO                 4
-#define STB0899_WIDTH_TMG_AUTO                 1
-#define STB0899_END_MAIN                       (0x01 << 3)
-#define STB0899_OFFST_END_MAIN                 3
-#define STB0899_WIDTH_END_MAIN                 1
-
-#define STB0899_LDI                            0xf43b
-#define STB0899_OFFST_LDI                      0
-#define STB0899_WIDTH_LDI                      8
-
-#define STB0899_CFRM                           0xf43e
-#define STB0899_OFFST_CFRM                     0
-#define STB0899_WIDTH_CFRM                     8
-
-#define STB0899_CFRL                           0xf43f
-#define STB0899_OFFST_CFRL                     0
-#define STB0899_WIDTH_CFRL                     8
-
-#define STB0899_NIRM                           0xf440
-#define STB0899_OFFST_NIRM                     0
-#define STB0899_WIDTH_NIRM                     8
-
-#define STB0899_NIRL                           0xf441
-#define STB0899_OFFST_NIRL                     0
-#define STB0899_WIDTH_NIRL                     8
-
-#define STB0899_ISYMB                          0xf444
-#define STB0899_QSYMB                          0xf445
-
-#define STB0899_SFRH                           0xf446
-#define STB0899_OFFST_SFRH                     0
-#define STB0899_WIDTH_SFRH                     8
-
-#define STB0899_SFRM                           0xf447
-#define STB0899_OFFST_SFRM                     0
-#define STB0899_WIDTH_SFRM                     8
-
-#define STB0899_SFRL                           0xf448
-#define STB0899_OFFST_SFRL                     4
-#define STB0899_WIDTH_SFRL                     4
-
-#define STB0899_SFRUPH                         0xf44c
-#define STB0899_SFRUPM                         0xf44d
-#define STB0899_SFRUPL                         0xf44e
-
-#define STB0899_EQUAI1                         0xf4e0
-#define STB0899_EQUAQ1                         0xf4e1
-#define STB0899_EQUAI2                         0xf4e2
-#define STB0899_EQUAQ2                         0xf4e3
-#define STB0899_EQUAI3                         0xf4e4
-#define STB0899_EQUAQ3                         0xf4e5
-#define STB0899_EQUAI4                         0xf4e6
-#define STB0899_EQUAQ4                         0xf4e7
-#define STB0899_EQUAI5                         0xf4e8
-#define STB0899_EQUAQ5                         0xf4e9
-
-#define STB0899_DSTATUS2                       0xf50c
-#define STB0899_DS2_TMG_AUTOSRCH               (0x01 << 7)
-#define STB8999_OFFST_DS2_TMG_AUTOSRCH         7
-#define STB0899_WIDTH_DS2_TMG_AUTOSRCH         1
-#define STB0899_DS2_END_MAINLOOP               (0x01 << 6)
-#define STB0899_OFFST_DS2_END_MAINLOOP         6
-#define STB0899_WIDTH_DS2_END_MAINLOOP         1
-#define STB0899_DS2_CFSYNC                     (0x01 << 5)
-#define STB0899_OFFST_DS2_CFSYNC               5
-#define STB0899_WIDTH_DS2_CFSYNC               1
-#define STB0899_DS2_TMGLOCK                    (0x01 << 4)
-#define STB0899_OFFST_DS2_TMGLOCK              4
-#define STB0899_WIDTH_DS2_TMGLOCK              1
-#define STB0899_DS2_DEMODWAIT                  (0x01 << 3)
-#define STB0899_OFFST_DS2_DEMODWAIT            3
-#define STB0899_WIDTH_DS2_DEMODWAIT            1
-#define STB0899_DS2_FECON                      (0x01 << 1)
-#define STB0899_OFFST_DS2_FECON                        1
-#define STB0899_WIDTH_DS2_FECON                        1
-
-/*     S1 FEC  */
-#define STB0899_VSTATUS                                0xf50d
-#define STB0899_VSTATUS_VITERBI_ON             (0x01 << 7)
-#define STB0899_OFFST_VSTATUS_VITERBI_ON       7
-#define STB0899_WIDTH_VSTATUS_VITERBI_ON       1
-#define STB0899_VSTATUS_END_LOOPVIT            (0x01 << 6)
-#define STB0899_OFFST_VSTATUS_END_LOOPVIT      6
-#define STB0899_WIDTH_VSTATUS_END_LOOPVIT      1
-#define STB0899_VSTATUS_PRFVIT                 (0x01 << 4)
-#define STB0899_OFFST_VSTATUS_PRFVIT           4
-#define STB0899_WIDTH_VSTATUS_PRFVIT           1
-#define STB0899_VSTATUS_LOCKEDVIT              (0x01 << 3)
-#define STB0899_OFFST_VSTATUS_LOCKEDVIT                3
-#define STB0899_WIDTH_VSTATUS_LOCKEDVIT                1
-
-#define STB0899_VERROR                         0xf50f
-
-#define STB0899_IQSWAP                         0xf523
-#define STB0899_SYM                            (0x01 << 3)
-#define STB0899_OFFST_SYM                      3
-#define STB0899_WIDTH_SYM                      1
-
-#define STB0899_FECAUTO1                       0xf530
-#define STB0899_DSSSRCH                                (0x01 << 3)
-#define STB0899_OFFST_DSSSRCH                  3
-#define STB0899_WIDTH_DSSSRCH                  1
-#define STB0899_SYMSRCH                                (0x01 << 2)
-#define STB0899_OFFST_SYMSRCH                  2
-#define STB0899_WIDTH_SYMSRCH                  1
-#define STB0899_QPSKSRCH                       (0x01 << 1)
-#define STB0899_OFFST_QPSKSRCH                 1
-#define STB0899_WIDTH_QPSKSRCH                 1
-#define STB0899_BPSKSRCH                       (0x01 << 0)
-#define STB0899_OFFST_BPSKSRCH                 0
-#define STB0899_WIDTH_BPSKSRCH                 1
-
-#define STB0899_FECM                           0xf533
-#define STB0899_FECM_NOT_DVB                   (0x01 << 7)
-#define STB0899_OFFST_FECM_NOT_DVB             7
-#define STB0899_WIDTH_FECM_NOT_DVB             1
-#define STB0899_FECM_RSVD1                     (0x07 << 4)
-#define STB0899_OFFST_FECM_RSVD1               4
-#define STB0899_WIDTH_FECM_RSVD1               3
-#define STB0899_FECM_VITERBI_ON                        (0x01 << 3)
-#define STB0899_OFFST_FECM_VITERBI_ON          3
-#define STB0899_WIDTH_FECM_VITERBI_ON          1
-#define STB0899_FECM_RSVD0                     (0x01 << 2)
-#define STB0899_OFFST_FECM_RSVD0               2
-#define STB0899_WIDTH_FECM_RSVD0               1
-#define STB0899_FECM_SYNCDIS                   (0x01 << 1)
-#define STB0899_OFFST_FECM_SYNCDIS             1
-#define STB0899_WIDTH_FECM_SYNCDIS             1
-#define STB0899_FECM_SYMI                      (0x01 << 0)
-#define STB0899_OFFST_FECM_SYMI                        0
-#define STB0899_WIDTH_FECM_SYMI                        1
-
-#define STB0899_VTH12                          0xf534
-#define STB0899_VTH23                          0xf535
-#define STB0899_VTH34                          0xf536
-#define STB0899_VTH56                          0xf537
-#define STB0899_VTH67                          0xf538
-#define STB0899_VTH78                          0xf539
-
-#define STB0899_PRVIT                          0xf53c
-#define STB0899_PR_7_8                         (0x01 << 5)
-#define STB0899_OFFST_PR_7_8                   5
-#define STB0899_WIDTH_PR_7_8                   1
-#define STB0899_PR_6_7                         (0x01 << 4)
-#define STB0899_OFFST_PR_6_7                   4
-#define STB0899_WIDTH_PR_6_7                   1
-#define STB0899_PR_5_6                         (0x01 << 3)
-#define STB0899_OFFST_PR_5_6                   3
-#define STB0899_WIDTH_PR_5_6                   1
-#define STB0899_PR_3_4                         (0x01 << 2)
-#define STB0899_OFFST_PR_3_4                   2
-#define STB0899_WIDTH_PR_3_4                   1
-#define STB0899_PR_2_3                         (0x01 << 1)
-#define STB0899_OFFST_PR_2_3                   1
-#define STB0899_WIDTH_PR_2_3                   1
-#define STB0899_PR_1_2                         (0x01 << 0)
-#define STB0899_OFFST_PR_1_2                   0
-#define STB0899_WIDTH_PR_1_2                   1
-
-#define STB0899_VITSYNC                                0xf53d
-#define STB0899_AM                             (0x01 << 7)
-#define STB0899_OFFST_AM                       7
-#define STB0899_WIDTH_AM                       1
-#define STB0899_FREEZE                         (0x01 << 6)
-#define STB0899_OFFST_FREEZE                   6
-#define STB0899_WIDTH_FREEZE                   1
-#define STB0899_SN_65536                       (0x03 << 4)
-#define STB0899_OFFST_SN_65536                 4
-#define STB0899_WIDTH_SN_65536                 2
-#define STB0899_SN_16384                       (0x01 << 5)
-#define STB0899_OFFST_SN_16384                 5
-#define STB0899_WIDTH_SN_16384                 1
-#define STB0899_SN_4096                                (0x01 << 4)
-#define STB0899_OFFST_SN_4096                  4
-#define STB0899_WIDTH_SN_4096                  1
-#define STB0899_SN_1024                                (0x00 << 4)
-#define STB0899_OFFST_SN_1024                  4
-#define STB0899_WIDTH_SN_1024                  0
-#define STB0899_TO_128                         (0x03 << 2)
-#define STB0899_OFFST_TO_128                   2
-#define STB0899_WIDTH_TO_128                   2
-#define STB0899_TO_64                          (0x01 << 3)
-#define STB0899_OFFST_TO_64                    3
-#define STB0899_WIDTH_TO_64                    1
-#define STB0899_TO_32                          (0x01 << 2)
-#define STB0899_OFFST_TO_32                    2
-#define STB0899_WIDTH_TO_32                    1
-#define STB0899_TO_16                          (0x00 << 2)
-#define STB0899_OFFST_TO_16                    2
-#define STB0899_WIDTH_TO_16                    0
-#define STB0899_HYST_128                       (0x03 << 1)
-#define STB0899_OFFST_HYST_128                 1
-#define STB0899_WIDTH_HYST_128                 2
-#define STB0899_HYST_64                                (0x01 << 1)
-#define STB0899_OFFST_HYST_64                  1
-#define STB0899_WIDTH_HYST_64                  1
-#define STB0899_HYST_32                                (0x01 << 0)
-#define STB0899_OFFST_HYST_32                  0
-#define STB0899_WIDTH_HYST_32                  1
-#define STB0899_HYST_16                                (0x00 << 0)
-#define STB0899_OFFST_HYST_16                  0
-#define STB0899_WIDTH_HYST_16                  0
-
-#define STB0899_RSULC                          0xf548
-#define STB0899_ULDIL_ON                       (0x01 << 7)
-#define STB0899_OFFST_ULDIL_ON                 7
-#define STB0899_WIDTH_ULDIL_ON                 1
-#define STB0899_ULAUTO_ON                      (0x01 << 6)
-#define STB0899_OFFST_ULAUTO_ON                        6
-#define STB0899_WIDTH_ULAUTO_ON                        1
-#define STB0899_ULRS_ON                                (0x01 << 5)
-#define STB0899_OFFST_ULRS_ON                  5
-#define STB0899_WIDTH_ULRS_ON                  1
-#define STB0899_ULDESCRAM_ON                   (0x01 << 4)
-#define STB0899_OFFST_ULDESCRAM_ON             4
-#define STB0899_WIDTH_ULDESCRAM_ON             1
-#define STB0899_UL_DISABLE                     (0x01 << 2)
-#define STB0899_OFFST_UL_DISABLE               2
-#define STB0899_WIDTH_UL_DISABLE               1
-#define STB0899_NOFTHRESHOLD                   (0x01 << 0)
-#define STB0899_OFFST_NOFTHRESHOLD             0
-#define STB0899_WIDTH_NOFTHRESHOLD             1
-
-#define STB0899_RSLLC                          0xf54a
-#define STB0899_DEMAPVIT                       0xf583
-#define STB0899_DEMAPVIT_RSVD                  (0x01 << 7)
-#define STB0899_OFFST_DEMAPVIT_RSVD            7
-#define STB0899_WIDTH_DEMAPVIT_RSVD            1
-#define STB0899_DEMAPVIT_KDIVIDER              (0x7f << 0)
-#define STB0899_OFFST_DEMAPVIT_KDIVIDER                0
-#define STB0899_WIDTH_DEMAPVIT_KDIVIDER                7
-
-#define STB0899_PLPARM                         0xf58c
-#define STB0899_VITMAPPING                     (0x07 << 5)
-#define STB0899_OFFST_VITMAPPING               5
-#define STB0899_WIDTH_VITMAPPING               3
-#define STB0899_VITMAPPING_BPSK                        (0x01 << 5)
-#define STB0899_OFFST_VITMAPPING_BPSK          5
-#define STB0899_WIDTH_VITMAPPING_BPSK          1
-#define STB0899_VITMAPPING_QPSK                        (0x00 << 5)
-#define STB0899_OFFST_VITMAPPING_QPSK          5
-#define STB0899_WIDTH_VITMAPPING_QPSK          0
-#define STB0899_VITCURPUN                      (0x1f << 0)
-#define STB0899_OFFST_VITCURPUN                        0
-#define STB0899_WIDTH_VITCURPUN                        5
-#define STB0899_VITCURPUN_1_2                  (0x0d << 0)
-#define STB0899_VITCURPUN_2_3                  (0x12 << 0)
-#define STB0899_VITCURPUN_3_4                  (0x15 << 0)
-#define STB0899_VITCURPUN_5_6                  (0x18 << 0)
-#define STB0899_VITCURPUN_6_7                  (0x19 << 0)
-#define STB0899_VITCURPUN_7_8                  (0x1a << 0)
-
-/*     S2 DEMOD        */
-#define STB0899_OFF0_DMD_STATUS                        0xf300
-#define STB0899_BASE_DMD_STATUS                        0x00000000
-#define STB0899_IF_AGC_LOCK                    (0x01 << 8)
-#define STB0899_OFFST_IF_AGC_LOCK              0
-#define STB0899_WIDTH_IF_AGC_LOCK              1
-
-#define STB0899_OFF0_CRL_FREQ                  0xf304
-#define STB0899_BASE_CRL_FREQ                  0x00000000
-#define STB0899_CARR_FREQ                      (0x3fffffff << 0)
-#define STB0899_OFFST_CARR_FREQ                        0
-#define STB0899_WIDTH_CARR_FREQ                        30
-
-#define STB0899_OFF0_BTR_FREQ                  0xf308
-#define STB0899_BASE_BTR_FREQ                  0x00000000
-#define STB0899_BTR_FREQ                       (0xfffffff << 0)
-#define STB0899_OFFST_BTR_FREQ                 0
-#define STB0899_WIDTH_BTR_FREQ                 28
-
-#define STB0899_OFF0_IF_AGC_GAIN               0xf30c
-#define STB0899_BASE_IF_AGC_GAIN               0x00000000
-#define STB0899_IF_AGC_GAIN                    (0x3fff < 0)
-#define STB0899_OFFST_IF_AGC_GAIN              0
-#define STB0899_WIDTH_IF_AGC_GAIN              14
-
-#define STB0899_OFF0_BB_AGC_GAIN               0xf310
-#define STB0899_BASE_BB_AGC_GAIN               0x00000000
-#define STB0899_BB_AGC_GAIN                    (0x3fff < 0)
-#define STB0899_OFFST_BB_AGC_GAIN              0
-#define STB0899_WIDTH_BB_AGC_GAIN              14
-
-#define STB0899_OFF0_DC_OFFSET                 0xf314
-#define STB0899_BASE_DC_OFFSET                 0x00000000
-#define STB0899_I                              (0xff < 8)
-#define STB0899_OFFST_I                                8
-#define STB0899_WIDTH_I                                8
-#define STB0899_Q                              (0xff < 0)
-#define STB0899_OFFST_Q                                8
-#define STB0899_WIDTH_Q                                8
-
-#define STB0899_OFF0_DMD_CNTRL                 0xf31c
-#define STB0899_BASE_DMD_CNTRL                 0x00000000
-#define STB0899_ADC0_PINS1IN                   (0x01 << 6)
-#define STB0899_OFFST_ADC0_PINS1IN              6
-#define STB0899_WIDTH_ADC0_PINS1IN              1
-#define STB0899_IN2COMP1_OFFBIN0               (0x01 << 3)
-#define STB0899_OFFST_IN2COMP1_OFFBIN0          3
-#define STB0899_WIDTH_IN2COMP1_OFFBIN0          1
-#define STB0899_DC_COMP                                (0x01 << 2)
-#define STB0899_OFFST_DC_COMP                  2
-#define STB0899_WIDTH_DC_COMP                  1
-#define STB0899_MODMODE                                (0x03 << 0)
-#define STB0899_OFFST_MODMODE                  0
-#define STB0899_WIDTH_MODMODE                  2
-
-#define STB0899_OFF0_IF_AGC_CNTRL              0xf320
-#define STB0899_BASE_IF_AGC_CNTRL              0x00000000
-#define STB0899_IF_GAIN_INIT                   (0x3fff << 13)
-#define STB0899_OFFST_IF_GAIN_INIT             13
-#define STB0899_WIDTH_IF_GAIN_INIT             14
-#define STB0899_IF_GAIN_SENSE                  (0x01 << 12)
-#define STB0899_OFFST_IF_GAIN_SENSE            12
-#define STB0899_WIDTH_IF_GAIN_SENSE            1
-#define STB0899_IF_LOOP_GAIN                   (0x0f << 8)
-#define STB0899_OFFST_IF_LOOP_GAIN             8
-#define STB0899_WIDTH_IF_LOOP_GAIN             4
-#define STB0899_IF_LD_GAIN_INIT                        (0x01 << 7)
-#define STB0899_OFFST_IF_LD_GAIN_INIT          7
-#define STB0899_WIDTH_IF_LD_GAIN_INIT          1
-#define STB0899_IF_AGC_REF                     (0x7f << 0)
-#define STB0899_OFFST_IF_AGC_REF               0
-#define STB0899_WIDTH_IF_AGC_REF               7
-
-#define STB0899_OFF0_BB_AGC_CNTRL              0xf324
-#define STB0899_BASE_BB_AGC_CNTRL              0x00000000
-#define STB0899_BB_GAIN_INIT                   (0x3fff << 12)
-#define STB0899_OFFST_BB_GAIN_INIT             12
-#define STB0899_WIDTH_BB_GAIN_INIT             14
-#define STB0899_BB_LOOP_GAIN                   (0x0f << 8)
-#define STB0899_OFFST_BB_LOOP_GAIN             8
-#define STB0899_WIDTH_BB_LOOP_GAIN             4
-#define STB0899_BB_LD_GAIN_INIT                        (0x01 << 7)
-#define STB0899_OFFST_BB_LD_GAIN_INIT          7
-#define STB0899_WIDTH_BB_LD_GAIN_INIT          1
-#define STB0899_BB_AGC_REF                     (0x7f << 0)
-#define STB0899_OFFST_BB_AGC_REF               0
-#define STB0899_WIDTH_BB_AGC_REF               7
-
-#define STB0899_OFF0_CRL_CNTRL                 0xf328
-#define STB0899_BASE_CRL_CNTRL                 0x00000000
-#define STB0899_CRL_LOCK_CLEAR                 (0x01 << 5)
-#define STB0899_OFFST_CRL_LOCK_CLEAR           5
-#define STB0899_WIDTH_CRL_LOCK_CLEAR           1
-#define STB0899_CRL_SWPR_CLEAR                 (0x01 << 4)
-#define STB0899_OFFST_CRL_SWPR_CLEAR           4
-#define STB0899_WIDTH_CRL_SWPR_CLEAR           1
-#define STB0899_CRL_SWP_ENA                    (0x01 << 3)
-#define STB0899_OFFST_CRL_SWP_ENA              3
-#define STB0899_WIDTH_CRL_SWP_ENA              1
-#define STB0899_CRL_DET_SEL                    (0x01 << 2)
-#define STB0899_OFFST_CRL_DET_SEL              2
-#define STB0899_WIDTH_CRL_DET_SEL              1
-#define STB0899_CRL_SENSE                      (0x01 << 1)
-#define STB0899_OFFST_CRL_SENSE                        1
-#define STB0899_WIDTH_CRL_SENSE                        1
-#define STB0899_CRL_PHSERR_CLEAR               (0x01 << 0)
-#define STB0899_OFFST_CRL_PHSERR_CLEAR         0
-#define STB0899_WIDTH_CRL_PHSERR_CLEAR         1
-
-#define STB0899_OFF0_CRL_PHS_INIT              0xf32c
-#define STB0899_BASE_CRL_PHS_INIT              0x00000000
-#define STB0899_CRL_PHS_INIT_31                        (0x1 << 30)
-#define STB0899_OFFST_CRL_PHS_INIT_31          30
-#define STB0899_WIDTH_CRL_PHS_INIT_31          1
-#define STB0899_CRL_LD_INIT_PHASE              (0x1 << 24)
-#define STB0899_OFFST_CRL_LD_INIT_PHASE                24
-#define STB0899_WIDTH_CRL_LD_INIT_PHASE                1
-#define STB0899_CRL_INIT_PHASE                 (0xffffff << 0)
-#define STB0899_OFFST_CRL_INIT_PHASE           0
-#define STB0899_WIDTH_CRL_INIT_PHASE           24
-
-#define STB0899_OFF0_CRL_FREQ_INIT             0xf330
-#define STB0899_BASE_CRL_FREQ_INIT             0x00000000
-#define STB0899_CRL_FREQ_INIT_31               (0x1 << 30)
-#define STB0899_OFFST_CRL_FREQ_INIT_31         30
-#define STB0899_WIDTH_CRL_FREQ_INIT_31         1
-#define STB0899_CRL_LD_FREQ_INIT               (0x1 << 24)
-#define STB0899_OFFST_CRL_LD_FREQ_INIT         24
-#define STB0899_WIDTH_CRL_LD_FREQ_INIT         1
-#define STB0899_CRL_FREQ_INIT                  (0xffffff << 0)
-#define STB0899_OFFST_CRL_FREQ_INIT            0
-#define STB0899_WIDTH_CRL_FREQ_INIT            24
-
-#define STB0899_OFF0_CRL_LOOP_GAIN             0xf334
-#define STB0899_BASE_CRL_LOOP_GAIN             0x00000000
-#define STB0899_KCRL2_RSHFT                    (0xf << 16)
-#define STB0899_OFFST_KCRL2_RSHFT              16
-#define STB0899_WIDTH_KCRL2_RSHFT              4
-#define STB0899_KCRL1                          (0xf << 12)
-#define STB0899_OFFST_KCRL1                    12
-#define STB0899_WIDTH_KCRL1                    4
-#define STB0899_KCRL1_RSHFT                    (0xf << 8)
-#define STB0899_OFFST_KCRL1_RSHFT              8
-#define STB0899_WIDTH_KCRL1_RSHFT              4
-#define STB0899_KCRL0                          (0xf << 4)
-#define STB0899_OFFST_KCRL0                    4
-#define STB0899_WIDTH_KCRL0                    4
-#define STB0899_KCRL0_RSHFT                    (0xf << 0)
-#define STB0899_OFFST_KCRL0_RSHFT              0
-#define STB0899_WIDTH_KCRL0_RSHFT              4
-
-#define STB0899_OFF0_CRL_NOM_FREQ              0xf338
-#define STB0899_BASE_CRL_NOM_FREQ              0x00000000
-#define STB0899_CRL_NOM_FREQ                   (0x3fffffff << 0)
-#define STB0899_OFFST_CRL_NOM_FREQ             0
-#define STB0899_WIDTH_CRL_NOM_FREQ             30
-
-#define STB0899_OFF0_CRL_SWP_RATE              0xf33c
-#define STB0899_BASE_CRL_SWP_RATE              0x00000000
-#define STB0899_CRL_SWP_RATE                   (0x3fffffff << 0)
-#define STB0899_OFFST_CRL_SWP_RATE             0
-#define STB0899_WIDTH_CRL_SWP_RATE             30
-
-#define STB0899_OFF0_CRL_MAX_SWP               0xf340
-#define STB0899_BASE_CRL_MAX_SWP               0x00000000
-#define STB0899_CRL_MAX_SWP                    (0x3fffffff << 0)
-#define STB0899_OFFST_CRL_MAX_SWP              0
-#define STB0899_WIDTH_CRL_MAX_SWP              30
-
-#define STB0899_OFF0_CRL_LK_CNTRL              0xf344
-#define STB0899_BASE_CRL_LK_CNTRL              0x00000000
-
-#define STB0899_OFF0_DECIM_CNTRL               0xf348
-#define STB0899_BASE_DECIM_CNTRL               0x00000000
-#define STB0899_BAND_LIMIT_B                   (0x01 << 5)
-#define STB0899_OFFST_BAND_LIMIT_B             5
-#define STB0899_WIDTH_BAND_LIMIT_B             1
-#define STB0899_WIN_SEL                                (0x03 << 3)
-#define STB0899_OFFST_WIN_SEL                  3
-#define STB0899_WIDTH_WIN_SEL                  2
-#define STB0899_DECIM_RATE                     (0x07 << 0)
-#define STB0899_OFFST_DECIM_RATE               0
-#define STB0899_WIDTH_DECIM_RATE               3
-
-#define STB0899_OFF0_BTR_CNTRL                 0xf34c
-#define STB0899_BASE_BTR_CNTRL                 0x00000000
-#define STB0899_BTR_FREQ_CORR                  (0x7ff << 4)
-#define STB0899_OFFST_BTR_FREQ_CORR            4
-#define STB0899_WIDTH_BTR_FREQ_CORR            11
-#define STB0899_BTR_CLR_LOCK                   (0x01 << 3)
-#define STB0899_OFFST_BTR_CLR_LOCK             3
-#define STB0899_WIDTH_BTR_CLR_LOCK             1
-#define STB0899_BTR_SENSE                      (0x01 << 2)
-#define STB0899_OFFST_BTR_SENSE                        2
-#define STB0899_WIDTH_BTR_SENSE                        1
-#define STB0899_BTR_ERR_ENA                    (0x01 << 1)
-#define STB0899_OFFST_BTR_ERR_ENA              1
-#define STB0899_WIDTH_BTR_ERR_ENA              1
-#define STB0899_INTRP_PHS_SENSE                        (0x01 << 0)
-#define STB0899_OFFST_INTRP_PHS_SENSE          0
-#define STB0899_WIDTH_INTRP_PHS_SENSE          1
-
-#define STB0899_OFF0_BTR_LOOP_GAIN             0xf350
-#define STB0899_BASE_BTR_LOOP_GAIN             0x00000000
-#define STB0899_KBTR2_RSHFT                    (0x0f << 16)
-#define STB0899_OFFST_KBTR2_RSHFT              16
-#define STB0899_WIDTH_KBTR2_RSHFT              4
-#define STB0899_KBTR1                          (0x0f << 12)
-#define STB0899_OFFST_KBTR1                    12
-#define STB0899_WIDTH_KBTR1                    4
-#define STB0899_KBTR1_RSHFT                    (0x0f << 8)
-#define STB0899_OFFST_KBTR1_RSHFT              8
-#define STB0899_WIDTH_KBTR1_RSHFT              4
-#define STB0899_KBTR0                          (0x0f << 4)
-#define STB0899_OFFST_KBTR0                    4
-#define STB0899_WIDTH_KBTR0                    4
-#define STB0899_KBTR0_RSHFT                    (0x0f << 0)
-#define STB0899_OFFST_KBTR0_RSHFT              0
-#define STB0899_WIDTH_KBTR0_RSHFT              4
-
-#define STB0899_OFF0_BTR_PHS_INIT              0xf354
-#define STB0899_BASE_BTR_PHS_INIT              0x00000000
-#define STB0899_BTR_LD_PHASE_INIT              (0x01 << 28)
-#define STB0899_OFFST_BTR_LD_PHASE_INIT                28
-#define STB0899_WIDTH_BTR_LD_PHASE_INIT                1
-#define STB0899_BTR_INIT_PHASE                 (0xfffffff << 0)
-#define STB0899_OFFST_BTR_INIT_PHASE           0
-#define STB0899_WIDTH_BTR_INIT_PHASE           28
-
-#define STB0899_OFF0_BTR_FREQ_INIT             0xf358
-#define STB0899_BASE_BTR_FREQ_INIT             0x00000000
-#define STB0899_BTR_LD_FREQ_INIT               (1 << 28)
-#define STB0899_OFFST_BTR_LD_FREQ_INIT         28
-#define STB0899_WIDTH_BTR_LD_FREQ_INIT         1
-#define STB0899_BTR_FREQ_INIT                  (0xfffffff << 0)
-#define STB0899_OFFST_BTR_FREQ_INIT            0
-#define STB0899_WIDTH_BTR_FREQ_INIT            28
-
-#define STB0899_OFF0_BTR_NOM_FREQ              0xf35c
-#define STB0899_BASE_BTR_NOM_FREQ              0x00000000
-#define STB0899_BTR_NOM_FREQ                   (0xfffffff << 0)
-#define STB0899_OFFST_BTR_NOM_FREQ             0
-#define STB0899_WIDTH_BTR_NOM_FREQ             28
-
-#define STB0899_OFF0_BTR_LK_CNTRL              0xf360
-#define STB0899_BASE_BTR_LK_CNTRL              0x00000000
-#define STB0899_BTR_MIN_ENERGY                 (0x0f << 24)
-#define STB0899_OFFST_BTR_MIN_ENERGY           24
-#define STB0899_WIDTH_BTR_MIN_ENERGY           4
-#define STB0899_BTR_LOCK_TH_LO                 (0xff << 16)
-#define STB0899_OFFST_BTR_LOCK_TH_LO           16
-#define STB0899_WIDTH_BTR_LOCK_TH_LO           8
-#define STB0899_BTR_LOCK_TH_HI                 (0xff << 8)
-#define STB0899_OFFST_BTR_LOCK_TH_HI           8
-#define STB0899_WIDTH_BTR_LOCK_TH_HI           8
-#define STB0899_BTR_LOCK_GAIN                  (0x03 << 6)
-#define STB0899_OFFST_BTR_LOCK_GAIN            6
-#define STB0899_WIDTH_BTR_LOCK_GAIN            2
-#define STB0899_BTR_LOCK_LEAK                  (0x3f << 0)
-#define STB0899_OFFST_BTR_LOCK_LEAK            0
-#define STB0899_WIDTH_BTR_LOCK_LEAK            6
-
-#define STB0899_OFF0_DECN_CNTRL                        0xf364
-#define STB0899_BASE_DECN_CNTRL                        0x00000000
-
-#define STB0899_OFF0_TP_CNTRL                  0xf368
-#define STB0899_BASE_TP_CNTRL                  0x00000000
-
-#define STB0899_OFF0_TP_BUF_STATUS             0xf36c
-#define STB0899_BASE_TP_BUF_STATUS             0x00000000
-#define STB0899_TP_BUFFER_FULL                  (1 << 0)
-
-#define STB0899_OFF0_DC_ESTIM                  0xf37c
-#define STB0899_BASE_DC_ESTIM                  0x0000
-#define STB0899_I_DC_ESTIMATE                  (0xff << 8)
-#define STB0899_OFFST_I_DC_ESTIMATE            8
-#define STB0899_WIDTH_I_DC_ESTIMATE            8
-#define STB0899_Q_DC_ESTIMATE                  (0xff << 0)
-#define STB0899_OFFST_Q_DC_ESTIMATE            0
-#define STB0899_WIDTH_Q_DC_ESTIMATE            8
-
-#define STB0899_OFF0_FLL_CNTRL                 0xf310
-#define STB0899_BASE_FLL_CNTRL                 0x00000020
-#define STB0899_CRL_FLL_ACC                    (0x01 << 4)
-#define STB0899_OFFST_CRL_FLL_ACC              4
-#define STB0899_WIDTH_CRL_FLL_ACC              1
-#define STB0899_FLL_AVG_PERIOD                 (0x0f << 0)
-#define STB0899_OFFST_FLL_AVG_PERIOD           0
-#define STB0899_WIDTH_FLL_AVG_PERIOD           4
-
-#define STB0899_OFF0_FLL_FREQ_WD               0xf314
-#define STB0899_BASE_FLL_FREQ_WD               0x00000020
-#define STB0899_FLL_FREQ_WD                    (0xffffffff << 0)
-#define STB0899_OFFST_FLL_FREQ_WD              0
-#define STB0899_WIDTH_FLL_FREQ_WD              32
-
-#define STB0899_OFF0_ANTI_ALIAS_SEL            0xf358
-#define STB0899_BASE_ANTI_ALIAS_SEL            0x00000020
-#define STB0899_ANTI_ALIAS_SELB                        (0x03 << 0)
-#define STB0899_OFFST_ANTI_ALIAS_SELB          0
-#define STB0899_WIDTH_ANTI_ALIAS_SELB          2
-
-#define STB0899_OFF0_RRC_ALPHA                 0xf35c
-#define STB0899_BASE_RRC_ALPHA                 0x00000020
-#define STB0899_RRC_ALPHA                      (0x03 << 0)
-#define STB0899_OFFST_RRC_ALPHA                        0
-#define STB0899_WIDTH_RRC_ALPHA                        2
-
-#define STB0899_OFF0_DC_ADAPT_LSHFT            0xf360
-#define STB0899_BASE_DC_ADAPT_LSHFT            0x00000020
-#define STB0899_DC_ADAPT_LSHFT                 (0x077 << 0)
-#define STB0899_OFFST_DC_ADAPT_LSHFT           0
-#define STB0899_WIDTH_DC_ADAPT_LSHFT           3
-
-#define STB0899_OFF0_IMB_OFFSET                        0xf364
-#define STB0899_BASE_IMB_OFFSET                        0x00000020
-#define STB0899_PHS_IMB_COMP                   (0xff << 8)
-#define STB0899_OFFST_PHS_IMB_COMP             8
-#define STB0899_WIDTH_PHS_IMB_COMP             8
-#define STB0899_AMPL_IMB_COMP                  (0xff << 0)
-#define STB0899_OFFST_AMPL_IMB_COMP            0
-#define STB0899_WIDTH_AMPL_IMB_COMP            8
-
-#define STB0899_OFF0_IMB_ESTIMATE              0xf368
-#define STB0899_BASE_IMB_ESTIMATE              0x00000020
-#define STB0899_PHS_IMB_ESTIMATE               (0xff << 8)
-#define STB0899_OFFST_PHS_IMB_ESTIMATE         8
-#define STB0899_WIDTH_PHS_IMB_ESTIMATE         8
-#define STB0899_AMPL_IMB_ESTIMATE              (0xff << 0)
-#define STB0899_OFFST_AMPL_IMB_ESTIMATE                0
-#define STB0899_WIDTH_AMPL_IMB_ESTIMATE                8
-
-#define STB0899_OFF0_IMB_CNTRL                 0xf36c
-#define STB0899_BASE_IMB_CNTRL                 0x00000020
-#define STB0899_PHS_ADAPT_LSHFT                        (0x07 << 4)
-#define STB0899_OFFST_PHS_ADAPT_LSHFT          4
-#define STB0899_WIDTH_PHS_ADAPT_LSHFT          3
-#define STB0899_AMPL_ADAPT_LSHFT               (0x07 << 1)
-#define STB0899_OFFST_AMPL_ADAPT_LSHFT         1
-#define STB0899_WIDTH_AMPL_ADAPT_LSHFT         3
-#define STB0899_IMB_COMP                       (0x01 << 0)
-#define STB0899_OFFST_IMB_COMP                 0
-#define STB0899_WIDTH_IMB_COMP                 1
-
-#define STB0899_OFF0_IF_AGC_CNTRL2             0xf374
-#define STB0899_BASE_IF_AGC_CNTRL2             0x00000020
-#define STB0899_IF_AGC_LOCK_TH                 (0xff << 11)
-#define STB0899_OFFST_IF_AGC_LOCK_TH           11
-#define STB0899_WIDTH_IF_AGC_LOCK_TH           8
-#define STB0899_IF_AGC_SD_DIV                  (0xff << 3)
-#define STB0899_OFFST_IF_AGC_SD_DIV            3
-#define STB0899_WIDTH_IF_AGC_SD_DIV            8
-#define STB0899_IF_AGC_DUMP_PER                        (0x07 << 0)
-#define STB0899_OFFST_IF_AGC_DUMP_PER          0
-#define STB0899_WIDTH_IF_AGC_DUMP_PER          3
-
-#define STB0899_OFF0_DMD_CNTRL2                        0xf378
-#define STB0899_BASE_DMD_CNTRL2                        0x00000020
-#define STB0899_SPECTRUM_INVERT                        (0x01 << 2)
-#define STB0899_OFFST_SPECTRUM_INVERT          2
-#define STB0899_WIDTH_SPECTRUM_INVERT          1
-#define STB0899_AGC_MODE                       (0x01 << 1)
-#define STB0899_OFFST_AGC_MODE                 1
-#define STB0899_WIDTH_AGC_MODE                 1
-#define STB0899_CRL_FREQ_ADJ                   (0x01 << 0)
-#define STB0899_OFFST_CRL_FREQ_ADJ             0
-#define STB0899_WIDTH_CRL_FREQ_ADJ             1
-
-#define STB0899_OFF0_TP_BUFFER                 0xf300
-#define STB0899_BASE_TP_BUFFER                 0x00000040
-#define STB0899_TP_BUFFER_IN                   (0xffff << 0)
-#define STB0899_OFFST_TP_BUFFER_IN             0
-#define STB0899_WIDTH_TP_BUFFER_IN             16
-
-#define STB0899_OFF0_TP_BUFFER1                        0xf304
-#define STB0899_BASE_TP_BUFFER1                        0x00000040
-#define STB0899_OFF0_TP_BUFFER2                        0xf308
-#define STB0899_BASE_TP_BUFFER2                        0x00000040
-#define STB0899_OFF0_TP_BUFFER3                        0xf30c
-#define STB0899_BASE_TP_BUFFER3                        0x00000040
-#define STB0899_OFF0_TP_BUFFER4                        0xf310
-#define STB0899_BASE_TP_BUFFER4                        0x00000040
-#define STB0899_OFF0_TP_BUFFER5                        0xf314
-#define STB0899_BASE_TP_BUFFER5                        0x00000040
-#define STB0899_OFF0_TP_BUFFER6                        0xf318
-#define STB0899_BASE_TP_BUFFER6                        0x00000040
-#define STB0899_OFF0_TP_BUFFER7                        0xf31c
-#define STB0899_BASE_TP_BUFFER7                        0x00000040
-#define STB0899_OFF0_TP_BUFFER8                        0xf320
-#define STB0899_BASE_TP_BUFFER8                        0x00000040
-#define STB0899_OFF0_TP_BUFFER9                        0xf324
-#define STB0899_BASE_TP_BUFFER9                        0x00000040
-#define STB0899_OFF0_TP_BUFFER10               0xf328
-#define STB0899_BASE_TP_BUFFER10               0x00000040
-#define STB0899_OFF0_TP_BUFFER11               0xf32c
-#define STB0899_BASE_TP_BUFFER11               0x00000040
-#define STB0899_OFF0_TP_BUFFER12               0xf330
-#define STB0899_BASE_TP_BUFFER12               0x00000040
-#define STB0899_OFF0_TP_BUFFER13               0xf334
-#define STB0899_BASE_TP_BUFFER13               0x00000040
-#define STB0899_OFF0_TP_BUFFER14               0xf338
-#define STB0899_BASE_TP_BUFFER14               0x00000040
-#define STB0899_OFF0_TP_BUFFER15               0xf33c
-#define STB0899_BASE_TP_BUFFER15               0x00000040
-#define STB0899_OFF0_TP_BUFFER16               0xf340
-#define STB0899_BASE_TP_BUFFER16               0x00000040
-#define STB0899_OFF0_TP_BUFFER17               0xf344
-#define STB0899_BASE_TP_BUFFER17               0x00000040
-#define STB0899_OFF0_TP_BUFFER18               0xf348
-#define STB0899_BASE_TP_BUFFER18               0x00000040
-#define STB0899_OFF0_TP_BUFFER19               0xf34c
-#define STB0899_BASE_TP_BUFFER19               0x00000040
-#define STB0899_OFF0_TP_BUFFER20               0xf350
-#define STB0899_BASE_TP_BUFFER20               0x00000040
-#define STB0899_OFF0_TP_BUFFER21               0xf354
-#define STB0899_BASE_TP_BUFFER21               0x00000040
-#define STB0899_OFF0_TP_BUFFER22               0xf358
-#define STB0899_BASE_TP_BUFFER22               0x00000040
-#define STB0899_OFF0_TP_BUFFER23               0xf35c
-#define STB0899_BASE_TP_BUFFER23               0x00000040
-#define STB0899_OFF0_TP_BUFFER24               0xf360
-#define STB0899_BASE_TP_BUFFER24               0x00000040
-#define STB0899_OFF0_TP_BUFFER25               0xf364
-#define STB0899_BASE_TP_BUFFER25               0x00000040
-#define STB0899_OFF0_TP_BUFFER26               0xf368
-#define STB0899_BASE_TP_BUFFER26               0x00000040
-#define STB0899_OFF0_TP_BUFFER27               0xf36c
-#define STB0899_BASE_TP_BUFFER27               0x00000040
-#define STB0899_OFF0_TP_BUFFER28               0xf370
-#define STB0899_BASE_TP_BUFFER28               0x00000040
-#define STB0899_OFF0_TP_BUFFER29               0xf374
-#define STB0899_BASE_TP_BUFFER29               0x00000040
-#define STB0899_OFF0_TP_BUFFER30               0xf378
-#define STB0899_BASE_TP_BUFFER30               0x00000040
-#define STB0899_OFF0_TP_BUFFER31               0xf37c
-#define STB0899_BASE_TP_BUFFER31               0x00000040
-#define STB0899_OFF0_TP_BUFFER32               0xf300
-#define STB0899_BASE_TP_BUFFER32               0x00000060
-#define STB0899_OFF0_TP_BUFFER33               0xf304
-#define STB0899_BASE_TP_BUFFER33               0x00000060
-#define STB0899_OFF0_TP_BUFFER34               0xf308
-#define STB0899_BASE_TP_BUFFER34               0x00000060
-#define STB0899_OFF0_TP_BUFFER35               0xf30c
-#define STB0899_BASE_TP_BUFFER35               0x00000060
-#define STB0899_OFF0_TP_BUFFER36               0xf310
-#define STB0899_BASE_TP_BUFFER36               0x00000060
-#define STB0899_OFF0_TP_BUFFER37               0xf314
-#define STB0899_BASE_TP_BUFFER37               0x00000060
-#define STB0899_OFF0_TP_BUFFER38               0xf318
-#define STB0899_BASE_TP_BUFFER38               0x00000060
-#define STB0899_OFF0_TP_BUFFER39               0xf31c
-#define STB0899_BASE_TP_BUFFER39               0x00000060
-#define STB0899_OFF0_TP_BUFFER40               0xf320
-#define STB0899_BASE_TP_BUFFER40               0x00000060
-#define STB0899_OFF0_TP_BUFFER41               0xf324
-#define STB0899_BASE_TP_BUFFER41               0x00000060
-#define STB0899_OFF0_TP_BUFFER42               0xf328
-#define STB0899_BASE_TP_BUFFER42               0x00000060
-#define STB0899_OFF0_TP_BUFFER43               0xf32c
-#define STB0899_BASE_TP_BUFFER43               0x00000060
-#define STB0899_OFF0_TP_BUFFER44               0xf330
-#define STB0899_BASE_TP_BUFFER44               0x00000060
-#define STB0899_OFF0_TP_BUFFER45               0xf334
-#define STB0899_BASE_TP_BUFFER45               0x00000060
-#define STB0899_OFF0_TP_BUFFER46               0xf338
-#define STB0899_BASE_TP_BUFFER46               0x00000060
-#define STB0899_OFF0_TP_BUFFER47               0xf33c
-#define STB0899_BASE_TP_BUFFER47               0x00000060
-#define STB0899_OFF0_TP_BUFFER48               0xf340
-#define STB0899_BASE_TP_BUFFER48               0x00000060
-#define STB0899_OFF0_TP_BUFFER49               0xf344
-#define STB0899_BASE_TP_BUFFER49               0x00000060
-#define STB0899_OFF0_TP_BUFFER50               0xf348
-#define STB0899_BASE_TP_BUFFER50               0x00000060
-#define STB0899_OFF0_TP_BUFFER51               0xf34c
-#define STB0899_BASE_TP_BUFFER51               0x00000060
-#define STB0899_OFF0_TP_BUFFER52               0xf350
-#define STB0899_BASE_TP_BUFFER52               0x00000060
-#define STB0899_OFF0_TP_BUFFER53               0xf354
-#define STB0899_BASE_TP_BUFFER53               0x00000060
-#define STB0899_OFF0_TP_BUFFER54               0xf358
-#define STB0899_BASE_TP_BUFFER54               0x00000060
-#define STB0899_OFF0_TP_BUFFER55               0xf35c
-#define STB0899_BASE_TP_BUFFER55               0x00000060
-#define STB0899_OFF0_TP_BUFFER56               0xf360
-#define STB0899_BASE_TP_BUFFER56               0x00000060
-#define STB0899_OFF0_TP_BUFFER57               0xf364
-#define STB0899_BASE_TP_BUFFER57               0x00000060
-#define STB0899_OFF0_TP_BUFFER58               0xf368
-#define STB0899_BASE_TP_BUFFER58               0x00000060
-#define STB0899_OFF0_TP_BUFFER59               0xf36c
-#define STB0899_BASE_TP_BUFFER59               0x00000060
-#define STB0899_OFF0_TP_BUFFER60               0xf370
-#define STB0899_BASE_TP_BUFFER60               0x00000060
-#define STB0899_OFF0_TP_BUFFER61               0xf374
-#define STB0899_BASE_TP_BUFFER61               0x00000060
-#define STB0899_OFF0_TP_BUFFER62               0xf378
-#define STB0899_BASE_TP_BUFFER62               0x00000060
-#define STB0899_OFF0_TP_BUFFER63               0xf37c
-#define STB0899_BASE_TP_BUFFER63               0x00000060
-
-#define STB0899_OFF0_RESET_CNTRL               0xf300
-#define STB0899_BASE_RESET_CNTRL               0x00000400
-#define STB0899_DVBS2_RESET                    (0x01 << 0)
-#define STB0899_OFFST_DVBS2_RESET              0
-#define STB0899_WIDTH_DVBS2_RESET              1
-
-#define STB0899_OFF0_ACM_ENABLE                        0xf304
-#define STB0899_BASE_ACM_ENABLE                        0x00000400
-#define STB0899_ACM_ENABLE                     1
-
-#define STB0899_OFF0_DESCR_CNTRL               0xf30c
-#define STB0899_BASE_DESCR_CNTRL               0x00000400
-#define STB0899_OFFST_DESCR_CNTRL               0
-#define STB0899_WIDTH_DESCR_CNTRL               16
-
-#define STB0899_OFF0_UWP_CNTRL1                        0xf320
-#define STB0899_BASE_UWP_CNTRL1                        0x00000400
-#define STB0899_UWP_TH_SOF                     (0x7fff << 11)
-#define STB0899_OFFST_UWP_TH_SOF               11
-#define STB0899_WIDTH_UWP_TH_SOF               15
-#define STB0899_UWP_ESN0_QUANT                 (0xff << 3)
-#define STB0899_OFFST_UWP_ESN0_QUANT           3
-#define STB0899_WIDTH_UWP_ESN0_QUANT           8
-#define STB0899_UWP_ESN0_AVE                   (0x03 << 1)
-#define STB0899_OFFST_UWP_ESN0_AVE             1
-#define STB0899_WIDTH_UWP_ESN0_AVE             2
-#define STB0899_UWP_START                      (0x01 << 0)
-#define STB0899_OFFST_UWP_START                        0
-#define STB0899_WIDTH_UWP_START                        1
-
-#define STB0899_OFF0_UWP_CNTRL2                        0xf324
-#define STB0899_BASE_UWP_CNTRL2                        0x00000400
-#define STB0899_UWP_MISS_TH                    (0xff << 16)
-#define STB0899_OFFST_UWP_MISS_TH              16
-#define STB0899_WIDTH_UWP_MISS_TH              8
-#define STB0899_FE_FINE_TRK                    (0xff << 8)
-#define STB0899_OFFST_FE_FINE_TRK              8
-#define STB0899_WIDTH_FE_FINE_TRK              8
-#define STB0899_FE_COARSE_TRK                  (0xff << 0)
-#define STB0899_OFFST_FE_COARSE_TRK            0
-#define STB0899_WIDTH_FE_COARSE_TRK            8
-
-#define STB0899_OFF0_UWP_STAT1                 0xf328
-#define STB0899_BASE_UWP_STAT1                 0x00000400
-#define STB0899_UWP_STATE                      (0x03ff << 15)
-#define STB0899_OFFST_UWP_STATE                        15
-#define STB0899_WIDTH_UWP_STATE                        10
-#define STB0899_UW_MAX_PEAK                    (0x7fff << 0)
-#define STB0899_OFFST_UW_MAX_PEAK              0
-#define STB0899_WIDTH_UW_MAX_PEAK              15
-
-#define STB0899_OFF0_UWP_STAT2                 0xf32c
-#define STB0899_BASE_UWP_STAT2                 0x00000400
-#define STB0899_ESNO_EST                       (0x07ffff << 7)
-#define STB0899_OFFST_ESN0_EST                 7
-#define STB0899_WIDTH_ESN0_EST                 19
-#define STB0899_UWP_DECODE_MOD                 (0x7f << 0)
-#define STB0899_OFFST_UWP_DECODE_MOD           0
-#define STB0899_WIDTH_UWP_DECODE_MOD           7
-
-#define STB0899_OFF0_DMD_CORE_ID               0xf334
-#define STB0899_BASE_DMD_CORE_ID               0x00000400
-#define STB0899_CORE_ID                                (0xffffffff << 0)
-#define STB0899_OFFST_CORE_ID                  0
-#define STB0899_WIDTH_CORE_ID                  32
-
-#define STB0899_OFF0_DMD_VERSION_ID            0xf33c
-#define STB0899_BASE_DMD_VERSION_ID            0x00000400
-#define STB0899_VERSION_ID                     (0xff << 0)
-#define STB0899_OFFST_VERSION_ID               0
-#define STB0899_WIDTH_VERSION_ID               8
-
-#define STB0899_OFF0_DMD_STAT2                 0xf340
-#define STB0899_BASE_DMD_STAT2                 0x00000400
-#define STB0899_CSM_LOCK                       (0x01 << 1)
-#define STB0899_OFFST_CSM_LOCK                 1
-#define STB0899_WIDTH_CSM_LOCK                 1
-#define STB0899_UWP_LOCK                       (0x01 << 0)
-#define STB0899_OFFST_UWP_LOCK                 0
-#define STB0899_WIDTH_UWP_LOCK                 1
-
-#define STB0899_OFF0_FREQ_ADJ_SCALE            0xf344
-#define STB0899_BASE_FREQ_ADJ_SCALE            0x00000400
-#define STB0899_FREQ_ADJ_SCALE                 (0x0fff << 0)
-#define STB0899_OFFST_FREQ_ADJ_SCALE           0
-#define STB0899_WIDTH_FREQ_ADJ_SCALE           12
-
-#define STB0899_OFF0_UWP_CNTRL3                        0xf34c
-#define STB0899_BASE_UWP_CNTRL3                        0x00000400
-#define STB0899_UWP_TH_TRACK                   (0x7fff << 15)
-#define STB0899_OFFST_UWP_TH_TRACK             15
-#define STB0899_WIDTH_UWP_TH_TRACK             15
-#define STB0899_UWP_TH_ACQ                     (0x7fff << 0)
-#define STB0899_OFFST_UWP_TH_ACQ               0
-#define STB0899_WIDTH_UWP_TH_ACQ               15
-
-#define STB0899_OFF0_SYM_CLK_SEL               0xf350
-#define STB0899_BASE_SYM_CLK_SEL               0x00000400
-#define STB0899_SYM_CLK_SEL                    (0x03 << 0)
-#define STB0899_OFFST_SYM_CLK_SEL              0
-#define STB0899_WIDTH_SYM_CLK_SEL              2
-
-#define STB0899_OFF0_SOF_SRCH_TO               0xf354
-#define STB0899_BASE_SOF_SRCH_TO               0x00000400
-#define STB0899_SOF_SEARCH_TIMEOUT             (0x3fffff << 0)
-#define STB0899_OFFST_SOF_SEARCH_TIMEOUT       0
-#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT       22
-
-#define STB0899_OFF0_ACQ_CNTRL1                        0xf358
-#define STB0899_BASE_ACQ_CNTRL1                        0x00000400
-#define STB0899_FE_FINE_ACQ                    (0xff << 8)
-#define STB0899_OFFST_FE_FINE_ACQ              8
-#define STB0899_WIDTH_FE_FINE_ACQ              8
-#define STB0899_FE_COARSE_ACQ                  (0xff << 0)
-#define STB0899_OFFST_FE_COARSE_ACQ            0
-#define STB0899_WIDTH_FE_COARSE_ACQ            8
-
-#define STB0899_OFF0_ACQ_CNTRL2                        0xf35c
-#define STB0899_BASE_ACQ_CNTRL2                        0x00000400
-#define STB0899_ZIGZAG                         (0x01 << 25)
-#define STB0899_OFFST_ZIGZAG                   25
-#define STB0899_WIDTH_ZIGZAG                   1
-#define STB0899_NUM_STEPS                      (0xff << 17)
-#define STB0899_OFFST_NUM_STEPS                        17
-#define STB0899_WIDTH_NUM_STEPS                        8
-#define STB0899_FREQ_STEPSIZE                  (0x1ffff << 0)
-#define STB0899_OFFST_FREQ_STEPSIZE            0
-#define STB0899_WIDTH_FREQ_STEPSIZE            17
-
-#define STB0899_OFF0_ACQ_CNTRL3                        0xf360
-#define STB0899_BASE_ACQ_CNTRL3                        0x00000400
-#define STB0899_THRESHOLD_SCL                  (0x3f << 23)
-#define STB0899_OFFST_THRESHOLD_SCL            23
-#define STB0899_WIDTH_THRESHOLD_SCL            6
-#define STB0899_UWP_TH_SRCH                    (0x7fff << 8)
-#define STB0899_OFFST_UWP_TH_SRCH              8
-#define STB0899_WIDTH_UWP_TH_SRCH              15
-#define STB0899_AUTO_REACQUIRE                 (0x01 << 7)
-#define STB0899_OFFST_AUTO_REACQUIRE           7
-#define STB0899_WIDTH_AUTO_REACQUIRE           1
-#define STB0899_TRACK_LOCK_SEL                 (0x01 << 6)
-#define STB0899_OFFST_TRACK_LOCK_SEL           6
-#define STB0899_WIDTH_TRACK_LOCK_SEL           1
-#define STB0899_ACQ_SEARCH_MODE                        (0x03 << 4)
-#define STB0899_OFFST_ACQ_SEARCH_MODE          4
-#define STB0899_WIDTH_ACQ_SEARCH_MODE          2
-#define STB0899_CONFIRM_FRAMES                 (0x0f << 0)
-#define STB0899_OFFST_CONFIRM_FRAMES           0
-#define STB0899_WIDTH_CONFIRM_FRAMES           4
-
-#define STB0899_OFF0_FE_SETTLE                 0xf364
-#define STB0899_BASE_FE_SETTLE                 0x00000400
-#define STB0899_SETTLING_TIME                  (0x3fffff << 0)
-#define STB0899_OFFST_SETTLING_TIME            0
-#define STB0899_WIDTH_SETTLING_TIME            22
-
-#define STB0899_OFF0_AC_DWELL                  0xf368
-#define STB0899_BASE_AC_DWELL                  0x00000400
-#define STB0899_DWELL_TIME                     (0x3fffff << 0)
-#define STB0899_OFFST_DWELL_TIME               0
-#define STB0899_WIDTH_DWELL_TIME               22
-
-#define STB0899_OFF0_ACQUIRE_TRIG              0xf36c
-#define STB0899_BASE_ACQUIRE_TRIG              0x00000400
-#define STB0899_ACQUIRE                                (0x01 << 0)
-#define STB0899_OFFST_ACQUIRE                  0
-#define STB0899_WIDTH_ACQUIRE                  1
-
-#define STB0899_OFF0_LOCK_LOST                 0xf370
-#define STB0899_BASE_LOCK_LOST                 0x00000400
-#define STB0899_LOCK_LOST                      (0x01 << 0)
-#define STB0899_OFFST_LOCK_LOST                        0
-#define STB0899_WIDTH_LOCK_LOST                        1
-
-#define STB0899_OFF0_ACQ_STAT1                 0xf374
-#define STB0899_BASE_ACQ_STAT1                 0x00000400
-#define STB0899_STEP_FREQ                      (0x1fffff << 11)
-#define STB0899_OFFST_STEP_FREQ                        11
-#define STB0899_WIDTH_STEP_FREQ                        21
-#define STB0899_ACQ_STATE                      (0x07 << 8)
-#define STB0899_OFFST_ACQ_STATE                        8
-#define STB0899_WIDTH_ACQ_STATE                        3
-#define STB0899_UW_DETECT_COUNT                        (0xff << 0)
-#define STB0899_OFFST_UW_DETECT_COUNT          0
-#define STB0899_WIDTH_UW_DETECT_COUNT          8
-
-#define STB0899_OFF0_ACQ_TIMEOUT               0xf378
-#define STB0899_BASE_ACQ_TIMEOUT               0x00000400
-#define STB0899_ACQ_TIMEOUT                    (0x3fffff << 0)
-#define STB0899_OFFST_ACQ_TIMEOUT              0
-#define STB0899_WIDTH_ACQ_TIMEOUT              22
-
-#define STB0899_OFF0_ACQ_TIME                  0xf37c
-#define STB0899_BASE_ACQ_TIME                  0x00000400
-#define STB0899_ACQ_TIME_SYM                   (0xffffff << 0)
-#define STB0899_OFFST_ACQ_TIME_SYM             0
-#define STB0899_WIDTH_ACQ_TIME_SYM             24
-
-#define STB0899_OFF0_FINAL_AGC_CNTRL           0xf308
-#define STB0899_BASE_FINAL_AGC_CNTRL           0x00000440
-#define STB0899_FINAL_GAIN_INIT                        (0x3fff << 12)
-#define STB0899_OFFST_FINAL_GAIN_INIT          12
-#define STB0899_WIDTH_FINAL_GAIN_INIT          14
-#define STB0899_FINAL_LOOP_GAIN                        (0x0f << 8)
-#define STB0899_OFFST_FINAL_LOOP_GAIN          8
-#define STB0899_WIDTH_FINAL_LOOP_GAIN          4
-#define STB0899_FINAL_LD_GAIN_INIT             (0x01 << 7)
-#define STB0899_OFFST_FINAL_LD_GAIN_INIT       7
-#define STB0899_WIDTH_FINAL_LD_GAIN_INIT       1
-#define STB0899_FINAL_AGC_REF                  (0x7f << 0)
-#define STB0899_OFFST_FINAL_AGC_REF            0
-#define STB0899_WIDTH_FINAL_AGC_REF            7
-
-#define STB0899_OFF0_FINAL_AGC_GAIN            0xf30c
-#define STB0899_BASE_FINAL_AGC_GAIN            0x00000440
-#define STB0899_FINAL_AGC_GAIN                 (0x3fff << 0)
-#define STB0899_OFFST_FINAL_AGC_GAIN           0
-#define STB0899_WIDTH_FINAL_AGC_GAIN           14
-
-#define STB0899_OFF0_EQUALIZER_INIT            0xf310
-#define STB0899_BASE_EQUALIZER_INIT            0x00000440
-#define STB0899_EQ_SRST                                (0x01 << 1)
-#define STB0899_OFFST_EQ_SRST                  1
-#define STB0899_WIDTH_EQ_SRST                  1
-#define STB0899_EQ_INIT                                (0x01 << 0)
-#define STB0899_OFFST_EQ_INIT                  0
-#define STB0899_WIDTH_EQ_INIT                  1
-
-#define STB0899_OFF0_EQ_CNTRL                  0xf314
-#define STB0899_BASE_EQ_CNTRL                  0x00000440
-#define STB0899_EQ_ADAPT_MODE                  (0x01 << 18)
-#define STB0899_OFFST_EQ_ADAPT_MODE            18
-#define STB0899_WIDTH_EQ_ADAPT_MODE            1
-#define STB0899_EQ_DELAY                       (0x0f << 14)
-#define STB0899_OFFST_EQ_DELAY                 14
-#define STB0899_WIDTH_EQ_DELAY                 4
-#define STB0899_EQ_QUANT_LEVEL                 (0xff << 6)
-#define STB0899_OFFST_EQ_QUANT_LEVEL           6
-#define STB0899_WIDTH_EQ_QUANT_LEVEL           8
-#define STB0899_EQ_DISABLE_UPDATE              (0x01 << 5)
-#define STB0899_OFFST_EQ_DISABLE_UPDATE                5
-#define STB0899_WIDTH_EQ_DISABLE_UPDATE                1
-#define STB0899_EQ_BYPASS                      (0x01 << 4)
-#define STB0899_OFFST_EQ_BYPASS                        4
-#define STB0899_WIDTH_EQ_BYPASS                        1
-#define STB0899_EQ_SHIFT                       (0x0f << 0)
-#define STB0899_OFFST_EQ_SHIFT                 0
-#define STB0899_WIDTH_EQ_SHIFT                 4
-
-#define STB0899_OFF0_EQ_I_INIT_COEFF_0         0xf320
-#define STB0899_OFF1_EQ_I_INIT_COEFF_1         0xf324
-#define STB0899_OFF2_EQ_I_INIT_COEFF_2         0xf328
-#define STB0899_OFF3_EQ_I_INIT_COEFF_3         0xf32c
-#define STB0899_OFF4_EQ_I_INIT_COEFF_4         0xf330
-#define STB0899_OFF5_EQ_I_INIT_COEFF_5         0xf334
-#define STB0899_OFF6_EQ_I_INIT_COEFF_6         0xf338
-#define STB0899_OFF7_EQ_I_INIT_COEFF_7         0xf33c
-#define STB0899_OFF8_EQ_I_INIT_COEFF_8         0xf340
-#define STB0899_OFF9_EQ_I_INIT_COEFF_9         0xf344
-#define STB0899_OFFa_EQ_I_INIT_COEFF_10                0xf348
-#define STB0899_BASE_EQ_I_INIT_COEFF_N         0x00000440
-#define STB0899_EQ_I_INIT_COEFF_N              (0x0fff << 0)
-#define STB0899_OFFST_EQ_I_INIT_COEFF_N                0
-#define STB0899_WIDTH_EQ_I_INIT_COEFF_N                12
-
-#define STB0899_OFF0_EQ_Q_INIT_COEFF_0         0xf350
-#define STB0899_OFF1_EQ_Q_INIT_COEFF_1         0xf354
-#define STB0899_OFF2_EQ_Q_INIT_COEFF_2         0xf358
-#define STB0899_OFF3_EQ_Q_INIT_COEFF_3         0xf35c
-#define STB0899_OFF4_EQ_Q_INIT_COEFF_4         0xf360
-#define STB0899_OFF5_EQ_Q_INIT_COEFF_5         0xf364
-#define STB0899_OFF6_EQ_Q_INIT_COEFF_6         0xf368
-#define STB0899_OFF7_EQ_Q_INIT_COEFF_7         0xf36c
-#define STB0899_OFF8_EQ_Q_INIT_COEFF_8         0xf370
-#define STB0899_OFF9_EQ_Q_INIT_COEFF_9         0xf374
-#define STB0899_OFFa_EQ_Q_INIT_COEFF_10                0xf378
-#define STB0899_BASE_EQ_Q_INIT_COEFF_N         0x00000440
-#define STB0899_EQ_Q_INIT_COEFF_N              (0x0fff << 0)
-#define STB0899_OFFST_EQ_Q_INIT_COEFF_N                0
-#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N                12
-
-#define STB0899_OFF0_EQ_I_OUT_COEFF_0          0xf300
-#define STB0899_OFF1_EQ_I_OUT_COEFF_1          0xf304
-#define STB0899_OFF2_EQ_I_OUT_COEFF_2          0xf308
-#define STB0899_OFF3_EQ_I_OUT_COEFF_3          0xf30c
-#define STB0899_OFF4_EQ_I_OUT_COEFF_4          0xf310
-#define STB0899_OFF5_EQ_I_OUT_COEFF_5          0xf314
-#define STB0899_OFF6_EQ_I_OUT_COEFF_6          0xf318
-#define STB0899_OFF7_EQ_I_OUT_COEFF_7          0xf31c
-#define STB0899_OFF8_EQ_I_OUT_COEFF_8          0xf320
-#define STB0899_OFF9_EQ_I_OUT_COEFF_9          0xf324
-#define STB0899_OFFa_EQ_I_OUT_COEFF_10         0xf328
-#define STB0899_BASE_EQ_I_OUT_COEFF_N          0x00000460
-#define STB0899_EQ_I_OUT_COEFF_N               (0x0fff << 0)
-#define STB0899_OFFST_EQ_I_OUT_COEFF_N         0
-#define STB0899_WIDTH_EQ_I_OUT_COEFF_N         12
-
-#define STB0899_OFF0_EQ_Q_OUT_COEFF_0          0xf330
-#define STB0899_OFF1_EQ_Q_OUT_COEFF_1          0xf334
-#define STB0899_OFF2_EQ_Q_OUT_COEFF_2          0xf338
-#define STB0899_OFF3_EQ_Q_OUT_COEFF_3          0xf33c
-#define STB0899_OFF4_EQ_Q_OUT_COEFF_4          0xf340
-#define STB0899_OFF5_EQ_Q_OUT_COEFF_5          0xf344
-#define STB0899_OFF6_EQ_Q_OUT_COEFF_6          0xf348
-#define STB0899_OFF7_EQ_Q_OUT_COEFF_7          0xf34c
-#define STB0899_OFF8_EQ_Q_OUT_COEFF_8          0xf350
-#define STB0899_OFF9_EQ_Q_OUT_COEFF_9          0xf354
-#define STB0899_OFFa_EQ_Q_OUT_COEFF_10         0xf358
-#define STB0899_BASE_EQ_Q_OUT_COEFF_N          0x00000460
-#define STB0899_EQ_Q_OUT_COEFF_N               (0x0fff << 0)
-#define STB0899_OFFST_EQ_Q_OUT_COEFF_N         0
-#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N         12
-
-/*     S2 FEC  */
-#define STB0899_OFF0_BLOCK_LNGTH               0xfa04
-#define STB0899_BASE_BLOCK_LNGTH               0x00000000
-#define STB0899_BLOCK_LENGTH                   (0xff << 0)
-#define STB0899_OFFST_BLOCK_LENGTH             0
-#define STB0899_WIDTH_BLOCK_LENGTH             8
-
-#define STB0899_OFF0_ROW_STR                   0xfa08
-#define STB0899_BASE_ROW_STR                   0x00000000
-#define STB0899_ROW_STRIDE                     (0xff << 0)
-#define STB0899_OFFST_ROW_STRIDE               0
-#define STB0899_WIDTH_ROW_STRIDE               8
-
-#define STB0899_OFF0_MAX_ITER                  0xfa0c
-#define STB0899_BASE_MAX_ITER                  0x00000000
-#define STB0899_MAX_ITERATIONS                 (0xff << 0)
-#define STB0899_OFFST_MAX_ITERATIONS           0
-#define STB0899_WIDTH_MAX_ITERATIONS           8
-
-#define STB0899_OFF0_BN_END_ADDR               0xfa10
-#define STB0899_BASE_BN_END_ADDR               0x00000000
-#define STB0899_BN_END_ADDR                    (0x0fff << 0)
-#define STB0899_OFFST_BN_END_ADDR              0
-#define STB0899_WIDTH_BN_END_ADDR              12
-
-#define STB0899_OFF0_CN_END_ADDR               0xfa14
-#define STB0899_BASE_CN_END_ADDR               0x00000000
-#define STB0899_CN_END_ADDR                    (0x0fff << 0)
-#define STB0899_OFFST_CN_END_ADDR              0
-#define STB0899_WIDTH_CN_END_ADDR              12
-
-#define STB0899_OFF0_INFO_LENGTH               0xfa1c
-#define STB0899_BASE_INFO_LENGTH               0x00000000
-#define STB0899_INFO_LENGTH                    (0xff << 0)
-#define STB0899_OFFST_INFO_LENGTH              0
-#define STB0899_WIDTH_INFO_LENGTH              8
-
-#define STB0899_OFF0_BOT_ADDR                  0xfa20
-#define STB0899_BASE_BOT_ADDR                  0x00000000
-#define STB0899_BOTTOM_BASE_ADDR               (0x03ff << 0)
-#define STB0899_OFFST_BOTTOM_BASE_ADDR         0
-#define STB0899_WIDTH_BOTTOM_BASE_ADDR         10
-
-#define STB0899_OFF0_BCH_BLK_LN                        0xfa24
-#define STB0899_BASE_BCH_BLK_LN                        0x00000000
-#define STB0899_BCH_BLOCK_LENGTH               (0xffff << 0)
-#define STB0899_OFFST_BCH_BLOCK_LENGTH         0
-#define STB0899_WIDTH_BCH_BLOCK_LENGTH         16
-
-#define STB0899_OFF0_BCH_T                     0xfa28
-#define STB0899_BASE_BCH_T                     0x00000000
-#define STB0899_BCH_T                          (0x0f << 0)
-#define STB0899_OFFST_BCH_T                    0
-#define STB0899_WIDTH_BCH_T                    4
-
-#define STB0899_OFF0_CNFG_MODE                 0xfa00
-#define STB0899_BASE_CNFG_MODE                 0x00000800
-#define STB0899_MODCOD                         (0x1f << 2)
-#define STB0899_OFFST_MODCOD                   2
-#define STB0899_WIDTH_MODCOD                   5
-#define STB0899_MODCOD_SEL                     (0x01 << 1)
-#define STB0899_OFFST_MODCOD_SEL               1
-#define STB0899_WIDTH_MODCOD_SEL               1
-#define STB0899_CONFIG_MODE                    (0x01 << 0)
-#define STB0899_OFFST_CONFIG_MODE              0
-#define STB0899_WIDTH_CONFIG_MODE              1
-
-#define STB0899_OFF0_LDPC_STAT                 0xfa04
-#define STB0899_BASE_LDPC_STAT                 0x00000800
-#define STB0899_ITERATION                      (0xff << 3)
-#define STB0899_OFFST_ITERATION                        3
-#define STB0899_WIDTH_ITERATION                        8
-#define STB0899_LDPC_DEC_STATE                 (0x07 << 0)
-#define STB0899_OFFST_LDPC_DEC_STATE           0
-#define STB0899_WIDTH_LDPC_DEC_STATE           3
-
-#define STB0899_OFF0_ITER_SCALE                        0xfa08
-#define STB0899_BASE_ITER_SCALE                        0x00000800
-#define STB0899_ITERATION_SCALE                        (0xff << 0)
-#define STB0899_OFFST_ITERATION_SCALE          0
-#define STB0899_WIDTH_ITERATION_SCALE          8
-
-#define STB0899_OFF0_INPUT_MODE                        0xfa0c
-#define STB0899_BASE_INPUT_MODE                        0x00000800
-#define STB0899_SD_BLOCK1_STREAM0              (0x01 << 0)
-#define STB0899_OFFST_SD_BLOCK1_STREAM0                0
-#define STB0899_WIDTH_SD_BLOCK1_STREAM0                1
-
-#define STB0899_OFF0_LDPCDECRST                        0xfa10
-#define STB0899_BASE_LDPCDECRST                        0x00000800
-#define STB0899_LDPC_DEC_RST                   (0x01 << 0)
-#define STB0899_OFFST_LDPC_DEC_RST             0
-#define STB0899_WIDTH_LDPC_DEC_RST             1
-
-#define STB0899_OFF0_CLK_PER_BYTE_RW           0xfa14
-#define STB0899_BASE_CLK_PER_BYTE_RW           0x00000800
-#define STB0899_CLKS_PER_BYTE                  (0x0f << 0)
-#define STB0899_OFFST_CLKS_PER_BYTE            0
-#define STB0899_WIDTH_CLKS_PER_BYTE            5
-
-#define STB0899_OFF0_BCH_ERRORS                        0xfa18
-#define STB0899_BASE_BCH_ERRORS                        0x00000800
-#define STB0899_BCH_ERRORS                     (0x0f << 0)
-#define STB0899_OFFST_BCH_ERRORS               0
-#define STB0899_WIDTH_BCH_ERRORS               4
-
-#define STB0899_OFF0_LDPC_ERRORS               0xfa1c
-#define STB0899_BASE_LDPC_ERRORS               0x00000800
-#define STB0899_LDPC_ERRORS                    (0xffff << 0)
-#define STB0899_OFFST_LDPC_ERRORS              0
-#define STB0899_WIDTH_LDPC_ERRORS              16
-
-#define STB0899_OFF0_BCH_MODE                  0xfa20
-#define STB0899_BASE_BCH_MODE                  0x00000800
-#define STB0899_BCH_CORRECT_N                  (0x01 << 1)
-#define STB0899_OFFST_BCH_CORRECT_N            1
-#define STB0899_WIDTH_BCH_CORRECT_N            1
-#define STB0899_FULL_BYPASS                    (0x01 << 0)
-#define STB0899_OFFST_FULL_BYPASS              0
-#define STB0899_WIDTH_FULL_BYPASS              1
-
-#define STB0899_OFF0_ERR_ACC_PER               0xfa24
-#define STB0899_BASE_ERR_ACC_PER               0x00000800
-#define STB0899_BCH_ERR_ACC_PERIOD             (0x0f << 0)
-#define STB0899_OFFST_BCH_ERR_ACC_PERIOD       0
-#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD       4
-
-#define STB0899_OFF0_BCH_ERR_ACC               0xfa28
-#define STB0899_BASE_BCH_ERR_ACC               0x00000800
-#define STB0899_BCH_ERR_ACCUM                  (0xff << 0)
-#define STB0899_OFFST_BCH_ERR_ACCUM            0
-#define STB0899_WIDTH_BCH_ERR_ACCUM            8
-
-#define STB0899_OFF0_FEC_CORE_ID_REG           0xfa2c
-#define STB0899_BASE_FEC_CORE_ID_REG           0x00000800
-#define STB0899_FEC_CORE_ID                    (0xffffffff << 0)
-#define STB0899_OFFST_FEC_CORE_ID              0
-#define STB0899_WIDTH_FEC_CORE_ID              32
-
-#define STB0899_OFF0_FEC_VER_ID_REG            0xfa34
-#define STB0899_BASE_FEC_VER_ID_REG            0x00000800
-#define STB0899_FEC_VER_ID                     (0xff << 0)
-#define STB0899_OFFST_FEC_VER_ID               0
-#define STB0899_WIDTH_FEC_VER_ID               8
-
-#define STB0899_OFF0_FEC_TP_SEL                        0xfa38
-#define STB0899_BASE_FEC_TP_SEL                        0x00000800
-
-#define STB0899_OFF0_CSM_CNTRL1                        0xf310
-#define STB0899_BASE_CSM_CNTRL1                        0x00000400
-#define STB0899_CSM_FORCE_FREQLOCK             (0x01 << 19)
-#define STB0899_OFFST_CSM_FORCE_FREQLOCK       19
-#define STB0899_WIDTH_CSM_FORCE_FREQLOCK       1
-#define STB0899_CSM_FREQ_LOCKSTATE             (0x01 << 18)
-#define STB0899_OFFST_CSM_FREQ_LOCKSTATE       18
-#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE       1
-#define STB0899_CSM_AUTO_PARAM                 (0x01 << 17)
-#define STB0899_OFFST_CSM_AUTO_PARAM           17
-#define STB0899_WIDTH_CSM_AUTO_PARAM           1
-#define STB0899_FE_LOOP_SHIFT                  (0x07 << 14)
-#define STB0899_OFFST_FE_LOOP_SHIFT            14
-#define STB0899_WIDTH_FE_LOOP_SHIFT            3
-#define STB0899_CSM_AGC_SHIFT                  (0x07 << 11)
-#define STB0899_OFFST_CSM_AGC_SHIFT            11
-#define STB0899_WIDTH_CSM_AGC_SHIFT            3
-#define STB0899_CSM_AGC_GAIN                   (0x1ff << 2)
-#define STB0899_OFFST_CSM_AGC_GAIN             2
-#define STB0899_WIDTH_CSM_AGC_GAIN             9
-#define STB0899_CSM_TWO_PASS                   (0x01 << 1)
-#define STB0899_OFFST_CSM_TWO_PASS             1
-#define STB0899_WIDTH_CSM_TWO_PASS             1
-#define STB0899_CSM_DVT_TABLE                  (0x01 << 0)
-#define STB0899_OFFST_CSM_DVT_TABLE            0
-#define STB0899_WIDTH_CSM_DVT_TABLE            1
-
-#define STB0899_OFF0_CSM_CNTRL2                        0xf314
-#define STB0899_BASE_CSM_CNTRL2                        0x00000400
-#define STB0899_CSM_GAMMA_RHO_ACQ              (0x1ff << 9)
-#define STB0899_OFFST_CSM_GAMMA_RHOACQ         9
-#define STB0899_WIDTH_CSM_GAMMA_RHOACQ         9
-#define STB0899_CSM_GAMMA_ACQ                  (0x1ff << 0)
-#define STB0899_OFFST_CSM_GAMMA_ACQ            0
-#define STB0899_WIDTH_CSM_GAMMA_ACQ            9
-
-#define STB0899_OFF0_CSM_CNTRL3                        0xf318
-#define STB0899_BASE_CSM_CNTRL3                        0x00000400
-#define STB0899_CSM_GAMMA_RHO_TRACK            (0x1ff << 9)
-#define STB0899_OFFST_CSM_GAMMA_RHOTRACK       9
-#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK       9
-#define STB0899_CSM_GAMMA_TRACK                        (0x1ff << 0)
-#define STB0899_OFFST_CSM_GAMMA_TRACK          0
-#define STB0899_WIDTH_CSM_GAMMA_TRACK          9
-
-#define STB0899_OFF0_CSM_CNTRL4                        0xf31c
-#define STB0899_BASE_CSM_CNTRL4                        0x00000400
-#define STB0899_CSM_PHASEDIFF_THRESH           (0x0f << 8)
-#define STB0899_OFFST_CSM_PHASEDIFF_THRESH     8
-#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH     4
-#define STB0899_CSM_LOCKCOUNT_THRESH           (0xff << 0)
-#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH     0
-#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH     8
-
-/*     Check on chapter 8 page 42      */
-#define STB0899_ERRCTRL1                       0xf574
-#define STB0899_ERRCTRL2                       0xf575
-#define STB0899_ERRCTRL3                       0xf576
-#define STB0899_ERR_SRC_S1                     (0x1f << 3)
-#define STB0899_OFFST_ERR_SRC_S1               3
-#define STB0899_WIDTH_ERR_SRC_S1               5
-#define STB0899_ERR_SRC_S2                     (0x0f << 0)
-#define STB0899_OFFST_ERR_SRC_S2               0
-#define STB0899_WIDTH_ERR_SRC_S2               4
-#define STB0899_NOE                            (0x07 << 0)
-#define STB0899_OFFST_NOE                      0
-#define STB0899_WIDTH_NOE                      3
-
-#define STB0899_ECNT1M                         0xf524
-#define STB0899_ECNT1L                         0xf525
-#define STB0899_ECNT2M                         0xf526
-#define STB0899_ECNT2L                         0xf527
-#define STB0899_ECNT3M                         0xf528
-#define STB0899_ECNT3L                         0xf529
-
-#define STB0899_DMONMSK1                       0xf57b
-#define STB0899_DMONMSK1_WAIT_1STEP            (1 << 7)
-#define STB0899_DMONMSK1_FREE_14               (1 << 6)
-#define STB0899_DMONMSK1_AVRGVIT_CALC          (1 << 5)
-#define STB0899_DMONMSK1_FREE_12               (1 << 4)
-#define STB0899_DMONMSK1_FREE_11               (1 << 3)
-#define STB0899_DMONMSK1_B0DIV_CALC            (1 << 2)
-#define STB0899_DMONMSK1_KDIVB1_CALC           (1 << 1)
-#define STB0899_DMONMSK1_KDIVB2_CALC           (1 << 0)
-
-#define STB0899_DMONMSK0                       0xf57c
-#define STB0899_DMONMSK0_SMOTTH_CALC           (1 << 7)
-#define STB0899_DMONMSK0_FREE_6                        (1 << 6)
-#define STB0899_DMONMSK0_SIGPOWER_CALC         (1 << 5)
-#define STB0899_DMONMSK0_QSEUIL_CALC           (1 << 4)
-#define STB0899_DMONMSK0_FREE_3                        (1 << 3)
-#define STB0899_DMONMSK0_FREE_2                        (1 << 2)
-#define STB0899_DMONMSK0_KVDIVB1_CALC          (1 << 1)
-#define STB0899_DMONMSK0_KVDIVB2_CALC          (1 << 0)
-
-#define STB0899_TSULC                          0xf549
-#define STB0899_ULNOSYNCBYTES                  (0x01 << 7)
-#define STB0899_OFFST_ULNOSYNCBYTES            7
-#define STB0899_WIDTH_ULNOSYNCBYTES            1
-#define STB0899_ULPARITY_ON                    (0x01 << 6)
-#define STB0899_OFFST_ULPARITY_ON              6
-#define STB0899_WIDTH_ULPARITY_ON              1
-#define STB0899_ULSYNCOUTRS                    (0x01 << 5)
-#define STB0899_OFFST_ULSYNCOUTRS              5
-#define STB0899_WIDTH_ULSYNCOUTRS              1
-#define STB0899_ULDSS_PACKETS                  (0x01 << 0)
-#define STB0899_OFFST_ULDSS_PACKETS            0
-#define STB0899_WIDTH_ULDSS_PACKETS            1
-
-#define STB0899_TSLPL                          0xf54b
-#define STB0899_LLDVBS2_MODE                   (0x01 << 4)
-#define STB0899_OFFST_LLDVBS2_MODE             4
-#define STB0899_WIDTH_LLDVBS2_MODE             1
-#define STB0899_LLISSYI_ON                     (0x01 << 3)
-#define STB0899_OFFST_LLISSYI_ON               3
-#define STB0899_WIDTH_LLISSYI_ON               1
-#define STB0899_LLNPD_ON                       (0x01 << 2)
-#define STB0899_OFFST_LLNPD_ON                 2
-#define STB0899_WIDTH_LLNPD_ON                 1
-#define STB0899_LLCRC8_ON                      (0x01 << 1)
-#define STB0899_OFFST_LLCRC8_ON                        1
-#define STB0899_WIDTH_LLCRC8_ON                        1
-
-#define STB0899_TSCFGH                         0xf54c
-#define STB0899_OUTRS_PS                       (0x01 << 6)
-#define STB0899_OFFST_OUTRS_PS                 6
-#define STB0899_WIDTH_OUTRS_PS                 1
-#define STB0899_SYNCBYTE                       (0x01 << 5)
-#define STB0899_OFFST_SYNCBYTE                 5
-#define STB0899_WIDTH_SYNCBYTE                 1
-#define STB0899_PFBIT                          (0x01 << 4)
-#define STB0899_OFFST_PFBIT                    4
-#define STB0899_WIDTH_PFBIT                    1
-#define STB0899_ERR_BIT                                (0x01 << 3)
-#define STB0899_OFFST_ERR_BIT                  3
-#define STB0899_WIDTH_ERR_BIT                  1
-#define STB0899_MPEG                           (0x01 << 2)
-#define STB0899_OFFST_MPEG                     2
-#define STB0899_WIDTH_MPEG                     1
-#define STB0899_CLK_POL                                (0x01 << 1)
-#define STB0899_OFFST_CLK_POL                  1
-#define STB0899_WIDTH_CLK_POL                  1
-#define STB0899_FORCE0                         (0x01 << 0)
-#define STB0899_OFFST_FORCE0                   0
-#define STB0899_WIDTH_FORCE0                   1
-
-#define STB0899_TSCFGM                         0xf54d
-#define STB0899_LLPRIORITY                     (0x01 << 3)
-#define STB0899_OFFST_LLPRIORIY                        3
-#define STB0899_WIDTH_LLPRIORITY               1
-#define STB0899_EN188                          (0x01 << 2)
-#define STB0899_OFFST_EN188                    2
-#define STB0899_WIDTH_EN188                    1
-
-#define STB0899_TSCFGL                         0xf54e
-#define STB0899_DEL_ERRPCK                     (0x01 << 7)
-#define STB0899_OFFST_DEL_ERRPCK               7
-#define STB0899_WIDTH_DEL_ERRPCK               1
-#define STB0899_ERRFLAGSTD                     (0x01 << 5)
-#define STB0899_OFFST_ERRFLAGSTD               5
-#define STB0899_WIDTH_ERRFLAGSTD               1
-#define STB0899_MPEGERR                                (0x01 << 4)
-#define STB0899_OFFST_MPEGERR                  4
-#define STB0899_WIDTH_MPEGERR                  1
-#define STB0899_BCH_CHK                                (0x01 << 3)
-#define STB0899_OFFST_BCH_CHK                  5
-#define STB0899_WIDTH_BCH_CHK                  1
-#define STB0899_CRC8CHK                                (0x01 << 2)
-#define STB0899_OFFST_CRC8CHK                  2
-#define STB0899_WIDTH_CRC8CHK                  1
-#define STB0899_SPEC_INFO                      (0x01 << 1)
-#define STB0899_OFFST_SPEC_INFO                        1
-#define STB0899_WIDTH_SPEC_INFO                        1
-#define STB0899_LOW_PRIO_CLK                   (0x01 << 0)
-#define STB0899_OFFST_LOW_PRIO_CLK             0
-#define STB0899_WIDTH_LOW_PRIO_CLK             1
-#define STB0899_ERROR_NORM                     (0x00 << 0)
-#define STB0899_OFFST_ERROR_NORM               0
-#define STB0899_WIDTH_ERROR_NORM               0
-
-#define STB0899_TSOUT                          0xf54f
-#define STB0899_RSSYNCDEL                      0xf550
-#define STB0899_TSINHDELH                      0xf551
-#define STB0899_TSINHDELM                      0xf552
-#define STB0899_TSINHDELL                      0xf553
-#define STB0899_TSLLSTKM                       0xf55a
-#define STB0899_TSLLSTKL                       0xf55b
-#define STB0899_TSULSTKM                       0xf55c
-#define STB0899_TSULSTKL                       0xf55d
-#define STB0899_TSSTATUS                       0xf561
-
-#define STB0899_PDELCTRL                       0xf600
-#define STB0899_INVERT_RES                     (0x01 << 7)
-#define STB0899_OFFST_INVERT_RES               7
-#define STB0899_WIDTH_INVERT_RES               1
-#define STB0899_FORCE_ACCEPTED                 (0x01 << 6)
-#define STB0899_OFFST_FORCE_ACCEPTED           6
-#define STB0899_WIDTH_FORCE_ACCEPTED           1
-#define STB0899_FILTER_EN                      (0x01 << 5)
-#define STB0899_OFFST_FILTER_EN                        5
-#define STB0899_WIDTH_FILTER_EN                        1
-#define STB0899_LOCKFALL_THRESH                        (0x01 << 4)
-#define STB0899_OFFST_LOCKFALL_THRESH          4
-#define STB0899_WIDTH_LOCKFALL_THRESH          1
-#define STB0899_HYST_EN                                (0x01 << 3)
-#define STB0899_OFFST_HYST_EN                  3
-#define STB0899_WIDTH_HYST_EN                  1
-#define STB0899_HYST_SWRST                     (0x01 << 2)
-#define STB0899_OFFST_HYST_SWRST               2
-#define STB0899_WIDTH_HYST_SWRST               1
-#define STB0899_ALGO_EN                                (0x01 << 1)
-#define STB0899_OFFST_ALGO_EN                  1
-#define STB0899_WIDTH_ALGO_EN                  1
-#define STB0899_ALGO_SWRST                     (0x01 << 0)
-#define STB0899_OFFST_ALGO_SWRST               0
-#define STB0899_WIDTH_ALGO_SWRST               1
-
-#define STB0899_PDELCTRL2                      0xf601
-#define STB0899_BBHCTRL1                       0xf602
-#define STB0899_BBHCTRL2                       0xf603
-#define STB0899_HYSTTHRESH                     0xf604
-
-#define STB0899_MATCSTM                                0xf605
-#define STB0899_MATCSTL                                0xf606
-#define STB0899_UPLCSTM                                0xf607
-#define STB0899_UPLCSTL                                0xf608
-#define STB0899_DFLCSTM                                0xf609
-#define STB0899_DFLCSTL                                0xf60a
-#define STB0899_SYNCCST                                0xf60b
-#define STB0899_SYNCDCSTM                      0xf60c
-#define STB0899_SYNCDCSTL                      0xf60d
-#define STB0899_ISI_ENTRY                      0xf60e
-#define STB0899_ISI_BIT_EN                     0xf60f
-#define STB0899_MATSTRM                                0xf610
-#define STB0899_MATSTRL                                0xf611
-#define STB0899_UPLSTRM                                0xf612
-#define STB0899_UPLSTRL                                0xf613
-#define STB0899_DFLSTRM                                0xf614
-#define STB0899_DFLSTRL                                0xf615
-#define STB0899_SYNCSTR                                0xf616
-#define STB0899_SYNCDSTRM                      0xf617
-#define STB0899_SYNCDSTRL                      0xf618
-
-#define STB0899_CFGPDELSTATUS1                 0xf619
-#define STB0899_BADDFL                         (0x01 << 6)
-#define STB0899_OFFST_BADDFL                   6
-#define STB0899_WIDTH_BADDFL                   1
-#define STB0899_CONTINUOUS_STREAM              (0x01 << 5)
-#define STB0899_OFFST_CONTINUOUS_STREAM                5
-#define STB0899_WIDTH_CONTINUOUS_STREAM                1
-#define STB0899_ACCEPTED_STREAM                        (0x01 << 4)
-#define STB0899_OFFST_ACCEPTED_STREAM          4
-#define STB0899_WIDTH_ACCEPTED_STREAM          1
-#define STB0899_BCH_ERRFLAG                    (0x01 << 3)
-#define STB0899_OFFST_BCH_ERRFLAG              3
-#define STB0899_WIDTH_BCH_ERRFLAG              1
-#define STB0899_CRCRES                         (0x01 << 2)
-#define STB0899_OFFST_CRCRES                   2
-#define STB0899_WIDTH_CRCRES                   1
-#define STB0899_CFGPDELSTATUS_LOCK             (0x01 << 1)
-#define STB0899_OFFST_CFGPDELSTATUS_LOCK       1
-#define STB0899_WIDTH_CFGPDELSTATUS_LOCK       1
-#define STB0899_1STLOCK                                (0x01 << 0)
-#define STB0899_OFFST_1STLOCK                  0
-#define STB0899_WIDTH_1STLOCK                  1
-
-#define STB0899_CFGPDELSTATUS2                 0xf61a
-#define STB0899_BBFERRORM                      0xf61b
-#define STB0899_BBFERRORL                      0xf61c
-#define STB0899_UPKTERRORM                     0xf61d
-#define STB0899_UPKTERRORL                     0xf61e
-
-#define STB0899_TSTCK                          0xff10
-
-#define STB0899_TSTRES                         0xff11
-#define STB0899_FRESLDPC                       (0x01 << 7)
-#define STB0899_OFFST_FRESLDPC                 7
-#define STB0899_WIDTH_FRESLDPC                 1
-#define STB0899_FRESRS                         (0x01 << 6)
-#define STB0899_OFFST_FRESRS                   6
-#define STB0899_WIDTH_FRESRS                   1
-#define STB0899_FRESVIT                                (0x01 << 5)
-#define STB0899_OFFST_FRESVIT                  5
-#define STB0899_WIDTH_FRESVIT                  1
-#define STB0899_FRESMAS1_2                     (0x01 << 4)
-#define STB0899_OFFST_FRESMAS1_2               4
-#define STB0899_WIDTH_FRESMAS1_2               1
-#define STB0899_FRESACS                                (0x01 << 3)
-#define STB0899_OFFST_FRESACS                  3
-#define STB0899_WIDTH_FRESACS                  1
-#define STB0899_FRESSYM                                (0x01 << 2)
-#define STB0899_OFFST_FRESSYM                  2
-#define STB0899_WIDTH_FRESSYM                  1
-#define STB0899_FRESMAS                                (0x01 << 1)
-#define STB0899_OFFST_FRESMAS                  1
-#define STB0899_WIDTH_FRESMAS                  1
-#define STB0899_FRESINT                                (0x01 << 0)
-#define STB0899_OFFST_FRESINIT                 0
-#define STB0899_WIDTH_FRESINIT                 1
-
-#define STB0899_TSTOUT                         0xff12
-#define STB0899_EN_SIGNATURE                   (0x01 << 7)
-#define STB0899_OFFST_EN_SIGNATURE             7
-#define STB0899_WIDTH_EN_SIGNATURE             1
-#define STB0899_BCLK_CLK                       (0x01 << 6)
-#define STB0899_OFFST_BCLK_CLK                 6
-#define STB0899_WIDTH_BCLK_CLK                 1
-#define STB0899_SGNL_OUT                       (0x01 << 5)
-#define STB0899_OFFST_SGNL_OUT                 5
-#define STB0899_WIDTH_SGNL_OUT                 1
-#define STB0899_TS                             (0x01 << 4)
-#define STB0899_OFFST_TS                       4
-#define STB0899_WIDTH_TS                       1
-#define STB0899_CTEST                          (0x01 << 0)
-#define STB0899_OFFST_CTEST                    0
-#define STB0899_WIDTH_CTEST                    1
-
-#define STB0899_TSTIN                          0xff13
-#define STB0899_TEST_IN                                (0x01 << 7)
-#define STB0899_OFFST_TEST_IN                  7
-#define STB0899_WIDTH_TEST_IN                  1
-#define STB0899_EN_ADC                         (0x01 << 6)
-#define STB0899_OFFST_EN_ADC                   6
-#define STB0899_WIDTH_ENADC                    1
-#define STB0899_SGN_ADC                                (0x01 << 5)
-#define STB0899_OFFST_SGN_ADC                  5
-#define STB0899_WIDTH_SGN_ADC                  1
-#define STB0899_BCLK_IN                                (0x01 << 4)
-#define STB0899_OFFST_BCLK_IN                  4
-#define STB0899_WIDTH_BCLK_IN                  1
-#define STB0899_JETONIN_MODE                   (0x01 << 3)
-#define STB0899_OFFST_JETONIN_MODE             3
-#define STB0899_WIDTH_JETONIN_MODE             1
-#define STB0899_BCLK_VALUE                     (0x01 << 2)
-#define STB0899_OFFST_BCLK_VALUE               2
-#define STB0899_WIDTH_BCLK_VALUE               1
-#define STB0899_SGNRST_T12                     (0x01 << 1)
-#define STB0899_OFFST_SGNRST_T12               1
-#define STB0899_WIDTH_SGNRST_T12               1
-#define STB0899_LOWSP_ENAX                     (0x01 << 0)
-#define STB0899_OFFST_LOWSP_ENAX               0
-#define STB0899_WIDTH_LOWSP_ENAX               1
-
-#define STB0899_TSTSYS                         0xff14
-#define STB0899_TSTCHIP                                0xff15
-#define STB0899_TSTFREE                                0xff16
-#define STB0899_TSTI2C                         0xff17
-#define STB0899_BITSPEEDM                      0xff1c
-#define STB0899_BITSPEEDL                      0xff1d
-#define STB0899_TBUSBIT                                0xff1e
-#define STB0899_TSTDIS                         0xff24
-#define STB0899_TSTDISRX                       0xff25
-#define STB0899_TSTJETON                       0xff28
-#define STB0899_TSTDCADJ                       0xff40
-#define STB0899_TSTAGC1                                0xff41
-#define STB0899_TSTAGC1N                       0xff42
-#define STB0899_TSTPOLYPH                      0xff48
-#define STB0899_TSTR                           0xff49
-#define STB0899_TSTAGC2                                0xff4a
-#define STB0899_TSTCTL1                                0xff4b
-#define STB0899_TSTCTL2                                0xff4c
-#define STB0899_TSTCTL3                                0xff4d
-#define STB0899_TSTDEMAP                       0xff50
-#define STB0899_TSTDEMAP2                      0xff51
-#define STB0899_TSTDEMMON                      0xff52
-#define STB0899_TSTRATE                                0xff53
-#define STB0899_TSTSELOUT                      0xff54
-#define STB0899_TSYNC                          0xff55
-#define STB0899_TSTERR                         0xff56
-#define STB0899_TSTRAM1                                0xff58
-#define STB0899_TSTVSELOUT                     0xff59
-#define STB0899_TSTFORCEIN                     0xff5a
-#define STB0899_TSTRS1                         0xff5c
-#define STB0899_TSTRS2                         0xff5d
-#define STB0899_TSTRS3                         0xff53
-
-#define STB0899_INTBUFSTATUS                   0xf200
-#define STB0899_INTBUFCTRL                     0xf201
-#define STB0899_PCKLENUL                       0xf55e
-#define STB0899_PCKLENLL                       0xf55f
-#define STB0899_RSPCKLEN                       0xf560
-
-/*     2 registers     */
-#define STB0899_SYNCDCST                       0xf60c
-
-/*     DiSEqC  */
-#define STB0899_DISCNTRL1                      0xf0a0
-#define STB0899_TIMOFF                         (0x01 << 7)
-#define STB0899_OFFST_TIMOFF                   7
-#define STB0899_WIDTH_TIMOFF                   1
-#define STB0899_DISEQCRESET                    (0x01 << 6)
-#define STB0899_OFFST_DISEQCRESET              6
-#define STB0899_WIDTH_DISEQCRESET              1
-#define STB0899_TIMCMD                         (0x03 << 4)
-#define STB0899_OFFST_TIMCMD                   4
-#define STB0899_WIDTH_TIMCMD                   2
-#define STB0899_DISPRECHARGE                   (0x01 << 2)
-#define STB0899_OFFST_DISPRECHARGE             2
-#define STB0899_WIDTH_DISPRECHARGE             1
-#define STB0899_DISEQCMODE                     (0x03 << 0)
-#define STB0899_OFFST_DISEQCMODE               0
-#define STB0899_WIDTH_DISEQCMODE               2
-
-#define STB0899_DISCNTRL2                      0xf0a1
-#define STB0899_RECEIVER_ON                    (0x01 << 7)
-#define STB0899_OFFST_RECEIVER_ON              7
-#define STB0899_WIDTH_RECEIVER_ON              1
-#define STB0899_IGNO_SHORT_22K                 (0x01 << 6)
-#define STB0899_OFFST_IGNO_SHORT_22K           6
-#define STB0899_WIDTH_IGNO_SHORT_22K           1
-#define STB0899_ONECHIP_TRX                    (0x01 << 5)
-#define STB0899_OFFST_ONECHIP_TRX              5
-#define STB0899_WIDTH_ONECHIP_TRX              1
-#define STB0899_EXT_ENVELOP                    (0x01 << 4)
-#define STB0899_OFFST_EXT_ENVELOP              4
-#define STB0899_WIDTH_EXT_ENVELOP              1
-#define STB0899_PIN_SELECT                     (0x03 << 2)
-#define STB0899_OFFST_PIN_SELCT                        2
-#define STB0899_WIDTH_PIN_SELCT                        2
-#define STB0899_IRQ_RXEND                      (0x01 << 1)
-#define STB0899_OFFST_IRQ_RXEND                        1
-#define STB0899_WIDTH_IRQ_RXEND                        1
-#define STB0899_IRQ_4NBYTES                    (0x01 << 0)
-#define STB0899_OFFST_IRQ_4NBYTES              0
-#define STB0899_WIDTH_IRQ_4NBYTES              1
-
-#define STB0899_DISRX_ST0                      0xf0a4
-#define STB0899_RXEND                          (0x01 << 7)
-#define STB0899_OFFST_RXEND                    7
-#define STB0899_WIDTH_RXEND                    1
-#define STB0899_RXACTIVE                       (0x01 << 6)
-#define STB0899_OFFST_RXACTIVE                 6
-#define STB0899_WIDTH_RXACTIVE                 1
-#define STB0899_SHORT22K                       (0x01 << 5)
-#define STB0899_OFFST_SHORT22K                 5
-#define STB0899_WIDTH_SHORT22K                 1
-#define STB0899_CONTTONE                       (0x01 << 4)
-#define STB0899_OFFST_CONTTONE                 4
-#define STB0899_WIDTH_CONTONE                  1
-#define STB0899_4BFIFOREDY                     (0x01 << 3)
-#define STB0899_OFFST_4BFIFOREDY               3
-#define STB0899_WIDTH_4BFIFOREDY               1
-#define STB0899_FIFOEMPTY                      (0x01 << 2)
-#define STB0899_OFFST_FIFOEMPTY                        2
-#define STB0899_WIDTH_FIFOEMPTY                        1
-#define STB0899_ABORTTRX                       (0x01 << 0)
-#define STB0899_OFFST_ABORTTRX                 0
-#define STB0899_WIDTH_ABORTTRX                 1
-
-#define STB0899_DISRX_ST1                      0xf0a5
-#define STB0899_RXFAIL                         (0x01 << 7)
-#define STB0899_OFFST_RXFAIL                   7
-#define STB0899_WIDTH_RXFAIL                   1
-#define STB0899_FIFOPFAIL                      (0x01 << 6)
-#define STB0899_OFFST_FIFOPFAIL                        6
-#define STB0899_WIDTH_FIFOPFAIL                        1
-#define STB0899_RXNONBYTES                     (0x01 << 5)
-#define STB0899_OFFST_RXNONBYTES               5
-#define STB0899_WIDTH_RXNONBYTES               1
-#define STB0899_FIFOOVF                                (0x01 << 4)
-#define STB0899_OFFST_FIFOOVF                  4
-#define STB0899_WIDTH_FIFOOVF                  1
-#define STB0899_FIFOBYTENBR                    (0x0f << 0)
-#define STB0899_OFFST_FIFOBYTENBR              0
-#define STB0899_WIDTH_FIFOBYTENBR              4
-
-#define STB0899_DISPARITY                      0xf0a6
-
-#define STB0899_DISFIFO                                0xf0a7
-
-#define STB0899_DISSTATUS                      0xf0a8
-#define STB0899_FIFOFULL                       (0x01 << 6)
-#define STB0899_OFFST_FIFOFULL                 6
-#define STB0899_WIDTH_FIFOFULL                 1
-#define STB0899_TXIDLE                         (0x01 << 5)
-#define STB0899_OFFST_TXIDLE                   5
-#define STB0899_WIDTH_TXIDLE                   1
-#define STB0899_GAPBURST                       (0x01 << 4)
-#define STB0899_OFFST_GAPBURST                 4
-#define STB0899_WIDTH_GAPBURST                 1
-#define STB0899_TXFIFOBYTES                    (0x0f << 0)
-#define STB0899_OFFST_TXFIFOBYTES              0
-#define STB0899_WIDTH_TXFIFOBYTES              4
-#define STB0899_DISF22                         0xf0a9
-
-#define STB0899_DISF22RX                       0xf0aa
-
-/*     General Purpose */
-#define STB0899_SYSREG                         0xf101
-#define STB0899_ACRPRESC                       0xf110
-#define STB0899_OFFST_RSVD2                    7
-#define STB0899_WIDTH_RSVD2                    1
-#define STB0899_OFFST_ACRPRESC                 4
-#define STB0899_WIDTH_ACRPRESC                 3
-#define STB0899_OFFST_RSVD1                    3
-#define STB0899_WIDTH_RSVD1                    1
-#define STB0899_OFFST_ACRPRESC2                        0
-#define STB0899_WIDTH_ACRPRESC2                        3
-
-#define STB0899_ACRDIV1                                0xf111
-#define STB0899_ACRDIV2                                0xf112
-#define STB0899_DACR1                          0xf113
-#define STB0899_DACR2                          0xf114
-#define STB0899_OUTCFG                         0xf11c
-#define STB0899_MODECFG                                0xf11d
-#define STB0899_NCOARSE                                0xf1b3
-
-#define STB0899_SYNTCTRL                       0xf1b6
-#define STB0899_STANDBY                                (0x01 << 7)
-#define STB0899_OFFST_STANDBY                  7
-#define STB0899_WIDTH_STANDBY                  1
-#define STB0899_BYPASSPLL                      (0x01 << 6)
-#define STB0899_OFFST_BYPASSPLL                        6
-#define STB0899_WIDTH_BYPASSPLL                        1
-#define STB0899_SEL1XRATIO                     (0x01 << 5)
-#define STB0899_OFFST_SEL1XRATIO               5
-#define STB0899_WIDTH_SEL1XRATIO               1
-#define STB0899_SELOSCI                                (0x01 << 1)
-#define STB0899_OFFST_SELOSCI                  1
-#define STB0899_WIDTH_SELOSCI                  1
-
-#define STB0899_FILTCTRL                       0xf1b7
-#define STB0899_SYSCTRL                                0xf1b8
-
-#define STB0899_STOPCLK1                       0xf1c2
-#define STB0899_STOP_CKINTBUF108               (0x01 << 7)
-#define STB0899_OFFST_STOP_CKINTBUF108         7
-#define STB0899_WIDTH_STOP_CKINTBUF108         1
-#define STB0899_STOP_CKINTBUF216               (0x01 << 6)
-#define STB0899_OFFST_STOP_CKINTBUF216         6
-#define STB0899_WIDTH_STOP_CKINTBUF216         1
-#define STB0899_STOP_CHK8PSK                   (0x01 << 5)
-#define STB0899_OFFST_STOP_CHK8PSK             5
-#define STB0899_WIDTH_STOP_CHK8PSK             1
-#define STB0899_STOP_CKFEC108                  (0x01 << 4)
-#define STB0899_OFFST_STOP_CKFEC108            4
-#define STB0899_WIDTH_STOP_CKFEC108            1
-#define STB0899_STOP_CKFEC216                  (0x01 << 3)
-#define STB0899_OFFST_STOP_CKFEC216            3
-#define STB0899_WIDTH_STOP_CKFEC216            1
-#define STB0899_STOP_CKCORE216                 (0x01 << 2)
-#define STB0899_OFFST_STOP_CKCORE216           2
-#define STB0899_WIDTH_STOP_CKCORE216           1
-#define STB0899_STOP_CKADCI108                 (0x01 << 1)
-#define STB0899_OFFST_STOP_CKADCI108           1
-#define STB0899_WIDTH_STOP_CKADCI108           1
-#define STB0899_STOP_INVCKADCI108              (0x01 << 0)
-#define STB0899_OFFST_STOP_INVCKADCI108                0
-#define STB0899_WIDTH_STOP_INVCKADCI108                1
-
-#define STB0899_STOPCLK2                       0xf1c3
-#define STB0899_STOP_CKS2DMD108                        (0x01 << 2)
-#define STB0899_OFFST_STOP_CKS2DMD108          2
-#define STB0899_WIDTH_STOP_CKS2DMD108          1
-#define STB0899_STOP_CKPKDLIN108               (0x01 << 1)
-#define STB0899_OFFST_STOP_CKPKDLIN108         1
-#define STB0899_WIDTH_STOP_CKPKDLIN108         1
-#define STB0899_STOP_CKPKDLIN216               (0x01 << 0)
-#define STB0899_OFFST_STOP_CKPKDLIN216         0
-#define STB0899_WIDTH_STOP_CKPKDLIN216         1
-
-#define STB0899_TSTTNR1                                0xf1e0
-#define STB0899_BYPASS_ADC                     (0x01 << 7)
-#define STB0899_OFFST_BYPASS_ADC               7
-#define STB0899_WIDTH_BYPASS_ADC               1
-#define STB0899_INVADCICKOUT                   (0x01 << 6)
-#define STB0899_OFFST_INVADCICKOUT             6
-#define STB0899_WIDTH_INVADCICKOUT             1
-#define STB0899_ADCTEST_VOLTAGE                        (0x03 << 4)
-#define STB0899_OFFST_ADCTEST_VOLTAGE          4
-#define STB0899_WIDTH_ADCTEST_VOLTAGE          1
-#define STB0899_ADC_RESET                      (0x01 << 3)
-#define STB0899_OFFST_ADC_RESET                        3
-#define STB0899_WIDTH_ADC_RESET                        1
-#define STB0899_TSTTNR1_2                      (0x01 << 2)
-#define STB0899_OFFST_TSTTNR1_2                        2
-#define STB0899_WIDTH_TSTTNR1_2                        1
-#define STB0899_ADCPON                         (0x01 << 1)
-#define STB0899_OFFST_ADCPON                   1
-#define STB0899_WIDTH_ADCPON                   1
-#define STB0899_ADCIN_MODE                     (0x01 << 0)
-#define STB0899_OFFST_ADCIN_MODE               0
-#define STB0899_WIDTH_ADCIN_MODE               1
-
-#define STB0899_TSTTNR2                                0xf1e1
-#define STB0899_TSTTNR2_7                      (0x01 << 7)
-#define STB0899_OFFST_TSTTNR2_7                        7
-#define STB0899_WIDTH_TSTTNR2_7                        1
-#define STB0899_NOT_DISRX_WIRED                        (0x01 << 6)
-#define STB0899_OFFST_NOT_DISRX_WIRED          6
-#define STB0899_WIDTH_NOT_DISRX_WIRED          1
-#define STB0899_DISEQC_DCURRENT                        (0x01 << 5)
-#define STB0899_OFFST_DISEQC_DCURRENT          5
-#define STB0899_WIDTH_DISEQC_DCURRENT          1
-#define STB0899_DISEQC_ZCURRENT                        (0x01 << 4)
-#define STB0899_OFFST_DISEQC_ZCURRENT          4
-#define STB0899_WIDTH_DISEQC_ZCURRENT          1
-#define STB0899_DISEQC_SINC_SOURCE             (0x03 << 2)
-#define STB0899_OFFST_DISEQC_SINC_SOURCE       2
-#define STB0899_WIDTH_DISEQC_SINC_SOURCE       2
-#define STB0899_SELIQSRC                       (0x03 << 0)
-#define STB0899_OFFST_SELIQSRC                 0
-#define STB0899_WIDTH_SELIQSRC                 2
-
-#define STB0899_TSTTNR3                                0xf1e2
-
-#define STB0899_I2CCFG                         0xf129
-#define STB0899_I2CCFGRSVD                     (0x0f << 4)
-#define STB0899_OFFST_I2CCFGRSVD               4
-#define STB0899_WIDTH_I2CCFGRSVD               4
-#define STB0899_I2CFASTMODE                    (0x01 << 3)
-#define STB0899_OFFST_I2CFASTMODE              3
-#define STB0899_WIDTH_I2CFASTMODE              1
-#define STB0899_STATUSWR                       (0x01 << 2)
-#define STB0899_OFFST_STATUSWR                 2
-#define STB0899_WIDTH_STATUSWR                 1
-#define STB0899_I2CADDRINC                     (0x03 << 0)
-#define STB0899_OFFST_I2CADDRINC               0
-#define STB0899_WIDTH_I2CADDRINC               2
-
-#define STB0899_I2CRPT                         0xf12a
-#define STB0899_I2CTON                         (0x01 << 7)
-#define STB0899_OFFST_I2CTON                   7
-#define STB0899_WIDTH_I2CTON                   1
-#define STB0899_ENARPTLEVEL                    (0x01 << 6)
-#define STB0899_OFFST_ENARPTLEVEL              6
-#define STB0899_WIDTH_ENARPTLEVEL              2
-#define STB0899_SCLTDELAY                      (0x01 << 3)
-#define STB0899_OFFST_SCLTDELAY                        3
-#define STB0899_WIDTH_SCLTDELAY                        1
-#define STB0899_STOPENA                                (0x01 << 2)
-#define STB0899_OFFST_STOPENA                  2
-#define STB0899_WIDTH_STOPENA                  1
-#define STB0899_STOPSDAT2SDA                   (0x01 << 1)
-#define STB0899_OFFST_STOPSDAT2SDA             1
-#define STB0899_WIDTH_STOPSDAT2SDA             1
-
-#define STB0899_IOPVALUE8                      0xf136
-#define STB0899_IOPVALUE7                      0xf137
-#define STB0899_IOPVALUE6                      0xf138
-#define STB0899_IOPVALUE5                      0xf139
-#define STB0899_IOPVALUE4                      0xf13a
-#define STB0899_IOPVALUE3                      0xf13b
-#define STB0899_IOPVALUE2                      0xf13c
-#define STB0899_IOPVALUE1                      0xf13d
-#define STB0899_IOPVALUE0                      0xf13e
-
-#define STB0899_GPIO00CFG                      0xf140
-
-#define STB0899_GPIO01CFG                      0xf141
-#define STB0899_GPIO02CFG                      0xf142
-#define STB0899_GPIO03CFG                      0xf143
-#define STB0899_GPIO04CFG                      0xf144
-#define STB0899_GPIO05CFG                      0xf145
-#define STB0899_GPIO06CFG                      0xf146
-#define STB0899_GPIO07CFG                      0xf147
-#define STB0899_GPIO08CFG                      0xf148
-#define STB0899_GPIO09CFG                      0xf149
-#define STB0899_GPIO10CFG                      0xf14a
-#define STB0899_GPIO11CFG                      0xf14b
-#define STB0899_GPIO12CFG                      0xf14c
-#define STB0899_GPIO13CFG                      0xf14d
-#define STB0899_GPIO14CFG                      0xf14e
-#define STB0899_GPIO15CFG                      0xf14f
-#define STB0899_GPIO16CFG                      0xf150
-#define STB0899_GPIO17CFG                      0xf151
-#define STB0899_GPIO18CFG                      0xf152
-#define STB0899_GPIO19CFG                      0xf153
-#define STB0899_GPIO20CFG                      0xf154
-
-#define STB0899_SDATCFG                                0xf155
-#define STB0899_SCLTCFG                                0xf156
-#define STB0899_AGCRFCFG                       0xf157
-#define STB0899_GPIO22                         0xf158  /* AGCBB2CFG    */
-#define STB0899_GPIO21                         0xf159  /* AGCBB1CFG    */
-#define STB0899_DIRCLKCFG                      0xf15a
-#define STB0899_CLKOUT27CFG                    0xf15b
-#define STB0899_STDBYCFG                       0xf15c
-#define STB0899_CS0CFG                         0xf15d
-#define STB0899_CS1CFG                         0xf15e
-#define STB0899_DISEQCOCFG                     0xf15f
-
-#define STB0899_GPIO32CFG                      0xf160
-#define STB0899_GPIO33CFG                      0xf161
-#define STB0899_GPIO34CFG                      0xf162
-#define STB0899_GPIO35CFG                      0xf163
-#define STB0899_GPIO36CFG                      0xf164
-#define STB0899_GPIO37CFG                      0xf165
-#define STB0899_GPIO38CFG                      0xf166
-#define STB0899_GPIO39CFG                      0xf167
-
-#define STB0899_IRQSTATUS_3                    0xf120
-#define STB0899_IRQSTATUS_2                    0xf121
-#define STB0899_IRQSTATUS_1                    0xf122
-#define STB0899_IRQSTATUS_0                    0xf123
-
-#define STB0899_IRQMSK_3                       0xf124
-#define STB0899_IRQMSK_2                       0xf125
-#define STB0899_IRQMSK_1                       0xf126
-#define STB0899_IRQMSK_0                       0xf127
-
-#define STB0899_IRQCFG                         0xf128
-
-#define STB0899_GHOSTREG                       0xf000
-
-#define STB0899_S2DEMOD                                0xf3fc
-#define STB0899_S2FEC                          0xfafc
-
-
-#endif
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c
deleted file mode 100644 (file)
index a0c3c52..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-  /*
-     Driver for ST STB6000 DVBS Silicon tuner
-
-     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-  */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <asm/types.h>
-
-#include "stb6000.h"
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "stb6000: " args); \
-       } while (0)
-
-struct stb6000_priv {
-       /* i2c details */
-       int i2c_address;
-       struct i2c_adapter *i2c;
-       u32 frequency;
-};
-
-static int stb6000_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int stb6000_sleep(struct dvb_frontend *fe)
-{
-       struct stb6000_priv *priv = fe->tuner_priv;
-       int ret;
-       u8 buf[] = { 10, 0 };
-       struct i2c_msg msg = {
-               .addr = priv->i2c_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 2
-       };
-
-       dprintk("%s:\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       ret = i2c_transfer(priv->i2c, &msg, 1);
-       if (ret != 1)
-               dprintk("%s: i2c error\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return (ret == 1) ? 0 : ret;
-}
-
-static int stb6000_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stb6000_priv *priv = fe->tuner_priv;
-       unsigned int n, m;
-       int ret;
-       u32 freq_mhz;
-       int bandwidth;
-       u8 buf[12];
-       struct i2c_msg msg = {
-               .addr = priv->i2c_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 12
-       };
-
-       dprintk("%s:\n", __func__);
-
-       freq_mhz = p->frequency / 1000;
-       bandwidth = p->symbol_rate / 1000000;
-
-       if (bandwidth > 31)
-               bandwidth = 31;
-
-       if ((freq_mhz > 949) && (freq_mhz < 2151)) {
-               buf[0] = 0x01;
-               buf[1] = 0xac;
-               if (freq_mhz < 1950)
-                       buf[1] = 0xaa;
-               if (freq_mhz < 1800)
-                       buf[1] = 0xa8;
-               if (freq_mhz < 1650)
-                       buf[1] = 0xa6;
-               if (freq_mhz < 1530)
-                       buf[1] = 0xa5;
-               if (freq_mhz < 1470)
-                       buf[1] = 0xa4;
-               if (freq_mhz < 1370)
-                       buf[1] = 0xa2;
-               if (freq_mhz < 1300)
-                       buf[1] = 0xa1;
-               if (freq_mhz < 1200)
-                       buf[1] = 0xa0;
-               if (freq_mhz < 1075)
-                       buf[1] = 0xbc;
-               if (freq_mhz < 1000)
-                       buf[1] = 0xba;
-               if (freq_mhz < 1075) {
-                       n = freq_mhz / 8; /* vco=lo*4 */
-                       m = 2;
-               } else {
-                       n = freq_mhz / 16; /* vco=lo*2 */
-                       m = 1;
-               }
-               buf[2] = n >> 1;
-               buf[3] = (unsigned char)(((n & 1) << 7) |
-                                       (m * freq_mhz - n * 16) | 0x60);
-               buf[4] = 0x04;
-               buf[5] = 0x0e;
-
-               buf[6] = (unsigned char)(bandwidth);
-
-               buf[7] = 0xd8;
-               buf[8] = 0xd0;
-               buf[9] = 0x50;
-               buf[10] = 0xeb;
-               buf[11] = 0x4f;
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = i2c_transfer(priv->i2c, &msg, 1);
-               if (ret != 1)
-                       dprintk("%s: i2c error\n", __func__);
-
-               udelay(10);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-               buf[0] = 0x07;
-               buf[1] = 0xdf;
-               buf[2] = 0xd0;
-               buf[3] = 0x50;
-               buf[4] = 0xfb;
-               msg.len = 5;
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = i2c_transfer(priv->i2c, &msg, 1);
-               if (ret != 1)
-                       dprintk("%s: i2c error\n", __func__);
-
-               udelay(10);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-               priv->frequency = freq_mhz * 1000;
-
-               return (ret == 1) ? 0 : ret;
-       }
-       return -1;
-}
-
-static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct stb6000_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static struct dvb_tuner_ops stb6000_tuner_ops = {
-       .info = {
-               .name = "ST STB6000",
-               .frequency_min = 950000,
-               .frequency_max = 2150000
-       },
-       .release = stb6000_release,
-       .sleep = stb6000_sleep,
-       .set_params = stb6000_set_params,
-       .get_frequency = stb6000_get_frequency,
-};
-
-struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
-                                               struct i2c_adapter *i2c)
-{
-       struct stb6000_priv *priv = NULL;
-       u8 b0[] = { 0 };
-       u8 b1[] = { 0, 0 };
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = addr,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 0
-               }, {
-                       .addr = addr,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 2
-               }
-       };
-       int ret;
-
-       dprintk("%s:\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       /* is some i2c device here ? */
-       ret = i2c_transfer(i2c, msg, 2);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret != 2)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c_address = addr;
-       priv->i2c = i2c;
-
-       memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
-                               sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-
-       return fe;
-}
-EXPORT_SYMBOL(stb6000_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("DVB STB6000 driver");
-MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h
deleted file mode 100644 (file)
index 7be479c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-  /*
-     Driver for ST stb6000 DVBS Silicon tuner
-
-     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-  */
-
-#ifndef __DVB_STB6000_H__
-#define __DVB_STB6000_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/**
- * Attach a stb6000 tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @return FE pointer on success, NULL on failure.
- */
-#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
-                                                       && defined(MODULE))
-extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe,
-                                                 int addr,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_STB6000 */
-
-#endif /* __DVB_STB6000_H__ */
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
deleted file mode 100644 (file)
index 2e93e65..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
-       STB6100 Silicon Tuner
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "dvb_frontend.h"
-#include "stb6100.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-
-
-#define FE_ERROR               0
-#define FE_NOTICE              1
-#define FE_INFO                        2
-#define FE_DEBUG               3
-
-#define dprintk(x, y, z, format, arg...) do {                                          \
-       if (z) {                                                                        \
-               if      ((x > FE_ERROR) && (x > y))                                     \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
-               else if ((x > FE_NOTICE) && (x > y))                                    \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((x > FE_INFO) && (x > y))                                      \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
-               else if ((x > FE_DEBUG) && (x > y))                                     \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (x > y)                                                              \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while (0)
-
-struct stb6100_lkup {
-       u32 val_low;
-       u32 val_high;
-       u8   reg;
-};
-
-static int stb6100_release(struct dvb_frontend *fe);
-
-static const struct stb6100_lkup lkup[] = {
-       {       0,  950000, 0x0a },
-       {  950000, 1000000, 0x0a },
-       { 1000000, 1075000, 0x0c },
-       { 1075000, 1200000, 0x00 },
-       { 1200000, 1300000, 0x01 },
-       { 1300000, 1370000, 0x02 },
-       { 1370000, 1470000, 0x04 },
-       { 1470000, 1530000, 0x05 },
-       { 1530000, 1650000, 0x06 },
-       { 1650000, 1800000, 0x08 },
-       { 1800000, 1950000, 0x0a },
-       { 1950000, 2150000, 0x0c },
-       { 2150000, 9999999, 0x0c },
-       {       0,       0, 0x00 }
-};
-
-/* Register names for easy debugging.  */
-static const char *stb6100_regnames[] = {
-       [STB6100_LD]            = "LD",
-       [STB6100_VCO]           = "VCO",
-       [STB6100_NI]            = "NI",
-       [STB6100_NF_LSB]        = "NF",
-       [STB6100_K]             = "K",
-       [STB6100_G]             = "G",
-       [STB6100_F]             = "F",
-       [STB6100_DLB]           = "DLB",
-       [STB6100_TEST1]         = "TEST1",
-       [STB6100_FCCK]          = "FCCK",
-       [STB6100_LPEN]          = "LPEN",
-       [STB6100_TEST3]         = "TEST3",
-};
-
-/* Template for normalisation, i.e. setting unused or undocumented
- * bits as required according to the documentation.
- */
-struct stb6100_regmask {
-       u8 mask;
-       u8 set;
-};
-
-static const struct stb6100_regmask stb6100_template[] = {
-       [STB6100_LD]            = { 0xff, 0x00 },
-       [STB6100_VCO]           = { 0xff, 0x00 },
-       [STB6100_NI]            = { 0xff, 0x00 },
-       [STB6100_NF_LSB]        = { 0xff, 0x00 },
-       [STB6100_K]             = { 0xc7, 0x38 },
-       [STB6100_G]             = { 0xef, 0x10 },
-       [STB6100_F]             = { 0x1f, 0xc0 },
-       [STB6100_DLB]           = { 0x38, 0xc4 },
-       [STB6100_TEST1]         = { 0x00, 0x8f },
-       [STB6100_FCCK]          = { 0x40, 0x0d },
-       [STB6100_LPEN]          = { 0xf0, 0x0b },
-       [STB6100_TEST3]         = { 0x00, 0xde },
-};
-
-/*
- * Currently unused. Some boards might need it in the future
- */
-static inline void stb6100_normalise_regs(u8 regs[])
-{
-       int i;
-
-       for (i = 0; i < STB6100_NUMREGS; i++)
-               regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set;
-}
-
-static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
-{
-       int rc;
-       struct i2c_msg msg = {
-               .addr   = state->config->tuner_address,
-               .flags  = I2C_M_RD,
-               .buf    = regs,
-               .len    = STB6100_NUMREGS
-       };
-
-       rc = i2c_transfer(state->i2c, &msg, 1);
-       if (unlikely(rc != 1)) {
-               dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
-                       state->config->tuner_address, rc);
-
-               return -EREMOTEIO;
-       }
-       if (unlikely(verbose > FE_DEBUG)) {
-               int i;
-
-               dprintk(verbose, FE_DEBUG, 1, "    Read from 0x%02x", state->config->tuner_address);
-               for (i = 0; i < STB6100_NUMREGS; i++)
-                       dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[i], regs[i]);
-       }
-       return 0;
-}
-
-static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
-{
-       u8 regs[STB6100_NUMREGS];
-
-       struct i2c_msg msg = {
-               .addr   = state->config->tuner_address + reg,
-               .flags  = I2C_M_RD,
-               .buf    = regs,
-               .len    = 1
-       };
-
-       i2c_transfer(state->i2c, &msg, 1);
-
-       if (unlikely(reg >= STB6100_NUMREGS)) {
-               dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
-               return -EINVAL;
-       }
-       if (unlikely(verbose > FE_DEBUG)) {
-               dprintk(verbose, FE_DEBUG, 1, "    Read from 0x%02x", state->config->tuner_address);
-               dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[reg], regs[0]);
-       }
-
-       return (unsigned int)regs[0];
-}
-
-static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
-{
-       int rc;
-       u8 cmdbuf[len + 1];
-       struct i2c_msg msg = {
-               .addr   = state->config->tuner_address,
-               .flags  = 0,
-               .buf    = cmdbuf,
-               .len    = len + 1
-       };
-
-       if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) {
-               dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d",
-                       start, len);
-               return -EINVAL;
-       }
-       memcpy(&cmdbuf[1], buf, len);
-       cmdbuf[0] = start;
-
-       if (unlikely(verbose > FE_DEBUG)) {
-               int i;
-
-               dprintk(verbose, FE_DEBUG, 1, "    Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len);
-               for (i = 0; i < len; i++)
-                       dprintk(verbose, FE_DEBUG, 1, "        %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
-       }
-       rc = i2c_transfer(state->i2c, &msg, 1);
-       if (unlikely(rc != 1)) {
-               dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
-                       (unsigned int)state->config->tuner_address, start, len, rc);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
-{
-       if (unlikely(reg >= STB6100_NUMREGS)) {
-               dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
-               return -EREMOTEIO;
-       }
-       data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
-       return stb6100_write_reg_range(state, &data, reg, 1);
-}
-
-
-static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       int rc;
-       struct stb6100_state *state = fe->tuner_priv;
-
-       rc = stb6100_read_reg(state, STB6100_LD);
-       if (rc < 0) {
-               dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
-               return rc;
-       }
-       return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
-}
-
-static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       int rc;
-       u8 f;
-       struct stb6100_state *state = fe->tuner_priv;
-
-       rc = stb6100_read_reg(state, STB6100_F);
-       if (rc < 0)
-               return rc;
-       f = rc & STB6100_F_F;
-
-       state->status.bandwidth = (f + 5) * 2000;       /* x2 for ZIF   */
-
-       *bandwidth = state->bandwidth = state->status.bandwidth * 1000;
-       dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
-       return 0;
-}
-
-static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
-{
-       u32 tmp;
-       int rc;
-       struct stb6100_state *state = fe->tuner_priv;
-
-       dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth);
-
-       bandwidth /= 2; /* ZIF */
-
-       if (bandwidth >= 36000000)      /* F[4:0] BW/2 max =31+5=36 mhz for F=31        */
-               tmp = 31;
-       else if (bandwidth <= 5000000)  /* bw/2 min = 5Mhz for F=0                      */
-               tmp = 0;
-       else                            /* if 5 < bw/2 < 36                             */
-               tmp = (bandwidth + 500000) / 1000000 - 5;
-
-       /* Turn on LPF bandwidth setting clock control,
-        * set bandwidth, wait 10ms, turn off.
-        */
-       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
-       if (rc < 0)
-               return rc;
-       rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
-       if (rc < 0)
-               return rc;
-
-       msleep(5);  /*  This is dangerous as another (related) thread may start */
-
-       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
-       if (rc < 0)
-               return rc;
-
-       msleep(10);  /*  This is dangerous as another (related) thread may start */
-
-       return 0;
-}
-
-static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       int rc;
-       u32 nint, nfrac, fvco;
-       int psd2, odiv;
-       struct stb6100_state *state = fe->tuner_priv;
-       u8 regs[STB6100_NUMREGS];
-
-       rc = stb6100_read_regs(state, regs);
-       if (rc < 0)
-               return rc;
-
-       odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
-       psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT;
-       nint = regs[STB6100_NI];
-       nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB];
-       fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2);
-       *frequency = state->frequency = fvco >> (odiv + 1);
-
-       dprintk(verbose, FE_DEBUG, 1,
-               "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u",
-               state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac);
-       return 0;
-}
-
-
-static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
-{
-       int rc;
-       const struct stb6100_lkup *ptr;
-       struct stb6100_state *state = fe->tuner_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       u32 srate = 0, fvco, nint, nfrac;
-       u8 regs[STB6100_NUMREGS];
-       u8 g, psd2, odiv;
-
-       dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
-
-       if (fe->ops.get_frontend) {
-               dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
-               fe->ops.get_frontend(fe);
-       }
-       srate = p->symbol_rate;
-
-       /* Set up tuner cleanly, LPF calibration on */
-       rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
-       if (rc < 0)
-               return rc;  /* allow LPF calibration */
-
-       /* PLL Loop disabled, bias on, VCO on, synth on */
-       regs[STB6100_LPEN] = 0xeb;
-       rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
-       if (rc < 0)
-               return rc;
-
-       /* Program the registers with their data values */
-
-       /* VCO divide ratio (LO divide ratio, VCO prescaler enable).    */
-       if (frequency <= 1075000)
-               odiv = 1;
-       else
-               odiv = 0;
-
-       /* VCO enabled, search clock off as per LL3.7, 3.4.1 */
-       regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
-
-       /* OSM  */
-       for (ptr = lkup;
-            (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
-            ptr++);
-
-       if (ptr->val_high == 0) {
-               printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
-               return -EINVAL;
-       }
-       regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
-       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
-       if (rc < 0)
-               return rc;
-
-       if ((frequency > 1075000) && (frequency <= 1325000))
-               psd2 = 0;
-       else
-               psd2 = 1;
-       /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4)                 */
-       fvco = frequency << (1 + odiv);
-       /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1)))    */
-       nint = fvco / (state->reference << psd2);
-       /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9       */
-       nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
-                                        << (9 - psd2), state->reference);
-
-       /* NI */
-       regs[STB6100_NI] = nint;
-       rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
-       if (rc < 0)
-               return rc;
-
-       /* NF */
-       regs[STB6100_NF_LSB] = nfrac;
-       rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
-       if (rc < 0)
-               return rc;
-
-       /* K */
-       regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
-       regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
-       rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
-       if (rc < 0)
-               return rc;
-
-       /* G Baseband gain. */
-       if (srate >= 15000000)
-               g = 9;  /*  +4 dB */
-       else if (srate >= 5000000)
-               g = 11; /*  +8 dB */
-       else
-               g = 14; /* +14 dB */
-
-       regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
-       regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
-       regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
-       rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
-       if (rc < 0)
-               return rc;
-
-       /* F we don't write as it is set up in BW set */
-
-       /* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
-       regs[STB6100_DLB] = 0xcc;
-       rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
-       if (rc < 0)
-               return rc;
-
-       dprintk(verbose, FE_DEBUG, 1,
-               "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
-               frequency, srate, (unsigned int)g, (unsigned int)odiv,
-               (unsigned int)psd2, state->reference,
-               ptr->reg, fvco, nint, nfrac);
-
-       /* Set up the test registers */
-       regs[STB6100_TEST1] = 0x8f;
-       rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
-       if (rc < 0)
-               return rc;
-       regs[STB6100_TEST3] = 0xde;
-       rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
-       if (rc < 0)
-               return rc;
-
-       /* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
-       regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
-       rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
-       if (rc < 0)
-               return rc;
-
-       msleep(2);
-
-       /* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
-       regs[STB6100_VCO] &= ~STB6100_VCO_OCK;          /* VCO fast search              */
-       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
-       if (rc < 0)
-               return rc;
-
-       msleep(10);  /*  This is dangerous as another (related) thread may start */ /* wait for LO to lock */
-
-       regs[STB6100_VCO] &= ~STB6100_VCO_OSCH;         /* vco search disabled          */
-       regs[STB6100_VCO] |= STB6100_VCO_OCK;           /* search clock off             */
-       rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
-       if (rc < 0)
-               return rc;
-
-       rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
-       if (rc < 0)
-               return rc;  /* Stop LPF calibration */
-
-       msleep(10);  /*  This is dangerous as another (related) thread may start */
-                    /* wait for stabilisation, (should not be necessary)               */
-       return 0;
-}
-
-static int stb6100_sleep(struct dvb_frontend *fe)
-{
-       /* TODO: power down     */
-       return 0;
-}
-
-static int stb6100_init(struct dvb_frontend *fe)
-{
-       struct stb6100_state *state = fe->tuner_priv;
-       struct tuner_state *status = &state->status;
-
-       status->tunerstep       = 125000;
-       status->ifreq           = 0;
-       status->refclock        = 27000000;     /* Hz   */
-       status->iqsense         = 1;
-       status->bandwidth       = 36000;        /* kHz  */
-       state->bandwidth        = status->bandwidth * 1000;     /* Hz   */
-       state->reference        = status->refclock / 1000;      /* kHz  */
-
-       /* Set default bandwidth. Modified, PN 13-May-10        */
-       return 0;
-}
-
-static int stb6100_get_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *state)
-{
-       switch (param) {
-       case DVBFE_TUNER_FREQUENCY:
-               stb6100_get_frequency(fe, &state->frequency);
-               break;
-       case DVBFE_TUNER_TUNERSTEP:
-               break;
-       case DVBFE_TUNER_IFFREQ:
-               break;
-       case DVBFE_TUNER_BANDWIDTH:
-               stb6100_get_bandwidth(fe, &state->bandwidth);
-               break;
-       case DVBFE_TUNER_REFCLOCK:
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static int stb6100_set_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *state)
-{
-       struct stb6100_state *tstate = fe->tuner_priv;
-
-       switch (param) {
-       case DVBFE_TUNER_FREQUENCY:
-               stb6100_set_frequency(fe, state->frequency);
-               tstate->frequency = state->frequency;
-               break;
-       case DVBFE_TUNER_TUNERSTEP:
-               break;
-       case DVBFE_TUNER_IFFREQ:
-               break;
-       case DVBFE_TUNER_BANDWIDTH:
-               stb6100_set_bandwidth(fe, state->bandwidth);
-               tstate->bandwidth = state->bandwidth;
-               break;
-       case DVBFE_TUNER_REFCLOCK:
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static struct dvb_tuner_ops stb6100_ops = {
-       .info = {
-               .name                   = "STB6100 Silicon Tuner",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_step         = 0,
-       },
-
-       .init           = stb6100_init,
-       .sleep          = stb6100_sleep,
-       .get_status     = stb6100_get_status,
-       .get_state      = stb6100_get_state,
-       .set_state      = stb6100_set_state,
-       .release        = stb6100_release
-};
-
-struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
-                                   const struct stb6100_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct stb6100_state *state = NULL;
-
-       state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->config           = config;
-       state->i2c              = i2c;
-       state->frontend         = fe;
-       state->reference        = config->refclock / 1000; /* kHz */
-       fe->tuner_priv          = state;
-       fe->ops.tuner_ops       = stb6100_ops;
-
-       printk("%s: Attaching STB6100 \n", __func__);
-       return fe;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static int stb6100_release(struct dvb_frontend *fe)
-{
-       struct stb6100_state *state = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(stb6100_attach);
-MODULE_PARM_DESC(verbose, "Set Verbosity level");
-
-MODULE_AUTHOR("Manu Abraham");
-MODULE_DESCRIPTION("STB6100 Silicon tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h
deleted file mode 100644 (file)
index 2ab0966..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-       STB6100 Silicon Tuner
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STB_6100_REG_H
-#define __STB_6100_REG_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-#define STB6100_LD                     0x00
-#define STB6100_LD_LOCK                        (1 << 0)
-
-#define STB6100_VCO                    0x01
-#define STB6100_VCO_OSCH               (0x01 << 7)
-#define STB6100_VCO_OSCH_SHIFT         7
-#define STB6100_VCO_OCK                        (0x03 << 5)
-#define STB6100_VCO_OCK_SHIFT          5
-#define STB6100_VCO_ODIV               (0x01 << 4)
-#define STB6100_VCO_ODIV_SHIFT         4
-#define STB6100_VCO_OSM                        (0x0f << 0)
-
-#define STB6100_NI                     0x02
-#define STB6100_NF_LSB                 0x03
-
-#define STB6100_K                      0x04
-#define STB6100_K_PSD2                 (0x01 << 2)
-#define STB6100_K_PSD2_SHIFT            2
-#define STB6100_K_NF_MSB               (0x03 << 0)
-
-#define STB6100_G                      0x05
-#define STB6100_G_G                    (0x0f << 0)
-#define STB6100_G_GCT                  (0x07 << 5)
-
-#define STB6100_F                      0x06
-#define STB6100_F_F                    (0x1f << 0)
-
-#define STB6100_DLB                    0x07
-
-#define STB6100_TEST1                  0x08
-
-#define STB6100_FCCK                   0x09
-#define STB6100_FCCK_FCCK              (0x01 << 6)
-
-#define STB6100_LPEN                   0x0a
-#define STB6100_LPEN_LPEN              (0x01 << 4)
-#define STB6100_LPEN_SYNP              (0x01 << 5)
-#define STB6100_LPEN_OSCP              (0x01 << 6)
-#define STB6100_LPEN_BEN               (0x01 << 7)
-
-#define STB6100_TEST3                  0x0b
-
-#define STB6100_NUMREGS                 0x0c
-
-
-#define INRANGE(val, x, y)             (((x <= val) && (val <= y)) ||          \
-                                        ((y <= val) && (val <= x)) ? 1 : 0)
-
-#define CHKRANGE(val, x, y)            (((val >= x) && (val < y)) ? 1 : 0)
-
-struct stb6100_config {
-       u8      tuner_address;
-       u32     refclock;
-};
-
-struct stb6100_state {
-       struct i2c_adapter *i2c;
-
-       const struct stb6100_config     *config;
-       struct dvb_tuner_ops            ops;
-       struct dvb_frontend             *frontend;
-       struct tuner_state              status;
-
-       u32 frequency;
-       u32 srate;
-       u32 bandwidth;
-       u32 reference;
-};
-
-#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
-                                          const struct stb6100_config *config,
-                                          struct i2c_adapter *i2c);
-
-#else
-
-static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
-                                                 const struct stb6100_config *config,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif //CONFIG_DVB_STB6100
-
-#endif
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
deleted file mode 100644 (file)
index 6314d18..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-       STB6100 Silicon Tuner
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-               *frequency = t_state.frequency;
-       }
-       return 0;
-}
-
-static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       t_state.frequency = frequency;
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->set_state) {
-               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-       }
-       return 0;
-}
-
-static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = &fe->ops;
-       struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-               *bandwidth = t_state.bandwidth;
-       }
-       return 0;
-}
-
-static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       t_state.bandwidth = bandwidth;
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->set_state) {
-               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-       }
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb/frontends/stb6100_proc.h
deleted file mode 100644 (file)
index 112163a..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-       STB6100 Silicon Tuner wrapper
-       Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 1);
-
-               err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
-               if (err < 0) {
-                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 0);
-
-               *frequency = state.frequency;
-       }
-
-       return 0;
-}
-
-static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      state;
-       int err = 0;
-
-       state.frequency = frequency;
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->set_state) {
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 1);
-
-               err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
-               if (err < 0) {
-                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 0);
-
-       }
-
-       return 0;
-}
-
-static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 1);
-
-               err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
-               if (err < 0) {
-                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 0);
-
-               *bandwidth = state.bandwidth;
-       }
-
-       return 0;
-}
-
-static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      state;
-       int err = 0;
-
-       state.bandwidth = bandwidth;
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->set_state) {
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 1);
-
-               err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
-               if (err < 0) {
-                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-
-               if (frontend_ops->i2c_gate_ctrl)
-                       frontend_ops->i2c_gate_ctrl(fe, 0);
-
-       }
-
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
deleted file mode 100644 (file)
index 632b251..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
-       Driver for ST STV0288 demodulator
-       Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
-               for Reel Multimedia
-       Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
-       Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
-               Removed stb6000 specific tuner code and revised some
-               procedures.
-       2010-09-01 Josef Pavlik <josef@pavlik.it>
-               Fixed diseqc_msg, diseqc_burst and set_tone problems
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "stv0288.h"
-
-struct stv0288_state {
-       struct i2c_adapter *i2c;
-       const struct stv0288_config *config;
-       struct dvb_frontend frontend;
-
-       u8 initialised:1;
-       u32 tuner_frequency;
-       u32 symbol_rate;
-       fe_code_rate_t fec_inner;
-       int errmode;
-};
-
-#define STATUS_BER 0
-#define STATUS_UCBLOCKS 1
-
-static int debug;
-static int debug_legacy_dish_switch;
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "stv0288: " args); \
-       } while (0)
-
-
-static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address,
-               .flags = 0,
-               .buf = buf,
-               .len = 2
-       };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
-                       "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return stv0288_writeregI(state, buf[0], buf[1]);
-}
-
-static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 1
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
-                               __func__, reg, ret);
-
-       return b1[0];
-}
-
-static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-       unsigned int temp;
-       unsigned char b[3];
-
-       if ((srate < 1000000) || (srate > 45000000))
-               return -EINVAL;
-
-       stv0288_writeregI(state, 0x22, 0);
-       stv0288_writeregI(state, 0x23, 0);
-       stv0288_writeregI(state, 0x2b, 0xff);
-       stv0288_writeregI(state, 0x2c, 0xf7);
-
-       temp = (unsigned int)srate / 1000;
-
-               temp = temp * 32768;
-               temp = temp / 25;
-               temp = temp / 125;
-               b[0] = (unsigned char)((temp >> 12) & 0xff);
-               b[1] = (unsigned char)((temp >> 4) & 0xff);
-               b[2] = (unsigned char)((temp << 4) & 0xf0);
-               stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
-               stv0288_writeregI(state, 0x29, 0); /* SFRM */
-               stv0288_writeregI(state, 0x2a, 0); /* SFRL */
-
-               stv0288_writeregI(state, 0x28, b[0]);
-               stv0288_writeregI(state, 0x29, b[1]);
-               stv0288_writeregI(state, 0x2a, b[2]);
-               dprintk("stv0288: stv0288_set_symbolrate\n");
-
-       return 0;
-}
-
-static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       int i;
-
-       dprintk("%s\n", __func__);
-
-       stv0288_writeregI(state, 0x09, 0);
-       msleep(30);
-       stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
-
-       for (i = 0; i < m->msg_len; i++) {
-               if (stv0288_writeregI(state, 0x06, m->msg[i]))
-                       return -EREMOTEIO;
-       }
-       msleep(m->msg_len*12);
-       return 0;
-}
-
-static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
-                                               fe_sec_mini_cmd_t burst)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
-               return -EREMOTEIO;
-
-       if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
-               return -EREMOTEIO;
-
-       msleep(15);
-       if (stv0288_writeregI(state, 0x05, 0x12))
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
-                       return -EREMOTEIO;
-       break;
-
-       case SEC_TONE_OFF:
-               if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
-                       return -EREMOTEIO;
-       break;
-
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static u8 stv0288_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x20,
-       0x09, 0x0,
-       0x0a, 0x4,
-       0x0b, 0x0,
-       0x0c, 0x0,
-       0x0d, 0x0,
-       0x0e, 0xd4,
-       0x0f, 0x30,
-       0x11, 0x80,
-       0x12, 0x03,
-       0x13, 0x48,
-       0x14, 0x84,
-       0x15, 0x45,
-       0x16, 0xb7,
-       0x17, 0x9c,
-       0x18, 0x0,
-       0x19, 0xa6,
-       0x1a, 0x88,
-       0x1b, 0x8f,
-       0x1c, 0xf0,
-       0x20, 0x0b,
-       0x21, 0x54,
-       0x22, 0x0,
-       0x23, 0x0,
-       0x2b, 0xff,
-       0x2c, 0xf7,
-       0x30, 0x0,
-       0x31, 0x1e,
-       0x32, 0x14,
-       0x33, 0x0f,
-       0x34, 0x09,
-       0x35, 0x0c,
-       0x36, 0x05,
-       0x37, 0x2f,
-       0x38, 0x16,
-       0x39, 0xbe,
-       0x3a, 0x0,
-       0x3b, 0x13,
-       0x3c, 0x11,
-       0x3d, 0x30,
-       0x40, 0x63,
-       0x41, 0x04,
-       0x42, 0x20,
-       0x43, 0x00,
-       0x44, 0x00,
-       0x45, 0x00,
-       0x46, 0x00,
-       0x47, 0x00,
-       0x4a, 0x00,
-       0x50, 0x10,
-       0x51, 0x38,
-       0x52, 0x21,
-       0x58, 0x54,
-       0x59, 0x86,
-       0x5a, 0x0,
-       0x5b, 0x9b,
-       0x5c, 0x08,
-       0x5d, 0x7f,
-       0x5e, 0x0,
-       0x5f, 0xff,
-       0x70, 0x0,
-       0x71, 0x0,
-       0x72, 0x0,
-       0x74, 0x0,
-       0x75, 0x0,
-       0x76, 0x0,
-       0x81, 0x0,
-       0x82, 0x3f,
-       0x83, 0x3f,
-       0x84, 0x0,
-       0x85, 0x0,
-       0x88, 0x0,
-       0x89, 0x0,
-       0x8a, 0x0,
-       0x8b, 0x0,
-       0x8c, 0x0,
-       0x90, 0x0,
-       0x91, 0x0,
-       0x92, 0x0,
-       0x93, 0x0,
-       0x94, 0x1c,
-       0x97, 0x0,
-       0xa0, 0x48,
-       0xa1, 0x0,
-       0xb0, 0xb8,
-       0xb1, 0x3a,
-       0xb2, 0x10,
-       0xb3, 0x82,
-       0xb4, 0x80,
-       0xb5, 0x82,
-       0xb6, 0x82,
-       0xb7, 0x82,
-       0xb8, 0x20,
-       0xb9, 0x0,
-       0xf0, 0x0,
-       0xf1, 0x0,
-       0xf2, 0xc0,
-       0x51, 0x36,
-       0x52, 0x09,
-       0x53, 0x94,
-       0x54, 0x62,
-       0x55, 0x29,
-       0x56, 0x64,
-       0x57, 0x2b,
-       0xff, 0xff,
-};
-
-static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
-{
-       dprintk("%s: %s\n", __func__,
-               volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
-               volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
-
-       return 0;
-}
-
-static int stv0288_init(struct dvb_frontend *fe)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-       int i;
-       u8 reg;
-       u8 val;
-
-       dprintk("stv0288: init chip\n");
-       stv0288_writeregI(state, 0x41, 0x04);
-       msleep(50);
-
-       /* we have default inittab */
-       if (state->config->inittab == NULL) {
-               for (i = 0; !(stv0288_inittab[i] == 0xff &&
-                               stv0288_inittab[i + 1] == 0xff); i += 2)
-                       stv0288_writeregI(state, stv0288_inittab[i],
-                                       stv0288_inittab[i + 1]);
-       } else {
-               for (i = 0; ; i += 2)  {
-                       reg = state->config->inittab[i];
-                       val = state->config->inittab[i+1];
-                       if (reg == 0xff && val == 0xff)
-                               break;
-                       stv0288_writeregI(state, reg, val);
-               }
-       }
-       return 0;
-}
-
-static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       u8 sync = stv0288_readreg(state, 0x24);
-       if (sync == 255)
-               sync = 0;
-
-       dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
-
-       *status = 0;
-       if (sync & 0x80)
-               *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-       if (sync & 0x10)
-               *status |= FE_HAS_VITERBI;
-       if (sync & 0x08) {
-               *status |= FE_HAS_LOCK;
-               dprintk("stv0288 has locked\n");
-       }
-
-       return 0;
-}
-
-static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       if (state->errmode != STATUS_BER)
-               return 0;
-       *ber = (stv0288_readreg(state, 0x26) << 8) |
-                                       stv0288_readreg(state, 0x27);
-       dprintk("stv0288_read_ber %d\n", *ber);
-
-       return 0;
-}
-
-
-static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       s32 signal =  0xffff - ((stv0288_readreg(state, 0x10) << 8));
-
-
-       signal = signal * 5 / 4;
-       *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
-       dprintk("stv0288_read_signal_strength %d\n", *strength);
-
-       return 0;
-}
-static int stv0288_sleep(struct dvb_frontend *fe)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       stv0288_writeregI(state, 0x41, 0x84);
-       state->initialised = 0;
-
-       return 0;
-}
-static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
-                          | stv0288_readreg(state, 0x2e));
-       xsnr = 3 * (xsnr - 0xa100);
-       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
-       dprintk("stv0288_read_snr %d\n", *snr);
-
-       return 0;
-}
-
-static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       if (state->errmode != STATUS_BER)
-               return 0;
-       *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
-                                       stv0288_readreg(state, 0x27);
-       dprintk("stv0288_read_ber %d\n", *ucblocks);
-
-       return 0;
-}
-
-static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
-{
-       dprintk("%s(..)\n", __func__);
-       return 0;
-}
-
-static int stv0288_set_frontend(struct dvb_frontend *fe)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-       char tm;
-       unsigned char tda[3];
-       u8 reg, time_out = 0;
-
-       dprintk("%s : FE_SET_FRONTEND\n", __func__);
-
-       if (c->delivery_system != SYS_DVBS) {
-                       dprintk("%s: unsupported delivery "
-                               "system selected (%d)\n",
-                               __func__, c->delivery_system);
-                       return -EOPNOTSUPP;
-       }
-
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-
-       /* only frequency & symbol_rate are used for tuner*/
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       udelay(10);
-       stv0288_set_symbolrate(fe, c->symbol_rate);
-       /* Carrier lock control register */
-       stv0288_writeregI(state, 0x15, 0xc5);
-
-       tda[2] = 0x0; /* CFRL */
-       for (tm = -9; tm < 7;) {
-               /* Viterbi status */
-               reg = stv0288_readreg(state, 0x24);
-               if (reg & 0x8)
-                               break;
-               if (reg & 0x80) {
-                       time_out++;
-                       if (time_out > 10)
-                               break;
-                       tda[2] += 40;
-                       if (tda[2] < 40)
-                               tm++;
-               } else {
-                       tm++;
-                       tda[2] = 0;
-                       time_out = 0;
-               }
-               tda[1] = (unsigned char)tm;
-               stv0288_writeregI(state, 0x2b, tda[1]);
-               stv0288_writeregI(state, 0x2c, tda[2]);
-               msleep(30);
-       }
-       state->tuner_frequency = c->frequency;
-       state->fec_inner = FEC_AUTO;
-       state->symbol_rate = c->symbol_rate;
-
-       return 0;
-}
-
-static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-
-       if (enable)
-               stv0288_writeregI(state, 0x01, 0xb5);
-       else
-               stv0288_writeregI(state, 0x01, 0x35);
-
-       udelay(1);
-
-       return 0;
-}
-
-static void stv0288_release(struct dvb_frontend *fe)
-{
-       struct stv0288_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops stv0288_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "ST STV0288 DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 1000,  /* kHz for QPSK frontends */
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,  /* ppm */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                     FE_CAN_QPSK |
-                     FE_CAN_FEC_AUTO
-       },
-
-       .release = stv0288_release,
-       .init = stv0288_init,
-       .sleep = stv0288_sleep,
-       .write = stv0288_write,
-       .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
-       .read_status = stv0288_read_status,
-       .read_ber = stv0288_read_ber,
-       .read_signal_strength = stv0288_read_signal_strength,
-       .read_snr = stv0288_read_snr,
-       .read_ucblocks = stv0288_read_ucblocks,
-       .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
-       .diseqc_send_burst = stv0288_send_diseqc_burst,
-       .set_tone = stv0288_set_tone,
-       .set_voltage = stv0288_set_voltage,
-
-       .set_property = stv0288_set_property,
-       .set_frontend = stv0288_set_frontend,
-};
-
-struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct stv0288_state *state = NULL;
-       int id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-       state->tuner_frequency = 0;
-       state->symbol_rate = 0;
-       state->fec_inner = 0;
-       state->errmode = STATUS_BER;
-
-       stv0288_writeregI(state, 0x41, 0x04);
-       msleep(200);
-       id = stv0288_readreg(state, 0x00);
-       dprintk("stv0288 id %x\n", id);
-
-       /* register 0x00 contains 0x11 for STV0288  */
-       if (id != 0x11)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &stv0288_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-
-       return NULL;
-}
-EXPORT_SYMBOL(stv0288_attach);
-
-module_param(debug_legacy_dish_switch, int, 0444);
-MODULE_PARM_DESC(debug_legacy_dish_switch,
-               "Enable timing analysis for Dish Network legacy switches");
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
-MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h
deleted file mode 100644 (file)
index f2b53db..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-       Driver for ST STV0288 demodulator
-
-       Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
-               for Reel Multimedia
-       Copyright (C) 2008 TurboSight.com, <bob@turbosight.com>
-       Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
-               Removed stb6000 specific tuner code and revised some
-               procedures.
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef STV0288_H
-#define STV0288_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct stv0288_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       u8* inittab;
-
-       /* minimum delay before retuning */
-       int min_delay_ms;
-
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-};
-
-#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
-                                                       defined(MODULE))
-extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
-                                          struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_STV0288 */
-
-static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
-{
-       int r = 0;
-       u8 buf[] = { reg, val };
-       if (fe->ops.write)
-               r = fe->ops.write(fe, buf, 2);
-       return r;
-}
-
-#endif /* STV0288_H */
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
deleted file mode 100644 (file)
index d40f226..0000000
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
-    Driver for STV0297 demodulator
-
-    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
-    Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "stv0297.h"
-
-struct stv0297_state {
-       struct i2c_adapter *i2c;
-       const struct stv0297_config *config;
-       struct dvb_frontend frontend;
-
-       unsigned long last_ber;
-       unsigned long base_freq;
-};
-
-#if 1
-#define dprintk(x...) printk(x)
-#else
-#define dprintk(x...)
-#endif
-
-#define STV0297_CLOCK_KHZ   28900
-
-
-static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
-                       "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static int stv0297_readreg(struct stv0297_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
-                                {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
-                              };
-
-       // this device needs a STOP between the register and data
-       if (state->config->stop_during_read) {
-               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
-                       return -1;
-               }
-               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
-                       return -1;
-               }
-       } else {
-               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
-                       return -1;
-               }
-       }
-
-       return b1[0];
-}
-
-static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
-{
-       int val;
-
-       val = stv0297_readreg(state, reg);
-       val &= ~mask;
-       val |= (data & mask);
-       stv0297_writereg(state, reg, val);
-
-       return 0;
-}
-
-static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
-{
-       int ret;
-       struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
-                                 &reg1,.len = 1},
-       {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
-       };
-
-       // this device needs a STOP between the register and data
-       if (state->config->stop_during_read) {
-               if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
-                       return -1;
-               }
-               if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
-                       return -1;
-               }
-       } else {
-               if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
-                       dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static u32 stv0297_get_symbolrate(struct stv0297_state *state)
-{
-       u64 tmp;
-
-       tmp = stv0297_readreg(state, 0x55);
-       tmp |= stv0297_readreg(state, 0x56) << 8;
-       tmp |= stv0297_readreg(state, 0x57) << 16;
-       tmp |= stv0297_readreg(state, 0x58) << 24;
-
-       tmp *= STV0297_CLOCK_KHZ;
-       tmp >>= 32;
-
-       return (u32) tmp;
-}
-
-static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
-{
-       long tmp;
-
-       tmp = 131072L * srate;  /* 131072 = 2^17  */
-       tmp = tmp / (STV0297_CLOCK_KHZ / 4);    /* 1/4 = 2^-2 */
-       tmp = tmp * 8192L;      /* 8192 = 2^13 */
-
-       stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
-       stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
-       stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
-       stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
-}
-
-static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
-{
-       long tmp;
-
-       tmp = (long) fshift *262144L;   /* 262144 = 2*18 */
-       tmp /= symrate;
-       tmp *= 1024;            /* 1024 = 2*10   */
-
-       // adjust
-       if (tmp >= 0) {
-               tmp += 500000;
-       } else {
-               tmp -= 500000;
-       }
-       tmp /= 1000000;
-
-       stv0297_writereg(state, 0x60, tmp & 0xFF);
-       stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
-}
-
-static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
-{
-       long tmp;
-
-       /* symrate is hardcoded to 10000 */
-       tmp = offset * 26844L;  /* (2**28)/10000 */
-       if (tmp < 0)
-               tmp += 0x10000000;
-       tmp &= 0x0FFFFFFF;
-
-       stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
-       stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
-       stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
-       stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
-}
-
-/*
-static long stv0297_get_carrieroffset(struct stv0297_state *state)
-{
-       s64 tmp;
-
-       stv0297_writereg(state, 0x6B, 0x00);
-
-       tmp = stv0297_readreg(state, 0x66);
-       tmp |= (stv0297_readreg(state, 0x67) << 8);
-       tmp |= (stv0297_readreg(state, 0x68) << 16);
-       tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
-
-       tmp *= stv0297_get_symbolrate(state);
-       tmp >>= 28;
-
-       return (s32) tmp;
-}
-*/
-
-static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
-{
-       s32 tmp;
-
-       if (freq > 10000)
-               freq -= STV0297_CLOCK_KHZ;
-
-       tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
-       tmp = (freq * 1000) / tmp;
-       if (tmp > 0xffff)
-               tmp = 0xffff;
-
-       stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
-       stv0297_writereg(state, 0x21, tmp >> 8);
-       stv0297_writereg(state, 0x20, tmp);
-}
-
-static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
-{
-       int val = 0;
-
-       switch (modulation) {
-       case QAM_16:
-               val = 0;
-               break;
-
-       case QAM_32:
-               val = 1;
-               break;
-
-       case QAM_64:
-               val = 4;
-               break;
-
-       case QAM_128:
-               val = 2;
-               break;
-
-       case QAM_256:
-               val = 3;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
-
-       return 0;
-}
-
-static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
-{
-       int val = 0;
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               val = 0;
-               break;
-
-       case INVERSION_ON:
-               val = 1;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
-
-       return 0;
-}
-
-static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-
-       if (enable) {
-               stv0297_writereg(state, 0x87, 0x78);
-               stv0297_writereg(state, 0x86, 0xc8);
-       }
-
-       return 0;
-}
-
-static int stv0297_init(struct dvb_frontend *fe)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-       int i;
-
-       /* load init table */
-       for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
-               stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
-       msleep(200);
-
-       state->last_ber = 0;
-
-       return 0;
-}
-
-static int stv0297_sleep(struct dvb_frontend *fe)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-
-       stv0297_writereg_mask(state, 0x80, 1, 1);
-
-       return 0;
-}
-
-static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-
-       u8 sync = stv0297_readreg(state, 0xDF);
-
-       *status = 0;
-       if (sync & 0x80)
-               *status |=
-                       FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
-       return 0;
-}
-
-static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-       u8 BER[3];
-
-       stv0297_readregs(state, 0xA0, BER, 3);
-       if (!(BER[0] & 0x80)) {
-               state->last_ber = BER[2] << 8 | BER[1];
-               stv0297_writereg_mask(state, 0xA0, 0x80, 0x80);
-       }
-
-       *ber = state->last_ber;
-
-       return 0;
-}
-
-
-static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-       u8 STRENGTH[3];
-       u16 tmp;
-
-       stv0297_readregs(state, 0x41, STRENGTH, 3);
-       tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
-       if (STRENGTH[2] & 0x20) {
-               if (tmp < 0x200)
-                       tmp = 0;
-               else
-                       tmp = tmp - 0x200;
-       } else {
-               if (tmp > 0x1ff)
-                       tmp = 0;
-               else
-                       tmp = 0x1ff - tmp;
-       }
-       *strength = (tmp << 7) | (tmp >> 2);
-       return 0;
-}
-
-static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-       u8 SNR[2];
-
-       stv0297_readregs(state, 0x07, SNR, 2);
-       *snr = SNR[1] << 8 | SNR[0];
-
-       return 0;
-}
-
-static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-
-       stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */
-
-       *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
-               | stv0297_readreg(state, 0xD4);
-
-       stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */
-       stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */
-
-       return 0;
-}
-
-static int stv0297_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0297_state *state = fe->demodulator_priv;
-       int u_threshold;
-       int initial_u;
-       int blind_u;
-       int delay;
-       int sweeprate;
-       int carrieroffset;
-       unsigned long timeout;
-       fe_spectral_inversion_t inversion;
-
-       switch (p->modulation) {
-       case QAM_16:
-       case QAM_32:
-       case QAM_64:
-               delay = 100;
-               sweeprate = 1000;
-               break;
-
-       case QAM_128:
-       case QAM_256:
-               delay = 200;
-               sweeprate = 500;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // determine inversion dependent parameters
-       inversion = p->inversion;
-       if (state->config->invert)
-               inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
-       carrieroffset = -330;
-       switch (inversion) {
-       case INVERSION_OFF:
-               break;
-
-       case INVERSION_ON:
-               sweeprate = -sweeprate;
-               carrieroffset = -carrieroffset;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       stv0297_init(fe);
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* clear software interrupts */
-       stv0297_writereg(state, 0x82, 0x0);
-
-       /* set initial demodulation frequency */
-       stv0297_set_initialdemodfreq(state, 7250);
-
-       /* setup AGC */
-       stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
-       stv0297_writereg(state, 0x41, 0x00);
-       stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
-       stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
-       stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
-       stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
-       stv0297_writereg(state, 0x72, 0x00);
-       stv0297_writereg(state, 0x73, 0x00);
-       stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
-       stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
-       stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
-
-       /* setup STL */
-       stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
-       stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
-       stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
-       stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
-       stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
-
-       /* disable frequency sweep */
-       stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
-
-       /* reset deinterleaver */
-       stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
-       stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
-
-       /* ??? */
-       stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
-       stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
-
-       /* reset equaliser */
-       u_threshold = stv0297_readreg(state, 0x00) & 0xf;
-       initial_u = stv0297_readreg(state, 0x01) >> 4;
-       blind_u = stv0297_readreg(state, 0x01) & 0xf;
-       stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
-       stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
-       stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
-       stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
-       stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
-
-       /* data comes from internal A/D */
-       stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
-
-       /* clear phase registers */
-       stv0297_writereg(state, 0x63, 0x00);
-       stv0297_writereg(state, 0x64, 0x00);
-       stv0297_writereg(state, 0x65, 0x00);
-       stv0297_writereg(state, 0x66, 0x00);
-       stv0297_writereg(state, 0x67, 0x00);
-       stv0297_writereg(state, 0x68, 0x00);
-       stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
-
-       /* set parameters */
-       stv0297_set_qam(state, p->modulation);
-       stv0297_set_symbolrate(state, p->symbol_rate / 1000);
-       stv0297_set_sweeprate(state, sweeprate, p->symbol_rate / 1000);
-       stv0297_set_carrieroffset(state, carrieroffset);
-       stv0297_set_inversion(state, inversion);
-
-       /* kick off lock */
-       /* Disable corner detection for higher QAMs */
-       if (p->modulation == QAM_128 ||
-               p->modulation == QAM_256)
-               stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
-       else
-               stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
-
-       stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
-       stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
-       stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
-       stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
-       stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
-       stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
-       stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
-
-       /* wait for WGAGC lock */
-       timeout = jiffies + msecs_to_jiffies(2000);
-       while (time_before(jiffies, timeout)) {
-               msleep(10);
-               if (stv0297_readreg(state, 0x43) & 0x08)
-                       break;
-       }
-       if (time_after(jiffies, timeout)) {
-               goto timeout;
-       }
-       msleep(20);
-
-       /* wait for equaliser partial convergence */
-       timeout = jiffies + msecs_to_jiffies(500);
-       while (time_before(jiffies, timeout)) {
-               msleep(10);
-
-               if (stv0297_readreg(state, 0x82) & 0x04) {
-                       break;
-               }
-       }
-       if (time_after(jiffies, timeout)) {
-               goto timeout;
-       }
-
-       /* wait for equaliser full convergence */
-       timeout = jiffies + msecs_to_jiffies(delay);
-       while (time_before(jiffies, timeout)) {
-               msleep(10);
-
-               if (stv0297_readreg(state, 0x82) & 0x08) {
-                       break;
-               }
-       }
-       if (time_after(jiffies, timeout)) {
-               goto timeout;
-       }
-
-       /* disable sweep */
-       stv0297_writereg_mask(state, 0x6a, 1, 0);
-       stv0297_writereg_mask(state, 0x88, 8, 0);
-
-       /* wait for main lock */
-       timeout = jiffies + msecs_to_jiffies(20);
-       while (time_before(jiffies, timeout)) {
-               msleep(10);
-
-               if (stv0297_readreg(state, 0xDF) & 0x80) {
-                       break;
-               }
-       }
-       if (time_after(jiffies, timeout)) {
-               goto timeout;
-       }
-       msleep(100);
-
-       /* is it still locked after that delay? */
-       if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
-               goto timeout;
-       }
-
-       /* success!! */
-       stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
-       state->base_freq = p->frequency;
-       return 0;
-
-timeout:
-       stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
-       return 0;
-}
-
-static int stv0297_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0297_state *state = fe->demodulator_priv;
-       int reg_00, reg_83;
-
-       reg_00 = stv0297_readreg(state, 0x00);
-       reg_83 = stv0297_readreg(state, 0x83);
-
-       p->frequency = state->base_freq;
-       p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
-       if (state->config->invert)
-               p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
-       p->symbol_rate = stv0297_get_symbolrate(state) * 1000;
-       p->fec_inner = FEC_NONE;
-
-       switch ((reg_00 >> 4) & 0x7) {
-       case 0:
-               p->modulation = QAM_16;
-               break;
-       case 1:
-               p->modulation = QAM_32;
-               break;
-       case 2:
-               p->modulation = QAM_128;
-               break;
-       case 3:
-               p->modulation = QAM_256;
-               break;
-       case 4:
-               p->modulation = QAM_64;
-               break;
-       }
-
-       return 0;
-}
-
-static void stv0297_release(struct dvb_frontend *fe)
-{
-       struct stv0297_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops stv0297_ops;
-
-struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct stv0297_state *state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->last_ber = 0;
-       state->base_freq = 0;
-
-       /* check if the demod is there */
-       if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops stv0297_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-                .name = "ST STV0297 DVB-C",
-                .frequency_min = 47000000,
-                .frequency_max = 862000000,
-                .frequency_stepsize = 62500,
-                .symbol_rate_min = 870000,
-                .symbol_rate_max = 11700000,
-                .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-                FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
-
-       .release = stv0297_release,
-
-       .init = stv0297_init,
-       .sleep = stv0297_sleep,
-       .i2c_gate_ctrl = stv0297_i2c_gate_ctrl,
-
-       .set_frontend = stv0297_set_frontend,
-       .get_frontend = stv0297_get_frontend,
-
-       .read_status = stv0297_read_status,
-       .read_ber = stv0297_read_ber,
-       .read_signal_strength = stv0297_read_signal_strength,
-       .read_snr = stv0297_read_snr,
-       .read_ucblocks = stv0297_read_ucblocks,
-};
-
-MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
-MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(stv0297_attach);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
deleted file mode 100644 (file)
index 3f8f946..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-    Driver for STV0297 demodulator
-
-    Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef STV0297_H
-#define STV0297_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct stv0297_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* inittab - array of pairs of values.
-       * First of each pair is the register, second is the value.
-       * List should be terminated with an 0xff, 0xff pair.
-       */
-       u8* inittab;
-
-       /* does the "inversion" need inverted? */
-       u8 invert:1;
-
-       /* set to 1 if the device requires an i2c STOP during reading */
-       u8 stop_during_read:1;
-};
-
-#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE))
-extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_STV0297
-
-#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
deleted file mode 100644 (file)
index 057b5f8..0000000
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
-    Driver for ST STV0299 demodulator
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-       <ralph@convergence.de>,
-       <holger@convergence.de>,
-       <js@convergence.de>
-
-
-    Philips SU1278/SH
-
-    Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
-
-
-    LG TDQF-S001F
-
-    Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
-                    & Andreas Oberritter <obi@linuxtv.org>
-
-
-    Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
-
-    Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
-
-    Support for Philips SU1278 on Technotrend hardware
-
-    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "stv0299.h"
-
-struct stv0299_state {
-       struct i2c_adapter* i2c;
-       const struct stv0299_config* config;
-       struct dvb_frontend frontend;
-
-       u8 initialised:1;
-       u32 tuner_frequency;
-       u32 symbol_rate;
-       fe_code_rate_t fec_inner;
-       int errmode;
-       u32 ucblocks;
-       u8 mcr_reg;
-};
-
-#define STATUS_BER 0
-#define STATUS_UCBLOCKS 1
-
-static int debug;
-static int debug_legacy_dish_switch;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "stv0299: " args); \
-       } while (0)
-
-
-static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf [] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       ret = i2c_transfer (state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
-                       "ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return stv0299_writeregI(state, buf[0], buf[1]);
-}
-
-static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
-                               __func__, reg, ret);
-
-       return b1[0];
-}
-
-static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
-{
-       int ret;
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
-
-       return ret == 2 ? 0 : ret;
-}
-
-static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
-{
-       dprintk ("%s\n", __func__);
-
-       switch (fec) {
-       case FEC_AUTO:
-       {
-               return stv0299_writeregI (state, 0x31, 0x1f);
-       }
-       case FEC_1_2:
-       {
-               return stv0299_writeregI (state, 0x31, 0x01);
-       }
-       case FEC_2_3:
-       {
-               return stv0299_writeregI (state, 0x31, 0x02);
-       }
-       case FEC_3_4:
-       {
-               return stv0299_writeregI (state, 0x31, 0x04);
-       }
-       case FEC_5_6:
-       {
-               return stv0299_writeregI (state, 0x31, 0x08);
-       }
-       case FEC_7_8:
-       {
-               return stv0299_writeregI (state, 0x31, 0x10);
-       }
-       default:
-       {
-               return -EINVAL;
-       }
-    }
-}
-
-static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
-{
-       static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
-                                            FEC_7_8, FEC_1_2 };
-       u8 index;
-
-       dprintk ("%s\n", __func__);
-
-       index = stv0299_readreg (state, 0x1b);
-       index &= 0x7;
-
-       if (index > 4)
-               return FEC_AUTO;
-
-       return fec_tab [index];
-}
-
-static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
-{
-       unsigned long start = jiffies;
-
-       dprintk ("%s\n", __func__);
-
-       while (stv0299_readreg(state, 0x0a) & 1) {
-               if (jiffies - start > timeout) {
-                       dprintk ("%s: timeout!!\n", __func__);
-                       return -ETIMEDOUT;
-               }
-               msleep(10);
-       };
-
-       return 0;
-}
-
-static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
-{
-       unsigned long start = jiffies;
-
-       dprintk ("%s\n", __func__);
-
-       while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
-               if (jiffies - start > timeout) {
-                       dprintk ("%s: timeout!!\n", __func__);
-                       return -ETIMEDOUT;
-               }
-               msleep(10);
-       };
-
-       return 0;
-}
-
-static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u64 big = srate;
-       u32 ratio;
-
-       // check rate is within limits
-       if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
-
-       // calculate value to program
-       big = big << 20;
-       big += (state->config->mclk-1); // round correctly
-       do_div(big, state->config->mclk);
-       ratio = big << 4;
-
-       return state->config->set_symbol_rate(fe, srate, ratio);
-}
-
-static int stv0299_get_symbolrate (struct stv0299_state* state)
-{
-       u32 Mclk = state->config->mclk / 4096L;
-       u32 srate;
-       s32 offset;
-       u8 sfr[3];
-       s8 rtf;
-
-       dprintk ("%s\n", __func__);
-
-       stv0299_readregs (state, 0x1f, sfr, 3);
-       stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1);
-
-       srate = (sfr[0] << 8) | sfr[1];
-       srate *= Mclk;
-       srate /= 16;
-       srate += (sfr[2] >> 4) * Mclk / 256;
-       offset = (s32) rtf * (srate / 4096L);
-       offset /= 128;
-
-       dprintk ("%s : srate = %i\n", __func__, srate);
-       dprintk ("%s : ofset = %i\n", __func__, offset);
-
-       srate += offset;
-
-       srate += 1000;
-       srate /= 2000;
-       srate *= 2000;
-
-       return srate;
-}
-
-static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u8 val;
-       int i;
-
-       dprintk ("%s\n", __func__);
-
-       if (stv0299_wait_diseqc_idle (state, 100) < 0)
-               return -ETIMEDOUT;
-
-       val = stv0299_readreg (state, 0x08);
-
-       if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6))  /* DiSEqC mode */
-               return -EREMOTEIO;
-
-       for (i=0; i<m->msg_len; i++) {
-               if (stv0299_wait_diseqc_fifo (state, 100) < 0)
-                       return -ETIMEDOUT;
-
-               if (stv0299_writeregI (state, 0x09, m->msg[i]))
-                       return -EREMOTEIO;
-       }
-
-       if (stv0299_wait_diseqc_idle (state, 100) < 0)
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
-static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk ("%s\n", __func__);
-
-       if (stv0299_wait_diseqc_idle (state, 100) < 0)
-               return -ETIMEDOUT;
-
-       val = stv0299_readreg (state, 0x08);
-
-       if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2))        /* burst mode */
-               return -EREMOTEIO;
-
-       if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
-               return -EREMOTEIO;
-
-       if (stv0299_wait_diseqc_idle (state, 100) < 0)
-               return -ETIMEDOUT;
-
-       if (stv0299_writeregI (state, 0x08, val))
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u8 val;
-
-       if (stv0299_wait_diseqc_idle (state, 100) < 0)
-               return -ETIMEDOUT;
-
-       val = stv0299_readreg (state, 0x08);
-
-       switch (tone) {
-       case SEC_TONE_ON:
-               return stv0299_writeregI (state, 0x08, val | 0x3);
-
-       case SEC_TONE_OFF:
-               return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u8 reg0x08;
-       u8 reg0x0c;
-
-       dprintk("%s: %s\n", __func__,
-               voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
-               voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
-
-       reg0x08 = stv0299_readreg (state, 0x08);
-       reg0x0c = stv0299_readreg (state, 0x0c);
-
-       /**
-        *  H/V switching over OP0, OP1 and OP2 are LNB power enable bits
-        */
-       reg0x0c &= 0x0f;
-       reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6);
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
-                       reg0x0c |= 0x10; /* OP1 off, OP0 on */
-               else
-                       reg0x0c |= 0x40; /* OP1 on, OP0 off */
-               break;
-       case SEC_VOLTAGE_18:
-               reg0x0c |= 0x50; /* OP1 on, OP0 on */
-               break;
-       case SEC_VOLTAGE_OFF:
-               /* LNB power off! */
-               reg0x08 = 0x00;
-               reg0x0c = 0x00;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       if (state->config->op0_off)
-               reg0x0c &= ~0x10;
-
-       stv0299_writeregI(state, 0x08, reg0x08);
-       return stv0299_writeregI(state, 0x0c, reg0x0c);
-}
-
-static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       u8 reg0x08;
-       u8 reg0x0c;
-       u8 lv_mask = 0x40;
-       u8 last = 1;
-       int i;
-       struct timeval nexttime;
-       struct timeval tv[10];
-
-       reg0x08 = stv0299_readreg (state, 0x08);
-       reg0x0c = stv0299_readreg (state, 0x0c);
-       reg0x0c &= 0x0f;
-       stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
-       if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
-               lv_mask = 0x10;
-
-       cmd = cmd << 1;
-       if (debug_legacy_dish_switch)
-               printk ("%s switch command: 0x%04lx\n",__func__, cmd);
-
-       do_gettimeofday (&nexttime);
-       if (debug_legacy_dish_switch)
-               memcpy (&tv[0], &nexttime, sizeof (struct timeval));
-       stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
-
-       dvb_frontend_sleep_until(&nexttime, 32000);
-
-       for (i=0; i<9; i++) {
-               if (debug_legacy_dish_switch)
-                       do_gettimeofday (&tv[i+1]);
-               if((cmd & 0x01) != last) {
-                       /* set voltage to (last ? 13V : 18V) */
-                       stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
-                       last = (last) ? 0 : 1;
-               }
-
-               cmd = cmd >> 1;
-
-               if (i != 8)
-                       dvb_frontend_sleep_until(&nexttime, 8000);
-       }
-       if (debug_legacy_dish_switch) {
-               printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
-                       __func__, fe->dvb->num);
-               for (i = 1; i < 10; i++)
-                       printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
-       }
-
-       return 0;
-}
-
-static int stv0299_init (struct dvb_frontend* fe)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       int i;
-       u8 reg;
-       u8 val;
-
-       dprintk("stv0299: init chip\n");
-
-       stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
-       msleep(50);
-
-       for (i = 0; ; i += 2)  {
-               reg = state->config->inittab[i];
-               val = state->config->inittab[i+1];
-               if (reg == 0xff && val == 0xff)
-                       break;
-               if (reg == 0x0c && state->config->op0_off)
-                       val &= ~0x10;
-               if (reg == 0x2)
-                       state->mcr_reg = val & 0xf;
-               stv0299_writeregI(state, reg, val);
-       }
-
-       return 0;
-}
-
-static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       u8 signal = 0xff - stv0299_readreg (state, 0x18);
-       u8 sync = stv0299_readreg (state, 0x1b);
-
-       dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
-       *status = 0;
-
-       if (signal > 10)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 0x80)
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 0x10)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 0x08)
-               *status |= FE_HAS_SYNC;
-
-       if ((sync & 0x98) == 0x98)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       if (state->errmode != STATUS_BER)
-               return -ENOSYS;
-
-       *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
-
-       return 0;
-}
-
-static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       s32 signal =  0xffff - ((stv0299_readreg (state, 0x18) << 8)
-                              | stv0299_readreg (state, 0x19));
-
-       dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
-                stv0299_readreg (state, 0x18),
-                stv0299_readreg (state, 0x19), (int) signal);
-
-       signal = signal * 5 / 4;
-       *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
-
-       return 0;
-}
-
-static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
-                          | stv0299_readreg (state, 0x25));
-       xsnr = 3 * (xsnr - 0xa100);
-       *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
-
-       return 0;
-}
-
-static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       if (state->errmode != STATUS_UCBLOCKS)
-               return -ENOSYS;
-
-       state->ucblocks += stv0299_readreg(state, 0x1e);
-       state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
-       *ucblocks = state->ucblocks;
-
-       return 0;
-}
-
-static int stv0299_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0299_state* state = fe->demodulator_priv;
-       int invval = 0;
-
-       dprintk ("%s : FE_SET_FRONTEND\n", __func__);
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-
-       // set the inversion
-       if (p->inversion == INVERSION_OFF) invval = 0;
-       else if (p->inversion == INVERSION_ON) invval = 1;
-       else {
-               printk("stv0299 does not support auto-inversion\n");
-               return -EINVAL;
-       }
-       if (state->config->invert) invval = (~invval) & 1;
-       stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       stv0299_set_FEC(state, p->fec_inner);
-       stv0299_set_symbolrate(fe, p->symbol_rate);
-       stv0299_writeregI(state, 0x22, 0x00);
-       stv0299_writeregI(state, 0x23, 0x00);
-
-       state->tuner_frequency = p->frequency;
-       state->fec_inner = p->fec_inner;
-       state->symbol_rate = p->symbol_rate;
-
-       return 0;
-}
-
-static int stv0299_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0299_state* state = fe->demodulator_priv;
-       s32 derot_freq;
-       int invval;
-
-       derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
-                               | stv0299_readreg (state, 0x23));
-
-       derot_freq *= (state->config->mclk >> 16);
-       derot_freq += 500;
-       derot_freq /= 1000;
-
-       p->frequency += derot_freq;
-
-       invval = stv0299_readreg (state, 0x0c) & 1;
-       if (state->config->invert) invval = (~invval) & 1;
-       p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
-
-       p->fec_inner = stv0299_get_fec(state);
-       p->symbol_rate = stv0299_get_symbolrate(state);
-
-       return 0;
-}
-
-static int stv0299_sleep(struct dvb_frontend* fe)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
-       state->initialised = 0;
-
-       return 0;
-}
-
-static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               stv0299_writeregI(state, 0x05, 0xb5);
-       } else {
-               stv0299_writeregI(state, 0x05, 0x35);
-       }
-       udelay(1);
-       return 0;
-}
-
-static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       fesettings->min_delay_ms = state->config->min_delay_ms;
-       if (p->symbol_rate < 10000000) {
-               fesettings->step_size = p->symbol_rate / 32000;
-               fesettings->max_drift = 5000;
-       } else {
-               fesettings->step_size = p->symbol_rate / 16000;
-               fesettings->max_drift = p->symbol_rate / 2000;
-       }
-       return 0;
-}
-
-static void stv0299_release(struct dvb_frontend* fe)
-{
-       struct stv0299_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops stv0299_ops;
-
-struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct stv0299_state* state = NULL;
-       int id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->initialised = 0;
-       state->tuner_frequency = 0;
-       state->symbol_rate = 0;
-       state->fec_inner = 0;
-       state->errmode = STATUS_BER;
-
-       /* check if the demod is there */
-       stv0299_writeregI(state, 0x02, 0x30); /* standby off */
-       msleep(200);
-       id = stv0299_readreg(state, 0x00);
-
-       /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
-       /* register 0x00 might contain 0x80 when returning from standby */
-       if (id != 0xa1 && id != 0x80) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops stv0299_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "ST STV0299 DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,  /* ppm */
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                     FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                     FE_CAN_QPSK |
-                     FE_CAN_FEC_AUTO
-       },
-
-       .release = stv0299_release,
-
-       .init = stv0299_init,
-       .sleep = stv0299_sleep,
-       .write = stv0299_write,
-       .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
-
-       .set_frontend = stv0299_set_frontend,
-       .get_frontend = stv0299_get_frontend,
-       .get_tune_settings = stv0299_get_tune_settings,
-
-       .read_status = stv0299_read_status,
-       .read_ber = stv0299_read_ber,
-       .read_signal_strength = stv0299_read_signal_strength,
-       .read_snr = stv0299_read_snr,
-       .read_ucblocks = stv0299_read_ucblocks,
-
-       .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
-       .diseqc_send_burst = stv0299_send_diseqc_burst,
-       .set_tone = stv0299_set_tone,
-       .set_voltage = stv0299_set_voltage,
-       .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
-};
-
-module_param(debug_legacy_dish_switch, int, 0444);
-MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
-MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
-             "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
deleted file mode 100644 (file)
index ba219b7..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-    Driver for ST STV0299 demodulator
-
-    Copyright (C) 2001-2002 Convergence Integrated Media GmbH
-       <ralph@convergence.de>,
-       <holger@convergence.de>,
-       <js@convergence.de>
-
-
-    Philips SU1278/SH
-
-    Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
-
-
-    LG TDQF-S001F
-
-    Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
-                    & Andreas Oberritter <obi@linuxtv.org>
-
-
-    Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
-
-    Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
-
-    Support for Philips SU1278 on Technotrend hardware
-
-    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef STV0299_H
-#define STV0299_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-#define STV0299_LOCKOUTPUT_0  0
-#define STV0299_LOCKOUTPUT_1  1
-#define STV0299_LOCKOUTPUT_CF 2
-#define STV0299_LOCKOUTPUT_LK 3
-
-#define STV0299_VOLT13_OP0 0
-#define STV0299_VOLT13_OP1 1
-
-struct stv0299_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* inittab - array of pairs of values.
-        * First of each pair is the register, second is the value.
-        * List should be terminated with an 0xff, 0xff pair.
-        */
-       const u8* inittab;
-
-       /* master clock to use */
-       u32 mclk;
-
-       /* does the inversion require inversion? */
-       u8 invert:1;
-
-       /* Skip reinitialisation? */
-       u8 skip_reinit:1;
-
-       /* LOCK OUTPUT setting */
-       u8 lock_output:2;
-
-       /* Is 13v controlled by OP0 or OP1? */
-       u8 volt13_op0_op1:1;
-
-       /* Turn-off OP0? */
-       u8 op0_off:1;
-
-       /* minimum delay before retuning */
-       int min_delay_ms;
-
-       /* Set the symbol rate */
-       int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio);
-
-       /* Set device param to start dma */
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-};
-
-#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
-extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
-                                          struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_STV0299
-
-static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
-       int r = 0;
-       u8 buf[] = {reg, val};
-       if (fe->ops.write)
-               r = fe->ops.write(fe, buf, 2);
-       return r;
-}
-
-#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c
deleted file mode 100644 (file)
index 2a8aaeb..0000000
+++ /dev/null
@@ -1,3450 +0,0 @@
-/*
- * stv0367.c
- *
- * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-
-#include "stv0367.h"
-#include "stv0367_regs.h"
-#include "stv0367_priv.h"
-
-static int stvdebug;
-module_param_named(debug, stvdebug, int, 0644);
-
-static int i2cdebug;
-module_param_named(i2c_debug, i2cdebug, int, 0644);
-
-#define dprintk(args...) \
-       do { \
-               if (stvdebug) \
-                       printk(KERN_DEBUG args); \
-       } while (0)
-       /* DVB-C */
-
-struct stv0367cab_state {
-       enum stv0367_cab_signal_type    state;
-       u32     mclk;
-       u32     adc_clk;
-       s32     search_range;
-       s32     derot_offset;
-       /* results */
-       int locked;                     /* channel found                */
-       u32 freq_khz;                   /* found frequency (in kHz)     */
-       u32 symbol_rate;                /* found symbol rate (in Bds)   */
-       enum stv0367cab_mod modulation; /* modulation                   */
-       fe_spectral_inversion_t spect_inv; /* Spectrum Inversion        */
-};
-
-struct stv0367ter_state {
-       /* DVB-T */
-       enum stv0367_ter_signal_type state;
-       enum stv0367_ter_if_iq_mode if_iq_mode;
-       enum stv0367_ter_mode mode;/* mode 2K or 8K */
-       fe_guard_interval_t guard;
-       enum stv0367_ter_hierarchy hierarchy;
-       u32 frequency;
-       fe_spectral_inversion_t  sense; /*  current search spectrum */
-       u8  force; /* force mode/guard */
-       u8  bw; /* channel width 6, 7 or 8 in MHz */
-       u8  pBW; /* channel width used during previous lock */
-       u32 pBER;
-       u32 pPER;
-       u32 ucblocks;
-       s8  echo_pos; /* echo position */
-       u8  first_lock;
-       u8  unlock_counter;
-       u32 agc_val;
-};
-
-struct stv0367_state {
-       struct dvb_frontend fe;
-       struct i2c_adapter *i2c;
-       /* config settings */
-       const struct stv0367_config *config;
-       u8 chip_id;
-       /* DVB-C */
-       struct stv0367cab_state *cab_state;
-       /* DVB-T */
-       struct stv0367ter_state *ter_state;
-};
-
-struct st_register {
-       u16     addr;
-       u8      value;
-};
-
-/* values for STV4100 XTAL=30M int clk=53.125M*/
-static struct st_register def0367ter[STV0367TER_NBREGS] = {
-       {R367TER_ID,            0x60},
-       {R367TER_I2CRPT,        0xa0},
-       /* {R367TER_I2CRPT,     0x22},*/
-       {R367TER_TOPCTRL,       0x00},/* for xc5000; was 0x02 */
-       {R367TER_IOCFG0,        0x40},
-       {R367TER_DAC0R,         0x00},
-       {R367TER_IOCFG1,        0x00},
-       {R367TER_DAC1R,         0x00},
-       {R367TER_IOCFG2,        0x62},
-       {R367TER_SDFR,          0x00},
-       {R367TER_STATUS,        0xf8},
-       {R367TER_AUX_CLK,       0x0a},
-       {R367TER_FREESYS1,      0x00},
-       {R367TER_FREESYS2,      0x00},
-       {R367TER_FREESYS3,      0x00},
-       {R367TER_GPIO_CFG,      0x55},
-       {R367TER_GPIO_CMD,      0x00},
-       {R367TER_AGC2MAX,       0xff},
-       {R367TER_AGC2MIN,       0x00},
-       {R367TER_AGC1MAX,       0xff},
-       {R367TER_AGC1MIN,       0x00},
-       {R367TER_AGCR,          0xbc},
-       {R367TER_AGC2TH,        0x00},
-       {R367TER_AGC12C,        0x00},
-       {R367TER_AGCCTRL1,      0x85},
-       {R367TER_AGCCTRL2,      0x1f},
-       {R367TER_AGC1VAL1,      0x00},
-       {R367TER_AGC1VAL2,      0x00},
-       {R367TER_AGC2VAL1,      0x6f},
-       {R367TER_AGC2VAL2,      0x05},
-       {R367TER_AGC2PGA,       0x00},
-       {R367TER_OVF_RATE1,     0x00},
-       {R367TER_OVF_RATE2,     0x00},
-       {R367TER_GAIN_SRC1,     0xaa},/* for xc5000; was 0x2b */
-       {R367TER_GAIN_SRC2,     0xd6},/* for xc5000; was 0x04 */
-       {R367TER_INC_DEROT1,    0x55},
-       {R367TER_INC_DEROT2,    0x55},
-       {R367TER_PPM_CPAMP_DIR, 0x2c},
-       {R367TER_PPM_CPAMP_INV, 0x00},
-       {R367TER_FREESTFE_1,    0x00},
-       {R367TER_FREESTFE_2,    0x1c},
-       {R367TER_DCOFFSET,      0x00},
-       {R367TER_EN_PROCESS,    0x05},
-       {R367TER_SDI_SMOOTHER,  0x80},
-       {R367TER_FE_LOOP_OPEN,  0x1c},
-       {R367TER_FREQOFF1,      0x00},
-       {R367TER_FREQOFF2,      0x00},
-       {R367TER_FREQOFF3,      0x00},
-       {R367TER_TIMOFF1,       0x00},
-       {R367TER_TIMOFF2,       0x00},
-       {R367TER_EPQ,           0x02},
-       {R367TER_EPQAUTO,       0x01},
-       {R367TER_SYR_UPDATE,    0xf5},
-       {R367TER_CHPFREE,       0x00},
-       {R367TER_PPM_STATE_MAC, 0x23},
-       {R367TER_INR_THRESHOLD, 0xff},
-       {R367TER_EPQ_TPS_ID_CELL, 0xf9},
-       {R367TER_EPQ_CFG,       0x00},
-       {R367TER_EPQ_STATUS,    0x01},
-       {R367TER_AUTORELOCK,    0x81},
-       {R367TER_BER_THR_VMSB,  0x00},
-       {R367TER_BER_THR_MSB,   0x00},
-       {R367TER_BER_THR_LSB,   0x00},
-       {R367TER_CCD,           0x83},
-       {R367TER_SPECTR_CFG,    0x00},
-       {R367TER_CHC_DUMMY,     0x18},
-       {R367TER_INC_CTL,       0x88},
-       {R367TER_INCTHRES_COR1, 0xb4},
-       {R367TER_INCTHRES_COR2, 0x96},
-       {R367TER_INCTHRES_DET1, 0x0e},
-       {R367TER_INCTHRES_DET2, 0x11},
-       {R367TER_IIR_CELLNB,    0x8d},
-       {R367TER_IIRCX_COEFF1_MSB, 0x00},
-       {R367TER_IIRCX_COEFF1_LSB, 0x00},
-       {R367TER_IIRCX_COEFF2_MSB, 0x09},
-       {R367TER_IIRCX_COEFF2_LSB, 0x18},
-       {R367TER_IIRCX_COEFF3_MSB, 0x14},
-       {R367TER_IIRCX_COEFF3_LSB, 0x9c},
-       {R367TER_IIRCX_COEFF4_MSB, 0x00},
-       {R367TER_IIRCX_COEFF4_LSB, 0x00},
-       {R367TER_IIRCX_COEFF5_MSB, 0x36},
-       {R367TER_IIRCX_COEFF5_LSB, 0x42},
-       {R367TER_FEPATH_CFG,    0x00},
-       {R367TER_PMC1_FUNC,     0x65},
-       {R367TER_PMC1_FOR,      0x00},
-       {R367TER_PMC2_FUNC,     0x00},
-       {R367TER_STATUS_ERR_DA, 0xe0},
-       {R367TER_DIG_AGC_R,     0xfe},
-       {R367TER_COMAGC_TARMSB, 0x0b},
-       {R367TER_COM_AGC_TAR_ENMODE, 0x41},
-       {R367TER_COM_AGC_CFG,   0x3e},
-       {R367TER_COM_AGC_GAIN1, 0x39},
-       {R367TER_AUT_AGC_TARGETMSB, 0x0b},
-       {R367TER_LOCK_DET_MSB,  0x01},
-       {R367TER_AGCTAR_LOCK_LSBS, 0x40},
-       {R367TER_AUT_GAIN_EN,   0xf4},
-       {R367TER_AUT_CFG,       0xf0},
-       {R367TER_LOCKN,         0x23},
-       {R367TER_INT_X_3,       0x00},
-       {R367TER_INT_X_2,       0x03},
-       {R367TER_INT_X_1,       0x8d},
-       {R367TER_INT_X_0,       0xa0},
-       {R367TER_MIN_ERRX_MSB,  0x00},
-       {R367TER_COR_CTL,       0x23},
-       {R367TER_COR_STAT,      0xf6},
-       {R367TER_COR_INTEN,     0x00},
-       {R367TER_COR_INTSTAT,   0x3f},
-       {R367TER_COR_MODEGUARD, 0x03},
-       {R367TER_AGC_CTL,       0x08},
-       {R367TER_AGC_MANUAL1,   0x00},
-       {R367TER_AGC_MANUAL2,   0x00},
-       {R367TER_AGC_TARG,      0x16},
-       {R367TER_AGC_GAIN1,     0x53},
-       {R367TER_AGC_GAIN2,     0x1d},
-       {R367TER_RESERVED_1,    0x00},
-       {R367TER_RESERVED_2,    0x00},
-       {R367TER_RESERVED_3,    0x00},
-       {R367TER_CAS_CTL,       0x44},
-       {R367TER_CAS_FREQ,      0xb3},
-       {R367TER_CAS_DAGCGAIN,  0x12},
-       {R367TER_SYR_CTL,       0x04},
-       {R367TER_SYR_STAT,      0x10},
-       {R367TER_SYR_NCO1,      0x00},
-       {R367TER_SYR_NCO2,      0x00},
-       {R367TER_SYR_OFFSET1,   0x00},
-       {R367TER_SYR_OFFSET2,   0x00},
-       {R367TER_FFT_CTL,       0x00},
-       {R367TER_SCR_CTL,       0x70},
-       {R367TER_PPM_CTL1,      0xf8},
-       {R367TER_TRL_CTL,       0x14},/* for xc5000; was 0xac */
-       {R367TER_TRL_NOMRATE1,  0xae},/* for xc5000; was 0x1e */
-       {R367TER_TRL_NOMRATE2,  0x56},/* for xc5000; was 0x58 */
-       {R367TER_TRL_TIME1,     0x1d},
-       {R367TER_TRL_TIME2,     0xfc},
-       {R367TER_CRL_CTL,       0x24},
-       {R367TER_CRL_FREQ1,     0xad},
-       {R367TER_CRL_FREQ2,     0x9d},
-       {R367TER_CRL_FREQ3,     0xff},
-       {R367TER_CHC_CTL,       0x01},
-       {R367TER_CHC_SNR,       0xf0},
-       {R367TER_BDI_CTL,       0x00},
-       {R367TER_DMP_CTL,       0x00},
-       {R367TER_TPS_RCVD1,     0x30},
-       {R367TER_TPS_RCVD2,     0x02},
-       {R367TER_TPS_RCVD3,     0x01},
-       {R367TER_TPS_RCVD4,     0x00},
-       {R367TER_TPS_ID_CELL1,  0x00},
-       {R367TER_TPS_ID_CELL2,  0x00},
-       {R367TER_TPS_RCVD5_SET1, 0x02},
-       {R367TER_TPS_SET2,      0x02},
-       {R367TER_TPS_SET3,      0x01},
-       {R367TER_TPS_CTL,       0x00},
-       {R367TER_CTL_FFTOSNUM,  0x34},
-       {R367TER_TESTSELECT,    0x09},
-       {R367TER_MSC_REV,       0x0a},
-       {R367TER_PIR_CTL,       0x00},
-       {R367TER_SNR_CARRIER1,  0xa1},
-       {R367TER_SNR_CARRIER2,  0x9a},
-       {R367TER_PPM_CPAMP,     0x2c},
-       {R367TER_TSM_AP0,       0x00},
-       {R367TER_TSM_AP1,       0x00},
-       {R367TER_TSM_AP2 ,      0x00},
-       {R367TER_TSM_AP3,       0x00},
-       {R367TER_TSM_AP4,       0x00},
-       {R367TER_TSM_AP5,       0x00},
-       {R367TER_TSM_AP6,       0x00},
-       {R367TER_TSM_AP7,       0x00},
-       {R367TER_TSTRES,        0x00},
-       {R367TER_ANACTRL,       0x0D},/* PLL stoped, restart at init!!! */
-       {R367TER_TSTBUS,        0x00},
-       {R367TER_TSTRATE,       0x00},
-       {R367TER_CONSTMODE,     0x01},
-       {R367TER_CONSTCARR1,    0x00},
-       {R367TER_CONSTCARR2,    0x00},
-       {R367TER_ICONSTEL,      0x0a},
-       {R367TER_QCONSTEL,      0x15},
-       {R367TER_TSTBISTRES0,   0x00},
-       {R367TER_TSTBISTRES1,   0x00},
-       {R367TER_TSTBISTRES2,   0x28},
-       {R367TER_TSTBISTRES3,   0x00},
-       {R367TER_RF_AGC1,       0xff},
-       {R367TER_RF_AGC2,       0x83},
-       {R367TER_ANADIGCTRL,    0x19},
-       {R367TER_PLLMDIV,       0x01},/* for xc5000; was 0x0c */
-       {R367TER_PLLNDIV,       0x06},/* for xc5000; was 0x55 */
-       {R367TER_PLLSETUP,      0x18},
-       {R367TER_DUAL_AD12,     0x0C},/* for xc5000 AGC voltage 1.6V */
-       {R367TER_TSTBIST,       0x00},
-       {R367TER_PAD_COMP_CTRL, 0x00},
-       {R367TER_PAD_COMP_WR,   0x00},
-       {R367TER_PAD_COMP_RD,   0xe0},
-       {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
-       {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
-       {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
-       {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
-       {R367TER_SYR_FLAG,      0x00},
-       {R367TER_CRL_TARGET1,   0x00},
-       {R367TER_CRL_TARGET2,   0x00},
-       {R367TER_CRL_TARGET3,   0x00},
-       {R367TER_CRL_TARGET4,   0x00},
-       {R367TER_CRL_FLAG,      0x00},
-       {R367TER_TRL_TARGET1,   0x00},
-       {R367TER_TRL_TARGET2,   0x00},
-       {R367TER_TRL_CHC,       0x00},
-       {R367TER_CHC_SNR_TARG,  0x00},
-       {R367TER_TOP_TRACK,     0x00},
-       {R367TER_TRACKER_FREE1, 0x00},
-       {R367TER_ERROR_CRL1,    0x00},
-       {R367TER_ERROR_CRL2,    0x00},
-       {R367TER_ERROR_CRL3,    0x00},
-       {R367TER_ERROR_CRL4,    0x00},
-       {R367TER_DEC_NCO1,      0x2c},
-       {R367TER_DEC_NCO2,      0x0f},
-       {R367TER_DEC_NCO3,      0x20},
-       {R367TER_SNR,           0xf1},
-       {R367TER_SYR_FFTADJ1,   0x00},
-       {R367TER_SYR_FFTADJ2,   0x00},
-       {R367TER_SYR_CHCADJ1,   0x00},
-       {R367TER_SYR_CHCADJ2,   0x00},
-       {R367TER_SYR_OFF,       0x00},
-       {R367TER_PPM_OFFSET1,   0x00},
-       {R367TER_PPM_OFFSET2,   0x03},
-       {R367TER_TRACKER_FREE2, 0x00},
-       {R367TER_DEBG_LT10,     0x00},
-       {R367TER_DEBG_LT11,     0x00},
-       {R367TER_DEBG_LT12,     0x00},
-       {R367TER_DEBG_LT13,     0x00},
-       {R367TER_DEBG_LT14,     0x00},
-       {R367TER_DEBG_LT15,     0x00},
-       {R367TER_DEBG_LT16,     0x00},
-       {R367TER_DEBG_LT17,     0x00},
-       {R367TER_DEBG_LT18,     0x00},
-       {R367TER_DEBG_LT19,     0x00},
-       {R367TER_DEBG_LT1A,     0x00},
-       {R367TER_DEBG_LT1B,     0x00},
-       {R367TER_DEBG_LT1C,     0x00},
-       {R367TER_DEBG_LT1D,     0x00},
-       {R367TER_DEBG_LT1E,     0x00},
-       {R367TER_DEBG_LT1F,     0x00},
-       {R367TER_RCCFGH,        0x00},
-       {R367TER_RCCFGM,        0x00},
-       {R367TER_RCCFGL,        0x00},
-       {R367TER_RCINSDELH,     0x00},
-       {R367TER_RCINSDELM,     0x00},
-       {R367TER_RCINSDELL,     0x00},
-       {R367TER_RCSTATUS,      0x00},
-       {R367TER_RCSPEED,       0x6f},
-       {R367TER_RCDEBUGM,      0xe7},
-       {R367TER_RCDEBUGL,      0x9b},
-       {R367TER_RCOBSCFG,      0x00},
-       {R367TER_RCOBSM,        0x00},
-       {R367TER_RCOBSL,        0x00},
-       {R367TER_RCFECSPY,      0x00},
-       {R367TER_RCFSPYCFG,     0x00},
-       {R367TER_RCFSPYDATA,    0x00},
-       {R367TER_RCFSPYOUT,     0x00},
-       {R367TER_RCFSTATUS,     0x00},
-       {R367TER_RCFGOODPACK,   0x00},
-       {R367TER_RCFPACKCNT,    0x00},
-       {R367TER_RCFSPYMISC,    0x00},
-       {R367TER_RCFBERCPT4,    0x00},
-       {R367TER_RCFBERCPT3,    0x00},
-       {R367TER_RCFBERCPT2,    0x00},
-       {R367TER_RCFBERCPT1,    0x00},
-       {R367TER_RCFBERCPT0,    0x00},
-       {R367TER_RCFBERERR2,    0x00},
-       {R367TER_RCFBERERR1,    0x00},
-       {R367TER_RCFBERERR0,    0x00},
-       {R367TER_RCFSTATESM,    0x00},
-       {R367TER_RCFSTATESL,    0x00},
-       {R367TER_RCFSPYBER,     0x00},
-       {R367TER_RCFSPYDISTM,   0x00},
-       {R367TER_RCFSPYDISTL,   0x00},
-       {R367TER_RCFSPYOBS7,    0x00},
-       {R367TER_RCFSPYOBS6,    0x00},
-       {R367TER_RCFSPYOBS5,    0x00},
-       {R367TER_RCFSPYOBS4,    0x00},
-       {R367TER_RCFSPYOBS3,    0x00},
-       {R367TER_RCFSPYOBS2,    0x00},
-       {R367TER_RCFSPYOBS1,    0x00},
-       {R367TER_RCFSPYOBS0,    0x00},
-       {R367TER_TSGENERAL,     0x00},
-       {R367TER_RC1SPEED,      0x6f},
-       {R367TER_TSGSTATUS,     0x18},
-       {R367TER_FECM,          0x01},
-       {R367TER_VTH12,         0xff},
-       {R367TER_VTH23,         0xa1},
-       {R367TER_VTH34,         0x64},
-       {R367TER_VTH56,         0x40},
-       {R367TER_VTH67,         0x00},
-       {R367TER_VTH78,         0x2c},
-       {R367TER_VITCURPUN,     0x12},
-       {R367TER_VERROR,        0x01},
-       {R367TER_PRVIT,         0x3f},
-       {R367TER_VAVSRVIT,      0x00},
-       {R367TER_VSTATUSVIT,    0xbd},
-       {R367TER_VTHINUSE,      0xa1},
-       {R367TER_KDIV12,        0x20},
-       {R367TER_KDIV23,        0x40},
-       {R367TER_KDIV34,        0x20},
-       {R367TER_KDIV56,        0x30},
-       {R367TER_KDIV67,        0x00},
-       {R367TER_KDIV78,        0x30},
-       {R367TER_SIGPOWER,      0x54},
-       {R367TER_DEMAPVIT,      0x40},
-       {R367TER_VITSCALE,      0x00},
-       {R367TER_FFEC1PRG,      0x00},
-       {R367TER_FVITCURPUN,    0x12},
-       {R367TER_FVERROR,       0x01},
-       {R367TER_FVSTATUSVIT,   0xbd},
-       {R367TER_DEBUG_LT1,     0x00},
-       {R367TER_DEBUG_LT2,     0x00},
-       {R367TER_DEBUG_LT3,     0x00},
-       {R367TER_TSTSFMET,      0x00},
-       {R367TER_SELOUT,        0x00},
-       {R367TER_TSYNC,         0x00},
-       {R367TER_TSTERR,        0x00},
-       {R367TER_TSFSYNC,       0x00},
-       {R367TER_TSTSFERR,      0x00},
-       {R367TER_TSTTSSF1,      0x01},
-       {R367TER_TSTTSSF2,      0x1f},
-       {R367TER_TSTTSSF3,      0x00},
-       {R367TER_TSTTS1,        0x00},
-       {R367TER_TSTTS2,        0x1f},
-       {R367TER_TSTTS3,        0x01},
-       {R367TER_TSTTS4,        0x00},
-       {R367TER_TSTTSRC,       0x00},
-       {R367TER_TSTTSRS,       0x00},
-       {R367TER_TSSTATEM,      0xb0},
-       {R367TER_TSSTATEL,      0x40},
-       {R367TER_TSCFGH,        0xC0},
-       {R367TER_TSCFGM,        0xc0},/* for xc5000; was 0x00 */
-       {R367TER_TSCFGL,        0x20},
-       {R367TER_TSSYNC,        0x00},
-       {R367TER_TSINSDELH,     0x00},
-       {R367TER_TSINSDELM,     0x00},
-       {R367TER_TSINSDELL,     0x00},
-       {R367TER_TSDIVN,        0x03},
-       {R367TER_TSDIVPM,       0x00},
-       {R367TER_TSDIVPL,       0x00},
-       {R367TER_TSDIVQM,       0x00},
-       {R367TER_TSDIVQL,       0x00},
-       {R367TER_TSDILSTKM,     0x00},
-       {R367TER_TSDILSTKL,     0x00},
-       {R367TER_TSSPEED,       0x40},/* for xc5000; was 0x6f */
-       {R367TER_TSSTATUS,      0x81},
-       {R367TER_TSSTATUS2,     0x6a},
-       {R367TER_TSBITRATEM,    0x0f},
-       {R367TER_TSBITRATEL,    0xc6},
-       {R367TER_TSPACKLENM,    0x00},
-       {R367TER_TSPACKLENL,    0xfc},
-       {R367TER_TSBLOCLENM,    0x0a},
-       {R367TER_TSBLOCLENL,    0x80},
-       {R367TER_TSDLYH,        0x90},
-       {R367TER_TSDLYM,        0x68},
-       {R367TER_TSDLYL,        0x01},
-       {R367TER_TSNPDAV,       0x00},
-       {R367TER_TSBUFSTATH,    0x00},
-       {R367TER_TSBUFSTATM,    0x00},
-       {R367TER_TSBUFSTATL,    0x00},
-       {R367TER_TSDEBUGM,      0xcf},
-       {R367TER_TSDEBUGL,      0x1e},
-       {R367TER_TSDLYSETH,     0x00},
-       {R367TER_TSDLYSETM,     0x68},
-       {R367TER_TSDLYSETL,     0x00},
-       {R367TER_TSOBSCFG,      0x00},
-       {R367TER_TSOBSM,        0x47},
-       {R367TER_TSOBSL,        0x1f},
-       {R367TER_ERRCTRL1,      0x95},
-       {R367TER_ERRCNT1H,      0x80},
-       {R367TER_ERRCNT1M,      0x00},
-       {R367TER_ERRCNT1L,      0x00},
-       {R367TER_ERRCTRL2,      0x95},
-       {R367TER_ERRCNT2H,      0x00},
-       {R367TER_ERRCNT2M,      0x00},
-       {R367TER_ERRCNT2L,      0x00},
-       {R367TER_FECSPY,        0x88},
-       {R367TER_FSPYCFG,       0x2c},
-       {R367TER_FSPYDATA,      0x3a},
-       {R367TER_FSPYOUT,       0x06},
-       {R367TER_FSTATUS,       0x61},
-       {R367TER_FGOODPACK,     0xff},
-       {R367TER_FPACKCNT,      0xff},
-       {R367TER_FSPYMISC,      0x66},
-       {R367TER_FBERCPT4,      0x00},
-       {R367TER_FBERCPT3,      0x00},
-       {R367TER_FBERCPT2,      0x36},
-       {R367TER_FBERCPT1,      0x36},
-       {R367TER_FBERCPT0,      0x14},
-       {R367TER_FBERERR2,      0x00},
-       {R367TER_FBERERR1,      0x03},
-       {R367TER_FBERERR0,      0x28},
-       {R367TER_FSTATESM,      0x00},
-       {R367TER_FSTATESL,      0x02},
-       {R367TER_FSPYBER,       0x00},
-       {R367TER_FSPYDISTM,     0x01},
-       {R367TER_FSPYDISTL,     0x9f},
-       {R367TER_FSPYOBS7,      0xc9},
-       {R367TER_FSPYOBS6,      0x99},
-       {R367TER_FSPYOBS5,      0x08},
-       {R367TER_FSPYOBS4,      0xec},
-       {R367TER_FSPYOBS3,      0x01},
-       {R367TER_FSPYOBS2,      0x0f},
-       {R367TER_FSPYOBS1,      0xf5},
-       {R367TER_FSPYOBS0,      0x08},
-       {R367TER_SFDEMAP,       0x40},
-       {R367TER_SFERROR,       0x00},
-       {R367TER_SFAVSR,        0x30},
-       {R367TER_SFECSTATUS,    0xcc},
-       {R367TER_SFKDIV12,      0x20},
-       {R367TER_SFKDIV23,      0x40},
-       {R367TER_SFKDIV34,      0x20},
-       {R367TER_SFKDIV56,      0x20},
-       {R367TER_SFKDIV67,      0x00},
-       {R367TER_SFKDIV78,      0x20},
-       {R367TER_SFDILSTKM,     0x00},
-       {R367TER_SFDILSTKL,     0x00},
-       {R367TER_SFSTATUS,      0xb5},
-       {R367TER_SFDLYH,        0x90},
-       {R367TER_SFDLYM,        0x60},
-       {R367TER_SFDLYL,        0x01},
-       {R367TER_SFDLYSETH,     0xc0},
-       {R367TER_SFDLYSETM,     0x60},
-       {R367TER_SFDLYSETL,     0x00},
-       {R367TER_SFOBSCFG,      0x00},
-       {R367TER_SFOBSM,        0x47},
-       {R367TER_SFOBSL,        0x05},
-       {R367TER_SFECINFO,      0x40},
-       {R367TER_SFERRCTRL,     0x74},
-       {R367TER_SFERRCNTH,     0x80},
-       {R367TER_SFERRCNTM ,    0x00},
-       {R367TER_SFERRCNTL,     0x00},
-       {R367TER_SYMBRATEM,     0x2f},
-       {R367TER_SYMBRATEL,     0x50},
-       {R367TER_SYMBSTATUS,    0x7f},
-       {R367TER_SYMBCFG,       0x00},
-       {R367TER_SYMBFIFOM,     0xf4},
-       {R367TER_SYMBFIFOL,     0x0d},
-       {R367TER_SYMBOFFSM,     0xf0},
-       {R367TER_SYMBOFFSL,     0x2d},
-       {R367TER_DEBUG_LT4,     0x00},
-       {R367TER_DEBUG_LT5,     0x00},
-       {R367TER_DEBUG_LT6,     0x00},
-       {R367TER_DEBUG_LT7,     0x00},
-       {R367TER_DEBUG_LT8,     0x00},
-       {R367TER_DEBUG_LT9,     0x00},
-};
-
-#define RF_LOOKUP_TABLE_SIZE  31
-#define RF_LOOKUP_TABLE2_SIZE 16
-/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
-       {/*AGC1*/
-               48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
-               64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
-               76, 77, 78, 80, 83, 85, 88,
-       }, {/*RF(dbm)*/
-               22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-               34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
-               49, 50, 52, 53, 54, 55, 56,
-       }
-};
-/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
-       {/*AGC2*/
-               28, 29, 31, 32, 34, 35, 36, 37,
-               38, 39, 40, 41, 42, 43, 44, 45,
-       }, {/*RF(dbm)*/
-               57, 58, 59, 60, 61, 62, 63, 64,
-               65, 66, 67, 68, 69, 70, 71, 72,
-       }
-};
-
-static struct st_register def0367cab[STV0367CAB_NBREGS] = {
-       {R367CAB_ID,            0x60},
-       {R367CAB_I2CRPT,        0xa0},
-       /*{R367CAB_I2CRPT,      0x22},*/
-       {R367CAB_TOPCTRL,       0x10},
-       {R367CAB_IOCFG0,        0x80},
-       {R367CAB_DAC0R,         0x00},
-       {R367CAB_IOCFG1,        0x00},
-       {R367CAB_DAC1R,         0x00},
-       {R367CAB_IOCFG2,        0x00},
-       {R367CAB_SDFR,          0x00},
-       {R367CAB_AUX_CLK,       0x00},
-       {R367CAB_FREESYS1,      0x00},
-       {R367CAB_FREESYS2,      0x00},
-       {R367CAB_FREESYS3,      0x00},
-       {R367CAB_GPIO_CFG,      0x55},
-       {R367CAB_GPIO_CMD,      0x01},
-       {R367CAB_TSTRES,        0x00},
-       {R367CAB_ANACTRL,       0x0d},/* was 0x00 need to check - I.M.L.*/
-       {R367CAB_TSTBUS,        0x00},
-       {R367CAB_RF_AGC1,       0xea},
-       {R367CAB_RF_AGC2,       0x82},
-       {R367CAB_ANADIGCTRL,    0x0b},
-       {R367CAB_PLLMDIV,       0x01},
-       {R367CAB_PLLNDIV,       0x08},
-       {R367CAB_PLLSETUP,      0x18},
-       {R367CAB_DUAL_AD12,     0x0C}, /* for xc5000 AGC voltage 1.6V */
-       {R367CAB_TSTBIST,       0x00},
-       {R367CAB_CTRL_1,        0x00},
-       {R367CAB_CTRL_2,        0x03},
-       {R367CAB_IT_STATUS1,    0x2b},
-       {R367CAB_IT_STATUS2,    0x08},
-       {R367CAB_IT_EN1,        0x00},
-       {R367CAB_IT_EN2,        0x00},
-       {R367CAB_CTRL_STATUS,   0x04},
-       {R367CAB_TEST_CTL,      0x00},
-       {R367CAB_AGC_CTL,       0x73},
-       {R367CAB_AGC_IF_CFG,    0x50},
-       {R367CAB_AGC_RF_CFG,    0x00},
-       {R367CAB_AGC_PWM_CFG,   0x03},
-       {R367CAB_AGC_PWR_REF_L, 0x5a},
-       {R367CAB_AGC_PWR_REF_H, 0x00},
-       {R367CAB_AGC_RF_TH_L,   0xff},
-       {R367CAB_AGC_RF_TH_H,   0x07},
-       {R367CAB_AGC_IF_LTH_L,  0x00},
-       {R367CAB_AGC_IF_LTH_H,  0x08},
-       {R367CAB_AGC_IF_HTH_L,  0xff},
-       {R367CAB_AGC_IF_HTH_H,  0x07},
-       {R367CAB_AGC_PWR_RD_L,  0xa0},
-       {R367CAB_AGC_PWR_RD_M,  0xe9},
-       {R367CAB_AGC_PWR_RD_H,  0x03},
-       {R367CAB_AGC_PWM_IFCMD_L,       0xe4},
-       {R367CAB_AGC_PWM_IFCMD_H,       0x00},
-       {R367CAB_AGC_PWM_RFCMD_L,       0xff},
-       {R367CAB_AGC_PWM_RFCMD_H,       0x07},
-       {R367CAB_IQDEM_CFG,     0x01},
-       {R367CAB_MIX_NCO_LL,    0x22},
-       {R367CAB_MIX_NCO_HL,    0x96},
-       {R367CAB_MIX_NCO_HH,    0x55},
-       {R367CAB_SRC_NCO_LL,    0xff},
-       {R367CAB_SRC_NCO_LH,    0x0c},
-       {R367CAB_SRC_NCO_HL,    0xf5},
-       {R367CAB_SRC_NCO_HH,    0x20},
-       {R367CAB_IQDEM_GAIN_SRC_L,      0x06},
-       {R367CAB_IQDEM_GAIN_SRC_H,      0x01},
-       {R367CAB_IQDEM_DCRM_CFG_LL,     0xfe},
-       {R367CAB_IQDEM_DCRM_CFG_LH,     0xff},
-       {R367CAB_IQDEM_DCRM_CFG_HL,     0x0f},
-       {R367CAB_IQDEM_DCRM_CFG_HH,     0x00},
-       {R367CAB_IQDEM_ADJ_COEFF0,      0x34},
-       {R367CAB_IQDEM_ADJ_COEFF1,      0xae},
-       {R367CAB_IQDEM_ADJ_COEFF2,      0x46},
-       {R367CAB_IQDEM_ADJ_COEFF3,      0x77},
-       {R367CAB_IQDEM_ADJ_COEFF4,      0x96},
-       {R367CAB_IQDEM_ADJ_COEFF5,      0x69},
-       {R367CAB_IQDEM_ADJ_COEFF6,      0xc7},
-       {R367CAB_IQDEM_ADJ_COEFF7,      0x01},
-       {R367CAB_IQDEM_ADJ_EN,  0x04},
-       {R367CAB_IQDEM_ADJ_AGC_REF,     0x94},
-       {R367CAB_ALLPASSFILT1,  0xc9},
-       {R367CAB_ALLPASSFILT2,  0x2d},
-       {R367CAB_ALLPASSFILT3,  0xa3},
-       {R367CAB_ALLPASSFILT4,  0xfb},
-       {R367CAB_ALLPASSFILT5,  0xf6},
-       {R367CAB_ALLPASSFILT6,  0x45},
-       {R367CAB_ALLPASSFILT7,  0x6f},
-       {R367CAB_ALLPASSFILT8,  0x7e},
-       {R367CAB_ALLPASSFILT9,  0x05},
-       {R367CAB_ALLPASSFILT10, 0x0a},
-       {R367CAB_ALLPASSFILT11, 0x51},
-       {R367CAB_TRL_AGC_CFG,   0x20},
-       {R367CAB_TRL_LPF_CFG,   0x28},
-       {R367CAB_TRL_LPF_ACQ_GAIN,      0x44},
-       {R367CAB_TRL_LPF_TRK_GAIN,      0x22},
-       {R367CAB_TRL_LPF_OUT_GAIN,      0x03},
-       {R367CAB_TRL_LOCKDET_LTH,       0x04},
-       {R367CAB_TRL_LOCKDET_HTH,       0x11},
-       {R367CAB_TRL_LOCKDET_TRGVAL,    0x20},
-       {R367CAB_IQ_QAM,        0x01},
-       {R367CAB_FSM_STATE,     0xa0},
-       {R367CAB_FSM_CTL,       0x08},
-       {R367CAB_FSM_STS,       0x0c},
-       {R367CAB_FSM_SNR0_HTH,  0x00},
-       {R367CAB_FSM_SNR1_HTH,  0x00},
-       {R367CAB_FSM_SNR2_HTH,  0x23},/* 0x00 */
-       {R367CAB_FSM_SNR0_LTH,  0x00},
-       {R367CAB_FSM_SNR1_LTH,  0x00},
-       {R367CAB_FSM_EQA1_HTH,  0x00},
-       {R367CAB_FSM_TEMPO,     0x32},
-       {R367CAB_FSM_CONFIG,    0x03},
-       {R367CAB_EQU_I_TESTTAP_L,       0x11},
-       {R367CAB_EQU_I_TESTTAP_M,       0x00},
-       {R367CAB_EQU_I_TESTTAP_H,       0x00},
-       {R367CAB_EQU_TESTAP_CFG,        0x00},
-       {R367CAB_EQU_Q_TESTTAP_L,       0xff},
-       {R367CAB_EQU_Q_TESTTAP_M,       0x00},
-       {R367CAB_EQU_Q_TESTTAP_H,       0x00},
-       {R367CAB_EQU_TAP_CTRL,  0x00},
-       {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
-       {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
-       {R367CAB_EQU_CTR_HIPOW_L,       0x00},
-       {R367CAB_EQU_CTR_HIPOW_H,       0x00},
-       {R367CAB_EQU_I_EQU_LO,  0xef},
-       {R367CAB_EQU_I_EQU_HI,  0x00},
-       {R367CAB_EQU_Q_EQU_LO,  0xee},
-       {R367CAB_EQU_Q_EQU_HI,  0x00},
-       {R367CAB_EQU_MAPPER,    0xc5},
-       {R367CAB_EQU_SWEEP_RATE,        0x80},
-       {R367CAB_EQU_SNR_LO,    0x64},
-       {R367CAB_EQU_SNR_HI,    0x03},
-       {R367CAB_EQU_GAMMA_LO,  0x00},
-       {R367CAB_EQU_GAMMA_HI,  0x00},
-       {R367CAB_EQU_ERR_GAIN,  0x36},
-       {R367CAB_EQU_RADIUS,    0xaa},
-       {R367CAB_EQU_FFE_MAINTAP,       0x00},
-       {R367CAB_EQU_FFE_LEAKAGE,       0x63},
-       {R367CAB_EQU_FFE_MAINTAP_POS,   0xdf},
-       {R367CAB_EQU_GAIN_WIDE, 0x88},
-       {R367CAB_EQU_GAIN_NARROW,       0x41},
-       {R367CAB_EQU_CTR_LPF_GAIN,      0xd1},
-       {R367CAB_EQU_CRL_LPF_GAIN,      0xa7},
-       {R367CAB_EQU_GLOBAL_GAIN,       0x06},
-       {R367CAB_EQU_CRL_LD_SEN,        0x85},
-       {R367CAB_EQU_CRL_LD_VAL,        0xe2},
-       {R367CAB_EQU_CRL_TFR,   0x20},
-       {R367CAB_EQU_CRL_BISTH_LO,      0x00},
-       {R367CAB_EQU_CRL_BISTH_HI,      0x00},
-       {R367CAB_EQU_SWEEP_RANGE_LO,    0x00},
-       {R367CAB_EQU_SWEEP_RANGE_HI,    0x00},
-       {R367CAB_EQU_CRL_LIMITER,       0x40},
-       {R367CAB_EQU_MODULUS_MAP,       0x90},
-       {R367CAB_EQU_PNT_GAIN,  0xa7},
-       {R367CAB_FEC_AC_CTR_0,  0x16},
-       {R367CAB_FEC_AC_CTR_1,  0x0b},
-       {R367CAB_FEC_AC_CTR_2,  0x88},
-       {R367CAB_FEC_AC_CTR_3,  0x02},
-       {R367CAB_FEC_STATUS,    0x12},
-       {R367CAB_RS_COUNTER_0,  0x7d},
-       {R367CAB_RS_COUNTER_1,  0xd0},
-       {R367CAB_RS_COUNTER_2,  0x19},
-       {R367CAB_RS_COUNTER_3,  0x0b},
-       {R367CAB_RS_COUNTER_4,  0xa3},
-       {R367CAB_RS_COUNTER_5,  0x00},
-       {R367CAB_BERT_0,        0x01},
-       {R367CAB_BERT_1,        0x25},
-       {R367CAB_BERT_2,        0x41},
-       {R367CAB_BERT_3,        0x39},
-       {R367CAB_OUTFORMAT_0,   0xc2},
-       {R367CAB_OUTFORMAT_1,   0x22},
-       {R367CAB_SMOOTHER_2,    0x28},
-       {R367CAB_TSMF_CTRL_0,   0x01},
-       {R367CAB_TSMF_CTRL_1,   0xc6},
-       {R367CAB_TSMF_CTRL_3,   0x43},
-       {R367CAB_TS_ON_ID_0,    0x00},
-       {R367CAB_TS_ON_ID_1,    0x00},
-       {R367CAB_TS_ON_ID_2,    0x00},
-       {R367CAB_TS_ON_ID_3,    0x00},
-       {R367CAB_RE_STATUS_0,   0x00},
-       {R367CAB_RE_STATUS_1,   0x00},
-       {R367CAB_RE_STATUS_2,   0x00},
-       {R367CAB_RE_STATUS_3,   0x00},
-       {R367CAB_TS_STATUS_0,   0x00},
-       {R367CAB_TS_STATUS_1,   0x00},
-       {R367CAB_TS_STATUS_2,   0xa0},
-       {R367CAB_TS_STATUS_3,   0x00},
-       {R367CAB_T_O_ID_0,      0x00},
-       {R367CAB_T_O_ID_1,      0x00},
-       {R367CAB_T_O_ID_2,      0x00},
-       {R367CAB_T_O_ID_3,      0x00},
-};
-
-static
-int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
-{
-       u8 buf[len + 2];
-       struct i2c_msg msg = {
-               .addr = state->config->demod_address,
-               .flags = 0,
-               .buf = buf,
-               .len = len + 2
-       };
-       int ret;
-
-       buf[0] = MSB(reg);
-       buf[1] = LSB(reg);
-       memcpy(buf + 2, data, len);
-
-       if (i2cdebug)
-               printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-       if (ret != 1)
-               printk(KERN_ERR "%s: i2c write error!\n", __func__);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
-{
-       return stv0367_writeregs(state, reg, &data, 1);
-}
-
-static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
-{
-       u8 b0[] = { 0, 0 };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {
-                       .addr = state->config->demod_address,
-                       .flags = 0,
-                       .buf = b0,
-                       .len = 2
-               }, {
-                       .addr = state->config->demod_address,
-                       .flags = I2C_M_RD,
-                       .buf = b1,
-                       .len = 1
-               }
-       };
-       int ret;
-
-       b0[0] = MSB(reg);
-       b0[1] = LSB(reg);
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2)
-               printk(KERN_ERR "%s: i2c read error\n", __func__);
-
-       if (i2cdebug)
-               printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
-
-       return b1[0];
-}
-
-static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
-{
-       u8 position = 0, i = 0;
-
-       (*mask) = label & 0xff;
-
-       while ((position == 0) && (i < 8)) {
-               position = ((*mask) >> i) & 0x01;
-               i++;
-       }
-
-       (*pos) = (i - 1);
-}
-
-static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
-{
-       u8 reg, mask, pos;
-
-       reg = stv0367_readreg(state, (label >> 16) & 0xffff);
-       extract_mask_pos(label, &mask, &pos);
-
-       val = mask & (val << pos);
-
-       reg = (reg & (~mask)) | val;
-       stv0367_writereg(state, (label >> 16) & 0xffff, reg);
-
-}
-
-static void stv0367_setbits(u8 *reg, u32 label, u8 val)
-{
-       u8 mask, pos;
-
-       extract_mask_pos(label, &mask, &pos);
-
-       val = mask & (val << pos);
-
-       (*reg) = ((*reg) & (~mask)) | val;
-}
-
-static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
-{
-       u8 val = 0xff;
-       u8 mask, pos;
-
-       extract_mask_pos(label, &mask, &pos);
-
-       val = stv0367_readreg(state, label >> 16);
-       val = (val & mask) >> pos;
-
-       return val;
-}
-
-u8 stv0367_getbits(u8 reg, u32 label)
-{
-       u8 mask, pos;
-
-       extract_mask_pos(label, &mask, &pos);
-
-       return (reg & mask) >> pos;
-}
-
-static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
-
-       dprintk("%s:\n", __func__);
-
-       if (enable) {
-               stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
-               stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
-       } else {
-               stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
-               stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
-       }
-
-       stv0367_writereg(state, R367TER_I2CRPT, tmp);
-
-       return 0;
-}
-
-static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       u32 freq = 0;
-       int err = 0;
-
-       dprintk("%s:\n", __func__);
-
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_frequency) {
-               err = tuner_ops->get_frequency(fe, &freq);
-               if (err < 0) {
-                       printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-
-               dprintk("%s: frequency=%d\n", __func__, freq);
-
-       } else
-               return -1;
-
-       return freq;
-}
-
-static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
-       {
-               {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
-               {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
-               {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
-               {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
-               {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
-               {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
-       }, {
-               {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
-               {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
-               {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
-               {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
-               {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
-               {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
-       }, {
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
-       }
-};
-
-static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
-       {
-               {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
-               {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
-               {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
-               {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
-               {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
-               {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
-       }, {
-               {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
-               {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
-               {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
-               {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
-               {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
-               {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
-       }, {
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
-       }
-};
-
-static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
-       {
-               {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
-               {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
-               {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
-               {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
-               {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
-               {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
-       }, {
-               {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
-               {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
-               {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
-               {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
-               {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
-               {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
-
-       }, {
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
-               {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
-       }
-};
-
-static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
-{
-       u32 mclk_Hz = 0; /* master clock frequency (Hz) */
-       u32 m, n, p;
-
-       dprintk("%s:\n", __func__);
-
-       if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
-               n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
-               if (n == 0)
-                       n = n + 1;
-
-               m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
-               if (m == 0)
-                       m = m + 1;
-
-               p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
-               if (p > 5)
-                       p = 5;
-
-               mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
-
-               dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
-                               n, m, p, mclk_Hz, ExtClk_Hz);
-       } else
-               mclk_Hz = ExtClk_Hz;
-
-       dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
-
-       return mclk_Hz;
-}
-
-static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
-                               u16 CellsCoeffs[3][6][5], u32 DemodXtal)
-{
-       int i, j, k, freq;
-
-       dprintk("%s:\n", __func__);
-
-       freq = stv0367ter_get_mclk(state, DemodXtal);
-
-       if (freq == 53125000)
-               k = 1; /* equivalent to Xtal 25M on 362*/
-       else if (freq == 54000000)
-               k = 0; /* equivalent to Xtal 27M on 362*/
-       else if (freq == 52500000)
-               k = 2; /* equivalent to Xtal 30M on 362*/
-       else
-               return 0;
-
-       for (i = 1; i <= 6; i++) {
-               stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
-
-               for (j = 1; j <= 5; j++) {
-                       stv0367_writereg(state,
-                               (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
-                               MSB(CellsCoeffs[k][i-1][j-1]));
-                       stv0367_writereg(state,
-                               (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
-                               LSB(CellsCoeffs[k][i-1][j-1]));
-               }
-       }
-
-       return 1;
-
-}
-
-static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
-{
-       dprintk("%s:\n", __func__);
-
-       stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
-
-       /* Lock detect 1 */
-       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
-       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
-       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
-
-       /* Lock detect 2 */
-       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
-       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
-       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
-
-       /* Lock detect 3 */
-       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
-       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
-       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
-
-       /* Lock detect 4 */
-       stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
-       stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
-       stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
-
-}
-
-static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
-                                                       u32 DemodXtalValue)
-{
-       dprintk("%s:\n", __func__);
-
-       stv0367_writebits(state, F367TER_NRST_IIR, 0);
-
-       switch (Bandwidth) {
-       case 6:
-               if (!stv0367ter_filt_coeff_init(state,
-                               CellsCoeffs_6MHz_367cofdm,
-                               DemodXtalValue))
-                       return 0;
-               break;
-       case 7:
-               if (!stv0367ter_filt_coeff_init(state,
-                               CellsCoeffs_7MHz_367cofdm,
-                               DemodXtalValue))
-                       return 0;
-               break;
-       case 8:
-               if (!stv0367ter_filt_coeff_init(state,
-                               CellsCoeffs_8MHz_367cofdm,
-                               DemodXtalValue))
-                       return 0;
-               break;
-       default:
-               return 0;
-       }
-
-       stv0367_writebits(state, F367TER_NRST_IIR, 1);
-
-       return 1;
-}
-
-static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
-{
-
-       u8 com_n;
-
-       dprintk("%s:\n", __func__);
-
-       com_n = stv0367_readbits(state, F367TER_COM_N);
-
-       stv0367_writebits(state, F367TER_COM_N, 0x07);
-
-       stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
-       stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
-
-       stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
-       stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
-
-       stv0367_writebits(state, F367TER_COM_N, com_n);
-
-}
-
-static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
-{
-       int local_tempo = 0;
-       switch (mode) {
-       case 0:
-               local_tempo = tempo1;
-               break;
-       case 1:
-               local_tempo = tempo2;
-               break ;
-
-       case 2:
-               local_tempo = tempo3;
-               break;
-
-       default:
-               break;
-       }
-       /*      msleep(local_tempo);  */
-       return local_tempo;
-}
-
-static enum
-stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
-{
-       int wd = 100;
-       unsigned short int SYR_var;
-       s32 SYRStatus;
-
-       dprintk("%s:\n", __func__);
-
-       SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
-
-       while ((!SYR_var) && (wd > 0)) {
-               usleep_range(2000, 3000);
-               wd -= 2;
-               SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
-       }
-
-       if (!SYR_var)
-               SYRStatus = FE_TER_NOSYMBOL;
-       else
-               SYRStatus =  FE_TER_SYMBOLOK;
-
-       dprintk("stv0367ter_check_syr SYRStatus %s\n",
-                               SYR_var == 0 ? "No Symbol" : "OK");
-
-       return SYRStatus;
-}
-
-static enum
-stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
-                                                               s32 FFTmode)
-{
-
-       s32  CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
-       int wd = 0;
-
-       dprintk("%s:\n", __func__);
-
-       switch (FFTmode) {
-       case 0: /*2k mode*/
-               CPAMPMin = 20;
-               wd = 10;
-               break;
-       case 1: /*8k mode*/
-               CPAMPMin = 80;
-               wd = 55;
-               break;
-       case 2: /*4k mode*/
-               CPAMPMin = 40;
-               wd = 30;
-               break;
-       default:
-               CPAMPMin = 0xffff;  /*drives to NOCPAMP */
-               break;
-       }
-
-       dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
-
-       CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
-       while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
-               usleep_range(1000, 2000);
-               wd -= 1;
-               CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
-               /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
-       }
-       dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
-       if (CPAMPvalue < CPAMPMin) {
-               CPAMPStatus = FE_TER_NOCPAMP;
-               printk(KERN_ERR "CPAMP failed\n");
-       } else {
-               printk(KERN_ERR "CPAMP OK !\n");
-               CPAMPStatus = FE_TER_CPAMPOK;
-       }
-
-       return CPAMPStatus;
-}
-
-enum
-stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
-{
-       enum stv0367_ter_signal_type ret_flag;
-       short int wd, tempo;
-       u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
-       u8 tmp, tmp2;
-
-       dprintk("%s:\n", __func__);
-
-       if (state == NULL)
-               return FE_TER_SWNOK;
-
-       try = 0;
-       do {
-               ret_flag = FE_TER_LOCKOK;
-
-               stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
-
-               if (state->config->if_iq_mode != 0)
-                       stv0367_writebits(state, F367TER_COM_N, 0x07);
-
-               stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
-               stv0367_writebits(state, F367TER_MODE, 0);
-               stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
-               usleep_range(5000, 10000);
-
-               stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
-
-
-               if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
-                       return FE_TER_NOSYMBOL;
-               else { /*
-                       if chip locked on wrong mode first try,
-                       it must lock correctly second try */
-                       mode = stv0367_readbits(state, F367TER_SYR_MODE);
-                       if (stv0367ter_check_cpamp(state, mode) ==
-                                                       FE_TER_NOCPAMP) {
-                               if (try == 0)
-                                       ret_flag = FE_TER_NOCPAMP;
-
-                       }
-               }
-
-               try++;
-       } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
-
-       tmp  = stv0367_readreg(state, R367TER_SYR_STAT);
-       tmp2 = stv0367_readreg(state, R367TER_STATUS);
-       dprintk("state=%p\n", state);
-       dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
-                                                       mode, tmp, tmp2);
-
-       tmp  = stv0367_readreg(state, R367TER_PRVIT);
-       tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
-       dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
-
-       tmp  = stv0367_readreg(state, R367TER_GAIN_SRC1);
-       dprintk("GAIN_SRC1=0x%x\n", tmp);
-
-       if ((mode != 0) && (mode != 1) && (mode != 2))
-               return FE_TER_SWNOK;
-
-       /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
-
-       /*suppress EPQ auto for SYR_GARD 1/16 or 1/32
-       and set channel predictor in automatic */
-#if 0
-       switch (guard) {
-
-       case 0:
-       case 1:
-               stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
-               stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
-               break;
-       case 2:
-       case 3:
-               stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
-               stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
-               break;
-
-       default:
-               return FE_TER_SWNOK;
-       }
-#endif
-
-       /*reset fec an reedsolo FOR 367 only*/
-       stv0367_writebits(state, F367TER_RST_SFEC, 1);
-       stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
-       usleep_range(1000, 2000);
-       stv0367_writebits(state, F367TER_RST_SFEC, 0);
-       stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
-
-       u_var1 = stv0367_readbits(state, F367TER_LK);
-       u_var2 = stv0367_readbits(state, F367TER_PRF);
-       u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
-       /*      u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
-
-       wd = stv0367ter_duration(mode, 125, 500, 250);
-       tempo = stv0367ter_duration(mode, 4, 16, 8);
-
-       /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4))  && (wd>=0)) */
-       while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
-               usleep_range(1000 * tempo, 1000 * (tempo + 1));
-               wd -= tempo;
-               u_var1 = stv0367_readbits(state, F367TER_LK);
-               u_var2 = stv0367_readbits(state, F367TER_PRF);
-               u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
-               /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
-       }
-
-       if (!u_var1)
-               return FE_TER_NOLOCK;
-
-
-       if (!u_var2)
-               return FE_TER_NOPRFOUND;
-
-       if (!u_var3)
-               return FE_TER_NOTPS;
-
-       guard = stv0367_readbits(state, F367TER_SYR_GUARD);
-       stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
-       switch (guard) {
-       case 0:
-       case 1:
-               stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
-               /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
-               stv0367_writebits(state, F367TER_SYR_FILTER, 0);
-               break;
-       case 2:
-       case 3:
-               stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
-               /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
-               stv0367_writebits(state, F367TER_SYR_FILTER, 1);
-               break;
-
-       default:
-               return FE_TER_SWNOK;
-       }
-
-       /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
-       if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
-                       (mode == 1) &&
-                       (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
-               stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
-               stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
-               stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
-       } else
-               stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
-
-       wd = stv0367ter_duration(mode, 125, 500, 250);
-       u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
-
-       while ((!u_var4) && (wd >= 0)) {
-               usleep_range(1000 * tempo, 1000 * (tempo + 1));
-               wd -= tempo;
-               u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
-       }
-
-       if (!u_var4)
-               return FE_TER_NOLOCK;
-
-       /* for 367 leave COM_N at 0x7 for IQ_mode*/
-       /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
-               tempo=0;
-               while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
-               (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
-                       ChipWaitOrAbort(state,1);
-                       tempo+=1;
-               }
-
-               stv0367_writebits(state,F367TER_COM_N,0x17);
-       } */
-
-       stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
-
-       dprintk("FE_TER_LOCKOK !!!\n");
-
-       return  FE_TER_LOCKOK;
-
-}
-
-static void stv0367ter_set_ts_mode(struct stv0367_state *state,
-                                       enum stv0367_ts_mode PathTS)
-{
-
-       dprintk("%s:\n", __func__);
-
-       if (state == NULL)
-               return;
-
-       stv0367_writebits(state, F367TER_TS_DIS, 0);
-       switch (PathTS) {
-       default:
-               /*for removing warning :default we can assume in parallel mode*/
-       case STV0367_PARALLEL_PUNCT_CLOCK:
-               stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
-               stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
-               break;
-       case STV0367_SERIAL_PUNCT_CLOCK:
-               stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
-               stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
-               break;
-       }
-}
-
-static void stv0367ter_set_clk_pol(struct stv0367_state *state,
-                                       enum stv0367_clk_pol clock)
-{
-
-       dprintk("%s:\n", __func__);
-
-       if (state == NULL)
-               return;
-
-       switch (clock) {
-       case STV0367_RISINGEDGE_CLOCK:
-               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
-               break;
-       case STV0367_FALLINGEDGE_CLOCK:
-               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
-               break;
-               /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
-       default:
-               stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
-               break;
-       }
-}
-
-#if 0
-static void stv0367ter_core_sw(struct stv0367_state *state)
-{
-
-       dprintk("%s:\n", __func__);
-
-       stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
-       stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
-       msleep(350);
-}
-#endif
-static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       dprintk("%s:\n", __func__);
-
-       if (standby_on) {
-               stv0367_writebits(state, F367TER_STDBY, 1);
-               stv0367_writebits(state, F367TER_STDBY_FEC, 1);
-               stv0367_writebits(state, F367TER_STDBY_CORE, 1);
-       } else {
-               stv0367_writebits(state, F367TER_STDBY, 0);
-               stv0367_writebits(state, F367TER_STDBY_FEC, 0);
-               stv0367_writebits(state, F367TER_STDBY_CORE, 0);
-       }
-
-       return 0;
-}
-
-static int stv0367ter_sleep(struct dvb_frontend *fe)
-{
-       return stv0367ter_standby(fe, 1);
-}
-
-int stv0367ter_init(struct dvb_frontend *fe)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-       int i;
-
-       dprintk("%s:\n", __func__);
-
-       ter_state->pBER = 0;
-
-       for (i = 0; i < STV0367TER_NBREGS; i++)
-               stv0367_writereg(state, def0367ter[i].addr,
-                                       def0367ter[i].value);
-
-       switch (state->config->xtal) {
-               /*set internal freq to 53.125MHz */
-       case 25000000:
-               stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
-               stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
-               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
-               break;
-       default:
-       case 27000000:
-               dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
-               stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
-               stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
-               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
-               break;
-       case 30000000:
-               stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
-               stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
-               stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
-               break;
-       }
-
-       stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
-       stv0367_writereg(state, R367TER_ANACTRL, 0x00);
-
-       /*Set TS1 and TS2 to serial or parallel mode */
-       stv0367ter_set_ts_mode(state, state->config->ts_mode);
-       stv0367ter_set_clk_pol(state, state->config->clk_pol);
-
-       state->chip_id = stv0367_readreg(state, R367TER_ID);
-       ter_state->first_lock = 0;
-       ter_state->unlock_counter = 2;
-
-       return 0;
-}
-
-static int stv0367ter_algo(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-       int offset = 0, tempo = 0;
-       u8 u_var;
-       u8 /*constell,*/ counter;
-       s8 step;
-       s32 timing_offset = 0;
-       u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
-
-       dprintk("%s:\n", __func__);
-
-       ter_state->frequency = p->frequency;
-       ter_state->force = FE_TER_FORCENONE
-                       + stv0367_readbits(state, F367TER_FORCE) * 2;
-       ter_state->if_iq_mode = state->config->if_iq_mode;
-       switch (state->config->if_iq_mode) {
-       case FE_TER_NORMAL_IF_TUNER:  /* Normal IF mode */
-               dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
-               stv0367_writebits(state, F367TER_TUNER_BB, 0);
-               stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
-               stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
-               break;
-       case FE_TER_LONGPATH_IF_TUNER:  /* Long IF mode */
-               dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
-               stv0367_writebits(state, F367TER_TUNER_BB, 0);
-               stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
-               stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
-               break;
-       case FE_TER_IQ_TUNER:  /* IQ mode */
-               dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
-               stv0367_writebits(state, F367TER_TUNER_BB, 1);
-               stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
-               break;
-       default:
-               printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
-               return -EINVAL;
-       }
-
-       usleep_range(5000, 7000);
-
-       switch (p->inversion) {
-       case INVERSION_AUTO:
-       default:
-               dprintk("%s: inversion AUTO\n", __func__);
-               if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
-                       stv0367_writebits(state, F367TER_IQ_INVERT,
-                                               ter_state->sense);
-               else
-                       stv0367_writebits(state, F367TER_INV_SPECTR,
-                                               ter_state->sense);
-
-               break;
-       case INVERSION_ON:
-       case INVERSION_OFF:
-               if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
-                       stv0367_writebits(state, F367TER_IQ_INVERT,
-                                               p->inversion);
-               else
-                       stv0367_writebits(state, F367TER_INV_SPECTR,
-                                               p->inversion);
-
-               break;
-       }
-
-       if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
-                               (ter_state->pBW != ter_state->bw)) {
-               stv0367ter_agc_iir_lock_detect_set(state);
-
-               /*set fine agc target to 180 for LPIF or IQ mode*/
-               /* set Q_AGCTarget */
-               stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
-               stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
-               /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
-
-               /* set Q_AGCTarget */
-               stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
-               stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
-               /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
-
-               if (!stv0367_iir_filt_init(state, ter_state->bw,
-                                               state->config->xtal))
-                       return -EINVAL;
-               /*set IIR filter once for 6,7 or 8MHz BW*/
-               ter_state->pBW = ter_state->bw;
-
-               stv0367ter_agc_iir_rst(state);
-       }
-
-       if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
-               stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
-       else
-               stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
-
-       InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
-       temp = (int)
-               ((((ter_state->bw * 64 * (1 << 15) * 100)
-                                               / (InternalFreq)) * 10) / 7);
-
-       stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
-       temp = temp / 2;
-       stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
-       stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
-
-       temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
-                       stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
-                       stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
-       temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
-       stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
-       stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
-       temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
-                       stv0367_readbits(state, F367TER_GAIN_SRC_LO);
-
-       temp = (int)
-               ((InternalFreq - state->config->if_khz) * (1 << 16)
-                                                       / (InternalFreq));
-
-       dprintk("DEROT temp=0x%x\n", temp);
-       stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
-       stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
-
-       ter_state->echo_pos = 0;
-       ter_state->ucblocks = 0; /* liplianin */
-       ter_state->pBER = 0; /* liplianin */
-       stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
-
-       if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
-               return 0;
-
-       ter_state->state = FE_TER_LOCKOK;
-
-       ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
-       ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
-
-       ter_state->first_lock = 1; /* we know sense now :) */
-
-       ter_state->agc_val =
-                       (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
-                       (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
-                       stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
-                       (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
-
-       /* Carrier offset calculation */
-       stv0367_writebits(state, F367TER_FREEZE, 1);
-       offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
-       offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
-       offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
-       stv0367_writebits(state, F367TER_FREEZE, 0);
-       if (offset > 8388607)
-               offset -= 16777216;
-
-       offset = offset * 2 / 16384;
-
-       if (ter_state->mode == FE_TER_MODE_2K)
-               offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
-       else if (ter_state->mode == FE_TER_MODE_4K)
-               offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
-       else  if (ter_state->mode == FE_TER_MODE_8K)
-               offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
-
-       if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
-               if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
-                               (stv0367_readbits(state,
-                                       F367TER_STATUS_INV_SPECRUM) == 1)))
-                       offset = offset * -1;
-       }
-
-       if (ter_state->bw == 6)
-               offset = (offset * 6) / 8;
-       else if (ter_state->bw == 7)
-               offset = (offset * 7) / 8;
-
-       ter_state->frequency += offset;
-
-       tempo = 10;  /* exit even if timing_offset stays null */
-       while ((timing_offset == 0) && (tempo > 0)) {
-               usleep_range(10000, 20000);     /*was 20ms  */
-               /* fine tuning of timing offset if required */
-               timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
-                               + 256 * stv0367_readbits(state,
-                                                       F367TER_TRL_TOFFSET_HI);
-               if (timing_offset >= 32768)
-                       timing_offset -= 65536;
-               trl_nomrate = (512 * stv0367_readbits(state,
-                                                       F367TER_TRL_NOMRATE_HI)
-                       + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
-                       + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
-
-               timing_offset = ((signed)(1000000 / trl_nomrate) *
-                                                       timing_offset) / 2048;
-               tempo--;
-       }
-
-       if (timing_offset <= 0) {
-               timing_offset = (timing_offset - 11) / 22;
-               step = -1;
-       } else {
-               timing_offset = (timing_offset + 11) / 22;
-               step = 1;
-       }
-
-       for (counter = 0; counter < abs(timing_offset); counter++) {
-               trl_nomrate += step;
-               stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
-                                               trl_nomrate % 2);
-               stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
-                                               trl_nomrate / 2);
-               usleep_range(1000, 2000);
-       }
-
-       usleep_range(5000, 6000);
-       /* unlocks could happen in case of trl centring big step,
-       then a core off/on restarts demod */
-       u_var = stv0367_readbits(state, F367TER_LK);
-
-       if (!u_var) {
-               stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
-               msleep(20);
-               stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
-       }
-
-       return 0;
-}
-
-static int stv0367ter_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-
-       /*u8 trials[2]; */
-       s8 num_trials, index;
-       u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
-
-       stv0367ter_init(fe);
-
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       switch (p->transmission_mode) {
-       default:
-       case TRANSMISSION_MODE_AUTO:
-       case TRANSMISSION_MODE_2K:
-               ter_state->mode = FE_TER_MODE_2K;
-               break;
-/*     case TRANSMISSION_MODE_4K:
-               pLook.mode = FE_TER_MODE_4K;
-               break;*/
-       case TRANSMISSION_MODE_8K:
-               ter_state->mode = FE_TER_MODE_8K;
-               break;
-       }
-
-       switch (p->guard_interval) {
-       default:
-       case GUARD_INTERVAL_1_32:
-       case GUARD_INTERVAL_1_16:
-       case GUARD_INTERVAL_1_8:
-       case GUARD_INTERVAL_1_4:
-               ter_state->guard = p->guard_interval;
-               break;
-       case GUARD_INTERVAL_AUTO:
-               ter_state->guard = GUARD_INTERVAL_1_32;
-               break;
-       }
-
-       switch (p->bandwidth_hz) {
-       case 6000000:
-               ter_state->bw = FE_TER_CHAN_BW_6M;
-               break;
-       case 7000000:
-               ter_state->bw = FE_TER_CHAN_BW_7M;
-               break;
-       case 8000000:
-       default:
-               ter_state->bw = FE_TER_CHAN_BW_8M;
-       }
-
-       ter_state->hierarchy = FE_TER_HIER_NONE;
-
-       switch (p->inversion) {
-       case INVERSION_OFF:
-       case INVERSION_ON:
-               num_trials = 1;
-               break;
-       default:
-               num_trials = 2;
-               if (ter_state->first_lock)
-                       num_trials = 1;
-               break;
-       }
-
-       ter_state->state = FE_TER_NOLOCK;
-       index = 0;
-
-       while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
-               if (!ter_state->first_lock) {
-                       if (p->inversion == INVERSION_AUTO)
-                               ter_state->sense = SenseTrials[index];
-
-               }
-               stv0367ter_algo(fe);
-
-               if ((ter_state->state == FE_TER_LOCKOK) &&
-                               (p->inversion == INVERSION_AUTO) &&
-                                                               (index == 1)) {
-                       /* invert spectrum sense */
-                       SenseTrials[index] = SenseTrials[0];
-                       SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
-               }
-
-               index++;
-       }
-
-       return 0;
-}
-
-static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-       u32 errs = 0;
-
-       /*wait for counting completion*/
-       if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
-               errs =
-                       ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
-                       * (1 << 16))
-                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
-                       * (1 << 8))
-                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
-               ter_state->ucblocks = errs;
-       }
-
-       (*ucblocks) = ter_state->ucblocks;
-
-       return 0;
-}
-
-static int stv0367ter_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-
-       int error = 0;
-       enum stv0367_ter_mode mode;
-       int constell = 0,/* snr = 0,*/ Data = 0;
-
-       p->frequency = stv0367_get_tuner_freq(fe);
-       if ((int)p->frequency < 0)
-               p->frequency = -p->frequency;
-
-       constell = stv0367_readbits(state, F367TER_TPS_CONST);
-       if (constell == 0)
-               p->modulation = QPSK;
-       else if (constell == 1)
-               p->modulation = QAM_16;
-       else
-               p->modulation = QAM_64;
-
-       p->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
-
-       /* Get the Hierarchical mode */
-       Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
-
-       switch (Data) {
-       case 0:
-               p->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               p->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               p->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               p->hierarchy = HIERARCHY_4;
-               break;
-       default:
-               p->hierarchy = HIERARCHY_AUTO;
-               break; /* error */
-       }
-
-       /* Get the FEC Rate */
-       if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
-               Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
-       else
-               Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
-
-       switch (Data) {
-       case 0:
-               p->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_HP = FEC_7_8;
-               break;
-       default:
-               p->code_rate_HP = FEC_AUTO;
-               break; /* error */
-       }
-
-       mode = stv0367_readbits(state, F367TER_SYR_MODE);
-
-       switch (mode) {
-       case FE_TER_MODE_2K:
-               p->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-/*     case FE_TER_MODE_4K:
-               p->transmission_mode = TRANSMISSION_MODE_4K;
-               break;*/
-       case FE_TER_MODE_8K:
-               p->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       default:
-               p->transmission_mode = TRANSMISSION_MODE_AUTO;
-       }
-
-       p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
-
-       return error;
-}
-
-static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       u32 snru32 = 0;
-       int cpt = 0;
-       u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
-
-       while (cpt < 10) {
-               usleep_range(2000, 3000);
-               if (cut == 0x50) /*cut 1.0 cut 1.1*/
-                       snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
-               else /*cu2.0*/
-                       snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
-
-               cpt++;
-       }
-
-       snru32 /= 10;/*average on 10 values*/
-
-       *snr = snru32 / 1000;
-
-       return 0;
-}
-
-#if 0
-static int stv0367ter_status(struct dvb_frontend *fe)
-{
-
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-       int locked = FALSE;
-
-       locked = (stv0367_readbits(state, F367TER_LK));
-       if (!locked)
-               ter_state->unlock_counter += 1;
-       else
-               ter_state->unlock_counter = 0;
-
-       if (ter_state->unlock_counter > 2) {
-               if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
-                               (!stv0367_readbits(state, F367TER_LK))) {
-                       stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
-                       usleep_range(2000, 3000);
-                       stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
-                       msleep(350);
-                       locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
-                                       (stv0367_readbits(state, F367TER_LK));
-               }
-
-       }
-
-       return locked;
-}
-#endif
-static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       dprintk("%s:\n", __func__);
-
-       *status = 0;
-
-       if (stv0367_readbits(state, F367TER_LK)) {
-               *status |= FE_HAS_LOCK;
-               dprintk("%s: stv0367 has locked\n", __func__);
-       }
-
-       return 0;
-}
-
-static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367ter_state *ter_state = state->ter_state;
-       u32 Errors = 0, tber = 0, temporary = 0;
-       int abc = 0, def = 0;
-
-
-       /*wait for counting completion*/
-       if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
-               Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
-                       * (1 << 16))
-                       + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
-                       * (1 << 8))
-                       + ((u32)stv0367_readbits(state,
-                                               F367TER_SFEC_ERR_CNT_LO));
-       /*measurement not completed, load previous value*/
-       else {
-               tber = ter_state->pBER;
-               return 0;
-       }
-
-       abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
-       def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
-
-       if (Errors == 0) {
-               tber = 0;
-       } else if (abc == 0x7) {
-               if (Errors <= 4) {
-                       temporary = (Errors * 1000000000) / (8 * (1 << 14));
-                       temporary =  temporary;
-               } else if (Errors <= 42) {
-                       temporary = (Errors * 100000000) / (8 * (1 << 14));
-                       temporary = temporary * 10;
-               } else if (Errors <= 429) {
-                       temporary = (Errors * 10000000) / (8 * (1 << 14));
-                       temporary = temporary * 100;
-               } else if (Errors <= 4294) {
-                       temporary = (Errors * 1000000) / (8 * (1 << 14));
-                       temporary = temporary * 1000;
-               } else if (Errors <= 42949) {
-                       temporary = (Errors * 100000) / (8 * (1 << 14));
-                       temporary = temporary * 10000;
-               } else if (Errors <= 429496) {
-                       temporary = (Errors * 10000) / (8 * (1 << 14));
-                       temporary = temporary * 100000;
-               } else { /*if (Errors<4294967) 2^22 max error*/
-                       temporary = (Errors * 1000) / (8 * (1 << 14));
-                       temporary = temporary * 100000; /* still to *10 */
-               }
-
-               /* Byte error*/
-               if (def == 2)
-                       /*tber=Errors/(8*(1 <<14));*/
-                       tber = temporary;
-               else if (def == 3)
-                       /*tber=Errors/(8*(1 <<16));*/
-                       tber = temporary / 4;
-               else if (def == 4)
-                       /*tber=Errors/(8*(1 <<18));*/
-                       tber = temporary / 16;
-               else if (def == 5)
-                       /*tber=Errors/(8*(1 <<20));*/
-                       tber = temporary / 64;
-               else if (def == 6)
-                       /*tber=Errors/(8*(1 <<22));*/
-                       tber = temporary / 256;
-               else
-                       /* should not pass here*/
-                       tber = 0;
-
-               if ((Errors < 4294967) && (Errors > 429496))
-                       tber *= 10;
-
-       }
-
-       /* save actual value */
-       ter_state->pBER = tber;
-
-       (*ber) = tber;
-
-       return 0;
-}
-#if 0
-static u32 stv0367ter_get_per(struct stv0367_state *state)
-{
-       struct stv0367ter_state *ter_state = state->ter_state;
-       u32 Errors = 0, Per = 0, temporary = 0;
-       int abc = 0, def = 0, cpt = 0;
-
-       while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
-                       (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
-               usleep_range(1000, 2000);
-               Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
-                       * (1 << 16))
-                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
-                       * (1 << 8))
-                       + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
-               cpt++;
-       }
-       abc = stv0367_readbits(state, F367TER_ERR_SRC1);
-       def = stv0367_readbits(state, F367TER_NUM_EVT1);
-
-       if (Errors == 0)
-               Per = 0;
-       else if (abc == 0x9) {
-               if (Errors <= 4) {
-                       temporary = (Errors * 1000000000) / (8 * (1 << 8));
-                       temporary =  temporary;
-               } else if (Errors <= 42) {
-                       temporary = (Errors * 100000000) / (8 * (1 << 8));
-                       temporary = temporary * 10;
-               } else if (Errors <= 429) {
-                       temporary = (Errors * 10000000) / (8 * (1 << 8));
-                       temporary = temporary * 100;
-               } else if (Errors <= 4294) {
-                       temporary = (Errors * 1000000) / (8 * (1 << 8));
-                       temporary = temporary * 1000;
-               } else if (Errors <= 42949) {
-                       temporary = (Errors * 100000) / (8 * (1 << 8));
-                       temporary = temporary * 10000;
-               } else { /*if(Errors<=429496)  2^16 errors max*/
-                       temporary = (Errors * 10000) / (8 * (1 << 8));
-                       temporary = temporary * 100000;
-               }
-
-               /* pkt error*/
-               if (def == 2)
-                       /*Per=Errors/(1 << 8);*/
-                       Per = temporary;
-               else if (def == 3)
-                       /*Per=Errors/(1 << 10);*/
-                       Per = temporary / 4;
-               else if (def == 4)
-                       /*Per=Errors/(1 << 12);*/
-                       Per = temporary / 16;
-               else if (def == 5)
-                       /*Per=Errors/(1 << 14);*/
-                       Per = temporary / 64;
-               else if (def == 6)
-                       /*Per=Errors/(1 << 16);*/
-                       Per = temporary / 256;
-               else
-                       Per = 0;
-
-       }
-       /* save actual value */
-       ter_state->pPER = Per;
-
-       return Per;
-}
-#endif
-static int stv0367_get_tune_settings(struct dvb_frontend *fe,
-                                       struct dvb_frontend_tune_settings
-                                       *fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 1000;
-       fe_tune_settings->step_size = 0;
-       fe_tune_settings->max_drift = 0;
-
-       return 0;
-}
-
-static void stv0367_release(struct dvb_frontend *fe)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       kfree(state->ter_state);
-       kfree(state->cab_state);
-       kfree(state);
-}
-
-static struct dvb_frontend_ops stv0367ter_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "ST STV0367 DVB-T",
-               .frequency_min          = 47000000,
-               .frequency_max          = 862000000,
-               .frequency_stepsize     = 15625,
-               .frequency_tolerance    = 0,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
-                       FE_CAN_INVERSION_AUTO |
-                       FE_CAN_MUTE_TS
-       },
-       .release = stv0367_release,
-       .init = stv0367ter_init,
-       .sleep = stv0367ter_sleep,
-       .i2c_gate_ctrl = stv0367ter_gate_ctrl,
-       .set_frontend = stv0367ter_set_frontend,
-       .get_frontend = stv0367ter_get_frontend,
-       .get_tune_settings = stv0367_get_tune_settings,
-       .read_status = stv0367ter_read_status,
-       .read_ber = stv0367ter_read_ber,/* too slow */
-/*     .read_signal_strength = stv0367_read_signal_strength,*/
-       .read_snr = stv0367ter_read_snr,
-       .read_ucblocks = stv0367ter_read_ucblocks,
-};
-
-struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       struct stv0367_state *state = NULL;
-       struct stv0367ter_state *ter_state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-       ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
-       if (ter_state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       state->config = config;
-       state->ter_state = ter_state;
-       state->fe.ops = stv0367ter_ops;
-       state->fe.demodulator_priv = state;
-       state->chip_id = stv0367_readreg(state, 0xf000);
-
-       dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
-
-       /* check if the demod is there */
-       if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
-               goto error;
-
-       return &state->fe;
-
-error:
-       kfree(ter_state);
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(stv0367ter_attach);
-
-static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       dprintk("%s:\n", __func__);
-
-       stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
-
-       return 0;
-}
-
-static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       u32 mclk_Hz = 0;/* master clock frequency (Hz) */
-       u32 M, N, P;
-
-
-       if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
-               N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
-               if (N == 0)
-                       N = N + 1;
-
-               M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
-               if (M == 0)
-                       M = M + 1;
-
-               P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
-
-               if (P > 5)
-                       P = 5;
-
-               mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
-               dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
-                                                               mclk_Hz);
-       } else
-               mclk_Hz = ExtClk_Hz;
-
-       dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
-
-       return mclk_Hz;
-}
-
-static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
-{
-       u32 ADCClk_Hz = ExtClk_Hz;
-
-       ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
-
-       return ADCClk_Hz;
-}
-
-enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
-                                       u32 SymbolRate,
-                                       enum stv0367cab_mod QAMSize)
-{
-       /* Set QAM size */
-       stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
-
-       /* Set Registers settings specific to the QAM size */
-       switch (QAMSize) {
-       case FE_CAB_MOD_QAM4:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               break;
-       case FE_CAB_MOD_QAM16:
-               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
-               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
-               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
-               break;
-       case FE_CAB_MOD_QAM32:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
-               stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
-               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
-               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
-               break;
-       case FE_CAB_MOD_QAM64:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
-               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
-               if (SymbolRate > 45000000) {
-                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
-               } else if (SymbolRate > 25000000) {
-                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
-               } else {
-                       stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
-               }
-               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
-               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
-               break;
-       case FE_CAB_MOD_QAM128:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
-               stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
-               stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
-               if (SymbolRate > 45000000)
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
-               else if (SymbolRate > 25000000)
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
-               else
-                       stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
-
-               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
-               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
-               break;
-       case FE_CAB_MOD_QAM256:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
-               stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
-               stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
-               if (SymbolRate > 45000000)
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-               else if (SymbolRate > 25000000)
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
-               else
-                       stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
-
-               stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
-               stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
-               stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
-               break;
-       case FE_CAB_MOD_QAM512:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               break;
-       case FE_CAB_MOD_QAM1024:
-               stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
-               break;
-       default:
-               break;
-       }
-
-       return QAMSize;
-}
-
-static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
-                                       u32 adc_hz, s32 derot_hz)
-{
-       u32 sampled_if = 0;
-       u32 adc_khz;
-
-       adc_khz = adc_hz / 1000;
-
-       dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
-
-       if (adc_khz != 0) {
-               if (derot_hz < 1000000)
-                       derot_hz = adc_hz / 4; /* ZIF operation */
-               if (derot_hz > adc_hz)
-                       derot_hz = derot_hz - adc_hz;
-               sampled_if = (u32)derot_hz / 1000;
-               sampled_if *= 32768;
-               sampled_if /= adc_khz;
-               sampled_if *= 256;
-       }
-
-       if (sampled_if > 8388607)
-               sampled_if = 8388607;
-
-       dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
-
-       stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
-       stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
-       stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
-
-       return derot_hz;
-}
-
-static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
-{
-       u32 sampled_if;
-
-       sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
-                       (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
-                       (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
-
-       sampled_if /= 256;
-       sampled_if *= (adc_hz / 1000);
-       sampled_if += 1;
-       sampled_if /= 32768;
-
-       return sampled_if;
-}
-
-static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
-                       u32 mclk_hz, u32 SymbolRate,
-                       enum stv0367cab_mod QAMSize)
-{
-       u32 QamSizeCorr = 0;
-       u32 u32_tmp = 0, u32_tmp1 = 0;
-       u32 adp_khz;
-
-       dprintk("%s:\n", __func__);
-
-       /* Set Correction factor of SRC gain */
-       switch (QAMSize) {
-       case FE_CAB_MOD_QAM4:
-               QamSizeCorr = 1110;
-               break;
-       case FE_CAB_MOD_QAM16:
-               QamSizeCorr = 1032;
-               break;
-       case FE_CAB_MOD_QAM32:
-               QamSizeCorr =  954;
-               break;
-       case FE_CAB_MOD_QAM64:
-               QamSizeCorr =  983;
-               break;
-       case FE_CAB_MOD_QAM128:
-               QamSizeCorr =  957;
-               break;
-       case FE_CAB_MOD_QAM256:
-               QamSizeCorr =  948;
-               break;
-       case FE_CAB_MOD_QAM512:
-               QamSizeCorr =    0;
-               break;
-       case FE_CAB_MOD_QAM1024:
-               QamSizeCorr =  944;
-               break;
-       default:
-               break;
-       }
-
-       /* Transfer ratio calculation */
-       if (adc_hz != 0) {
-               u32_tmp = 256 * SymbolRate;
-               u32_tmp = u32_tmp / adc_hz;
-       }
-       stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
-
-       /* Symbol rate and SRC gain calculation */
-       adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
-       if (adp_khz != 0) {
-               u32_tmp = SymbolRate;
-               u32_tmp1 = SymbolRate;
-
-               if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
-                       /* Symbol rate calculation */
-                       u32_tmp *= 2048; /* 2048 = 2^11 */
-                       u32_tmp = u32_tmp / adp_khz;
-                       u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
-                       u32_tmp /= 125 ; /* 125 = 1000/2^3 */
-                       u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
-
-                       /* SRC Gain Calculation */
-                       u32_tmp1 *= 2048; /* *2*2^10 */
-                       u32_tmp1 /= 439; /* *2/878 */
-                       u32_tmp1 *= 256; /* *2^8 */
-                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
-                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
-                       u32_tmp1 = u32_tmp1 / 10000000;
-
-               } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
-                       /* Symbol rate calculation */
-                       u32_tmp *= 1024 ; /* 1024 = 2**10 */
-                       u32_tmp = u32_tmp / adp_khz;
-                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
-                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
-                       u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
-
-                       /* SRC Gain Calculation */
-                       u32_tmp1 *= 1024; /* *2*2^9 */
-                       u32_tmp1 /= 439; /* *2/878 */
-                       u32_tmp1 *= 256; /* *2^8 */
-                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
-                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
-                       u32_tmp1 = u32_tmp1 / 5000000;
-               } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
-                       /* Symbol rate calculation */
-                       u32_tmp *= 512 ; /* 512 = 2**9 */
-                       u32_tmp = u32_tmp / adp_khz;
-                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
-                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
-                       u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
-
-                       /* SRC Gain Calculation */
-                       u32_tmp1 *= 512; /* *2*2^8 */
-                       u32_tmp1 /= 439; /* *2/878 */
-                       u32_tmp1 *= 256; /* *2^8 */
-                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
-                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
-                       u32_tmp1 = u32_tmp1 / 2500000;
-               } else {
-                       /* Symbol rate calculation */
-                       u32_tmp *= 256 ; /* 256 = 2**8 */
-                       u32_tmp = u32_tmp / adp_khz;
-                       u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
-                       u32_tmp /= 125 ; /* 125 = 1000/2**3 */
-                       u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
-
-                       /* SRC Gain Calculation */
-                       u32_tmp1 *= 256; /* 2*2^7 */
-                       u32_tmp1 /= 439; /* *2/878 */
-                       u32_tmp1 *= 256; /* *2^8 */
-                       u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
-                       u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
-                       u32_tmp1 = u32_tmp1 / 1250000;
-               }
-       }
-#if 0
-       /* Filters' coefficients are calculated and written
-       into registers only if the filters are enabled */
-       if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
-               stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
-                                                               SymbolRate);
-               /* AllPass filter must be enabled
-               when the adjacents filter is used */
-               stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
-               stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
-       } else
-               /* AllPass filter must be disabled
-               when the adjacents filter is not used */
-#endif
-       stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
-
-       stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
-       stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
-       stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
-       stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
-
-       stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
-       stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
-
-       return SymbolRate ;
-}
-
-static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
-{
-       u32 regsym;
-       u32 adp_khz;
-
-       regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
-               (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
-               (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
-               (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
-
-       adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
-
-       if (regsym < 134217728) {               /* 134217728L = 2**27*/
-               regsym = regsym * 32;           /* 32 = 2**5 */
-               regsym = regsym / 32768;        /* 32768L = 2**15 */
-               regsym = adp_khz * regsym;      /* AdpClk in kHz */
-               regsym = regsym / 128;          /* 128 = 2**7 */
-               regsym *= 125 ;                 /* 125 = 1000/2**3 */
-               regsym /= 2048 ;                /* 2048 = 2**11 */
-       } else if (regsym < 268435456) {        /* 268435456L = 2**28 */
-               regsym = regsym * 16;           /* 16 = 2**4 */
-               regsym = regsym / 32768;        /* 32768L = 2**15 */
-               regsym = adp_khz * regsym;      /* AdpClk in kHz */
-               regsym = regsym / 128;          /* 128 = 2**7 */
-               regsym *= 125 ;                 /* 125 = 1000/2**3*/
-               regsym /= 1024 ;                /* 256 = 2**10*/
-       } else if (regsym < 536870912) {        /* 536870912L = 2**29*/
-               regsym = regsym * 8;            /* 8 = 2**3 */
-               regsym = regsym / 32768;        /* 32768L = 2**15 */
-               regsym = adp_khz * regsym;      /* AdpClk in kHz */
-               regsym = regsym / 128;          /* 128 = 2**7 */
-               regsym *= 125 ;                 /* 125 = 1000/2**3 */
-               regsym /= 512 ;                 /* 128 = 2**9 */
-       } else {
-               regsym = regsym * 4;            /* 4 = 2**2 */
-               regsym = regsym / 32768;        /* 32768L = 2**15 */
-               regsym = adp_khz * regsym;      /* AdpClk in kHz */
-               regsym = regsym / 128;          /* 128 = 2**7 */
-               regsym *= 125 ;                 /* 125 = 1000/2**3 */
-               regsym /= 256 ;                 /* 64 = 2**8 */
-       }
-
-       return regsym;
-}
-
-static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       dprintk("%s:\n", __func__);
-
-       *status = 0;
-
-       if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
-               *status |= FE_HAS_LOCK;
-               dprintk("%s: stv0367 has locked\n", __func__);
-       }
-
-       return 0;
-}
-
-static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       dprintk("%s:\n", __func__);
-
-       if (standby_on) {
-               stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
-               stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
-               stv0367_writebits(state, F367CAB_STDBY, 1);
-               stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
-               stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
-               stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
-               stv0367_writebits(state, F367CAB_POFFQ, 1);
-               stv0367_writebits(state, F367CAB_POFFI, 1);
-       } else {
-               stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
-               stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
-               stv0367_writebits(state, F367CAB_STDBY, 0);
-               stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
-               stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
-               stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
-               stv0367_writebits(state, F367CAB_POFFQ, 0);
-               stv0367_writebits(state, F367CAB_POFFI, 0);
-       }
-
-       return 0;
-}
-
-static int stv0367cab_sleep(struct dvb_frontend *fe)
-{
-       return stv0367cab_standby(fe, 1);
-}
-
-int stv0367cab_init(struct dvb_frontend *fe)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367cab_state *cab_state = state->cab_state;
-       int i;
-
-       dprintk("%s:\n", __func__);
-
-       for (i = 0; i < STV0367CAB_NBREGS; i++)
-               stv0367_writereg(state, def0367cab[i].addr,
-                                               def0367cab[i].value);
-
-       switch (state->config->ts_mode) {
-       case STV0367_DVBCI_CLOCK:
-               dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
-               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
-               break;
-       case STV0367_SERIAL_PUNCT_CLOCK:
-       case STV0367_SERIAL_CONT_CLOCK:
-               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
-               break;
-       case STV0367_PARALLEL_PUNCT_CLOCK:
-       case STV0367_OUTPUTMODE_DEFAULT:
-               stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
-               break;
-       }
-
-       switch (state->config->clk_pol) {
-       case STV0367_RISINGEDGE_CLOCK:
-               stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
-               break;
-       case STV0367_FALLINGEDGE_CLOCK:
-       case STV0367_CLOCKPOLARITY_DEFAULT:
-               stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
-               break;
-       }
-
-       stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
-
-       stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
-
-       stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
-
-       stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
-
-       stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
-
-       cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
-       cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
-
-       return 0;
-}
-static
-enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
-                                            struct dtv_frontend_properties *p)
-{
-       struct stv0367cab_state *cab_state = state->cab_state;
-       enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
-       u32     QAMFEC_Lock, QAM_Lock, u32_tmp,
-               LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
-               CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
-       u8      TrackAGCAccum;
-       s32     tmp;
-
-       dprintk("%s:\n", __func__);
-
-       /* Timeouts calculation */
-       /* A max lock time of 25 ms is allowed for delayed AGC */
-       AGCTimeOut = 25;
-       /* 100000 symbols needed by the TRL as a maximum value */
-       TRLTimeOut = 100000000 / p->symbol_rate;
-       /* CRLSymbols is the needed number of symbols to achieve a lock
-          within [-4%, +4%] of the symbol rate.
-          CRL timeout is calculated
-          for a lock within [-search_range, +search_range].
-          EQL timeout can be changed depending on
-          the micro-reflections we want to handle.
-          A characterization must be performed
-          with these echoes to get new timeout values.
-       */
-       switch (p->modulation) {
-       case QAM_16:
-               CRLSymbols = 150000;
-               EQLTimeOut = 100;
-               break;
-       case QAM_32:
-               CRLSymbols = 250000;
-               EQLTimeOut = 100;
-               break;
-       case QAM_64:
-               CRLSymbols = 200000;
-               EQLTimeOut = 100;
-               break;
-       case QAM_128:
-               CRLSymbols = 250000;
-               EQLTimeOut = 100;
-               break;
-       case QAM_256:
-               CRLSymbols = 250000;
-               EQLTimeOut = 100;
-               break;
-       default:
-               CRLSymbols = 200000;
-               EQLTimeOut = 100;
-               break;
-       }
-#if 0
-       if (pIntParams->search_range < 0) {
-               CRLTimeOut = (25 * CRLSymbols *
-                               (-pIntParams->search_range / 1000)) /
-                                       (pIntParams->symbol_rate / 1000);
-       } else
-#endif
-       CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
-                                       (p->symbol_rate / 1000);
-
-       CRLTimeOut = (1000 * CRLTimeOut) / p->symbol_rate;
-       /* Timeouts below 50ms are coerced */
-       if (CRLTimeOut < 50)
-               CRLTimeOut = 50;
-       /* A maximum of 100 TS packets is needed to get FEC lock even in case
-       the spectrum inversion needs to be changed.
-          This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
-       */
-       FECTimeOut = 20;
-       DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
-
-       dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
-
-       /* Reset the TRL to ensure nothing starts until the
-          AGC is stable which ensures a better lock time
-       */
-       stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
-       /* Set AGC accumulation time to minimum and lock threshold to maximum
-       in order to speed up the AGC lock */
-       TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
-       stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
-       /* Modulus Mapper is disabled */
-       stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
-       /* Disable the sweep function */
-       stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
-       /* The sweep function is never used, Sweep rate must be set to 0 */
-       /* Set the derotator frequency in Hz */
-       stv0367cab_set_derot_freq(state, cab_state->adc_clk,
-               (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
-       /* Disable the Allpass Filter when the symbol rate is out of range */
-       if ((p->symbol_rate > 10800000) | (p->symbol_rate < 1800000)) {
-               stv0367_writebits(state, F367CAB_ADJ_EN, 0);
-               stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
-       }
-#if 0
-       /* Check if the tuner is locked */
-       tuner_lock = stv0367cab_tuner_get_status(fe);
-       if (tuner_lock == 0)
-               return FE_367CAB_NOTUNER;
-#endif
-       /* Relase the TRL to start demodulator acquisition */
-       /* Wait for QAM lock */
-       LockTime = 0;
-       stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
-       do {
-               QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
-               if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
-                                                       (QAM_Lock == 0x04))
-                       /*
-                        * We don't wait longer, the frequency/phase offset
-                        * must be too big
-                        */
-                       LockTime = DemodTimeOut;
-               else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
-                                                       (QAM_Lock == 0x02))
-                       /*
-                        * We don't wait longer, either there is no signal or
-                        * it is not the right symbol rate or it is an analog
-                        * carrier
-                        */
-               {
-                       LockTime = DemodTimeOut;
-                       u32_tmp = stv0367_readbits(state,
-                                               F367CAB_AGC_PWR_WORD_LO) +
-                                       (stv0367_readbits(state,
-                                               F367CAB_AGC_PWR_WORD_ME) << 8) +
-                                       (stv0367_readbits(state,
-                                               F367CAB_AGC_PWR_WORD_HI) << 16);
-                       if (u32_tmp >= 131072)
-                               u32_tmp = 262144 - u32_tmp;
-                       u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
-                                                       F367CAB_AGC_IF_BWSEL)));
-
-                       if (u32_tmp < stv0367_readbits(state,
-                                               F367CAB_AGC_PWRREF_LO) +
-                                       256 * stv0367_readbits(state,
-                                               F367CAB_AGC_PWRREF_HI) - 10)
-                               QAM_Lock = 0x0f;
-               } else {
-                       usleep_range(10000, 20000);
-                       LockTime += 10;
-               }
-               dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
-               tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
-
-               dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
-
-       } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
-                                               (LockTime < DemodTimeOut));
-
-       dprintk("QAM_Lock=0x%x\n", QAM_Lock);
-
-       tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
-       dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
-       tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
-       dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
-
-       tmp  = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
-       dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
-
-       if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
-               /* Wait for FEC lock */
-               LockTime = 0;
-               do {
-                       usleep_range(5000, 7000);
-                       LockTime += 5;
-                       QAMFEC_Lock = stv0367_readbits(state,
-                                                       F367CAB_QAMFEC_LOCK);
-               } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
-       } else
-               QAMFEC_Lock = 0;
-
-       if (QAMFEC_Lock) {
-               signalType = FE_CAB_DATAOK;
-               cab_state->modulation = p->modulation;
-               cab_state->spect_inv = stv0367_readbits(state,
-                                                       F367CAB_QUAD_INV);
-#if 0
-/* not clear for me */
-               if (state->config->if_khz != 0) {
-                       if (state->config->if_khz > cab_state->adc_clk / 1000) {
-                               cab_state->freq_khz =
-                                       FE_Cab_TunerGetFrequency(pIntParams->hTuner)
-                               - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
-                               - cab_state->adc_clk / 1000 + state->config->if_khz;
-                       } else {
-                               cab_state->freq_khz =
-                                               FE_Cab_TunerGetFrequency(pIntParams->hTuner)
-                                               - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
-                                                                               + state->config->if_khz;
-                       }
-               } else {
-                       cab_state->freq_khz =
-                               FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
-                               stv0367cab_get_derot_freq(state,
-                                                       cab_state->adc_clk) -
-                               cab_state->adc_clk / 4000;
-               }
-#endif
-               cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
-                                                       cab_state->mclk);
-               cab_state->locked = 1;
-
-               /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
-       } else {
-               switch (QAM_Lock) {
-               case 1:
-                       signalType = FE_CAB_NOAGC;
-                       break;
-               case 2:
-                       signalType = FE_CAB_NOTIMING;
-                       break;
-               case 3:
-                       signalType = FE_CAB_TIMINGOK;
-                       break;
-               case 4:
-                       signalType = FE_CAB_NOCARRIER;
-                       break;
-               case 5:
-                       signalType = FE_CAB_CARRIEROK;
-                       break;
-               case 7:
-                       signalType = FE_CAB_NOBLIND;
-                       break;
-               case 8:
-                       signalType = FE_CAB_BLINDOK;
-                       break;
-               case 10:
-                       signalType = FE_CAB_NODEMOD;
-                       break;
-               case 11:
-                       signalType = FE_CAB_DEMODOK;
-                       break;
-               case 12:
-                       signalType = FE_CAB_DEMODOK;
-                       break;
-               case 13:
-                       signalType = FE_CAB_NODEMOD;
-                       break;
-               case 14:
-                       signalType = FE_CAB_NOBLIND;
-                       break;
-               case 15:
-                       signalType = FE_CAB_NOSIGNAL;
-                       break;
-               default:
-                       break;
-               }
-
-       }
-
-       /* Set the AGC control values to tracking values */
-       stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
-       return signalType;
-}
-
-static int stv0367cab_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367cab_state *cab_state = state->cab_state;
-       enum stv0367cab_mod QAMSize = 0;
-
-       dprintk("%s: freq = %d, srate = %d\n", __func__,
-                                       p->frequency, p->symbol_rate);
-
-       cab_state->derot_offset = 0;
-
-       switch (p->modulation) {
-       case QAM_16:
-               QAMSize = FE_CAB_MOD_QAM16;
-               break;
-       case QAM_32:
-               QAMSize = FE_CAB_MOD_QAM32;
-               break;
-       case QAM_64:
-               QAMSize = FE_CAB_MOD_QAM64;
-               break;
-       case QAM_128:
-               QAMSize = FE_CAB_MOD_QAM128;
-               break;
-       case QAM_256:
-               QAMSize = FE_CAB_MOD_QAM256;
-               break;
-       default:
-               break;
-       }
-
-       stv0367cab_init(fe);
-
-       /* Tuner Frequency Setting */
-       if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       stv0367cab_SetQamSize(
-                       state,
-                       p->symbol_rate,
-                       QAMSize);
-
-       stv0367cab_set_srate(state,
-                       cab_state->adc_clk,
-                       cab_state->mclk,
-                       p->symbol_rate,
-                       QAMSize);
-       /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
-       cab_state->state = stv0367cab_algo(state, p);
-       return 0;
-}
-
-static int stv0367cab_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0367_state *state = fe->demodulator_priv;
-       struct stv0367cab_state *cab_state = state->cab_state;
-
-       enum stv0367cab_mod QAMSize;
-
-       dprintk("%s:\n", __func__);
-
-       p->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
-
-       QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
-       switch (QAMSize) {
-       case FE_CAB_MOD_QAM16:
-               p->modulation = QAM_16;
-               break;
-       case FE_CAB_MOD_QAM32:
-               p->modulation = QAM_32;
-               break;
-       case FE_CAB_MOD_QAM64:
-               p->modulation = QAM_64;
-               break;
-       case FE_CAB_MOD_QAM128:
-               p->modulation = QAM_128;
-               break;
-       case QAM_256:
-               p->modulation = QAM_256;
-               break;
-       default:
-               break;
-       }
-
-       p->frequency = stv0367_get_tuner_freq(fe);
-
-       dprintk("%s: tuner frequency = %d\n", __func__, p->frequency);
-
-       if (state->config->if_khz == 0) {
-               p->frequency +=
-                       (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
-                       cab_state->adc_clk / 4000);
-               return 0;
-       }
-
-       if (state->config->if_khz > cab_state->adc_clk / 1000)
-               p->frequency += (state->config->if_khz
-                       - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
-                       - cab_state->adc_clk / 1000);
-       else
-               p->frequency += (state->config->if_khz
-                       - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
-
-       return 0;
-}
-
-#if 0
-void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
-                       u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
-{
-       stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
-       stv0367cab_GetPacketsCount(state, Monitor_results);
-
-       return;
-}
-
-static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       return 0;
-}
-#endif
-static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
-{
-       s32 rfLevel = 0;
-       s32 RfAgcPwm = 0, IfAgcPwm = 0;
-       u8 i;
-
-       stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
-
-       RfAgcPwm =
-               (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
-               (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
-       RfAgcPwm = 100 * RfAgcPwm / 1023;
-
-       IfAgcPwm =
-               stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
-               (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
-       if (IfAgcPwm >= 2048)
-               IfAgcPwm -= 2048;
-       else
-               IfAgcPwm += 2048;
-
-       IfAgcPwm = 100 * IfAgcPwm / 4095;
-
-       /* For DTT75467 on NIM */
-       if (RfAgcPwm < 90  && IfAgcPwm < 28) {
-               for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
-                       if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
-                               rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
-                               break;
-                       }
-               }
-               if (i == RF_LOOKUP_TABLE_SIZE)
-                       rfLevel = -56;
-       } else { /*if IF AGC>10*/
-               for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
-                       if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
-                               rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
-                               break;
-                       }
-               }
-               if (i == RF_LOOKUP_TABLE2_SIZE)
-                       rfLevel = -72;
-       }
-       return rfLevel;
-}
-
-static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-
-       s32 signal =  stv0367cab_get_rf_lvl(state);
-
-       dprintk("%s: signal=%d dBm\n", __func__, signal);
-
-       if (signal <= -72)
-               *strength = 65535;
-       else
-               *strength = (22 + signal) * (-1311);
-
-       dprintk("%s: strength=%d\n", __func__, (*strength));
-
-       return 0;
-}
-
-static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       u32 noisepercentage;
-       enum stv0367cab_mod QAMSize;
-       u32 regval = 0, temp = 0;
-       int power, i;
-
-       QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
-       switch (QAMSize) {
-       case FE_CAB_MOD_QAM4:
-               power = 21904;
-               break;
-       case FE_CAB_MOD_QAM16:
-               power = 20480;
-               break;
-       case FE_CAB_MOD_QAM32:
-               power = 23040;
-               break;
-       case FE_CAB_MOD_QAM64:
-               power = 21504;
-               break;
-       case FE_CAB_MOD_QAM128:
-               power = 23616;
-               break;
-       case FE_CAB_MOD_QAM256:
-               power = 21760;
-               break;
-       case FE_CAB_MOD_QAM512:
-               power = 1;
-               break;
-       case FE_CAB_MOD_QAM1024:
-               power = 21280;
-               break;
-       default:
-               power = 1;
-               break;
-       }
-
-       for (i = 0; i < 10; i++) {
-               regval += (stv0367_readbits(state, F367CAB_SNR_LO)
-                       + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
-       }
-
-       regval /= 10; /*for average over 10 times in for loop above*/
-       if (regval != 0) {
-               temp = power
-                       * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
-               temp /= regval;
-       }
-
-       /* table values, not needed to calculate logarithms */
-       if (temp >= 5012)
-               noisepercentage = 100;
-       else if (temp >= 3981)
-               noisepercentage = 93;
-       else if (temp >= 3162)
-               noisepercentage = 86;
-       else if (temp >= 2512)
-               noisepercentage = 79;
-       else if (temp >= 1995)
-               noisepercentage = 72;
-       else if (temp >= 1585)
-               noisepercentage = 65;
-       else if (temp >= 1259)
-               noisepercentage = 58;
-       else if (temp >= 1000)
-               noisepercentage = 50;
-       else if (temp >= 794)
-               noisepercentage = 43;
-       else if (temp >= 501)
-               noisepercentage = 36;
-       else if (temp >= 316)
-               noisepercentage = 29;
-       else if (temp >= 200)
-               noisepercentage = 22;
-       else if (temp >= 158)
-               noisepercentage = 14;
-       else if (temp >= 126)
-               noisepercentage = 7;
-       else
-               noisepercentage = 0;
-
-       dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
-
-       *snr = (noisepercentage * 65535) / 100;
-
-       return 0;
-}
-
-static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct stv0367_state *state = fe->demodulator_priv;
-       int corrected, tscount;
-
-       *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
-                       | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
-       corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
-                       | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
-       tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
-                       | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
-
-       dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
-                               __func__, *ucblocks, corrected, tscount);
-
-       return 0;
-};
-
-static struct dvb_frontend_ops stv0367cab_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-               .name = "ST STV0367 DVB-C",
-               .frequency_min = 47000000,
-               .frequency_max = 862000000,
-               .frequency_stepsize = 62500,
-               .symbol_rate_min = 870000,
-               .symbol_rate_max = 11700000,
-               .caps = 0x400 |/* FE_CAN_QAM_4 */
-                       FE_CAN_QAM_16 | FE_CAN_QAM_32  |
-                       FE_CAN_QAM_64 | FE_CAN_QAM_128 |
-                       FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
-       },
-       .release                                = stv0367_release,
-       .init                                   = stv0367cab_init,
-       .sleep                                  = stv0367cab_sleep,
-       .i2c_gate_ctrl                          = stv0367cab_gate_ctrl,
-       .set_frontend                           = stv0367cab_set_frontend,
-       .get_frontend                           = stv0367cab_get_frontend,
-       .read_status                            = stv0367cab_read_status,
-/*     .read_ber                               = stv0367cab_read_ber, */
-       .read_signal_strength                   = stv0367cab_read_strength,
-       .read_snr                               = stv0367cab_read_snr,
-       .read_ucblocks                          = stv0367cab_read_ucblcks,
-       .get_tune_settings                      = stv0367_get_tune_settings,
-};
-
-struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       struct stv0367_state *state = NULL;
-       struct stv0367cab_state *cab_state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-       cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
-       if (cab_state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       state->config = config;
-       cab_state->search_range = 280000;
-       state->cab_state = cab_state;
-       state->fe.ops = stv0367cab_ops;
-       state->fe.demodulator_priv = state;
-       state->chip_id = stv0367_readreg(state, 0xf000);
-
-       dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
-
-       /* check if the demod is there */
-       if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
-               goto error;
-
-       return &state->fe;
-
-error:
-       kfree(cab_state);
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(stv0367cab_attach);
-
-MODULE_PARM_DESC(debug, "Set debug");
-MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
-
-MODULE_AUTHOR("Igor M. Liplianin");
-MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb/frontends/stv0367.h
deleted file mode 100644 (file)
index 93cc4a5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * stv0367.h
- *
- * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0367_H
-#define STV0367_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct stv0367_config {
-       u8 demod_address;
-       u32 xtal;
-       u32 if_khz;/*4500*/
-       int if_iq_mode;
-       int ts_mode;
-       int clk_pol;
-};
-
-#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
-                                                       && defined(MODULE))
-extern struct
-dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
-                                       struct i2c_adapter *i2c);
-extern struct
-dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
-                                       struct i2c_adapter *i2c);
-#else
-static inline struct
-dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline struct
-dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv0367_priv.h b/drivers/media/dvb/frontends/stv0367_priv.h
deleted file mode 100644 (file)
index 995db06..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * stv0367_priv.h
- *
- * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* Common driver error constants */
-
-#ifndef STV0367_PRIV_H
-#define STV0367_PRIV_H
-
-#ifndef TRUE
-    #define TRUE (1 == 1)
-#endif
-#ifndef FALSE
-    #define FALSE (!TRUE)
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* MACRO definitions */
-#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
-#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
-#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
-#define INRANGE(X, Y, Z) \
-       ((((X) <= (Y)) && ((Y) <= (Z))) || \
-       (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
-
-#ifndef MAKEWORD
-#define MAKEWORD(X, Y) (((X) << 8) + (Y))
-#endif
-
-#define LSB(X) (((X) & 0xff))
-#define MSB(Y) (((Y) >> 8) & 0xff)
-#define MMSB(Y)(((Y) >> 16) & 0xff)
-
-enum stv0367_ter_signal_type {
-       FE_TER_NOAGC = 0,
-       FE_TER_AGCOK = 5,
-       FE_TER_NOTPS = 6,
-       FE_TER_TPSOK = 7,
-       FE_TER_NOSYMBOL = 8,
-       FE_TER_BAD_CPQ = 9,
-       FE_TER_PRFOUNDOK = 10,
-       FE_TER_NOPRFOUND = 11,
-       FE_TER_LOCKOK = 12,
-       FE_TER_NOLOCK = 13,
-       FE_TER_SYMBOLOK = 15,
-       FE_TER_CPAMPOK = 16,
-       FE_TER_NOCPAMP = 17,
-       FE_TER_SWNOK = 18
-};
-
-enum stv0367_ts_mode {
-       STV0367_OUTPUTMODE_DEFAULT,
-       STV0367_SERIAL_PUNCT_CLOCK,
-       STV0367_SERIAL_CONT_CLOCK,
-       STV0367_PARALLEL_PUNCT_CLOCK,
-       STV0367_DVBCI_CLOCK
-};
-
-enum stv0367_clk_pol {
-       STV0367_CLOCKPOLARITY_DEFAULT,
-       STV0367_RISINGEDGE_CLOCK,
-       STV0367_FALLINGEDGE_CLOCK
-};
-
-enum stv0367_ter_bw {
-       FE_TER_CHAN_BW_6M = 6,
-       FE_TER_CHAN_BW_7M = 7,
-       FE_TER_CHAN_BW_8M = 8
-};
-
-#if 0
-enum FE_TER_Rate_TPS {
-       FE_TER_TPS_1_2 = 0,
-       FE_TER_TPS_2_3 = 1,
-       FE_TER_TPS_3_4 = 2,
-       FE_TER_TPS_5_6 = 3,
-       FE_TER_TPS_7_8 = 4
-};
-#endif
-
-enum stv0367_ter_mode {
-       FE_TER_MODE_2K,
-       FE_TER_MODE_8K,
-       FE_TER_MODE_4K
-};
-#if 0
-enum FE_TER_Hierarchy_Alpha {
-       FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
-       FE_TER_HIER_ALPHA_1,    /* Hierarchical modulation a = 1*/
-       FE_TER_HIER_ALPHA_2,    /* Hierarchical modulation a = 2*/
-       FE_TER_HIER_ALPHA_4     /* Hierarchical modulation a = 4*/
-};
-#endif
-enum stv0367_ter_hierarchy {
-       FE_TER_HIER_NONE,       /*Hierarchy None*/
-       FE_TER_HIER_LOW_PRIO,   /*Hierarchy : Low Priority*/
-       FE_TER_HIER_HIGH_PRIO,  /*Hierarchy : High Priority*/
-       FE_TER_HIER_PRIO_ANY    /*Hierarchy  :Any*/
-};
-
-#if 0
-enum fe_stv0367_ter_spec {
-       FE_TER_INVERSION_NONE = 0,
-       FE_TER_INVERSION = 1,
-       FE_TER_INVERSION_AUTO = 2,
-       FE_TER_INVERSION_UNK  = 4
-};
-#endif
-
-enum stv0367_ter_if_iq_mode {
-       FE_TER_NORMAL_IF_TUNER = 0,
-       FE_TER_LONGPATH_IF_TUNER = 1,
-       FE_TER_IQ_TUNER = 2
-
-};
-
-#if 0
-enum FE_TER_FECRate {
-       FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
-       FE_TER_FEC_ALL = 0xFF,   /* Logical OR of all FECs */
-       FE_TER_FEC_1_2 = 1,
-       FE_TER_FEC_2_3 = (1 << 1),
-       FE_TER_FEC_3_4 = (1 << 2),
-       FE_TER_FEC_4_5 = (1 << 3),
-       FE_TER_FEC_5_6 = (1 << 4),
-       FE_TER_FEC_6_7 = (1 << 5),
-       FE_TER_FEC_7_8 = (1 << 6),
-       FE_TER_FEC_8_9 = (1 << 7)
-};
-
-enum FE_TER_Rate {
-       FE_TER_FE_1_2 = 0,
-       FE_TER_FE_2_3 = 1,
-       FE_TER_FE_3_4 = 2,
-       FE_TER_FE_5_6 = 3,
-       FE_TER_FE_6_7 = 4,
-       FE_TER_FE_7_8 = 5
-};
-#endif
-
-enum stv0367_ter_force {
-       FE_TER_FORCENONE = 0,
-       FE_TER_FORCE_M_G = 1
-};
-
-enum  stv0367cab_mod {
-       FE_CAB_MOD_QAM4,
-       FE_CAB_MOD_QAM16,
-       FE_CAB_MOD_QAM32,
-       FE_CAB_MOD_QAM64,
-       FE_CAB_MOD_QAM128,
-       FE_CAB_MOD_QAM256,
-       FE_CAB_MOD_QAM512,
-       FE_CAB_MOD_QAM1024
-};
-#if 0
-enum {
-       FE_CAB_FEC_A = 1,       /* J83 Annex A */
-       FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
-       FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
-} FE_CAB_FECType_t;
-#endif
-struct stv0367_cab_signal_info {
-       int locked;
-       u32 frequency; /* kHz */
-       u32 symbol_rate; /* Mbds */
-       enum stv0367cab_mod modulation;
-       fe_spectral_inversion_t spect_inv;
-       s32 Power_dBmx10;       /* Power of the RF signal (dBm x 10) */
-       u32     CN_dBx10;       /* Carrier to noise ratio (dB x 10) */
-       u32     BER;            /* Bit error rate (x 10000000)  */
-};
-
-enum stv0367_cab_signal_type {
-       FE_CAB_NOTUNER,
-       FE_CAB_NOAGC,
-       FE_CAB_NOSIGNAL,
-       FE_CAB_NOTIMING,
-       FE_CAB_TIMINGOK,
-       FE_CAB_NOCARRIER,
-       FE_CAB_CARRIEROK,
-       FE_CAB_NOBLIND,
-       FE_CAB_BLINDOK,
-       FE_CAB_NODEMOD,
-       FE_CAB_DEMODOK,
-       FE_CAB_DATAOK
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv0367_regs.h b/drivers/media/dvb/frontends/stv0367_regs.h
deleted file mode 100644 (file)
index a96fbdc..0000000
+++ /dev/null
@@ -1,3614 +0,0 @@
-/*
- * stv0367_regs.h
- *
- * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0367_REGS_H
-#define STV0367_REGS_H
-
-/* ID */
-#define        R367TER_ID      0xf000
-#define        F367TER_IDENTIFICATIONREG       0xf00000ff
-
-/* I2CRPT */
-#define        R367TER_I2CRPT  0xf001
-#define        F367TER_I2CT_ON 0xf0010080
-#define        F367TER_ENARPT_LEVEL    0xf0010070
-#define        F367TER_SCLT_DELAY      0xf0010008
-#define        F367TER_SCLT_NOD        0xf0010004
-#define        F367TER_STOP_ENABLE     0xf0010002
-#define        F367TER_SDAT_NOD        0xf0010001
-
-/* TOPCTRL */
-#define        R367TER_TOPCTRL 0xf002
-#define        F367TER_STDBY   0xf0020080
-#define        F367TER_STDBY_FEC       0xf0020040
-#define        F367TER_STDBY_CORE      0xf0020020
-#define        F367TER_QAM_COFDM       0xf0020010
-#define        F367TER_TS_DIS  0xf0020008
-#define        F367TER_DIR_CLK_216     0xf0020004
-#define        F367TER_TUNER_BB        0xf0020002
-#define        F367TER_DVBT_H  0xf0020001
-
-/* IOCFG0 */
-#define        R367TER_IOCFG0  0xf003
-#define        F367TER_OP0_SD  0xf0030080
-#define        F367TER_OP0_VAL 0xf0030040
-#define        F367TER_OP0_OD  0xf0030020
-#define        F367TER_OP0_INV 0xf0030010
-#define        F367TER_OP0_DACVALUE_HI 0xf003000f
-
-/* DAc0R */
-#define        R367TER_DAC0R   0xf004
-#define        F367TER_OP0_DACVALUE_LO 0xf00400ff
-
-/* IOCFG1 */
-#define        R367TER_IOCFG1  0xf005
-#define        F367TER_IP0     0xf0050040
-#define        F367TER_OP1_OD  0xf0050020
-#define        F367TER_OP1_INV 0xf0050010
-#define        F367TER_OP1_DACVALUE_HI 0xf005000f
-
-/* DAC1R */
-#define        R367TER_DAC1R   0xf006
-#define        F367TER_OP1_DACVALUE_LO 0xf00600ff
-
-/* IOCFG2 */
-#define        R367TER_IOCFG2  0xf007
-#define        F367TER_OP2_LOCK_CONF   0xf00700e0
-#define        F367TER_OP2_OD  0xf0070010
-#define        F367TER_OP2_VAL 0xf0070008
-#define        F367TER_OP1_LOCK_CONF   0xf0070007
-
-/* SDFR */
-#define        R367TER_SDFR    0xf008
-#define        F367TER_OP0_FREQ        0xf00800f0
-#define        F367TER_OP1_FREQ        0xf008000f
-
-/* STATUS */
-#define        R367TER_STATUS  0xf009
-#define        F367TER_TPS_LOCK        0xf0090080
-#define        F367TER_SYR_LOCK        0xf0090040
-#define        F367TER_AGC_LOCK        0xf0090020
-#define        F367TER_PRF     0xf0090010
-#define        F367TER_LK      0xf0090008
-#define        F367TER_PR      0xf0090007
-
-/* AUX_CLK */
-#define        R367TER_AUX_CLK 0xf00a
-#define        F367TER_AUXFEC_CTL      0xf00a00c0
-#define        F367TER_DIS_CKX4        0xf00a0020
-#define        F367TER_CKSEL   0xf00a0018
-#define        F367TER_CKDIV_PROG      0xf00a0006
-#define        F367TER_AUXCLK_ENA      0xf00a0001
-
-/* FREESYS1 */
-#define        R367TER_FREESYS1        0xf00b
-#define        F367TER_FREE_SYS1       0xf00b00ff
-
-/* FREESYS2 */
-#define        R367TER_FREESYS2        0xf00c
-#define        F367TER_FREE_SYS2       0xf00c00ff
-
-/* FREESYS3 */
-#define        R367TER_FREESYS3        0xf00d
-#define        F367TER_FREE_SYS3       0xf00d00ff
-
-/* GPIO_CFG */
-#define        R367TER_GPIO_CFG        0xf00e
-#define        F367TER_GPIO7_NOD       0xf00e0080
-#define        F367TER_GPIO7_CFG       0xf00e0040
-#define        F367TER_GPIO6_NOD       0xf00e0020
-#define        F367TER_GPIO6_CFG       0xf00e0010
-#define        F367TER_GPIO5_NOD       0xf00e0008
-#define        F367TER_GPIO5_CFG       0xf00e0004
-#define        F367TER_GPIO4_NOD       0xf00e0002
-#define        F367TER_GPIO4_CFG       0xf00e0001
-
-/* GPIO_CMD */
-#define        R367TER_GPIO_CMD        0xf00f
-#define        F367TER_GPIO7_VAL       0xf00f0008
-#define        F367TER_GPIO6_VAL       0xf00f0004
-#define        F367TER_GPIO5_VAL       0xf00f0002
-#define        F367TER_GPIO4_VAL       0xf00f0001
-
-/* AGC2MAX */
-#define        R367TER_AGC2MAX 0xf010
-#define        F367TER_AGC2_MAX        0xf01000ff
-
-/* AGC2MIN */
-#define        R367TER_AGC2MIN 0xf011
-#define        F367TER_AGC2_MIN        0xf01100ff
-
-/* AGC1MAX */
-#define        R367TER_AGC1MAX 0xf012
-#define        F367TER_AGC1_MAX        0xf01200ff
-
-/* AGC1MIN */
-#define        R367TER_AGC1MIN 0xf013
-#define        F367TER_AGC1_MIN        0xf01300ff
-
-/* AGCR */
-#define        R367TER_AGCR    0xf014
-#define        F367TER_RATIO_A 0xf01400e0
-#define        F367TER_RATIO_B 0xf0140018
-#define        F367TER_RATIO_C 0xf0140007
-
-/* AGC2TH */
-#define        R367TER_AGC2TH  0xf015
-#define        F367TER_AGC2_THRES      0xf01500ff
-
-/* AGC12c */
-#define        R367TER_AGC12C  0xf016
-#define        F367TER_AGC1_IV 0xf0160080
-#define        F367TER_AGC1_OD 0xf0160040
-#define        F367TER_AGC1_LOAD       0xf0160020
-#define        F367TER_AGC2_IV 0xf0160010
-#define        F367TER_AGC2_OD 0xf0160008
-#define        F367TER_AGC2_LOAD       0xf0160004
-#define        F367TER_AGC12_MODE      0xf0160003
-
-/* AGCCTRL1 */
-#define        R367TER_AGCCTRL1        0xf017
-#define        F367TER_DAGC_ON 0xf0170080
-#define        F367TER_INVERT_AGC12    0xf0170040
-#define        F367TER_AGC1_MODE       0xf0170008
-#define        F367TER_AGC2_MODE       0xf0170007
-
-/* AGCCTRL2 */
-#define        R367TER_AGCCTRL2        0xf018
-#define        F367TER_FRZ2_CTRL       0xf0180060
-#define        F367TER_FRZ1_CTRL       0xf0180018
-#define        F367TER_TIME_CST        0xf0180007
-
-/* AGC1VAL1 */
-#define        R367TER_AGC1VAL1        0xf019
-#define        F367TER_AGC1_VAL_LO     0xf01900ff
-
-/* AGC1VAL2 */
-#define        R367TER_AGC1VAL2        0xf01a
-#define        F367TER_AGC1_VAL_HI     0xf01a000f
-
-/* AGC2VAL1 */
-#define        R367TER_AGC2VAL1        0xf01b
-#define        F367TER_AGC2_VAL_LO     0xf01b00ff
-
-/* AGC2VAL2 */
-#define        R367TER_AGC2VAL2        0xf01c
-#define        F367TER_AGC2_VAL_HI     0xf01c000f
-
-/* AGC2PGA */
-#define        R367TER_AGC2PGA 0xf01d
-#define        F367TER_AGC2_PGA        0xf01d00ff
-
-/* OVF_RATE1 */
-#define        R367TER_OVF_RATE1       0xf01e
-#define        F367TER_OVF_RATE_HI     0xf01e000f
-
-/* OVF_RATE2 */
-#define        R367TER_OVF_RATE2       0xf01f
-#define        F367TER_OVF_RATE_LO     0xf01f00ff
-
-/* GAIN_SRC1 */
-#define        R367TER_GAIN_SRC1       0xf020
-#define        F367TER_INV_SPECTR      0xf0200080
-#define        F367TER_IQ_INVERT       0xf0200040
-#define        F367TER_INR_BYPASS      0xf0200020
-#define        F367TER_STATUS_INV_SPECRUM      0xf0200010
-#define        F367TER_GAIN_SRC_HI     0xf020000f
-
-/* GAIN_SRC2 */
-#define        R367TER_GAIN_SRC2       0xf021
-#define        F367TER_GAIN_SRC_LO     0xf02100ff
-
-/* INC_DEROT1 */
-#define        R367TER_INC_DEROT1      0xf022
-#define        F367TER_INC_DEROT_HI    0xf02200ff
-
-/* INC_DEROT2 */
-#define        R367TER_INC_DEROT2      0xf023
-#define        F367TER_INC_DEROT_LO    0xf02300ff
-
-/* PPM_CPAMP_DIR */
-#define        R367TER_PPM_CPAMP_DIR   0xf024
-#define        F367TER_PPM_CPAMP_DIRECT        0xf02400ff
-
-/* PPM_CPAMP_INV */
-#define        R367TER_PPM_CPAMP_INV   0xf025
-#define        F367TER_PPM_CPAMP_INVER 0xf02500ff
-
-/* FREESTFE_1 */
-#define        R367TER_FREESTFE_1      0xf026
-#define        F367TER_SYMBOL_NUMBER_INC       0xf02600c0
-#define        F367TER_SEL_LSB 0xf0260004
-#define        F367TER_AVERAGE_ON      0xf0260002
-#define        F367TER_DC_ADJ  0xf0260001
-
-/* FREESTFE_2 */
-#define        R367TER_FREESTFE_2      0xf027
-#define        F367TER_SEL_SRCOUT      0xf02700c0
-#define        F367TER_SEL_SYRTHR      0xf027001f
-
-/* DCOFFSET */
-#define        R367TER_DCOFFSET        0xf028
-#define        F367TER_SELECT_I_Q      0xf0280080
-#define        F367TER_DC_OFFSET       0xf028007f
-
-/* EN_PROCESS */
-#define        R367TER_EN_PROCESS      0xf029
-#define        F367TER_FREE    0xf02900f0
-#define        F367TER_ENAB_MANUAL     0xf0290001
-
-/* SDI_SMOOTHER */
-#define        R367TER_SDI_SMOOTHER    0xf02a
-#define        F367TER_DIS_SMOOTH      0xf02a0080
-#define        F367TER_SDI_INC_SMOOTHER        0xf02a007f
-
-/* FE_LOOP_OPEN */
-#define        R367TER_FE_LOOP_OPEN    0xf02b
-#define        F367TER_TRL_LOOP_OP     0xf02b0002
-#define        F367TER_CRL_LOOP_OP     0xf02b0001
-
-/* FREQOFF1 */
-#define        R367TER_FREQOFF1        0xf02c
-#define        F367TER_FREQ_OFFSET_LOOP_OPEN_VHI       0xf02c00ff
-
-/* FREQOFF2 */
-#define        R367TER_FREQOFF2        0xf02d
-#define        F367TER_FREQ_OFFSET_LOOP_OPEN_HI        0xf02d00ff
-
-/* FREQOFF3 */
-#define        R367TER_FREQOFF3        0xf02e
-#define        F367TER_FREQ_OFFSET_LOOP_OPEN_LO        0xf02e00ff
-
-/* TIMOFF1 */
-#define        R367TER_TIMOFF1 0xf02f
-#define        F367TER_TIM_OFFSET_LOOP_OPEN_HI 0xf02f00ff
-
-/* TIMOFF2 */
-#define        R367TER_TIMOFF2 0xf030
-#define        F367TER_TIM_OFFSET_LOOP_OPEN_LO 0xf03000ff
-
-/* EPQ */
-#define        R367TER_EPQ     0xf031
-#define        F367TER_EPQ1    0xf03100ff
-
-/* EPQAUTO */
-#define        R367TER_EPQAUTO 0xf032
-#define        F367TER_EPQ2    0xf03200ff
-
-/* SYR_UPDATE */
-#define        R367TER_SYR_UPDATE      0xf033
-#define        F367TER_SYR_PROTV       0xf0330080
-#define        F367TER_SYR_PROTV_GAIN  0xf0330060
-#define        F367TER_SYR_FILTER      0xf0330010
-#define        F367TER_SYR_TRACK_THRES 0xf033000c
-
-/* CHPFREE */
-#define        R367TER_CHPFREE 0xf034
-#define        F367TER_CHP_FREE        0xf03400ff
-
-/* PPM_STATE_MAC */
-#define        R367TER_PPM_STATE_MAC   0xf035
-#define        F367TER_PPM_STATE_MACHINE_DECODER       0xf035003f
-
-/* INR_THRESHOLD */
-#define        R367TER_INR_THRESHOLD   0xf036
-#define        F367TER_INR_THRESH      0xf03600ff
-
-/* EPQ_TPS_ID_CELL */
-#define        R367TER_EPQ_TPS_ID_CELL 0xf037
-#define        F367TER_ENABLE_LGTH_TO_CF       0xf0370080
-#define        F367TER_DIS_TPS_RSVD    0xf0370040
-#define        F367TER_DIS_BCH 0xf0370020
-#define        F367TER_DIS_ID_CEL      0xf0370010
-#define        F367TER_TPS_ADJUST_SYM  0xf037000f
-
-/* EPQ_CFG */
-#define        R367TER_EPQ_CFG 0xf038
-#define        F367TER_EPQ_RANGE       0xf0380002
-#define        F367TER_EPQ_SOFT        0xf0380001
-
-/* EPQ_STATUS */
-#define        R367TER_EPQ_STATUS      0xf039
-#define        F367TER_SLOPE_INC       0xf03900fc
-#define        F367TER_TPS_FIELD       0xf0390003
-
-/* AUTORELOCK */
-#define        R367TER_AUTORELOCK      0xf03a
-#define        F367TER_BYPASS_BER_TEMPO        0xf03a0080
-#define        F367TER_BER_TEMPO       0xf03a0070
-#define        F367TER_BYPASS_COFDM_TEMPO      0xf03a0008
-#define        F367TER_COFDM_TEMPO     0xf03a0007
-
-/* BER_THR_VMSB */
-#define        R367TER_BER_THR_VMSB    0xf03b
-#define        F367TER_BER_THRESHOLD_HI        0xf03b00ff
-
-/* BER_THR_MSB */
-#define        R367TER_BER_THR_MSB     0xf03c
-#define        F367TER_BER_THRESHOLD_MID       0xf03c00ff
-
-/* BER_THR_LSB */
-#define        R367TER_BER_THR_LSB     0xf03d
-#define        F367TER_BER_THRESHOLD_LO        0xf03d00ff
-
-/* CCD */
-#define        R367TER_CCD     0xf03e
-#define        F367TER_CCD_DETECTED    0xf03e0080
-#define        F367TER_CCD_RESET       0xf03e0040
-#define        F367TER_CCD_THRESHOLD   0xf03e000f
-
-/* SPECTR_CFG */
-#define        R367TER_SPECTR_CFG      0xf03f
-#define        F367TER_SPECT_CFG       0xf03f0003
-
-/* CONSTMU_MSB */
-#define        R367TER_CONSTMU_MSB     0xf040
-#define        F367TER_CONSTMU_FREEZE  0xf0400080
-#define        F367TER_CONSTNU_FORCE_EN        0xf0400040
-#define        F367TER_CONST_MU_MSB    0xf040003f
-
-/* CONSTMU_LSB */
-#define        R367TER_CONSTMU_LSB     0xf041
-#define        F367TER_CONST_MU_LSB    0xf04100ff
-
-/* CONSTMU_MAX_MSB */
-#define        R367TER_CONSTMU_MAX_MSB 0xf042
-#define        F367TER_CONST_MU_MAX_MSB        0xf042003f
-
-/* CONSTMU_MAX_LSB */
-#define        R367TER_CONSTMU_MAX_LSB 0xf043
-#define        F367TER_CONST_MU_MAX_LSB        0xf04300ff
-
-/* ALPHANOISE */
-#define        R367TER_ALPHANOISE      0xf044
-#define        F367TER_USE_ALLFILTER   0xf0440080
-#define        F367TER_INTER_ON        0xf0440040
-#define        F367TER_ALPHA_NOISE     0xf044001f
-
-/* MAXGP_MSB */
-#define        R367TER_MAXGP_MSB       0xf045
-#define        F367TER_MUFILTER_LENGTH 0xf04500f0
-#define        F367TER_MAX_GP_MSB      0xf045000f
-
-/* MAXGP_LSB */
-#define        R367TER_MAXGP_LSB       0xf046
-#define        F367TER_MAX_GP_LSB      0xf04600ff
-
-/* ALPHAMSB */
-#define        R367TER_ALPHAMSB        0xf047
-#define        F367TER_CHC_DATARATE    0xf04700c0
-#define        F367TER_ALPHA_MSB       0xf047003f
-
-/* ALPHALSB */
-#define        R367TER_ALPHALSB        0xf048
-#define        F367TER_ALPHA_LSB       0xf04800ff
-
-/* PILOT_ACCU */
-#define        R367TER_PILOT_ACCU      0xf049
-#define        F367TER_USE_SCAT4ADDAPT 0xf0490080
-#define        F367TER_PILOT_ACC       0xf049001f
-
-/* PILOTMU_ACCU */
-#define        R367TER_PILOTMU_ACCU    0xf04a
-#define        F367TER_DISCARD_BAD_SP  0xf04a0080
-#define        F367TER_DISCARD_BAD_CP  0xf04a0040
-#define        F367TER_PILOT_MU_ACCU   0xf04a001f
-
-/* FILT_CHANNEL_EST */
-#define        R367TER_FILT_CHANNEL_EST        0xf04b
-#define        F367TER_USE_FILT_PILOT  0xf04b0080
-#define        F367TER_FILT_CHANNEL    0xf04b007f
-
-/* ALPHA_NOPISE_FREQ */
-#define        R367TER_ALPHA_NOPISE_FREQ       0xf04c
-#define        F367TER_NOISE_FREQ_FILT 0xf04c0040
-#define        F367TER_ALPHA_NOISE_FREQ        0xf04c003f
-
-/* RATIO_PILOT */
-#define        R367TER_RATIO_PILOT     0xf04d
-#define        F367TER_RATIO_MEAN_SP   0xf04d00f0
-#define        F367TER_RATIO_MEAN_CP   0xf04d000f
-
-/* CHC_CTL */
-#define        R367TER_CHC_CTL 0xf04e
-#define        F367TER_TRACK_EN        0xf04e0080
-#define        F367TER_NOISE_NORM_EN   0xf04e0040
-#define        F367TER_FORCE_CHC_RESET 0xf04e0020
-#define        F367TER_SHORT_TIME      0xf04e0010
-#define        F367TER_FORCE_STATE_EN  0xf04e0008
-#define        F367TER_FORCE_STATE     0xf04e0007
-
-/* EPQ_ADJUST */
-#define        R367TER_EPQ_ADJUST      0xf04f
-#define        F367TER_ADJUST_SCAT_IND 0xf04f00c0
-#define        F367TER_ONE_SYMBOL      0xf04f0010
-#define        F367TER_EPQ_DECAY       0xf04f000e
-#define        F367TER_HOLD_SLOPE      0xf04f0001
-
-/* EPQ_THRES */
-#define        R367TER_EPQ_THRES       0xf050
-#define        F367TER_EPQ_THR 0xf05000ff
-
-/* OMEGA_CTL */
-#define        R367TER_OMEGA_CTL       0xf051
-#define        F367TER_OMEGA_RST       0xf0510080
-#define        F367TER_FREEZE_OMEGA    0xf0510040
-#define        F367TER_OMEGA_SEL       0xf051003f
-
-/* GP_CTL */
-#define        R367TER_GP_CTL  0xf052
-#define        F367TER_CHC_STATE       0xf05200e0
-#define        F367TER_FREEZE_GP       0xf0520010
-#define        F367TER_GP_SEL  0xf052000f
-
-/* MUMSB */
-#define        R367TER_MUMSB   0xf053
-#define        F367TER_MU_MSB  0xf053007f
-
-/* MULSB */
-#define        R367TER_MULSB   0xf054
-#define        F367TER_MU_LSB  0xf05400ff
-
-/* GPMSB */
-#define        R367TER_GPMSB   0xf055
-#define        F367TER_CSI_THRESHOLD   0xf05500e0
-#define        F367TER_GP_MSB  0xf055000f
-
-/* GPLSB */
-#define        R367TER_GPLSB   0xf056
-#define        F367TER_GP_LSB  0xf05600ff
-
-/* OMEGAMSB */
-#define        R367TER_OMEGAMSB        0xf057
-#define        F367TER_OMEGA_MSB       0xf057007f
-
-/* OMEGALSB */
-#define        R367TER_OMEGALSB        0xf058
-#define        F367TER_OMEGA_LSB       0xf05800ff
-
-/* SCAT_NB */
-#define        R367TER_SCAT_NB 0xf059
-#define        F367TER_CHC_TEST        0xf05900f8
-#define        F367TER_SCAT_NUMB       0xf0590003
-
-/* CHC_DUMMY */
-#define        R367TER_CHC_DUMMY       0xf05a
-#define        F367TER_CHC_DUM 0xf05a00ff
-
-/* INC_CTL */
-#define        R367TER_INC_CTL 0xf05b
-#define        F367TER_INC_BYPASS      0xf05b0080
-#define        F367TER_INC_NDEPTH      0xf05b000c
-#define        F367TER_INC_MADEPTH     0xf05b0003
-
-/* INCTHRES_COR1 */
-#define        R367TER_INCTHRES_COR1   0xf05c
-#define        F367TER_INC_THRES_COR1  0xf05c00ff
-
-/* INCTHRES_COR2 */
-#define        R367TER_INCTHRES_COR2   0xf05d
-#define        F367TER_INC_THRES_COR2  0xf05d00ff
-
-/* INCTHRES_DET1 */
-#define        R367TER_INCTHRES_DET1   0xf05e
-#define        F367TER_INC_THRES_DET1  0xf05e003f
-
-/* INCTHRES_DET2 */
-#define        R367TER_INCTHRES_DET2   0xf05f
-#define        F367TER_INC_THRES_DET2  0xf05f003f
-
-/* IIR_CELLNB */
-#define        R367TER_IIR_CELLNB      0xf060
-#define        F367TER_NRST_IIR        0xf0600080
-#define        F367TER_IIR_CELL_NB     0xf0600007
-
-/* IIRCX_COEFF1_MSB */
-#define        R367TER_IIRCX_COEFF1_MSB        0xf061
-#define        F367TER_IIR_CX_COEFF1_MSB       0xf06100ff
-
-/* IIRCX_COEFF1_LSB */
-#define        R367TER_IIRCX_COEFF1_LSB        0xf062
-#define        F367TER_IIR_CX_COEFF1_LSB       0xf06200ff
-
-/* IIRCX_COEFF2_MSB */
-#define        R367TER_IIRCX_COEFF2_MSB        0xf063
-#define        F367TER_IIR_CX_COEFF2_MSB       0xf06300ff
-
-/* IIRCX_COEFF2_LSB */
-#define        R367TER_IIRCX_COEFF2_LSB        0xf064
-#define        F367TER_IIR_CX_COEFF2_LSB       0xf06400ff
-
-/* IIRCX_COEFF3_MSB */
-#define        R367TER_IIRCX_COEFF3_MSB        0xf065
-#define        F367TER_IIR_CX_COEFF3_MSB       0xf06500ff
-
-/* IIRCX_COEFF3_LSB */
-#define        R367TER_IIRCX_COEFF3_LSB        0xf066
-#define        F367TER_IIR_CX_COEFF3_LSB       0xf06600ff
-
-/* IIRCX_COEFF4_MSB */
-#define        R367TER_IIRCX_COEFF4_MSB        0xf067
-#define        F367TER_IIR_CX_COEFF4_MSB       0xf06700ff
-
-/* IIRCX_COEFF4_LSB */
-#define        R367TER_IIRCX_COEFF4_LSB        0xf068
-#define        F367TER_IIR_CX_COEFF4_LSB       0xf06800ff
-
-/* IIRCX_COEFF5_MSB */
-#define        R367TER_IIRCX_COEFF5_MSB        0xf069
-#define        F367TER_IIR_CX_COEFF5_MSB       0xf06900ff
-
-/* IIRCX_COEFF5_LSB */
-#define        R367TER_IIRCX_COEFF5_LSB        0xf06a
-#define        F367TER_IIR_CX_COEFF5_LSB       0xf06a00ff
-
-/* FEPATH_CFG */
-#define        R367TER_FEPATH_CFG      0xf06b
-#define        F367TER_DEMUX_SWAP      0xf06b0004
-#define        F367TER_DIGAGC_SWAP     0xf06b0002
-#define        F367TER_LONGPATH_IF     0xf06b0001
-
-/* PMC1_FUNC */
-#define        R367TER_PMC1_FUNC       0xf06c
-#define        F367TER_SOFT_RSTN       0xf06c0080
-#define        F367TER_PMC1_AVERAGE_TIME       0xf06c0078
-#define        F367TER_PMC1_WAIT_TIME  0xf06c0006
-#define        F367TER_PMC1_2N_SEL     0xf06c0001
-
-/* PMC1_FOR */
-#define        R367TER_PMC1_FOR        0xf06d
-#define        F367TER_PMC1_FORCE      0xf06d0080
-#define        F367TER_PMC1_FORCE_VALUE        0xf06d007c
-
-/* PMC2_FUNC */
-#define        R367TER_PMC2_FUNC       0xf06e
-#define        F367TER_PMC2_SOFT_STN   0xf06e0080
-#define        F367TER_PMC2_ACCU_TIME  0xf06e0070
-#define        F367TER_PMC2_CMDP_MN    0xf06e0008
-#define        F367TER_PMC2_SWAP       0xf06e0004
-
-/* STATUS_ERR_DA */
-#define        R367TER_STATUS_ERR_DA   0xf06f
-#define        F367TER_COM_USEGAINTRK  0xf06f0080
-#define        F367TER_COM_AGCLOCK     0xf06f0040
-#define        F367TER_AUT_AGCLOCK     0xf06f0020
-#define        F367TER_MIN_ERR_X_LSB   0xf06f000f
-
-/* DIG_AGC_R */
-#define        R367TER_DIG_AGC_R       0xf070
-#define        F367TER_COM_SOFT_RSTN   0xf0700080
-#define        F367TER_COM_AGC_ON      0xf0700040
-#define        F367TER_COM_EARLY       0xf0700020
-#define        F367TER_AUT_SOFT_RESETN 0xf0700010
-#define        F367TER_AUT_AGC_ON      0xf0700008
-#define        F367TER_AUT_EARLY       0xf0700004
-#define        F367TER_AUT_ROT_EN      0xf0700002
-#define        F367TER_LOCK_SOFT_RESETN        0xf0700001
-
-/* COMAGC_TARMSB */
-#define        R367TER_COMAGC_TARMSB   0xf071
-#define        F367TER_COM_AGC_TARGET_MSB      0xf07100ff
-
-/* COM_AGC_TAR_ENMODE */
-#define        R367TER_COM_AGC_TAR_ENMODE      0xf072
-#define        F367TER_COM_AGC_TARGET_LSB      0xf07200f0
-#define        F367TER_COM_ENMODE      0xf072000f
-
-/* COM_AGC_CFG */
-#define        R367TER_COM_AGC_CFG     0xf073
-#define        F367TER_COM_N   0xf07300f8
-#define        F367TER_COM_STABMODE    0xf0730006
-#define        F367TER_ERR_SEL 0xf0730001
-
-/* COM_AGC_GAIN1 */
-#define        R367TER_COM_AGC_GAIN1   0xf074
-#define        F367TER_COM_GAIN1aCK    0xf07400f0
-#define        F367TER_COM_GAIN1TRK    0xf074000f
-
-/* AUT_AGC_TARGETMSB */
-#define        R367TER_AUT_AGC_TARGETMSB       0xf075
-#define        F367TER_AUT_AGC_TARGET_MSB      0xf07500ff
-
-/* LOCK_DET_MSB */
-#define        R367TER_LOCK_DET_MSB    0xf076
-#define        F367TER_LOCK_DETECT_MSB 0xf07600ff
-
-/* AGCTAR_LOCK_LSBS */
-#define        R367TER_AGCTAR_LOCK_LSBS        0xf077
-#define        F367TER_AUT_AGC_TARGET_LSB      0xf07700f0
-#define        F367TER_LOCK_DETECT_LSB 0xf077000f
-
-/* AUT_GAIN_EN */
-#define        R367TER_AUT_GAIN_EN     0xf078
-#define        F367TER_AUT_ENMODE      0xf07800f0
-#define        F367TER_AUT_GAIN2       0xf078000f
-
-/* AUT_CFG */
-#define        R367TER_AUT_CFG 0xf079
-#define        F367TER_AUT_N   0xf07900f8
-#define        F367TER_INT_CHOICE      0xf0790006
-#define        F367TER_INT_LOAD        0xf0790001
-
-/* LOCKN */
-#define        R367TER_LOCKN   0xf07a
-#define        F367TER_LOCK_N  0xf07a00f8
-#define        F367TER_SEL_IQNTAR      0xf07a0004
-#define        F367TER_LOCK_DETECT_CHOICE      0xf07a0003
-
-/* INT_X_3 */
-#define        R367TER_INT_X_3 0xf07b
-#define        F367TER_INT_X3  0xf07b00ff
-
-/* INT_X_2 */
-#define        R367TER_INT_X_2 0xf07c
-#define        F367TER_INT_X2  0xf07c00ff
-
-/* INT_X_1 */
-#define        R367TER_INT_X_1 0xf07d
-#define        F367TER_INT_X1  0xf07d00ff
-
-/* INT_X_0 */
-#define        R367TER_INT_X_0 0xf07e
-#define        F367TER_INT_X0  0xf07e00ff
-
-/* MIN_ERRX_MSB */
-#define        R367TER_MIN_ERRX_MSB    0xf07f
-#define        F367TER_MIN_ERR_X_MSB   0xf07f00ff
-
-/* COR_CTL */
-#define        R367TER_COR_CTL 0xf080
-#define        F367TER_CORE_ACTIVE     0xf0800020
-#define        F367TER_HOLD    0xf0800010
-#define        F367TER_CORE_STATE_CTL  0xf080000f
-
-/* COR_STAT */
-#define        R367TER_COR_STAT        0xf081
-#define        F367TER_SCATT_LOCKED    0xf0810080
-#define        F367TER_TPS_LOCKED      0xf0810040
-#define        F367TER_SYR_LOCKED_COR  0xf0810020
-#define        F367TER_AGC_LOCKED_STAT 0xf0810010
-#define        F367TER_CORE_STATE_STAT 0xf081000f
-
-/* COR_INTEN */
-#define        R367TER_COR_INTEN       0xf082
-#define        F367TER_INTEN   0xf0820080
-#define        F367TER_INTEN_SYR       0xf0820020
-#define        F367TER_INTEN_FFT       0xf0820010
-#define        F367TER_INTEN_AGC       0xf0820008
-#define        F367TER_INTEN_TPS1      0xf0820004
-#define        F367TER_INTEN_TPS2      0xf0820002
-#define        F367TER_INTEN_TPS3      0xf0820001
-
-/* COR_INTSTAT */
-#define        R367TER_COR_INTSTAT     0xf083
-#define        F367TER_INTSTAT_SYR     0xf0830020
-#define        F367TER_INTSTAT_FFT     0xf0830010
-#define        F367TER_INTSAT_AGC      0xf0830008
-#define        F367TER_INTSTAT_TPS1    0xf0830004
-#define        F367TER_INTSTAT_TPS2    0xf0830002
-#define        F367TER_INTSTAT_TPS3    0xf0830001
-
-/* COR_MODEGUARD */
-#define        R367TER_COR_MODEGUARD   0xf084
-#define        F367TER_FORCE   0xf0840010
-#define        F367TER_MODE    0xf084000c
-#define        F367TER_GUARD   0xf0840003
-
-/* AGC_CTL */
-#define        R367TER_AGC_CTL 0xf085
-#define        F367TER_AGC_TIMING_FACTOR       0xf08500e0
-#define        F367TER_AGC_LAST        0xf0850010
-#define        F367TER_AGC_GAIN        0xf085000c
-#define        F367TER_AGC_NEG 0xf0850002
-#define        F367TER_AGC_SET 0xf0850001
-
-/* AGC_MANUAL1 */
-#define        R367TER_AGC_MANUAL1     0xf086
-#define        F367TER_AGC_VAL_LO      0xf08600ff
-
-/* AGC_MANUAL2 */
-#define        R367TER_AGC_MANUAL2     0xf087
-#define        F367TER_AGC_VAL_HI      0xf087000f
-
-/* AGC_TARG */
-#define        R367TER_AGC_TARG        0xf088
-#define        F367TER_AGC_TARGET      0xf08800ff
-
-/* AGC_GAIN1 */
-#define        R367TER_AGC_GAIN1       0xf089
-#define        F367TER_AGC_GAIN_LO     0xf08900ff
-
-/* AGC_GAIN2 */
-#define        R367TER_AGC_GAIN2       0xf08a
-#define        F367TER_AGC_LOCKED_GAIN2        0xf08a0010
-#define        F367TER_AGC_GAIN_HI     0xf08a000f
-
-/* RESERVED_1 */
-#define        R367TER_RESERVED_1      0xf08b
-#define        F367TER_RESERVED1       0xf08b00ff
-
-/* RESERVED_2 */
-#define        R367TER_RESERVED_2      0xf08c
-#define        F367TER_RESERVED2       0xf08c00ff
-
-/* RESERVED_3 */
-#define        R367TER_RESERVED_3      0xf08d
-#define        F367TER_RESERVED3       0xf08d00ff
-
-/* CAS_CTL */
-#define        R367TER_CAS_CTL 0xf08e
-#define        F367TER_CCS_ENABLE      0xf08e0080
-#define        F367TER_ACS_DISABLE     0xf08e0040
-#define        F367TER_DAGC_DIS        0xf08e0020
-#define        F367TER_DAGC_GAIN       0xf08e0018
-#define        F367TER_CCSMU   0xf08e0007
-
-/* CAS_FREQ */
-#define        R367TER_CAS_FREQ        0xf08f
-#define        F367TER_CCS_FREQ        0xf08f00ff
-
-/* CAS_DAGCGAIN */
-#define        R367TER_CAS_DAGCGAIN    0xf090
-#define        F367TER_CAS_DAGC_GAIN   0xf09000ff
-
-/* SYR_CTL */
-#define        R367TER_SYR_CTL 0xf091
-#define        F367TER_SICTH_ENABLE    0xf0910080
-#define        F367TER_LONG_ECHO       0xf0910078
-#define        F367TER_AUTO_LE_EN      0xf0910004
-#define        F367TER_SYR_BYPASS      0xf0910002
-#define        F367TER_SYR_TR_DIS      0xf0910001
-
-/* SYR_STAT */
-#define        R367TER_SYR_STAT        0xf092
-#define        F367TER_SYR_LOCKED_STAT 0xf0920010
-#define        F367TER_SYR_MODE        0xf092000c
-#define        F367TER_SYR_GUARD       0xf0920003
-
-/* SYR_NCO1 */
-#define        R367TER_SYR_NCO1        0xf093
-#define        F367TER_SYR_NCO_LO      0xf09300ff
-
-/* SYR_NCO2 */
-#define        R367TER_SYR_NCO2        0xf094
-#define        F367TER_SYR_NCO_HI      0xf094003f
-
-/* SYR_OFFSET1 */
-#define        R367TER_SYR_OFFSET1     0xf095
-#define        F367TER_SYR_OFFSET_LO   0xf09500ff
-
-/* SYR_OFFSET2 */
-#define        R367TER_SYR_OFFSET2     0xf096
-#define        F367TER_SYR_OFFSET_HI   0xf096003f
-
-/* FFT_CTL */
-#define        R367TER_FFT_CTL 0xf097
-#define        F367TER_SHIFT_FFT_TRIG  0xf0970018
-#define        F367TER_FFT_TRIGGER     0xf0970004
-#define        F367TER_FFT_MANUAL      0xf0970002
-#define        F367TER_IFFT_MODE       0xf0970001
-
-/* SCR_CTL */
-#define        R367TER_SCR_CTL 0xf098
-#define        F367TER_SYRADJDECAY     0xf0980070
-#define        F367TER_SCR_CPEDIS      0xf0980002
-#define        F367TER_SCR_DIS 0xf0980001
-
-/* PPM_CTL1 */
-#define        R367TER_PPM_CTL1        0xf099
-#define        F367TER_PPM_MAXFREQ     0xf0990030
-#define        F367TER_PPM_MAXTIM      0xf0990008
-#define        F367TER_PPM_INVSEL      0xf0990004
-#define        F367TER_PPM_SCATDIS     0xf0990002
-#define        F367TER_PPM_BYP 0xf0990001
-
-/* TRL_CTL */
-#define        R367TER_TRL_CTL 0xf09a
-#define        F367TER_TRL_NOMRATE_LSB 0xf09a0080
-#define        F367TER_TRL_GAIN_FACTOR 0xf09a0078
-#define        F367TER_TRL_LOOPGAIN    0xf09a0007
-
-/* TRL_NOMRATE1 */
-#define        R367TER_TRL_NOMRATE1    0xf09b
-#define        F367TER_TRL_NOMRATE_LO  0xf09b00ff
-
-/* TRL_NOMRATE2 */
-#define        R367TER_TRL_NOMRATE2    0xf09c
-#define        F367TER_TRL_NOMRATE_HI  0xf09c00ff
-
-/* TRL_TIME1 */
-#define        R367TER_TRL_TIME1       0xf09d
-#define        F367TER_TRL_TOFFSET_LO  0xf09d00ff
-
-/* TRL_TIME2 */
-#define        R367TER_TRL_TIME2       0xf09e
-#define        F367TER_TRL_TOFFSET_HI  0xf09e00ff
-
-/* CRL_CTL */
-#define        R367TER_CRL_CTL 0xf09f
-#define        F367TER_CRL_DIS 0xf09f0080
-#define        F367TER_CRL_GAIN_FACTOR 0xf09f0078
-#define        F367TER_CRL_LOOPGAIN    0xf09f0007
-
-/* CRL_FREQ1 */
-#define        R367TER_CRL_FREQ1       0xf0a0
-#define        F367TER_CRL_FOFFSET_LO  0xf0a000ff
-
-/* CRL_FREQ2 */
-#define        R367TER_CRL_FREQ2       0xf0a1
-#define        F367TER_CRL_FOFFSET_HI  0xf0a100ff
-
-/* CRL_FREQ3 */
-#define        R367TER_CRL_FREQ3       0xf0a2
-#define        F367TER_CRL_FOFFSET_VHI 0xf0a200ff
-
-/* TPS_SFRAME_CTL */
-#define        R367TER_TPS_SFRAME_CTL  0xf0a3
-#define        F367TER_TPS_SFRAME_SYNC 0xf0a30001
-
-/* CHC_SNR */
-#define        R367TER_CHC_SNR 0xf0a4
-#define        F367TER_CHCSNR  0xf0a400ff
-
-/* BDI_CTL */
-#define        R367TER_BDI_CTL 0xf0a5
-#define        F367TER_BDI_LPSEL       0xf0a50002
-#define        F367TER_BDI_SERIAL      0xf0a50001
-
-/* DMP_CTL */
-#define        R367TER_DMP_CTL 0xf0a6
-#define        F367TER_DMP_SCALING_FACTOR      0xf0a6001e
-#define        F367TER_DMP_SDDIS       0xf0a60001
-
-/* TPS_RCVD1 */
-#define        R367TER_TPS_RCVD1       0xf0a7
-#define        F367TER_TPS_CHANGE      0xf0a70040
-#define        F367TER_BCH_OK  0xf0a70020
-#define        F367TER_TPS_SYNC        0xf0a70010
-#define        F367TER_TPS_FRAME       0xf0a70003
-
-/* TPS_RCVD2 */
-#define        R367TER_TPS_RCVD2       0xf0a8
-#define        F367TER_TPS_HIERMODE    0xf0a80070
-#define        F367TER_TPS_CONST       0xf0a80003
-
-/* TPS_RCVD3 */
-#define        R367TER_TPS_RCVD3       0xf0a9
-#define        F367TER_TPS_LPCODE      0xf0a90070
-#define        F367TER_TPS_HPCODE      0xf0a90007
-
-/* TPS_RCVD4 */
-#define        R367TER_TPS_RCVD4       0xf0aa
-#define        F367TER_TPS_GUARD       0xf0aa0030
-#define        F367TER_TPS_MODE        0xf0aa0003
-
-/* TPS_ID_CELL1 */
-#define        R367TER_TPS_ID_CELL1    0xf0ab
-#define        F367TER_TPS_ID_CELL_LO  0xf0ab00ff
-
-/* TPS_ID_CELL2 */
-#define        R367TER_TPS_ID_CELL2    0xf0ac
-#define        F367TER_TPS_ID_CELL_HI  0xf0ac00ff
-
-/* TPS_RCVD5_SET1 */
-#define        R367TER_TPS_RCVD5_SET1  0xf0ad
-#define        F367TER_TPS_NA  0xf0ad00fC
-#define        F367TER_TPS_SETFRAME    0xf0ad0003
-
-/* TPS_SET2 */
-#define        R367TER_TPS_SET2        0xf0ae
-#define        F367TER_TPS_SETHIERMODE 0xf0ae0070
-#define        F367TER_TPS_SETCONST    0xf0ae0003
-
-/* TPS_SET3 */
-#define        R367TER_TPS_SET3        0xf0af
-#define        F367TER_TPS_SETLPCODE   0xf0af0070
-#define        F367TER_TPS_SETHPCODE   0xf0af0007
-
-/* TPS_CTL */
-#define        R367TER_TPS_CTL 0xf0b0
-#define        F367TER_TPS_IMM 0xf0b00004
-#define        F367TER_TPS_BCHDIS      0xf0b00002
-#define        F367TER_TPS_UPDDIS      0xf0b00001
-
-/* CTL_FFTOSNUM */
-#define        R367TER_CTL_FFTOSNUM    0xf0b1
-#define        F367TER_SYMBOL_NUMBER   0xf0b1007f
-
-/* TESTSELECT */
-#define        R367TER_TESTSELECT      0xf0b2
-#define        F367TER_TEST_SELECT     0xf0b2001f
-
-/* MSC_REV */
-#define        R367TER_MSC_REV 0xf0b3
-#define        F367TER_REV_NUMBER      0xf0b300ff
-
-/* PIR_CTL */
-#define        R367TER_PIR_CTL 0xf0b4
-#define        F367TER_FREEZE  0xf0b40001
-
-/* SNR_CARRIER1 */
-#define        R367TER_SNR_CARRIER1    0xf0b5
-#define        F367TER_SNR_CARRIER_LO  0xf0b500ff
-
-/* SNR_CARRIER2 */
-#define        R367TER_SNR_CARRIER2    0xf0b6
-#define        F367TER_MEAN    0xf0b600c0
-#define        F367TER_SNR_CARRIER_HI  0xf0b6001f
-
-/* PPM_CPAMP */
-#define        R367TER_PPM_CPAMP       0xf0b7
-#define        F367TER_PPM_CPC 0xf0b700ff
-
-/* TSM_AP0 */
-#define        R367TER_TSM_AP0 0xf0b8
-#define        F367TER_ADDRESS_BYTE_0  0xf0b800ff
-
-/* TSM_AP1 */
-#define        R367TER_TSM_AP1 0xf0b9
-#define        F367TER_ADDRESS_BYTE_1  0xf0b900ff
-
-/* TSM_AP2 */
-#define        R367TER_TSM_AP2 0xf0bA
-#define        F367TER_DATA_BYTE_0     0xf0ba00ff
-
-/* TSM_AP3 */
-#define        R367TER_TSM_AP3 0xf0bB
-#define        F367TER_DATA_BYTE_1     0xf0bb00ff
-
-/* TSM_AP4 */
-#define        R367TER_TSM_AP4 0xf0bC
-#define        F367TER_DATA_BYTE_2     0xf0bc00ff
-
-/* TSM_AP5 */
-#define        R367TER_TSM_AP5 0xf0bD
-#define        F367TER_DATA_BYTE_3     0xf0bd00ff
-
-/* TSM_AP6 */
-#define        R367TER_TSM_AP6 0xf0bE
-#define        F367TER_TSM_AP_6        0xf0be00ff
-
-/* TSM_AP7 */
-#define        R367TER_TSM_AP7 0xf0bF
-#define        F367TER_MEM_SELECT_BYTE 0xf0bf00ff
-
-/* TSTRES */
-#define        R367TER_TSTRES  0xf0c0
-#define        F367TER_FRES_DISPLAY    0xf0c00080
-#define        F367TER_FRES_FIFO_AD    0xf0c00020
-#define        F367TER_FRESRS  0xf0c00010
-#define        F367TER_FRESACS 0xf0c00008
-#define        F367TER_FRESFEC 0xf0c00004
-#define        F367TER_FRES_PRIF       0xf0c00002
-#define        F367TER_FRESCORE        0xf0c00001
-
-/* ANACTRL */
-#define        R367TER_ANACTRL 0xf0c1
-#define        F367TER_BYPASS_XTAL     0xf0c10040
-#define        F367TER_BYPASS_PLLXN    0xf0c1000c
-#define        F367TER_DIS_PAD_OSC     0xf0c10002
-#define        F367TER_STDBY_PLLXN     0xf0c10001
-
-/* TSTBUS */
-#define        R367TER_TSTBUS  0xf0c2
-#define        F367TER_TS_BYTE_CLK_INV 0xf0c20080
-#define        F367TER_CFG_IP  0xf0c20070
-#define        F367TER_CFG_TST 0xf0c2000f
-
-/* TSTRATE */
-#define        R367TER_TSTRATE 0xf0c6
-#define        F367TER_FORCEPHA        0xf0c60080
-#define        F367TER_FNEWPHA 0xf0c60010
-#define        F367TER_FROT90  0xf0c60008
-#define        F367TER_FR      0xf0c60007
-
-/* CONSTMODE */
-#define        R367TER_CONSTMODE       0xf0cb
-#define        F367TER_TST_PRIF        0xf0cb00e0
-#define        F367TER_CAR_TYPE        0xf0cb0018
-#define        F367TER_CONST_MODE      0xf0cb0003
-
-/* CONSTCARR1 */
-#define        R367TER_CONSTCARR1      0xf0cc
-#define        F367TER_CONST_CARR_LO   0xf0cc00ff
-
-/* CONSTCARR2 */
-#define        R367TER_CONSTCARR2      0xf0cd
-#define        F367TER_CONST_CARR_HI   0xf0cd001f
-
-/* ICONSTEL */
-#define        R367TER_ICONSTEL        0xf0ce
-#define        F367TER_PICONSTEL       0xf0ce00ff
-
-/* QCONSTEL */
-#define        R367TER_QCONSTEL        0xf0cf
-#define        F367TER_PQCONSTEL       0xf0cf00ff
-
-/* TSTBISTRES0 */
-#define        R367TER_TSTBISTRES0     0xf0d0
-#define        F367TER_BEND_PPM        0xf0d00080
-#define        F367TER_BBAD_PPM        0xf0d00040
-#define        F367TER_BEND_FFTW       0xf0d00020
-#define        F367TER_BBAD_FFTW       0xf0d00010
-#define        F367TER_BEND_FFT_BUF    0xf0d00008
-#define        F367TER_BBAD_FFT_BUF    0xf0d00004
-#define        F367TER_BEND_SYR        0xf0d00002
-#define        F367TER_BBAD_SYR        0xf0d00001
-
-/* TSTBISTRES1 */
-#define        R367TER_TSTBISTRES1     0xf0d1
-#define        F367TER_BEND_CHC_CP     0xf0d10080
-#define        F367TER_BBAD_CHC_CP     0xf0d10040
-#define        F367TER_BEND_CHCI       0xf0d10020
-#define        F367TER_BBAD_CHCI       0xf0d10010
-#define        F367TER_BEND_BDI        0xf0d10008
-#define        F367TER_BBAD_BDI        0xf0d10004
-#define        F367TER_BEND_SDI        0xf0d10002
-#define        F367TER_BBAD_SDI        0xf0d10001
-
-/* TSTBISTRES2 */
-#define        R367TER_TSTBISTRES2     0xf0d2
-#define        F367TER_BEND_CHC_INC    0xf0d20080
-#define        F367TER_BBAD_CHC_INC    0xf0d20040
-#define        F367TER_BEND_CHC_SPP    0xf0d20020
-#define        F367TER_BBAD_CHC_SPP    0xf0d20010
-#define        F367TER_BEND_CHC_CPP    0xf0d20008
-#define        F367TER_BBAD_CHC_CPP    0xf0d20004
-#define        F367TER_BEND_CHC_SP     0xf0d20002
-#define        F367TER_BBAD_CHC_SP     0xf0d20001
-
-/* TSTBISTRES3 */
-#define        R367TER_TSTBISTRES3     0xf0d3
-#define        F367TER_BEND_QAM        0xf0d30080
-#define        F367TER_BBAD_QAM        0xf0d30040
-#define        F367TER_BEND_SFEC_VIT   0xf0d30020
-#define        F367TER_BBAD_SFEC_VIT   0xf0d30010
-#define        F367TER_BEND_SFEC_DLINE 0xf0d30008
-#define        F367TER_BBAD_SFEC_DLINE 0xf0d30004
-#define        F367TER_BEND_SFEC_HW    0xf0d30002
-#define        F367TER_BBAD_SFEC_HW    0xf0d30001
-
-/* RF_AGC1 */
-#define        R367TER_RF_AGC1 0xf0d4
-#define        F367TER_RF_AGC1_LEVEL_HI        0xf0d400ff
-
-/* RF_AGC2 */
-#define        R367TER_RF_AGC2 0xf0d5
-#define        F367TER_REF_ADGP        0xf0d50080
-#define        F367TER_STDBY_ADCGP     0xf0d50020
-#define        F367TER_CHANNEL_SEL     0xf0d5001c
-#define        F367TER_RF_AGC1_LEVEL_LO        0xf0d50003
-
-/* ANADIGCTRL */
-#define        R367TER_ANADIGCTRL      0xf0d7
-#define        F367TER_SEL_CLKDEM      0xf0d70020
-#define        F367TER_EN_BUFFER_Q     0xf0d70010
-#define        F367TER_EN_BUFFER_I     0xf0d70008
-#define        F367TER_ADC_RIS_EGDE    0xf0d70004
-#define        F367TER_SGN_ADC 0xf0d70002
-#define        F367TER_SEL_AD12_SYNC   0xf0d70001
-
-/* PLLMDIV */
-#define        R367TER_PLLMDIV 0xf0d8
-#define        F367TER_PLL_MDIV        0xf0d800ff
-
-/* PLLNDIV */
-#define        R367TER_PLLNDIV 0xf0d9
-#define        F367TER_PLL_NDIV        0xf0d900ff
-
-/* PLLSETUP */
-#define        R367TER_PLLSETUP        0xf0dA
-#define        F367TER_PLL_PDIV        0xf0da0070
-#define        F367TER_PLL_KDIV        0xf0da000f
-
-/* DUAL_AD12 */
-#define        R367TER_DUAL_AD12       0xf0dB
-#define        F367TER_FS20M   0xf0db0020
-#define        F367TER_FS50M   0xf0db0010
-#define        F367TER_INMODe0 0xf0db0008
-#define        F367TER_POFFQ   0xf0db0004
-#define        F367TER_POFFI   0xf0db0002
-#define        F367TER_INMODE1 0xf0db0001
-
-/* TSTBIST */
-#define        R367TER_TSTBIST 0xf0dC
-#define        F367TER_TST_BYP_CLK     0xf0dc0080
-#define        F367TER_TST_GCLKENA_STD 0xf0dc0040
-#define        F367TER_TST_GCLKENA     0xf0dc0020
-#define        F367TER_TST_MEMBIST     0xf0dc001f
-
-/* PAD_COMP_CTRL */
-#define        R367TER_PAD_COMP_CTRL   0xf0dD
-#define        F367TER_COMPTQ  0xf0dd0010
-#define        F367TER_COMPEN  0xf0dd0008
-#define        F367TER_FREEZE2 0xf0dd0004
-#define        F367TER_SLEEP_INHBT     0xf0dd0002
-#define        F367TER_CHIP_SLEEP      0xf0dd0001
-
-/* PAD_COMP_WR */
-#define        R367TER_PAD_COMP_WR     0xf0de
-#define        F367TER_WR_ASRC 0xf0de007f
-
-/* PAD_COMP_RD */
-#define        R367TER_PAD_COMP_RD     0xf0df
-#define        F367TER_COMPOK  0xf0df0080
-#define        F367TER_RD_ASRC 0xf0df007f
-
-/* SYR_TARGET_FFTADJT_MSB */
-#define        R367TER_SYR_TARGET_FFTADJT_MSB  0xf100
-#define        F367TER_SYR_START       0xf1000080
-#define        F367TER_SYR_TARGET_FFTADJ_HI    0xf100000f
-
-/* SYR_TARGET_FFTADJT_LSB */
-#define        R367TER_SYR_TARGET_FFTADJT_LSB  0xf101
-#define        F367TER_SYR_TARGET_FFTADJ_LO    0xf10100ff
-
-/* SYR_TARGET_CHCADJT_MSB */
-#define        R367TER_SYR_TARGET_CHCADJT_MSB  0xf102
-#define        F367TER_SYR_TARGET_CHCADJ_HI    0xf102000f
-
-/* SYR_TARGET_CHCADJT_LSB */
-#define        R367TER_SYR_TARGET_CHCADJT_LSB  0xf103
-#define        F367TER_SYR_TARGET_CHCADJ_LO    0xf10300ff
-
-/* SYR_FLAG */
-#define        R367TER_SYR_FLAG        0xf104
-#define        F367TER_TRIG_FLG1       0xf1040080
-#define        F367TER_TRIG_FLG0       0xf1040040
-#define        F367TER_FFT_FLG1        0xf1040008
-#define        F367TER_FFT_FLG0        0xf1040004
-#define        F367TER_CHC_FLG1        0xf1040002
-#define        F367TER_CHC_FLG0        0xf1040001
-
-/* CRL_TARGET1 */
-#define        R367TER_CRL_TARGET1     0xf105
-#define        F367TER_CRL_START       0xf1050080
-#define        F367TER_CRL_TARGET_VHI  0xf105000f
-
-/* CRL_TARGET2 */
-#define        R367TER_CRL_TARGET2     0xf106
-#define        F367TER_CRL_TARGET_HI   0xf10600ff
-
-/* CRL_TARGET3 */
-#define        R367TER_CRL_TARGET3     0xf107
-#define        F367TER_CRL_TARGET_LO   0xf10700ff
-
-/* CRL_TARGET4 */
-#define        R367TER_CRL_TARGET4     0xf108
-#define        F367TER_CRL_TARGET_VLO  0xf10800ff
-
-/* CRL_FLAG */
-#define        R367TER_CRL_FLAG        0xf109
-#define        F367TER_CRL_FLAG1       0xf1090002
-#define        F367TER_CRL_FLAG0       0xf1090001
-
-/* TRL_TARGET1 */
-#define        R367TER_TRL_TARGET1     0xf10a
-#define        F367TER_TRL_TARGET_HI   0xf10a00ff
-
-/* TRL_TARGET2 */
-#define        R367TER_TRL_TARGET2     0xf10b
-#define        F367TER_TRL_TARGET_LO   0xf10b00ff
-
-/* TRL_CHC */
-#define        R367TER_TRL_CHC 0xf10c
-#define        F367TER_TRL_START       0xf10c0080
-#define        F367TER_CHC_START       0xf10c0040
-#define        F367TER_TRL_FLAG1       0xf10c0002
-#define        F367TER_TRL_FLAG0       0xf10c0001
-
-/* CHC_SNR_TARG */
-#define        R367TER_CHC_SNR_TARG    0xf10d
-#define        F367TER_CHC_SNR_TARGET  0xf10d00ff
-
-/* TOP_TRACK */
-#define        R367TER_TOP_TRACK       0xf10e
-#define        F367TER_TOP_START       0xf10e0080
-#define        F367TER_FIRST_FLAG      0xf10e0070
-#define        F367TER_TOP_FLAG1       0xf10e0008
-#define        F367TER_TOP_FLAG0       0xf10e0004
-#define        F367TER_CHC_FLAG1       0xf10e0002
-#define        F367TER_CHC_FLAG0       0xf10e0001
-
-/* TRACKER_FREE1 */
-#define        R367TER_TRACKER_FREE1   0xf10f
-#define        F367TER_TRACKER_FREE_1  0xf10f00ff
-
-/* ERROR_CRL1 */
-#define        R367TER_ERROR_CRL1      0xf110
-#define        F367TER_ERROR_CRL_VHI   0xf11000ff
-
-/* ERROR_CRL2 */
-#define        R367TER_ERROR_CRL2      0xf111
-#define        F367TER_ERROR_CRL_HI    0xf11100ff
-
-/* ERROR_CRL3 */
-#define        R367TER_ERROR_CRL3      0xf112
-#define        F367TER_ERROR_CRL_LOI   0xf11200ff
-
-/* ERROR_CRL4 */
-#define        R367TER_ERROR_CRL4      0xf113
-#define        F367TER_ERROR_CRL_VLO   0xf11300ff
-
-/* DEC_NCO1 */
-#define        R367TER_DEC_NCO1        0xf114
-#define        F367TER_DEC_NCO_VHI     0xf11400ff
-
-/* DEC_NCO2 */
-#define        R367TER_DEC_NCO2        0xf115
-#define        F367TER_DEC_NCO_HI      0xf11500ff
-
-/* DEC_NCO3 */
-#define        R367TER_DEC_NCO3        0xf116
-#define        F367TER_DEC_NCO_LO      0xf11600ff
-
-/* SNR */
-#define        R367TER_SNR     0xf117
-#define        F367TER_SNRATIO 0xf11700ff
-
-/* SYR_FFTADJ1 */
-#define        R367TER_SYR_FFTADJ1     0xf118
-#define        F367TER_SYR_FFTADJ_HI   0xf11800ff
-
-/* SYR_FFTADJ2 */
-#define        R367TER_SYR_FFTADJ2     0xf119
-#define        F367TER_SYR_FFTADJ_LO   0xf11900ff
-
-/* SYR_CHCADJ1 */
-#define        R367TER_SYR_CHCADJ1     0xf11a
-#define        F367TER_SYR_CHCADJ_HI   0xf11a00ff
-
-/* SYR_CHCADJ2 */
-#define        R367TER_SYR_CHCADJ2     0xf11b
-#define        F367TER_SYR_CHCADJ_LO   0xf11b00ff
-
-/* SYR_OFF */
-#define        R367TER_SYR_OFF 0xf11c
-#define        F367TER_SYR_OFFSET      0xf11c00ff
-
-/* PPM_OFFSET1 */
-#define        R367TER_PPM_OFFSET1     0xf11d
-#define        F367TER_PPM_OFFSET_HI   0xf11d00ff
-
-/* PPM_OFFSET2 */
-#define        R367TER_PPM_OFFSET2     0xf11e
-#define        F367TER_PPM_OFFSET_LO   0xf11e00ff
-
-/* TRACKER_FREE2 */
-#define        R367TER_TRACKER_FREE2   0xf11f
-#define        F367TER_TRACKER_FREE_2  0xf11f00ff
-
-/* DEBG_LT10 */
-#define        R367TER_DEBG_LT10       0xf120
-#define        F367TER_DEBUG_LT10      0xf12000ff
-
-/* DEBG_LT11 */
-#define        R367TER_DEBG_LT11       0xf121
-#define        F367TER_DEBUG_LT11      0xf12100ff
-
-/* DEBG_LT12 */
-#define        R367TER_DEBG_LT12       0xf122
-#define        F367TER_DEBUG_LT12      0xf12200ff
-
-/* DEBG_LT13 */
-#define        R367TER_DEBG_LT13       0xf123
-#define        F367TER_DEBUG_LT13      0xf12300ff
-
-/* DEBG_LT14 */
-#define        R367TER_DEBG_LT14       0xf124
-#define        F367TER_DEBUG_LT14      0xf12400ff
-
-/* DEBG_LT15 */
-#define        R367TER_DEBG_LT15       0xf125
-#define        F367TER_DEBUG_LT15      0xf12500ff
-
-/* DEBG_LT16 */
-#define        R367TER_DEBG_LT16       0xf126
-#define        F367TER_DEBUG_LT16      0xf12600ff
-
-/* DEBG_LT17 */
-#define        R367TER_DEBG_LT17       0xf127
-#define        F367TER_DEBUG_LT17      0xf12700ff
-
-/* DEBG_LT18 */
-#define        R367TER_DEBG_LT18       0xf128
-#define        F367TER_DEBUG_LT18      0xf12800ff
-
-/* DEBG_LT19 */
-#define        R367TER_DEBG_LT19       0xf129
-#define        F367TER_DEBUG_LT19      0xf12900ff
-
-/* DEBG_LT1a */
-#define        R367TER_DEBG_LT1A       0xf12a
-#define        F367TER_DEBUG_LT1A      0xf12a00ff
-
-/* DEBG_LT1b */
-#define        R367TER_DEBG_LT1B       0xf12b
-#define        F367TER_DEBUG_LT1B      0xf12b00ff
-
-/* DEBG_LT1c */
-#define        R367TER_DEBG_LT1C       0xf12c
-#define        F367TER_DEBUG_LT1C      0xf12c00ff
-
-/* DEBG_LT1D */
-#define        R367TER_DEBG_LT1D       0xf12d
-#define        F367TER_DEBUG_LT1D      0xf12d00ff
-
-/* DEBG_LT1E */
-#define        R367TER_DEBG_LT1E       0xf12e
-#define        F367TER_DEBUG_LT1E      0xf12e00ff
-
-/* DEBG_LT1F */
-#define        R367TER_DEBG_LT1F       0xf12f
-#define        F367TER_DEBUG_LT1F      0xf12f00ff
-
-/* RCCFGH */
-#define        R367TER_RCCFGH  0xf200
-#define        F367TER_TSRCFIFO_DVBCI  0xf2000080
-#define        F367TER_TSRCFIFO_SERIAL 0xf2000040
-#define        F367TER_TSRCFIFO_DISABLE        0xf2000020
-#define        F367TER_TSFIFO_2TORC    0xf2000010
-#define        F367TER_TSRCFIFO_HSGNLOUT       0xf2000008
-#define        F367TER_TSRCFIFO_ERRMODE        0xf2000006
-#define        F367TER_RCCFGH_0        0xf2000001
-
-/* RCCFGM */
-#define        R367TER_RCCFGM  0xf201
-#define        F367TER_TSRCFIFO_MANSPEED       0xf20100c0
-#define        F367TER_TSRCFIFO_PERMDATA       0xf2010020
-#define        F367TER_TSRCFIFO_NONEWSGNL      0xf2010010
-#define        F367TER_RCBYTE_OVERSAMPLING     0xf201000e
-#define        F367TER_TSRCFIFO_INVDATA        0xf2010001
-
-/* RCCFGL */
-#define        R367TER_RCCFGL  0xf202
-#define        F367TER_TSRCFIFO_BCLKDEL1cK     0xf20200c0
-#define        F367TER_RCCFGL_5        0xf2020020
-#define        F367TER_TSRCFIFO_DUTY50 0xf2020010
-#define        F367TER_TSRCFIFO_NSGNL2dATA     0xf2020008
-#define        F367TER_TSRCFIFO_DISSERMUX      0xf2020004
-#define        F367TER_RCCFGL_1        0xf2020002
-#define        F367TER_TSRCFIFO_STOPCKDIS      0xf2020001
-
-/* RCINSDELH */
-#define        R367TER_RCINSDELH       0xf203
-#define        F367TER_TSRCDEL_SYNCBYTE        0xf2030080
-#define        F367TER_TSRCDEL_XXHEADER        0xf2030040
-#define        F367TER_TSRCDEL_BBHEADER        0xf2030020
-#define        F367TER_TSRCDEL_DATAFIELD       0xf2030010
-#define        F367TER_TSRCINSDEL_ISCR 0xf2030008
-#define        F367TER_TSRCINSDEL_NPD  0xf2030004
-#define        F367TER_TSRCINSDEL_RSPARITY     0xf2030002
-#define        F367TER_TSRCINSDEL_CRC8 0xf2030001
-
-/* RCINSDELM */
-#define        R367TER_RCINSDELM       0xf204
-#define        F367TER_TSRCINS_BBPADDING       0xf2040080
-#define        F367TER_TSRCINS_BCHFEC  0xf2040040
-#define        F367TER_TSRCINS_LDPCFEC 0xf2040020
-#define        F367TER_TSRCINS_EMODCOD 0xf2040010
-#define        F367TER_TSRCINS_TOKEN   0xf2040008
-#define        F367TER_TSRCINS_XXXERR  0xf2040004
-#define        F367TER_TSRCINS_MATYPE  0xf2040002
-#define        F367TER_TSRCINS_UPL     0xf2040001
-
-/* RCINSDELL */
-#define        R367TER_RCINSDELL       0xf205
-#define        F367TER_TSRCINS_DFL     0xf2050080
-#define        F367TER_TSRCINS_SYNCD   0xf2050040
-#define        F367TER_TSRCINS_BLOCLEN 0xf2050020
-#define        F367TER_TSRCINS_SIGPCOUNT       0xf2050010
-#define        F367TER_TSRCINS_FIFO    0xf2050008
-#define        F367TER_TSRCINS_REALPACK        0xf2050004
-#define        F367TER_TSRCINS_TSCONFIG        0xf2050002
-#define        F367TER_TSRCINS_LATENCY 0xf2050001
-
-/* RCSTATUS */
-#define        R367TER_RCSTATUS        0xf206
-#define        F367TER_TSRCFIFO_LINEOK 0xf2060080
-#define        F367TER_TSRCFIFO_ERROR  0xf2060040
-#define        F367TER_TSRCFIFO_DATA7  0xf2060020
-#define        F367TER_RCSTATUS_4      0xf2060010
-#define        F367TER_TSRCFIFO_DEMODSEL       0xf2060008
-#define        F367TER_TSRC1FIFOSPEED_STORE    0xf2060004
-#define        F367TER_RCSTATUS_1      0xf2060002
-#define        F367TER_TSRCSERIAL_IMPOSSIBLE   0xf2060001
-
-/* RCSPEED */
-#define        R367TER_RCSPEED 0xf207
-#define        F367TER_TSRCFIFO_OUTSPEED       0xf20700ff
-
-/* RCDEBUGM */
-#define        R367TER_RCDEBUGM        0xf208
-#define        F367TER_SD_UNSYNC       0xf2080080
-#define        F367TER_ULFLOCK_DETECTM 0xf2080040
-#define        F367TER_SUL_SELECTOS    0xf2080020
-#define        F367TER_DILUL_NOSCRBLE  0xf2080010
-#define        F367TER_NUL_SCRB        0xf2080008
-#define        F367TER_UL_SCRB 0xf2080004
-#define        F367TER_SCRAULBAD       0xf2080002
-#define        F367TER_SCRAUL_UNSYNC   0xf2080001
-
-/* RCDEBUGL */
-#define        R367TER_RCDEBUGL        0xf209
-#define        F367TER_RS_ERR  0xf2090080
-#define        F367TER_LLFLOCK_DETECTM 0xf2090040
-#define        F367TER_NOT_SUL_SELECTOS        0xf2090020
-#define        F367TER_DILLL_NOSCRBLE  0xf2090010
-#define        F367TER_NLL_SCRB        0xf2090008
-#define        F367TER_LL_SCRB 0xf2090004
-#define        F367TER_SCRALLBAD       0xf2090002
-#define        F367TER_SCRALL_UNSYNC   0xf2090001
-
-/* RCOBSCFG */
-#define        R367TER_RCOBSCFG        0xf20a
-#define        F367TER_TSRCFIFO_OBSCFG 0xf20a00ff
-
-/* RCOBSM */
-#define        R367TER_RCOBSM  0xf20b
-#define        F367TER_TSRCFIFO_OBSDATA_HI     0xf20b00ff
-
-/* RCOBSL */
-#define        R367TER_RCOBSL  0xf20c
-#define        F367TER_TSRCFIFO_OBSDATA_LO     0xf20c00ff
-
-/* RCFECSPY */
-#define        R367TER_RCFECSPY        0xf210
-#define        F367TER_SPYRC_ENABLE    0xf2100080
-#define        F367TER_RCNO_SYNCBYTE   0xf2100040
-#define        F367TER_RCSERIAL_MODE   0xf2100020
-#define        F367TER_RCUNUSUAL_PACKET        0xf2100010
-#define        F367TER_BERRCMETER_DATAMODE     0xf210000c
-#define        F367TER_BERRCMETER_LMODE        0xf2100002
-#define        F367TER_BERRCMETER_RESET        0xf2100001
-
-/* RCFSPYCFG */
-#define        R367TER_RCFSPYCFG       0xf211
-#define        F367TER_FECSPYRC_INPUT  0xf21100c0
-#define        F367TER_RCRST_ON_ERROR  0xf2110020
-#define        F367TER_RCONE_SHOT      0xf2110010
-#define        F367TER_RCI2C_MODE      0xf211000c
-#define        F367TER_SPYRC_HSTERESIS 0xf2110003
-
-/* RCFSPYDATA */
-#define        R367TER_RCFSPYDATA      0xf212
-#define        F367TER_SPYRC_STUFFING  0xf2120080
-#define        F367TER_RCNOERR_PKTJITTER       0xf2120040
-#define        F367TER_SPYRC_CNULLPKT  0xf2120020
-#define        F367TER_SPYRC_OUTDATA_MODE      0xf212001f
-
-/* RCFSPYOUT */
-#define        R367TER_RCFSPYOUT       0xf213
-#define        F367TER_FSPYRC_DIRECT   0xf2130080
-#define        F367TER_RCFSPYOUT_6     0xf2130040
-#define        F367TER_SPYRC_OUTDATA_BUS       0xf2130038
-#define        F367TER_RCSTUFF_MODE    0xf2130007
-
-/* RCFSTATUS */
-#define        R367TER_RCFSTATUS       0xf214
-#define        F367TER_SPYRC_ENDSIM    0xf2140080
-#define        F367TER_RCVALID_SIM     0xf2140040
-#define        F367TER_RCFOUND_SIGNAL  0xf2140020
-#define        F367TER_RCDSS_SYNCBYTE  0xf2140010
-#define        F367TER_RCRESULT_STATE  0xf214000f
-
-/* RCFGOODPACK */
-#define        R367TER_RCFGOODPACK     0xf215
-#define        F367TER_RCGOOD_PACKET   0xf21500ff
-
-/* RCFPACKCNT */
-#define        R367TER_RCFPACKCNT      0xf216
-#define        F367TER_RCPACKET_COUNTER        0xf21600ff
-
-/* RCFSPYMISC */
-#define        R367TER_RCFSPYMISC      0xf217
-#define        F367TER_RCLABEL_COUNTER 0xf21700ff
-
-/* RCFBERCPT4 */
-#define        R367TER_RCFBERCPT4      0xf218
-#define        F367TER_FBERRCMETER_CPT_MMMMSB  0xf21800ff
-
-/* RCFBERCPT3 */
-#define        R367TER_RCFBERCPT3      0xf219
-#define        F367TER_FBERRCMETER_CPT_MMMSB   0xf21900ff
-
-/* RCFBERCPT2 */
-#define        R367TER_RCFBERCPT2      0xf21a
-#define        F367TER_FBERRCMETER_CPT_MMSB    0xf21a00ff
-
-/* RCFBERCPT1 */
-#define        R367TER_RCFBERCPT1      0xf21b
-#define        F367TER_FBERRCMETER_CPT_MSB     0xf21b00ff
-
-/* RCFBERCPT0 */
-#define        R367TER_RCFBERCPT0      0xf21c
-#define        F367TER_FBERRCMETER_CPT_LSB     0xf21c00ff
-
-/* RCFBERERR2 */
-#define        R367TER_RCFBERERR2      0xf21d
-#define        F367TER_FBERRCMETER_ERR_HI      0xf21d00ff
-
-/* RCFBERERR1 */
-#define        R367TER_RCFBERERR1      0xf21e
-#define        F367TER_FBERRCMETER_ERR 0xf21e00ff
-
-/* RCFBERERR0 */
-#define        R367TER_RCFBERERR0      0xf21f
-#define        F367TER_FBERRCMETER_ERR_LO      0xf21f00ff
-
-/* RCFSTATESM */
-#define        R367TER_RCFSTATESM      0xf220
-#define        F367TER_RCRSTATE_F      0xf2200080
-#define        F367TER_RCRSTATE_E      0xf2200040
-#define        F367TER_RCRSTATE_D      0xf2200020
-#define        F367TER_RCRSTATE_C      0xf2200010
-#define        F367TER_RCRSTATE_B      0xf2200008
-#define        F367TER_RCRSTATE_A      0xf2200004
-#define        F367TER_RCRSTATE_9      0xf2200002
-#define        F367TER_RCRSTATE_8      0xf2200001
-
-/* RCFSTATESL */
-#define        R367TER_RCFSTATESL      0xf221
-#define        F367TER_RCRSTATE_7      0xf2210080
-#define        F367TER_RCRSTATE_6      0xf2210040
-#define        F367TER_RCRSTATE_5      0xf2210020
-#define        F367TER_RCRSTATE_4      0xf2210010
-#define        F367TER_RCRSTATE_3      0xf2210008
-#define        F367TER_RCRSTATE_2      0xf2210004
-#define        F367TER_RCRSTATE_1      0xf2210002
-#define        F367TER_RCRSTATE_0      0xf2210001
-
-/* RCFSPYBER */
-#define        R367TER_RCFSPYBER       0xf222
-#define        F367TER_RCFSPYBER_7     0xf2220080
-#define        F367TER_SPYRCOBS_XORREAD        0xf2220040
-#define        F367TER_FSPYRCBER_OBSMODE       0xf2220020
-#define        F367TER_FSPYRCBER_SYNCBYT       0xf2220010
-#define        F367TER_FSPYRCBER_UNSYNC        0xf2220008
-#define        F367TER_FSPYRCBER_CTIME 0xf2220007
-
-/* RCFSPYDISTM */
-#define        R367TER_RCFSPYDISTM     0xf223
-#define        F367TER_RCPKTTIME_DISTANCE_HI   0xf22300ff
-
-/* RCFSPYDISTL */
-#define        R367TER_RCFSPYDISTL     0xf224
-#define        F367TER_RCPKTTIME_DISTANCE_LO   0xf22400ff
-
-/* RCFSPYOBS7 */
-#define        R367TER_RCFSPYOBS7      0xf228
-#define        F367TER_RCSPYOBS_SPYFAIL        0xf2280080
-#define        F367TER_RCSPYOBS_SPYFAIL1       0xf2280040
-#define        F367TER_RCSPYOBS_ERROR  0xf2280020
-#define        F367TER_RCSPYOBS_STROUT 0xf2280010
-#define        F367TER_RCSPYOBS_RESULTSTATE1   0xf228000f
-
-/* RCFSPYOBS6 */
-#define        R367TER_RCFSPYOBS6      0xf229
-#define        F367TER_RCSPYOBS_RESULTSTATe0   0xf22900f0
-#define        F367TER_RCSPYOBS_RESULTSTATEM1  0xf229000f
-
-/* RCFSPYOBS5 */
-#define        R367TER_RCFSPYOBS5      0xf22a
-#define        F367TER_RCSPYOBS_BYTEOFPACKET1  0xf22a00ff
-
-/* RCFSPYOBS4 */
-#define        R367TER_RCFSPYOBS4      0xf22b
-#define        F367TER_RCSPYOBS_BYTEVALUE1     0xf22b00ff
-
-/* RCFSPYOBS3 */
-#define        R367TER_RCFSPYOBS3      0xf22c
-#define        F367TER_RCSPYOBS_DATA1  0xf22c00ff
-
-/* RCFSPYOBS2 */
-#define        R367TER_RCFSPYOBS2      0xf22d
-#define        F367TER_RCSPYOBS_DATa0  0xf22d00ff
-
-/* RCFSPYOBS1 */
-#define        R367TER_RCFSPYOBS1      0xf22e
-#define        F367TER_RCSPYOBS_DATAM1 0xf22e00ff
-
-/* RCFSPYOBS0 */
-#define        R367TER_RCFSPYOBS0      0xf22f
-#define        F367TER_RCSPYOBS_DATAM2 0xf22f00ff
-
-/* TSGENERAL */
-#define        R367TER_TSGENERAL       0xf230
-#define        F367TER_TSGENERAL_7     0xf2300080
-#define        F367TER_TSGENERAL_6     0xf2300040
-#define        F367TER_TSFIFO_BCLK1aLL 0xf2300020
-#define        F367TER_TSGENERAL_4     0xf2300010
-#define        F367TER_MUXSTREAM_OUTMODE       0xf2300008
-#define        F367TER_TSFIFO_PERMPARAL        0xf2300006
-#define        F367TER_RST_REEDSOLO    0xf2300001
-
-/* RC1SPEED */
-#define        R367TER_RC1SPEED        0xf231
-#define        F367TER_TSRCFIFO1_OUTSPEED      0xf23100ff
-
-/* TSGSTATUS */
-#define        R367TER_TSGSTATUS       0xf232
-#define        F367TER_TSGSTATUS_7     0xf2320080
-#define        F367TER_TSGSTATUS_6     0xf2320040
-#define        F367TER_RSMEM_FULL      0xf2320020
-#define        F367TER_RS_MULTCALC     0xf2320010
-#define        F367TER_RSIN_OVERTIME   0xf2320008
-#define        F367TER_TSFIFO3_DEMODSEL        0xf2320004
-#define        F367TER_TSFIFO2_DEMODSEL        0xf2320002
-#define        F367TER_TSFIFO1_DEMODSEL        0xf2320001
-
-
-/* FECM */
-#define        R367TER_FECM    0xf233
-#define        F367TER_DSS_DVB 0xf2330080
-#define        F367TER_DEMOD_BYPASS    0xf2330040
-#define        F367TER_CMP_SLOWMODE    0xf2330020
-#define        F367TER_DSS_SRCH        0xf2330010
-#define        F367TER_FECM_3  0xf2330008
-#define        F367TER_DIFF_MODEVIT    0xf2330004
-#define        F367TER_SYNCVIT 0xf2330002
-#define        F367TER_I2CSYM  0xf2330001
-
-/* VTH12 */
-#define        R367TER_VTH12   0xf234
-#define        F367TER_VTH_12  0xf23400ff
-
-/* VTH23 */
-#define        R367TER_VTH23   0xf235
-#define        F367TER_VTH_23  0xf23500ff
-
-/* VTH34 */
-#define        R367TER_VTH34   0xf236
-#define        F367TER_VTH_34  0xf23600ff
-
-/* VTH56 */
-#define        R367TER_VTH56   0xf237
-#define        F367TER_VTH_56  0xf23700ff
-
-/* VTH67 */
-#define        R367TER_VTH67   0xf238
-#define        F367TER_VTH_67  0xf23800ff
-
-/* VTH78 */
-#define        R367TER_VTH78   0xf239
-#define        F367TER_VTH_78  0xf23900ff
-
-/* VITCURPUN */
-#define        R367TER_VITCURPUN       0xf23a
-#define        F367TER_VIT_MAPPING     0xf23a00e0
-#define        F367TER_VIT_CURPUN      0xf23a001f
-
-/* VERROR */
-#define        R367TER_VERROR  0xf23b
-#define        F367TER_REGERR_VIT      0xf23b00ff
-
-/* PRVIT */
-#define        R367TER_PRVIT   0xf23c
-#define        F367TER_PRVIT_7 0xf23c0080
-#define        F367TER_DIS_VTHLOCK     0xf23c0040
-#define        F367TER_E7_8VIT 0xf23c0020
-#define        F367TER_E6_7VIT 0xf23c0010
-#define        F367TER_E5_6VIT 0xf23c0008
-#define        F367TER_E3_4VIT 0xf23c0004
-#define        F367TER_E2_3VIT 0xf23c0002
-#define        F367TER_E1_2VIT 0xf23c0001
-
-/* VAVSRVIT */
-#define        R367TER_VAVSRVIT        0xf23d
-#define        F367TER_AMVIT   0xf23d0080
-#define        F367TER_FROZENVIT       0xf23d0040
-#define        F367TER_SNVIT   0xf23d0030
-#define        F367TER_TOVVIT  0xf23d000c
-#define        F367TER_HYPVIT  0xf23d0003
-
-/* VSTATUSVIT */
-#define        R367TER_VSTATUSVIT      0xf23e
-#define        F367TER_VITERBI_ON      0xf23e0080
-#define        F367TER_END_LOOPVIT     0xf23e0040
-#define        F367TER_VITERBI_DEPRF   0xf23e0020
-#define        F367TER_PRFVIT  0xf23e0010
-#define        F367TER_LOCKEDVIT       0xf23e0008
-#define        F367TER_VITERBI_DELOCK  0xf23e0004
-#define        F367TER_VIT_DEMODSEL    0xf23e0002
-#define        F367TER_VITERBI_COMPOUT 0xf23e0001
-
-/* VTHINUSE */
-#define        R367TER_VTHINUSE        0xf23f
-#define        F367TER_VIT_INUSE       0xf23f00ff
-
-/* KDIV12 */
-#define        R367TER_KDIV12  0xf240
-#define        F367TER_KDIV12_MANUAL   0xf2400080
-#define        F367TER_K_DIVIDER_12    0xf240007f
-
-/* KDIV23 */
-#define        R367TER_KDIV23  0xf241
-#define        F367TER_KDIV23_MANUAL   0xf2410080
-#define        F367TER_K_DIVIDER_23    0xf241007f
-
-/* KDIV34 */
-#define        R367TER_KDIV34  0xf242
-#define        F367TER_KDIV34_MANUAL   0xf2420080
-#define        F367TER_K_DIVIDER_34    0xf242007f
-
-/* KDIV56 */
-#define        R367TER_KDIV56  0xf243
-#define        F367TER_KDIV56_MANUAL   0xf2430080
-#define        F367TER_K_DIVIDER_56    0xf243007f
-
-/* KDIV67 */
-#define        R367TER_KDIV67  0xf244
-#define        F367TER_KDIV67_MANUAL   0xf2440080
-#define        F367TER_K_DIVIDER_67    0xf244007f
-
-/* KDIV78 */
-#define        R367TER_KDIV78  0xf245
-#define        F367TER_KDIV78_MANUAL   0xf2450080
-#define        F367TER_K_DIVIDER_78    0xf245007f
-
-/* SIGPOWER */
-#define        R367TER_SIGPOWER        0xf246
-#define        F367TER_SIGPOWER_MANUAL 0xf2460080
-#define        F367TER_SIG_POWER       0xf246007f
-
-/* DEMAPVIT */
-#define        R367TER_DEMAPVIT        0xf247
-#define        F367TER_DEMAPVIT_7      0xf2470080
-#define        F367TER_K_DIVIDER_VIT   0xf247007f
-
-/* VITSCALE */
-#define        R367TER_VITSCALE        0xf248
-#define        F367TER_NVTH_NOSRANGE   0xf2480080
-#define        F367TER_VERROR_MAXMODE  0xf2480040
-#define        F367TER_KDIV_MODE       0xf2480030
-#define        F367TER_NSLOWSN_LOCKED  0xf2480008
-#define        F367TER_DELOCK_PRFLOSS  0xf2480004
-#define        F367TER_DIS_RSFLOCK     0xf2480002
-#define        F367TER_VITSCALE_0      0xf2480001
-
-/* FFEC1PRG */
-#define        R367TER_FFEC1PRG        0xf249
-#define        F367TER_FDSS_DVB        0xf2490080
-#define        F367TER_FDSS_SRCH       0xf2490040
-#define        F367TER_FFECPROG_5      0xf2490020
-#define        F367TER_FFECPROG_4      0xf2490010
-#define        F367TER_FFECPROG_3      0xf2490008
-#define        F367TER_FFECPROG_2      0xf2490004
-#define        F367TER_FTS1_DISABLE    0xf2490002
-#define        F367TER_FTS2_DISABLE    0xf2490001
-
-/* FVITCURPUN */
-#define        R367TER_FVITCURPUN      0xf24a
-#define        F367TER_FVIT_MAPPING    0xf24a00e0
-#define        F367TER_FVIT_CURPUN     0xf24a001f
-
-/* FVERROR */
-#define        R367TER_FVERROR 0xf24b
-#define        F367TER_FREGERR_VIT     0xf24b00ff
-
-/* FVSTATUSVIT */
-#define        R367TER_FVSTATUSVIT     0xf24c
-#define        F367TER_FVITERBI_ON     0xf24c0080
-#define        F367TER_F1END_LOOPVIT   0xf24c0040
-#define        F367TER_FVITERBI_DEPRF  0xf24c0020
-#define        F367TER_FPRFVIT 0xf24c0010
-#define        F367TER_FLOCKEDVIT      0xf24c0008
-#define        F367TER_FVITERBI_DELOCK 0xf24c0004
-#define        F367TER_FVIT_DEMODSEL   0xf24c0002
-#define        F367TER_FVITERBI_COMPOUT        0xf24c0001
-
-/* DEBUG_LT1 */
-#define        R367TER_DEBUG_LT1       0xf24d
-#define        F367TER_DBG_LT1 0xf24d00ff
-
-/* DEBUG_LT2 */
-#define        R367TER_DEBUG_LT2       0xf24e
-#define        F367TER_DBG_LT2 0xf24e00ff
-
-/* DEBUG_LT3 */
-#define        R367TER_DEBUG_LT3       0xf24f
-#define        F367TER_DBG_LT3 0xf24f00ff
-
-/*     TSTSFMET */
-#define        R367TER_TSTSFMET        0xf250
-#define F367TER_TSTSFEC_METRIQUES      0xf25000ff
-
-/*     SELOUT */
-#define        R367TER_SELOUT  0xf252
-#define        F367TER_EN_SYNC 0xf2520080
-#define        F367TER_EN_TBUSDEMAP    0xf2520040
-#define        F367TER_SELOUT_5        0xf2520020
-#define        F367TER_SELOUT_4        0xf2520010
-#define        F367TER_TSTSYNCHRO_MODE 0xf2520002
-
-/*     TSYNC */
-#define R367TER_TSYNC  0xf253
-#define F367TER_CURPUN_INCMODE 0xf2530080
-#define F367TER_CERR_TSTMODE   0xf2530040
-#define F367TER_SHIFTSOF_MODE  0xf2530030
-#define F367TER_SLOWPHA_MODE   0xf2530008
-#define F367TER_PXX_BYPALL     0xf2530004
-#define F367TER_FROTA45_FIRST  0xf2530002
-#define F367TER_TST_BCHERROR   0xf2530001
-
-/*     TSTERR */
-#define R367TER_TSTERR 0xf254
-#define F367TER_TST_LONGPKT    0xf2540080
-#define F367TER_TST_ISSYION    0xf2540040
-#define F367TER_TST_NPDON      0xf2540020
-#define F367TER_TSTERR_4       0xf2540010
-#define F367TER_TRACEBACK_MODE 0xf2540008
-#define F367TER_TST_RSPARITY   0xf2540004
-#define F367TER_METRIQUE_MODE  0xf2540003
-
-/*     TSFSYNC */
-#define R367TER_TSFSYNC        0xf255
-#define F367TER_EN_SFECSYNC    0xf2550080
-#define F367TER_EN_SFECDEMAP   0xf2550040
-#define F367TER_SFCERR_TSTMODE 0xf2550020
-#define F367TER_SFECPXX_BYPALL 0xf2550010
-#define F367TER_SFECTSTSYNCHRO_MODE 0xf255000f
-
-/*     TSTSFERR */
-#define R367TER_TSTSFERR       0xf256
-#define F367TER_TSTSTERR_7     0xf2560080
-#define F367TER_TSTSTERR_6     0xf2560040
-#define F367TER_TSTSTERR_5     0xf2560020
-#define F367TER_TSTSTERR_4     0xf2560010
-#define F367TER_SFECTRACEBACK_MODE     0xf2560008
-#define F367TER_SFEC_NCONVPROG 0xf2560004
-#define F367TER_SFECMETRIQUE_MODE      0xf2560003
-
-/*     TSTTSSF1 */
-#define R367TER_TSTTSSF1       0xf258
-#define F367TER_TSTERSSF       0xf2580080
-#define F367TER_TSTTSSFEN      0xf2580040
-#define F367TER_SFEC_OUTMODE   0xf2580030
-#define F367TER_XLSF_NOFTHRESHOLD  0xf2580008
-#define F367TER_TSTTSSF_STACKSEL       0xf2580007
-
-/*     TSTTSSF2 */
-#define R367TER_TSTTSSF2       0xf259
-#define F367TER_DILSF_DBBHEADER        0xf2590080
-#define F367TER_TSTTSSF_DISBUG 0xf2590040
-#define F367TER_TSTTSSF_NOBADSTART     0xf2590020
-#define F367TER_TSTTSSF_SELECT 0xf259001f
-
-/*     TSTTSSF3 */
-#define R367TER_TSTTSSF3       0xf25a
-#define F367TER_TSTTSSF3_7     0xf25a0080
-#define F367TER_TSTTSSF3_6     0xf25a0040
-#define F367TER_TSTTSSF3_5     0xf25a0020
-#define F367TER_TSTTSSF3_4     0xf25a0010
-#define F367TER_TSTTSSF3_3     0xf25a0008
-#define F367TER_TSTTSSF3_2     0xf25a0004
-#define F367TER_TSTTSSF3_1     0xf25a0002
-#define F367TER_DISSF_CLKENABLE        0xf25a0001
-
-/*     TSTTS1 */
-#define R367TER_TSTTS1 0xf25c
-#define F367TER_TSTERS 0xf25c0080
-#define F367TER_TSFIFO_DSSSYNCB        0xf25c0040
-#define F367TER_TSTTS_FSPYBEFRS        0xf25c0020
-#define F367TER_NFORCE_SYNCBYTE        0xf25c0010
-#define F367TER_XL_NOFTHRESHOLD        0xf25c0008
-#define F367TER_TSTTS_FRFORCEPKT       0xf25c0004
-#define F367TER_DESCR_NOTAUTO  0xf25c0002
-#define F367TER_TSTTSEN        0xf25c0001
-
-/*     TSTTS2 */
-#define R367TER_TSTTS2 0xf25d
-#define F367TER_DIL_DBBHEADER  0xf25d0080
-#define F367TER_TSTTS_NOBADXXX 0xf25d0040
-#define F367TER_TSFIFO_DELSPEEDUP      0xf25d0020
-#define F367TER_TSTTS_SELECT   0xf25d001f
-
-/*     TSTTS3 */
-#define R367TER_TSTTS3 0xf25e
-#define F367TER_TSTTS_NOPKTGAIN        0xf25e0080
-#define F367TER_TSTTS_NOPKTENE 0xf25e0040
-#define F367TER_TSTTS_ISOLATION        0xf25e0020
-#define F367TER_TSTTS_DISBUG   0xf25e0010
-#define F367TER_TSTTS_NOBADSTART       0xf25e0008
-#define F367TER_TSTTS_STACKSEL 0xf25e0007
-
-/*     TSTTS4 */
-#define R367TER_TSTTS4 0xf25f
-#define F367TER_TSTTS4_7       0xf25f0080
-#define F367TER_TSTTS4_6       0xf25f0040
-#define F367TER_TSTTS4_5       0xf25f0020
-#define F367TER_TSTTS_DISDSTATE        0xf25f0010
-#define F367TER_TSTTS_FASTNOSYNC       0xf25f0008
-#define F367TER_EXT_FECSPYIN   0xf25f0004
-#define F367TER_TSTTS_NODPZERO 0xf25f0002
-#define F367TER_TSTTS_NODIV3   0xf25f0001
-
-/*     TSTTSRC */
-#define R367TER_TSTTSRC        0xf26c
-#define F367TER_TSTTSRC_7      0xf26c0080
-#define F367TER_TSRCFIFO_DSSSYNCB      0xf26c0040
-#define F367TER_TSRCFIFO_DPUNACTIVE    0xf26c0020
-#define F367TER_TSRCFIFO_DELSPEEDUP    0xf26c0010
-#define F367TER_TSTTSRC_NODIV3 0xf26c0008
-#define F367TER_TSTTSRC_FRFORCEPKT     0xf26c0004
-#define F367TER_SAT25_SDDORIGINE       0xf26c0002
-#define F367TER_TSTTSRC_INACTIVE       0xf26c0001
-
-/*     TSTTSRS */
-#define R367TER_TSTTSRS        0xf26d
-#define F367TER_TSTTSRS_7      0xf26d0080
-#define F367TER_TSTTSRS_6      0xf26d0040
-#define F367TER_TSTTSRS_5      0xf26d0020
-#define F367TER_TSTTSRS_4      0xf26d0010
-#define F367TER_TSTTSRS_3      0xf26d0008
-#define F367TER_TSTTSRS_2      0xf26d0004
-#define F367TER_TSTRS_DISRS2   0xf26d0002
-#define F367TER_TSTRS_DISRS1   0xf26d0001
-
-/* TSSTATEM */
-#define        R367TER_TSSTATEM        0xf270
-#define        F367TER_TSDIL_ON        0xf2700080
-#define        F367TER_TSSKIPRS_ON     0xf2700040
-#define        F367TER_TSRS_ON 0xf2700020
-#define        F367TER_TSDESCRAMB_ON   0xf2700010
-#define        F367TER_TSFRAME_MODE    0xf2700008
-#define        F367TER_TS_DISABLE      0xf2700004
-#define        F367TER_TSACM_MODE      0xf2700002
-#define        F367TER_TSOUT_NOSYNC    0xf2700001
-
-/* TSSTATEL */
-#define        R367TER_TSSTATEL        0xf271
-#define        F367TER_TSNOSYNCBYTE    0xf2710080
-#define        F367TER_TSPARITY_ON     0xf2710040
-#define        F367TER_TSSYNCOUTRS_ON  0xf2710020
-#define        F367TER_TSDVBS2_MODE    0xf2710010
-#define        F367TER_TSISSYI_ON      0xf2710008
-#define        F367TER_TSNPD_ON        0xf2710004
-#define        F367TER_TSCRC8_ON       0xf2710002
-#define        F367TER_TSDSS_PACKET    0xf2710001
-
-/* TSCFGH */
-#define        R367TER_TSCFGH  0xf272
-#define        F367TER_TSFIFO_DVBCI    0xf2720080
-#define        F367TER_TSFIFO_SERIAL   0xf2720040
-#define        F367TER_TSFIFO_TEIUPDATE        0xf2720020
-#define        F367TER_TSFIFO_DUTY50   0xf2720010
-#define        F367TER_TSFIFO_HSGNLOUT 0xf2720008
-#define        F367TER_TSFIFO_ERRMODE  0xf2720006
-#define        F367TER_RST_HWARE       0xf2720001
-
-/* TSCFGM */
-#define        R367TER_TSCFGM  0xf273
-#define        F367TER_TSFIFO_MANSPEED 0xf27300c0
-#define        F367TER_TSFIFO_PERMDATA 0xf2730020
-#define        F367TER_TSFIFO_NONEWSGNL        0xf2730010
-#define        F367TER_TSFIFO_BITSPEED 0xf2730008
-#define        F367TER_NPD_SPECDVBS2   0xf2730004
-#define        F367TER_TSFIFO_STOPCKDIS        0xf2730002
-#define        F367TER_TSFIFO_INVDATA  0xf2730001
-
-/* TSCFGL */
-#define        R367TER_TSCFGL  0xf274
-#define        F367TER_TSFIFO_BCLKDEL1cK       0xf27400c0
-#define        F367TER_BCHERROR_MODE   0xf2740030
-#define        F367TER_TSFIFO_NSGNL2dATA       0xf2740008
-#define        F367TER_TSFIFO_EMBINDVB 0xf2740004
-#define        F367TER_TSFIFO_DPUNACT  0xf2740002
-#define        F367TER_TSFIFO_NPDOFF   0xf2740001
-
-/* TSSYNC */
-#define        R367TER_TSSYNC  0xf275
-#define        F367TER_TSFIFO_PERMUTE  0xf2750080
-#define        F367TER_TSFIFO_FISCR3B  0xf2750060
-#define        F367TER_TSFIFO_SYNCMODE 0xf2750018
-#define        F367TER_TSFIFO_SYNCSEL  0xf2750007
-
-/* TSINSDELH */
-#define        R367TER_TSINSDELH       0xf276
-#define        F367TER_TSDEL_SYNCBYTE  0xf2760080
-#define        F367TER_TSDEL_XXHEADER  0xf2760040
-#define        F367TER_TSDEL_BBHEADER  0xf2760020
-#define        F367TER_TSDEL_DATAFIELD 0xf2760010
-#define        F367TER_TSINSDEL_ISCR   0xf2760008
-#define        F367TER_TSINSDEL_NPD    0xf2760004
-#define        F367TER_TSINSDEL_RSPARITY       0xf2760002
-#define        F367TER_TSINSDEL_CRC8   0xf2760001
-
-/* TSINSDELM */
-#define        R367TER_TSINSDELM       0xf277
-#define        F367TER_TSINS_BBPADDING 0xf2770080
-#define        F367TER_TSINS_BCHFEC    0xf2770040
-#define        F367TER_TSINS_LDPCFEC   0xf2770020
-#define        F367TER_TSINS_EMODCOD   0xf2770010
-#define        F367TER_TSINS_TOKEN     0xf2770008
-#define        F367TER_TSINS_XXXERR    0xf2770004
-#define        F367TER_TSINS_MATYPE    0xf2770002
-#define        F367TER_TSINS_UPL       0xf2770001
-
-/* TSINSDELL */
-#define        R367TER_TSINSDELL       0xf278
-#define        F367TER_TSINS_DFL       0xf2780080
-#define        F367TER_TSINS_SYNCD     0xf2780040
-#define        F367TER_TSINS_BLOCLEN   0xf2780020
-#define        F367TER_TSINS_SIGPCOUNT 0xf2780010
-#define        F367TER_TSINS_FIFO      0xf2780008
-#define        F367TER_TSINS_REALPACK  0xf2780004
-#define        F367TER_TSINS_TSCONFIG  0xf2780002
-#define        F367TER_TSINS_LATENCY   0xf2780001
-
-/* TSDIVN */
-#define        R367TER_TSDIVN  0xf279
-#define        F367TER_TSFIFO_LOWSPEED 0xf2790080
-#define        F367TER_BYTE_OVERSAMPLING       0xf2790070
-#define        F367TER_TSMANUAL_PACKETNBR      0xf279000f
-
-/* TSDIVPM */
-#define        R367TER_TSDIVPM 0xf27a
-#define        F367TER_TSMANUAL_P_HI   0xf27a00ff
-
-/* TSDIVPL */
-#define        R367TER_TSDIVPL 0xf27b
-#define        F367TER_TSMANUAL_P_LO   0xf27b00ff
-
-/* TSDIVQM */
-#define        R367TER_TSDIVQM 0xf27c
-#define        F367TER_TSMANUAL_Q_HI   0xf27c00ff
-
-/* TSDIVQL */
-#define        R367TER_TSDIVQL 0xf27d
-#define        F367TER_TSMANUAL_Q_LO   0xf27d00ff
-
-/* TSDILSTKM */
-#define        R367TER_TSDILSTKM       0xf27e
-#define        F367TER_TSFIFO_DILSTK_HI        0xf27e00ff
-
-/* TSDILSTKL */
-#define        R367TER_TSDILSTKL       0xf27f
-#define        F367TER_TSFIFO_DILSTK_LO        0xf27f00ff
-
-/* TSSPEED */
-#define        R367TER_TSSPEED 0xf280
-#define        F367TER_TSFIFO_OUTSPEED 0xf28000ff
-
-/* TSSTATUS */
-#define        R367TER_TSSTATUS        0xf281
-#define        F367TER_TSFIFO_LINEOK   0xf2810080
-#define        F367TER_TSFIFO_ERROR    0xf2810040
-#define        F367TER_TSFIFO_DATA7    0xf2810020
-#define        F367TER_TSFIFO_NOSYNC   0xf2810010
-#define        F367TER_ISCR_INITIALIZED        0xf2810008
-#define        F367TER_ISCR_UPDATED    0xf2810004
-#define        F367TER_SOFFIFO_UNREGUL 0xf2810002
-#define        F367TER_DIL_READY       0xf2810001
-
-/* TSSTATUS2 */
-#define        R367TER_TSSTATUS2       0xf282
-#define        F367TER_TSFIFO_DEMODSEL 0xf2820080
-#define        F367TER_TSFIFOSPEED_STORE       0xf2820040
-#define        F367TER_DILXX_RESET     0xf2820020
-#define        F367TER_TSSERIAL_IMPOSSIBLE     0xf2820010
-#define        F367TER_TSFIFO_UNDERSPEED       0xf2820008
-#define        F367TER_BITSPEED_EVENT  0xf2820004
-#define        F367TER_UL_SCRAMBDETECT 0xf2820002
-#define        F367TER_ULDTV67_FALSELOCK       0xf2820001
-
-/* TSBITRATEM */
-#define        R367TER_TSBITRATEM      0xf283
-#define        F367TER_TSFIFO_BITRATE_HI       0xf28300ff
-
-/* TSBITRATEL */
-#define        R367TER_TSBITRATEL      0xf284
-#define        F367TER_TSFIFO_BITRATE_LO       0xf28400ff
-
-/* TSPACKLENM */
-#define        R367TER_TSPACKLENM      0xf285
-#define        F367TER_TSFIFO_PACKCPT  0xf28500e0
-#define        F367TER_DIL_RPLEN_HI    0xf285001f
-
-/* TSPACKLENL */
-#define        R367TER_TSPACKLENL      0xf286
-#define        F367TER_DIL_RPLEN_LO    0xf28600ff
-
-/* TSBLOCLENM */
-#define        R367TER_TSBLOCLENM      0xf287
-#define        F367TER_TSFIFO_PFLEN_HI 0xf28700ff
-
-/* TSBLOCLENL */
-#define        R367TER_TSBLOCLENL      0xf288
-#define        F367TER_TSFIFO_PFLEN_LO 0xf28800ff
-
-/* TSDLYH */
-#define        R367TER_TSDLYH  0xf289
-#define        F367TER_SOFFIFO_TSTIMEVALID     0xf2890080
-#define        F367TER_SOFFIFO_SPEEDUP 0xf2890040
-#define        F367TER_SOFFIFO_STOP    0xf2890020
-#define        F367TER_SOFFIFO_REGULATED       0xf2890010
-#define        F367TER_SOFFIFO_REALSBOFF_HI    0xf289000f
-
-/* TSDLYM */
-#define        R367TER_TSDLYM  0xf28a
-#define        F367TER_SOFFIFO_REALSBOFF_MED   0xf28a00ff
-
-/* TSDLYL */
-#define        R367TER_TSDLYL  0xf28b
-#define        F367TER_SOFFIFO_REALSBOFF_LO    0xf28b00ff
-
-/* TSNPDAV */
-#define        R367TER_TSNPDAV 0xf28c
-#define        F367TER_TSNPD_AVERAGE   0xf28c00ff
-
-/* TSBUFSTATH */
-#define        R367TER_TSBUFSTATH      0xf28d
-#define        F367TER_TSISCR_3BYTES   0xf28d0080
-#define        F367TER_TSISCR_NEWDATA  0xf28d0040
-#define        F367TER_TSISCR_BUFSTAT_HI       0xf28d003f
-
-/* TSBUFSTATM */
-#define        R367TER_TSBUFSTATM      0xf28e
-#define        F367TER_TSISCR_BUFSTAT_MED      0xf28e00ff
-
-/* TSBUFSTATL */
-#define        R367TER_TSBUFSTATL      0xf28f
-#define        F367TER_TSISCR_BUFSTAT_LO       0xf28f00ff
-
-/* TSDEBUGM */
-#define        R367TER_TSDEBUGM        0xf290
-#define        F367TER_TSFIFO_ILLPACKET        0xf2900080
-#define        F367TER_DIL_NOSYNC      0xf2900040
-#define        F367TER_DIL_ISCR        0xf2900020
-#define        F367TER_DILOUT_BSYNCB   0xf2900010
-#define        F367TER_TSFIFO_EMPTYPKT 0xf2900008
-#define        F367TER_TSFIFO_EMPTYRD  0xf2900004
-#define        F367TER_SOFFIFO_STOPM   0xf2900002
-#define        F367TER_SOFFIFO_SPEEDUPM        0xf2900001
-
-/* TSDEBUGL */
-#define        R367TER_TSDEBUGL        0xf291
-#define        F367TER_TSFIFO_PACKLENFAIL      0xf2910080
-#define        F367TER_TSFIFO_SYNCBFAIL        0xf2910040
-#define        F367TER_TSFIFO_VITLIBRE 0xf2910020
-#define        F367TER_TSFIFO_BOOSTSPEEDM      0xf2910010
-#define        F367TER_TSFIFO_UNDERSPEEDM      0xf2910008
-#define        F367TER_TSFIFO_ERROR_EVNT       0xf2910004
-#define        F367TER_TSFIFO_FULL     0xf2910002
-#define        F367TER_TSFIFO_OVERFLOWM        0xf2910001
-
-/* TSDLYSETH */
-#define        R367TER_TSDLYSETH       0xf292
-#define        F367TER_SOFFIFO_OFFSET  0xf29200e0
-#define        F367TER_SOFFIFO_SYMBOFFSET_HI   0xf292001f
-
-/* TSDLYSETM */
-#define        R367TER_TSDLYSETM       0xf293
-#define        F367TER_SOFFIFO_SYMBOFFSET_MED  0xf29300ff
-
-/* TSDLYSETL */
-#define        R367TER_TSDLYSETL       0xf294
-#define        F367TER_SOFFIFO_SYMBOFFSET_LO   0xf29400ff
-
-/* TSOBSCFG */
-#define        R367TER_TSOBSCFG        0xf295
-#define        F367TER_TSFIFO_OBSCFG   0xf29500ff
-
-/* TSOBSM */
-#define        R367TER_TSOBSM  0xf296
-#define        F367TER_TSFIFO_OBSDATA_HI       0xf29600ff
-
-/* TSOBSL */
-#define        R367TER_TSOBSL  0xf297
-#define        F367TER_TSFIFO_OBSDATA_LO       0xf29700ff
-
-/* ERRCTRL1 */
-#define        R367TER_ERRCTRL1        0xf298
-#define        F367TER_ERR_SRC1        0xf29800f0
-#define        F367TER_ERRCTRL1_3      0xf2980008
-#define        F367TER_NUM_EVT1        0xf2980007
-
-/* ERRCNT1H */
-#define        R367TER_ERRCNT1H        0xf299
-#define        F367TER_ERRCNT1_OLDVALUE        0xf2990080
-#define        F367TER_ERR_CNT1        0xf299007f
-
-/* ERRCNT1M */
-#define        R367TER_ERRCNT1M        0xf29a
-#define        F367TER_ERR_CNT1_HI     0xf29a00ff
-
-/* ERRCNT1L */
-#define        R367TER_ERRCNT1L        0xf29b
-#define        F367TER_ERR_CNT1_LO     0xf29b00ff
-
-/* ERRCTRL2 */
-#define        R367TER_ERRCTRL2        0xf29c
-#define        F367TER_ERR_SRC2        0xf29c00f0
-#define        F367TER_ERRCTRL2_3      0xf29c0008
-#define        F367TER_NUM_EVT2        0xf29c0007
-
-/* ERRCNT2H */
-#define        R367TER_ERRCNT2H        0xf29d
-#define        F367TER_ERRCNT2_OLDVALUE        0xf29d0080
-#define        F367TER_ERR_CNT2_HI     0xf29d007f
-
-/* ERRCNT2M */
-#define        R367TER_ERRCNT2M        0xf29e
-#define        F367TER_ERR_CNT2_MED    0xf29e00ff
-
-/* ERRCNT2L */
-#define        R367TER_ERRCNT2L        0xf29f
-#define        F367TER_ERR_CNT2_LO     0xf29f00ff
-
-/* FECSPY */
-#define        R367TER_FECSPY  0xf2a0
-#define        F367TER_SPY_ENABLE      0xf2a00080
-#define        F367TER_NO_SYNCBYTE     0xf2a00040
-#define        F367TER_SERIAL_MODE     0xf2a00020
-#define        F367TER_UNUSUAL_PACKET  0xf2a00010
-#define        F367TER_BERMETER_DATAMODE       0xf2a0000c
-#define        F367TER_BERMETER_LMODE  0xf2a00002
-#define        F367TER_BERMETER_RESET  0xf2a00001
-
-/* FSPYCFG */
-#define        R367TER_FSPYCFG 0xf2a1
-#define        F367TER_FECSPY_INPUT    0xf2a100c0
-#define        F367TER_RST_ON_ERROR    0xf2a10020
-#define        F367TER_ONE_SHOT        0xf2a10010
-#define        F367TER_I2C_MOD 0xf2a1000c
-#define        F367TER_SPY_HYSTERESIS  0xf2a10003
-
-/* FSPYDATA */
-#define        R367TER_FSPYDATA        0xf2a2
-#define        F367TER_SPY_STUFFING    0xf2a20080
-#define        F367TER_NOERROR_PKTJITTER       0xf2a20040
-#define        F367TER_SPY_CNULLPKT    0xf2a20020
-#define        F367TER_SPY_OUTDATA_MODE        0xf2a2001f
-
-/* FSPYOUT */
-#define        R367TER_FSPYOUT 0xf2a3
-#define        F367TER_FSPY_DIRECT     0xf2a30080
-#define        F367TER_FSPYOUT_6       0xf2a30040
-#define        F367TER_SPY_OUTDATA_BUS 0xf2a30038
-#define        F367TER_STUFF_MODE      0xf2a30007
-
-/* FSTATUS */
-#define        R367TER_FSTATUS 0xf2a4
-#define        F367TER_SPY_ENDSIM      0xf2a40080
-#define        F367TER_VALID_SIM       0xf2a40040
-#define        F367TER_FOUND_SIGNAL    0xf2a40020
-#define        F367TER_DSS_SYNCBYTE    0xf2a40010
-#define        F367TER_RESULT_STATE    0xf2a4000f
-
-/* FGOODPACK */
-#define        R367TER_FGOODPACK       0xf2a5
-#define        F367TER_FGOOD_PACKET    0xf2a500ff
-
-/* FPACKCNT */
-#define        R367TER_FPACKCNT        0xf2a6
-#define        F367TER_FPACKET_COUNTER 0xf2a600ff
-
-/* FSPYMISC */
-#define        R367TER_FSPYMISC        0xf2a7
-#define        F367TER_FLABEL_COUNTER  0xf2a700ff
-
-/* FBERCPT4 */
-#define        R367TER_FBERCPT4        0xf2a8
-#define        F367TER_FBERMETER_CPT5  0xf2a800ff
-
-/* FBERCPT3 */
-#define        R367TER_FBERCPT3        0xf2a9
-#define        F367TER_FBERMETER_CPT4  0xf2a900ff
-
-/* FBERCPT2 */
-#define        R367TER_FBERCPT2        0xf2aa
-#define        F367TER_FBERMETER_CPT3  0xf2aa00ff
-
-/* FBERCPT1 */
-#define        R367TER_FBERCPT1        0xf2ab
-#define        F367TER_FBERMETER_CPT2  0xf2ab00ff
-
-/* FBERCPT0 */
-#define        R367TER_FBERCPT0        0xf2ac
-#define        F367TER_FBERMETER_CPT1  0xf2ac00ff
-
-/* FBERERR2 */
-#define        R367TER_FBERERR2        0xf2ad
-#define        F367TER_FBERMETER_ERR_HI        0xf2ad00ff
-
-/* FBERERR1 */
-#define        R367TER_FBERERR1        0xf2ae
-#define        F367TER_FBERMETER_ERR_MED       0xf2ae00ff
-
-/* FBERERR0 */
-#define        R367TER_FBERERR0        0xf2af
-#define        F367TER_FBERMETER_ERR_LO        0xf2af00ff
-
-/* FSTATESM */
-#define        R367TER_FSTATESM        0xf2b0
-#define        F367TER_RSTATE_F        0xf2b00080
-#define        F367TER_RSTATE_E        0xf2b00040
-#define        F367TER_RSTATE_D        0xf2b00020
-#define        F367TER_RSTATE_C        0xf2b00010
-#define        F367TER_RSTATE_B        0xf2b00008
-#define        F367TER_RSTATE_A        0xf2b00004
-#define        F367TER_RSTATE_9        0xf2b00002
-#define        F367TER_RSTATE_8        0xf2b00001
-
-/* FSTATESL */
-#define        R367TER_FSTATESL        0xf2b1
-#define        F367TER_RSTATE_7        0xf2b10080
-#define        F367TER_RSTATE_6        0xf2b10040
-#define        F367TER_RSTATE_5        0xf2b10020
-#define        F367TER_RSTATE_4        0xf2b10010
-#define        F367TER_RSTATE_3        0xf2b10008
-#define        F367TER_RSTATE_2        0xf2b10004
-#define        F367TER_RSTATE_1        0xf2b10002
-#define        F367TER_RSTATE_0        0xf2b10001
-
-/* FSPYBER */
-#define        R367TER_FSPYBER 0xf2b2
-#define        F367TER_FSPYBER_7       0xf2b20080
-#define        F367TER_FSPYOBS_XORREAD 0xf2b20040
-#define        F367TER_FSPYBER_OBSMODE 0xf2b20020
-#define        F367TER_FSPYBER_SYNCBYTE        0xf2b20010
-#define        F367TER_FSPYBER_UNSYNC  0xf2b20008
-#define        F367TER_FSPYBER_CTIME   0xf2b20007
-
-/* FSPYDISTM */
-#define        R367TER_FSPYDISTM       0xf2b3
-#define        F367TER_PKTTIME_DISTANCE_HI     0xf2b300ff
-
-/* FSPYDISTL */
-#define        R367TER_FSPYDISTL       0xf2b4
-#define        F367TER_PKTTIME_DISTANCE_LO     0xf2b400ff
-
-/* FSPYOBS7 */
-#define        R367TER_FSPYOBS7        0xf2b8
-#define        F367TER_FSPYOBS_SPYFAIL 0xf2b80080
-#define        F367TER_FSPYOBS_SPYFAIL1        0xf2b80040
-#define        F367TER_FSPYOBS_ERROR   0xf2b80020
-#define        F367TER_FSPYOBS_STROUT  0xf2b80010
-#define        F367TER_FSPYOBS_RESULTSTATE1    0xf2b8000f
-
-/* FSPYOBS6 */
-#define        R367TER_FSPYOBS6        0xf2b9
-#define        F367TER_FSPYOBS_RESULTSTATe0    0xf2b900f0
-#define        F367TER_FSPYOBS_RESULTSTATEM1   0xf2b9000f
-
-/* FSPYOBS5 */
-#define        R367TER_FSPYOBS5        0xf2ba
-#define        F367TER_FSPYOBS_BYTEOFPACKET1   0xf2ba00ff
-
-/* FSPYOBS4 */
-#define        R367TER_FSPYOBS4        0xf2bb
-#define        F367TER_FSPYOBS_BYTEVALUE1      0xf2bb00ff
-
-/* FSPYOBS3 */
-#define        R367TER_FSPYOBS3        0xf2bc
-#define        F367TER_FSPYOBS_DATA1   0xf2bc00ff
-
-/* FSPYOBS2 */
-#define        R367TER_FSPYOBS2        0xf2bd
-#define        F367TER_FSPYOBS_DATa0   0xf2bd00ff
-
-/* FSPYOBS1 */
-#define        R367TER_FSPYOBS1        0xf2be
-#define        F367TER_FSPYOBS_DATAM1  0xf2be00ff
-
-/* FSPYOBS0 */
-#define        R367TER_FSPYOBS0        0xf2bf
-#define        F367TER_FSPYOBS_DATAM2  0xf2bf00ff
-
-/* SFDEMAP */
-#define        R367TER_SFDEMAP 0xf2c0
-#define        F367TER_SFDEMAP_7       0xf2c00080
-#define        F367TER_SFEC_K_DIVIDER_VIT      0xf2c0007f
-
-/* SFERROR */
-#define        R367TER_SFERROR 0xf2c1
-#define        F367TER_SFEC_REGERR_VIT 0xf2c100ff
-
-/* SFAVSR */
-#define        R367TER_SFAVSR  0xf2c2
-#define        F367TER_SFEC_SUMERRORS  0xf2c20080
-#define        F367TER_SERROR_MAXMODE  0xf2c20040
-#define        F367TER_SN_SFEC 0xf2c20030
-#define        F367TER_KDIV_MODE_SFEC  0xf2c2000c
-#define        F367TER_SFAVSR_1        0xf2c20002
-#define        F367TER_SFAVSR_0        0xf2c20001
-
-/* SFECSTATUS */
-#define        R367TER_SFECSTATUS      0xf2c3
-#define        F367TER_SFEC_ON 0xf2c30080
-#define        F367TER_SFSTATUS_6      0xf2c30040
-#define        F367TER_SFSTATUS_5      0xf2c30020
-#define        F367TER_SFSTATUS_4      0xf2c30010
-#define        F367TER_LOCKEDSFEC      0xf2c30008
-#define        F367TER_SFEC_DELOCK     0xf2c30004
-#define        F367TER_SFEC_DEMODSEL1  0xf2c30002
-#define        F367TER_SFEC_OVFON      0xf2c30001
-
-/* SFKDIV12 */
-#define        R367TER_SFKDIV12        0xf2c4
-#define        F367TER_SFECKDIV12_MAN  0xf2c40080
-#define        F367TER_SFEC_K_DIVIDER_12       0xf2c4007f
-
-/* SFKDIV23 */
-#define        R367TER_SFKDIV23        0xf2c5
-#define        F367TER_SFECKDIV23_MAN  0xf2c50080
-#define        F367TER_SFEC_K_DIVIDER_23       0xf2c5007f
-
-/* SFKDIV34 */
-#define        R367TER_SFKDIV34        0xf2c6
-#define        F367TER_SFECKDIV34_MAN  0xf2c60080
-#define        F367TER_SFEC_K_DIVIDER_34       0xf2c6007f
-
-/* SFKDIV56 */
-#define        R367TER_SFKDIV56        0xf2c7
-#define        F367TER_SFECKDIV56_MAN  0xf2c70080
-#define        F367TER_SFEC_K_DIVIDER_56       0xf2c7007f
-
-/* SFKDIV67 */
-#define        R367TER_SFKDIV67        0xf2c8
-#define        F367TER_SFECKDIV67_MAN  0xf2c80080
-#define        F367TER_SFEC_K_DIVIDER_67       0xf2c8007f
-
-/* SFKDIV78 */
-#define        R367TER_SFKDIV78        0xf2c9
-#define        F367TER_SFECKDIV78_MAN  0xf2c90080
-#define        F367TER_SFEC_K_DIVIDER_78       0xf2c9007f
-
-/* SFDILSTKM */
-#define        R367TER_SFDILSTKM       0xf2ca
-#define        F367TER_SFEC_PACKCPT    0xf2ca00e0
-#define        F367TER_SFEC_DILSTK_HI  0xf2ca001f
-
-/* SFDILSTKL */
-#define        R367TER_SFDILSTKL       0xf2cb
-#define        F367TER_SFEC_DILSTK_LO  0xf2cb00ff
-
-/* SFSTATUS */
-#define        R367TER_SFSTATUS        0xf2cc
-#define        F367TER_SFEC_LINEOK     0xf2cc0080
-#define        F367TER_SFEC_ERROR      0xf2cc0040
-#define        F367TER_SFEC_DATA7      0xf2cc0020
-#define        F367TER_SFEC_OVERFLOW   0xf2cc0010
-#define        F367TER_SFEC_DEMODSEL2  0xf2cc0008
-#define        F367TER_SFEC_NOSYNC     0xf2cc0004
-#define        F367TER_SFEC_UNREGULA   0xf2cc0002
-#define        F367TER_SFEC_READY      0xf2cc0001
-
-/* SFDLYH */
-#define        R367TER_SFDLYH  0xf2cd
-#define        F367TER_SFEC_TSTIMEVALID        0xf2cd0080
-#define        F367TER_SFEC_SPEEDUP    0xf2cd0040
-#define        F367TER_SFEC_STOP       0xf2cd0020
-#define        F367TER_SFEC_REGULATED  0xf2cd0010
-#define        F367TER_SFEC_REALSYMBOFFSET     0xf2cd000f
-
-/* SFDLYM */
-#define        R367TER_SFDLYM  0xf2ce
-#define        F367TER_SFEC_REALSYMBOFFSET_HI  0xf2ce00ff
-
-/* SFDLYL */
-#define        R367TER_SFDLYL  0xf2cf
-#define        F367TER_SFEC_REALSYMBOFFSET_LO  0xf2cf00ff
-
-/* SFDLYSETH */
-#define        R367TER_SFDLYSETH       0xf2d0
-#define        F367TER_SFEC_OFFSET     0xf2d000e0
-#define        F367TER_SFECDLYSETH_4   0xf2d00010
-#define        F367TER_RST_SFEC        0xf2d00008
-#define        F367TER_SFECDLYSETH_2   0xf2d00004
-#define        F367TER_SFEC_DISABLE    0xf2d00002
-#define        F367TER_SFEC_UNREGUL    0xf2d00001
-
-/* SFDLYSETM */
-#define        R367TER_SFDLYSETM       0xf2d1
-#define        F367TER_SFECDLYSETM_7   0xf2d10080
-#define        F367TER_SFEC_SYMBOFFSET_HI      0xf2d1007f
-
-/* SFDLYSETL */
-#define        R367TER_SFDLYSETL       0xf2d2
-#define        F367TER_SFEC_SYMBOFFSET_LO      0xf2d200ff
-
-/* SFOBSCFG */
-#define        R367TER_SFOBSCFG        0xf2d3
-#define        F367TER_SFEC_OBSCFG     0xf2d300ff
-
-/* SFOBSM */
-#define        R367TER_SFOBSM  0xf2d4
-#define        F367TER_SFEC_OBSDATA_HI 0xf2d400ff
-
-/* SFOBSL */
-#define        R367TER_SFOBSL  0xf2d5
-#define        F367TER_SFEC_OBSDATA_LO 0xf2d500ff
-
-/* SFECINFO */
-#define        R367TER_SFECINFO        0xf2d6
-#define        F367TER_SFECINFO_7      0xf2d60080
-#define        F367TER_SFEC_SYNCDLSB   0xf2d60070
-#define        F367TER_SFCE_S1cPHASE   0xf2d6000f
-
-/* SFERRCTRL */
-#define        R367TER_SFERRCTRL       0xf2d8
-#define        F367TER_SFEC_ERR_SOURCE 0xf2d800f0
-#define        F367TER_SFERRCTRL_3     0xf2d80008
-#define        F367TER_SFEC_NUM_EVENT  0xf2d80007
-
-/* SFERRCNTH */
-#define        R367TER_SFERRCNTH       0xf2d9
-#define        F367TER_SFERRC_OLDVALUE 0xf2d90080
-#define        F367TER_SFEC_ERR_CNT    0xf2d9007f
-
-/* SFERRCNTM */
-#define        R367TER_SFERRCNTM       0xf2da
-#define        F367TER_SFEC_ERR_CNT_HI 0xf2da00ff
-
-/* SFERRCNTL */
-#define        R367TER_SFERRCNTL       0xf2db
-#define        F367TER_SFEC_ERR_CNT_LO 0xf2db00ff
-
-/* SYMBRATEM */
-#define        R367TER_SYMBRATEM       0xf2e0
-#define        F367TER_DEFGEN_SYMBRATE_HI      0xf2e000ff
-
-/* SYMBRATEL */
-#define        R367TER_SYMBRATEL       0xf2e1
-#define        F367TER_DEFGEN_SYMBRATE_LO      0xf2e100ff
-
-/* SYMBSTATUS */
-#define        R367TER_SYMBSTATUS      0xf2e2
-#define        F367TER_SYMBDLINE2_OFF  0xf2e20080
-#define        F367TER_SDDL_REINIT1    0xf2e20040
-#define        F367TER_SDD_REINIT1     0xf2e20020
-#define        F367TER_TOKENID_ERROR   0xf2e20010
-#define        F367TER_SYMBRATE_OVERFLOW       0xf2e20008
-#define        F367TER_SYMBRATE_UNDERFLOW      0xf2e20004
-#define        F367TER_TOKENID_RSTEVENT        0xf2e20002
-#define        F367TER_TOKENID_RESET1  0xf2e20001
-
-/* SYMBCFG */
-#define        R367TER_SYMBCFG 0xf2e3
-#define        F367TER_SYMBCFG_7       0xf2e30080
-#define        F367TER_SYMBCFG_6       0xf2e30040
-#define        F367TER_SYMBCFG_5       0xf2e30020
-#define        F367TER_SYMBCFG_4       0xf2e30010
-#define        F367TER_SYMRATE_FSPEED  0xf2e3000c
-#define        F367TER_SYMRATE_SSPEED  0xf2e30003
-
-/* SYMBFIFOM */
-#define        R367TER_SYMBFIFOM       0xf2e4
-#define        F367TER_SYMBFIFOM_7     0xf2e40080
-#define        F367TER_SYMBFIFOM_6     0xf2e40040
-#define        F367TER_DEFGEN_SYMFIFO_HI       0xf2e4003f
-
-/* SYMBFIFOL */
-#define        R367TER_SYMBFIFOL       0xf2e5
-#define        F367TER_DEFGEN_SYMFIFO_LO       0xf2e500ff
-
-/* SYMBOFFSM */
-#define        R367TER_SYMBOFFSM       0xf2e6
-#define        F367TER_TOKENID_RESET2  0xf2e60080
-#define        F367TER_SDDL_REINIT2    0xf2e60040
-#define        F367TER_SDD_REINIT2     0xf2e60020
-#define        F367TER_SYMBOFFSM_4     0xf2e60010
-#define        F367TER_SYMBOFFSM_3     0xf2e60008
-#define        F367TER_DEFGEN_SYMBOFFSET_HI    0xf2e60007
-
-/* SYMBOFFSL */
-#define        R367TER_SYMBOFFSL       0xf2e7
-#define        F367TER_DEFGEN_SYMBOFFSET_LO    0xf2e700ff
-
-/* DEBUG_LT4 */
-#define        R367TER_DEBUG_LT4       0xf400
-#define        F367TER_F_DEBUG_LT4     0xf40000ff
-
-/* DEBUG_LT5 */
-#define        R367TER_DEBUG_LT5       0xf401
-#define        F367TER_F_DEBUG_LT5     0xf40100ff
-
-/* DEBUG_LT6 */
-#define        R367TER_DEBUG_LT6       0xf402
-#define        F367TER_F_DEBUG_LT6     0xf40200ff
-
-/* DEBUG_LT7 */
-#define        R367TER_DEBUG_LT7       0xf403
-#define        F367TER_F_DEBUG_LT7     0xf40300ff
-
-/* DEBUG_LT8 */
-#define        R367TER_DEBUG_LT8       0xf404
-#define        F367TER_F_DEBUG_LT8     0xf40400ff
-
-/* DEBUG_LT9 */
-#define        R367TER_DEBUG_LT9       0xf405
-#define        F367TER_F_DEBUG_LT9     0xf40500ff
-
-#define STV0367TER_NBREGS      445
-
-/* ID */
-#define        R367CAB_ID      0xf000
-#define        F367CAB_IDENTIFICATIONREGISTER  0xf00000ff
-
-/* I2CRPT */
-#define        R367CAB_I2CRPT  0xf001
-#define        F367CAB_I2CT_ON 0xf0010080
-#define        F367CAB_ENARPT_LEVEL    0xf0010070
-#define        F367CAB_SCLT_DELAY      0xf0010008
-#define        F367CAB_SCLT_NOD        0xf0010004
-#define        F367CAB_STOP_ENABLE     0xf0010002
-#define        F367CAB_SDAT_NOD        0xf0010001
-
-/* TOPCTRL */
-#define        R367CAB_TOPCTRL 0xf002
-#define        F367CAB_STDBY   0xf0020080
-#define        F367CAB_STDBY_CORE      0xf0020020
-#define        F367CAB_QAM_COFDM       0xf0020010
-#define        F367CAB_TS_DIS  0xf0020008
-#define        F367CAB_DIR_CLK_216     0xf0020004
-
-/* IOCFG0 */
-#define        R367CAB_IOCFG0  0xf003
-#define        F367CAB_OP0_SD  0xf0030080
-#define        F367CAB_OP0_VAL 0xf0030040
-#define        F367CAB_OP0_OD  0xf0030020
-#define        F367CAB_OP0_INV 0xf0030010
-#define        F367CAB_OP0_DACVALUE_HI 0xf003000f
-
-/* DAc0R */
-#define        R367CAB_DAC0R   0xf004
-#define        F367CAB_OP0_DACVALUE_LO 0xf00400ff
-
-/* IOCFG1 */
-#define        R367CAB_IOCFG1  0xf005
-#define        F367CAB_IP0     0xf0050040
-#define        F367CAB_OP1_OD  0xf0050020
-#define        F367CAB_OP1_INV 0xf0050010
-#define        F367CAB_OP1_DACVALUE_HI 0xf005000f
-
-/* DAC1R */
-#define        R367CAB_DAC1R   0xf006
-#define        F367CAB_OP1_DACVALUE_LO 0xf00600ff
-
-/* IOCFG2 */
-#define        R367CAB_IOCFG2  0xf007
-#define        F367CAB_OP2_LOCK_CONF   0xf00700e0
-#define        F367CAB_OP2_OD  0xf0070010
-#define        F367CAB_OP2_VAL 0xf0070008
-#define        F367CAB_OP1_LOCK_CONF   0xf0070007
-
-/* SDFR */
-#define        R367CAB_SDFR    0xf008
-#define        F367CAB_OP0_FREQ        0xf00800f0
-#define        F367CAB_OP1_FREQ        0xf008000f
-
-/* AUX_CLK */
-#define        R367CAB_AUX_CLK 0xf00a
-#define        F367CAB_AUXFEC_CTL      0xf00a00c0
-#define        F367CAB_DIS_CKX4        0xf00a0020
-#define        F367CAB_CKSEL   0xf00a0018
-#define        F367CAB_CKDIV_PROG      0xf00a0006
-#define        F367CAB_AUXCLK_ENA      0xf00a0001
-
-/* FREESYS1 */
-#define        R367CAB_FREESYS1        0xf00b
-#define        F367CAB_FREESYS_1       0xf00b00ff
-
-/* FREESYS2 */
-#define        R367CAB_FREESYS2        0xf00c
-#define        F367CAB_FREESYS_2       0xf00c00ff
-
-/* FREESYS3 */
-#define        R367CAB_FREESYS3        0xf00d
-#define        F367CAB_FREESYS_3       0xf00d00ff
-
-/* GPIO_CFG */
-#define        R367CAB_GPIO_CFG        0xf00e
-#define        F367CAB_GPIO7_OD        0xf00e0080
-#define        F367CAB_GPIO7_CFG       0xf00e0040
-#define        F367CAB_GPIO6_OD        0xf00e0020
-#define        F367CAB_GPIO6_CFG       0xf00e0010
-#define        F367CAB_GPIO5_OD        0xf00e0008
-#define        F367CAB_GPIO5_CFG       0xf00e0004
-#define        F367CAB_GPIO4_OD        0xf00e0002
-#define        F367CAB_GPIO4_CFG       0xf00e0001
-
-/* GPIO_CMD */
-#define        R367CAB_GPIO_CMD        0xf00f
-#define        F367CAB_GPIO7_VAL       0xf00f0008
-#define        F367CAB_GPIO6_VAL       0xf00f0004
-#define        F367CAB_GPIO5_VAL       0xf00f0002
-#define        F367CAB_GPIO4_VAL       0xf00f0001
-
-/* TSTRES */
-#define        R367CAB_TSTRES  0xf0c0
-#define        F367CAB_FRES_DISPLAY    0xf0c00080
-#define        F367CAB_FRES_FIFO_AD    0xf0c00020
-#define        F367CAB_FRESRS  0xf0c00010
-#define        F367CAB_FRESACS 0xf0c00008
-#define        F367CAB_FRESFEC 0xf0c00004
-#define        F367CAB_FRES_PRIF       0xf0c00002
-#define        F367CAB_FRESCORE        0xf0c00001
-
-/* ANACTRL */
-#define        R367CAB_ANACTRL 0xf0c1
-#define        F367CAB_BYPASS_XTAL     0xf0c10040
-#define        F367CAB_BYPASS_PLLXN    0xf0c1000c
-#define        F367CAB_DIS_PAD_OSC     0xf0c10002
-#define        F367CAB_STDBY_PLLXN     0xf0c10001
-
-/* TSTBUS */
-#define        R367CAB_TSTBUS  0xf0c2
-#define        F367CAB_TS_BYTE_CLK_INV 0xf0c20080
-#define        F367CAB_CFG_IP  0xf0c20070
-#define        F367CAB_CFG_TST 0xf0c2000f
-
-/* RF_AGC1 */
-#define        R367CAB_RF_AGC1 0xf0d4
-#define        F367CAB_RF_AGC1_LEVEL_HI        0xf0d400ff
-
-/* RF_AGC2 */
-#define        R367CAB_RF_AGC2 0xf0d5
-#define        F367CAB_REF_ADGP        0xf0d50080
-#define        F367CAB_STDBY_ADCGP     0xf0d50020
-#define        F367CAB_RF_AGC1_LEVEL_LO        0xf0d50003
-
-/* ANADIGCTRL */
-#define        R367CAB_ANADIGCTRL      0xf0d7
-#define        F367CAB_SEL_CLKDEM      0xf0d70020
-#define        F367CAB_EN_BUFFER_Q     0xf0d70010
-#define        F367CAB_EN_BUFFER_I     0xf0d70008
-#define        F367CAB_ADC_RIS_EGDE    0xf0d70004
-#define        F367CAB_SGN_ADC 0xf0d70002
-#define        F367CAB_SEL_AD12_SYNC   0xf0d70001
-
-/* PLLMDIV */
-#define        R367CAB_PLLMDIV 0xf0d8
-#define        F367CAB_PLL_MDIV        0xf0d800ff
-
-/* PLLNDIV */
-#define        R367CAB_PLLNDIV 0xf0d9
-#define        F367CAB_PLL_NDIV        0xf0d900ff
-
-/* PLLSETUP */
-#define        R367CAB_PLLSETUP        0xf0da
-#define        F367CAB_PLL_PDIV        0xf0da0070
-#define        F367CAB_PLL_KDIV        0xf0da000f
-
-/* DUAL_AD12 */
-#define        R367CAB_DUAL_AD12       0xf0db
-#define        F367CAB_FS20M   0xf0db0020
-#define        F367CAB_FS50M   0xf0db0010
-#define        F367CAB_INMODe0 0xf0db0008
-#define        F367CAB_POFFQ   0xf0db0004
-#define        F367CAB_POFFI   0xf0db0002
-#define        F367CAB_INMODE1 0xf0db0001
-
-/* TSTBIST */
-#define        R367CAB_TSTBIST 0xf0dc
-#define        F367CAB_TST_BYP_CLK     0xf0dc0080
-#define        F367CAB_TST_GCLKENA_STD 0xf0dc0040
-#define        F367CAB_TST_GCLKENA     0xf0dc0020
-#define        F367CAB_TST_MEMBIST     0xf0dc001f
-
-/* CTRL_1 */
-#define        R367CAB_CTRL_1  0xf402
-#define        F367CAB_SOFT_RST        0xf4020080
-#define        F367CAB_EQU_RST 0xf4020008
-#define        F367CAB_CRL_RST 0xf4020004
-#define        F367CAB_TRL_RST 0xf4020002
-#define        F367CAB_AGC_RST 0xf4020001
-
-/* CTRL_2 */
-#define        R367CAB_CTRL_2  0xf403
-#define        F367CAB_DEINT_RST       0xf4030008
-#define        F367CAB_RS_RST  0xf4030004
-
-/* IT_STATUS1 */
-#define        R367CAB_IT_STATUS1      0xf408
-#define        F367CAB_SWEEP_OUT       0xf4080080
-#define        F367CAB_FSM_CRL 0xf4080040
-#define        F367CAB_CRL_LOCK        0xf4080020
-#define        F367CAB_MFSM    0xf4080010
-#define        F367CAB_TRL_LOCK        0xf4080008
-#define        F367CAB_TRL_AGC_LIMIT   0xf4080004
-#define        F367CAB_ADJ_AGC_LOCK    0xf4080002
-#define        F367CAB_AGC_QAM_LOCK    0xf4080001
-
-/* IT_STATUS2 */
-#define        R367CAB_IT_STATUS2      0xf409
-#define        F367CAB_TSMF_CNT        0xf4090080
-#define        F367CAB_TSMF_EOF        0xf4090040
-#define        F367CAB_TSMF_RDY        0xf4090020
-#define        F367CAB_FEC_NOCORR      0xf4090010
-#define        F367CAB_SYNCSTATE       0xf4090008
-#define        F367CAB_DEINT_LOCK      0xf4090004
-#define        F367CAB_FADDING_FRZ     0xf4090002
-#define        F367CAB_TAPMON_ALARM    0xf4090001
-
-/* IT_EN1 */
-#define        R367CAB_IT_EN1  0xf40a
-#define        F367CAB_SWEEP_OUTE      0xf40a0080
-#define        F367CAB_FSM_CRLE        0xf40a0040
-#define        F367CAB_CRL_LOCKE       0xf40a0020
-#define        F367CAB_MFSME   0xf40a0010
-#define        F367CAB_TRL_LOCKE       0xf40a0008
-#define        F367CAB_TRL_AGC_LIMITE  0xf40a0004
-#define        F367CAB_ADJ_AGC_LOCKE   0xf40a0002
-#define        F367CAB_AGC_LOCKE       0xf40a0001
-
-/* IT_EN2 */
-#define        R367CAB_IT_EN2  0xf40b
-#define        F367CAB_TSMF_CNTE       0xf40b0080
-#define        F367CAB_TSMF_EOFE       0xf40b0040
-#define        F367CAB_TSMF_RDYE       0xf40b0020
-#define        F367CAB_FEC_NOCORRE     0xf40b0010
-#define        F367CAB_SYNCSTATEE      0xf40b0008
-#define        F367CAB_DEINT_LOCKE     0xf40b0004
-#define        F367CAB_FADDING_FRZE    0xf40b0002
-#define        F367CAB_TAPMON_ALARME   0xf40b0001
-
-/* CTRL_STATUS */
-#define        R367CAB_CTRL_STATUS     0xf40c
-#define        F367CAB_QAMFEC_LOCK     0xf40c0004
-#define        F367CAB_TSMF_LOCK       0xf40c0002
-#define        F367CAB_TSMF_ERROR      0xf40c0001
-
-/* TEST_CTL */
-#define        R367CAB_TEST_CTL        0xf40f
-#define        F367CAB_TST_BLK_SEL     0xf40f0060
-#define        F367CAB_TST_BUS_SEL     0xf40f001f
-
-/* AGC_CTL */
-#define        R367CAB_AGC_CTL 0xf410
-#define        F367CAB_AGC_LCK_TH      0xf41000f0
-#define        F367CAB_AGC_ACCUMRSTSEL 0xf4100007
-
-/* AGC_IF_CFG */
-#define        R367CAB_AGC_IF_CFG      0xf411
-#define        F367CAB_AGC_IF_BWSEL    0xf41100f0
-#define        F367CAB_AGC_IF_FREEZE   0xf4110002
-
-/* AGC_RF_CFG */
-#define        R367CAB_AGC_RF_CFG      0xf412
-#define        F367CAB_AGC_RF_BWSEL    0xf4120070
-#define        F367CAB_AGC_RF_FREEZE   0xf4120002
-
-/* AGC_PWM_CFG */
-#define        R367CAB_AGC_PWM_CFG     0xf413
-#define        F367CAB_AGC_RF_PWM_TST  0xf4130080
-#define        F367CAB_AGC_RF_PWM_INV  0xf4130040
-#define        F367CAB_AGC_IF_PWM_TST  0xf4130008
-#define        F367CAB_AGC_IF_PWM_INV  0xf4130004
-#define        F367CAB_AGC_PWM_CLKDIV  0xf4130003
-
-/* AGC_PWR_REF_L */
-#define        R367CAB_AGC_PWR_REF_L   0xf414
-#define        F367CAB_AGC_PWRREF_LO   0xf41400ff
-
-/* AGC_PWR_REF_H */
-#define        R367CAB_AGC_PWR_REF_H   0xf415
-#define        F367CAB_AGC_PWRREF_HI   0xf4150003
-
-/* AGC_RF_TH_L */
-#define        R367CAB_AGC_RF_TH_L     0xf416
-#define        F367CAB_AGC_RF_TH_LO    0xf41600ff
-
-/* AGC_RF_TH_H */
-#define        R367CAB_AGC_RF_TH_H     0xf417
-#define        F367CAB_AGC_RF_TH_HI    0xf417000f
-
-/* AGC_IF_LTH_L */
-#define        R367CAB_AGC_IF_LTH_L    0xf418
-#define        F367CAB_AGC_IF_THLO_LO  0xf41800ff
-
-/* AGC_IF_LTH_H */
-#define        R367CAB_AGC_IF_LTH_H    0xf419
-#define        F367CAB_AGC_IF_THLO_HI  0xf419000f
-
-/* AGC_IF_HTH_L */
-#define        R367CAB_AGC_IF_HTH_L    0xf41a
-#define        F367CAB_AGC_IF_THHI_LO  0xf41a00ff
-
-/* AGC_IF_HTH_H */
-#define        R367CAB_AGC_IF_HTH_H    0xf41b
-#define        F367CAB_AGC_IF_THHI_HI  0xf41b000f
-
-/* AGC_PWR_RD_L */
-#define        R367CAB_AGC_PWR_RD_L    0xf41c
-#define        F367CAB_AGC_PWR_WORD_LO 0xf41c00ff
-
-/* AGC_PWR_RD_M */
-#define        R367CAB_AGC_PWR_RD_M    0xf41d
-#define        F367CAB_AGC_PWR_WORD_ME 0xf41d00ff
-
-/* AGC_PWR_RD_H */
-#define        R367CAB_AGC_PWR_RD_H    0xf41e
-#define        F367CAB_AGC_PWR_WORD_HI 0xf41e0003
-
-/* AGC_PWM_IFCMD_L */
-#define        R367CAB_AGC_PWM_IFCMD_L 0xf420
-#define        F367CAB_AGC_IF_PWMCMD_LO        0xf42000ff
-
-/* AGC_PWM_IFCMD_H */
-#define        R367CAB_AGC_PWM_IFCMD_H 0xf421
-#define        F367CAB_AGC_IF_PWMCMD_HI        0xf421000f
-
-/* AGC_PWM_RFCMD_L */
-#define        R367CAB_AGC_PWM_RFCMD_L 0xf422
-#define        F367CAB_AGC_RF_PWMCMD_LO        0xf42200ff
-
-/* AGC_PWM_RFCMD_H */
-#define        R367CAB_AGC_PWM_RFCMD_H 0xf423
-#define        F367CAB_AGC_RF_PWMCMD_HI        0xf423000f
-
-/* IQDEM_CFG */
-#define        R367CAB_IQDEM_CFG       0xf424
-#define        F367CAB_IQDEM_CLK_SEL   0xf4240004
-#define        F367CAB_IQDEM_INVIQ     0xf4240002
-#define        F367CAB_IQDEM_A2dTYPE   0xf4240001
-
-/* MIX_NCO_LL */
-#define        R367CAB_MIX_NCO_LL      0xf425
-#define        F367CAB_MIX_NCO_INC_LL  0xf42500ff
-
-/* MIX_NCO_HL */
-#define        R367CAB_MIX_NCO_HL      0xf426
-#define        F367CAB_MIX_NCO_INC_HL  0xf42600ff
-
-/* MIX_NCO_HH */
-#define        R367CAB_MIX_NCO_HH      0xf427
-#define        F367CAB_MIX_NCO_INVCNST 0xf4270080
-#define        F367CAB_MIX_NCO_INC_HH  0xf427007f
-
-/* SRC_NCO_LL */
-#define        R367CAB_SRC_NCO_LL      0xf428
-#define        F367CAB_SRC_NCO_INC_LL  0xf42800ff
-
-/* SRC_NCO_LH */
-#define        R367CAB_SRC_NCO_LH      0xf429
-#define        F367CAB_SRC_NCO_INC_LH  0xf42900ff
-
-/* SRC_NCO_HL */
-#define        R367CAB_SRC_NCO_HL      0xf42a
-#define        F367CAB_SRC_NCO_INC_HL  0xf42a00ff
-
-/* SRC_NCO_HH */
-#define        R367CAB_SRC_NCO_HH      0xf42b
-#define        F367CAB_SRC_NCO_INC_HH  0xf42b007f
-
-/* IQDEM_GAIN_SRC_L */
-#define        R367CAB_IQDEM_GAIN_SRC_L        0xf42c
-#define        F367CAB_GAIN_SRC_LO     0xf42c00ff
-
-/* IQDEM_GAIN_SRC_H */
-#define        R367CAB_IQDEM_GAIN_SRC_H        0xf42d
-#define        F367CAB_GAIN_SRC_HI     0xf42d0003
-
-/* IQDEM_DCRM_CFG_LL */
-#define        R367CAB_IQDEM_DCRM_CFG_LL       0xf430
-#define        F367CAB_DCRM0_DCIN_L    0xf43000ff
-
-/* IQDEM_DCRM_CFG_LH */
-#define        R367CAB_IQDEM_DCRM_CFG_LH       0xf431
-#define        F367CAB_DCRM1_I_DCIN_L  0xf43100fc
-#define        F367CAB_DCRM0_DCIN_H    0xf4310003
-
-/* IQDEM_DCRM_CFG_HL */
-#define        R367CAB_IQDEM_DCRM_CFG_HL       0xf432
-#define        F367CAB_DCRM1_Q_DCIN_L  0xf43200f0
-#define        F367CAB_DCRM1_I_DCIN_H  0xf432000f
-
-/* IQDEM_DCRM_CFG_HH */
-#define        R367CAB_IQDEM_DCRM_CFG_HH       0xf433
-#define        F367CAB_DCRM1_FRZ       0xf4330080
-#define        F367CAB_DCRM0_FRZ       0xf4330040
-#define        F367CAB_DCRM1_Q_DCIN_H  0xf433003f
-
-/* IQDEM_ADJ_COEFf0 */
-#define        R367CAB_IQDEM_ADJ_COEFF0        0xf434
-#define        F367CAB_ADJIIR_COEFF10_L        0xf43400ff
-
-/* IQDEM_ADJ_COEFF1 */
-#define        R367CAB_IQDEM_ADJ_COEFF1        0xf435
-#define        F367CAB_ADJIIR_COEFF11_L        0xf43500fc
-#define        F367CAB_ADJIIR_COEFF10_H        0xf4350003
-
-/* IQDEM_ADJ_COEFF2 */
-#define        R367CAB_IQDEM_ADJ_COEFF2        0xf436
-#define        F367CAB_ADJIIR_COEFF12_L        0xf43600f0
-#define        F367CAB_ADJIIR_COEFF11_H        0xf436000f
-
-/* IQDEM_ADJ_COEFF3 */
-#define        R367CAB_IQDEM_ADJ_COEFF3        0xf437
-#define        F367CAB_ADJIIR_COEFF20_L        0xf43700c0
-#define        F367CAB_ADJIIR_COEFF12_H        0xf437003f
-
-/* IQDEM_ADJ_COEFF4 */
-#define        R367CAB_IQDEM_ADJ_COEFF4        0xf438
-#define        F367CAB_ADJIIR_COEFF20_H        0xf43800ff
-
-/* IQDEM_ADJ_COEFF5 */
-#define        R367CAB_IQDEM_ADJ_COEFF5        0xf439
-#define        F367CAB_ADJIIR_COEFF21_L        0xf43900ff
-
-/* IQDEM_ADJ_COEFF6 */
-#define        R367CAB_IQDEM_ADJ_COEFF6        0xf43a
-#define        F367CAB_ADJIIR_COEFF22_L        0xf43a00fc
-#define        F367CAB_ADJIIR_COEFF21_H        0xf43a0003
-
-/* IQDEM_ADJ_COEFF7 */
-#define        R367CAB_IQDEM_ADJ_COEFF7        0xf43b
-#define        F367CAB_ADJIIR_COEFF22_H        0xf43b000f
-
-/* IQDEM_ADJ_EN */
-#define        R367CAB_IQDEM_ADJ_EN    0xf43c
-#define        F367CAB_ALLPASSFILT_EN  0xf43c0008
-#define        F367CAB_ADJ_AGC_EN      0xf43c0004
-#define        F367CAB_ADJ_COEFF_FRZ   0xf43c0002
-#define        F367CAB_ADJ_EN  0xf43c0001
-
-/* IQDEM_ADJ_AGC_REF */
-#define        R367CAB_IQDEM_ADJ_AGC_REF       0xf43d
-#define        F367CAB_ADJ_AGC_REF     0xf43d00ff
-
-/* ALLPASSFILT1 */
-#define        R367CAB_ALLPASSFILT1    0xf440
-#define        F367CAB_ALLPASSFILT_COEFF1_LO   0xf44000ff
-
-/* ALLPASSFILT2 */
-#define        R367CAB_ALLPASSFILT2    0xf441
-#define        F367CAB_ALLPASSFILT_COEFF1_ME   0xf44100ff
-
-/* ALLPASSFILT3 */
-#define        R367CAB_ALLPASSFILT3    0xf442
-#define        F367CAB_ALLPASSFILT_COEFF2_LO   0xf44200c0
-#define        F367CAB_ALLPASSFILT_COEFF1_HI   0xf442003f
-
-/* ALLPASSFILT4 */
-#define        R367CAB_ALLPASSFILT4    0xf443
-#define        F367CAB_ALLPASSFILT_COEFF2_MEL  0xf44300ff
-
-/* ALLPASSFILT5 */
-#define        R367CAB_ALLPASSFILT5    0xf444
-#define        F367CAB_ALLPASSFILT_COEFF2_MEH  0xf44400ff
-
-/* ALLPASSFILT6 */
-#define        R367CAB_ALLPASSFILT6    0xf445
-#define        F367CAB_ALLPASSFILT_COEFF3_LO   0xf44500f0
-#define        F367CAB_ALLPASSFILT_COEFF2_HI   0xf445000f
-
-/* ALLPASSFILT7 */
-#define        R367CAB_ALLPASSFILT7    0xf446
-#define        F367CAB_ALLPASSFILT_COEFF3_MEL  0xf44600ff
-
-/* ALLPASSFILT8 */
-#define        R367CAB_ALLPASSFILT8    0xf447
-#define        F367CAB_ALLPASSFILT_COEFF3_MEH  0xf44700ff
-
-/* ALLPASSFILT9 */
-#define        R367CAB_ALLPASSFILT9    0xf448
-#define        F367CAB_ALLPASSFILT_COEFF4_LO   0xf44800fc
-#define        F367CAB_ALLPASSFILT_COEFF3_HI   0xf4480003
-
-/* ALLPASSFILT10 */
-#define        R367CAB_ALLPASSFILT10   0xf449
-#define        F367CAB_ALLPASSFILT_COEFF4_ME   0xf44900ff
-
-/* ALLPASSFILT11 */
-#define        R367CAB_ALLPASSFILT11   0xf44a
-#define        F367CAB_ALLPASSFILT_COEFF4_HI   0xf44a00ff
-
-/* TRL_AGC_CFG */
-#define        R367CAB_TRL_AGC_CFG     0xf450
-#define        F367CAB_TRL_AGC_FREEZE  0xf4500080
-#define        F367CAB_TRL_AGC_REF     0xf450007f
-
-/* TRL_LPF_CFG */
-#define        R367CAB_TRL_LPF_CFG     0xf454
-#define        F367CAB_NYQPOINT_INV    0xf4540040
-#define        F367CAB_TRL_SHIFT       0xf4540030
-#define        F367CAB_NYQ_COEFF_SEL   0xf454000c
-#define        F367CAB_TRL_LPF_FREEZE  0xf4540002
-#define        F367CAB_TRL_LPF_CRT     0xf4540001
-
-/* TRL_LPF_ACQ_GAIN */
-#define        R367CAB_TRL_LPF_ACQ_GAIN        0xf455
-#define        F367CAB_TRL_GDIR_ACQ    0xf4550070
-#define        F367CAB_TRL_GINT_ACQ    0xf4550007
-
-/* TRL_LPF_TRK_GAIN */
-#define        R367CAB_TRL_LPF_TRK_GAIN        0xf456
-#define        F367CAB_TRL_GDIR_TRK    0xf4560070
-#define        F367CAB_TRL_GINT_TRK    0xf4560007
-
-/* TRL_LPF_OUT_GAIN */
-#define        R367CAB_TRL_LPF_OUT_GAIN        0xf457
-#define        F367CAB_TRL_GAIN_OUT    0xf4570007
-
-/* TRL_LOCKDET_LTH */
-#define        R367CAB_TRL_LOCKDET_LTH 0xf458
-#define        F367CAB_TRL_LCK_THLO    0xf4580007
-
-/* TRL_LOCKDET_HTH */
-#define        R367CAB_TRL_LOCKDET_HTH 0xf459
-#define        F367CAB_TRL_LCK_THHI    0xf45900ff
-
-/* TRL_LOCKDET_TRGVAL */
-#define        R367CAB_TRL_LOCKDET_TRGVAL      0xf45a
-#define        F367CAB_TRL_LCK_TRG     0xf45a00ff
-
-/* IQ_QAM */
-#define        R367CAB_IQ_QAM  0xf45c
-#define        F367CAB_IQ_INPUT        0xf45c0008
-#define        F367CAB_DETECT_MODE     0xf45c0007
-
-/* FSM_STATE */
-#define        R367CAB_FSM_STATE       0xf460
-#define        F367CAB_CRL_DFE 0xf4600080
-#define        F367CAB_DFE_START       0xf4600040
-#define        F367CAB_CTRLG_START     0xf4600030
-#define        F367CAB_FSM_FORCESTATE  0xf460000f
-
-/* FSM_CTL */
-#define        R367CAB_FSM_CTL 0xf461
-#define        F367CAB_FEC2_EN 0xf4610040
-#define        F367CAB_SIT_EN  0xf4610020
-#define        F367CAB_TRL_AHEAD       0xf4610010
-#define        F367CAB_TRL2_EN 0xf4610008
-#define        F367CAB_FSM_EQA1_EN     0xf4610004
-#define        F367CAB_FSM_BKP_DIS     0xf4610002
-#define        F367CAB_FSM_FORCE_EN    0xf4610001
-
-/* FSM_STS */
-#define        R367CAB_FSM_STS 0xf462
-#define        F367CAB_FSM_STATUS      0xf462000f
-
-/* FSM_SNR0_HTH */
-#define        R367CAB_FSM_SNR0_HTH    0xf463
-#define        F367CAB_SNR0_HTH        0xf46300ff
-
-/* FSM_SNR1_HTH */
-#define        R367CAB_FSM_SNR1_HTH    0xf464
-#define        F367CAB_SNR1_HTH        0xf46400ff
-
-/* FSM_SNR2_HTH */
-#define        R367CAB_FSM_SNR2_HTH    0xf465
-#define        F367CAB_SNR2_HTH        0xf46500ff
-
-/* FSM_SNR0_LTH */
-#define        R367CAB_FSM_SNR0_LTH    0xf466
-#define        F367CAB_SNR0_LTH        0xf46600ff
-
-/* FSM_SNR1_LTH */
-#define        R367CAB_FSM_SNR1_LTH    0xf467
-#define        F367CAB_SNR1_LTH        0xf46700ff
-
-/* FSM_EQA1_HTH */
-#define        R367CAB_FSM_EQA1_HTH    0xf468
-#define        F367CAB_SNR3_HTH_LO     0xf46800f0
-#define        F367CAB_EQA1_HTH        0xf468000f
-
-/* FSM_TEMPO */
-#define        R367CAB_FSM_TEMPO       0xf469
-#define        F367CAB_SIT     0xf46900c0
-#define        F367CAB_WST     0xf4690038
-#define        F367CAB_ELT     0xf4690006
-#define        F367CAB_SNR3_HTH_HI     0xf4690001
-
-/* FSM_CONFIG */
-#define        R367CAB_FSM_CONFIG      0xf46a
-#define        F367CAB_FEC2_DFEOFF     0xf46a0004
-#define        F367CAB_PRIT_STATE      0xf46a0002
-#define        F367CAB_MODMAP_STATE    0xf46a0001
-
-/* EQU_I_TESTTAP_L */
-#define        R367CAB_EQU_I_TESTTAP_L 0xf474
-#define        F367CAB_I_TEST_TAP_L    0xf47400ff
-
-/* EQU_I_TESTTAP_M */
-#define        R367CAB_EQU_I_TESTTAP_M 0xf475
-#define        F367CAB_I_TEST_TAP_M    0xf47500ff
-
-/* EQU_I_TESTTAP_H */
-#define        R367CAB_EQU_I_TESTTAP_H 0xf476
-#define        F367CAB_I_TEST_TAP_H    0xf476001f
-
-/* EQU_TESTAP_CFG */
-#define        R367CAB_EQU_TESTAP_CFG  0xf477
-#define        F367CAB_TEST_FFE_DFE_SEL        0xf4770040
-#define        F367CAB_TEST_TAP_SELECT 0xf477003f
-
-/* EQU_Q_TESTTAP_L */
-#define        R367CAB_EQU_Q_TESTTAP_L 0xf478
-#define        F367CAB_Q_TEST_TAP_L    0xf47800ff
-
-/* EQU_Q_TESTTAP_M */
-#define        R367CAB_EQU_Q_TESTTAP_M 0xf479
-#define        F367CAB_Q_TEST_TAP_M    0xf47900ff
-
-/* EQU_Q_TESTTAP_H */
-#define        R367CAB_EQU_Q_TESTTAP_H 0xf47a
-#define        F367CAB_Q_TEST_TAP_H    0xf47a001f
-
-/* EQU_TAP_CTRL */
-#define        R367CAB_EQU_TAP_CTRL    0xf47b
-#define        F367CAB_MTAP_FRZ        0xf47b0010
-#define        F367CAB_PRE_FREEZE      0xf47b0008
-#define        F367CAB_DFE_TAPMON_EN   0xf47b0004
-#define        F367CAB_FFE_TAPMON_EN   0xf47b0002
-#define        F367CAB_MTAP_ONLY       0xf47b0001
-
-/* EQU_CTR_CRL_CONTROL_L */
-#define        R367CAB_EQU_CTR_CRL_CONTROL_L   0xf47c
-#define        F367CAB_EQU_CTR_CRL_CONTROL_LO  0xf47c00ff
-
-/* EQU_CTR_CRL_CONTROL_H */
-#define        R367CAB_EQU_CTR_CRL_CONTROL_H   0xf47d
-#define        F367CAB_EQU_CTR_CRL_CONTROL_HI  0xf47d00ff
-
-/* EQU_CTR_HIPOW_L */
-#define        R367CAB_EQU_CTR_HIPOW_L 0xf47e
-#define        F367CAB_CTR_HIPOW_L     0xf47e00ff
-
-/* EQU_CTR_HIPOW_H */
-#define        R367CAB_EQU_CTR_HIPOW_H 0xf47f
-#define        F367CAB_CTR_HIPOW_H     0xf47f00ff
-
-/* EQU_I_EQU_LO */
-#define        R367CAB_EQU_I_EQU_LO    0xf480
-#define        F367CAB_EQU_I_EQU_L     0xf48000ff
-
-/* EQU_I_EQU_HI */
-#define        R367CAB_EQU_I_EQU_HI    0xf481
-#define        F367CAB_EQU_I_EQU_H     0xf4810003
-
-/* EQU_Q_EQU_LO */
-#define        R367CAB_EQU_Q_EQU_LO    0xf482
-#define        F367CAB_EQU_Q_EQU_L     0xf48200ff
-
-/* EQU_Q_EQU_HI */
-#define        R367CAB_EQU_Q_EQU_HI    0xf483
-#define        F367CAB_EQU_Q_EQU_H     0xf4830003
-
-/* EQU_MAPPER */
-#define        R367CAB_EQU_MAPPER      0xf484
-#define        F367CAB_QUAD_AUTO       0xf4840080
-#define        F367CAB_QUAD_INV        0xf4840040
-#define        F367CAB_QAM_MODE        0xf4840007
-
-/* EQU_SWEEP_RATE */
-#define        R367CAB_EQU_SWEEP_RATE  0xf485
-#define        F367CAB_SNR_PER 0xf48500c0
-#define        F367CAB_SWEEP_RATE      0xf485003f
-
-/* EQU_SNR_LO */
-#define        R367CAB_EQU_SNR_LO      0xf486
-#define        F367CAB_SNR_LO  0xf48600ff
-
-/* EQU_SNR_HI */
-#define        R367CAB_EQU_SNR_HI      0xf487
-#define        F367CAB_SNR_HI  0xf48700ff
-
-/* EQU_GAMMA_LO */
-#define        R367CAB_EQU_GAMMA_LO    0xf488
-#define        F367CAB_GAMMA_LO        0xf48800ff
-
-/* EQU_GAMMA_HI */
-#define        R367CAB_EQU_GAMMA_HI    0xf489
-#define        F367CAB_GAMMA_ME        0xf48900ff
-
-/* EQU_ERR_GAIN */
-#define        R367CAB_EQU_ERR_GAIN    0xf48a
-#define        F367CAB_EQA1MU  0xf48a0070
-#define        F367CAB_CRL2MU  0xf48a000e
-#define        F367CAB_GAMMA_HI        0xf48a0001
-
-/* EQU_RADIUS */
-#define        R367CAB_EQU_RADIUS      0xf48b
-#define        F367CAB_RADIUS  0xf48b00ff
-
-/* EQU_FFE_MAINTAP */
-#define        R367CAB_EQU_FFE_MAINTAP 0xf48c
-#define        F367CAB_FFE_MAINTAP_INIT        0xf48c00ff
-
-/* EQU_FFE_LEAKAGE */
-#define        R367CAB_EQU_FFE_LEAKAGE 0xf48e
-#define        F367CAB_LEAK_PER        0xf48e00f0
-#define        F367CAB_EQU_OUTSEL      0xf48e0002
-#define        F367CAB_PNT2dFE 0xf48e0001
-
-/* EQU_FFE_MAINTAP_POS */
-#define        R367CAB_EQU_FFE_MAINTAP_POS     0xf48f
-#define        F367CAB_FFE_LEAK_EN     0xf48f0080
-#define        F367CAB_DFE_LEAK_EN     0xf48f0040
-#define        F367CAB_FFE_MAINTAP_POS 0xf48f003f
-
-/* EQU_GAIN_WIDE */
-#define        R367CAB_EQU_GAIN_WIDE   0xf490
-#define        F367CAB_DFE_GAIN_WIDE   0xf49000f0
-#define        F367CAB_FFE_GAIN_WIDE   0xf490000f
-
-/* EQU_GAIN_NARROW */
-#define        R367CAB_EQU_GAIN_NARROW 0xf491
-#define        F367CAB_DFE_GAIN_NARROW 0xf49100f0
-#define        F367CAB_FFE_GAIN_NARROW 0xf491000f
-
-/* EQU_CTR_LPF_GAIN */
-#define        R367CAB_EQU_CTR_LPF_GAIN        0xf492
-#define        F367CAB_CTR_GTO 0xf4920080
-#define        F367CAB_CTR_GDIR        0xf4920070
-#define        F367CAB_SWEEP_EN        0xf4920008
-#define        F367CAB_CTR_GINT        0xf4920007
-
-/* EQU_CRL_LPF_GAIN */
-#define        R367CAB_EQU_CRL_LPF_GAIN        0xf493
-#define        F367CAB_CRL_GTO 0xf4930080
-#define        F367CAB_CRL_GDIR        0xf4930070
-#define        F367CAB_SWEEP_DIR       0xf4930008
-#define        F367CAB_CRL_GINT        0xf4930007
-
-/* EQU_GLOBAL_GAIN */
-#define        R367CAB_EQU_GLOBAL_GAIN 0xf494
-#define        F367CAB_CRL_GAIN        0xf49400f8
-#define        F367CAB_CTR_INC_GAIN    0xf4940004
-#define        F367CAB_CTR_FRAC        0xf4940003
-
-/* EQU_CRL_LD_SEN */
-#define        R367CAB_EQU_CRL_LD_SEN  0xf495
-#define        F367CAB_CTR_BADPOINT_EN 0xf4950080
-#define        F367CAB_CTR_GAIN        0xf4950070
-#define        F367CAB_LIMANEN 0xf4950008
-#define        F367CAB_CRL_LD_SEN      0xf4950007
-
-/* EQU_CRL_LD_VAL */
-#define        R367CAB_EQU_CRL_LD_VAL  0xf496
-#define        F367CAB_CRL_BISTH_LIMIT 0xf4960080
-#define        F367CAB_CARE_EN 0xf4960040
-#define        F367CAB_CRL_LD_PER      0xf4960030
-#define        F367CAB_CRL_LD_WST      0xf496000c
-#define        F367CAB_CRL_LD_TFS      0xf4960003
-
-/* EQU_CRL_TFR */
-#define        R367CAB_EQU_CRL_TFR     0xf497
-#define        F367CAB_CRL_LD_TFR      0xf49700ff
-
-/* EQU_CRL_BISTH_LO */
-#define        R367CAB_EQU_CRL_BISTH_LO        0xf498
-#define        F367CAB_CRL_BISTH_LO    0xf49800ff
-
-/* EQU_CRL_BISTH_HI */
-#define        R367CAB_EQU_CRL_BISTH_HI        0xf499
-#define        F367CAB_CRL_BISTH_HI    0xf49900ff
-
-/* EQU_SWEEP_RANGE_LO */
-#define        R367CAB_EQU_SWEEP_RANGE_LO      0xf49a
-#define        F367CAB_SWEEP_RANGE_LO  0xf49a00ff
-
-/* EQU_SWEEP_RANGE_HI */
-#define        R367CAB_EQU_SWEEP_RANGE_HI      0xf49b
-#define        F367CAB_SWEEP_RANGE_HI  0xf49b00ff
-
-/* EQU_CRL_LIMITER */
-#define        R367CAB_EQU_CRL_LIMITER 0xf49c
-#define        F367CAB_BISECTOR_EN     0xf49c0080
-#define        F367CAB_PHEST128_EN     0xf49c0040
-#define        F367CAB_CRL_LIM 0xf49c003f
-
-/* EQU_MODULUS_MAP */
-#define        R367CAB_EQU_MODULUS_MAP 0xf49d
-#define        F367CAB_PNT_DEPTH       0xf49d00e0
-#define        F367CAB_MODULUS_CMP     0xf49d001f
-
-/* EQU_PNT_GAIN */
-#define        R367CAB_EQU_PNT_GAIN    0xf49e
-#define        F367CAB_PNT_EN  0xf49e0080
-#define        F367CAB_MODULUSMAP_EN   0xf49e0040
-#define        F367CAB_PNT_GAIN        0xf49e003f
-
-/* FEC_AC_CTR_0 */
-#define        R367CAB_FEC_AC_CTR_0    0xf4a8
-#define        F367CAB_BE_BYPASS       0xf4a80020
-#define        F367CAB_REFRESH47       0xf4a80010
-#define        F367CAB_CT_NBST 0xf4a80008
-#define        F367CAB_TEI_ENA 0xf4a80004
-#define        F367CAB_DS_ENA  0xf4a80002
-#define        F367CAB_TSMF_EN 0xf4a80001
-
-/* FEC_AC_CTR_1 */
-#define        R367CAB_FEC_AC_CTR_1    0xf4a9
-#define        F367CAB_DEINT_DEPTH     0xf4a900ff
-
-/* FEC_AC_CTR_2 */
-#define        R367CAB_FEC_AC_CTR_2    0xf4aa
-#define        F367CAB_DEINT_M 0xf4aa00f8
-#define        F367CAB_DIS_UNLOCK      0xf4aa0004
-#define        F367CAB_DESCR_MODE      0xf4aa0003
-
-/* FEC_AC_CTR_3 */
-#define        R367CAB_FEC_AC_CTR_3    0xf4ab
-#define        F367CAB_DI_UNLOCK       0xf4ab0080
-#define        F367CAB_DI_FREEZE       0xf4ab0040
-#define        F367CAB_MISMATCH        0xf4ab0030
-#define        F367CAB_ACQ_MODE        0xf4ab000c
-#define        F367CAB_TRK_MODE        0xf4ab0003
-
-/* FEC_STATUS */
-#define        R367CAB_FEC_STATUS      0xf4ac
-#define        F367CAB_DEINT_SMCNTR    0xf4ac00e0
-#define        F367CAB_DEINT_SYNCSTATE 0xf4ac0018
-#define        F367CAB_DEINT_SYNLOST   0xf4ac0004
-#define        F367CAB_DESCR_SYNCSTATE 0xf4ac0002
-
-/* RS_COUNTER_0 */
-#define        R367CAB_RS_COUNTER_0    0xf4ae
-#define        F367CAB_BK_CT_L 0xf4ae00ff
-
-/* RS_COUNTER_1 */
-#define        R367CAB_RS_COUNTER_1    0xf4af
-#define        F367CAB_BK_CT_H 0xf4af00ff
-
-/* RS_COUNTER_2 */
-#define        R367CAB_RS_COUNTER_2    0xf4b0
-#define        F367CAB_CORR_CT_L       0xf4b000ff
-
-/* RS_COUNTER_3 */
-#define        R367CAB_RS_COUNTER_3    0xf4b1
-#define        F367CAB_CORR_CT_H       0xf4b100ff
-
-/* RS_COUNTER_4 */
-#define        R367CAB_RS_COUNTER_4    0xf4b2
-#define        F367CAB_UNCORR_CT_L     0xf4b200ff
-
-/* RS_COUNTER_5 */
-#define        R367CAB_RS_COUNTER_5    0xf4b3
-#define        F367CAB_UNCORR_CT_H     0xf4b300ff
-
-/* BERT_0 */
-#define        R367CAB_BERT_0  0xf4b4
-#define        F367CAB_RS_NOCORR       0xf4b40004
-#define        F367CAB_CT_HOLD 0xf4b40002
-#define        F367CAB_CT_CLEAR        0xf4b40001
-
-/* BERT_1 */
-#define        R367CAB_BERT_1  0xf4b5
-#define        F367CAB_BERT_ON 0xf4b50020
-#define        F367CAB_BERT_ERR_SRC    0xf4b50010
-#define        F367CAB_BERT_ERR_MODE   0xf4b50008
-#define        F367CAB_BERT_NBYTE      0xf4b50007
-
-/* BERT_2 */
-#define        R367CAB_BERT_2  0xf4b6
-#define        F367CAB_BERT_ERRCOUNT_L 0xf4b600ff
-
-/* BERT_3 */
-#define        R367CAB_BERT_3  0xf4b7
-#define        F367CAB_BERT_ERRCOUNT_H 0xf4b700ff
-
-/* OUTFORMAT_0 */
-#define        R367CAB_OUTFORMAT_0     0xf4b8
-#define        F367CAB_CLK_POLARITY    0xf4b80080
-#define        F367CAB_FEC_TYPE        0xf4b80040
-#define        F367CAB_SYNC_STRIP      0xf4b80008
-#define        F367CAB_TS_SWAP 0xf4b80004
-#define        F367CAB_OUTFORMAT       0xf4b80003
-
-/* OUTFORMAT_1 */
-#define        R367CAB_OUTFORMAT_1     0xf4b9
-#define        F367CAB_CI_DIVRANGE     0xf4b900ff
-
-/* SMOOTHER_2 */
-#define        R367CAB_SMOOTHER_2      0xf4be
-#define        F367CAB_FIFO_BYPASS     0xf4be0020
-
-/* TSMF_CTRL_0 */
-#define        R367CAB_TSMF_CTRL_0     0xf4c0
-#define        F367CAB_TS_NUMBER       0xf4c0001e
-#define        F367CAB_SEL_MODE        0xf4c00001
-
-/* TSMF_CTRL_1 */
-#define        R367CAB_TSMF_CTRL_1     0xf4c1
-#define        F367CAB_CHECK_ERROR_BIT 0xf4c10080
-#define        F367CAB_CHCK_F_SYNC     0xf4c10040
-#define        F367CAB_H_MODE  0xf4c10008
-#define        F367CAB_D_V_MODE        0xf4c10004
-#define        F367CAB_MODE    0xf4c10003
-
-/* TSMF_CTRL_3 */
-#define        R367CAB_TSMF_CTRL_3     0xf4c3
-#define        F367CAB_SYNC_IN_COUNT   0xf4c300f0
-#define        F367CAB_SYNC_OUT_COUNT  0xf4c3000f
-
-/* TS_ON_ID_0 */
-#define        R367CAB_TS_ON_ID_0      0xf4c4
-#define        F367CAB_TS_ID_L 0xf4c400ff
-
-/* TS_ON_ID_1 */
-#define        R367CAB_TS_ON_ID_1      0xf4c5
-#define        F367CAB_TS_ID_H 0xf4c500ff
-
-/* TS_ON_ID_2 */
-#define        R367CAB_TS_ON_ID_2      0xf4c6
-#define        F367CAB_ON_ID_L 0xf4c600ff
-
-/* TS_ON_ID_3 */
-#define        R367CAB_TS_ON_ID_3      0xf4c7
-#define        F367CAB_ON_ID_H 0xf4c700ff
-
-/* RE_STATUS_0 */
-#define        R367CAB_RE_STATUS_0     0xf4c8
-#define        F367CAB_RECEIVE_STATUS_L        0xf4c800ff
-
-/* RE_STATUS_1 */
-#define        R367CAB_RE_STATUS_1     0xf4c9
-#define        F367CAB_RECEIVE_STATUS_LH       0xf4c900ff
-
-/* RE_STATUS_2 */
-#define        R367CAB_RE_STATUS_2     0xf4ca
-#define        F367CAB_RECEIVE_STATUS_HL       0xf4ca00ff
-
-/* RE_STATUS_3 */
-#define        R367CAB_RE_STATUS_3     0xf4cb
-#define        F367CAB_RECEIVE_STATUS_HH       0xf4cb003f
-
-/* TS_STATUS_0 */
-#define        R367CAB_TS_STATUS_0     0xf4cc
-#define        F367CAB_TS_STATUS_L     0xf4cc00ff
-
-/* TS_STATUS_1 */
-#define        R367CAB_TS_STATUS_1     0xf4cd
-#define        F367CAB_TS_STATUS_H     0xf4cd007f
-
-/* TS_STATUS_2 */
-#define        R367CAB_TS_STATUS_2     0xf4ce
-#define        F367CAB_ERROR   0xf4ce0080
-#define        F367CAB_EMERGENCY       0xf4ce0040
-#define        F367CAB_CRE_TS  0xf4ce0030
-#define        F367CAB_VER     0xf4ce000e
-#define        F367CAB_M_LOCK  0xf4ce0001
-
-/* TS_STATUS_3 */
-#define        R367CAB_TS_STATUS_3     0xf4cf
-#define        F367CAB_UPDATE_READY    0xf4cf0080
-#define        F367CAB_END_FRAME_HEADER        0xf4cf0040
-#define        F367CAB_CONTCNT 0xf4cf0020
-#define        F367CAB_TS_IDENTIFIER_SEL       0xf4cf000f
-
-/* T_O_ID_0 */
-#define        R367CAB_T_O_ID_0        0xf4d0
-#define        F367CAB_ON_ID_I_L       0xf4d000ff
-
-/* T_O_ID_1 */
-#define        R367CAB_T_O_ID_1        0xf4d1
-#define        F367CAB_ON_ID_I_H       0xf4d100ff
-
-/* T_O_ID_2 */
-#define        R367CAB_T_O_ID_2        0xf4d2
-#define        F367CAB_TS_ID_I_L       0xf4d200ff
-
-/* T_O_ID_3 */
-#define        R367CAB_T_O_ID_3        0xf4d3
-#define        F367CAB_TS_ID_I_H       0xf4d300ff
-
-#define STV0367CAB_NBREGS      187
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
deleted file mode 100644 (file)
index 91c7ee8..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * stv0900.h
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0900_H
-#define STV0900_H
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-struct stv0900_reg {
-       u16 addr;
-       u8  val;
-};
-
-struct stv0900_config {
-       u8 demod_address;
-       u8 demod_mode;
-       u32 xtal;
-       u8 clkmode;/* 0 for CLKI,  2 for XTALI */
-
-       u8 diseqc_mode;
-
-       u8 path1_mode;
-       u8 path2_mode;
-       struct stv0900_reg *ts_config_regs;
-       u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
-       u8 tun2_maddress;
-       u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
-       u8 tun2_adc;
-       u8 tun1_type;/* for now 3 for stb6100 auto, else - software */
-       u8 tun2_type;
-       /* Set device param to start dma */
-       int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-       /* Hook for Lock LED */
-       void (*set_lock_led)(struct dvb_frontend *fe, int offon);
-};
-
-#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
-                                                       && defined(MODULE))
-extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
-                                       struct i2c_adapter *i2c, int demod);
-#else
-static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
-                                       struct i2c_adapter *i2c, int demod)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
-
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
deleted file mode 100644 (file)
index 7f1bada..0000000
+++ /dev/null
@@ -1,1959 +0,0 @@
-/*
- * stv0900_core.c
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-
-#include "stv0900.h"
-#include "stv0900_reg.h"
-#include "stv0900_priv.h"
-#include "stv0900_init.h"
-
-int stvdebug = 1;
-module_param_named(debug, stvdebug, int, 0644);
-
-/* internal params node */
-struct stv0900_inode {
-       /* pointer for internal params, one for each pair of demods */
-       struct stv0900_internal         *internal;
-       struct stv0900_inode            *next_inode;
-};
-
-/* first internal params */
-static struct stv0900_inode *stv0900_first_inode;
-
-/* find chip by i2c adapter and i2c address */
-static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
-                                                       u8 i2c_addr)
-{
-       struct stv0900_inode *temp_chip = stv0900_first_inode;
-
-       if (temp_chip != NULL) {
-               /*
-                Search of the last stv0900 chip or
-                find it by i2c adapter and i2c address */
-               while ((temp_chip != NULL) &&
-                       ((temp_chip->internal->i2c_adap != i2c_adap) ||
-                       (temp_chip->internal->i2c_addr != i2c_addr)))
-
-                       temp_chip = temp_chip->next_inode;
-
-       }
-
-       return temp_chip;
-}
-
-/* deallocating chip */
-static void remove_inode(struct stv0900_internal *internal)
-{
-       struct stv0900_inode *prev_node = stv0900_first_inode;
-       struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
-                                               internal->i2c_addr);
-
-       if (del_node != NULL) {
-               if (del_node == stv0900_first_inode) {
-                       stv0900_first_inode = del_node->next_inode;
-               } else {
-                       while (prev_node->next_inode != del_node)
-                               prev_node = prev_node->next_inode;
-
-                       if (del_node->next_inode == NULL)
-                               prev_node->next_inode = NULL;
-                       else
-                               prev_node->next_inode =
-                                       prev_node->next_inode->next_inode;
-               }
-
-               kfree(del_node);
-       }
-}
-
-/* allocating new chip */
-static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
-{
-       struct stv0900_inode *new_node = stv0900_first_inode;
-
-       if (new_node == NULL) {
-               new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
-               stv0900_first_inode = new_node;
-       } else {
-               while (new_node->next_inode != NULL)
-                       new_node = new_node->next_inode;
-
-               new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
-                                                               GFP_KERNEL);
-               if (new_node->next_inode != NULL)
-                       new_node = new_node->next_inode;
-               else
-                       new_node = NULL;
-       }
-
-       if (new_node != NULL) {
-               new_node->internal = internal;
-               new_node->next_inode = NULL;
-       }
-
-       return new_node;
-}
-
-s32 ge2comp(s32 a, s32 width)
-{
-       if (width == 32)
-               return a;
-       else
-               return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
-}
-
-void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
-                                                               u8 reg_data)
-{
-       u8 data[3];
-       int ret;
-       struct i2c_msg i2cmsg = {
-               .addr  = intp->i2c_addr,
-               .flags = 0,
-               .len   = 3,
-               .buf   = data,
-       };
-
-       data[0] = MSB(reg_addr);
-       data[1] = LSB(reg_addr);
-       data[2] = reg_data;
-
-       ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
-       if (ret != 1)
-               dprintk("%s: i2c error %d\n", __func__, ret);
-}
-
-u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
-{
-       int ret;
-       u8 b0[] = { MSB(reg), LSB(reg) };
-       u8 buf = 0;
-       struct i2c_msg msg[] = {
-               {
-                       .addr   = intp->i2c_addr,
-                       .flags  = 0,
-                       .buf = b0,
-                       .len = 2,
-               }, {
-                       .addr   = intp->i2c_addr,
-                       .flags  = I2C_M_RD,
-                       .buf = &buf,
-                       .len = 1,
-               },
-       };
-
-       ret = i2c_transfer(intp->i2c_adap, msg, 2);
-       if (ret != 2)
-               dprintk("%s: i2c error %d, reg[0x%02x]\n",
-                               __func__, ret, reg);
-
-       return buf;
-}
-
-static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
-{
-       u8 position = 0, i = 0;
-
-       (*mask) = label & 0xff;
-
-       while ((position == 0) && (i < 8)) {
-               position = ((*mask) >> i) & 0x01;
-               i++;
-       }
-
-       (*pos) = (i - 1);
-}
-
-void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
-{
-       u8 reg, mask, pos;
-
-       reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
-       extract_mask_pos(label, &mask, &pos);
-
-       val = mask & (val << pos);
-
-       reg = (reg & (~mask)) | val;
-       stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
-
-}
-
-u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
-{
-       u8 val = 0xff;
-       u8 mask, pos;
-
-       extract_mask_pos(label, &mask, &pos);
-
-       val = stv0900_read_reg(intp, label >> 16);
-       val = (val & mask) >> pos;
-
-       return val;
-}
-
-static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
-{
-       s32 i;
-
-       if (intp == NULL)
-               return STV0900_INVALID_HANDLE;
-
-       intp->chip_id = stv0900_read_reg(intp, R0900_MID);
-
-       if (intp->errs != STV0900_NO_ERROR)
-               return intp->errs;
-
-       /*Startup sequence*/
-       stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
-       stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
-       msleep(3);
-       stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
-       stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
-       stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
-       stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
-       stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
-       msleep(3);
-       stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
-
-       switch (intp->clkmode) {
-       case 0:
-       case 2:
-               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
-                               | intp->clkmode);
-               break;
-       default:
-               /* preserve SELOSCI bit */
-               i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
-               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
-               break;
-       }
-
-       msleep(3);
-       for (i = 0; i < 181; i++)
-               stv0900_write_reg(intp, STV0900_InitVal[i][0],
-                               STV0900_InitVal[i][1]);
-
-       if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
-               stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
-               for (i = 0; i < 32; i++)
-                       stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
-                                       STV0900_Cut20_AddOnVal[i][1]);
-       }
-
-       stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
-       stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
-
-       stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
-       stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
-
-       stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
-       stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
-
-       stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
-       stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
-
-       return STV0900_NO_ERROR;
-}
-
-static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
-{
-       u32 mclk = 90000000, div = 0, ad_div = 0;
-
-       div = stv0900_get_bits(intp, F0900_M_DIV);
-       ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
-
-       mclk = (div + 1) * ext_clk / ad_div;
-
-       dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
-
-       return mclk;
-}
-
-static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
-{
-       u32 m_div, clk_sel;
-
-       dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
-                       intp->quartz);
-
-       if (intp == NULL)
-               return STV0900_INVALID_HANDLE;
-
-       if (intp->errs)
-               return STV0900_I2C_ERROR;
-
-       clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
-       m_div = ((clk_sel * mclk) / intp->quartz) - 1;
-       stv0900_write_bits(intp, F0900_M_DIV, m_div);
-       intp->mclk = stv0900_get_mclk_freq(intp,
-                                       intp->quartz);
-
-       /*Set the DiseqC frequency to 22KHz */
-       /*
-               Formula:
-               DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
-               DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
-       */
-       m_div = intp->mclk / 704000;
-       stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
-       stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
-
-       stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
-       stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
-
-       if ((intp->errs))
-               return STV0900_I2C_ERROR;
-
-       return STV0900_NO_ERROR;
-}
-
-static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32 lsb, msb, hsb, err_val;
-
-       switch (cntr) {
-       case 0:
-       default:
-               hsb = stv0900_get_bits(intp, ERR_CNT12);
-               msb = stv0900_get_bits(intp, ERR_CNT11);
-               lsb = stv0900_get_bits(intp, ERR_CNT10);
-               break;
-       case 1:
-               hsb = stv0900_get_bits(intp, ERR_CNT22);
-               msb = stv0900_get_bits(intp, ERR_CNT21);
-               lsb = stv0900_get_bits(intp, ERR_CNT20);
-               break;
-       }
-
-       err_val = (hsb << 16) + (msb << 8) + (lsb);
-
-       return err_val;
-}
-
-static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       stv0900_write_bits(intp, I2CT_ON, enable);
-
-       return 0;
-}
-
-static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
-                                       enum fe_stv0900_clock_type path1_ts,
-                                       enum fe_stv0900_clock_type path2_ts)
-{
-
-       dprintk("%s\n", __func__);
-
-       if (intp->chip_id >= 0x20) {
-               switch (path1_ts) {
-               case STV0900_PARALLEL_PUNCT_CLOCK:
-               case STV0900_DVBCI_CLOCK:
-                       switch (path2_ts) {
-                       case STV0900_SERIAL_PUNCT_CLOCK:
-                       case STV0900_SERIAL_CONT_CLOCK:
-                       default:
-                               stv0900_write_reg(intp, R0900_TSGENERAL,
-                                                       0x00);
-                               break;
-                       case STV0900_PARALLEL_PUNCT_CLOCK:
-                       case STV0900_DVBCI_CLOCK:
-                               stv0900_write_reg(intp, R0900_TSGENERAL,
-                                                       0x06);
-                               stv0900_write_bits(intp,
-                                               F0900_P1_TSFIFO_MANSPEED, 3);
-                               stv0900_write_bits(intp,
-                                               F0900_P2_TSFIFO_MANSPEED, 0);
-                               stv0900_write_reg(intp,
-                                               R0900_P1_TSSPEED, 0x14);
-                               stv0900_write_reg(intp,
-                                               R0900_P2_TSSPEED, 0x28);
-                               break;
-                       }
-                       break;
-               case STV0900_SERIAL_PUNCT_CLOCK:
-               case STV0900_SERIAL_CONT_CLOCK:
-               default:
-                       switch (path2_ts) {
-                       case STV0900_SERIAL_PUNCT_CLOCK:
-                       case STV0900_SERIAL_CONT_CLOCK:
-                       default:
-                               stv0900_write_reg(intp,
-                                               R0900_TSGENERAL, 0x0C);
-                               break;
-                       case STV0900_PARALLEL_PUNCT_CLOCK:
-                       case STV0900_DVBCI_CLOCK:
-                               stv0900_write_reg(intp,
-                                               R0900_TSGENERAL, 0x0A);
-                               dprintk("%s: 0x0a\n", __func__);
-                               break;
-                       }
-                       break;
-               }
-       } else {
-               switch (path1_ts) {
-               case STV0900_PARALLEL_PUNCT_CLOCK:
-               case STV0900_DVBCI_CLOCK:
-                       switch (path2_ts) {
-                       case STV0900_SERIAL_PUNCT_CLOCK:
-                       case STV0900_SERIAL_CONT_CLOCK:
-                       default:
-                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
-                                                       0x10);
-                               break;
-                       case STV0900_PARALLEL_PUNCT_CLOCK:
-                       case STV0900_DVBCI_CLOCK:
-                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
-                                                       0x16);
-                               stv0900_write_bits(intp,
-                                               F0900_P1_TSFIFO_MANSPEED, 3);
-                               stv0900_write_bits(intp,
-                                               F0900_P2_TSFIFO_MANSPEED, 0);
-                               stv0900_write_reg(intp, R0900_P1_TSSPEED,
-                                                       0x14);
-                               stv0900_write_reg(intp, R0900_P2_TSSPEED,
-                                                       0x28);
-                               break;
-                       }
-
-                       break;
-               case STV0900_SERIAL_PUNCT_CLOCK:
-               case STV0900_SERIAL_CONT_CLOCK:
-               default:
-                       switch (path2_ts) {
-                       case STV0900_SERIAL_PUNCT_CLOCK:
-                       case STV0900_SERIAL_CONT_CLOCK:
-                       default:
-                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
-                                                       0x14);
-                               break;
-                       case STV0900_PARALLEL_PUNCT_CLOCK:
-                       case STV0900_DVBCI_CLOCK:
-                               stv0900_write_reg(intp, R0900_TSGENERAL1X,
-                                                       0x12);
-                               dprintk("%s: 0x12\n", __func__);
-                               break;
-                       }
-
-                       break;
-               }
-       }
-
-       switch (path1_ts) {
-       case STV0900_PARALLEL_PUNCT_CLOCK:
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
-               break;
-       case STV0900_DVBCI_CLOCK:
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
-               break;
-       case STV0900_SERIAL_PUNCT_CLOCK:
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
-               break;
-       case STV0900_SERIAL_CONT_CLOCK:
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
-               stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
-               break;
-       default:
-               break;
-       }
-
-       switch (path2_ts) {
-       case STV0900_PARALLEL_PUNCT_CLOCK:
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
-               break;
-       case STV0900_DVBCI_CLOCK:
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
-               break;
-       case STV0900_SERIAL_PUNCT_CLOCK:
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
-               break;
-       case STV0900_SERIAL_CONT_CLOCK:
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
-               stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
-               break;
-       default:
-               break;
-       }
-
-       stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
-       stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
-       stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
-       stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
-}
-
-void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
-                                                       u32 bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops *tuner_ops = NULL;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-
-       if (tuner_ops->set_frequency) {
-               if ((tuner_ops->set_frequency(fe, frequency)) < 0)
-                       dprintk("%s: Invalid parameter\n", __func__);
-               else
-                       dprintk("%s: Frequency=%d\n", __func__, frequency);
-
-       }
-
-       if (tuner_ops->set_bandwidth) {
-               if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
-                       dprintk("%s: Invalid parameter\n", __func__);
-               else
-                       dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
-
-       }
-}
-
-void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops *tuner_ops = NULL;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-
-       if (tuner_ops->set_bandwidth) {
-               if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
-                       dprintk("%s: Invalid parameter\n", __func__);
-               else
-                       dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
-
-       }
-}
-
-u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod)
-{
-       u32 freq, round;
-       /*      Formulat :
-       Tuner_Frequency(MHz)    = Regs / 64
-       Tuner_granularity(MHz)  = Regs / 2048
-       real_Tuner_Frequency    = Tuner_Frequency(MHz) - Tuner_granularity(MHz)
-       */
-       freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) +
-               (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) +
-               stv0900_get_bits(intp, TUN_RFFREQ0);
-
-       freq = (freq * 1000) / 64;
-
-       round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) +
-               stv0900_get_bits(intp, TUN_RFRESTE0);
-
-       round = (round * 1000) / 2048;
-
-       return freq + round;
-}
-
-void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
-                                               u32 Bandwidth, int demod)
-{
-       u32 tunerFrequency;
-       /* Formulat:
-       Tuner_frequency_reg= Frequency(MHz)*64
-       */
-       tunerFrequency = (Frequency * 64) / 1000;
-
-       stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10));
-       stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff);
-       stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03));
-       /* Low Pass Filter = BW /2 (MHz)*/
-       stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000);
-       /* Tuner Write trig */
-       stv0900_write_reg(intp, TNRLD, 1);
-}
-
-static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
-                               const struct stv0900_table *lookup,
-                               enum fe_stv0900_demod_num demod)
-{
-       s32 agc_gain = 0,
-               imin,
-               imax,
-               i,
-               rf_lvl = 0;
-
-       dprintk("%s\n", __func__);
-
-       if ((lookup == NULL) || (lookup->size <= 0))
-               return 0;
-
-       agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
-                               stv0900_get_bits(intp, AGCIQ_VALUE0));
-
-       imin = 0;
-       imax = lookup->size - 1;
-       if (INRANGE(lookup->table[imin].regval, agc_gain,
-                                       lookup->table[imax].regval)) {
-               while ((imax - imin) > 1) {
-                       i = (imax + imin) >> 1;
-
-                       if (INRANGE(lookup->table[imin].regval,
-                                       agc_gain,
-                                       lookup->table[i].regval))
-                               imax = i;
-                       else
-                               imin = i;
-               }
-
-               rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
-               rf_lvl *= (lookup->table[imax].realval -
-                               lookup->table[imin].realval);
-               rf_lvl /= (lookup->table[imax].regval -
-                               lookup->table[imin].regval);
-               rf_lvl += lookup->table[imin].realval;
-       } else if (agc_gain > lookup->table[0].regval)
-               rf_lvl = 5;
-       else if (agc_gain < lookup->table[lookup->size-1].regval)
-               rf_lvl = -100;
-
-       dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
-
-       return rf_lvl;
-}
-
-static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *internal = state->internal;
-       s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
-                                                               state->demod);
-
-       rflevel = (rflevel + 100) * (65535 / 70);
-       if (rflevel < 0)
-               rflevel = 0;
-
-       if (rflevel > 65535)
-               rflevel = 65535;
-
-       *strength = rflevel;
-
-       return 0;
-}
-
-static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
-                                       const struct stv0900_table *lookup)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       s32     c_n = -100,
-               regval,
-               imin,
-               imax,
-               i,
-               noise_field1,
-               noise_field0;
-
-       dprintk("%s\n", __func__);
-
-       if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
-               noise_field1 = NOSPLHT_NORMED1;
-               noise_field0 = NOSPLHT_NORMED0;
-       } else {
-               noise_field1 = NOSDATAT_NORMED1;
-               noise_field0 = NOSDATAT_NORMED0;
-       }
-
-       if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
-               if ((lookup != NULL) && lookup->size) {
-                       regval = 0;
-                       msleep(5);
-                       for (i = 0; i < 16; i++) {
-                               regval += MAKEWORD(stv0900_get_bits(intp,
-                                                               noise_field1),
-                                               stv0900_get_bits(intp,
-                                                               noise_field0));
-                               msleep(1);
-                       }
-
-                       regval /= 16;
-                       imin = 0;
-                       imax = lookup->size - 1;
-                       if (INRANGE(lookup->table[imin].regval,
-                                       regval,
-                                       lookup->table[imax].regval)) {
-                               while ((imax - imin) > 1) {
-                                       i = (imax + imin) >> 1;
-                                       if (INRANGE(lookup->table[imin].regval,
-                                                   regval,
-                                                   lookup->table[i].regval))
-                                               imax = i;
-                                       else
-                                               imin = i;
-                               }
-
-                               c_n = ((regval - lookup->table[imin].regval)
-                                               * (lookup->table[imax].realval
-                                               - lookup->table[imin].realval)
-                                               / (lookup->table[imax].regval
-                                               - lookup->table[imin].regval))
-                                               + lookup->table[imin].realval;
-                       } else if (regval < lookup->table[imin].regval)
-                               c_n = 1000;
-               }
-       }
-
-       return c_n;
-}
-
-static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       u8 err_val1, err_val0;
-       u32 header_err_val = 0;
-
-       *ucblocks = 0x0;
-       if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
-               /* DVB-S2 delineator errors count */
-
-               /* retreiving number for errnous headers */
-               err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
-               err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
-               header_err_val = (err_val1 << 8) | err_val0;
-
-               /* retreiving number for errnous packets */
-               err_val1 = stv0900_read_reg(intp, UPCRCKO1);
-               err_val0 = stv0900_read_reg(intp, UPCRCKO0);
-               *ucblocks = (err_val1 << 8) | err_val0;
-               *ucblocks += header_err_val;
-       }
-
-       return 0;
-}
-
-static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       s32 snrlcl = stv0900_carr_get_quality(fe,
-                       (const struct stv0900_table *)&stv0900_s2_cn);
-       snrlcl = (snrlcl + 30) * 384;
-       if (snrlcl < 0)
-               snrlcl = 0;
-
-       if (snrlcl > 65535)
-               snrlcl = 65535;
-
-       *snr = snrlcl;
-
-       return 0;
-}
-
-static u32 stv0900_get_ber(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       u32 ber = 10000000, i;
-       s32 demod_state;
-
-       demod_state = stv0900_get_bits(intp, HEADER_MODE);
-
-       switch (demod_state) {
-       case STV0900_SEARCH:
-       case STV0900_PLH_DETECTED:
-       default:
-               ber = 10000000;
-               break;
-       case STV0900_DVBS_FOUND:
-               ber = 0;
-               for (i = 0; i < 5; i++) {
-                       msleep(5);
-                       ber += stv0900_get_err_count(intp, 0, demod);
-               }
-
-               ber /= 5;
-               if (stv0900_get_bits(intp, PRFVIT)) {
-                       ber *= 9766;
-                       ber = ber >> 13;
-               }
-
-               break;
-       case STV0900_DVBS2_FOUND:
-               ber = 0;
-               for (i = 0; i < 5; i++) {
-                       msleep(5);
-                       ber += stv0900_get_err_count(intp, 0, demod);
-               }
-
-               ber /= 5;
-               if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
-                       ber *= 9766;
-                       ber = ber >> 13;
-               }
-
-               break;
-       }
-
-       return ber;
-}
-
-static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *internal = state->internal;
-
-       *ber = stv0900_get_ber(internal, state->demod);
-
-       return 0;
-}
-
-int stv0900_get_demod_lock(struct stv0900_internal *intp,
-                       enum fe_stv0900_demod_num demod, s32 time_out)
-{
-       s32 timer = 0,
-               lock = 0;
-
-       enum fe_stv0900_search_state    dmd_state;
-
-       while ((timer < time_out) && (lock == 0)) {
-               dmd_state = stv0900_get_bits(intp, HEADER_MODE);
-               dprintk("Demod State = %d\n", dmd_state);
-               switch (dmd_state) {
-               case STV0900_SEARCH:
-               case STV0900_PLH_DETECTED:
-               default:
-                       lock = 0;
-                       break;
-               case STV0900_DVBS2_FOUND:
-               case STV0900_DVBS_FOUND:
-                       lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
-                       break;
-               }
-
-               if (lock == 0)
-                       msleep(10);
-
-               timer += 10;
-       }
-
-       if (lock)
-               dprintk("DEMOD LOCK OK\n");
-       else
-               dprintk("DEMOD LOCK FAIL\n");
-
-       return lock;
-}
-
-void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       s32 regflist,
-       i;
-
-       dprintk("%s\n", __func__);
-
-       regflist = MODCODLST0;
-
-       for (i = 0; i < 16; i++)
-               stv0900_write_reg(intp, regflist + i, 0xff);
-}
-
-void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       u32 matype,
-               mod_code,
-               fmod,
-               reg_index,
-               field_index;
-
-       dprintk("%s\n", __func__);
-
-       if (intp->chip_id <= 0x11) {
-               msleep(5);
-
-               mod_code = stv0900_read_reg(intp, PLHMODCOD);
-               matype = mod_code & 0x3;
-               mod_code = (mod_code & 0x7f) >> 2;
-
-               reg_index = MODCODLSTF - mod_code / 2;
-               field_index = mod_code % 2;
-
-               switch (matype) {
-               case 0:
-               default:
-                       fmod = 14;
-                       break;
-               case 1:
-                       fmod = 13;
-                       break;
-               case 2:
-                       fmod = 11;
-                       break;
-               case 3:
-                       fmod = 7;
-                       break;
-               }
-
-               if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
-                                               && (matype <= 1)) {
-                       if (field_index == 0)
-                               stv0900_write_reg(intp, reg_index,
-                                                       0xf0 | fmod);
-                       else
-                               stv0900_write_reg(intp, reg_index,
-                                                       (fmod << 4) | 0xf);
-               }
-
-       } else if (intp->chip_id >= 0x12) {
-               for (reg_index = 0; reg_index < 7; reg_index++)
-                       stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
-
-               stv0900_write_reg(intp, MODCODLSTE, 0xff);
-               stv0900_write_reg(intp, MODCODLSTF, 0xcf);
-               for (reg_index = 0; reg_index < 8; reg_index++)
-                       stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
-
-
-       }
-}
-
-void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32 reg_index;
-
-       dprintk("%s\n", __func__);
-
-       stv0900_write_reg(intp, MODCODLST0, 0xff);
-       stv0900_write_reg(intp, MODCODLST1, 0xf0);
-       stv0900_write_reg(intp, MODCODLSTF, 0x0f);
-       for (reg_index = 0; reg_index < 13; reg_index++)
-               stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
-
-}
-
-static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-void stv0900_start_search(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       u32 freq;
-       s16 freq_s16 ;
-
-       stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
-       if (intp->chip_id == 0x10)
-               stv0900_write_reg(intp, CORRELEXP, 0xaa);
-
-       if (intp->chip_id < 0x20)
-               stv0900_write_reg(intp, CARHDR, 0x55);
-
-       if (intp->chip_id <= 0x20) {
-               if (intp->symbol_rate[0] <= 5000000) {
-                       stv0900_write_reg(intp, CARCFG, 0x44);
-                       stv0900_write_reg(intp, CFRUP1, 0x0f);
-                       stv0900_write_reg(intp, CFRUP0, 0xff);
-                       stv0900_write_reg(intp, CFRLOW1, 0xf0);
-                       stv0900_write_reg(intp, CFRLOW0, 0x00);
-                       stv0900_write_reg(intp, RTCS2, 0x68);
-               } else {
-                       stv0900_write_reg(intp, CARCFG, 0xc4);
-                       stv0900_write_reg(intp, RTCS2, 0x44);
-               }
-
-       } else { /*cut 3.0 above*/
-               if (intp->symbol_rate[demod] <= 5000000)
-                       stv0900_write_reg(intp, RTCS2, 0x68);
-               else
-                       stv0900_write_reg(intp, RTCS2, 0x44);
-
-               stv0900_write_reg(intp, CARCFG, 0x46);
-               if (intp->srch_algo[demod] == STV0900_WARM_START) {
-                       freq = 1000 << 16;
-                       freq /= (intp->mclk / 1000);
-                       freq_s16 = (s16)freq;
-               } else {
-                       freq = (intp->srch_range[demod] / 2000);
-                       if (intp->symbol_rate[demod] <= 5000000)
-                               freq += 80;
-                       else
-                               freq += 600;
-
-                       freq = freq << 16;
-                       freq /= (intp->mclk / 1000);
-                       freq_s16 = (s16)freq;
-               }
-
-               stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
-               stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
-               freq_s16 *= (-1);
-               stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
-               stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
-       }
-
-       stv0900_write_reg(intp, CFRINIT1, 0);
-       stv0900_write_reg(intp, CFRINIT0, 0);
-
-       if (intp->chip_id >= 0x20) {
-               stv0900_write_reg(intp, EQUALCFG, 0x41);
-               stv0900_write_reg(intp, FFECFG, 0x41);
-
-               if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
-                       (intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
-                       (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
-                       stv0900_write_reg(intp, VITSCALE,
-                                                               0x82);
-                       stv0900_write_reg(intp, VAVSRVIT, 0x0);
-               }
-       }
-
-       stv0900_write_reg(intp, SFRSTEP, 0x00);
-       stv0900_write_reg(intp, TMGTHRISE, 0xe0);
-       stv0900_write_reg(intp, TMGTHFALL, 0xc0);
-       stv0900_write_bits(intp, SCAN_ENABLE, 0);
-       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-       stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
-       stv0900_write_reg(intp, RTC, 0x88);
-       if (intp->chip_id >= 0x20) {
-               if (intp->symbol_rate[demod] < 2000000) {
-                       if (intp->chip_id <= 0x20)
-                               stv0900_write_reg(intp, CARFREQ, 0x39);
-                       else  /*cut 3.0*/
-                               stv0900_write_reg(intp, CARFREQ, 0x89);
-
-                       stv0900_write_reg(intp, CARHDR, 0x40);
-               } else if (intp->symbol_rate[demod] < 10000000) {
-                       stv0900_write_reg(intp, CARFREQ, 0x4c);
-                       stv0900_write_reg(intp, CARHDR, 0x20);
-               } else {
-                       stv0900_write_reg(intp, CARFREQ, 0x4b);
-                       stv0900_write_reg(intp, CARHDR, 0x20);
-               }
-
-       } else {
-               if (intp->symbol_rate[demod] < 10000000)
-                       stv0900_write_reg(intp, CARFREQ, 0xef);
-               else
-                       stv0900_write_reg(intp, CARFREQ, 0xed);
-       }
-
-       switch (intp->srch_algo[demod]) {
-       case STV0900_WARM_START:
-               stv0900_write_reg(intp, DMDISTATE, 0x1f);
-               stv0900_write_reg(intp, DMDISTATE, 0x18);
-               break;
-       case STV0900_COLD_START:
-               stv0900_write_reg(intp, DMDISTATE, 0x1f);
-               stv0900_write_reg(intp, DMDISTATE, 0x15);
-               break;
-       default:
-               break;
-       }
-}
-
-u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
-                                                       s32 pilot, u8 chip_id)
-{
-       u8 aclc_value = 0x29;
-       s32 i;
-       const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
-
-       dprintk("%s\n", __func__);
-
-       if (chip_id <= 0x12) {
-               cls2 = FE_STV0900_S2CarLoop;
-               cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
-               cllas2 = FE_STV0900_S2APSKCarLoopCut30;
-       } else if (chip_id == 0x20) {
-               cls2 = FE_STV0900_S2CarLoopCut20;
-               cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
-               cllas2 = FE_STV0900_S2APSKCarLoopCut20;
-       } else {
-               cls2 = FE_STV0900_S2CarLoopCut30;
-               cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
-               cllas2 = FE_STV0900_S2APSKCarLoopCut30;
-       }
-
-       if (modcode < STV0900_QPSK_12) {
-               i = 0;
-               while ((i < 3) && (modcode != cllqs2[i].modcode))
-                       i++;
-
-               if (i >= 3)
-                       i = 2;
-       } else {
-               i = 0;
-               while ((i < 14) && (modcode != cls2[i].modcode))
-                       i++;
-
-               if (i >= 14) {
-                       i = 0;
-                       while ((i < 11) && (modcode != cllas2[i].modcode))
-                               i++;
-
-                       if (i >= 11)
-                               i = 10;
-               }
-       }
-
-       if (modcode <= STV0900_QPSK_25) {
-               if (pilot) {
-                       if (srate <= 3000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_on_2;
-                       else if (srate <= 7000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_on_5;
-                       else if (srate <= 15000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_on_10;
-                       else if (srate <= 25000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_on_20;
-                       else
-                               aclc_value = cllqs2[i].car_loop_pilots_on_30;
-               } else {
-                       if (srate <= 3000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_off_2;
-                       else if (srate <= 7000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_off_5;
-                       else if (srate <= 15000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_off_10;
-                       else if (srate <= 25000000)
-                               aclc_value = cllqs2[i].car_loop_pilots_off_20;
-                       else
-                               aclc_value = cllqs2[i].car_loop_pilots_off_30;
-               }
-
-       } else if (modcode <= STV0900_8PSK_910) {
-               if (pilot) {
-                       if (srate <= 3000000)
-                               aclc_value = cls2[i].car_loop_pilots_on_2;
-                       else if (srate <= 7000000)
-                               aclc_value = cls2[i].car_loop_pilots_on_5;
-                       else if (srate <= 15000000)
-                               aclc_value = cls2[i].car_loop_pilots_on_10;
-                       else if (srate <= 25000000)
-                               aclc_value = cls2[i].car_loop_pilots_on_20;
-                       else
-                               aclc_value = cls2[i].car_loop_pilots_on_30;
-               } else {
-                       if (srate <= 3000000)
-                               aclc_value = cls2[i].car_loop_pilots_off_2;
-                       else if (srate <= 7000000)
-                               aclc_value = cls2[i].car_loop_pilots_off_5;
-                       else if (srate <= 15000000)
-                               aclc_value = cls2[i].car_loop_pilots_off_10;
-                       else if (srate <= 25000000)
-                               aclc_value = cls2[i].car_loop_pilots_off_20;
-                       else
-                               aclc_value = cls2[i].car_loop_pilots_off_30;
-               }
-
-       } else {
-               if (srate <= 3000000)
-                       aclc_value = cllas2[i].car_loop_pilots_on_2;
-               else if (srate <= 7000000)
-                       aclc_value = cllas2[i].car_loop_pilots_on_5;
-               else if (srate <= 15000000)
-                       aclc_value = cllas2[i].car_loop_pilots_on_10;
-               else if (srate <= 25000000)
-                       aclc_value = cllas2[i].car_loop_pilots_on_20;
-               else
-                       aclc_value = cllas2[i].car_loop_pilots_on_30;
-       }
-
-       return aclc_value;
-}
-
-u8 stv0900_get_optim_short_carr_loop(s32 srate,
-                               enum fe_stv0900_modulation modulation,
-                               u8 chip_id)
-{
-       const struct stv0900_short_frames_car_loop_optim *s2scl;
-       const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
-       s32 mod_index = 0;
-       u8 aclc_value = 0x0b;
-
-       dprintk("%s\n", __func__);
-
-       s2scl = FE_STV0900_S2ShortCarLoop;
-       s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
-
-       switch (modulation) {
-       case STV0900_QPSK:
-       default:
-               mod_index = 0;
-               break;
-       case STV0900_8PSK:
-               mod_index = 1;
-               break;
-       case STV0900_16APSK:
-               mod_index = 2;
-               break;
-       case STV0900_32APSK:
-               mod_index = 3;
-               break;
-       }
-
-       if (chip_id >= 0x30) {
-               if (srate <= 3000000)
-                       aclc_value = s2sclc30[mod_index].car_loop_2;
-               else if (srate <= 7000000)
-                       aclc_value = s2sclc30[mod_index].car_loop_5;
-               else if (srate <= 15000000)
-                       aclc_value = s2sclc30[mod_index].car_loop_10;
-               else if (srate <= 25000000)
-                       aclc_value = s2sclc30[mod_index].car_loop_20;
-               else
-                       aclc_value = s2sclc30[mod_index].car_loop_30;
-
-       } else if (chip_id >= 0x20) {
-               if (srate <= 3000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut20_2;
-               else if (srate <= 7000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut20_5;
-               else if (srate <= 15000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut20_10;
-               else if (srate <= 25000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut20_20;
-               else
-                       aclc_value = s2scl[mod_index].car_loop_cut20_30;
-
-       } else {
-               if (srate <= 3000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut12_2;
-               else if (srate <= 7000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut12_5;
-               else if (srate <= 15000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut12_10;
-               else if (srate <= 25000000)
-                       aclc_value = s2scl[mod_index].car_loop_cut12_20;
-               else
-                       aclc_value = s2scl[mod_index].car_loop_cut12_30;
-
-       }
-
-       return aclc_value;
-}
-
-static
-enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_mode LDPC_Mode,
-                                       enum fe_stv0900_demod_num demod)
-{
-       enum fe_stv0900_error error = STV0900_NO_ERROR;
-       s32 reg_ind;
-
-       dprintk("%s\n", __func__);
-
-       switch (LDPC_Mode) {
-       case STV0900_DUAL:
-       default:
-               if ((intp->demod_mode != STV0900_DUAL)
-                       || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
-                       stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
-
-                       intp->demod_mode = STV0900_DUAL;
-
-                       stv0900_write_bits(intp, F0900_FRESFEC, 1);
-                       stv0900_write_bits(intp, F0900_FRESFEC, 0);
-
-                       for (reg_ind = 0; reg_ind < 7; reg_ind++)
-                               stv0900_write_reg(intp,
-                                               R0900_P1_MODCODLST0 + reg_ind,
-                                               0xff);
-                       for (reg_ind = 0; reg_ind < 8; reg_ind++)
-                               stv0900_write_reg(intp,
-                                               R0900_P1_MODCODLST7 + reg_ind,
-                                               0xcc);
-
-                       stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
-                       stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
-
-                       for (reg_ind = 0; reg_ind < 7; reg_ind++)
-                               stv0900_write_reg(intp,
-                                               R0900_P2_MODCODLST0 + reg_ind,
-                                               0xff);
-                       for (reg_ind = 0; reg_ind < 8; reg_ind++)
-                               stv0900_write_reg(intp,
-                                               R0900_P2_MODCODLST7 + reg_ind,
-                                               0xcc);
-
-                       stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
-                       stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
-               }
-
-               break;
-       case STV0900_SINGLE:
-               if (demod == STV0900_DEMOD_2) {
-                       stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
-                       stv0900_activate_s2_modcod_single(intp,
-                                                       STV0900_DEMOD_2);
-                       stv0900_write_reg(intp, R0900_GENCFG, 0x06);
-               } else {
-                       stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
-                       stv0900_activate_s2_modcod_single(intp,
-                                                       STV0900_DEMOD_1);
-                       stv0900_write_reg(intp, R0900_GENCFG, 0x04);
-               }
-
-               intp->demod_mode = STV0900_SINGLE;
-
-               stv0900_write_bits(intp, F0900_FRESFEC, 1);
-               stv0900_write_bits(intp, F0900_FRESFEC, 0);
-               stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
-               stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
-               stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
-               stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
-               break;
-       }
-
-       return error;
-}
-
-static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
-                                       struct stv0900_init_params *p_init)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       enum fe_stv0900_error error = STV0900_NO_ERROR;
-       enum fe_stv0900_error demodError = STV0900_NO_ERROR;
-       struct stv0900_internal *intp = NULL;
-       int selosci, i;
-
-       struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
-                                               state->config->demod_address);
-
-       dprintk("%s\n", __func__);
-
-       if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
-               state->internal = temp_int->internal;
-               (state->internal->dmds_used)++;
-               dprintk("%s: Find Internal Structure!\n", __func__);
-               return STV0900_NO_ERROR;
-       } else {
-               state->internal = kmalloc(sizeof(struct stv0900_internal),
-                                                               GFP_KERNEL);
-               if (state->internal == NULL)
-                       return STV0900_INVALID_HANDLE;
-               temp_int = append_internal(state->internal);
-               if (temp_int == NULL) {
-                       kfree(state->internal);
-                       state->internal = NULL;
-                       return STV0900_INVALID_HANDLE;
-               }
-               state->internal->dmds_used = 1;
-               state->internal->i2c_adap = state->i2c_adap;
-               state->internal->i2c_addr = state->config->demod_address;
-               state->internal->clkmode = state->config->clkmode;
-               state->internal->errs = STV0900_NO_ERROR;
-               dprintk("%s: Create New Internal Structure!\n", __func__);
-       }
-
-       if (state->internal == NULL) {
-               error = STV0900_INVALID_HANDLE;
-               return error;
-       }
-
-       demodError = stv0900_initialize(state->internal);
-       if (demodError == STV0900_NO_ERROR) {
-                       error = STV0900_NO_ERROR;
-       } else {
-               if (demodError == STV0900_INVALID_HANDLE)
-                       error = STV0900_INVALID_HANDLE;
-               else
-                       error = STV0900_I2C_ERROR;
-
-               return error;
-       }
-
-       intp = state->internal;
-
-       intp->demod_mode = p_init->demod_mode;
-       stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1);
-       intp->chip_id = stv0900_read_reg(intp, R0900_MID);
-       intp->rolloff = p_init->rolloff;
-       intp->quartz = p_init->dmd_ref_clk;
-
-       stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
-       stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
-
-       intp->ts_config = p_init->ts_config;
-       if (intp->ts_config == NULL)
-               stv0900_set_ts_parallel_serial(intp,
-                               p_init->path1_ts_clock,
-                               p_init->path2_ts_clock);
-       else {
-               for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
-                       stv0900_write_reg(intp,
-                                       intp->ts_config[i].addr,
-                                       intp->ts_config[i].val);
-
-               stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
-               stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
-               stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
-               stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
-       }
-
-       intp->tuner_type[0] = p_init->tuner1_type;
-       intp->tuner_type[1] = p_init->tuner2_type;
-       /* tuner init */
-       switch (p_init->tuner1_type) {
-       case 3: /*FE_AUTO_STB6100:*/
-               stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c);
-               stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86);
-               stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18);
-               stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */
-               stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05);
-               stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17);
-               stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f);
-               stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0);
-               stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3);
-               break;
-       /* case FE_SW_TUNER: */
-       default:
-               stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6);
-               break;
-       }
-
-       stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
-       switch (p_init->tuner1_adc) {
-       case 1:
-               stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
-               break;
-       default:
-               break;
-       }
-
-       stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */
-
-       /* tuner init */
-       switch (p_init->tuner2_type) {
-       case 3: /*FE_AUTO_STB6100:*/
-               stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c);
-               stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86);
-               stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18);
-               stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */
-               stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05);
-               stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17);
-               stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f);
-               stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0);
-               stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3);
-               break;
-       /* case FE_SW_TUNER: */
-       default:
-               stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6);
-               break;
-       }
-
-       stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
-       switch (p_init->tuner2_adc) {
-       case 1:
-               stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
-               break;
-       default:
-               break;
-       }
-
-       stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */
-
-       stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
-       stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
-       stv0900_set_mclk(intp, 135000000);
-       msleep(3);
-
-       switch (intp->clkmode) {
-       case 0:
-       case 2:
-               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
-               break;
-       default:
-               selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
-               stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
-               break;
-       }
-       msleep(3);
-
-       intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
-       if (intp->errs)
-               error = STV0900_I2C_ERROR;
-
-       return error;
-}
-
-static int stv0900_status(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       enum fe_stv0900_search_state demod_state;
-       int locked = FALSE;
-       u8 tsbitrate0_val, tsbitrate1_val;
-       s32 bitrate;
-
-       demod_state = stv0900_get_bits(intp, HEADER_MODE);
-       switch (demod_state) {
-       case STV0900_SEARCH:
-       case STV0900_PLH_DETECTED:
-       default:
-               locked = FALSE;
-               break;
-       case STV0900_DVBS2_FOUND:
-               locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
-                               stv0900_get_bits(intp, PKTDELIN_LOCK) &&
-                               stv0900_get_bits(intp, TSFIFO_LINEOK);
-               break;
-       case STV0900_DVBS_FOUND:
-               locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
-                               stv0900_get_bits(intp, LOCKEDVIT) &&
-                               stv0900_get_bits(intp, TSFIFO_LINEOK);
-               break;
-       }
-
-       dprintk("%s: locked = %d\n", __func__, locked);
-
-       if (stvdebug) {
-               /* Print TS bitrate */
-               tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
-               tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
-               /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
-               bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
-                       * (tsbitrate1_val << 8 | tsbitrate0_val);
-               bitrate /= 16384;
-               dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
-       };
-
-       return locked;
-}
-
-static enum dvbfe_search stv0900_search(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
-       struct stv0900_search_params p_search;
-       struct stv0900_signal_info p_result = intp->result[demod];
-
-       enum fe_stv0900_error error = STV0900_NO_ERROR;
-
-       dprintk("%s: ", __func__);
-
-       if (!(INRANGE(100000, c->symbol_rate, 70000000)))
-               return DVBFE_ALGO_SEARCH_FAILED;
-
-       if (state->config->set_ts_params)
-               state->config->set_ts_params(fe, 0);
-
-       p_result.locked = FALSE;
-       p_search.path = demod;
-       p_search.frequency = c->frequency;
-       p_search.symbol_rate = c->symbol_rate;
-       p_search.search_range = 10000000;
-       p_search.fec = STV0900_FEC_UNKNOWN;
-       p_search.standard = STV0900_AUTO_SEARCH;
-       p_search.iq_inversion = STV0900_IQ_AUTO;
-       p_search.search_algo = STV0900_BLIND_SEARCH;
-       /* Speeds up DVB-S searching */
-       if (c->delivery_system == SYS_DVBS)
-               p_search.standard = STV0900_SEARCH_DVBS1;
-
-       intp->srch_standard[demod] = p_search.standard;
-       intp->symbol_rate[demod] = p_search.symbol_rate;
-       intp->srch_range[demod] = p_search.search_range;
-       intp->freq[demod] = p_search.frequency;
-       intp->srch_algo[demod] = p_search.search_algo;
-       intp->srch_iq_inv[demod] = p_search.iq_inversion;
-       intp->fec[demod] = p_search.fec;
-       if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
-                               (intp->errs == STV0900_NO_ERROR)) {
-               p_result.locked = intp->result[demod].locked;
-               p_result.standard = intp->result[demod].standard;
-               p_result.frequency = intp->result[demod].frequency;
-               p_result.symbol_rate = intp->result[demod].symbol_rate;
-               p_result.fec = intp->result[demod].fec;
-               p_result.modcode = intp->result[demod].modcode;
-               p_result.pilot = intp->result[demod].pilot;
-               p_result.frame_len = intp->result[demod].frame_len;
-               p_result.spectrum = intp->result[demod].spectrum;
-               p_result.rolloff = intp->result[demod].rolloff;
-               p_result.modulation = intp->result[demod].modulation;
-       } else {
-               p_result.locked = FALSE;
-               switch (intp->err[demod]) {
-               case STV0900_I2C_ERROR:
-                       error = STV0900_I2C_ERROR;
-                       break;
-               case STV0900_NO_ERROR:
-               default:
-                       error = STV0900_SEARCH_FAILED;
-                       break;
-               }
-       }
-
-       if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
-               dprintk("Search Success\n");
-               return DVBFE_ALGO_SEARCH_SUCCESS;
-       } else {
-               dprintk("Search Fail\n");
-               return DVBFE_ALGO_SEARCH_FAILED;
-       }
-
-}
-
-static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-
-       dprintk("%s: ", __func__);
-
-       if ((stv0900_status(state->internal, state->demod)) == TRUE) {
-               dprintk("DEMOD LOCK OK\n");
-               *status = FE_HAS_CARRIER
-                       | FE_HAS_VITERBI
-                       | FE_HAS_SYNC
-                       | FE_HAS_LOCK;
-               if (state->config->set_lock_led)
-                       state->config->set_lock_led(fe, 1);
-       } else {
-               *status = 0;
-               if (state->config->set_lock_led)
-                       state->config->set_lock_led(fe, 0);
-               dprintk("DEMOD LOCK FAIL\n");
-       }
-
-       return 0;
-}
-
-static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
-{
-
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       if (stop_ts == TRUE)
-               stv0900_write_bits(intp, RST_HWARE, 1);
-       else
-               stv0900_write_bits(intp, RST_HWARE, 0);
-
-       return 0;
-}
-
-static int stv0900_diseqc_init(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
-       stv0900_write_bits(intp, DISEQC_RESET, 1);
-       stv0900_write_bits(intp, DISEQC_RESET, 0);
-
-       return 0;
-}
-
-static int stv0900_init(struct dvb_frontend *fe)
-{
-       dprintk("%s\n", __func__);
-
-       stv0900_stop_ts(fe, 1);
-       stv0900_diseqc_init(fe);
-
-       return 0;
-}
-
-static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
-                               u32 NbData, enum fe_stv0900_demod_num demod)
-{
-       s32 i = 0;
-
-       stv0900_write_bits(intp, DIS_PRECHARGE, 1);
-       while (i < NbData) {
-               while (stv0900_get_bits(intp, FIFO_FULL))
-                       ;/* checkpatch complains */
-               stv0900_write_reg(intp, DISTXDATA, data[i]);
-               i++;
-       }
-
-       stv0900_write_bits(intp, DIS_PRECHARGE, 0);
-       i = 0;
-       while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
-               msleep(10);
-               i++;
-       }
-
-       return 0;
-}
-
-static int stv0900_send_master_cmd(struct dvb_frontend *fe,
-                                       struct dvb_diseqc_master_cmd *cmd)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-
-       return stv0900_diseqc_send(state->internal,
-                               cmd->msg,
-                               cmd->msg_len,
-                               state->demod);
-}
-
-static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       u8 data;
-
-
-       switch (burst) {
-       case SEC_MINI_A:
-               stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
-               data = 0x00;
-               stv0900_diseqc_send(intp, &data, 1, state->demod);
-               break;
-       case SEC_MINI_B:
-               stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
-               data = 0xff;
-               stv0900_diseqc_send(intp, &data, 1, state->demod);
-               break;
-       }
-
-       return 0;
-}
-
-static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
-                               struct dvb_diseqc_slave_reply *reply)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       s32 i = 0;
-
-       reply->msg_len = 0;
-
-       while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
-               msleep(10);
-               i++;
-       }
-
-       if (stv0900_get_bits(intp, RX_END)) {
-               reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
-
-               for (i = 0; i < reply->msg_len; i++)
-                       reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
-       }
-
-       return 0;
-}
-
-static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
-
-       switch (toneoff) {
-       case SEC_TONE_ON:
-               /*Set the DiseqC mode to 22Khz _continues_ tone*/
-               stv0900_write_bits(intp, DISTX_MODE, 0);
-               stv0900_write_bits(intp, DISEQC_RESET, 1);
-               /*release DiseqC reset to enable the 22KHz tone*/
-               stv0900_write_bits(intp, DISEQC_RESET, 0);
-               break;
-       case SEC_TONE_OFF:
-               /*return diseqc mode to config->diseqc_mode.
-               Usually it's without _continues_ tone */
-               stv0900_write_bits(intp, DISTX_MODE,
-                               state->config->diseqc_mode);
-               /*maintain the DiseqC reset to disable the 22KHz tone*/
-               stv0900_write_bits(intp, DISEQC_RESET, 1);
-               stv0900_write_bits(intp, DISEQC_RESET, 0);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void stv0900_release(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (state->config->set_lock_led)
-               state->config->set_lock_led(fe, 0);
-
-       if ((--(state->internal->dmds_used)) <= 0) {
-
-               dprintk("%s: Actually removing\n", __func__);
-
-               remove_inode(state->internal);
-               kfree(state->internal);
-       }
-
-       kfree(state);
-}
-
-static int stv0900_sleep(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (state->config->set_lock_led)
-               state->config->set_lock_led(fe, 0);
-
-       return 0;
-}
-
-static int stv0900_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       struct stv0900_signal_info p_result = intp->result[demod];
-
-       p->frequency = p_result.locked ? p_result.frequency : 0;
-       p->symbol_rate = p_result.locked ? p_result.symbol_rate : 0;
-       return 0;
-}
-
-static struct dvb_frontend_ops stv0900_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
-       .info = {
-               .name                   = "STV0900 frontend",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 125,
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .symbol_rate_tolerance  = 500,
-               .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                                         FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
-                                         FE_CAN_FEC_7_8 | FE_CAN_QPSK    |
-                                         FE_CAN_2G_MODULATION |
-                                         FE_CAN_FEC_AUTO
-       },
-       .release                        = stv0900_release,
-       .init                           = stv0900_init,
-       .get_frontend                   = stv0900_get_frontend,
-       .sleep                          = stv0900_sleep,
-       .get_frontend_algo              = stv0900_frontend_algo,
-       .i2c_gate_ctrl                  = stv0900_i2c_gate_ctrl,
-       .diseqc_send_master_cmd         = stv0900_send_master_cmd,
-       .diseqc_send_burst              = stv0900_send_burst,
-       .diseqc_recv_slave_reply        = stv0900_recv_slave_reply,
-       .set_tone                       = stv0900_set_tone,
-       .search                         = stv0900_search,
-       .read_status                    = stv0900_read_status,
-       .read_ber                       = stv0900_read_ber,
-       .read_signal_strength           = stv0900_read_signal_strength,
-       .read_snr                       = stv0900_read_snr,
-       .read_ucblocks                  = stv0900_read_ucblocks,
-};
-
-struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
-                                       struct i2c_adapter *i2c,
-                                       int demod)
-{
-       struct stv0900_state *state = NULL;
-       struct stv0900_init_params init_params;
-       enum fe_stv0900_error err_stv0900;
-
-       state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->demod            = demod;
-       state->config           = config;
-       state->i2c_adap         = i2c;
-
-       memcpy(&state->frontend.ops, &stv0900_ops,
-                       sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       switch (demod) {
-       case 0:
-       case 1:
-               init_params.dmd_ref_clk         = config->xtal;
-               init_params.demod_mode          = config->demod_mode;
-               init_params.rolloff             = STV0900_35;
-               init_params.path1_ts_clock      = config->path1_mode;
-               init_params.tun1_maddress       = config->tun1_maddress;
-               init_params.tun1_iq_inv         = STV0900_IQ_NORMAL;
-               init_params.tuner1_adc          = config->tun1_adc;
-               init_params.tuner1_type         = config->tun1_type;
-               init_params.path2_ts_clock      = config->path2_mode;
-               init_params.ts_config           = config->ts_config_regs;
-               init_params.tun2_maddress       = config->tun2_maddress;
-               init_params.tuner2_adc          = config->tun2_adc;
-               init_params.tuner2_type         = config->tun2_type;
-               init_params.tun2_iq_inv         = STV0900_IQ_SWAPPED;
-
-               err_stv0900 = stv0900_init_internal(&state->frontend,
-                                                       &init_params);
-
-               if (err_stv0900)
-                       goto error;
-
-               break;
-       default:
-               goto error;
-               break;
-       }
-
-       dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
-       return &state->frontend;
-
-error:
-       dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
-               __func__, demod);
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(stv0900_attach);
-
-MODULE_PARM_DESC(debug, "Set debug");
-
-MODULE_AUTHOR("Igor M. Liplianin");
-MODULE_DESCRIPTION("ST STV0900 frontend");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
deleted file mode 100644 (file)
index b684df9..0000000
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * stv0900_init.h
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0900_INIT_H
-#define STV0900_INIT_H
-
-#include "stv0900_priv.h"
-
-/* DVBS2 C/N Look-Up table */
-static const struct stv0900_table stv0900_s2_cn = {
-       55,
-       {
-               { -30,  13348 }, /*C/N=-3dB*/
-               { -20,  12640 }, /*C/N=-2dB*/
-               { -10,  11883 }, /*C/N=-1dB*/
-               { 0,    11101 }, /*C/N=-0dB*/
-               { 5,    10718 }, /*C/N=0.5dB*/
-               { 10,   10339 }, /*C/N=1.0dB*/
-               { 15,   9947 }, /*C/N=1.5dB*/
-               { 20,   9552 }, /*C/N=2.0dB*/
-               { 25,   9183 }, /*C/N=2.5dB*/
-               { 30,   8799 }, /*C/N=3.0dB*/
-               { 35,   8422 }, /*C/N=3.5dB*/
-               { 40,   8062 }, /*C/N=4.0dB*/
-               { 45,   7707 }, /*C/N=4.5dB*/
-               { 50,   7353 }, /*C/N=5.0dB*/
-               { 55,   7025 }, /*C/N=5.5dB*/
-               { 60,   6684 }, /*C/N=6.0dB*/
-               { 65,   6331 }, /*C/N=6.5dB*/
-               { 70,   6036 }, /*C/N=7.0dB*/
-               { 75,   5727 }, /*C/N=7.5dB*/
-               { 80,   5437 }, /*C/N=8.0dB*/
-               { 85,   5164 }, /*C/N=8.5dB*/
-               { 90,   4902 }, /*C/N=9.0dB*/
-               { 95,   4653 }, /*C/N=9.5dB*/
-               { 100,  4408 }, /*C/N=10.0dB*/
-               { 105,  4187 }, /*C/N=10.5dB*/
-               { 110,  3961 }, /*C/N=11.0dB*/
-               { 115,  3751 }, /*C/N=11.5dB*/
-               { 120,  3558 }, /*C/N=12.0dB*/
-               { 125,  3368 }, /*C/N=12.5dB*/
-               { 130,  3191 }, /*C/N=13.0dB*/
-               { 135,  3017 }, /*C/N=13.5dB*/
-               { 140,  2862 }, /*C/N=14.0dB*/
-               { 145,  2710 }, /*C/N=14.5dB*/
-               { 150,  2565 }, /*C/N=15.0dB*/
-               { 160,  2300 }, /*C/N=16.0dB*/
-               { 170,  2058 }, /*C/N=17.0dB*/
-               { 180,  1849 }, /*C/N=18.0dB*/
-               { 190,  1663 }, /*C/N=19.0dB*/
-               { 200,  1495 }, /*C/N=20.0dB*/
-               { 210,  1349 }, /*C/N=21.0dB*/
-               { 220,  1222 }, /*C/N=22.0dB*/
-               { 230,  1110 }, /*C/N=23.0dB*/
-               { 240,  1011 }, /*C/N=24.0dB*/
-               { 250,  925 }, /*C/N=25.0dB*/
-               { 260,  853 }, /*C/N=26.0dB*/
-               { 270,  789 }, /*C/N=27.0dB*/
-               { 280,  734 }, /*C/N=28.0dB*/
-               { 290,  690 }, /*C/N=29.0dB*/
-               { 300,  650 }, /*C/N=30.0dB*/
-               { 310,  619 }, /*C/N=31.0dB*/
-               { 320,  593 }, /*C/N=32.0dB*/
-               { 330,  571 }, /*C/N=33.0dB*/
-               { 400,  498 }, /*C/N=40.0dB*/
-               { 450,  484 }, /*C/N=45.0dB*/
-               { 500,  481 }  /*C/N=50.0dB*/
-       }
-};
-
-/* RF level C/N Look-Up table */
-static const struct stv0900_table stv0900_rf = {
-       14,
-       {
-               { -5, 0xCAA1 }, /*-5dBm*/
-               { -10, 0xC229 }, /*-10dBm*/
-               { -15, 0xBB08 }, /*-15dBm*/
-               { -20, 0xB4BC }, /*-20dBm*/
-               { -25, 0xAD5A }, /*-25dBm*/
-               { -30, 0xA298 }, /*-30dBm*/
-               { -35, 0x98A8 }, /*-35dBm*/
-               { -40, 0x8389 }, /*-40dBm*/
-               { -45, 0x59BE }, /*-45dBm*/
-               { -50, 0x3A14 }, /*-50dBm*/
-               { -55, 0x2D11 }, /*-55dBm*/
-               { -60, 0x210D }, /*-60dBm*/
-               { -65, 0xA14F }, /*-65dBm*/
-               { -70, 0x7AA }  /*-70dBm*/
-       }
-};
-
-struct stv0900_car_loop_optim {
-       enum fe_stv0900_modcode modcode;
-       u8 car_loop_pilots_on_2;
-       u8 car_loop_pilots_off_2;
-       u8 car_loop_pilots_on_5;
-       u8 car_loop_pilots_off_5;
-       u8 car_loop_pilots_on_10;
-       u8 car_loop_pilots_off_10;
-       u8 car_loop_pilots_on_20;
-       u8 car_loop_pilots_off_20;
-       u8 car_loop_pilots_on_30;
-       u8 car_loop_pilots_off_30;
-
-};
-
-struct stv0900_short_frames_car_loop_optim {
-       enum fe_stv0900_modulation modulation;
-       u8 car_loop_cut12_2;    /* Cut 1.2,   SR<=3msps     */
-       u8 car_loop_cut20_2;    /* Cut 2.0,   SR<3msps      */
-       u8 car_loop_cut12_5;    /* Cut 1.2,   3<SR<=7msps   */
-       u8 car_loop_cut20_5;    /* Cut 2.0,   3<SR<=7msps   */
-       u8 car_loop_cut12_10;   /* Cut 1.2,   7<SR<=15msps  */
-       u8 car_loop_cut20_10;   /* Cut 2.0,   7<SR<=15msps  */
-       u8 car_loop_cut12_20;   /* Cut 1.2,   10<SR<=25msps */
-       u8 car_loop_cut20_20;   /* Cut 2.0,   10<SR<=25msps */
-       u8 car_loop_cut12_30;   /* Cut 1.2,   25<SR<=45msps */
-       u8 car_loop_cut20_30;   /* Cut 2.0,   10<SR<=45msps */
-
-};
-
-struct stv0900_short_frames_car_loop_optim_vs_mod {
-       enum fe_stv0900_modulation modulation;
-       u8 car_loop_2;    /* SR<3msps      */
-       u8 car_loop_5;    /* 3<SR<=7msps   */
-       u8 car_loop_10;   /* 7<SR<=15msps  */
-       u8 car_loop_20;   /* 10<SR<=25msps */
-       u8 car_loop_30;   /* 10<SR<=45msps */
-};
-
-/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
-       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_QPSK_12,      0x1C,   0x0D,   0x1B,   0x2C,   0x3A,
-                               0x1C,   0x2A,   0x3B,   0x2A,   0x1B },
-       { STV0900_QPSK_35,      0x2C,   0x0D,   0x2B,   0x2C,   0x3A,
-                               0x0C,   0x3A,   0x2B,   0x2A,   0x0B },
-       { STV0900_QPSK_23,      0x2C,   0x0D,   0x2B,   0x2C,   0x0B,
-                               0x0C,   0x3A,   0x1B,   0x2A,   0x3A },
-       { STV0900_QPSK_34,      0x3C,   0x0D,   0x3B,   0x1C,   0x0B,
-                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
-       { STV0900_QPSK_45,      0x3C,   0x0D,   0x3B,   0x1C,   0x0B,
-                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
-       { STV0900_QPSK_56,      0x0D,   0x0D,   0x3B,   0x1C,   0x0B,
-                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
-       { STV0900_QPSK_89,      0x0D,   0x0D,   0x3B,   0x1C,   0x1B,
-                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
-       { STV0900_QPSK_910,     0x1D,   0x0D,   0x3B,   0x1C,   0x1B,
-                               0x3B,   0x3A,   0x0B,   0x2A,   0x3A },
-       { STV0900_8PSK_35,      0x29,   0x3B,   0x09,   0x2B,   0x38,
-                               0x0B,   0x18,   0x1A,   0x08,   0x0A },
-       { STV0900_8PSK_23,      0x0A,   0x3B,   0x29,   0x2B,   0x19,
-                               0x0B,   0x38,   0x1A,   0x18,   0x0A },
-       { STV0900_8PSK_34,      0x3A,   0x3B,   0x2A,   0x2B,   0x39,
-                               0x0B,   0x19,   0x1A,   0x38,   0x0A },
-       { STV0900_8PSK_56,      0x1B,   0x3B,   0x0B,   0x2B,   0x1A,
-                               0x0B,   0x39,   0x1A,   0x19,   0x0A },
-       { STV0900_8PSK_89,      0x3B,   0x3B,   0x0B,   0x2B,   0x2A,
-                               0x0B,   0x39,   0x1A,   0x29,   0x39 },
-       { STV0900_8PSK_910,     0x3B,   0x3B,   0x0B,   0x2B,   0x2A,
-                               0x0B,   0x39,   0x1A,   0x29,   0x39 }
-};
-
-
-/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
-       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_QPSK_12,      0x1F,   0x3F,   0x1E,   0x3F,   0x3D,
-                               0x1F,   0x3D,   0x3E,   0x3D,   0x1E },
-       { STV0900_QPSK_35,      0x2F,   0x3F,   0x2E,   0x2F,   0x3D,
-                               0x0F,   0x0E,   0x2E,   0x3D,   0x0E },
-       { STV0900_QPSK_23,      0x2F,   0x3F,   0x2E,   0x2F,   0x0E,
-                               0x0F,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_QPSK_34,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
-                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_QPSK_45,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
-                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_QPSK_56,      0x3F,   0x3F,   0x3E,   0x1F,   0x0E,
-                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_QPSK_89,      0x3F,   0x3F,   0x3E,   0x1F,   0x1E,
-                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_QPSK_910,     0x3F,   0x3F,   0x3E,   0x1F,   0x1E,
-                               0x3E,   0x0E,   0x1E,   0x3D,   0x3D },
-       { STV0900_8PSK_35,      0x3c,   0x0c,   0x1c,   0x3b,   0x0c,
-                               0x3b,   0x2b,   0x2b,   0x1b,   0x2b },
-       { STV0900_8PSK_23,      0x1d,   0x0c,   0x3c,   0x0c,   0x2c,
-                               0x3b,   0x0c,   0x2b,   0x2b,   0x2b },
-       { STV0900_8PSK_34,      0x0e,   0x1c,   0x3d,   0x0c,   0x0d,
-                               0x3b,   0x2c,   0x3b,   0x0c,   0x2b },
-       { STV0900_8PSK_56,      0x2e,   0x3e,   0x1e,   0x2e,   0x2d,
-                               0x1e,   0x3c,   0x2d,   0x2c,   0x1d },
-       { STV0900_8PSK_89,      0x3e,   0x3e,   0x1e,   0x2e,   0x3d,
-                               0x1e,   0x0d,   0x2d,   0x3c,   0x1d },
-       { STV0900_8PSK_910,     0x3e,   0x3e,   0x1e,   0x2e,   0x3d,
-                               0x1e,   0x1d,   0x2d,   0x0d,   0x1d },
-};
-
-
-
-/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
-static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
-       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_16APSK_23,    0x0C,   0x0C,   0x0C,   0x0C,   0x1D,
-                               0x0C,   0x3C,   0x0C,   0x2C,   0x0C },
-       { STV0900_16APSK_34,    0x0C,   0x0C,   0x0C,   0x0C,   0x0E,
-                               0x0C,   0x2D,   0x0C,   0x1D,   0x0C },
-       { STV0900_16APSK_45,    0x0C,   0x0C,   0x0C,   0x0C,   0x1E,
-                               0x0C,   0x3D,   0x0C,   0x2D,   0x0C },
-       { STV0900_16APSK_56,    0x0C,   0x0C,   0x0C,   0x0C,   0x1E,
-                               0x0C,   0x3D,   0x0C,   0x2D,   0x0C },
-       { STV0900_16APSK_89,    0x0C,   0x0C,   0x0C,   0x0C,   0x2E,
-                               0x0C,   0x0E,   0x0C,   0x3D,   0x0C },
-       { STV0900_16APSK_910,   0x0C,   0x0C,   0x0C,   0x0C,   0x2E,
-                               0x0C,   0x0E,   0x0C,   0x3D,   0x0C },
-       { STV0900_32APSK_34,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
-                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
-       { STV0900_32APSK_45,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
-                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
-       { STV0900_32APSK_56,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
-                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
-       { STV0900_32APSK_89,    0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
-                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
-       { STV0900_32APSK_910,   0x0C,   0x0C,   0x0C,   0x0C,   0x0C,
-                               0x0C,   0x0C,   0x0C,   0x0C,   0x0C },
-};
-
-
-/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
-static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
-       /* Modcod               2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_QPSK_14,      0x0F,   0x3F,   0x0E,   0x3F,   0x2D,
-                               0x2F,   0x2D,   0x1F,   0x3D,   0x3E },
-       { STV0900_QPSK_13,      0x0F,   0x3F,   0x0E,   0x3F,   0x2D,
-                               0x2F,   0x3D,   0x0F,   0x3D,   0x2E },
-       { STV0900_QPSK_25,      0x1F,   0x3F,   0x1E,   0x3F,   0x3D,
-                               0x1F,   0x3D,   0x3E,   0x3D,   0x2E }
-};
-
-
-/* Cut 2.0 Tracking carrier loop carrier  short Frame, cut 1.2 and 2.0 */
-static const
-struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
-       /*Mod           2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
-                       10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
-       { STV0900_QPSK,         0x3C,   0x2F,   0x2B,   0x2E,   0x0B,
-                               0x0E,   0x3A,   0x0E,   0x2A,   0x3D },
-       { STV0900_8PSK,         0x0B,   0x3E,   0x2A,   0x0E,   0x0A,
-                               0x2D,   0x19,   0x0D,   0x09,   0x3C },
-       { STV0900_16APSK,       0x1B,   0x1E,   0x1B,   0x1E,   0x1B,
-                               0x1E,   0x3A,   0x3D,   0x2A,   0x2D },
-       { STV0900_32APSK,       0x1B,   0x1E,   0x1B,   0x1E,   0x1B,
-                               0x1E,   0x3A,   0x3D,   0x2A,   0x2D }
-};
-
-static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
-       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_QPSK_12,      0x3C,   0x2C,   0x0C,   0x2C,   0x1B,
-                               0x2C,   0x1B,   0x1C,   0x0B,   0x3B },
-       { STV0900_QPSK_35,      0x0D,   0x0D,   0x0C,   0x0D,   0x1B,
-                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
-       { STV0900_QPSK_23,      0x1D,   0x0D,   0x0C,   0x1D,   0x2B,
-                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
-       { STV0900_QPSK_34,      0x1D,   0x1D,   0x0C,   0x1D,   0x2B,
-                               0x3C,   0x1B,   0x1C,   0x0B,   0x3B },
-       { STV0900_QPSK_45,      0x2D,   0x1D,   0x1C,   0x1D,   0x2B,
-                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
-       { STV0900_QPSK_56,      0x2D,   0x1D,   0x1C,   0x1D,   0x2B,
-                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
-       { STV0900_QPSK_89,      0x3D,   0x2D,   0x1C,   0x1D,   0x3B,
-                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
-       { STV0900_QPSK_910,     0x3D,   0x2D,   0x1C,   0x1D,   0x3B,
-                               0x3C,   0x2B,   0x0C,   0x1B,   0x3B },
-       { STV0900_8PSK_35,      0x39,   0x19,   0x39,   0x19,   0x19,
-                               0x19,   0x19,   0x19,   0x09,   0x19 },
-       { STV0900_8PSK_23,      0x2A,   0x39,   0x1A,   0x0A,   0x39,
-                               0x0A,   0x29,   0x39,   0x29,   0x0A },
-       { STV0900_8PSK_34,      0x0B,   0x3A,   0x0B,   0x0B,   0x3A,
-                               0x1B,   0x1A,   0x0B,   0x1A,   0x3A },
-       { STV0900_8PSK_56,      0x0C,   0x1B,   0x3B,   0x2B,   0x1B,
-                               0x3B,   0x3A,   0x3B,   0x3A,   0x1B },
-       { STV0900_8PSK_89,      0x2C,   0x2C,   0x2C,   0x1C,   0x2B,
-                               0x0C,   0x0B,   0x3B,   0x0B,   0x1B },
-       { STV0900_8PSK_910,     0x2C,   0x3C,   0x2C,   0x1C,   0x3B,
-                               0x1C,   0x0B,   0x3B,   0x0B,   0x1B }
-};
-
-static const
-struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
-       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff */
-       { STV0900_16APSK_23,    0x0A,   0x0A,   0x0A,   0x0A,   0x1A,
-                               0x0A,   0x3A,   0x0A,   0x2A,   0x0A },
-       { STV0900_16APSK_34,    0x0A,   0x0A,   0x0A,   0x0A,   0x0B,
-                               0x0A,   0x3B,   0x0A,   0x1B,   0x0A },
-       { STV0900_16APSK_45,    0x0A,   0x0A,   0x0A,   0x0A,   0x1B,
-                               0x0A,   0x3B,   0x0A,   0x2B,   0x0A },
-       { STV0900_16APSK_56,    0x0A,   0x0A,   0x0A,   0x0A,   0x1B,
-                               0x0A,   0x3B,   0x0A,   0x2B,   0x0A },
-       { STV0900_16APSK_89,    0x0A,   0x0A,   0x0A,   0x0A,   0x2B,
-                               0x0A,   0x0C,   0x0A,   0x3B,   0x0A },
-       { STV0900_16APSK_910,   0x0A,   0x0A,   0x0A,   0x0A,   0x2B,
-                               0x0A,   0x0C,   0x0A,   0x3B,   0x0A },
-       { STV0900_32APSK_34,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
-                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
-       { STV0900_32APSK_45,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
-                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
-       { STV0900_32APSK_56,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
-                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
-       { STV0900_32APSK_89,    0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
-                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A },
-       { STV0900_32APSK_910,   0x0A,   0x0A,   0x0A,   0x0A,   0x0A,
-                               0x0A,   0x0A,   0x0A,   0x0A,   0x0A }
-};
-
-static const
-struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
-       /*Modcod                2MPon   2MPoff  5MPon   5MPoff  10MPon
-                               10MPoff 20MPon  20MPoff 30MPon  30MPoff*/
-       { STV0900_QPSK_14,      0x0C,   0x3C,   0x0B,   0x3C,   0x2A,
-                               0x2C,   0x2A,   0x1C,   0x3A,   0x3B },
-       { STV0900_QPSK_13,      0x0C,   0x3C,   0x0B,   0x3C,   0x2A,
-                               0x2C,   0x3A,   0x0C,   0x3A,   0x2B },
-       { STV0900_QPSK_25,      0x1C,   0x3C,   0x1B,   0x3C,   0x3A,
-                               0x1C,   0x3A,   0x3B,   0x3A,   0x2B }
-};
-
-static const struct stv0900_short_frames_car_loop_optim_vs_mod
-FE_STV0900_S2ShortCarLoopCut30[4] = {
-       /*Mod           2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
-       { STV0900_QPSK,         0x2C,   0x2B,   0x0B,   0x0B,   0x3A },
-       { STV0900_8PSK,         0x3B,   0x0B,   0x2A,   0x0A,   0x39 },
-       { STV0900_16APSK,       0x1B,   0x1B,   0x1B,   0x3A,   0x2A },
-       { STV0900_32APSK,       0x1B,   0x1B,   0x1B,   0x3A,   0x2A },
-
-};
-
-static const u16 STV0900_InitVal[181][2] = {
-       { R0900_OUTCFG          , 0x00  },
-       { R0900_AGCRF1CFG       , 0x11  },
-       { R0900_AGCRF2CFG       , 0x13  },
-       { R0900_TSGENERAL1X     , 0x14  },
-       { R0900_TSTTNR2         , 0x21  },
-       { R0900_TSTTNR4         , 0x21  },
-       { R0900_P2_DISTXCTL     , 0x22  },
-       { R0900_P2_F22TX        , 0xc0  },
-       { R0900_P2_F22RX        , 0xc0  },
-       { R0900_P2_DISRXCTL     , 0x00  },
-       { R0900_P2_TNRSTEPS     , 0x87  },
-       { R0900_P2_TNRGAIN      , 0x09  },
-       { R0900_P2_DMDCFGMD     , 0xF9  },
-       { R0900_P2_DEMOD        , 0x08  },
-       { R0900_P2_DMDCFG3      , 0xc4  },
-       { R0900_P2_CARFREQ      , 0xed  },
-       { R0900_P2_TNRCFG2      , 0x02  },
-       { R0900_P2_TNRCFG3      , 0x02  },
-       { R0900_P2_LDT          , 0xd0  },
-       { R0900_P2_LDT2         , 0xb8  },
-       { R0900_P2_TMGCFG       , 0xd2  },
-       { R0900_P2_TMGTHRISE    , 0x20  },
-       { R0900_P2_TMGTHFALL    , 0x00  },
-       { R0900_P2_FECSPY       , 0x88  },
-       { R0900_P2_FSPYDATA     , 0x3a  },
-       { R0900_P2_FBERCPT4     , 0x00  },
-       { R0900_P2_FSPYBER      , 0x10  },
-       { R0900_P2_ERRCTRL1     , 0x35  },
-       { R0900_P2_ERRCTRL2     , 0xc1  },
-       { R0900_P2_CFRICFG      , 0xf8  },
-       { R0900_P2_NOSCFG       , 0x1c  },
-       { R0900_P2_DMDT0M       , 0x20  },
-       { R0900_P2_CORRELMANT   , 0x70  },
-       { R0900_P2_CORRELABS    , 0x88  },
-       { R0900_P2_AGC2O        , 0x5b  },
-       { R0900_P2_AGC2REF      , 0x38  },
-       { R0900_P2_CARCFG       , 0xe4  },
-       { R0900_P2_ACLC         , 0x1A  },
-       { R0900_P2_BCLC         , 0x09  },
-       { R0900_P2_CARHDR       , 0x08  },
-       { R0900_P2_KREFTMG      , 0xc1  },
-       { R0900_P2_SFRUPRATIO   , 0xf0  },
-       { R0900_P2_SFRLOWRATIO  , 0x70  },
-       { R0900_P2_SFRSTEP      , 0x58  },
-       { R0900_P2_TMGCFG2      , 0x01  },
-       { R0900_P2_CAR2CFG      , 0x26  },
-       { R0900_P2_BCLC2S2Q     , 0x86  },
-       { R0900_P2_BCLC2S28     , 0x86  },
-       { R0900_P2_SMAPCOEF7    , 0x77  },
-       { R0900_P2_SMAPCOEF6    , 0x85  },
-       { R0900_P2_SMAPCOEF5    , 0x77  },
-       { R0900_P2_TSCFGL       , 0x20  },
-       { R0900_P2_DMDCFG2      , 0x3b  },
-       { R0900_P2_MODCODLST0   , 0xff  },
-       { R0900_P2_MODCODLST1   , 0xff  },
-       { R0900_P2_MODCODLST2   , 0xff  },
-       { R0900_P2_MODCODLST3   , 0xff  },
-       { R0900_P2_MODCODLST4   , 0xff  },
-       { R0900_P2_MODCODLST5   , 0xff  },
-       { R0900_P2_MODCODLST6   , 0xff  },
-       { R0900_P2_MODCODLST7   , 0xcc  },
-       { R0900_P2_MODCODLST8   , 0xcc  },
-       { R0900_P2_MODCODLST9   , 0xcc  },
-       { R0900_P2_MODCODLSTA   , 0xcc  },
-       { R0900_P2_MODCODLSTB   , 0xcc  },
-       { R0900_P2_MODCODLSTC   , 0xcc  },
-       { R0900_P2_MODCODLSTD   , 0xcc  },
-       { R0900_P2_MODCODLSTE   , 0xcc  },
-       { R0900_P2_MODCODLSTF   , 0xcf  },
-       { R0900_P1_DISTXCTL     , 0x22  },
-       { R0900_P1_F22TX        , 0xc0  },
-       { R0900_P1_F22RX        , 0xc0  },
-       { R0900_P1_DISRXCTL     , 0x00  },
-       { R0900_P1_TNRSTEPS     , 0x87  },
-       { R0900_P1_TNRGAIN      , 0x09  },
-       { R0900_P1_DMDCFGMD     , 0xf9  },
-       { R0900_P1_DEMOD        , 0x08  },
-       { R0900_P1_DMDCFG3      , 0xc4  },
-       { R0900_P1_DMDT0M       , 0x20  },
-       { R0900_P1_CARFREQ      , 0xed  },
-       { R0900_P1_TNRCFG2      , 0x82  },
-       { R0900_P1_TNRCFG3      , 0x02  },
-       { R0900_P1_LDT          , 0xd0  },
-       { R0900_P1_LDT2         , 0xb8  },
-       { R0900_P1_TMGCFG       , 0xd2  },
-       { R0900_P1_TMGTHRISE    , 0x20  },
-       { R0900_P1_TMGTHFALL    , 0x00  },
-       { R0900_P1_SFRUPRATIO   , 0xf0  },
-       { R0900_P1_SFRLOWRATIO  , 0x70  },
-       { R0900_P1_TSCFGL       , 0x20  },
-       { R0900_P1_FECSPY       , 0x88  },
-       { R0900_P1_FSPYDATA     , 0x3a  },
-       { R0900_P1_FBERCPT4     , 0x00  },
-       { R0900_P1_FSPYBER      , 0x10  },
-       { R0900_P1_ERRCTRL1     , 0x35  },
-       { R0900_P1_ERRCTRL2     , 0xc1  },
-       { R0900_P1_CFRICFG      , 0xf8  },
-       { R0900_P1_NOSCFG       , 0x1c  },
-       { R0900_P1_CORRELMANT   , 0x70  },
-       { R0900_P1_CORRELABS    , 0x88  },
-       { R0900_P1_AGC2O        , 0x5b  },
-       { R0900_P1_AGC2REF      , 0x38  },
-       { R0900_P1_CARCFG       , 0xe4  },
-       { R0900_P1_ACLC         , 0x1A  },
-       { R0900_P1_BCLC         , 0x09  },
-       { R0900_P1_CARHDR       , 0x08  },
-       { R0900_P1_KREFTMG      , 0xc1  },
-       { R0900_P1_SFRSTEP      , 0x58  },
-       { R0900_P1_TMGCFG2      , 0x01  },
-       { R0900_P1_CAR2CFG      , 0x26  },
-       { R0900_P1_BCLC2S2Q     , 0x86  },
-       { R0900_P1_BCLC2S28     , 0x86  },
-       { R0900_P1_SMAPCOEF7    , 0x77  },
-       { R0900_P1_SMAPCOEF6    , 0x85  },
-       { R0900_P1_SMAPCOEF5    , 0x77  },
-       { R0900_P1_DMDCFG2      , 0x3b  },
-       { R0900_P1_MODCODLST0   , 0xff  },
-       { R0900_P1_MODCODLST1   , 0xff  },
-       { R0900_P1_MODCODLST2   , 0xff  },
-       { R0900_P1_MODCODLST3   , 0xff  },
-       { R0900_P1_MODCODLST4   , 0xff  },
-       { R0900_P1_MODCODLST5   , 0xff  },
-       { R0900_P1_MODCODLST6   , 0xff  },
-       { R0900_P1_MODCODLST7   , 0xcc  },
-       { R0900_P1_MODCODLST8   , 0xcc  },
-       { R0900_P1_MODCODLST9   , 0xcc  },
-       { R0900_P1_MODCODLSTA   , 0xcc  },
-       { R0900_P1_MODCODLSTB   , 0xcc  },
-       { R0900_P1_MODCODLSTC   , 0xcc  },
-       { R0900_P1_MODCODLSTD   , 0xcc  },
-       { R0900_P1_MODCODLSTE   , 0xcc  },
-       { R0900_P1_MODCODLSTF   , 0xcf  },
-       { R0900_GENCFG          , 0x1d  },
-       { R0900_NBITER_NF4      , 0x37  },
-       { R0900_NBITER_NF5      , 0x29  },
-       { R0900_NBITER_NF6      , 0x37  },
-       { R0900_NBITER_NF7      , 0x33  },
-       { R0900_NBITER_NF8      , 0x31  },
-       { R0900_NBITER_NF9      , 0x2f  },
-       { R0900_NBITER_NF10     , 0x39  },
-       { R0900_NBITER_NF11     , 0x3a  },
-       { R0900_NBITER_NF12     , 0x29  },
-       { R0900_NBITER_NF13     , 0x37  },
-       { R0900_NBITER_NF14     , 0x33  },
-       { R0900_NBITER_NF15     , 0x2f  },
-       { R0900_NBITER_NF16     , 0x39  },
-       { R0900_NBITER_NF17     , 0x3a  },
-       { R0900_NBITERNOERR     , 0x04  },
-       { R0900_GAINLLR_NF4     , 0x0C  },
-       { R0900_GAINLLR_NF5     , 0x0F  },
-       { R0900_GAINLLR_NF6     , 0x11  },
-       { R0900_GAINLLR_NF7     , 0x14  },
-       { R0900_GAINLLR_NF8     , 0x17  },
-       { R0900_GAINLLR_NF9     , 0x19  },
-       { R0900_GAINLLR_NF10    , 0x20  },
-       { R0900_GAINLLR_NF11    , 0x21  },
-       { R0900_GAINLLR_NF12    , 0x0D  },
-       { R0900_GAINLLR_NF13    , 0x0F  },
-       { R0900_GAINLLR_NF14    , 0x13  },
-       { R0900_GAINLLR_NF15    , 0x1A  },
-       { R0900_GAINLLR_NF16    , 0x1F  },
-       { R0900_GAINLLR_NF17    , 0x21  },
-       { R0900_RCCFG2          , 0x20  },
-       { R0900_P1_FECM         , 0x01  }, /*disable DSS modes*/
-       { R0900_P2_FECM         , 0x01  }, /*disable DSS modes*/
-       { R0900_P1_PRVIT        , 0x2F  }, /*disable puncture rate 6/7*/
-       { R0900_P2_PRVIT        , 0x2F  }, /*disable puncture rate 6/7*/
-       { R0900_STROUT1CFG      , 0x4c  },
-       { R0900_STROUT2CFG      , 0x4c  },
-       { R0900_CLKOUT1CFG      , 0x50  },
-       { R0900_CLKOUT2CFG      , 0x50  },
-       { R0900_DPN1CFG         , 0x4a  },
-       { R0900_DPN2CFG         , 0x4a  },
-       { R0900_DATA71CFG       , 0x52  },
-       { R0900_DATA72CFG       , 0x52  },
-       { R0900_P1_TSCFGM       , 0xc0  },
-       { R0900_P2_TSCFGM       , 0xc0  },
-       { R0900_P1_TSCFGH       , 0xe0  }, /* DVB-CI timings */
-       { R0900_P2_TSCFGH       , 0xe0  }, /* DVB-CI timings */
-       { R0900_P1_TSSPEED      , 0x40  },
-       { R0900_P2_TSSPEED      , 0x40  },
-};
-
-static const u16 STV0900_Cut20_AddOnVal[32][2] = {
-       { R0900_P2_DMDCFG3      , 0xe8  },
-       { R0900_P2_DMDCFG4      , 0x10  },
-       { R0900_P2_CARFREQ      , 0x38  },
-       { R0900_P2_CARHDR       , 0x20  },
-       { R0900_P2_KREFTMG      , 0x5a  },
-       { R0900_P2_SMAPCOEF7    , 0x06  },
-       { R0900_P2_SMAPCOEF6    , 0x00  },
-       { R0900_P2_SMAPCOEF5    , 0x04  },
-       { R0900_P2_NOSCFG       , 0x0c  },
-       { R0900_P1_DMDCFG3      , 0xe8  },
-       { R0900_P1_DMDCFG4      , 0x10  },
-       { R0900_P1_CARFREQ      , 0x38  },
-       { R0900_P1_CARHDR       , 0x20  },
-       { R0900_P1_KREFTMG      , 0x5a  },
-       { R0900_P1_SMAPCOEF7    , 0x06  },
-       { R0900_P1_SMAPCOEF6    , 0x00  },
-       { R0900_P1_SMAPCOEF5    , 0x04  },
-       { R0900_P1_NOSCFG       , 0x0c  },
-       { R0900_GAINLLR_NF4     , 0x21  },
-       { R0900_GAINLLR_NF5     , 0x21  },
-       { R0900_GAINLLR_NF6     , 0x20  },
-       { R0900_GAINLLR_NF7     , 0x1F  },
-       { R0900_GAINLLR_NF8     , 0x1E  },
-       { R0900_GAINLLR_NF9     , 0x1E  },
-       { R0900_GAINLLR_NF10    , 0x1D  },
-       { R0900_GAINLLR_NF11    , 0x1B  },
-       { R0900_GAINLLR_NF12    , 0x20  },
-       { R0900_GAINLLR_NF13    , 0x20  },
-       { R0900_GAINLLR_NF14    , 0x20  },
-       { R0900_GAINLLR_NF15    , 0x20  },
-       { R0900_GAINLLR_NF16    , 0x20  },
-       { R0900_GAINLLR_NF17    , 0x21  }
-
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
deleted file mode 100644 (file)
index e0ea74c..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * stv0900_priv.h
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0900_PRIV_H
-#define STV0900_PRIV_H
-
-#include <linux/i2c.h>
-
-#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
-#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
-               || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
-
-#ifndef MAKEWORD
-#define MAKEWORD(X, Y) (((X) << 8) + (Y))
-#endif
-
-#define LSB(X) (((X) & 0xFF))
-#define MSB(Y) (((Y) >> 8) & 0xFF)
-
-#ifndef TRUE
-#define TRUE (1 == 1)
-#endif
-#ifndef FALSE
-#define FALSE (!TRUE)
-#endif
-
-#define dprintk(args...) \
-       do { \
-               if (stvdebug) \
-                       printk(KERN_DEBUG args); \
-       } while (0)
-
-#define STV0900_MAXLOOKUPSIZE 500
-#define STV0900_BLIND_SEARCH_AGC2_TH 700
-#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
-#define IQPOWER_THRESHOLD  30
-
-/* One point of the lookup table */
-struct stv000_lookpoint {
-       s32 realval;/* real value */
-       s32 regval;/* binary value */
-};
-
-/* Lookup table definition */
-struct stv0900_table{
-       s32 size;/* Size of the lookup table */
-       struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
-};
-
-enum fe_stv0900_error {
-       STV0900_NO_ERROR = 0,
-       STV0900_INVALID_HANDLE,
-       STV0900_BAD_PARAMETER,
-       STV0900_I2C_ERROR,
-       STV0900_SEARCH_FAILED,
-};
-
-enum fe_stv0900_clock_type {
-       STV0900_USE_REGISTERS_DEFAULT,
-       STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
-       STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
-       STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
-       STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
-};
-
-enum fe_stv0900_search_state {
-       STV0900_SEARCH = 0,
-       STV0900_PLH_DETECTED,
-       STV0900_DVBS2_FOUND,
-       STV0900_DVBS_FOUND
-
-};
-
-enum fe_stv0900_ldpc_state {
-       STV0900_PATH1_OFF_PATH2_OFF = 0,
-       STV0900_PATH1_ON_PATH2_OFF = 1,
-       STV0900_PATH1_OFF_PATH2_ON = 2,
-       STV0900_PATH1_ON_PATH2_ON = 3
-};
-
-enum fe_stv0900_signal_type {
-       STV0900_NOAGC1 = 0,
-       STV0900_AGC1OK,
-       STV0900_NOTIMING,
-       STV0900_ANALOGCARRIER,
-       STV0900_TIMINGOK,
-       STV0900_NOAGC2,
-       STV0900_AGC2OK,
-       STV0900_NOCARRIER,
-       STV0900_CARRIEROK,
-       STV0900_NODATA,
-       STV0900_DATAOK,
-       STV0900_OUTOFRANGE,
-       STV0900_RANGEOK
-};
-
-enum fe_stv0900_demod_num {
-       STV0900_DEMOD_1,
-       STV0900_DEMOD_2
-};
-
-enum fe_stv0900_tracking_standard {
-       STV0900_DVBS1_STANDARD,/* Found Standard*/
-       STV0900_DVBS2_STANDARD,
-       STV0900_DSS_STANDARD,
-       STV0900_TURBOCODE_STANDARD,
-       STV0900_UNKNOWN_STANDARD
-};
-
-enum fe_stv0900_search_standard {
-       STV0900_AUTO_SEARCH,
-       STV0900_SEARCH_DVBS1,/* Search Standard*/
-       STV0900_SEARCH_DVBS2,
-       STV0900_SEARCH_DSS,
-       STV0900_SEARCH_TURBOCODE
-};
-
-enum fe_stv0900_search_algo {
-       STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
-       STV0900_COLD_START,/* only the SR is known */
-       STV0900_WARM_START/* offset freq and SR are known */
-};
-
-enum fe_stv0900_modulation {
-       STV0900_QPSK,
-       STV0900_8PSK,
-       STV0900_16APSK,
-       STV0900_32APSK,
-       STV0900_UNKNOWN
-};
-
-enum fe_stv0900_modcode {
-       STV0900_DUMMY_PLF,
-       STV0900_QPSK_14,
-       STV0900_QPSK_13,
-       STV0900_QPSK_25,
-       STV0900_QPSK_12,
-       STV0900_QPSK_35,
-       STV0900_QPSK_23,
-       STV0900_QPSK_34,
-       STV0900_QPSK_45,
-       STV0900_QPSK_56,
-       STV0900_QPSK_89,
-       STV0900_QPSK_910,
-       STV0900_8PSK_35,
-       STV0900_8PSK_23,
-       STV0900_8PSK_34,
-       STV0900_8PSK_56,
-       STV0900_8PSK_89,
-       STV0900_8PSK_910,
-       STV0900_16APSK_23,
-       STV0900_16APSK_34,
-       STV0900_16APSK_45,
-       STV0900_16APSK_56,
-       STV0900_16APSK_89,
-       STV0900_16APSK_910,
-       STV0900_32APSK_34,
-       STV0900_32APSK_45,
-       STV0900_32APSK_56,
-       STV0900_32APSK_89,
-       STV0900_32APSK_910,
-       STV0900_MODCODE_UNKNOWN
-};
-
-enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
-       STV0900_FEC_1_2 = 0,
-       STV0900_FEC_2_3,
-       STV0900_FEC_3_4,
-       STV0900_FEC_4_5,/*for turbo code only*/
-       STV0900_FEC_5_6,
-       STV0900_FEC_6_7,/*for DSS only */
-       STV0900_FEC_7_8,
-       STV0900_FEC_8_9,/*for turbo code only*/
-       STV0900_FEC_UNKNOWN
-};
-
-enum fe_stv0900_frame_length {
-       STV0900_LONG_FRAME,
-       STV0900_SHORT_FRAME
-};
-
-enum fe_stv0900_pilot {
-       STV0900_PILOTS_OFF,
-       STV0900_PILOTS_ON
-};
-
-enum fe_stv0900_rolloff {
-       STV0900_35,
-       STV0900_25,
-       STV0900_20
-};
-
-enum fe_stv0900_search_iq {
-       STV0900_IQ_AUTO,
-       STV0900_IQ_AUTO_NORMAL_FIRST,
-       STV0900_IQ_FORCE_NORMAL,
-       STV0900_IQ_FORCE_SWAPPED
-};
-
-enum stv0900_iq_inversion {
-       STV0900_IQ_NORMAL,
-       STV0900_IQ_SWAPPED
-};
-
-enum fe_stv0900_diseqc_mode {
-       STV0900_22KHZ_Continues = 0,
-       STV0900_DISEQC_2_3_PWM = 2,
-       STV0900_DISEQC_3_3_PWM = 3,
-       STV0900_DISEQC_2_3_ENVELOP = 4,
-       STV0900_DISEQC_3_3_ENVELOP = 5
-};
-
-enum fe_stv0900_demod_mode {
-       STV0900_SINGLE = 0,
-       STV0900_DUAL
-};
-
-struct stv0900_init_params{
-       u32     dmd_ref_clk;/* Reference,Input clock for the demod in Hz */
-
-       /* Demodulator Type (single demod or dual demod) */
-       enum fe_stv0900_demod_mode      demod_mode;
-       enum fe_stv0900_rolloff         rolloff;
-       enum fe_stv0900_clock_type      path1_ts_clock;
-
-       u8      tun1_maddress;
-       int     tuner1_adc;
-       int     tuner1_type;
-
-       /* IQ from the tuner1 to the demod */
-       enum stv0900_iq_inversion       tun1_iq_inv;
-       enum fe_stv0900_clock_type      path2_ts_clock;
-
-       u8      tun2_maddress;
-       int     tuner2_adc;
-       int     tuner2_type;
-
-       /* IQ from the tuner2 to the demod */
-       enum stv0900_iq_inversion       tun2_iq_inv;
-       struct stv0900_reg              *ts_config;
-};
-
-struct stv0900_search_params {
-       enum fe_stv0900_demod_num       path;/* Path Used demod1 or 2 */
-
-       u32     frequency;/* Transponder frequency (in KHz) */
-       u32     symbol_rate;/* Transponder symbol rate  (in bds)*/
-       u32     search_range;/* Range of the search (in Hz) */
-
-       enum fe_stv0900_search_standard standard;
-       enum fe_stv0900_modulation      modulation;
-       enum fe_stv0900_fec             fec;
-       enum fe_stv0900_modcode         modcode;
-       enum fe_stv0900_search_iq       iq_inversion;
-       enum fe_stv0900_search_algo     search_algo;
-
-};
-
-struct stv0900_signal_info {
-       int     locked;/* Transponder locked */
-       u32     frequency;/* Transponder frequency (in KHz) */
-       u32     symbol_rate;/* Transponder symbol rate  (in Mbds) */
-
-       enum fe_stv0900_tracking_standard       standard;
-       enum fe_stv0900_fec                     fec;
-       enum fe_stv0900_modcode                 modcode;
-       enum fe_stv0900_modulation              modulation;
-       enum fe_stv0900_pilot                   pilot;
-       enum fe_stv0900_frame_length            frame_len;
-       enum stv0900_iq_inversion               spectrum;
-       enum fe_stv0900_rolloff                 rolloff;
-
-       s32 Power;/* Power of the RF signal (dBm) */
-       s32 C_N;/* Carrier to noise ratio (dB x10)*/
-       u32 BER;/* Bit error rate (x10^7) */
-
-};
-
-struct stv0900_internal{
-       s32     quartz;
-       s32     mclk;
-       /* manual RollOff for DVBS1/DSS only */
-       enum fe_stv0900_rolloff         rolloff;
-       /* Demodulator use for single demod or for dual demod) */
-       enum fe_stv0900_demod_mode      demod_mode;
-
-       /*Demods */
-       s32     freq[2];
-       s32     bw[2];
-       s32     symbol_rate[2];
-       s32     srch_range[2];
-       /* for software/auto tuner */
-       int     tuner_type[2];
-
-       /* algorithm for search Blind, Cold or Warm*/
-       enum fe_stv0900_search_algo     srch_algo[2];
-       /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
-       enum fe_stv0900_search_standard srch_standard[2];
-       /* inversion search : auto, auto norma first, normal or inverted */
-       enum fe_stv0900_search_iq       srch_iq_inv[2];
-       enum fe_stv0900_modcode         modcode[2];
-       enum fe_stv0900_modulation      modulation[2];
-       enum fe_stv0900_fec             fec[2];
-
-       struct stv0900_signal_info      result[2];
-       enum fe_stv0900_error           err[2];
-
-
-       struct i2c_adapter      *i2c_adap;
-       u8                      i2c_addr;
-       u8                      clkmode;/* 0 for CLKI, 2 for XTALI */
-       u8                      chip_id;
-       struct stv0900_reg      *ts_config;
-       enum fe_stv0900_error   errs;
-       int dmds_used;
-};
-
-/* state for each demod */
-struct stv0900_state {
-       /* pointer for internal params, one for each pair of demods */
-       struct stv0900_internal         *internal;
-       struct i2c_adapter              *i2c_adap;
-       const struct stv0900_config     *config;
-       struct dvb_frontend             frontend;
-       int demod;
-};
-
-extern int stvdebug;
-
-extern s32 ge2comp(s32 a, s32 width);
-
-extern void stv0900_write_reg(struct stv0900_internal *i_params,
-                               u16 reg_addr, u8 reg_data);
-
-extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
-                               u16 reg_addr);
-
-extern void stv0900_write_bits(struct stv0900_internal *i_params,
-                               u32 label, u8 val);
-
-extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
-                               u32 label);
-
-extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod, s32 time_out);
-extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod);
-
-extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
-
-extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
-                               u32 bandwidth);
-extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
-
-extern void stv0900_start_search(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod);
-
-extern u8 stv0900_get_optim_carr_loop(s32 srate,
-                               enum fe_stv0900_modcode modcode,
-                               s32 pilot, u8 chip_id);
-
-extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
-                               enum fe_stv0900_modulation modulation,
-                               u8 chip_id);
-
-extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod);
-
-extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod);
-
-extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
-                               enum fe_stv0900_demod_num demod);
-
-extern enum
-fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
-                               enum fe_stv0900_demod_num demod);
-
-extern u32
-stv0900_get_freq_auto(struct stv0900_internal *intp, int demod);
-
-extern void
-stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
-                                               u32 Bandwidth, int demod);
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
deleted file mode 100644 (file)
index 731afe9..0000000
+++ /dev/null
@@ -1,3981 +0,0 @@
-/*
- * stv0900_reg.h
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef STV0900_REG_H
-#define STV0900_REG_H
-
-extern s32 shiftx(s32 x, int demod, s32 shift);
-
-#define REGx(x) shiftx(x, demod, 0x200)
-#define FLDx(x) shiftx(x, demod, 0x2000000)
-
-/*MID*/
-#define R0900_MID 0xf100
-#define F0900_MCHIP_IDENT 0xf10000f0
-#define F0900_MRELEASE 0xf100000f
-
-/*DACR1*/
-#define R0900_DACR1 0xf113
-#define F0900_DAC_MODE 0xf11300e0
-#define F0900_DAC_VALUE1 0xf113000f
-
-/*DACR2*/
-#define R0900_DACR2 0xf114
-#define F0900_DAC_VALUE0 0xf11400ff
-
-/*OUTCFG*/
-#define R0900_OUTCFG 0xf11c
-#define F0900_OUTSERRS1_HZ 0xf11c0040
-#define F0900_OUTSERRS2_HZ 0xf11c0020
-#define F0900_OUTSERRS3_HZ 0xf11c0010
-#define F0900_OUTPARRS3_HZ 0xf11c0008
-
-/*IRQSTATUS3*/
-#define R0900_IRQSTATUS3 0xf120
-#define F0900_SPLL_LOCK 0xf1200020
-#define F0900_SSTREAM_LCK_3 0xf1200010
-#define F0900_SSTREAM_LCK_2 0xf1200008
-#define F0900_SSTREAM_LCK_1 0xf1200004
-#define F0900_SDVBS1_PRF_2 0xf1200002
-#define F0900_SDVBS1_PRF_1 0xf1200001
-
-/*IRQSTATUS2*/
-#define R0900_IRQSTATUS2 0xf121
-#define F0900_SSPY_ENDSIM_3 0xf1210080
-#define F0900_SSPY_ENDSIM_2 0xf1210040
-#define F0900_SSPY_ENDSIM_1 0xf1210020
-#define F0900_SPKTDEL_ERROR_2 0xf1210010
-#define F0900_SPKTDEL_LOCKB_2 0xf1210008
-#define F0900_SPKTDEL_LOCK_2 0xf1210004
-#define F0900_SPKTDEL_ERROR_1 0xf1210002
-#define F0900_SPKTDEL_LOCKB_1 0xf1210001
-
-/*IRQSTATUS1*/
-#define R0900_IRQSTATUS1 0xf122
-#define F0900_SPKTDEL_LOCK_1 0xf1220080
-#define F0900_SDEMOD_LOCKB_2 0xf1220004
-#define F0900_SDEMOD_LOCK_2 0xf1220002
-#define F0900_SDEMOD_IRQ_2 0xf1220001
-
-/*IRQSTATUS0*/
-#define R0900_IRQSTATUS0 0xf123
-#define F0900_SDEMOD_LOCKB_1 0xf1230080
-#define F0900_SDEMOD_LOCK_1 0xf1230040
-#define F0900_SDEMOD_IRQ_1 0xf1230020
-#define F0900_SBCH_ERRFLAG 0xf1230010
-#define F0900_SDISEQC2RX_IRQ 0xf1230008
-#define F0900_SDISEQC2TX_IRQ 0xf1230004
-#define F0900_SDISEQC1RX_IRQ 0xf1230002
-#define F0900_SDISEQC1TX_IRQ 0xf1230001
-
-/*IRQMASK3*/
-#define R0900_IRQMASK3 0xf124
-#define F0900_MPLL_LOCK 0xf1240020
-#define F0900_MSTREAM_LCK_3 0xf1240010
-#define F0900_MSTREAM_LCK_2 0xf1240008
-#define F0900_MSTREAM_LCK_1 0xf1240004
-#define F0900_MDVBS1_PRF_2 0xf1240002
-#define F0900_MDVBS1_PRF_1 0xf1240001
-
-/*IRQMASK2*/
-#define R0900_IRQMASK2 0xf125
-#define F0900_MSPY_ENDSIM_3 0xf1250080
-#define F0900_MSPY_ENDSIM_2 0xf1250040
-#define F0900_MSPY_ENDSIM_1 0xf1250020
-#define F0900_MPKTDEL_ERROR_2 0xf1250010
-#define F0900_MPKTDEL_LOCKB_2 0xf1250008
-#define F0900_MPKTDEL_LOCK_2 0xf1250004
-#define F0900_MPKTDEL_ERROR_1 0xf1250002
-#define F0900_MPKTDEL_LOCKB_1 0xf1250001
-
-/*IRQMASK1*/
-#define R0900_IRQMASK1 0xf126
-#define F0900_MPKTDEL_LOCK_1 0xf1260080
-#define F0900_MEXTPINB2 0xf1260040
-#define F0900_MEXTPIN2 0xf1260020
-#define F0900_MEXTPINB1 0xf1260010
-#define F0900_MEXTPIN1 0xf1260008
-#define F0900_MDEMOD_LOCKB_2 0xf1260004
-#define F0900_MDEMOD_LOCK_2 0xf1260002
-#define F0900_MDEMOD_IRQ_2 0xf1260001
-
-/*IRQMASK0*/
-#define R0900_IRQMASK0 0xf127
-#define F0900_MDEMOD_LOCKB_1 0xf1270080
-#define F0900_MDEMOD_LOCK_1 0xf1270040
-#define F0900_MDEMOD_IRQ_1 0xf1270020
-#define F0900_MBCH_ERRFLAG 0xf1270010
-#define F0900_MDISEQC2RX_IRQ 0xf1270008
-#define F0900_MDISEQC2TX_IRQ 0xf1270004
-#define F0900_MDISEQC1RX_IRQ 0xf1270002
-#define F0900_MDISEQC1TX_IRQ 0xf1270001
-
-/*I2CCFG*/
-#define R0900_I2CCFG 0xf129
-#define F0900_I2C_FASTMODE 0xf1290008
-#define F0900_I2CADDR_INC 0xf1290003
-
-/*P1_I2CRPT*/
-#define R0900_P1_I2CRPT 0xf12a
-#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
-#define F0900_P1_I2CT_ON 0xf12a0080
-#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
-#define F0900_P1_ENARPT_LEVEL 0xf12a0070
-#define F0900_P1_SCLT_DELAY 0xf12a0008
-#define F0900_P1_STOP_ENABLE 0xf12a0004
-#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
-
-/*P2_I2CRPT*/
-#define R0900_P2_I2CRPT 0xf12b
-#define F0900_P2_I2CT_ON 0xf12b0080
-#define F0900_P2_ENARPT_LEVEL 0xf12b0070
-#define F0900_P2_SCLT_DELAY 0xf12b0008
-#define F0900_P2_STOP_ENABLE 0xf12b0004
-#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
-
-/*IOPVALUE6*/
-#define R0900_IOPVALUE6 0xf138
-#define F0900_VSCL 0xf1380004
-#define F0900_VSDA 0xf1380002
-#define F0900_VDATA3_0 0xf1380001
-
-/*IOPVALUE5*/
-#define R0900_IOPVALUE5 0xf139
-#define F0900_VDATA3_1 0xf1390080
-#define F0900_VDATA3_2 0xf1390040
-#define F0900_VDATA3_3 0xf1390020
-#define F0900_VDATA3_4 0xf1390010
-#define F0900_VDATA3_5 0xf1390008
-#define F0900_VDATA3_6 0xf1390004
-#define F0900_VDATA3_7 0xf1390002
-#define F0900_VCLKOUT3 0xf1390001
-
-/*IOPVALUE4*/
-#define R0900_IOPVALUE4 0xf13a
-#define F0900_VSTROUT3 0xf13a0080
-#define F0900_VDPN3 0xf13a0040
-#define F0900_VERROR3 0xf13a0020
-#define F0900_VDATA2_7 0xf13a0010
-#define F0900_VCLKOUT2 0xf13a0008
-#define F0900_VSTROUT2 0xf13a0004
-#define F0900_VDPN2 0xf13a0002
-#define F0900_VERROR2 0xf13a0001
-
-/*IOPVALUE3*/
-#define R0900_IOPVALUE3 0xf13b
-#define F0900_VDATA1_7 0xf13b0080
-#define F0900_VCLKOUT1 0xf13b0040
-#define F0900_VSTROUT1 0xf13b0020
-#define F0900_VDPN1 0xf13b0010
-#define F0900_VERROR1 0xf13b0008
-#define F0900_VCLKOUT27 0xf13b0004
-#define F0900_VDISEQCOUT2 0xf13b0002
-#define F0900_VSCLT2 0xf13b0001
-
-/*IOPVALUE2*/
-#define R0900_IOPVALUE2 0xf13c
-#define F0900_VSDAT2 0xf13c0080
-#define F0900_VAGCRF2 0xf13c0040
-#define F0900_VDISEQCOUT1 0xf13c0020
-#define F0900_VSCLT1 0xf13c0010
-#define F0900_VSDAT1 0xf13c0008
-#define F0900_VAGCRF1 0xf13c0004
-#define F0900_VDIRCLK 0xf13c0002
-#define F0900_VSTDBY 0xf13c0001
-
-/*IOPVALUE1*/
-#define R0900_IOPVALUE1 0xf13d
-#define F0900_VCS1 0xf13d0080
-#define F0900_VCS0 0xf13d0040
-#define F0900_VGPIO13 0xf13d0020
-#define F0900_VGPIO12 0xf13d0010
-#define F0900_VGPIO11 0xf13d0008
-#define F0900_VGPIO10 0xf13d0004
-#define F0900_VGPIO9 0xf13d0002
-#define F0900_VGPIO8 0xf13d0001
-
-/*IOPVALUE0*/
-#define R0900_IOPVALUE0 0xf13e
-#define F0900_VGPIO7 0xf13e0080
-#define F0900_VGPIO6 0xf13e0040
-#define F0900_VGPIO5 0xf13e0020
-#define F0900_VGPIO4 0xf13e0010
-#define F0900_VGPIO3 0xf13e0008
-#define F0900_VGPIO2 0xf13e0004
-#define F0900_VGPIO1 0xf13e0002
-#define F0900_VCLKI2 0xf13e0001
-
-/*CLKI2CFG*/
-#define R0900_CLKI2CFG 0xf140
-#define F0900_CLKI2_OPD 0xf1400080
-#define F0900_CLKI2_CONFIG 0xf140007e
-#define F0900_CLKI2_XOR 0xf1400001
-
-/*GPIO1CFG*/
-#define R0900_GPIO1CFG 0xf141
-#define F0900_GPIO1_OPD 0xf1410080
-#define F0900_GPIO1_CONFIG 0xf141007e
-#define F0900_GPIO1_XOR 0xf1410001
-
-/*GPIO2CFG*/
-#define R0900_GPIO2CFG 0xf142
-#define F0900_GPIO2_OPD 0xf1420080
-#define F0900_GPIO2_CONFIG 0xf142007e
-#define F0900_GPIO2_XOR 0xf1420001
-
-/*GPIO3CFG*/
-#define R0900_GPIO3CFG 0xf143
-#define F0900_GPIO3_OPD 0xf1430080
-#define F0900_GPIO3_CONFIG 0xf143007e
-#define F0900_GPIO3_XOR 0xf1430001
-
-/*GPIO4CFG*/
-#define R0900_GPIO4CFG 0xf144
-#define F0900_GPIO4_OPD 0xf1440080
-#define F0900_GPIO4_CONFIG 0xf144007e
-#define F0900_GPIO4_XOR 0xf1440001
-
-/*GPIO5CFG*/
-#define R0900_GPIO5CFG 0xf145
-#define F0900_GPIO5_OPD 0xf1450080
-#define F0900_GPIO5_CONFIG 0xf145007e
-#define F0900_GPIO5_XOR 0xf1450001
-
-/*GPIO6CFG*/
-#define R0900_GPIO6CFG 0xf146
-#define F0900_GPIO6_OPD 0xf1460080
-#define F0900_GPIO6_CONFIG 0xf146007e
-#define F0900_GPIO6_XOR 0xf1460001
-
-/*GPIO7CFG*/
-#define R0900_GPIO7CFG 0xf147
-#define F0900_GPIO7_OPD 0xf1470080
-#define F0900_GPIO7_CONFIG 0xf147007e
-#define F0900_GPIO7_XOR 0xf1470001
-
-/*GPIO8CFG*/
-#define R0900_GPIO8CFG 0xf148
-#define F0900_GPIO8_OPD 0xf1480080
-#define F0900_GPIO8_CONFIG 0xf148007e
-#define F0900_GPIO8_XOR 0xf1480001
-
-/*GPIO9CFG*/
-#define R0900_GPIO9CFG 0xf149
-#define F0900_GPIO9_OPD 0xf1490080
-#define F0900_GPIO9_CONFIG 0xf149007e
-#define F0900_GPIO9_XOR 0xf1490001
-
-/*GPIO10CFG*/
-#define R0900_GPIO10CFG 0xf14a
-#define F0900_GPIO10_OPD 0xf14a0080
-#define F0900_GPIO10_CONFIG 0xf14a007e
-#define F0900_GPIO10_XOR 0xf14a0001
-
-/*GPIO11CFG*/
-#define R0900_GPIO11CFG 0xf14b
-#define F0900_GPIO11_OPD 0xf14b0080
-#define F0900_GPIO11_CONFIG 0xf14b007e
-#define F0900_GPIO11_XOR 0xf14b0001
-
-/*GPIO12CFG*/
-#define R0900_GPIO12CFG 0xf14c
-#define F0900_GPIO12_OPD 0xf14c0080
-#define F0900_GPIO12_CONFIG 0xf14c007e
-#define F0900_GPIO12_XOR 0xf14c0001
-
-/*GPIO13CFG*/
-#define R0900_GPIO13CFG 0xf14d
-#define F0900_GPIO13_OPD 0xf14d0080
-#define F0900_GPIO13_CONFIG 0xf14d007e
-#define F0900_GPIO13_XOR 0xf14d0001
-
-/*CS0CFG*/
-#define R0900_CS0CFG 0xf14e
-#define F0900_CS0_OPD 0xf14e0080
-#define F0900_CS0_CONFIG 0xf14e007e
-#define F0900_CS0_XOR 0xf14e0001
-
-/*CS1CFG*/
-#define R0900_CS1CFG 0xf14f
-#define F0900_CS1_OPD 0xf14f0080
-#define F0900_CS1_CONFIG 0xf14f007e
-#define F0900_CS1_XOR 0xf14f0001
-
-/*STDBYCFG*/
-#define R0900_STDBYCFG 0xf150
-#define F0900_STDBY_OPD 0xf1500080
-#define F0900_STDBY_CONFIG 0xf150007e
-#define F0900_STBDY_XOR 0xf1500001
-
-/*DIRCLKCFG*/
-#define R0900_DIRCLKCFG 0xf151
-#define F0900_DIRCLK_OPD 0xf1510080
-#define F0900_DIRCLK_CONFIG 0xf151007e
-#define F0900_DIRCLK_XOR 0xf1510001
-
-/*AGCRF1CFG*/
-#define R0900_AGCRF1CFG 0xf152
-#define F0900_AGCRF1_OPD 0xf1520080
-#define F0900_AGCRF1_CONFIG 0xf152007e
-#define F0900_AGCRF1_XOR 0xf1520001
-
-/*SDAT1CFG*/
-#define R0900_SDAT1CFG 0xf153
-#define F0900_SDAT1_OPD 0xf1530080
-#define F0900_SDAT1_CONFIG 0xf153007e
-#define F0900_SDAT1_XOR 0xf1530001
-
-/*SCLT1CFG*/
-#define R0900_SCLT1CFG 0xf154
-#define F0900_SCLT1_OPD 0xf1540080
-#define F0900_SCLT1_CONFIG 0xf154007e
-#define F0900_SCLT1_XOR 0xf1540001
-
-/*DISEQCO1CFG*/
-#define R0900_DISEQCO1CFG 0xf155
-#define F0900_DISEQCO1_OPD 0xf1550080
-#define F0900_DISEQCO1_CONFIG 0xf155007e
-#define F0900_DISEQC1_XOR 0xf1550001
-
-/*AGCRF2CFG*/
-#define R0900_AGCRF2CFG 0xf156
-#define F0900_AGCRF2_OPD 0xf1560080
-#define F0900_AGCRF2_CONFIG 0xf156007e
-#define F0900_AGCRF2_XOR 0xf1560001
-
-/*SDAT2CFG*/
-#define R0900_SDAT2CFG 0xf157
-#define F0900_SDAT2_OPD 0xf1570080
-#define F0900_SDAT2_CONFIG 0xf157007e
-#define F0900_SDAT2_XOR 0xf1570001
-
-/*SCLT2CFG*/
-#define R0900_SCLT2CFG 0xf158
-#define F0900_SCLT2_OPD 0xf1580080
-#define F0900_SCLT2_CONFIG 0xf158007e
-#define F0900_SCLT2_XOR 0xf1580001
-
-/*DISEQCO2CFG*/
-#define R0900_DISEQCO2CFG 0xf159
-#define F0900_DISEQCO2_OPD 0xf1590080
-#define F0900_DISEQCO2_CONFIG 0xf159007e
-#define F0900_DISEQC2_XOR 0xf1590001
-
-/*CLKOUT27CFG*/
-#define R0900_CLKOUT27CFG 0xf15a
-#define F0900_CLKOUT27_OPD 0xf15a0080
-#define F0900_CLKOUT27_CONFIG 0xf15a007e
-#define F0900_CLKOUT27_XOR 0xf15a0001
-
-/*ERROR1CFG*/
-#define R0900_ERROR1CFG 0xf15b
-#define F0900_ERROR1_OPD 0xf15b0080
-#define F0900_ERROR1_CONFIG 0xf15b007e
-#define F0900_ERROR1_XOR 0xf15b0001
-
-/*DPN1CFG*/
-#define R0900_DPN1CFG 0xf15c
-#define F0900_DPN1_OPD 0xf15c0080
-#define F0900_DPN1_CONFIG 0xf15c007e
-#define F0900_DPN1_XOR 0xf15c0001
-
-/*STROUT1CFG*/
-#define R0900_STROUT1CFG 0xf15d
-#define F0900_STROUT1_OPD 0xf15d0080
-#define F0900_STROUT1_CONFIG 0xf15d007e
-#define F0900_STROUT1_XOR 0xf15d0001
-
-/*CLKOUT1CFG*/
-#define R0900_CLKOUT1CFG 0xf15e
-#define F0900_CLKOUT1_OPD 0xf15e0080
-#define F0900_CLKOUT1_CONFIG 0xf15e007e
-#define F0900_CLKOUT1_XOR 0xf15e0001
-
-/*DATA71CFG*/
-#define R0900_DATA71CFG 0xf15f
-#define F0900_DATA71_OPD 0xf15f0080
-#define F0900_DATA71_CONFIG 0xf15f007e
-#define F0900_DATA71_XOR 0xf15f0001
-
-/*ERROR2CFG*/
-#define R0900_ERROR2CFG 0xf160
-#define F0900_ERROR2_OPD 0xf1600080
-#define F0900_ERROR2_CONFIG 0xf160007e
-#define F0900_ERROR2_XOR 0xf1600001
-
-/*DPN2CFG*/
-#define R0900_DPN2CFG 0xf161
-#define F0900_DPN2_OPD 0xf1610080
-#define F0900_DPN2_CONFIG 0xf161007e
-#define F0900_DPN2_XOR 0xf1610001
-
-/*STROUT2CFG*/
-#define R0900_STROUT2CFG 0xf162
-#define F0900_STROUT2_OPD 0xf1620080
-#define F0900_STROUT2_CONFIG 0xf162007e
-#define F0900_STROUT2_XOR 0xf1620001
-
-/*CLKOUT2CFG*/
-#define R0900_CLKOUT2CFG 0xf163
-#define F0900_CLKOUT2_OPD 0xf1630080
-#define F0900_CLKOUT2_CONFIG 0xf163007e
-#define F0900_CLKOUT2_XOR 0xf1630001
-
-/*DATA72CFG*/
-#define R0900_DATA72CFG 0xf164
-#define F0900_DATA72_OPD 0xf1640080
-#define F0900_DATA72_CONFIG 0xf164007e
-#define F0900_DATA72_XOR 0xf1640001
-
-/*ERROR3CFG*/
-#define R0900_ERROR3CFG 0xf165
-#define F0900_ERROR3_OPD 0xf1650080
-#define F0900_ERROR3_CONFIG 0xf165007e
-#define F0900_ERROR3_XOR 0xf1650001
-
-/*DPN3CFG*/
-#define R0900_DPN3CFG 0xf166
-#define F0900_DPN3_OPD 0xf1660080
-#define F0900_DPN3_CONFIG 0xf166007e
-#define F0900_DPN3_XOR 0xf1660001
-
-/*STROUT3CFG*/
-#define R0900_STROUT3CFG 0xf167
-#define F0900_STROUT3_OPD 0xf1670080
-#define F0900_STROUT3_CONFIG 0xf167007e
-#define F0900_STROUT3_XOR 0xf1670001
-
-/*CLKOUT3CFG*/
-#define R0900_CLKOUT3CFG 0xf168
-#define F0900_CLKOUT3_OPD 0xf1680080
-#define F0900_CLKOUT3_CONFIG 0xf168007e
-#define F0900_CLKOUT3_XOR 0xf1680001
-
-/*DATA73CFG*/
-#define R0900_DATA73CFG 0xf169
-#define F0900_DATA73_OPD 0xf1690080
-#define F0900_DATA73_CONFIG 0xf169007e
-#define F0900_DATA73_XOR 0xf1690001
-
-/*STRSTATUS1*/
-#define R0900_STRSTATUS1 0xf16a
-#define F0900_STRSTATUS_SEL2 0xf16a00f0
-#define F0900_STRSTATUS_SEL1 0xf16a000f
-
-/*STRSTATUS2*/
-#define R0900_STRSTATUS2 0xf16b
-#define F0900_STRSTATUS_SEL4 0xf16b00f0
-#define F0900_STRSTATUS_SEL3 0xf16b000f
-
-/*STRSTATUS3*/
-#define R0900_STRSTATUS3 0xf16c
-#define F0900_STRSTATUS_SEL6 0xf16c00f0
-#define F0900_STRSTATUS_SEL5 0xf16c000f
-
-/*FSKTFC2*/
-#define R0900_FSKTFC2 0xf170
-#define F0900_FSKT_KMOD 0xf17000fc
-#define F0900_FSKT_CAR2 0xf1700003
-
-/*FSKTFC1*/
-#define R0900_FSKTFC1 0xf171
-#define F0900_FSKT_CAR1 0xf17100ff
-
-/*FSKTFC0*/
-#define R0900_FSKTFC0 0xf172
-#define F0900_FSKT_CAR0 0xf17200ff
-
-/*FSKTDELTAF1*/
-#define R0900_FSKTDELTAF1 0xf173
-#define F0900_FSKT_DELTAF1 0xf173000f
-
-/*FSKTDELTAF0*/
-#define R0900_FSKTDELTAF0 0xf174
-#define F0900_FSKT_DELTAF0 0xf17400ff
-
-/*FSKTCTRL*/
-#define R0900_FSKTCTRL 0xf175
-#define F0900_FSKT_EN_SGN 0xf1750040
-#define F0900_FSKT_MOD_SGN 0xf1750020
-#define F0900_FSKT_MOD_EN 0xf175001c
-#define F0900_FSKT_DACMODE 0xf1750003
-
-/*FSKRFC2*/
-#define R0900_FSKRFC2 0xf176
-#define F0900_FSKR_DETSGN 0xf1760040
-#define F0900_FSKR_OUTSGN 0xf1760020
-#define F0900_FSKR_KAGC 0xf176001c
-#define F0900_FSKR_CAR2 0xf1760003
-
-/*FSKRFC1*/
-#define R0900_FSKRFC1 0xf177
-#define F0900_FSKR_CAR1 0xf17700ff
-
-/*FSKRFC0*/
-#define R0900_FSKRFC0 0xf178
-#define F0900_FSKR_CAR0 0xf17800ff
-
-/*FSKRK1*/
-#define R0900_FSKRK1 0xf179
-#define F0900_FSKR_K1_EXP 0xf17900e0
-#define F0900_FSKR_K1_MANT 0xf179001f
-
-/*FSKRK2*/
-#define R0900_FSKRK2 0xf17a
-#define F0900_FSKR_K2_EXP 0xf17a00e0
-#define F0900_FSKR_K2_MANT 0xf17a001f
-
-/*FSKRAGCR*/
-#define R0900_FSKRAGCR 0xf17b
-#define F0900_FSKR_OUTCTL 0xf17b00c0
-#define F0900_FSKR_AGC_REF 0xf17b003f
-
-/*FSKRAGC*/
-#define R0900_FSKRAGC 0xf17c
-#define F0900_FSKR_AGC_ACCU 0xf17c00ff
-
-/*FSKRALPHA*/
-#define R0900_FSKRALPHA 0xf17d
-#define F0900_FSKR_ALPHA_EXP 0xf17d001c
-#define F0900_FSKR_ALPHA_M 0xf17d0003
-
-/*FSKRPLTH1*/
-#define R0900_FSKRPLTH1 0xf17e
-#define F0900_FSKR_BETA 0xf17e00f0
-#define F0900_FSKR_PLL_TRESH1 0xf17e000f
-
-/*FSKRPLTH0*/
-#define R0900_FSKRPLTH0 0xf17f
-#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
-
-/*FSKRDF1*/
-#define R0900_FSKRDF1 0xf180
-#define F0900_FSKR_OUT 0xf1800080
-#define F0900_FSKR_DELTAF1 0xf180001f
-
-/*FSKRDF0*/
-#define R0900_FSKRDF0 0xf181
-#define F0900_FSKR_DELTAF0 0xf18100ff
-
-/*FSKRSTEPP*/
-#define R0900_FSKRSTEPP 0xf182
-#define F0900_FSKR_STEP_PLUS 0xf18200ff
-
-/*FSKRSTEPM*/
-#define R0900_FSKRSTEPM 0xf183
-#define F0900_FSKR_STEP_MINUS 0xf18300ff
-
-/*FSKRDET1*/
-#define R0900_FSKRDET1 0xf184
-#define F0900_FSKR_DETECT 0xf1840080
-#define F0900_FSKR_CARDET_ACCU1 0xf184000f
-
-/*FSKRDET0*/
-#define R0900_FSKRDET0 0xf185
-#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
-
-/*FSKRDTH1*/
-#define R0900_FSKRDTH1 0xf186
-#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
-#define F0900_FSKR_CARDET_THRESH1 0xf186000f
-
-/*FSKRDTH0*/
-#define R0900_FSKRDTH0 0xf187
-#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
-
-/*FSKRLOSS*/
-#define R0900_FSKRLOSS 0xf188
-#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
-
-/*P2_DISTXCTL*/
-#define R0900_P2_DISTXCTL 0xf190
-#define F0900_P2_TIM_OFF 0xf1900080
-#define F0900_P2_DISEQC_RESET 0xf1900040
-#define F0900_P2_TIM_CMD 0xf1900030
-#define F0900_P2_DIS_PRECHARGE 0xf1900008
-#define F0900_P2_DISTX_MODE 0xf1900007
-
-/*P2_DISRXCTL*/
-#define R0900_P2_DISRXCTL 0xf191
-#define F0900_P2_RECEIVER_ON 0xf1910080
-#define F0900_P2_IGNO_SHORT22K 0xf1910040
-#define F0900_P2_ONECHIP_TRX 0xf1910020
-#define F0900_P2_EXT_ENVELOP 0xf1910010
-#define F0900_P2_PIN_SELECT0 0xf191000c
-#define F0900_P2_IRQ_RXEND 0xf1910002
-#define F0900_P2_IRQ_4NBYTES 0xf1910001
-
-/*P2_DISRX_ST0*/
-#define R0900_P2_DISRX_ST0 0xf194
-#define F0900_P2_RX_END 0xf1940080
-#define F0900_P2_RX_ACTIVE 0xf1940040
-#define F0900_P2_SHORT_22KHZ 0xf1940020
-#define F0900_P2_CONT_TONE 0xf1940010
-#define F0900_P2_FIFO_4BREADY 0xf1940008
-#define F0900_P2_FIFO_EMPTY 0xf1940004
-#define F0900_P2_ABORT_DISRX 0xf1940001
-
-/*P2_DISRX_ST1*/
-#define R0900_P2_DISRX_ST1 0xf195
-#define F0900_P2_RX_FAIL 0xf1950080
-#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
-#define F0900_P2_RX_NONBYTE 0xf1950020
-#define F0900_P2_FIFO_OVERFLOW 0xf1950010
-#define F0900_P2_FIFO_BYTENBR 0xf195000f
-
-/*P2_DISRXDATA*/
-#define R0900_P2_DISRXDATA 0xf196
-#define F0900_P2_DISRX_DATA 0xf19600ff
-
-/*P2_DISTXDATA*/
-#define R0900_P2_DISTXDATA 0xf197
-#define F0900_P2_DISEQC_FIFO 0xf19700ff
-
-/*P2_DISTXSTATUS*/
-#define R0900_P2_DISTXSTATUS 0xf198
-#define F0900_P2_TX_FAIL 0xf1980080
-#define F0900_P2_FIFO_FULL 0xf1980040
-#define F0900_P2_TX_IDLE 0xf1980020
-#define F0900_P2_GAP_BURST 0xf1980010
-#define F0900_P2_TXFIFO_BYTES 0xf198000f
-
-/*P2_F22TX*/
-#define R0900_P2_F22TX 0xf199
-#define F0900_P2_F22_REG 0xf19900ff
-
-/*P2_F22RX*/
-#define R0900_P2_F22RX 0xf19a
-#define F0900_P2_F22RX_REG 0xf19a00ff
-
-/*P2_ACRPRESC*/
-#define R0900_P2_ACRPRESC 0xf19c
-#define F0900_P2_ACR_PRESC 0xf19c0007
-
-/*P2_ACRDIV*/
-#define R0900_P2_ACRDIV 0xf19d
-#define F0900_P2_ACR_DIV 0xf19d00ff
-
-/*P1_DISTXCTL*/
-#define R0900_P1_DISTXCTL 0xf1a0
-#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
-#define F0900_P1_TIM_OFF 0xf1a00080
-#define F0900_P1_DISEQC_RESET 0xf1a00040
-#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
-#define F0900_P1_TIM_CMD 0xf1a00030
-#define F0900_P1_DIS_PRECHARGE 0xf1a00008
-#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
-#define F0900_P1_DISTX_MODE 0xf1a00007
-#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
-
-/*P1_DISRXCTL*/
-#define R0900_P1_DISRXCTL 0xf1a1
-#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
-#define F0900_P1_RECEIVER_ON 0xf1a10080
-#define F0900_P1_IGNO_SHORT22K 0xf1a10040
-#define F0900_P1_ONECHIP_TRX 0xf1a10020
-#define F0900_P1_EXT_ENVELOP 0xf1a10010
-#define F0900_P1_PIN_SELECT0 0xf1a1000c
-#define F0900_P1_IRQ_RXEND 0xf1a10002
-#define F0900_P1_IRQ_4NBYTES 0xf1a10001
-
-/*P1_DISRX_ST0*/
-#define R0900_P1_DISRX_ST0 0xf1a4
-#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
-#define F0900_P1_RX_END 0xf1a40080
-#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
-#define F0900_P1_RX_ACTIVE 0xf1a40040
-#define F0900_P1_SHORT_22KHZ 0xf1a40020
-#define F0900_P1_CONT_TONE 0xf1a40010
-#define F0900_P1_FIFO_4BREADY 0xf1a40008
-#define F0900_P1_FIFO_EMPTY 0xf1a40004
-#define F0900_P1_ABORT_DISRX 0xf1a40001
-
-/*P1_DISRX_ST1*/
-#define R0900_P1_DISRX_ST1 0xf1a5
-#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
-#define F0900_P1_RX_FAIL 0xf1a50080
-#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
-#define F0900_P1_RX_NONBYTE 0xf1a50020
-#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
-#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
-#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
-
-/*P1_DISRXDATA*/
-#define R0900_P1_DISRXDATA 0xf1a6
-#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
-#define F0900_P1_DISRX_DATA 0xf1a600ff
-
-/*P1_DISTXDATA*/
-#define R0900_P1_DISTXDATA 0xf1a7
-#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
-#define F0900_P1_DISEQC_FIFO 0xf1a700ff
-
-/*P1_DISTXSTATUS*/
-#define R0900_P1_DISTXSTATUS 0xf1a8
-#define F0900_P1_TX_FAIL 0xf1a80080
-#define F0900_P1_FIFO_FULL 0xf1a80040
-#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
-#define F0900_P1_TX_IDLE 0xf1a80020
-#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
-#define F0900_P1_GAP_BURST 0xf1a80010
-#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
-
-/*P1_F22TX*/
-#define R0900_P1_F22TX 0xf1a9
-#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
-#define F0900_P1_F22_REG 0xf1a900ff
-
-/*P1_F22RX*/
-#define R0900_P1_F22RX 0xf1aa
-#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
-#define F0900_P1_F22RX_REG 0xf1aa00ff
-
-/*P1_ACRPRESC*/
-#define R0900_P1_ACRPRESC 0xf1ac
-#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
-#define F0900_P1_ACR_PRESC 0xf1ac0007
-
-/*P1_ACRDIV*/
-#define R0900_P1_ACRDIV 0xf1ad
-#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
-#define F0900_P1_ACR_DIV 0xf1ad00ff
-
-/*NCOARSE*/
-#define R0900_NCOARSE 0xf1b3
-#define F0900_M_DIV 0xf1b300ff
-
-/*SYNTCTRL*/
-#define R0900_SYNTCTRL 0xf1b6
-#define F0900_STANDBY 0xf1b60080
-#define F0900_BYPASSPLLCORE 0xf1b60040
-#define F0900_SELX1RATIO 0xf1b60020
-#define F0900_STOP_PLL 0xf1b60008
-#define F0900_BYPASSPLLFSK 0xf1b60004
-#define F0900_SELOSCI 0xf1b60002
-#define F0900_BYPASSPLLADC 0xf1b60001
-
-/*FILTCTRL*/
-#define R0900_FILTCTRL 0xf1b7
-#define F0900_INV_CLK135 0xf1b70080
-#define F0900_SEL_FSKCKDIV 0xf1b70004
-#define F0900_INV_CLKFSK 0xf1b70002
-#define F0900_BYPASS_APPLI 0xf1b70001
-
-/*PLLSTAT*/
-#define R0900_PLLSTAT 0xf1b8
-#define F0900_PLLLOCK 0xf1b80001
-
-/*STOPCLK1*/
-#define R0900_STOPCLK1 0xf1c2
-#define F0900_STOP_CLKPKDT2 0xf1c20040
-#define F0900_STOP_CLKPKDT1 0xf1c20020
-#define F0900_STOP_CLKFEC 0xf1c20010
-#define F0900_STOP_CLKADCI2 0xf1c20008
-#define F0900_INV_CLKADCI2 0xf1c20004
-#define F0900_STOP_CLKADCI1 0xf1c20002
-#define F0900_INV_CLKADCI1 0xf1c20001
-
-/*STOPCLK2*/
-#define R0900_STOPCLK2 0xf1c3
-#define F0900_STOP_CLKSAMP2 0xf1c30010
-#define F0900_STOP_CLKSAMP1 0xf1c30008
-#define F0900_STOP_CLKVIT2 0xf1c30004
-#define F0900_STOP_CLKVIT1 0xf1c30002
-#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
-#define F0900_STOP_CLKTS 0xf1c30001
-
-/*TSTTNR0*/
-#define R0900_TSTTNR0 0xf1df
-#define F0900_SEL_FSK 0xf1df0080
-#define F0900_FSK_PON 0xf1df0004
-
-/*TSTTNR1*/
-#define R0900_TSTTNR1 0xf1e0
-#define F0900_ADC1_PON 0xf1e00002
-#define F0900_ADC1_INMODE 0xf1e00001
-
-/*TSTTNR2*/
-#define R0900_TSTTNR2 0xf1e1
-#define F0900_DISEQC1_PON 0xf1e10020
-
-/*TSTTNR3*/
-#define R0900_TSTTNR3 0xf1e2
-#define F0900_ADC2_PON 0xf1e20002
-#define F0900_ADC2_INMODE 0xf1e20001
-
-/*TSTTNR4*/
-#define R0900_TSTTNR4 0xf1e3
-#define F0900_DISEQC2_PON 0xf1e30020
-
-/*P2_IQCONST*/
-#define R0900_P2_IQCONST 0xf200
-#define F0900_P2_CONSTEL_SELECT 0xf2000060
-#define F0900_P2_IQSYMB_SEL 0xf200001f
-
-/*P2_NOSCFG*/
-#define R0900_P2_NOSCFG 0xf201
-#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
-#define F0900_P2_NOSPLH_BETA 0xf2010018
-#define F0900_P2_NOSDATA_BETA 0xf2010007
-
-/*P2_ISYMB*/
-#define R0900_P2_ISYMB 0xf202
-#define F0900_P2_I_SYMBOL 0xf20201ff
-
-/*P2_QSYMB*/
-#define R0900_P2_QSYMB 0xf203
-#define F0900_P2_Q_SYMBOL 0xf20301ff
-
-/*P2_AGC1CFG*/
-#define R0900_P2_AGC1CFG 0xf204
-#define F0900_P2_DC_FROZEN 0xf2040080
-#define F0900_P2_DC_CORRECT 0xf2040040
-#define F0900_P2_AMM_FROZEN 0xf2040020
-#define F0900_P2_AMM_CORRECT 0xf2040010
-#define F0900_P2_QUAD_FROZEN 0xf2040008
-#define F0900_P2_QUAD_CORRECT 0xf2040004
-
-/*P2_AGC1CN*/
-#define R0900_P2_AGC1CN 0xf206
-#define F0900_P2_AGC1_LOCKED 0xf2060080
-#define F0900_P2_AGC1_MINPOWER 0xf2060010
-#define F0900_P2_AGCOUT_FAST 0xf2060008
-#define F0900_P2_AGCIQ_BETA 0xf2060007
-
-/*P2_AGC1REF*/
-#define R0900_P2_AGC1REF 0xf207
-#define F0900_P2_AGCIQ_REF 0xf20700ff
-
-/*P2_IDCCOMP*/
-#define R0900_P2_IDCCOMP 0xf208
-#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
-
-/*P2_QDCCOMP*/
-#define R0900_P2_QDCCOMP 0xf209
-#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
-
-/*P2_POWERI*/
-#define R0900_P2_POWERI 0xf20a
-#define F0900_P2_POWER_I 0xf20a00ff
-
-/*P2_POWERQ*/
-#define R0900_P2_POWERQ 0xf20b
-#define F0900_P2_POWER_Q 0xf20b00ff
-
-/*P2_AGC1AMM*/
-#define R0900_P2_AGC1AMM 0xf20c
-#define F0900_P2_AMM_VALUE 0xf20c00ff
-
-/*P2_AGC1QUAD*/
-#define R0900_P2_AGC1QUAD 0xf20d
-#define F0900_P2_QUAD_VALUE 0xf20d01ff
-
-/*P2_AGCIQIN1*/
-#define R0900_P2_AGCIQIN1 0xf20e
-#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
-
-/*P2_AGCIQIN0*/
-#define R0900_P2_AGCIQIN0 0xf20f
-#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
-
-/*P2_DEMOD*/
-#define R0900_P2_DEMOD 0xf210
-#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
-#define F0900_P2_SPECINV_CONTROL 0xf2100030
-#define F0900_P2_FORCE_ENASAMP 0xf2100008
-#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
-#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
-
-/*P2_DMDMODCOD*/
-#define R0900_P2_DMDMODCOD 0xf211
-#define F0900_P2_MANUAL_MODCOD 0xf2110080
-#define F0900_P2_DEMOD_MODCOD 0xf211007c
-#define F0900_P2_DEMOD_TYPE 0xf2110003
-
-/*P2_DSTATUS*/
-#define R0900_P2_DSTATUS 0xf212
-#define F0900_P2_CAR_LOCK 0xf2120080
-#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
-#define F0900_P2_LOCK_DEFINITIF 0xf2120008
-#define F0900_P2_OVADC_DETECT 0xf2120001
-
-/*P2_DSTATUS2*/
-#define R0900_P2_DSTATUS2 0xf213
-#define F0900_P2_DEMOD_DELOCK 0xf2130080
-#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
-#define F0900_P2_AGC2_OVERFLOW 0xf2130004
-#define F0900_P2_CFR_OVERFLOW 0xf2130002
-#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
-
-/*P2_DMDCFGMD*/
-#define R0900_P2_DMDCFGMD 0xf214
-#define F0900_P2_DVBS2_ENABLE 0xf2140080
-#define F0900_P2_DVBS1_ENABLE 0xf2140040
-#define F0900_P2_SCAN_ENABLE 0xf2140010
-#define F0900_P2_CFR_AUTOSCAN 0xf2140008
-#define F0900_P2_TUN_RNG 0xf2140003
-
-/*P2_DMDCFG2*/
-#define R0900_P2_DMDCFG2 0xf215
-#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
-#define F0900_P2_INFINITE_RELOCK 0xf2150010
-
-/*P2_DMDISTATE*/
-#define R0900_P2_DMDISTATE 0xf216
-#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
-
-/*P2_DMDT0M*/
-#define R0900_P2_DMDT0M 0xf217
-#define F0900_P2_DMDT0_MIN 0xf21700ff
-
-/*P2_DMDSTATE*/
-#define R0900_P2_DMDSTATE 0xf21b
-#define F0900_P2_HEADER_MODE 0xf21b0060
-
-/*P2_DMDFLYW*/
-#define R0900_P2_DMDFLYW 0xf21c
-#define F0900_P2_I2C_IRQVAL 0xf21c00f0
-#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
-
-/*P2_DSTATUS3*/
-#define R0900_P2_DSTATUS3 0xf21d
-#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
-
-/*P2_DMDCFG3*/
-#define R0900_P2_DMDCFG3 0xf21e
-#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
-
-/*P2_DMDCFG4*/
-#define R0900_P2_DMDCFG4 0xf21f
-#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
-
-/*P2_CORRELMANT*/
-#define R0900_P2_CORRELMANT 0xf220
-#define F0900_P2_CORREL_MANT 0xf22000ff
-
-/*P2_CORRELABS*/
-#define R0900_P2_CORRELABS 0xf221
-#define F0900_P2_CORREL_ABS 0xf22100ff
-
-/*P2_CORRELEXP*/
-#define R0900_P2_CORRELEXP 0xf222
-#define F0900_P2_CORREL_ABSEXP 0xf22200f0
-#define F0900_P2_CORREL_EXP 0xf222000f
-
-/*P2_PLHMODCOD*/
-#define R0900_P2_PLHMODCOD 0xf224
-#define F0900_P2_SPECINV_DEMOD 0xf2240080
-#define F0900_P2_PLH_MODCOD 0xf224007c
-#define F0900_P2_PLH_TYPE 0xf2240003
-
-/*P2_DMDREG*/
-#define R0900_P2_DMDREG 0xf225
-#define F0900_P2_DECIM_PLFRAMES 0xf2250001
-
-/*P2_AGC2O*/
-#define R0900_P2_AGC2O 0xf22c
-#define F0900_P2_AGC2_COEF 0xf22c0007
-
-/*P2_AGC2REF*/
-#define R0900_P2_AGC2REF 0xf22d
-#define F0900_P2_AGC2_REF 0xf22d00ff
-
-/*P2_AGC1ADJ*/
-#define R0900_P2_AGC1ADJ 0xf22e
-#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
-
-/*P2_AGC2I1*/
-#define R0900_P2_AGC2I1 0xf236
-#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
-
-/*P2_AGC2I0*/
-#define R0900_P2_AGC2I0 0xf237
-#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
-
-/*P2_CARCFG*/
-#define R0900_P2_CARCFG 0xf238
-#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
-#define F0900_P2_CFRUPLOW_TEST 0xf2380040
-#define F0900_P2_ROTAON 0xf2380004
-#define F0900_P2_PH_DET_ALGO 0xf2380003
-
-/*P2_ACLC*/
-#define R0900_P2_ACLC 0xf239
-#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
-#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
-
-/*P2_BCLC*/
-#define R0900_P2_BCLC 0xf23a
-#define F0900_P2_CAR_BETA_MANT 0xf23a0030
-#define F0900_P2_CAR_BETA_EXP 0xf23a000f
-
-/*P2_CARFREQ*/
-#define R0900_P2_CARFREQ 0xf23d
-#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
-#define F0900_P2_BETA_FREQ 0xf23d000f
-
-/*P2_CARHDR*/
-#define R0900_P2_CARHDR 0xf23e
-#define F0900_P2_K_FREQ_HDR 0xf23e00ff
-
-/*P2_LDT*/
-#define R0900_P2_LDT 0xf23f
-#define F0900_P2_CARLOCK_THRES 0xf23f01ff
-
-/*P2_LDT2*/
-#define R0900_P2_LDT2 0xf240
-#define F0900_P2_CARLOCK_THRES2 0xf24001ff
-
-/*P2_CFRICFG*/
-#define R0900_P2_CFRICFG 0xf241
-#define F0900_P2_NEG_CFRSTEP 0xf2410001
-
-/*P2_CFRUP1*/
-#define R0900_P2_CFRUP1 0xf242
-#define F0900_P2_CFR_UP1 0xf24201ff
-
-/*P2_CFRUP0*/
-#define R0900_P2_CFRUP0 0xf243
-#define F0900_P2_CFR_UP0 0xf24300ff
-
-/*P2_CFRLOW1*/
-#define R0900_P2_CFRLOW1 0xf246
-#define F0900_P2_CFR_LOW1 0xf24601ff
-
-/*P2_CFRLOW0*/
-#define R0900_P2_CFRLOW0 0xf247
-#define F0900_P2_CFR_LOW0 0xf24700ff
-
-/*P2_CFRINIT1*/
-#define R0900_P2_CFRINIT1 0xf248
-#define F0900_P2_CFR_INIT1 0xf24801ff
-
-/*P2_CFRINIT0*/
-#define R0900_P2_CFRINIT0 0xf249
-#define F0900_P2_CFR_INIT0 0xf24900ff
-
-/*P2_CFRINC1*/
-#define R0900_P2_CFRINC1 0xf24a
-#define F0900_P2_MANUAL_CFRINC 0xf24a0080
-#define F0900_P2_CFR_INC1 0xf24a003f
-
-/*P2_CFRINC0*/
-#define R0900_P2_CFRINC0 0xf24b
-#define F0900_P2_CFR_INC0 0xf24b00f8
-
-/*P2_CFR2*/
-#define R0900_P2_CFR2 0xf24c
-#define F0900_P2_CAR_FREQ2 0xf24c01ff
-
-/*P2_CFR1*/
-#define R0900_P2_CFR1 0xf24d
-#define F0900_P2_CAR_FREQ1 0xf24d00ff
-
-/*P2_CFR0*/
-#define R0900_P2_CFR0 0xf24e
-#define F0900_P2_CAR_FREQ0 0xf24e00ff
-
-/*P2_LDI*/
-#define R0900_P2_LDI 0xf24f
-#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
-
-/*P2_TMGCFG*/
-#define R0900_P2_TMGCFG 0xf250
-#define F0900_P2_TMGLOCK_BETA 0xf25000c0
-#define F0900_P2_DO_TIMING_CORR 0xf2500010
-#define F0900_P2_TMG_MINFREQ 0xf2500003
-
-/*P2_RTC*/
-#define R0900_P2_RTC 0xf251
-#define F0900_P2_TMGALPHA_EXP 0xf25100f0
-#define F0900_P2_TMGBETA_EXP 0xf251000f
-
-/*P2_RTCS2*/
-#define R0900_P2_RTCS2 0xf252
-#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
-#define F0900_P2_TMGBETAS2_EXP 0xf252000f
-
-/*P2_TMGTHRISE*/
-#define R0900_P2_TMGTHRISE 0xf253
-#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
-
-/*P2_TMGTHFALL*/
-#define R0900_P2_TMGTHFALL 0xf254
-#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
-
-/*P2_SFRUPRATIO*/
-#define R0900_P2_SFRUPRATIO 0xf255
-#define F0900_P2_SFR_UPRATIO 0xf25500ff
-
-/*P2_SFRLOWRATIO*/
-#define R0900_P2_SFRLOWRATIO 0xf256
-#define F0900_P2_SFR_LOWRATIO 0xf25600ff
-
-/*P2_KREFTMG*/
-#define R0900_P2_KREFTMG 0xf258
-#define F0900_P2_KREF_TMG 0xf25800ff
-
-/*P2_SFRSTEP*/
-#define R0900_P2_SFRSTEP 0xf259
-#define F0900_P2_SFR_SCANSTEP 0xf25900f0
-#define F0900_P2_SFR_CENTERSTEP 0xf259000f
-
-/*P2_TMGCFG2*/
-#define R0900_P2_TMGCFG2 0xf25a
-#define F0900_P2_SFRRATIO_FINE 0xf25a0001
-
-/*P2_KREFTMG2*/
-#define R0900_P2_KREFTMG2 0xf25b
-#define F0900_P2_KREF_TMG2 0xf25b00ff
-
-/*P2_SFRINIT1*/
-#define R0900_P2_SFRINIT1 0xf25e
-#define F0900_P2_SFR_INIT1 0xf25e007f
-
-/*P2_SFRINIT0*/
-#define R0900_P2_SFRINIT0 0xf25f
-#define F0900_P2_SFR_INIT0 0xf25f00ff
-
-/*P2_SFRUP1*/
-#define R0900_P2_SFRUP1 0xf260
-#define F0900_P2_AUTO_GUP 0xf2600080
-#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
-
-/*P2_SFRUP0*/
-#define R0900_P2_SFRUP0 0xf261
-#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
-
-/*P2_SFRLOW1*/
-#define R0900_P2_SFRLOW1 0xf262
-#define F0900_P2_AUTO_GLOW 0xf2620080
-#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
-
-/*P2_SFRLOW0*/
-#define R0900_P2_SFRLOW0 0xf263
-#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
-
-/*P2_SFR3*/
-#define R0900_P2_SFR3 0xf264
-#define F0900_P2_SYMB_FREQ3 0xf26400ff
-
-/*P2_SFR2*/
-#define R0900_P2_SFR2 0xf265
-#define F0900_P2_SYMB_FREQ2 0xf26500ff
-
-/*P2_SFR1*/
-#define R0900_P2_SFR1 0xf266
-#define F0900_P2_SYMB_FREQ1 0xf26600ff
-
-/*P2_SFR0*/
-#define R0900_P2_SFR0 0xf267
-#define F0900_P2_SYMB_FREQ0 0xf26700ff
-
-/*P2_TMGREG2*/
-#define R0900_P2_TMGREG2 0xf268
-#define F0900_P2_TMGREG2 0xf26800ff
-
-/*P2_TMGREG1*/
-#define R0900_P2_TMGREG1 0xf269
-#define F0900_P2_TMGREG1 0xf26900ff
-
-/*P2_TMGREG0*/
-#define R0900_P2_TMGREG0 0xf26a
-#define F0900_P2_TMGREG0 0xf26a00ff
-
-/*P2_TMGLOCK1*/
-#define R0900_P2_TMGLOCK1 0xf26b
-#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
-
-/*P2_TMGLOCK0*/
-#define R0900_P2_TMGLOCK0 0xf26c
-#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
-
-/*P2_TMGOBS*/
-#define R0900_P2_TMGOBS 0xf26d
-#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
-
-/*P2_EQUALCFG*/
-#define R0900_P2_EQUALCFG 0xf26f
-#define F0900_P2_EQUAL_ON 0xf26f0040
-#define F0900_P2_MU_EQUALDFE 0xf26f0007
-
-/*P2_EQUAI1*/
-#define R0900_P2_EQUAI1 0xf270
-#define F0900_P2_EQUA_ACCI1 0xf27001ff
-
-/*P2_EQUAQ1*/
-#define R0900_P2_EQUAQ1 0xf271
-#define F0900_P2_EQUA_ACCQ1 0xf27101ff
-
-/*P2_EQUAI2*/
-#define R0900_P2_EQUAI2 0xf272
-#define F0900_P2_EQUA_ACCI2 0xf27201ff
-
-/*P2_EQUAQ2*/
-#define R0900_P2_EQUAQ2 0xf273
-#define F0900_P2_EQUA_ACCQ2 0xf27301ff
-
-/*P2_EQUAI3*/
-#define R0900_P2_EQUAI3 0xf274
-#define F0900_P2_EQUA_ACCI3 0xf27401ff
-
-/*P2_EQUAQ3*/
-#define R0900_P2_EQUAQ3 0xf275
-#define F0900_P2_EQUA_ACCQ3 0xf27501ff
-
-/*P2_EQUAI4*/
-#define R0900_P2_EQUAI4 0xf276
-#define F0900_P2_EQUA_ACCI4 0xf27601ff
-
-/*P2_EQUAQ4*/
-#define R0900_P2_EQUAQ4 0xf277
-#define F0900_P2_EQUA_ACCQ4 0xf27701ff
-
-/*P2_EQUAI5*/
-#define R0900_P2_EQUAI5 0xf278
-#define F0900_P2_EQUA_ACCI5 0xf27801ff
-
-/*P2_EQUAQ5*/
-#define R0900_P2_EQUAQ5 0xf279
-#define F0900_P2_EQUA_ACCQ5 0xf27901ff
-
-/*P2_EQUAI6*/
-#define R0900_P2_EQUAI6 0xf27a
-#define F0900_P2_EQUA_ACCI6 0xf27a01ff
-
-/*P2_EQUAQ6*/
-#define R0900_P2_EQUAQ6 0xf27b
-#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
-
-/*P2_EQUAI7*/
-#define R0900_P2_EQUAI7 0xf27c
-#define F0900_P2_EQUA_ACCI7 0xf27c01ff
-
-/*P2_EQUAQ7*/
-#define R0900_P2_EQUAQ7 0xf27d
-#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
-
-/*P2_EQUAI8*/
-#define R0900_P2_EQUAI8 0xf27e
-#define F0900_P2_EQUA_ACCI8 0xf27e01ff
-
-/*P2_EQUAQ8*/
-#define R0900_P2_EQUAQ8 0xf27f
-#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
-
-/*P2_NNOSDATAT1*/
-#define R0900_P2_NNOSDATAT1 0xf280
-#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
-
-/*P2_NNOSDATAT0*/
-#define R0900_P2_NNOSDATAT0 0xf281
-#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
-
-/*P2_NNOSDATA1*/
-#define R0900_P2_NNOSDATA1 0xf282
-#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
-
-/*P2_NNOSDATA0*/
-#define R0900_P2_NNOSDATA0 0xf283
-#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
-
-/*P2_NNOSPLHT1*/
-#define R0900_P2_NNOSPLHT1 0xf284
-#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
-
-/*P2_NNOSPLHT0*/
-#define R0900_P2_NNOSPLHT0 0xf285
-#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
-
-/*P2_NNOSPLH1*/
-#define R0900_P2_NNOSPLH1 0xf286
-#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
-
-/*P2_NNOSPLH0*/
-#define R0900_P2_NNOSPLH0 0xf287
-#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
-
-/*P2_NOSDATAT1*/
-#define R0900_P2_NOSDATAT1 0xf288
-#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
-
-/*P2_NOSDATAT0*/
-#define R0900_P2_NOSDATAT0 0xf289
-#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
-
-/*P2_NOSDATA1*/
-#define R0900_P2_NOSDATA1 0xf28a
-#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
-
-/*P2_NOSDATA0*/
-#define R0900_P2_NOSDATA0 0xf28b
-#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
-
-/*P2_NOSPLHT1*/
-#define R0900_P2_NOSPLHT1 0xf28c
-#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
-
-/*P2_NOSPLHT0*/
-#define R0900_P2_NOSPLHT0 0xf28d
-#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
-
-/*P2_NOSPLH1*/
-#define R0900_P2_NOSPLH1 0xf28e
-#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
-
-/*P2_NOSPLH0*/
-#define R0900_P2_NOSPLH0 0xf28f
-#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
-
-/*P2_CAR2CFG*/
-#define R0900_P2_CAR2CFG 0xf290
-#define F0900_P2_CARRIER3_DISABLE 0xf2900040
-#define F0900_P2_ROTA2ON 0xf2900004
-#define F0900_P2_PH_DET_ALGO2 0xf2900003
-
-/*P2_CFR2CFR1*/
-#define R0900_P2_CFR2CFR1 0xf291
-#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
-#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
-#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
-#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
-
-/*P2_CFR22*/
-#define R0900_P2_CFR22 0xf293
-#define F0900_P2_CAR2_FREQ2 0xf29301ff
-
-/*P2_CFR21*/
-#define R0900_P2_CFR21 0xf294
-#define F0900_P2_CAR2_FREQ1 0xf29400ff
-
-/*P2_CFR20*/
-#define R0900_P2_CFR20 0xf295
-#define F0900_P2_CAR2_FREQ0 0xf29500ff
-
-/*P2_ACLC2S2Q*/
-#define R0900_P2_ACLC2S2Q 0xf297
-#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
-#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
-#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
-
-/*P2_ACLC2S28*/
-#define R0900_P2_ACLC2S28 0xf298
-#define F0900_P2_OLDI3Q_MODE 0xf2980080
-#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
-#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
-
-/*P2_ACLC2S216A*/
-#define R0900_P2_ACLC2S216A 0xf299
-#define F0900_P2_DIS_C3STOPA2 0xf2990080
-#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
-#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
-#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
-
-/*P2_ACLC2S232A*/
-#define R0900_P2_ACLC2S232A 0xf29a
-#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
-#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
-#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
-
-/*P2_BCLC2S2Q*/
-#define R0900_P2_BCLC2S2Q 0xf29c
-#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
-#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
-
-/*P2_BCLC2S28*/
-#define R0900_P2_BCLC2S28 0xf29d
-#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
-#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
-
-/*P2_BCLC2S216A*/
-#define R0900_P2_BCLC2S216A 0xf29e
-
-/*P2_BCLC2S232A*/
-#define R0900_P2_BCLC2S232A 0xf29f
-
-/*P2_PLROOT2*/
-#define R0900_P2_PLROOT2 0xf2ac
-#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
-#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
-
-/*P2_PLROOT1*/
-#define R0900_P2_PLROOT1 0xf2ad
-#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
-
-/*P2_PLROOT0*/
-#define R0900_P2_PLROOT0 0xf2ae
-#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
-
-/*P2_MODCODLST0*/
-#define R0900_P2_MODCODLST0 0xf2b0
-
-/*P2_MODCODLST1*/
-#define R0900_P2_MODCODLST1 0xf2b1
-#define F0900_P2_DIS_MODCOD29 0xf2b100f0
-#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
-
-/*P2_MODCODLST2*/
-#define R0900_P2_MODCODLST2 0xf2b2
-#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
-#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
-
-/*P2_MODCODLST3*/
-#define R0900_P2_MODCODLST3 0xf2b3
-#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
-#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
-
-/*P2_MODCODLST4*/
-#define R0900_P2_MODCODLST4 0xf2b4
-#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
-#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
-
-/*P2_MODCODLST5*/
-#define R0900_P2_MODCODLST5 0xf2b5
-#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
-#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
-
-/*P2_MODCODLST6*/
-#define R0900_P2_MODCODLST6 0xf2b6
-#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
-#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
-
-/*P2_MODCODLST7*/
-#define R0900_P2_MODCODLST7 0xf2b7
-#define F0900_P2_DIS_8P_9_10 0xf2b700f0
-#define F0900_P2_DIS_8P_8_9 0xf2b7000f
-
-/*P2_MODCODLST8*/
-#define R0900_P2_MODCODLST8 0xf2b8
-#define F0900_P2_DIS_8P_5_6 0xf2b800f0
-#define F0900_P2_DIS_8P_3_4 0xf2b8000f
-
-/*P2_MODCODLST9*/
-#define R0900_P2_MODCODLST9 0xf2b9
-#define F0900_P2_DIS_8P_2_3 0xf2b900f0
-#define F0900_P2_DIS_8P_3_5 0xf2b9000f
-
-/*P2_MODCODLSTA*/
-#define R0900_P2_MODCODLSTA 0xf2ba
-#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
-#define F0900_P2_DIS_QP_8_9 0xf2ba000f
-
-/*P2_MODCODLSTB*/
-#define R0900_P2_MODCODLSTB 0xf2bb
-#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
-#define F0900_P2_DIS_QP_4_5 0xf2bb000f
-
-/*P2_MODCODLSTC*/
-#define R0900_P2_MODCODLSTC 0xf2bc
-#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
-#define F0900_P2_DIS_QP_2_3 0xf2bc000f
-
-/*P2_MODCODLSTD*/
-#define R0900_P2_MODCODLSTD 0xf2bd
-#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
-#define F0900_P2_DIS_QP_1_2 0xf2bd000f
-
-/*P2_MODCODLSTE*/
-#define R0900_P2_MODCODLSTE 0xf2be
-#define F0900_P2_DIS_QP_2_5 0xf2be00f0
-#define F0900_P2_DIS_QP_1_3 0xf2be000f
-
-/*P2_MODCODLSTF*/
-#define R0900_P2_MODCODLSTF 0xf2bf
-#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
-
-/*P2_GAUSSR0*/
-#define R0900_P2_GAUSSR0 0xf2c0
-#define F0900_P2_EN_CCIMODE 0xf2c00080
-#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
-
-/*P2_CCIR0*/
-#define R0900_P2_CCIR0 0xf2c1
-#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
-#define F0900_P2_R0_CCI 0xf2c1007f
-
-/*P2_CCIQUANT*/
-#define R0900_P2_CCIQUANT 0xf2c2
-#define F0900_P2_CCI_BETA 0xf2c200e0
-#define F0900_P2_CCI_QUANT 0xf2c2001f
-
-/*P2_CCITHRES*/
-#define R0900_P2_CCITHRES 0xf2c3
-#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
-
-/*P2_CCIACC*/
-#define R0900_P2_CCIACC 0xf2c4
-#define F0900_P2_CCI_VALUE 0xf2c400ff
-
-/*P2_DMDRESCFG*/
-#define R0900_P2_DMDRESCFG 0xf2c6
-#define F0900_P2_DMDRES_RESET 0xf2c60080
-#define F0900_P2_DMDRES_STRALL 0xf2c60008
-#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
-#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
-
-/*P2_DMDRESADR*/
-#define R0900_P2_DMDRESADR 0xf2c7
-#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
-#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
-#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
-
-/*P2_DMDRESDATA7*/
-#define R0900_P2_DMDRESDATA7 0xf2c8
-#define F0900_P2_DMDRES_DATA7 0xf2c800ff
-
-/*P2_DMDRESDATA6*/
-#define R0900_P2_DMDRESDATA6 0xf2c9
-#define F0900_P2_DMDRES_DATA6 0xf2c900ff
-
-/*P2_DMDRESDATA5*/
-#define R0900_P2_DMDRESDATA5 0xf2ca
-#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
-
-/*P2_DMDRESDATA4*/
-#define R0900_P2_DMDRESDATA4 0xf2cb
-#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
-
-/*P2_DMDRESDATA3*/
-#define R0900_P2_DMDRESDATA3 0xf2cc
-#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
-
-/*P2_DMDRESDATA2*/
-#define R0900_P2_DMDRESDATA2 0xf2cd
-#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
-
-/*P2_DMDRESDATA1*/
-#define R0900_P2_DMDRESDATA1 0xf2ce
-#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
-
-/*P2_DMDRESDATA0*/
-#define R0900_P2_DMDRESDATA0 0xf2cf
-#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
-
-/*P2_FFEI1*/
-#define R0900_P2_FFEI1 0xf2d0
-#define F0900_P2_FFE_ACCI1 0xf2d001ff
-
-/*P2_FFEQ1*/
-#define R0900_P2_FFEQ1 0xf2d1
-#define F0900_P2_FFE_ACCQ1 0xf2d101ff
-
-/*P2_FFEI2*/
-#define R0900_P2_FFEI2 0xf2d2
-#define F0900_P2_FFE_ACCI2 0xf2d201ff
-
-/*P2_FFEQ2*/
-#define R0900_P2_FFEQ2 0xf2d3
-#define F0900_P2_FFE_ACCQ2 0xf2d301ff
-
-/*P2_FFEI3*/
-#define R0900_P2_FFEI3 0xf2d4
-#define F0900_P2_FFE_ACCI3 0xf2d401ff
-
-/*P2_FFEQ3*/
-#define R0900_P2_FFEQ3 0xf2d5
-#define F0900_P2_FFE_ACCQ3 0xf2d501ff
-
-/*P2_FFEI4*/
-#define R0900_P2_FFEI4 0xf2d6
-#define F0900_P2_FFE_ACCI4 0xf2d601ff
-
-/*P2_FFEQ4*/
-#define R0900_P2_FFEQ4 0xf2d7
-#define F0900_P2_FFE_ACCQ4 0xf2d701ff
-
-/*P2_FFECFG*/
-#define R0900_P2_FFECFG 0xf2d8
-#define F0900_P2_EQUALFFE_ON 0xf2d80040
-#define F0900_P2_MU_EQUALFFE 0xf2d80007
-
-/*P2_TNRCFG*/
-#define R0900_P2_TNRCFG 0xf2e0
-#define F0900_P2_TUN_ACKFAIL 0xf2e00080
-#define F0900_P2_TUN_TYPE 0xf2e00070
-#define F0900_P2_TUN_SECSTOP 0xf2e00008
-#define F0900_P2_TUN_VCOSRCH 0xf2e00004
-#define F0900_P2_TUN_MADDRESS 0xf2e00003
-
-/*P2_TNRCFG2*/
-#define R0900_P2_TNRCFG2 0xf2e1
-#define F0900_P2_TUN_IQSWAP 0xf2e10080
-#define F0900_P2_DIS_BWCALC 0xf2e10004
-#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
-
-/*P2_TNRXTAL*/
-#define R0900_P2_TNRXTAL 0xf2e4
-#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
-
-/*P2_TNRSTEPS*/
-#define R0900_P2_TNRSTEPS 0xf2e7
-#define F0900_P2_TUNER_BW0P125 0xf2e70080
-#define F0900_P2_BWINC_OFFSET 0xf2e70170
-#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
-#define F0900_P2_TUN_BWOFFSET 0xf2e70007
-
-/*P2_TNRGAIN*/
-#define R0900_P2_TNRGAIN 0xf2e8
-#define F0900_P2_TUN_KDIVEN 0xf2e800c0
-#define F0900_P2_STB6X00_OCK 0xf2e80030
-#define F0900_P2_TUN_GAIN 0xf2e8000f
-
-/*P2_TNRRF1*/
-#define R0900_P2_TNRRF1 0xf2e9
-#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
-
-/*P2_TNRRF0*/
-#define R0900_P2_TNRRF0 0xf2ea
-#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
-
-/*P2_TNRBW*/
-#define R0900_P2_TNRBW 0xf2eb
-#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
-#define F0900_P2_TUN_BW 0xf2eb003f
-
-/*P2_TNRADJ*/
-#define R0900_P2_TNRADJ 0xf2ec
-#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
-
-/*P2_TNRCTL2*/
-#define R0900_P2_TNRCTL2 0xf2ed
-#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
-#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
-#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
-#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
-#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
-#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
-#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
-#define F0900_P2_STB6XX0_SYN 0xf2ed0001
-
-/*P2_TNRCFG3*/
-#define R0900_P2_TNRCFG3 0xf2ee
-#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
-#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
-
-/*P2_TNRLAUNCH*/
-#define R0900_P2_TNRLAUNCH 0xf2f0
-
-/*P2_TNRLD*/
-#define R0900_P2_TNRLD 0xf2f0
-#define F0900_P2_TUNLD_VCOING 0xf2f00080
-#define F0900_P2_TUN_REG1FAIL 0xf2f00040
-#define F0900_P2_TUN_REG2FAIL 0xf2f00020
-#define F0900_P2_TUN_REG3FAIL 0xf2f00010
-#define F0900_P2_TUN_REG4FAIL 0xf2f00008
-#define F0900_P2_TUN_REG5FAIL 0xf2f00004
-#define F0900_P2_TUN_BWING 0xf2f00002
-#define F0900_P2_TUN_LOCKED 0xf2f00001
-
-/*P2_TNROBSL*/
-#define R0900_P2_TNROBSL 0xf2f6
-#define F0900_P2_TUN_I2CABORTED 0xf2f60080
-#define F0900_P2_TUN_LPEN 0xf2f60040
-#define F0900_P2_TUN_FCCK 0xf2f60020
-#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
-#define F0900_P2_TUN_PROGDONE 0xf2f6000c
-#define F0900_P2_TUN_RFRESTE1 0xf2f60003
-
-/*P2_TNRRESTE*/
-#define R0900_P2_TNRRESTE 0xf2f7
-#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
-
-/*P2_SMAPCOEF7*/
-#define R0900_P2_SMAPCOEF7 0xf300
-#define F0900_P2_DIS_QSCALE 0xf3000080
-#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
-
-/*P2_SMAPCOEF6*/
-#define R0900_P2_SMAPCOEF6 0xf301
-#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
-#define F0900_P2_OLD_8PSKLLR1 0xf3010002
-#define F0900_P2_DIS_AB8PSK 0xf3010001
-
-/*P2_SMAPCOEF5*/
-#define R0900_P2_SMAPCOEF5 0xf302
-#define F0900_P2_DIS_8SCALE 0xf3020080
-#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
-
-/*P2_NCO2MAX1*/
-#define R0900_P2_NCO2MAX1 0xf314
-#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
-
-/*P2_NCO2MAX0*/
-#define R0900_P2_NCO2MAX0 0xf315
-#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
-
-/*P2_NCO2FR1*/
-#define R0900_P2_NCO2FR1 0xf316
-#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
-
-/*P2_NCO2FR0*/
-#define R0900_P2_NCO2FR0 0xf317
-#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
-
-/*P2_CFR2AVRGE1*/
-#define R0900_P2_CFR2AVRGE1 0xf318
-#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
-
-/*P2_CFR2AVRGE0*/
-#define R0900_P2_CFR2AVRGE0 0xf319
-#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
-
-/*P2_DMDPLHSTAT*/
-#define R0900_P2_DMDPLHSTAT 0xf320
-#define F0900_P2_PLH_STATISTIC 0xf32000ff
-
-/*P2_LOCKTIME3*/
-#define R0900_P2_LOCKTIME3 0xf322
-#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
-
-/*P2_LOCKTIME2*/
-#define R0900_P2_LOCKTIME2 0xf323
-#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
-
-/*P2_LOCKTIME1*/
-#define R0900_P2_LOCKTIME1 0xf324
-#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
-
-/*P2_LOCKTIME0*/
-#define R0900_P2_LOCKTIME0 0xf325
-#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
-
-/*P2_VITSCALE*/
-#define R0900_P2_VITSCALE 0xf332
-#define F0900_P2_NVTH_NOSRANGE 0xf3320080
-#define F0900_P2_VERROR_MAXMODE 0xf3320040
-#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
-#define F0900_P2_DIS_RSFLOCK 0xf3320002
-
-/*P2_FECM*/
-#define R0900_P2_FECM 0xf333
-#define F0900_P2_DSS_DVB 0xf3330080
-#define F0900_P2_DSS_SRCH 0xf3330010
-#define F0900_P2_SYNCVIT 0xf3330002
-#define F0900_P2_IQINV 0xf3330001
-
-/*P2_VTH12*/
-#define R0900_P2_VTH12 0xf334
-#define F0900_P2_VTH12 0xf33400ff
-
-/*P2_VTH23*/
-#define R0900_P2_VTH23 0xf335
-#define F0900_P2_VTH23 0xf33500ff
-
-/*P2_VTH34*/
-#define R0900_P2_VTH34 0xf336
-#define F0900_P2_VTH34 0xf33600ff
-
-/*P2_VTH56*/
-#define R0900_P2_VTH56 0xf337
-#define F0900_P2_VTH56 0xf33700ff
-
-/*P2_VTH67*/
-#define R0900_P2_VTH67 0xf338
-#define F0900_P2_VTH67 0xf33800ff
-
-/*P2_VTH78*/
-#define R0900_P2_VTH78 0xf339
-#define F0900_P2_VTH78 0xf33900ff
-
-/*P2_VITCURPUN*/
-#define R0900_P2_VITCURPUN 0xf33a
-#define F0900_P2_VIT_CURPUN 0xf33a001f
-
-/*P2_VERROR*/
-#define R0900_P2_VERROR 0xf33b
-#define F0900_P2_REGERR_VIT 0xf33b00ff
-
-/*P2_PRVIT*/
-#define R0900_P2_PRVIT 0xf33c
-#define F0900_P2_DIS_VTHLOCK 0xf33c0040
-#define F0900_P2_E7_8VIT 0xf33c0020
-#define F0900_P2_E6_7VIT 0xf33c0010
-#define F0900_P2_E5_6VIT 0xf33c0008
-#define F0900_P2_E3_4VIT 0xf33c0004
-#define F0900_P2_E2_3VIT 0xf33c0002
-#define F0900_P2_E1_2VIT 0xf33c0001
-
-/*P2_VAVSRVIT*/
-#define R0900_P2_VAVSRVIT 0xf33d
-#define F0900_P2_AMVIT 0xf33d0080
-#define F0900_P2_FROZENVIT 0xf33d0040
-#define F0900_P2_SNVIT 0xf33d0030
-#define F0900_P2_TOVVIT 0xf33d000c
-#define F0900_P2_HYPVIT 0xf33d0003
-
-/*P2_VSTATUSVIT*/
-#define R0900_P2_VSTATUSVIT 0xf33e
-#define F0900_P2_PRFVIT 0xf33e0010
-#define F0900_P2_LOCKEDVIT 0xf33e0008
-
-/*P2_VTHINUSE*/
-#define R0900_P2_VTHINUSE 0xf33f
-#define F0900_P2_VIT_INUSE 0xf33f00ff
-
-/*P2_KDIV12*/
-#define R0900_P2_KDIV12 0xf340
-#define F0900_P2_K_DIVIDER_12 0xf340007f
-
-/*P2_KDIV23*/
-#define R0900_P2_KDIV23 0xf341
-#define F0900_P2_K_DIVIDER_23 0xf341007f
-
-/*P2_KDIV34*/
-#define R0900_P2_KDIV34 0xf342
-#define F0900_P2_K_DIVIDER_34 0xf342007f
-
-/*P2_KDIV56*/
-#define R0900_P2_KDIV56 0xf343
-#define F0900_P2_K_DIVIDER_56 0xf343007f
-
-/*P2_KDIV67*/
-#define R0900_P2_KDIV67 0xf344
-#define F0900_P2_K_DIVIDER_67 0xf344007f
-
-/*P2_KDIV78*/
-#define R0900_P2_KDIV78 0xf345
-#define F0900_P2_K_DIVIDER_78 0xf345007f
-
-/*P2_PDELCTRL1*/
-#define R0900_P2_PDELCTRL1 0xf350
-#define F0900_P2_INV_MISMASK 0xf3500080
-#define F0900_P2_FILTER_EN 0xf3500020
-#define F0900_P2_EN_MIS00 0xf3500002
-#define F0900_P2_ALGOSWRST 0xf3500001
-
-/*P2_PDELCTRL2*/
-#define R0900_P2_PDELCTRL2 0xf351
-#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
-#define F0900_P2_FRAME_MODE 0xf3510002
-#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
-
-/*P2_HYSTTHRESH*/
-#define R0900_P2_HYSTTHRESH 0xf354
-#define F0900_P2_UNLCK_THRESH 0xf35400f0
-#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
-
-/*P2_ISIENTRY*/
-#define R0900_P2_ISIENTRY 0xf35e
-#define F0900_P2_ISI_ENTRY 0xf35e00ff
-
-/*P2_ISIBITENA*/
-#define R0900_P2_ISIBITENA 0xf35f
-#define F0900_P2_ISI_BIT_EN 0xf35f00ff
-
-/*P2_MATSTR1*/
-#define R0900_P2_MATSTR1 0xf360
-#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
-
-/*P2_MATSTR0*/
-#define R0900_P2_MATSTR0 0xf361
-#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
-
-/*P2_UPLSTR1*/
-#define R0900_P2_UPLSTR1 0xf362
-#define F0900_P2_UPL_CURRENT1 0xf36200ff
-
-/*P2_UPLSTR0*/
-#define R0900_P2_UPLSTR0 0xf363
-#define F0900_P2_UPL_CURRENT0 0xf36300ff
-
-/*P2_DFLSTR1*/
-#define R0900_P2_DFLSTR1 0xf364
-#define F0900_P2_DFL_CURRENT1 0xf36400ff
-
-/*P2_DFLSTR0*/
-#define R0900_P2_DFLSTR0 0xf365
-#define F0900_P2_DFL_CURRENT0 0xf36500ff
-
-/*P2_SYNCSTR*/
-#define R0900_P2_SYNCSTR 0xf366
-#define F0900_P2_SYNC_CURRENT 0xf36600ff
-
-/*P2_SYNCDSTR1*/
-#define R0900_P2_SYNCDSTR1 0xf367
-#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
-
-/*P2_SYNCDSTR0*/
-#define R0900_P2_SYNCDSTR0 0xf368
-#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
-
-/*P2_PDELSTATUS1*/
-#define R0900_P2_PDELSTATUS1 0xf369
-#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
-#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
-#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
-#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
-#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
-#define F0900_P2_PKTDELIN_LOCK 0xf3690002
-#define F0900_P2_FIRST_LOCK 0xf3690001
-
-/*P2_PDELSTATUS2*/
-#define R0900_P2_PDELSTATUS2 0xf36a
-#define F0900_P2_FRAME_MODCOD 0xf36a007c
-#define F0900_P2_FRAME_TYPE 0xf36a0003
-
-/*P2_BBFCRCKO1*/
-#define R0900_P2_BBFCRCKO1 0xf36b
-#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
-
-/*P2_BBFCRCKO0*/
-#define R0900_P2_BBFCRCKO0 0xf36c
-#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
-
-/*P2_UPCRCKO1*/
-#define R0900_P2_UPCRCKO1 0xf36d
-#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
-
-/*P2_UPCRCKO0*/
-#define R0900_P2_UPCRCKO0 0xf36e
-#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
-
-/*P2_PDELCTRL3*/
-#define R0900_P2_PDELCTRL3 0xf36f
-#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
-#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
-
-/*P2_TSSTATEM*/
-#define R0900_P2_TSSTATEM 0xf370
-#define F0900_P2_TSDIL_ON 0xf3700080
-#define F0900_P2_TSRS_ON 0xf3700020
-#define F0900_P2_TSDESCRAMB_ON 0xf3700010
-#define F0900_P2_TSFRAME_MODE 0xf3700008
-#define F0900_P2_TS_DISABLE 0xf3700004
-#define F0900_P2_TSOUT_NOSYNC 0xf3700001
-
-/*P2_TSCFGH*/
-#define R0900_P2_TSCFGH 0xf372
-#define F0900_P2_TSFIFO_DVBCI 0xf3720080
-#define F0900_P2_TSFIFO_SERIAL 0xf3720040
-#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
-#define F0900_P2_TSFIFO_DUTY50 0xf3720010
-#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
-#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
-#define F0900_P2_RST_HWARE 0xf3720001
-
-/*P2_TSCFGM*/
-#define R0900_P2_TSCFGM 0xf373
-#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
-#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
-#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
-#define F0900_P2_TSFIFO_INVDATA 0xf3730001
-
-/*P2_TSCFGL*/
-#define R0900_P2_TSCFGL 0xf374
-#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
-#define F0900_P2_BCHERROR_MODE 0xf3740030
-#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
-#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
-#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
-
-/*P2_TSINSDELH*/
-#define R0900_P2_TSINSDELH 0xf376
-#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
-#define F0900_P2_TSDEL_XXHEADER 0xf3760040
-#define F0900_P2_TSDEL_BBHEADER 0xf3760020
-#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
-#define F0900_P2_TSINSDEL_ISCR 0xf3760008
-#define F0900_P2_TSINSDEL_NPD 0xf3760004
-#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
-#define F0900_P2_TSINSDEL_CRC8 0xf3760001
-
-/*P2_TSDIVN*/
-#define R0900_P2_TSDIVN 0xf379
-#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
-
-/*P2_TSCFG4*/
-#define R0900_P2_TSCFG4 0xf37a
-#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
-
-/*P2_TSSPEED*/
-#define R0900_P2_TSSPEED 0xf380
-#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
-
-/*P2_TSSTATUS*/
-#define R0900_P2_TSSTATUS 0xf381
-#define F0900_P2_TSFIFO_LINEOK 0xf3810080
-#define F0900_P2_TSFIFO_ERROR 0xf3810040
-#define F0900_P2_DIL_READY 0xf3810001
-
-/*P2_TSSTATUS2*/
-#define R0900_P2_TSSTATUS2 0xf382
-#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
-#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
-#define F0900_P2_DILXX_RESET 0xf3820020
-#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
-#define F0900_P2_SCRAMBDETECT 0xf3820002
-
-/*P2_TSBITRATE1*/
-#define R0900_P2_TSBITRATE1 0xf383
-#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
-
-/*P2_TSBITRATE0*/
-#define R0900_P2_TSBITRATE0 0xf384
-#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
-
-/*P2_ERRCTRL1*/
-#define R0900_P2_ERRCTRL1 0xf398
-#define F0900_P2_ERR_SOURCE1 0xf39800f0
-#define F0900_P2_NUM_EVENT1 0xf3980007
-
-/*P2_ERRCNT12*/
-#define R0900_P2_ERRCNT12 0xf399
-#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
-#define F0900_P2_ERR_CNT12 0xf399007f
-
-/*P2_ERRCNT11*/
-#define R0900_P2_ERRCNT11 0xf39a
-#define F0900_P2_ERR_CNT11 0xf39a00ff
-
-/*P2_ERRCNT10*/
-#define R0900_P2_ERRCNT10 0xf39b
-#define F0900_P2_ERR_CNT10 0xf39b00ff
-
-/*P2_ERRCTRL2*/
-#define R0900_P2_ERRCTRL2 0xf39c
-#define F0900_P2_ERR_SOURCE2 0xf39c00f0
-#define F0900_P2_NUM_EVENT2 0xf39c0007
-
-/*P2_ERRCNT22*/
-#define R0900_P2_ERRCNT22 0xf39d
-#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
-#define F0900_P2_ERR_CNT22 0xf39d007f
-
-/*P2_ERRCNT21*/
-#define R0900_P2_ERRCNT21 0xf39e
-#define F0900_P2_ERR_CNT21 0xf39e00ff
-
-/*P2_ERRCNT20*/
-#define R0900_P2_ERRCNT20 0xf39f
-#define F0900_P2_ERR_CNT20 0xf39f00ff
-
-/*P2_FECSPY*/
-#define R0900_P2_FECSPY 0xf3a0
-#define F0900_P2_SPY_ENABLE 0xf3a00080
-#define F0900_P2_NO_SYNCBYTE 0xf3a00040
-#define F0900_P2_SERIAL_MODE 0xf3a00020
-#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
-#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
-#define F0900_P2_BERMETER_LMODE 0xf3a00002
-#define F0900_P2_BERMETER_RESET 0xf3a00001
-
-/*P2_FSPYCFG*/
-#define R0900_P2_FSPYCFG 0xf3a1
-#define F0900_P2_FECSPY_INPUT 0xf3a100c0
-#define F0900_P2_RST_ON_ERROR 0xf3a10020
-#define F0900_P2_ONE_SHOT 0xf3a10010
-#define F0900_P2_I2C_MODE 0xf3a1000c
-#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
-
-/*P2_FSPYDATA*/
-#define R0900_P2_FSPYDATA 0xf3a2
-#define F0900_P2_SPY_STUFFING 0xf3a20080
-#define F0900_P2_SPY_CNULLPKT 0xf3a20020
-#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
-
-/*P2_FSPYOUT*/
-#define R0900_P2_FSPYOUT 0xf3a3
-#define F0900_P2_FSPY_DIRECT 0xf3a30080
-#define F0900_P2_STUFF_MODE 0xf3a30007
-
-/*P2_FSTATUS*/
-#define R0900_P2_FSTATUS 0xf3a4
-#define F0900_P2_SPY_ENDSIM 0xf3a40080
-#define F0900_P2_VALID_SIM 0xf3a40040
-#define F0900_P2_FOUND_SIGNAL 0xf3a40020
-#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
-#define F0900_P2_RESULT_STATE 0xf3a4000f
-
-/*P2_FBERCPT4*/
-#define R0900_P2_FBERCPT4 0xf3a8
-#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
-
-/*P2_FBERCPT3*/
-#define R0900_P2_FBERCPT3 0xf3a9
-#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
-
-/*P2_FBERCPT2*/
-#define R0900_P2_FBERCPT2 0xf3aa
-#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
-
-/*P2_FBERCPT1*/
-#define R0900_P2_FBERCPT1 0xf3ab
-#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
-
-/*P2_FBERCPT0*/
-#define R0900_P2_FBERCPT0 0xf3ac
-#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
-
-/*P2_FBERERR2*/
-#define R0900_P2_FBERERR2 0xf3ad
-#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
-
-/*P2_FBERERR1*/
-#define R0900_P2_FBERERR1 0xf3ae
-#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
-
-/*P2_FBERERR0*/
-#define R0900_P2_FBERERR0 0xf3af
-#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
-
-/*P2_FSPYBER*/
-#define R0900_P2_FSPYBER 0xf3b2
-#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
-#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
-#define F0900_P2_FSPYBER_CTIME 0xf3b20007
-
-/*P1_IQCONST*/
-#define R0900_P1_IQCONST 0xf400
-#define IQCONST REGx(R0900_P1_IQCONST)
-#define F0900_P1_CONSTEL_SELECT 0xf4000060
-#define F0900_P1_IQSYMB_SEL 0xf400001f
-
-/*P1_NOSCFG*/
-#define R0900_P1_NOSCFG 0xf401
-#define NOSCFG REGx(R0900_P1_NOSCFG)
-#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
-#define F0900_P1_NOSPLH_BETA 0xf4010018
-#define F0900_P1_NOSDATA_BETA 0xf4010007
-
-/*P1_ISYMB*/
-#define R0900_P1_ISYMB 0xf402
-#define ISYMB REGx(R0900_P1_ISYMB)
-#define F0900_P1_I_SYMBOL 0xf40201ff
-
-/*P1_QSYMB*/
-#define R0900_P1_QSYMB 0xf403
-#define QSYMB REGx(R0900_P1_QSYMB)
-#define F0900_P1_Q_SYMBOL 0xf40301ff
-
-/*P1_AGC1CFG*/
-#define R0900_P1_AGC1CFG 0xf404
-#define AGC1CFG REGx(R0900_P1_AGC1CFG)
-#define F0900_P1_DC_FROZEN 0xf4040080
-#define F0900_P1_DC_CORRECT 0xf4040040
-#define F0900_P1_AMM_FROZEN 0xf4040020
-#define F0900_P1_AMM_CORRECT 0xf4040010
-#define F0900_P1_QUAD_FROZEN 0xf4040008
-#define F0900_P1_QUAD_CORRECT 0xf4040004
-
-/*P1_AGC1CN*/
-#define R0900_P1_AGC1CN 0xf406
-#define AGC1CN REGx(R0900_P1_AGC1CN)
-#define F0900_P1_AGC1_LOCKED 0xf4060080
-#define F0900_P1_AGC1_MINPOWER 0xf4060010
-#define F0900_P1_AGCOUT_FAST 0xf4060008
-#define F0900_P1_AGCIQ_BETA 0xf4060007
-
-/*P1_AGC1REF*/
-#define R0900_P1_AGC1REF 0xf407
-#define AGC1REF REGx(R0900_P1_AGC1REF)
-#define F0900_P1_AGCIQ_REF 0xf40700ff
-
-/*P1_IDCCOMP*/
-#define R0900_P1_IDCCOMP 0xf408
-#define IDCCOMP REGx(R0900_P1_IDCCOMP)
-#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
-
-/*P1_QDCCOMP*/
-#define R0900_P1_QDCCOMP 0xf409
-#define QDCCOMP REGx(R0900_P1_QDCCOMP)
-#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
-
-/*P1_POWERI*/
-#define R0900_P1_POWERI 0xf40a
-#define POWERI REGx(R0900_P1_POWERI)
-#define F0900_P1_POWER_I 0xf40a00ff
-#define POWER_I FLDx(F0900_P1_POWER_I)
-
-/*P1_POWERQ*/
-#define R0900_P1_POWERQ 0xf40b
-#define POWERQ REGx(R0900_P1_POWERQ)
-#define F0900_P1_POWER_Q 0xf40b00ff
-#define POWER_Q FLDx(F0900_P1_POWER_Q)
-
-/*P1_AGC1AMM*/
-#define R0900_P1_AGC1AMM 0xf40c
-#define AGC1AMM REGx(R0900_P1_AGC1AMM)
-#define F0900_P1_AMM_VALUE 0xf40c00ff
-
-/*P1_AGC1QUAD*/
-#define R0900_P1_AGC1QUAD 0xf40d
-#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
-#define F0900_P1_QUAD_VALUE 0xf40d01ff
-
-/*P1_AGCIQIN1*/
-#define R0900_P1_AGCIQIN1 0xf40e
-#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
-#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
-#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
-
-/*P1_AGCIQIN0*/
-#define R0900_P1_AGCIQIN0 0xf40f
-#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
-#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
-#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
-
-/*P1_DEMOD*/
-#define R0900_P1_DEMOD 0xf410
-#define DEMOD REGx(R0900_P1_DEMOD)
-#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
-#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
-
-#define F0900_P1_SPECINV_CONTROL 0xf4100030
-#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
-#define F0900_P1_FORCE_ENASAMP 0xf4100008
-#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
-#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
-#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
-#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
-
-/*P1_DMDMODCOD*/
-#define R0900_P1_DMDMODCOD 0xf411
-#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
-#define F0900_P1_MANUAL_MODCOD 0xf4110080
-#define F0900_P1_DEMOD_MODCOD 0xf411007c
-#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
-#define F0900_P1_DEMOD_TYPE 0xf4110003
-#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
-
-/*P1_DSTATUS*/
-#define R0900_P1_DSTATUS 0xf412
-#define DSTATUS REGx(R0900_P1_DSTATUS)
-#define F0900_P1_CAR_LOCK 0xf4120080
-#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
-#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
-#define F0900_P1_LOCK_DEFINITIF 0xf4120008
-#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
-#define F0900_P1_OVADC_DETECT 0xf4120001
-
-/*P1_DSTATUS2*/
-#define R0900_P1_DSTATUS2 0xf413
-#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
-#define F0900_P1_DEMOD_DELOCK 0xf4130080
-#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
-#define F0900_P1_AGC2_OVERFLOW 0xf4130004
-#define F0900_P1_CFR_OVERFLOW 0xf4130002
-#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
-
-/*P1_DMDCFGMD*/
-#define R0900_P1_DMDCFGMD 0xf414
-#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
-#define F0900_P1_DVBS2_ENABLE 0xf4140080
-#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
-#define F0900_P1_DVBS1_ENABLE 0xf4140040
-#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
-#define F0900_P1_SCAN_ENABLE 0xf4140010
-#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
-#define F0900_P1_CFR_AUTOSCAN 0xf4140008
-#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
-#define F0900_P1_TUN_RNG 0xf4140003
-
-/*P1_DMDCFG2*/
-#define R0900_P1_DMDCFG2 0xf415
-#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
-#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
-#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
-#define F0900_P1_INFINITE_RELOCK 0xf4150010
-
-/*P1_DMDISTATE*/
-#define R0900_P1_DMDISTATE 0xf416
-#define DMDISTATE REGx(R0900_P1_DMDISTATE)
-#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
-#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
-
-/*P1_DMDT0M*/
-#define R0900_P1_DMDT0M 0xf417
-#define DMDT0M REGx(R0900_P1_DMDT0M)
-#define F0900_P1_DMDT0_MIN 0xf41700ff
-
-/*P1_DMDSTATE*/
-#define R0900_P1_DMDSTATE 0xf41b
-#define DMDSTATE REGx(R0900_P1_DMDSTATE)
-#define F0900_P1_HEADER_MODE 0xf41b0060
-#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
-
-/*P1_DMDFLYW*/
-#define R0900_P1_DMDFLYW 0xf41c
-#define DMDFLYW REGx(R0900_P1_DMDFLYW)
-#define F0900_P1_I2C_IRQVAL 0xf41c00f0
-#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
-#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
-
-/*P1_DSTATUS3*/
-#define R0900_P1_DSTATUS3 0xf41d
-#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
-#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
-
-/*P1_DMDCFG3*/
-#define R0900_P1_DMDCFG3 0xf41e
-#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
-#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
-
-/*P1_DMDCFG4*/
-#define R0900_P1_DMDCFG4 0xf41f
-#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
-#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
-
-/*P1_CORRELMANT*/
-#define R0900_P1_CORRELMANT 0xf420
-#define CORRELMANT REGx(R0900_P1_CORRELMANT)
-#define F0900_P1_CORREL_MANT 0xf42000ff
-
-/*P1_CORRELABS*/
-#define R0900_P1_CORRELABS 0xf421
-#define CORRELABS REGx(R0900_P1_CORRELABS)
-#define F0900_P1_CORREL_ABS 0xf42100ff
-
-/*P1_CORRELEXP*/
-#define R0900_P1_CORRELEXP 0xf422
-#define CORRELEXP REGx(R0900_P1_CORRELEXP)
-#define F0900_P1_CORREL_ABSEXP 0xf42200f0
-#define F0900_P1_CORREL_EXP 0xf422000f
-
-/*P1_PLHMODCOD*/
-#define R0900_P1_PLHMODCOD 0xf424
-#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
-#define F0900_P1_SPECINV_DEMOD 0xf4240080
-#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
-#define F0900_P1_PLH_MODCOD 0xf424007c
-#define F0900_P1_PLH_TYPE 0xf4240003
-
-/*P1_DMDREG*/
-#define R0900_P1_DMDREG 0xf425
-#define DMDREG REGx(R0900_P1_DMDREG)
-#define F0900_P1_DECIM_PLFRAMES 0xf4250001
-
-/*P1_AGC2O*/
-#define R0900_P1_AGC2O 0xf42c
-#define AGC2O REGx(R0900_P1_AGC2O)
-#define F0900_P1_AGC2_COEF 0xf42c0007
-
-/*P1_AGC2REF*/
-#define R0900_P1_AGC2REF 0xf42d
-#define AGC2REF REGx(R0900_P1_AGC2REF)
-#define F0900_P1_AGC2_REF 0xf42d00ff
-
-/*P1_AGC1ADJ*/
-#define R0900_P1_AGC1ADJ 0xf42e
-#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
-#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
-
-/*P1_AGC2I1*/
-#define R0900_P1_AGC2I1 0xf436
-#define AGC2I1 REGx(R0900_P1_AGC2I1)
-#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
-
-/*P1_AGC2I0*/
-#define R0900_P1_AGC2I0 0xf437
-#define AGC2I0 REGx(R0900_P1_AGC2I0)
-#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
-
-/*P1_CARCFG*/
-#define R0900_P1_CARCFG 0xf438
-#define CARCFG REGx(R0900_P1_CARCFG)
-#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
-#define F0900_P1_CFRUPLOW_TEST 0xf4380040
-#define F0900_P1_ROTAON 0xf4380004
-#define F0900_P1_PH_DET_ALGO 0xf4380003
-
-/*P1_ACLC*/
-#define R0900_P1_ACLC 0xf439
-#define ACLC REGx(R0900_P1_ACLC)
-#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
-#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
-
-/*P1_BCLC*/
-#define R0900_P1_BCLC 0xf43a
-#define BCLC REGx(R0900_P1_BCLC)
-#define F0900_P1_CAR_BETA_MANT 0xf43a0030
-#define F0900_P1_CAR_BETA_EXP 0xf43a000f
-
-/*P1_CARFREQ*/
-#define R0900_P1_CARFREQ 0xf43d
-#define CARFREQ REGx(R0900_P1_CARFREQ)
-#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
-#define F0900_P1_BETA_FREQ 0xf43d000f
-
-/*P1_CARHDR*/
-#define R0900_P1_CARHDR 0xf43e
-#define CARHDR REGx(R0900_P1_CARHDR)
-#define F0900_P1_K_FREQ_HDR 0xf43e00ff
-
-/*P1_LDT*/
-#define R0900_P1_LDT 0xf43f
-#define LDT REGx(R0900_P1_LDT)
-#define F0900_P1_CARLOCK_THRES 0xf43f01ff
-
-/*P1_LDT2*/
-#define R0900_P1_LDT2 0xf440
-#define LDT2 REGx(R0900_P1_LDT2)
-#define F0900_P1_CARLOCK_THRES2 0xf44001ff
-
-/*P1_CFRICFG*/
-#define R0900_P1_CFRICFG 0xf441
-#define CFRICFG REGx(R0900_P1_CFRICFG)
-#define F0900_P1_NEG_CFRSTEP 0xf4410001
-
-/*P1_CFRUP1*/
-#define R0900_P1_CFRUP1 0xf442
-#define CFRUP1 REGx(R0900_P1_CFRUP1)
-#define F0900_P1_CFR_UP1 0xf44201ff
-#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
-
-/*P1_CFRUP0*/
-#define R0900_P1_CFRUP0 0xf443
-#define CFRUP0 REGx(R0900_P1_CFRUP0)
-#define F0900_P1_CFR_UP0 0xf44300ff
-#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
-
-/*P1_CFRLOW1*/
-#define R0900_P1_CFRLOW1 0xf446
-#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
-#define F0900_P1_CFR_LOW1 0xf44601ff
-#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
-
-/*P1_CFRLOW0*/
-#define R0900_P1_CFRLOW0 0xf447
-#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
-#define F0900_P1_CFR_LOW0 0xf44700ff
-#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
-
-/*P1_CFRINIT1*/
-#define R0900_P1_CFRINIT1 0xf448
-#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
-#define F0900_P1_CFR_INIT1 0xf44801ff
-#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
-
-/*P1_CFRINIT0*/
-#define R0900_P1_CFRINIT0 0xf449
-#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
-#define F0900_P1_CFR_INIT0 0xf44900ff
-#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
-
-/*P1_CFRINC1*/
-#define R0900_P1_CFRINC1 0xf44a
-#define CFRINC1 REGx(R0900_P1_CFRINC1)
-#define F0900_P1_MANUAL_CFRINC 0xf44a0080
-#define F0900_P1_CFR_INC1 0xf44a003f
-
-/*P1_CFRINC0*/
-#define R0900_P1_CFRINC0 0xf44b
-#define CFRINC0 REGx(R0900_P1_CFRINC0)
-#define F0900_P1_CFR_INC0 0xf44b00f8
-
-/*P1_CFR2*/
-#define R0900_P1_CFR2 0xf44c
-#define CFR2 REGx(R0900_P1_CFR2)
-#define F0900_P1_CAR_FREQ2 0xf44c01ff
-#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
-
-/*P1_CFR1*/
-#define R0900_P1_CFR1 0xf44d
-#define CFR1 REGx(R0900_P1_CFR1)
-#define F0900_P1_CAR_FREQ1 0xf44d00ff
-#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
-
-/*P1_CFR0*/
-#define R0900_P1_CFR0 0xf44e
-#define CFR0 REGx(R0900_P1_CFR0)
-#define F0900_P1_CAR_FREQ0 0xf44e00ff
-#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
-
-/*P1_LDI*/
-#define R0900_P1_LDI 0xf44f
-#define LDI REGx(R0900_P1_LDI)
-#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
-
-/*P1_TMGCFG*/
-#define R0900_P1_TMGCFG 0xf450
-#define TMGCFG REGx(R0900_P1_TMGCFG)
-#define F0900_P1_TMGLOCK_BETA 0xf45000c0
-#define F0900_P1_DO_TIMING_CORR 0xf4500010
-#define F0900_P1_TMG_MINFREQ 0xf4500003
-
-/*P1_RTC*/
-#define R0900_P1_RTC 0xf451
-#define RTC REGx(R0900_P1_RTC)
-#define F0900_P1_TMGALPHA_EXP 0xf45100f0
-#define F0900_P1_TMGBETA_EXP 0xf451000f
-
-/*P1_RTCS2*/
-#define R0900_P1_RTCS2 0xf452
-#define RTCS2 REGx(R0900_P1_RTCS2)
-#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
-#define F0900_P1_TMGBETAS2_EXP 0xf452000f
-
-/*P1_TMGTHRISE*/
-#define R0900_P1_TMGTHRISE 0xf453
-#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
-#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
-
-/*P1_TMGTHFALL*/
-#define R0900_P1_TMGTHFALL 0xf454
-#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
-#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
-
-/*P1_SFRUPRATIO*/
-#define R0900_P1_SFRUPRATIO 0xf455
-#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
-#define F0900_P1_SFR_UPRATIO 0xf45500ff
-
-/*P1_SFRLOWRATIO*/
-#define R0900_P1_SFRLOWRATIO 0xf456
-#define F0900_P1_SFR_LOWRATIO 0xf45600ff
-
-/*P1_KREFTMG*/
-#define R0900_P1_KREFTMG 0xf458
-#define KREFTMG REGx(R0900_P1_KREFTMG)
-#define F0900_P1_KREF_TMG 0xf45800ff
-
-/*P1_SFRSTEP*/
-#define R0900_P1_SFRSTEP 0xf459
-#define SFRSTEP REGx(R0900_P1_SFRSTEP)
-#define F0900_P1_SFR_SCANSTEP 0xf45900f0
-#define F0900_P1_SFR_CENTERSTEP 0xf459000f
-
-/*P1_TMGCFG2*/
-#define R0900_P1_TMGCFG2 0xf45a
-#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
-#define F0900_P1_SFRRATIO_FINE 0xf45a0001
-
-/*P1_KREFTMG2*/
-#define R0900_P1_KREFTMG2 0xf45b
-#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
-#define F0900_P1_KREF_TMG2 0xf45b00ff
-
-/*P1_SFRINIT1*/
-#define R0900_P1_SFRINIT1 0xf45e
-#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
-#define F0900_P1_SFR_INIT1 0xf45e007f
-
-/*P1_SFRINIT0*/
-#define R0900_P1_SFRINIT0 0xf45f
-#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
-#define F0900_P1_SFR_INIT0 0xf45f00ff
-
-/*P1_SFRUP1*/
-#define R0900_P1_SFRUP1 0xf460
-#define SFRUP1 REGx(R0900_P1_SFRUP1)
-#define F0900_P1_AUTO_GUP 0xf4600080
-#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
-#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
-
-/*P1_SFRUP0*/
-#define R0900_P1_SFRUP0 0xf461
-#define SFRUP0 REGx(R0900_P1_SFRUP0)
-#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
-
-/*P1_SFRLOW1*/
-#define R0900_P1_SFRLOW1 0xf462
-#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
-#define F0900_P1_AUTO_GLOW 0xf4620080
-#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
-#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
-
-/*P1_SFRLOW0*/
-#define R0900_P1_SFRLOW0 0xf463
-#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
-#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
-
-/*P1_SFR3*/
-#define R0900_P1_SFR3 0xf464
-#define SFR3 REGx(R0900_P1_SFR3)
-#define F0900_P1_SYMB_FREQ3 0xf46400ff
-#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
-
-/*P1_SFR2*/
-#define R0900_P1_SFR2 0xf465
-#define SFR2 REGx(R0900_P1_SFR2)
-#define F0900_P1_SYMB_FREQ2 0xf46500ff
-#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
-
-/*P1_SFR1*/
-#define R0900_P1_SFR1 0xf466
-#define SFR1 REGx(R0900_P1_SFR1)
-#define F0900_P1_SYMB_FREQ1 0xf46600ff
-#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
-
-/*P1_SFR0*/
-#define R0900_P1_SFR0 0xf467
-#define SFR0 REGx(R0900_P1_SFR0)
-#define F0900_P1_SYMB_FREQ0 0xf46700ff
-#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
-
-/*P1_TMGREG2*/
-#define R0900_P1_TMGREG2 0xf468
-#define TMGREG2 REGx(R0900_P1_TMGREG2)
-#define F0900_P1_TMGREG2 0xf46800ff
-
-/*P1_TMGREG1*/
-#define R0900_P1_TMGREG1 0xf469
-#define TMGREG1 REGx(R0900_P1_TMGREG1)
-#define F0900_P1_TMGREG1 0xf46900ff
-
-/*P1_TMGREG0*/
-#define R0900_P1_TMGREG0 0xf46a
-#define TMGREG0 REGx(R0900_P1_TMGREG0)
-#define F0900_P1_TMGREG0 0xf46a00ff
-
-/*P1_TMGLOCK1*/
-#define R0900_P1_TMGLOCK1 0xf46b
-#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
-#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
-
-/*P1_TMGLOCK0*/
-#define R0900_P1_TMGLOCK0 0xf46c
-#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
-#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
-
-/*P1_TMGOBS*/
-#define R0900_P1_TMGOBS 0xf46d
-#define TMGOBS REGx(R0900_P1_TMGOBS)
-#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
-#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
-
-/*P1_EQUALCFG*/
-#define R0900_P1_EQUALCFG 0xf46f
-#define EQUALCFG REGx(R0900_P1_EQUALCFG)
-#define F0900_P1_EQUAL_ON 0xf46f0040
-#define F0900_P1_MU_EQUALDFE 0xf46f0007
-
-/*P1_EQUAI1*/
-#define R0900_P1_EQUAI1 0xf470
-#define EQUAI1 REGx(R0900_P1_EQUAI1)
-#define F0900_P1_EQUA_ACCI1 0xf47001ff
-
-/*P1_EQUAQ1*/
-#define R0900_P1_EQUAQ1 0xf471
-#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
-#define F0900_P1_EQUA_ACCQ1 0xf47101ff
-
-/*P1_EQUAI2*/
-#define R0900_P1_EQUAI2 0xf472
-#define EQUAI2 REGx(R0900_P1_EQUAI2)
-#define F0900_P1_EQUA_ACCI2 0xf47201ff
-
-/*P1_EQUAQ2*/
-#define R0900_P1_EQUAQ2 0xf473
-#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
-#define F0900_P1_EQUA_ACCQ2 0xf47301ff
-
-/*P1_EQUAI3*/
-#define R0900_P1_EQUAI3 0xf474
-#define EQUAI3 REGx(R0900_P1_EQUAI3)
-#define F0900_P1_EQUA_ACCI3 0xf47401ff
-
-/*P1_EQUAQ3*/
-#define R0900_P1_EQUAQ3 0xf475
-#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
-#define F0900_P1_EQUA_ACCQ3 0xf47501ff
-
-/*P1_EQUAI4*/
-#define R0900_P1_EQUAI4 0xf476
-#define EQUAI4 REGx(R0900_P1_EQUAI4)
-#define F0900_P1_EQUA_ACCI4 0xf47601ff
-
-/*P1_EQUAQ4*/
-#define R0900_P1_EQUAQ4 0xf477
-#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
-#define F0900_P1_EQUA_ACCQ4 0xf47701ff
-
-/*P1_EQUAI5*/
-#define R0900_P1_EQUAI5 0xf478
-#define EQUAI5 REGx(R0900_P1_EQUAI5)
-#define F0900_P1_EQUA_ACCI5 0xf47801ff
-
-/*P1_EQUAQ5*/
-#define R0900_P1_EQUAQ5 0xf479
-#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
-#define F0900_P1_EQUA_ACCQ5 0xf47901ff
-
-/*P1_EQUAI6*/
-#define R0900_P1_EQUAI6 0xf47a
-#define EQUAI6 REGx(R0900_P1_EQUAI6)
-#define F0900_P1_EQUA_ACCI6 0xf47a01ff
-
-/*P1_EQUAQ6*/
-#define R0900_P1_EQUAQ6 0xf47b
-#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
-#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
-
-/*P1_EQUAI7*/
-#define R0900_P1_EQUAI7 0xf47c
-#define EQUAI7 REGx(R0900_P1_EQUAI7)
-#define F0900_P1_EQUA_ACCI7 0xf47c01ff
-
-/*P1_EQUAQ7*/
-#define R0900_P1_EQUAQ7 0xf47d
-#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
-#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
-
-/*P1_EQUAI8*/
-#define R0900_P1_EQUAI8 0xf47e
-#define EQUAI8 REGx(R0900_P1_EQUAI8)
-#define F0900_P1_EQUA_ACCI8 0xf47e01ff
-
-/*P1_EQUAQ8*/
-#define R0900_P1_EQUAQ8 0xf47f
-#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
-#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
-
-/*P1_NNOSDATAT1*/
-#define R0900_P1_NNOSDATAT1 0xf480
-#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
-#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
-#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
-
-/*P1_NNOSDATAT0*/
-#define R0900_P1_NNOSDATAT0 0xf481
-#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
-#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
-#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
-
-/*P1_NNOSDATA1*/
-#define R0900_P1_NNOSDATA1 0xf482
-#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
-#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
-
-/*P1_NNOSDATA0*/
-#define R0900_P1_NNOSDATA0 0xf483
-#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
-#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
-
-/*P1_NNOSPLHT1*/
-#define R0900_P1_NNOSPLHT1 0xf484
-#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
-#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
-#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
-
-/*P1_NNOSPLHT0*/
-#define R0900_P1_NNOSPLHT0 0xf485
-#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
-#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
-#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
-
-/*P1_NNOSPLH1*/
-#define R0900_P1_NNOSPLH1 0xf486
-#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
-#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
-
-/*P1_NNOSPLH0*/
-#define R0900_P1_NNOSPLH0 0xf487
-#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
-#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
-
-/*P1_NOSDATAT1*/
-#define R0900_P1_NOSDATAT1 0xf488
-#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
-#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
-
-/*P1_NOSDATAT0*/
-#define R0900_P1_NOSDATAT0 0xf489
-#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
-#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
-
-/*P1_NOSDATA1*/
-#define R0900_P1_NOSDATA1 0xf48a
-#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
-#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
-
-/*P1_NOSDATA0*/
-#define R0900_P1_NOSDATA0 0xf48b
-#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
-#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
-
-/*P1_NOSPLHT1*/
-#define R0900_P1_NOSPLHT1 0xf48c
-#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
-#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
-
-/*P1_NOSPLHT0*/
-#define R0900_P1_NOSPLHT0 0xf48d
-#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
-#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
-
-/*P1_NOSPLH1*/
-#define R0900_P1_NOSPLH1 0xf48e
-#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
-#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
-
-/*P1_NOSPLH0*/
-#define R0900_P1_NOSPLH0 0xf48f
-#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
-#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
-
-/*P1_CAR2CFG*/
-#define R0900_P1_CAR2CFG 0xf490
-#define CAR2CFG REGx(R0900_P1_CAR2CFG)
-#define F0900_P1_CARRIER3_DISABLE 0xf4900040
-#define F0900_P1_ROTA2ON 0xf4900004
-#define F0900_P1_PH_DET_ALGO2 0xf4900003
-
-/*P1_CFR2CFR1*/
-#define R0900_P1_CFR2CFR1 0xf491
-#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
-#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
-#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
-#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
-#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
-
-/*P1_CFR22*/
-#define R0900_P1_CFR22 0xf493
-#define CFR22 REGx(R0900_P1_CFR22)
-#define F0900_P1_CAR2_FREQ2 0xf49301ff
-
-/*P1_CFR21*/
-#define R0900_P1_CFR21 0xf494
-#define CFR21 REGx(R0900_P1_CFR21)
-#define F0900_P1_CAR2_FREQ1 0xf49400ff
-
-/*P1_CFR20*/
-#define R0900_P1_CFR20 0xf495
-#define CFR20 REGx(R0900_P1_CFR20)
-#define F0900_P1_CAR2_FREQ0 0xf49500ff
-
-/*P1_ACLC2S2Q*/
-#define R0900_P1_ACLC2S2Q 0xf497
-#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
-#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
-#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
-#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
-
-/*P1_ACLC2S28*/
-#define R0900_P1_ACLC2S28 0xf498
-#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
-#define F0900_P1_OLDI3Q_MODE 0xf4980080
-#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
-#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
-
-/*P1_ACLC2S216A*/
-#define R0900_P1_ACLC2S216A 0xf499
-#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
-#define F0900_P1_DIS_C3STOPA2 0xf4990080
-#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
-#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
-#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
-
-/*P1_ACLC2S232A*/
-#define R0900_P1_ACLC2S232A 0xf49a
-#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
-#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
-#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
-#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
-
-/*P1_BCLC2S2Q*/
-#define R0900_P1_BCLC2S2Q 0xf49c
-#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
-#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
-#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
-
-/*P1_BCLC2S28*/
-#define R0900_P1_BCLC2S28 0xf49d
-#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
-#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
-#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
-
-/*P1_BCLC2S216A*/
-#define R0900_P1_BCLC2S216A 0xf49e
-#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
-
-/*P1_BCLC2S232A*/
-#define R0900_P1_BCLC2S232A 0xf49f
-#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
-
-/*P1_PLROOT2*/
-#define R0900_P1_PLROOT2 0xf4ac
-#define PLROOT2 REGx(R0900_P1_PLROOT2)
-#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
-#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
-
-/*P1_PLROOT1*/
-#define R0900_P1_PLROOT1 0xf4ad
-#define PLROOT1 REGx(R0900_P1_PLROOT1)
-#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
-
-/*P1_PLROOT0*/
-#define R0900_P1_PLROOT0 0xf4ae
-#define PLROOT0 REGx(R0900_P1_PLROOT0)
-#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
-
-/*P1_MODCODLST0*/
-#define R0900_P1_MODCODLST0 0xf4b0
-#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
-
-/*P1_MODCODLST1*/
-#define R0900_P1_MODCODLST1 0xf4b1
-#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
-#define F0900_P1_DIS_MODCOD29 0xf4b100f0
-#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
-
-/*P1_MODCODLST2*/
-#define R0900_P1_MODCODLST2 0xf4b2
-#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
-#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
-#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
-
-/*P1_MODCODLST3*/
-#define R0900_P1_MODCODLST3 0xf4b3
-#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
-#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
-#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
-
-/*P1_MODCODLST4*/
-#define R0900_P1_MODCODLST4 0xf4b4
-#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
-#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
-#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
-
-/*P1_MODCODLST5*/
-#define R0900_P1_MODCODLST5 0xf4b5
-#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
-#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
-#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
-
-/*P1_MODCODLST6*/
-#define R0900_P1_MODCODLST6 0xf4b6
-#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
-#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
-#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
-
-/*P1_MODCODLST7*/
-#define R0900_P1_MODCODLST7 0xf4b7
-#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
-#define F0900_P1_DIS_8P_9_10 0xf4b700f0
-#define F0900_P1_DIS_8P_8_9 0xf4b7000f
-
-/*P1_MODCODLST8*/
-#define R0900_P1_MODCODLST8 0xf4b8
-#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
-#define F0900_P1_DIS_8P_5_6 0xf4b800f0
-#define F0900_P1_DIS_8P_3_4 0xf4b8000f
-
-/*P1_MODCODLST9*/
-#define R0900_P1_MODCODLST9 0xf4b9
-#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
-#define F0900_P1_DIS_8P_2_3 0xf4b900f0
-#define F0900_P1_DIS_8P_3_5 0xf4b9000f
-
-/*P1_MODCODLSTA*/
-#define R0900_P1_MODCODLSTA 0xf4ba
-#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
-#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
-#define F0900_P1_DIS_QP_8_9 0xf4ba000f
-
-/*P1_MODCODLSTB*/
-#define R0900_P1_MODCODLSTB 0xf4bb
-#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
-#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
-#define F0900_P1_DIS_QP_4_5 0xf4bb000f
-
-/*P1_MODCODLSTC*/
-#define R0900_P1_MODCODLSTC 0xf4bc
-#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
-#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
-#define F0900_P1_DIS_QP_2_3 0xf4bc000f
-
-/*P1_MODCODLSTD*/
-#define R0900_P1_MODCODLSTD 0xf4bd
-#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
-#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
-#define F0900_P1_DIS_QP_1_2 0xf4bd000f
-
-/*P1_MODCODLSTE*/
-#define R0900_P1_MODCODLSTE 0xf4be
-#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
-#define F0900_P1_DIS_QP_2_5 0xf4be00f0
-#define F0900_P1_DIS_QP_1_3 0xf4be000f
-
-/*P1_MODCODLSTF*/
-#define R0900_P1_MODCODLSTF 0xf4bf
-#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
-#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
-
-/*P1_GAUSSR0*/
-#define R0900_P1_GAUSSR0 0xf4c0
-#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
-#define F0900_P1_EN_CCIMODE 0xf4c00080
-#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
-
-/*P1_CCIR0*/
-#define R0900_P1_CCIR0 0xf4c1
-#define CCIR0 REGx(R0900_P1_CCIR0)
-#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
-#define F0900_P1_R0_CCI 0xf4c1007f
-
-/*P1_CCIQUANT*/
-#define R0900_P1_CCIQUANT 0xf4c2
-#define CCIQUANT REGx(R0900_P1_CCIQUANT)
-#define F0900_P1_CCI_BETA 0xf4c200e0
-#define F0900_P1_CCI_QUANT 0xf4c2001f
-
-/*P1_CCITHRES*/
-#define R0900_P1_CCITHRES 0xf4c3
-#define CCITHRES REGx(R0900_P1_CCITHRES)
-#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
-
-/*P1_CCIACC*/
-#define R0900_P1_CCIACC 0xf4c4
-#define CCIACC REGx(R0900_P1_CCIACC)
-#define F0900_P1_CCI_VALUE 0xf4c400ff
-
-/*P1_DMDRESCFG*/
-#define R0900_P1_DMDRESCFG 0xf4c6
-#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
-#define F0900_P1_DMDRES_RESET 0xf4c60080
-#define F0900_P1_DMDRES_STRALL 0xf4c60008
-#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
-#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
-
-/*P1_DMDRESADR*/
-#define R0900_P1_DMDRESADR 0xf4c7
-#define DMDRESADR REGx(R0900_P1_DMDRESADR)
-#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
-#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
-#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
-
-/*P1_DMDRESDATA7*/
-#define R0900_P1_DMDRESDATA7 0xf4c8
-#define F0900_P1_DMDRES_DATA7 0xf4c800ff
-
-/*P1_DMDRESDATA6*/
-#define R0900_P1_DMDRESDATA6 0xf4c9
-#define F0900_P1_DMDRES_DATA6 0xf4c900ff
-
-/*P1_DMDRESDATA5*/
-#define R0900_P1_DMDRESDATA5 0xf4ca
-#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
-
-/*P1_DMDRESDATA4*/
-#define R0900_P1_DMDRESDATA4 0xf4cb
-#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
-
-/*P1_DMDRESDATA3*/
-#define R0900_P1_DMDRESDATA3 0xf4cc
-#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
-
-/*P1_DMDRESDATA2*/
-#define R0900_P1_DMDRESDATA2 0xf4cd
-#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
-
-/*P1_DMDRESDATA1*/
-#define R0900_P1_DMDRESDATA1 0xf4ce
-#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
-
-/*P1_DMDRESDATA0*/
-#define R0900_P1_DMDRESDATA0 0xf4cf
-#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
-
-/*P1_FFEI1*/
-#define R0900_P1_FFEI1 0xf4d0
-#define FFEI1 REGx(R0900_P1_FFEI1)
-#define F0900_P1_FFE_ACCI1 0xf4d001ff
-
-/*P1_FFEQ1*/
-#define R0900_P1_FFEQ1 0xf4d1
-#define FFEQ1 REGx(R0900_P1_FFEQ1)
-#define F0900_P1_FFE_ACCQ1 0xf4d101ff
-
-/*P1_FFEI2*/
-#define R0900_P1_FFEI2 0xf4d2
-#define FFEI2 REGx(R0900_P1_FFEI2)
-#define F0900_P1_FFE_ACCI2 0xf4d201ff
-
-/*P1_FFEQ2*/
-#define R0900_P1_FFEQ2 0xf4d3
-#define FFEQ2 REGx(R0900_P1_FFEQ2)
-#define F0900_P1_FFE_ACCQ2 0xf4d301ff
-
-/*P1_FFEI3*/
-#define R0900_P1_FFEI3 0xf4d4
-#define FFEI3 REGx(R0900_P1_FFEI3)
-#define F0900_P1_FFE_ACCI3 0xf4d401ff
-
-/*P1_FFEQ3*/
-#define R0900_P1_FFEQ3 0xf4d5
-#define FFEQ3 REGx(R0900_P1_FFEQ3)
-#define F0900_P1_FFE_ACCQ3 0xf4d501ff
-
-/*P1_FFEI4*/
-#define R0900_P1_FFEI4 0xf4d6
-#define FFEI4 REGx(R0900_P1_FFEI4)
-#define F0900_P1_FFE_ACCI4 0xf4d601ff
-
-/*P1_FFEQ4*/
-#define R0900_P1_FFEQ4 0xf4d7
-#define FFEQ4 REGx(R0900_P1_FFEQ4)
-#define F0900_P1_FFE_ACCQ4 0xf4d701ff
-
-/*P1_FFECFG*/
-#define R0900_P1_FFECFG 0xf4d8
-#define FFECFG REGx(R0900_P1_FFECFG)
-#define F0900_P1_EQUALFFE_ON 0xf4d80040
-#define F0900_P1_MU_EQUALFFE 0xf4d80007
-
-/*P1_TNRCFG*/
-#define R0900_P1_TNRCFG 0xf4e0
-#define TNRCFG REGx(R0900_P1_TNRCFG)
-#define F0900_P1_TUN_ACKFAIL 0xf4e00080
-#define F0900_P1_TUN_TYPE 0xf4e00070
-#define F0900_P1_TUN_SECSTOP 0xf4e00008
-#define F0900_P1_TUN_VCOSRCH 0xf4e00004
-#define F0900_P1_TUN_MADDRESS 0xf4e00003
-
-/*P1_TNRCFG2*/
-#define R0900_P1_TNRCFG2 0xf4e1
-#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
-#define F0900_P1_TUN_IQSWAP 0xf4e10080
-#define F0900_P1_DIS_BWCALC 0xf4e10004
-#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
-
-/*P1_TNRXTAL*/
-#define R0900_P1_TNRXTAL 0xf4e4
-#define TNRXTAL REGx(R0900_P1_TNRXTAL)
-#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
-
-/*P1_TNRSTEPS*/
-#define R0900_P1_TNRSTEPS 0xf4e7
-#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
-#define F0900_P1_TUNER_BW0P125 0xf4e70080
-#define F0900_P1_BWINC_OFFSET 0xf4e70170
-#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
-#define F0900_P1_TUN_BWOFFSET 0xf4e70007
-
-/*P1_TNRGAIN*/
-#define R0900_P1_TNRGAIN 0xf4e8
-#define TNRGAIN REGx(R0900_P1_TNRGAIN)
-#define F0900_P1_TUN_KDIVEN 0xf4e800c0
-#define F0900_P1_STB6X00_OCK 0xf4e80030
-#define F0900_P1_TUN_GAIN 0xf4e8000f
-
-/*P1_TNRRF1*/
-#define R0900_P1_TNRRF1 0xf4e9
-#define TNRRF1 REGx(R0900_P1_TNRRF1)
-#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
-#define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2)
-
-/*P1_TNRRF0*/
-#define R0900_P1_TNRRF0 0xf4ea
-#define TNRRF0 REGx(R0900_P1_TNRRF0)
-#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
-#define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1)
-
-/*P1_TNRBW*/
-#define R0900_P1_TNRBW 0xf4eb
-#define TNRBW REGx(R0900_P1_TNRBW)
-#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
-#define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0)
-#define F0900_P1_TUN_BW 0xf4eb003f
-#define TUN_BW FLDx(F0900_P1_TUN_BW)
-
-/*P1_TNRADJ*/
-#define R0900_P1_TNRADJ 0xf4ec
-#define TNRADJ REGx(R0900_P1_TNRADJ)
-#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
-
-/*P1_TNRCTL2*/
-#define R0900_P1_TNRCTL2 0xf4ed
-#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
-#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
-#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
-#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
-#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
-#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
-#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
-#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
-#define F0900_P1_STB6XX0_SYN 0xf4ed0001
-
-/*P1_TNRCFG3*/
-#define R0900_P1_TNRCFG3 0xf4ee
-#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
-#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
-#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
-
-/*P1_TNRLAUNCH*/
-#define R0900_P1_TNRLAUNCH 0xf4f0
-#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
-
-/*P1_TNRLD*/
-#define R0900_P1_TNRLD 0xf4f0
-#define TNRLD REGx(R0900_P1_TNRLD)
-#define F0900_P1_TUNLD_VCOING 0xf4f00080
-#define F0900_P1_TUN_REG1FAIL 0xf4f00040
-#define F0900_P1_TUN_REG2FAIL 0xf4f00020
-#define F0900_P1_TUN_REG3FAIL 0xf4f00010
-#define F0900_P1_TUN_REG4FAIL 0xf4f00008
-#define F0900_P1_TUN_REG5FAIL 0xf4f00004
-#define F0900_P1_TUN_BWING 0xf4f00002
-#define F0900_P1_TUN_LOCKED 0xf4f00001
-
-/*P1_TNROBSL*/
-#define R0900_P1_TNROBSL 0xf4f6
-#define TNROBSL REGx(R0900_P1_TNROBSL)
-#define F0900_P1_TUN_I2CABORTED 0xf4f60080
-#define F0900_P1_TUN_LPEN 0xf4f60040
-#define F0900_P1_TUN_FCCK 0xf4f60020
-#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
-#define F0900_P1_TUN_PROGDONE 0xf4f6000c
-#define F0900_P1_TUN_RFRESTE1 0xf4f60003
-#define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1)
-
-/*P1_TNRRESTE*/
-#define R0900_P1_TNRRESTE 0xf4f7
-#define TNRRESTE REGx(R0900_P1_TNRRESTE)
-#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
-#define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0)
-
-/*P1_SMAPCOEF7*/
-#define R0900_P1_SMAPCOEF7 0xf500
-#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
-#define F0900_P1_DIS_QSCALE 0xf5000080
-#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
-
-/*P1_SMAPCOEF6*/
-#define R0900_P1_SMAPCOEF6 0xf501
-#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
-#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
-#define F0900_P1_OLD_8PSKLLR1 0xf5010002
-#define F0900_P1_DIS_AB8PSK 0xf5010001
-
-/*P1_SMAPCOEF5*/
-#define R0900_P1_SMAPCOEF5 0xf502
-#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
-#define F0900_P1_DIS_8SCALE 0xf5020080
-#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
-
-/*P1_NCO2MAX1*/
-#define R0900_P1_NCO2MAX1 0xf514
-#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
-#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
-
-/*P1_NCO2MAX0*/
-#define R0900_P1_NCO2MAX0 0xf515
-#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
-#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
-
-/*P1_NCO2FR1*/
-#define R0900_P1_NCO2FR1 0xf516
-#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
-#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
-
-/*P1_NCO2FR0*/
-#define R0900_P1_NCO2FR0 0xf517
-#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
-#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
-
-/*P1_CFR2AVRGE1*/
-#define R0900_P1_CFR2AVRGE1 0xf518
-#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
-#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
-
-/*P1_CFR2AVRGE0*/
-#define R0900_P1_CFR2AVRGE0 0xf519
-#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
-#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
-
-/*P1_DMDPLHSTAT*/
-#define R0900_P1_DMDPLHSTAT 0xf520
-#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
-#define F0900_P1_PLH_STATISTIC 0xf52000ff
-
-/*P1_LOCKTIME3*/
-#define R0900_P1_LOCKTIME3 0xf522
-#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
-#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
-
-/*P1_LOCKTIME2*/
-#define R0900_P1_LOCKTIME2 0xf523
-#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
-#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
-
-/*P1_LOCKTIME1*/
-#define R0900_P1_LOCKTIME1 0xf524
-#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
-#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
-
-/*P1_LOCKTIME0*/
-#define R0900_P1_LOCKTIME0 0xf525
-#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
-#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
-
-/*P1_VITSCALE*/
-#define R0900_P1_VITSCALE 0xf532
-#define VITSCALE REGx(R0900_P1_VITSCALE)
-#define F0900_P1_NVTH_NOSRANGE 0xf5320080
-#define F0900_P1_VERROR_MAXMODE 0xf5320040
-#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
-#define F0900_P1_DIS_RSFLOCK 0xf5320002
-
-/*P1_FECM*/
-#define R0900_P1_FECM 0xf533
-#define FECM REGx(R0900_P1_FECM)
-#define F0900_P1_DSS_DVB 0xf5330080
-#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
-#define F0900_P1_DSS_SRCH 0xf5330010
-#define F0900_P1_SYNCVIT 0xf5330002
-#define F0900_P1_IQINV 0xf5330001
-#define IQINV FLDx(F0900_P1_IQINV)
-
-/*P1_VTH12*/
-#define R0900_P1_VTH12 0xf534
-#define VTH12 REGx(R0900_P1_VTH12)
-#define F0900_P1_VTH12 0xf53400ff
-
-/*P1_VTH23*/
-#define R0900_P1_VTH23 0xf535
-#define VTH23 REGx(R0900_P1_VTH23)
-#define F0900_P1_VTH23 0xf53500ff
-
-/*P1_VTH34*/
-#define R0900_P1_VTH34 0xf536
-#define VTH34 REGx(R0900_P1_VTH34)
-#define F0900_P1_VTH34 0xf53600ff
-
-/*P1_VTH56*/
-#define R0900_P1_VTH56 0xf537
-#define VTH56 REGx(R0900_P1_VTH56)
-#define F0900_P1_VTH56 0xf53700ff
-
-/*P1_VTH67*/
-#define R0900_P1_VTH67 0xf538
-#define VTH67 REGx(R0900_P1_VTH67)
-#define F0900_P1_VTH67 0xf53800ff
-
-/*P1_VTH78*/
-#define R0900_P1_VTH78 0xf539
-#define VTH78 REGx(R0900_P1_VTH78)
-#define F0900_P1_VTH78 0xf53900ff
-
-/*P1_VITCURPUN*/
-#define R0900_P1_VITCURPUN 0xf53a
-#define VITCURPUN REGx(R0900_P1_VITCURPUN)
-#define F0900_P1_VIT_CURPUN 0xf53a001f
-#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
-
-/*P1_VERROR*/
-#define R0900_P1_VERROR 0xf53b
-#define VERROR REGx(R0900_P1_VERROR)
-#define F0900_P1_REGERR_VIT 0xf53b00ff
-
-/*P1_PRVIT*/
-#define R0900_P1_PRVIT 0xf53c
-#define PRVIT REGx(R0900_P1_PRVIT)
-#define F0900_P1_DIS_VTHLOCK 0xf53c0040
-#define F0900_P1_E7_8VIT 0xf53c0020
-#define F0900_P1_E6_7VIT 0xf53c0010
-#define F0900_P1_E5_6VIT 0xf53c0008
-#define F0900_P1_E3_4VIT 0xf53c0004
-#define F0900_P1_E2_3VIT 0xf53c0002
-#define F0900_P1_E1_2VIT 0xf53c0001
-
-/*P1_VAVSRVIT*/
-#define R0900_P1_VAVSRVIT 0xf53d
-#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
-#define F0900_P1_AMVIT 0xf53d0080
-#define F0900_P1_FROZENVIT 0xf53d0040
-#define F0900_P1_SNVIT 0xf53d0030
-#define F0900_P1_TOVVIT 0xf53d000c
-#define F0900_P1_HYPVIT 0xf53d0003
-
-/*P1_VSTATUSVIT*/
-#define R0900_P1_VSTATUSVIT 0xf53e
-#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
-#define F0900_P1_PRFVIT 0xf53e0010
-#define PRFVIT FLDx(F0900_P1_PRFVIT)
-#define F0900_P1_LOCKEDVIT 0xf53e0008
-#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
-
-/*P1_VTHINUSE*/
-#define R0900_P1_VTHINUSE 0xf53f
-#define VTHINUSE REGx(R0900_P1_VTHINUSE)
-#define F0900_P1_VIT_INUSE 0xf53f00ff
-
-/*P1_KDIV12*/
-#define R0900_P1_KDIV12 0xf540
-#define KDIV12 REGx(R0900_P1_KDIV12)
-#define F0900_P1_K_DIVIDER_12 0xf540007f
-
-/*P1_KDIV23*/
-#define R0900_P1_KDIV23 0xf541
-#define KDIV23 REGx(R0900_P1_KDIV23)
-#define F0900_P1_K_DIVIDER_23 0xf541007f
-
-/*P1_KDIV34*/
-#define R0900_P1_KDIV34 0xf542
-#define KDIV34 REGx(R0900_P1_KDIV34)
-#define F0900_P1_K_DIVIDER_34 0xf542007f
-
-/*P1_KDIV56*/
-#define R0900_P1_KDIV56 0xf543
-#define KDIV56 REGx(R0900_P1_KDIV56)
-#define F0900_P1_K_DIVIDER_56 0xf543007f
-
-/*P1_KDIV67*/
-#define R0900_P1_KDIV67 0xf544
-#define KDIV67 REGx(R0900_P1_KDIV67)
-#define F0900_P1_K_DIVIDER_67 0xf544007f
-
-/*P1_KDIV78*/
-#define R0900_P1_KDIV78 0xf545
-#define KDIV78 REGx(R0900_P1_KDIV78)
-#define F0900_P1_K_DIVIDER_78 0xf545007f
-
-/*P1_PDELCTRL1*/
-#define R0900_P1_PDELCTRL1 0xf550
-#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
-#define F0900_P1_INV_MISMASK 0xf5500080
-#define F0900_P1_FILTER_EN 0xf5500020
-#define F0900_P1_EN_MIS00 0xf5500002
-#define F0900_P1_ALGOSWRST 0xf5500001
-#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
-
-/*P1_PDELCTRL2*/
-#define R0900_P1_PDELCTRL2 0xf551
-#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
-#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
-#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
-#define F0900_P1_FRAME_MODE 0xf5510002
-#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
-
-/*P1_HYSTTHRESH*/
-#define R0900_P1_HYSTTHRESH 0xf554
-#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
-#define F0900_P1_UNLCK_THRESH 0xf55400f0
-#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
-
-/*P1_ISIENTRY*/
-#define R0900_P1_ISIENTRY 0xf55e
-#define ISIENTRY REGx(R0900_P1_ISIENTRY)
-#define F0900_P1_ISI_ENTRY 0xf55e00ff
-
-/*P1_ISIBITENA*/
-#define R0900_P1_ISIBITENA 0xf55f
-#define ISIBITENA REGx(R0900_P1_ISIBITENA)
-#define F0900_P1_ISI_BIT_EN 0xf55f00ff
-
-/*P1_MATSTR1*/
-#define R0900_P1_MATSTR1 0xf560
-#define MATSTR1 REGx(R0900_P1_MATSTR1)
-#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
-
-/*P1_MATSTR0*/
-#define R0900_P1_MATSTR0 0xf561
-#define MATSTR0 REGx(R0900_P1_MATSTR0)
-#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
-
-/*P1_UPLSTR1*/
-#define R0900_P1_UPLSTR1 0xf562
-#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
-#define F0900_P1_UPL_CURRENT1 0xf56200ff
-
-/*P1_UPLSTR0*/
-#define R0900_P1_UPLSTR0 0xf563
-#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
-#define F0900_P1_UPL_CURRENT0 0xf56300ff
-
-/*P1_DFLSTR1*/
-#define R0900_P1_DFLSTR1 0xf564
-#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
-#define F0900_P1_DFL_CURRENT1 0xf56400ff
-
-/*P1_DFLSTR0*/
-#define R0900_P1_DFLSTR0 0xf565
-#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
-#define F0900_P1_DFL_CURRENT0 0xf56500ff
-
-/*P1_SYNCSTR*/
-#define R0900_P1_SYNCSTR 0xf566
-#define SYNCSTR REGx(R0900_P1_SYNCSTR)
-#define F0900_P1_SYNC_CURRENT 0xf56600ff
-
-/*P1_SYNCDSTR1*/
-#define R0900_P1_SYNCDSTR1 0xf567
-#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
-#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
-
-/*P1_SYNCDSTR0*/
-#define R0900_P1_SYNCDSTR0 0xf568
-#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
-#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
-
-/*P1_PDELSTATUS1*/
-#define R0900_P1_PDELSTATUS1 0xf569
-#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
-#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
-#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
-#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
-#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
-#define F0900_P1_PKTDELIN_LOCK 0xf5690002
-#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
-#define F0900_P1_FIRST_LOCK 0xf5690001
-
-/*P1_PDELSTATUS2*/
-#define R0900_P1_PDELSTATUS2 0xf56a
-#define F0900_P1_FRAME_MODCOD 0xf56a007c
-#define F0900_P1_FRAME_TYPE 0xf56a0003
-
-/*P1_BBFCRCKO1*/
-#define R0900_P1_BBFCRCKO1 0xf56b
-#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
-#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
-
-/*P1_BBFCRCKO0*/
-#define R0900_P1_BBFCRCKO0 0xf56c
-#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
-#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
-
-/*P1_UPCRCKO1*/
-#define R0900_P1_UPCRCKO1 0xf56d
-#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
-#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
-
-/*P1_UPCRCKO0*/
-#define R0900_P1_UPCRCKO0 0xf56e
-#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
-#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
-
-/*P1_PDELCTRL3*/
-#define R0900_P1_PDELCTRL3 0xf56f
-#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
-#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
-#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
-
-/*P1_TSSTATEM*/
-#define R0900_P1_TSSTATEM 0xf570
-#define TSSTATEM REGx(R0900_P1_TSSTATEM)
-#define F0900_P1_TSDIL_ON 0xf5700080
-#define F0900_P1_TSRS_ON 0xf5700020
-#define F0900_P1_TSDESCRAMB_ON 0xf5700010
-#define F0900_P1_TSFRAME_MODE 0xf5700008
-#define F0900_P1_TS_DISABLE 0xf5700004
-#define F0900_P1_TSOUT_NOSYNC 0xf5700001
-
-/*P1_TSCFGH*/
-#define R0900_P1_TSCFGH 0xf572
-#define TSCFGH REGx(R0900_P1_TSCFGH)
-#define F0900_P1_TSFIFO_DVBCI 0xf5720080
-#define F0900_P1_TSFIFO_SERIAL 0xf5720040
-#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
-#define F0900_P1_TSFIFO_DUTY50 0xf5720010
-#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
-#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
-#define F0900_P1_RST_HWARE 0xf5720001
-#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
-
-/*P1_TSCFGM*/
-#define R0900_P1_TSCFGM 0xf573
-#define TSCFGM REGx(R0900_P1_TSCFGM)
-#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
-#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
-#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
-#define F0900_P1_TSFIFO_INVDATA 0xf5730001
-
-/*P1_TSCFGL*/
-#define R0900_P1_TSCFGL 0xf574
-#define TSCFGL REGx(R0900_P1_TSCFGL)
-#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
-#define F0900_P1_BCHERROR_MODE 0xf5740030
-#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
-#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
-#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
-
-/*P1_TSINSDELH*/
-#define R0900_P1_TSINSDELH 0xf576
-#define TSINSDELH REGx(R0900_P1_TSINSDELH)
-#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
-#define F0900_P1_TSDEL_XXHEADER 0xf5760040
-#define F0900_P1_TSDEL_BBHEADER 0xf5760020
-#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
-#define F0900_P1_TSINSDEL_ISCR 0xf5760008
-#define F0900_P1_TSINSDEL_NPD 0xf5760004
-#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
-#define F0900_P1_TSINSDEL_CRC8 0xf5760001
-
-/*P1_TSDIVN*/
-#define R0900_P1_TSDIVN 0xf579
-#define TSDIVN REGx(R0900_P1_TSDIVN)
-#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
-
-/*P1_TSCFG4*/
-#define R0900_P1_TSCFG4 0xf57a
-#define TSCFG4 REGx(R0900_P1_TSCFG4)
-#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
-
-/*P1_TSSPEED*/
-#define R0900_P1_TSSPEED 0xf580
-#define TSSPEED REGx(R0900_P1_TSSPEED)
-#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
-
-/*P1_TSSTATUS*/
-#define R0900_P1_TSSTATUS 0xf581
-#define TSSTATUS REGx(R0900_P1_TSSTATUS)
-#define F0900_P1_TSFIFO_LINEOK 0xf5810080
-#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
-#define F0900_P1_TSFIFO_ERROR 0xf5810040
-#define F0900_P1_DIL_READY 0xf5810001
-
-/*P1_TSSTATUS2*/
-#define R0900_P1_TSSTATUS2 0xf582
-#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
-#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
-#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
-#define F0900_P1_DILXX_RESET 0xf5820020
-#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
-#define F0900_P1_SCRAMBDETECT 0xf5820002
-
-/*P1_TSBITRATE1*/
-#define R0900_P1_TSBITRATE1 0xf583
-#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
-#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
-
-/*P1_TSBITRATE0*/
-#define R0900_P1_TSBITRATE0 0xf584
-#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
-#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
-
-/*P1_ERRCTRL1*/
-#define R0900_P1_ERRCTRL1 0xf598
-#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
-#define F0900_P1_ERR_SOURCE1 0xf59800f0
-#define F0900_P1_NUM_EVENT1 0xf5980007
-
-/*P1_ERRCNT12*/
-#define R0900_P1_ERRCNT12 0xf599
-#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
-#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
-#define F0900_P1_ERR_CNT12 0xf599007f
-#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
-
-/*P1_ERRCNT11*/
-#define R0900_P1_ERRCNT11 0xf59a
-#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
-#define F0900_P1_ERR_CNT11 0xf59a00ff
-#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
-
-/*P1_ERRCNT10*/
-#define R0900_P1_ERRCNT10 0xf59b
-#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
-#define F0900_P1_ERR_CNT10 0xf59b00ff
-#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
-
-/*P1_ERRCTRL2*/
-#define R0900_P1_ERRCTRL2 0xf59c
-#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
-#define F0900_P1_ERR_SOURCE2 0xf59c00f0
-#define F0900_P1_NUM_EVENT2 0xf59c0007
-
-/*P1_ERRCNT22*/
-#define R0900_P1_ERRCNT22 0xf59d
-#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
-#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
-#define F0900_P1_ERR_CNT22 0xf59d007f
-#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
-
-/*P1_ERRCNT21*/
-#define R0900_P1_ERRCNT21 0xf59e
-#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
-#define F0900_P1_ERR_CNT21 0xf59e00ff
-#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
-
-/*P1_ERRCNT20*/
-#define R0900_P1_ERRCNT20 0xf59f
-#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
-#define F0900_P1_ERR_CNT20 0xf59f00ff
-#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
-
-/*P1_FECSPY*/
-#define R0900_P1_FECSPY 0xf5a0
-#define FECSPY REGx(R0900_P1_FECSPY)
-#define F0900_P1_SPY_ENABLE 0xf5a00080
-#define F0900_P1_NO_SYNCBYTE 0xf5a00040
-#define F0900_P1_SERIAL_MODE 0xf5a00020
-#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
-#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
-#define F0900_P1_BERMETER_LMODE 0xf5a00002
-#define F0900_P1_BERMETER_RESET 0xf5a00001
-
-/*P1_FSPYCFG*/
-#define R0900_P1_FSPYCFG 0xf5a1
-#define FSPYCFG REGx(R0900_P1_FSPYCFG)
-#define F0900_P1_FECSPY_INPUT 0xf5a100c0
-#define F0900_P1_RST_ON_ERROR 0xf5a10020
-#define F0900_P1_ONE_SHOT 0xf5a10010
-#define F0900_P1_I2C_MODE 0xf5a1000c
-#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
-
-/*P1_FSPYDATA*/
-#define R0900_P1_FSPYDATA 0xf5a2
-#define FSPYDATA REGx(R0900_P1_FSPYDATA)
-#define F0900_P1_SPY_STUFFING 0xf5a20080
-#define F0900_P1_SPY_CNULLPKT 0xf5a20020
-#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
-
-/*P1_FSPYOUT*/
-#define R0900_P1_FSPYOUT 0xf5a3
-#define FSPYOUT REGx(R0900_P1_FSPYOUT)
-#define F0900_P1_FSPY_DIRECT 0xf5a30080
-#define F0900_P1_STUFF_MODE 0xf5a30007
-
-/*P1_FSTATUS*/
-#define R0900_P1_FSTATUS 0xf5a4
-#define FSTATUS REGx(R0900_P1_FSTATUS)
-#define F0900_P1_SPY_ENDSIM 0xf5a40080
-#define F0900_P1_VALID_SIM 0xf5a40040
-#define F0900_P1_FOUND_SIGNAL 0xf5a40020
-#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
-#define F0900_P1_RESULT_STATE 0xf5a4000f
-
-/*P1_FBERCPT4*/
-#define R0900_P1_FBERCPT4 0xf5a8
-#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
-#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
-
-/*P1_FBERCPT3*/
-#define R0900_P1_FBERCPT3 0xf5a9
-#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
-#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
-
-/*P1_FBERCPT2*/
-#define R0900_P1_FBERCPT2 0xf5aa
-#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
-#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
-
-/*P1_FBERCPT1*/
-#define R0900_P1_FBERCPT1 0xf5ab
-#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
-#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
-
-/*P1_FBERCPT0*/
-#define R0900_P1_FBERCPT0 0xf5ac
-#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
-#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
-
-/*P1_FBERERR2*/
-#define R0900_P1_FBERERR2 0xf5ad
-#define FBERERR2 REGx(R0900_P1_FBERERR2)
-#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
-
-/*P1_FBERERR1*/
-#define R0900_P1_FBERERR1 0xf5ae
-#define FBERERR1 REGx(R0900_P1_FBERERR1)
-#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
-
-/*P1_FBERERR0*/
-#define R0900_P1_FBERERR0 0xf5af
-#define FBERERR0 REGx(R0900_P1_FBERERR0)
-#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
-
-/*P1_FSPYBER*/
-#define R0900_P1_FSPYBER 0xf5b2
-#define FSPYBER REGx(R0900_P1_FSPYBER)
-#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
-#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
-#define F0900_P1_FSPYBER_CTIME 0xf5b20007
-
-/*RCCFG2*/
-#define R0900_RCCFG2 0xf600
-
-/*TSGENERAL*/
-#define R0900_TSGENERAL 0xf630
-#define F0900_TSFIFO_DISTS2PAR 0xf6300040
-#define F0900_MUXSTREAM_OUTMODE 0xf6300008
-#define F0900_TSFIFO_PERMPARAL 0xf6300006
-
-/*TSGENERAL1X*/
-#define R0900_TSGENERAL1X 0xf670
-
-/*NBITER_NF4*/
-#define R0900_NBITER_NF4 0xfa03
-#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
-
-/*NBITER_NF5*/
-#define R0900_NBITER_NF5 0xfa04
-#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
-
-/*NBITER_NF6*/
-#define R0900_NBITER_NF6 0xfa05
-#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
-
-/*NBITER_NF7*/
-#define R0900_NBITER_NF7 0xfa06
-#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
-
-/*NBITER_NF8*/
-#define R0900_NBITER_NF8 0xfa07
-#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
-
-/*NBITER_NF9*/
-#define R0900_NBITER_NF9 0xfa08
-#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
-
-/*NBITER_NF10*/
-#define R0900_NBITER_NF10 0xfa09
-#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
-
-/*NBITER_NF11*/
-#define R0900_NBITER_NF11 0xfa0a
-#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
-
-/*NBITER_NF12*/
-#define R0900_NBITER_NF12 0xfa0b
-#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
-
-/*NBITER_NF13*/
-#define R0900_NBITER_NF13 0xfa0c
-#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
-
-/*NBITER_NF14*/
-#define R0900_NBITER_NF14 0xfa0d
-#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
-
-/*NBITER_NF15*/
-#define R0900_NBITER_NF15 0xfa0e
-#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
-
-/*NBITER_NF16*/
-#define R0900_NBITER_NF16 0xfa0f
-#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
-
-/*NBITER_NF17*/
-#define R0900_NBITER_NF17 0xfa10
-#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
-
-/*NBITERNOERR*/
-#define R0900_NBITERNOERR 0xfa3f
-#define F0900_NBITER_STOP_CRIT 0xfa3f000f
-
-/*GAINLLR_NF4*/
-#define R0900_GAINLLR_NF4 0xfa43
-#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
-
-/*GAINLLR_NF5*/
-#define R0900_GAINLLR_NF5 0xfa44
-#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
-
-/*GAINLLR_NF6*/
-#define R0900_GAINLLR_NF6 0xfa45
-#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
-
-/*GAINLLR_NF7*/
-#define R0900_GAINLLR_NF7 0xfa46
-#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
-
-/*GAINLLR_NF8*/
-#define R0900_GAINLLR_NF8 0xfa47
-#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
-
-/*GAINLLR_NF9*/
-#define R0900_GAINLLR_NF9 0xfa48
-#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
-
-/*GAINLLR_NF10*/
-#define R0900_GAINLLR_NF10 0xfa49
-#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
-
-/*GAINLLR_NF11*/
-#define R0900_GAINLLR_NF11 0xfa4a
-#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
-
-/*GAINLLR_NF12*/
-#define R0900_GAINLLR_NF12 0xfa4b
-#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
-
-/*GAINLLR_NF13*/
-#define R0900_GAINLLR_NF13 0xfa4c
-#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
-
-/*GAINLLR_NF14*/
-#define R0900_GAINLLR_NF14 0xfa4d
-#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
-
-/*GAINLLR_NF15*/
-#define R0900_GAINLLR_NF15 0xfa4e
-#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
-
-/*GAINLLR_NF16*/
-#define R0900_GAINLLR_NF16 0xfa4f
-#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
-
-/*GAINLLR_NF17*/
-#define R0900_GAINLLR_NF17 0xfa50
-#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
-
-/*CFGEXT*/
-#define R0900_CFGEXT 0xfa80
-#define F0900_STAGMODE 0xfa800080
-#define F0900_BYPBCH 0xfa800040
-#define F0900_BYPLDPC 0xfa800020
-#define F0900_LDPCMODE 0xfa800010
-#define F0900_INVLLRSIGN 0xfa800008
-#define F0900_SHORTMULT 0xfa800004
-#define F0900_EXTERNTX 0xfa800001
-
-/*GENCFG*/
-#define R0900_GENCFG 0xfa86
-#define F0900_BROADCAST 0xfa860010
-#define F0900_PRIORITY 0xfa860002
-#define F0900_DDEMOD 0xfa860001
-
-/*LDPCERR1*/
-#define R0900_LDPCERR1 0xfa96
-#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
-
-/*LDPCERR0*/
-#define R0900_LDPCERR0 0xfa97
-#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
-
-/*BCHERR*/
-#define R0900_BCHERR 0xfa98
-#define F0900_ERRORFLAG 0xfa980010
-#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
-
-/*TSTRES0*/
-#define R0900_TSTRES0 0xff11
-#define F0900_FRESFEC 0xff110080
-
-/*P2_TCTL4*/
-#define R0900_P2_TCTL4 0xff28
-#define F0900_P2_PN4_SELECT 0xff280020
-
-/*P1_TCTL4*/
-#define R0900_P1_TCTL4 0xff48
-#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
-#define F0900_P1_PN4_SELECT 0xff480020
-
-/*P2_TSTDISRX*/
-#define R0900_P2_TSTDISRX 0xff65
-#define F0900_P2_PIN_SELECT1 0xff650008
-
-/*P1_TSTDISRX*/
-#define R0900_P1_TSTDISRX 0xff67
-#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
-#define F0900_P1_PIN_SELECT1 0xff670008
-#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
-
-#define STV0900_NBREGS 723
-#define STV0900_NBFIELDS 1420
-
-#endif
-
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
deleted file mode 100644 (file)
index 4af2078..0000000
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- * stv0900_sw.c
- *
- * Driver for ST STV0900 satellite demodulator IC.
- *
- * Copyright (C) ST Microelectronics.
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "stv0900.h"
-#include "stv0900_reg.h"
-#include "stv0900_priv.h"
-
-s32 shiftx(s32 x, int demod, s32 shift)
-{
-       if (demod == 1)
-               return x - shift;
-
-       return x;
-}
-
-int stv0900_check_signal_presence(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32     carr_offset,
-               agc2_integr,
-               max_carrier;
-
-       int no_signal = FALSE;
-
-       carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
-                                       | stv0900_read_reg(intp, CFR1);
-       carr_offset = ge2comp(carr_offset, 16);
-       agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
-                                       | stv0900_read_reg(intp, AGC2I0);
-       max_carrier = intp->srch_range[demod] / 1000;
-
-       max_carrier += (max_carrier / 10);
-       max_carrier = 65536 * (max_carrier / 2);
-       max_carrier /= intp->mclk / 1000;
-       if (max_carrier > 0x4000)
-               max_carrier = 0x4000;
-
-       if ((agc2_integr > 0x2000)
-                       || (carr_offset > (2 * max_carrier))
-                       || (carr_offset < (-2 * max_carrier)))
-               no_signal = TRUE;
-
-       return no_signal;
-}
-
-static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
-                               s32 *frequency_inc, s32 *sw_timeout,
-                               s32 *steps,
-                               enum fe_stv0900_demod_num demod)
-{
-       s32 timeout, freq_inc, max_steps, srate, max_carrier;
-
-       enum fe_stv0900_search_standard standard;
-
-       srate = intp->symbol_rate[demod];
-       max_carrier = intp->srch_range[demod] / 1000;
-       max_carrier += max_carrier / 10;
-       standard = intp->srch_standard[demod];
-
-       max_carrier = 65536 * (max_carrier / 2);
-       max_carrier /= intp->mclk / 1000;
-
-       if (max_carrier > 0x4000)
-               max_carrier = 0x4000;
-
-       freq_inc = srate;
-       freq_inc /= intp->mclk >> 10;
-       freq_inc = freq_inc << 6;
-
-       switch (standard) {
-       case STV0900_SEARCH_DVBS1:
-       case STV0900_SEARCH_DSS:
-               freq_inc *= 3;
-               timeout = 20;
-               break;
-       case STV0900_SEARCH_DVBS2:
-               freq_inc *= 4;
-               timeout = 25;
-               break;
-       case STV0900_AUTO_SEARCH:
-       default:
-               freq_inc *= 3;
-               timeout = 25;
-               break;
-       }
-
-       freq_inc /= 100;
-
-       if ((freq_inc > max_carrier) || (freq_inc < 0))
-               freq_inc = max_carrier / 2;
-
-       timeout *= 27500;
-
-       if (srate > 0)
-               timeout /= srate / 1000;
-
-       if ((timeout > 100) || (timeout < 0))
-               timeout = 100;
-
-       max_steps = (max_carrier / freq_inc) + 1;
-
-       if ((max_steps > 100) || (max_steps < 0)) {
-               max_steps =  100;
-               freq_inc = max_carrier / max_steps;
-       }
-
-       *frequency_inc = freq_inc;
-       *sw_timeout = timeout;
-       *steps = max_steps;
-
-}
-
-static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
-                               s32 FreqIncr, s32 Timeout, int zigzag,
-                               s32 MaxStep, enum fe_stv0900_demod_num demod)
-{
-       int     no_signal,
-               lock = FALSE;
-       s32     stepCpt,
-               freqOffset,
-               max_carrier;
-
-       max_carrier = intp->srch_range[demod] / 1000;
-       max_carrier += (max_carrier / 10);
-
-       max_carrier = 65536 * (max_carrier / 2);
-       max_carrier /= intp->mclk / 1000;
-
-       if (max_carrier > 0x4000)
-               max_carrier = 0x4000;
-
-       if (zigzag == TRUE)
-               freqOffset = 0;
-       else
-               freqOffset = -max_carrier + FreqIncr;
-
-       stepCpt = 0;
-
-       do {
-               stv0900_write_reg(intp, DMDISTATE, 0x1c);
-               stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
-               stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
-               stv0900_write_reg(intp, DMDISTATE, 0x18);
-               stv0900_write_bits(intp, ALGOSWRST, 1);
-
-               if (intp->chip_id == 0x12) {
-                       stv0900_write_bits(intp, RST_HWARE, 1);
-                       stv0900_write_bits(intp, RST_HWARE, 0);
-               }
-
-               if (zigzag == TRUE) {
-                       if (freqOffset >= 0)
-                               freqOffset = -freqOffset - 2 * FreqIncr;
-                       else
-                               freqOffset = -freqOffset;
-               } else
-                       freqOffset += + 2 * FreqIncr;
-
-               stepCpt++;
-               lock = stv0900_get_demod_lock(intp, demod, Timeout);
-               no_signal = stv0900_check_signal_presence(intp, demod);
-
-       } while ((lock == FALSE)
-                       && (no_signal == FALSE)
-                       && ((freqOffset - FreqIncr) <  max_carrier)
-                       && ((freqOffset + FreqIncr) > -max_carrier)
-                       && (stepCpt < MaxStep));
-
-       stv0900_write_bits(intp, ALGOSWRST, 0);
-
-       return lock;
-}
-
-static int stv0900_sw_algo(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       int     lock = FALSE,
-               no_signal,
-               zigzag;
-       s32     s2fw,
-               fqc_inc,
-               sft_stp_tout,
-               trial_cntr,
-               max_steps;
-
-       stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
-                                       &max_steps, demod);
-       switch (intp->srch_standard[demod]) {
-       case STV0900_SEARCH_DVBS1:
-       case STV0900_SEARCH_DSS:
-               if (intp->chip_id >= 0x20)
-                       stv0900_write_reg(intp, CARFREQ, 0x3b);
-               else
-                       stv0900_write_reg(intp, CARFREQ, 0xef);
-
-               stv0900_write_reg(intp, DMDCFGMD, 0x49);
-               zigzag = FALSE;
-               break;
-       case STV0900_SEARCH_DVBS2:
-               if (intp->chip_id >= 0x20)
-                       stv0900_write_reg(intp, CORRELABS, 0x79);
-               else
-                       stv0900_write_reg(intp, CORRELABS, 0x68);
-
-               stv0900_write_reg(intp, DMDCFGMD, 0x89);
-
-               zigzag = TRUE;
-               break;
-       case STV0900_AUTO_SEARCH:
-       default:
-               if (intp->chip_id >= 0x20) {
-                       stv0900_write_reg(intp, CARFREQ, 0x3b);
-                       stv0900_write_reg(intp, CORRELABS, 0x79);
-               } else {
-                       stv0900_write_reg(intp, CARFREQ, 0xef);
-                       stv0900_write_reg(intp, CORRELABS, 0x68);
-               }
-
-               stv0900_write_reg(intp, DMDCFGMD, 0xc9);
-               zigzag = FALSE;
-               break;
-       }
-
-       trial_cntr = 0;
-       do {
-               lock = stv0900_search_carr_sw_loop(intp,
-                                               fqc_inc,
-                                               sft_stp_tout,
-                                               zigzag,
-                                               max_steps,
-                                               demod);
-               no_signal = stv0900_check_signal_presence(intp, demod);
-               trial_cntr++;
-               if ((lock == TRUE)
-                               || (no_signal == TRUE)
-                               || (trial_cntr == 2)) {
-
-                       if (intp->chip_id >= 0x20) {
-                               stv0900_write_reg(intp, CARFREQ, 0x49);
-                               stv0900_write_reg(intp, CORRELABS, 0x9e);
-                       } else {
-                               stv0900_write_reg(intp, CARFREQ, 0xed);
-                               stv0900_write_reg(intp, CORRELABS, 0x88);
-                       }
-
-                       if ((stv0900_get_bits(intp, HEADER_MODE) ==
-                                               STV0900_DVBS2_FOUND) &&
-                                                       (lock == TRUE)) {
-                               msleep(sft_stp_tout);
-                               s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
-
-                               if (s2fw < 0xd) {
-                                       msleep(sft_stp_tout);
-                                       s2fw = stv0900_get_bits(intp,
-                                                               FLYWHEEL_CPT);
-                               }
-
-                               if (s2fw < 0xd) {
-                                       lock = FALSE;
-
-                                       if (trial_cntr < 2) {
-                                               if (intp->chip_id >= 0x20)
-                                                       stv0900_write_reg(intp,
-                                                               CORRELABS,
-                                                               0x79);
-                                               else
-                                                       stv0900_write_reg(intp,
-                                                               CORRELABS,
-                                                               0x68);
-
-                                               stv0900_write_reg(intp,
-                                                               DMDCFGMD,
-                                                               0x89);
-                                       }
-                               }
-                       }
-               }
-
-       } while ((lock == FALSE)
-               && (trial_cntr < 2)
-               && (no_signal == FALSE));
-
-       return lock;
-}
-
-static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
-                                       u32 mclk,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32     rem1, rem2, intval1, intval2, srate;
-
-       srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
-               (stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
-               (stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
-               (stv0900_get_bits(intp, SYMB_FREQ0));
-       dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
-               srate, stv0900_get_bits(intp, SYMB_FREQ0),
-               stv0900_get_bits(intp, SYMB_FREQ1),
-               stv0900_get_bits(intp, SYMB_FREQ2),
-               stv0900_get_bits(intp, SYMB_FREQ3));
-
-       intval1 = (mclk) >> 16;
-       intval2 = (srate) >> 16;
-
-       rem1 = (mclk) % 0x10000;
-       rem2 = (srate) % 0x10000;
-       srate = (intval1 * intval2) +
-               ((intval1 * rem2) >> 16) +
-               ((intval2 * rem1) >> 16);
-
-       return srate;
-}
-
-static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
-                                       u32 mclk, u32 srate,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32 symb;
-
-       dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
-                                                       srate, demod);
-
-       if (srate > 60000000) {
-               symb = srate << 4;
-               symb /= (mclk >> 12);
-       } else if (srate > 6000000) {
-               symb = srate << 6;
-               symb /= (mclk >> 10);
-       } else {
-               symb = srate << 9;
-               symb /= (mclk >> 7);
-       }
-
-       stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
-       stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
-}
-
-static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
-                                       u32 mclk, u32 srate,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32 symb;
-
-       srate = 105 * (srate / 100);
-
-       if (srate > 60000000) {
-               symb = srate << 4;
-               symb /= (mclk >> 12);
-       } else if (srate > 6000000) {
-               symb = srate << 6;
-               symb /= (mclk >> 10);
-       } else {
-               symb = srate << 9;
-               symb /= (mclk >> 7);
-       }
-
-       if (symb < 0x7fff) {
-               stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
-               stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
-       } else {
-               stv0900_write_reg(intp, SFRUP1, 0x7f);
-               stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
-       }
-}
-
-static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
-                                       u32 mclk, u32 srate,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32     symb;
-
-       srate = 95 * (srate / 100);
-       if (srate > 60000000) {
-               symb = srate << 4;
-               symb /= (mclk >> 12);
-
-       } else if (srate > 6000000) {
-               symb = srate << 6;
-               symb /= (mclk >> 10);
-
-       } else {
-               symb = srate << 9;
-               symb /= (mclk >> 7);
-       }
-
-       stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
-       stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
-}
-
-static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
-                                       u32 srate,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32 timingoffset;
-
-
-       timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
-                      (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
-                      (stv0900_read_reg(intp, TMGREG2 + 2));
-
-       timingoffset = ge2comp(timingoffset, 24);
-
-
-       if (timingoffset == 0)
-               timingoffset = 1;
-
-       timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
-       timingoffset /= 320;
-
-       return timingoffset;
-}
-
-static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32 rolloff;
-
-       if (intp->chip_id == 0x10) {
-               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
-               rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
-               stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
-       } else if (intp->chip_id <= 0x20)
-               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
-       else /* cut 3.0 */
-               stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
-}
-
-static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
-{
-       u32 rolloff;
-
-       switch (ro) {
-       case STV0900_20:
-               rolloff = 20;
-               break;
-       case STV0900_25:
-               rolloff = 25;
-               break;
-       case STV0900_35:
-       default:
-               rolloff = 35;
-               break;
-       }
-
-       return srate  + (srate * rolloff) / 100;
-}
-
-static int stv0900_check_timing_lock(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod)
-{
-       int timingLock = FALSE;
-       s32     i,
-               timingcpt = 0;
-       u8      car_freq,
-               tmg_th_high,
-               tmg_th_low;
-
-       car_freq = stv0900_read_reg(intp, CARFREQ);
-       tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
-       tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
-       stv0900_write_reg(intp, TMGTHRISE, 0x20);
-       stv0900_write_reg(intp, TMGTHFALL, 0x0);
-       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-       stv0900_write_reg(intp, RTC, 0x80);
-       stv0900_write_reg(intp, RTCS2, 0x40);
-       stv0900_write_reg(intp, CARFREQ, 0x0);
-       stv0900_write_reg(intp, CFRINIT1, 0x0);
-       stv0900_write_reg(intp, CFRINIT0, 0x0);
-       stv0900_write_reg(intp, AGC2REF, 0x65);
-       stv0900_write_reg(intp, DMDISTATE, 0x18);
-       msleep(7);
-
-       for (i = 0; i < 10; i++) {
-               if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
-                       timingcpt++;
-
-               msleep(1);
-       }
-
-       if (timingcpt >= 3)
-               timingLock = TRUE;
-
-       stv0900_write_reg(intp, AGC2REF, 0x38);
-       stv0900_write_reg(intp, RTC, 0x88);
-       stv0900_write_reg(intp, RTCS2, 0x68);
-       stv0900_write_reg(intp, CARFREQ, car_freq);
-       stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
-       stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
-
-       return  timingLock;
-}
-
-static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
-                                       s32 demod_timeout)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       int     lock = FALSE,
-               d = demod;
-       s32     srate,
-               search_range,
-               locktimeout,
-               currier_step,
-               nb_steps,
-               current_step,
-               direction,
-               tuner_freq,
-               timeout,
-               freq;
-
-       srate = intp->symbol_rate[d];
-       search_range = intp->srch_range[d];
-
-       if (srate >= 10000000)
-               locktimeout = demod_timeout / 3;
-       else
-               locktimeout = demod_timeout / 2;
-
-       lock = stv0900_get_demod_lock(intp, d, locktimeout);
-
-       if (lock != FALSE)
-               return lock;
-
-       if (srate >= 10000000) {
-               if (stv0900_check_timing_lock(intp, d) == TRUE) {
-                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
-                       stv0900_write_reg(intp, DMDISTATE, 0x15);
-                       lock = stv0900_get_demod_lock(intp, d, demod_timeout);
-               } else
-                       lock = FALSE;
-
-               return lock;
-       }
-
-       if (intp->chip_id <= 0x20) {
-               if (srate <= 1000000)
-                       currier_step = 500;
-               else if (srate <= 4000000)
-                       currier_step = 1000;
-               else if (srate <= 7000000)
-                       currier_step = 2000;
-               else if (srate <= 10000000)
-                       currier_step = 3000;
-               else
-                       currier_step = 5000;
-
-               if (srate >= 2000000) {
-                       timeout = (demod_timeout / 3);
-                       if (timeout > 1000)
-                               timeout = 1000;
-               } else
-                       timeout = (demod_timeout / 2);
-       } else {
-               /*cut 3.0 */
-               currier_step = srate / 4000;
-               timeout = (demod_timeout * 3) / 4;
-       }
-
-       nb_steps = ((search_range / 1000) / currier_step);
-
-       if ((nb_steps % 2) != 0)
-               nb_steps += 1;
-
-       if (nb_steps <= 0)
-               nb_steps = 2;
-       else if (nb_steps > 12)
-               nb_steps = 12;
-
-       current_step = 1;
-       direction = 1;
-
-       if (intp->chip_id <= 0x20) {
-               tuner_freq = intp->freq[d];
-               intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
-                               intp->rolloff) + intp->symbol_rate[d];
-       } else
-               tuner_freq = 0;
-
-       while ((current_step <= nb_steps) && (lock == FALSE)) {
-               if (direction > 0)
-                       tuner_freq += (current_step * currier_step);
-               else
-                       tuner_freq -= (current_step * currier_step);
-
-               if (intp->chip_id <= 0x20) {
-                       if (intp->tuner_type[d] == 3)
-                               stv0900_set_tuner_auto(intp, tuner_freq,
-                                               intp->bw[d], demod);
-                       else
-                               stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
-
-                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
-                       stv0900_write_reg(intp, CFRINIT1, 0);
-                       stv0900_write_reg(intp, CFRINIT0, 0);
-                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
-                       stv0900_write_reg(intp, DMDISTATE, 0x15);
-               } else {
-                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
-                       freq = (tuner_freq * 65536) / (intp->mclk / 1000);
-                       stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
-                       stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
-                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
-                       stv0900_write_reg(intp, DMDISTATE, 0x05);
-               }
-
-               lock = stv0900_get_demod_lock(intp, d, timeout);
-               direction *= -1;
-               current_step++;
-       }
-
-       return  lock;
-}
-
-static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
-                                       s32 srate,
-                                       enum fe_stv0900_search_algo algo)
-{
-       switch (algo) {
-       case STV0900_BLIND_SEARCH:
-               if (srate <= 1500000) {
-                       (*demod_timeout) = 1500;
-                       (*fec_timeout) = 400;
-               } else if (srate <= 5000000) {
-                       (*demod_timeout) = 1000;
-                       (*fec_timeout) = 300;
-               } else {
-                       (*demod_timeout) = 700;
-                       (*fec_timeout) = 100;
-               }
-
-               break;
-       case STV0900_COLD_START:
-       case STV0900_WARM_START:
-       default:
-               if (srate <= 1000000) {
-                       (*demod_timeout) = 3000;
-                       (*fec_timeout) = 1700;
-               } else if (srate <= 2000000) {
-                       (*demod_timeout) = 2500;
-                       (*fec_timeout) = 1100;
-               } else if (srate <= 5000000) {
-                       (*demod_timeout) = 1000;
-                       (*fec_timeout) = 550;
-               } else if (srate <= 10000000) {
-                       (*demod_timeout) = 700;
-                       (*fec_timeout) = 250;
-               } else if (srate <= 20000000) {
-                       (*demod_timeout) = 400;
-                       (*fec_timeout) = 130;
-               } else {
-                       (*demod_timeout) = 300;
-                       (*fec_timeout) = 100;
-               }
-
-               break;
-
-       }
-
-       if (algo == STV0900_WARM_START)
-               (*demod_timeout) /= 2;
-}
-
-static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-
-       s32 vth_reg = VTH12;
-
-       dprintk("%s\n", __func__);
-
-       stv0900_write_reg(intp, vth_reg++, 0xd0);
-       stv0900_write_reg(intp, vth_reg++, 0x7d);
-       stv0900_write_reg(intp, vth_reg++, 0x53);
-       stv0900_write_reg(intp, vth_reg++, 0x2f);
-       stv0900_write_reg(intp, vth_reg++, 0x24);
-       stv0900_write_reg(intp, vth_reg++, 0x1f);
-}
-
-static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
-                                  enum fe_stv0900_search_standard standard,
-                                  enum fe_stv0900_fec fec,
-                                  enum fe_stv0900_demod_num demod)
-{
-       dprintk("%s: ViterbiStandard = ", __func__);
-
-       switch (standard) {
-       case STV0900_AUTO_SEARCH:
-               dprintk("Auto\n");
-               stv0900_write_reg(intp, FECM, 0x10);
-               stv0900_write_reg(intp, PRVIT, 0x3f);
-               break;
-       case STV0900_SEARCH_DVBS1:
-               dprintk("DVBS1\n");
-               stv0900_write_reg(intp, FECM, 0x00);
-               switch (fec) {
-               case STV0900_FEC_UNKNOWN:
-               default:
-                       stv0900_write_reg(intp, PRVIT, 0x2f);
-                       break;
-               case STV0900_FEC_1_2:
-                       stv0900_write_reg(intp, PRVIT, 0x01);
-                       break;
-               case STV0900_FEC_2_3:
-                       stv0900_write_reg(intp, PRVIT, 0x02);
-                       break;
-               case STV0900_FEC_3_4:
-                       stv0900_write_reg(intp, PRVIT, 0x04);
-                       break;
-               case STV0900_FEC_5_6:
-                       stv0900_write_reg(intp, PRVIT, 0x08);
-                       break;
-               case STV0900_FEC_7_8:
-                       stv0900_write_reg(intp, PRVIT, 0x20);
-                       break;
-               }
-
-               break;
-       case STV0900_SEARCH_DSS:
-               dprintk("DSS\n");
-               stv0900_write_reg(intp, FECM, 0x80);
-               switch (fec) {
-               case STV0900_FEC_UNKNOWN:
-               default:
-                       stv0900_write_reg(intp, PRVIT, 0x13);
-                       break;
-               case STV0900_FEC_1_2:
-                       stv0900_write_reg(intp, PRVIT, 0x01);
-                       break;
-               case STV0900_FEC_2_3:
-                       stv0900_write_reg(intp, PRVIT, 0x02);
-                       break;
-               case STV0900_FEC_6_7:
-                       stv0900_write_reg(intp, PRVIT, 0x10);
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
-                                               enum fe_stv0900_demod_num demod)
-{
-       enum fe_stv0900_fec prate;
-       s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
-
-       switch (rate_fld) {
-       case 13:
-               prate = STV0900_FEC_1_2;
-               break;
-       case 18:
-               prate = STV0900_FEC_2_3;
-               break;
-       case 21:
-               prate = STV0900_FEC_3_4;
-               break;
-       case 24:
-               prate = STV0900_FEC_5_6;
-               break;
-       case 25:
-               prate = STV0900_FEC_6_7;
-               break;
-       case 26:
-               prate = STV0900_FEC_7_8;
-               break;
-       default:
-               prate = STV0900_FEC_UNKNOWN;
-               break;
-       }
-
-       return prate;
-}
-
-static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod,
-                                       u32 srate)
-{
-       if (intp->chip_id >= 0x30) {
-               if (srate >= 15000000) {
-                       stv0900_write_reg(intp, ACLC, 0x2b);
-                       stv0900_write_reg(intp, BCLC, 0x1a);
-               } else if ((srate >= 7000000) && (15000000 > srate)) {
-                       stv0900_write_reg(intp, ACLC, 0x0c);
-                       stv0900_write_reg(intp, BCLC, 0x1b);
-               } else if (srate < 7000000) {
-                       stv0900_write_reg(intp, ACLC, 0x2c);
-                       stv0900_write_reg(intp, BCLC, 0x1c);
-               }
-
-       } else { /*cut 2.0 and 1.x*/
-               stv0900_write_reg(intp, ACLC, 0x1a);
-               stv0900_write_reg(intp, BCLC, 0x09);
-       }
-
-}
-
-static void stv0900_track_optimization(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       s32     srate,
-               pilots,
-               aclc,
-               freq1,
-               freq0,
-               i = 0,
-               timed,
-               timef,
-               blind_tun_sw = 0,
-               modulation;
-
-       enum fe_stv0900_modcode foundModcod;
-
-       dprintk("%s\n", __func__);
-
-       srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
-       srate += stv0900_get_timing_offst(intp, srate, demod);
-
-       switch (intp->result[demod].standard) {
-       case STV0900_DVBS1_STANDARD:
-       case STV0900_DSS_STANDARD:
-               dprintk("%s: found DVB-S or DSS\n", __func__);
-               if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
-                       stv0900_write_bits(intp, DVBS1_ENABLE, 1);
-                       stv0900_write_bits(intp, DVBS2_ENABLE, 0);
-               }
-
-               stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
-               stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
-
-               if (intp->chip_id < 0x30) {
-                       stv0900_write_reg(intp, ERRCTRL1, 0x75);
-                       break;
-               }
-
-               if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
-                       stv0900_write_reg(intp, GAUSSR0, 0x98);
-                       stv0900_write_reg(intp, CCIR0, 0x18);
-               } else {
-                       stv0900_write_reg(intp, GAUSSR0, 0x18);
-                       stv0900_write_reg(intp, CCIR0, 0x18);
-               }
-
-               stv0900_write_reg(intp, ERRCTRL1, 0x75);
-               break;
-       case STV0900_DVBS2_STANDARD:
-               dprintk("%s: found DVB-S2\n", __func__);
-               stv0900_write_bits(intp, DVBS1_ENABLE, 0);
-               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
-               stv0900_write_reg(intp, ACLC, 0);
-               stv0900_write_reg(intp, BCLC, 0);
-               if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
-                       foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
-                       pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
-                       aclc = stv0900_get_optim_carr_loop(srate,
-                                                       foundModcod,
-                                                       pilots,
-                                                       intp->chip_id);
-                       if (foundModcod <= STV0900_QPSK_910)
-                               stv0900_write_reg(intp, ACLC2S2Q, aclc);
-                       else if (foundModcod <= STV0900_8PSK_910) {
-                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                               stv0900_write_reg(intp, ACLC2S28, aclc);
-                       }
-
-                       if ((intp->demod_mode == STV0900_SINGLE) &&
-                                       (foundModcod > STV0900_8PSK_910)) {
-                               if (foundModcod <= STV0900_16APSK_910) {
-                                       stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                                       stv0900_write_reg(intp, ACLC2S216A,
-                                                                       aclc);
-                               } else if (foundModcod <= STV0900_32APSK_910) {
-                                       stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                                       stv0900_write_reg(intp, ACLC2S232A,
-                                                                       aclc);
-                               }
-                       }
-
-               } else {
-                       modulation = intp->result[demod].modulation;
-                       aclc = stv0900_get_optim_short_carr_loop(srate,
-                                       modulation, intp->chip_id);
-                       if (modulation == STV0900_QPSK)
-                               stv0900_write_reg(intp, ACLC2S2Q, aclc);
-                       else if (modulation == STV0900_8PSK) {
-                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                               stv0900_write_reg(intp, ACLC2S28, aclc);
-                       } else if (modulation == STV0900_16APSK) {
-                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                               stv0900_write_reg(intp, ACLC2S216A, aclc);
-                       } else if (modulation == STV0900_32APSK) {
-                               stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
-                               stv0900_write_reg(intp, ACLC2S232A, aclc);
-                       }
-
-               }
-
-               if (intp->chip_id <= 0x11) {
-                       if (intp->demod_mode != STV0900_SINGLE)
-                               stv0900_activate_s2_modcod(intp, demod);
-
-               }
-
-               stv0900_write_reg(intp, ERRCTRL1, 0x67);
-               break;
-       case STV0900_UNKNOWN_STANDARD:
-       default:
-               dprintk("%s: found unknown standard\n", __func__);
-               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
-               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
-               break;
-       }
-
-       freq1 = stv0900_read_reg(intp, CFR2);
-       freq0 = stv0900_read_reg(intp, CFR1);
-       if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
-               stv0900_write_reg(intp, SFRSTEP, 0x00);
-               stv0900_write_bits(intp, SCAN_ENABLE, 0);
-               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-               stv0900_write_reg(intp, TMGCFG2, 0xc1);
-               stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
-               blind_tun_sw = 1;
-               if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
-                       stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
-
-       }
-
-       if (intp->chip_id >= 0x20) {
-               if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
-                               (intp->srch_standard[demod] ==
-                                                       STV0900_SEARCH_DSS) ||
-                               (intp->srch_standard[demod] ==
-                                                       STV0900_AUTO_SEARCH)) {
-                       stv0900_write_reg(intp, VAVSRVIT, 0x0a);
-                       stv0900_write_reg(intp, VITSCALE, 0x0);
-               }
-       }
-
-       if (intp->chip_id < 0x20)
-               stv0900_write_reg(intp, CARHDR, 0x08);
-
-       if (intp->chip_id == 0x10)
-               stv0900_write_reg(intp, CORRELEXP, 0x0a);
-
-       stv0900_write_reg(intp, AGC2REF, 0x38);
-
-       if ((intp->chip_id >= 0x20) ||
-                       (blind_tun_sw == 1) ||
-                       (intp->symbol_rate[demod] < 10000000)) {
-               stv0900_write_reg(intp, CFRINIT1, freq1);
-               stv0900_write_reg(intp, CFRINIT0, freq0);
-               intp->bw[demod] = stv0900_carrier_width(srate,
-                                       intp->rolloff) + 10000000;
-
-               if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
-                       if (intp->srch_algo[demod] != STV0900_WARM_START) {
-                               if (intp->tuner_type[demod] == 3)
-                                       stv0900_set_tuner_auto(intp,
-                                                       intp->freq[demod],
-                                                       intp->bw[demod],
-                                                       demod);
-                               else
-                                       stv0900_set_bandwidth(fe,
-                                                       intp->bw[demod]);
-                       }
-               }
-
-               if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
-                               (intp->symbol_rate[demod] < 10000000))
-                       msleep(50);
-               else
-                       msleep(5);
-
-               stv0900_get_lock_timeout(&timed, &timef, srate,
-                                               STV0900_WARM_START);
-
-               if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
-                       stv0900_write_reg(intp, DMDISTATE, 0x1f);
-                       stv0900_write_reg(intp, CFRINIT1, freq1);
-                       stv0900_write_reg(intp, CFRINIT0, freq0);
-                       stv0900_write_reg(intp, DMDISTATE, 0x18);
-                       i = 0;
-                       while ((stv0900_get_demod_lock(intp,
-                                                       demod,
-                                                       timed / 2) == FALSE) &&
-                                               (i <= 2)) {
-                               stv0900_write_reg(intp, DMDISTATE, 0x1f);
-                               stv0900_write_reg(intp, CFRINIT1, freq1);
-                               stv0900_write_reg(intp, CFRINIT0, freq0);
-                               stv0900_write_reg(intp, DMDISTATE, 0x18);
-                               i++;
-                       }
-               }
-
-       }
-
-       if (intp->chip_id >= 0x20)
-               stv0900_write_reg(intp, CARFREQ, 0x49);
-
-       if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
-                       (intp->result[demod].standard == STV0900_DSS_STANDARD))
-               stv0900_set_viterbi_tracq(intp, demod);
-
-}
-
-static int stv0900_get_fec_lock(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod, s32 time_out)
-{
-       s32 timer = 0, lock = 0;
-
-       enum fe_stv0900_search_state dmd_state;
-
-       dprintk("%s\n", __func__);
-
-       dmd_state = stv0900_get_bits(intp, HEADER_MODE);
-
-       while ((timer < time_out) && (lock == 0)) {
-               switch (dmd_state) {
-               case STV0900_SEARCH:
-               case STV0900_PLH_DETECTED:
-               default:
-                       lock = 0;
-                       break;
-               case STV0900_DVBS2_FOUND:
-                       lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
-                       break;
-               case STV0900_DVBS_FOUND:
-                       lock = stv0900_get_bits(intp, LOCKEDVIT);
-                       break;
-               }
-
-               if (lock == 0) {
-                       msleep(10);
-                       timer += 10;
-               }
-       }
-
-       if (lock)
-               dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
-       else
-               dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
-
-       return lock;
-}
-
-static int stv0900_wait_for_lock(struct stv0900_internal *intp,
-                               enum fe_stv0900_demod_num demod,
-                               s32 dmd_timeout, s32 fec_timeout)
-{
-
-       s32 timer = 0, lock = 0;
-
-       dprintk("%s\n", __func__);
-
-       lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
-
-       if (lock)
-               lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
-
-       if (lock) {
-               lock = 0;
-
-               dprintk("%s: Timer = %d, time_out = %d\n",
-                               __func__, timer, fec_timeout);
-
-               while ((timer < fec_timeout) && (lock == 0)) {
-                       lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
-                       msleep(1);
-                       timer++;
-               }
-       }
-
-       if (lock)
-               dprintk("%s: DEMOD LOCK OK\n", __func__);
-       else
-               dprintk("%s: DEMOD LOCK FAIL\n", __func__);
-
-       if (lock)
-               return TRUE;
-       else
-               return FALSE;
-}
-
-enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
-                                               enum fe_stv0900_demod_num demod)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_tracking_standard fnd_standard;
-
-       int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
-
-       switch (hdr_mode) {
-       case 2:
-               fnd_standard = STV0900_DVBS2_STANDARD;
-               break;
-       case 3:
-               if (stv0900_get_bits(intp, DSS_DVB) == 1)
-                       fnd_standard = STV0900_DSS_STANDARD;
-               else
-                       fnd_standard = STV0900_DVBS1_STANDARD;
-
-               break;
-       default:
-               fnd_standard = STV0900_UNKNOWN_STANDARD;
-       }
-
-       dprintk("%s: standard %d\n", __func__, fnd_standard);
-
-       return fnd_standard;
-}
-
-static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32     derot,
-               rem1,
-               rem2,
-               intval1,
-               intval2;
-
-       derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
-               (stv0900_get_bits(intp, CAR_FREQ1) << 8) +
-               (stv0900_get_bits(intp, CAR_FREQ0));
-
-       derot = ge2comp(derot, 24);
-       intval1 = mclk >> 12;
-       intval2 = derot >> 12;
-       rem1 = mclk % 0x1000;
-       rem2 = derot % 0x1000;
-       derot = (intval1 * intval2) +
-               ((intval1 * rem2) >> 12) +
-               ((intval2 * rem1) >> 12);
-
-       return derot;
-}
-
-static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops *tuner_ops = NULL;
-       u32 freq = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-
-       if (tuner_ops->get_frequency) {
-               if ((tuner_ops->get_frequency(fe, &freq)) < 0)
-                       dprintk("%s: Invalid parameter\n", __func__);
-               else
-                       dprintk("%s: Frequency=%d\n", __func__, freq);
-
-       }
-
-       return freq;
-}
-
-static enum
-fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
-       struct stv0900_signal_info *result = &intp->result[demod];
-       s32     offsetFreq,
-               srate_offset;
-       int     i = 0,
-               d = demod;
-
-       u8 timing;
-
-       msleep(5);
-       if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
-               timing = stv0900_read_reg(intp, TMGREG2);
-               i = 0;
-               stv0900_write_reg(intp, SFRSTEP, 0x5c);
-
-               while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
-                       timing = stv0900_read_reg(intp, TMGREG2);
-                       msleep(5);
-                       i += 5;
-               }
-       }
-
-       result->standard = stv0900_get_standard(fe, d);
-       if (intp->tuner_type[demod] == 3)
-               result->frequency = stv0900_get_freq_auto(intp, d);
-       else
-               result->frequency = stv0900_get_tuner_freq(fe);
-
-       offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
-       result->frequency += offsetFreq;
-       result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
-       srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
-       result->symbol_rate += srate_offset;
-       result->fec = stv0900_get_vit_fec(intp, d);
-       result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
-       result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
-       result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
-       result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
-
-       dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
-
-       switch (result->standard) {
-       case STV0900_DVBS2_STANDARD:
-               result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
-               if (result->modcode <= STV0900_QPSK_910)
-                       result->modulation = STV0900_QPSK;
-               else if (result->modcode <= STV0900_8PSK_910)
-                       result->modulation = STV0900_8PSK;
-               else if (result->modcode <= STV0900_16APSK_910)
-                       result->modulation = STV0900_16APSK;
-               else if (result->modcode <= STV0900_32APSK_910)
-                       result->modulation = STV0900_32APSK;
-               else
-                       result->modulation = STV0900_UNKNOWN;
-               break;
-       case STV0900_DVBS1_STANDARD:
-       case STV0900_DSS_STANDARD:
-               result->spectrum = stv0900_get_bits(intp, IQINV);
-               result->modulation = STV0900_QPSK;
-               break;
-       default:
-               break;
-       }
-
-       if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
-                               (intp->symbol_rate[d] < 10000000)) {
-               offsetFreq = result->frequency - intp->freq[d];
-               if (intp->tuner_type[demod] == 3)
-                       intp->freq[d] = stv0900_get_freq_auto(intp, d);
-               else
-                       intp->freq[d] = stv0900_get_tuner_freq(fe);
-
-               if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
-                       range = STV0900_RANGEOK;
-               else if (ABS(offsetFreq) <=
-                               (stv0900_carrier_width(result->symbol_rate,
-                                               result->rolloff) / 2000))
-                       range = STV0900_RANGEOK;
-
-       } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
-               range = STV0900_RANGEOK;
-
-       dprintk("%s: range %d\n", __func__, range);
-
-       return range;
-}
-
-static enum
-fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
-
-       s32     srate,
-               demod_timeout,
-               fec_timeout,
-               freq1,
-               freq0;
-
-       intp->result[demod].locked = FALSE;
-
-       if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
-               srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
-               srate += stv0900_get_timing_offst(intp, srate, demod);
-               if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
-                       stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
-
-               stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
-                                       srate, STV0900_WARM_START);
-               freq1 = stv0900_read_reg(intp, CFR2);
-               freq0 = stv0900_read_reg(intp, CFR1);
-               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-               stv0900_write_bits(intp, SPECINV_CONTROL,
-                                       STV0900_IQ_FORCE_SWAPPED);
-               stv0900_write_reg(intp, DMDISTATE, 0x1c);
-               stv0900_write_reg(intp, CFRINIT1, freq1);
-               stv0900_write_reg(intp, CFRINIT0, freq0);
-               stv0900_write_reg(intp, DMDISTATE, 0x18);
-               if (stv0900_wait_for_lock(intp, demod,
-                               demod_timeout, fec_timeout) == TRUE) {
-                       intp->result[demod].locked = TRUE;
-                       signal_type = stv0900_get_signal_params(fe);
-                       stv0900_track_optimization(fe);
-               } else {
-                       stv0900_write_bits(intp, SPECINV_CONTROL,
-                                       STV0900_IQ_FORCE_NORMAL);
-                       stv0900_write_reg(intp, DMDISTATE, 0x1c);
-                       stv0900_write_reg(intp, CFRINIT1, freq1);
-                       stv0900_write_reg(intp, CFRINIT0, freq0);
-                       stv0900_write_reg(intp, DMDISTATE, 0x18);
-                       if (stv0900_wait_for_lock(intp, demod,
-                                       demod_timeout, fec_timeout) == TRUE) {
-                               intp->result[demod].locked = TRUE;
-                               signal_type = stv0900_get_signal_params(fe);
-                               stv0900_track_optimization(fe);
-                       }
-
-               }
-
-       } else
-               intp->result[demod].locked = FALSE;
-
-       return signal_type;
-}
-
-static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       u32 minagc2level = 0xffff,
-               agc2level,
-               init_freq, freq_step;
-
-       s32 i, j, nb_steps, direction;
-
-       dprintk("%s\n", __func__);
-
-       stv0900_write_reg(intp, AGC2REF, 0x38);
-       stv0900_write_bits(intp, SCAN_ENABLE, 0);
-       stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-
-       stv0900_write_bits(intp, AUTO_GUP, 1);
-       stv0900_write_bits(intp, AUTO_GLOW, 1);
-
-       stv0900_write_reg(intp, DMDT0M, 0x0);
-
-       stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
-       nb_steps = -1 + (intp->srch_range[demod] / 1000000);
-       nb_steps /= 2;
-       nb_steps = (2 * nb_steps) + 1;
-
-       if (nb_steps < 0)
-               nb_steps = 1;
-
-       direction = 1;
-
-       freq_step = (1000000 << 8) / (intp->mclk >> 8);
-
-       init_freq = 0;
-
-       for (i = 0; i < nb_steps; i++) {
-               if (direction > 0)
-                       init_freq = init_freq + (freq_step * i);
-               else
-                       init_freq = init_freq - (freq_step * i);
-
-               direction *= -1;
-               stv0900_write_reg(intp, DMDISTATE, 0x5C);
-               stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
-               stv0900_write_reg(intp, CFRINIT0, init_freq  & 0xff);
-               stv0900_write_reg(intp, DMDISTATE, 0x58);
-               msleep(10);
-               agc2level = 0;
-
-               for (j = 0; j < 10; j++)
-                       agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
-                                       | stv0900_read_reg(intp, AGC2I0);
-
-               agc2level /= 10;
-
-               if (agc2level < minagc2level)
-                       minagc2level = agc2level;
-
-       }
-
-       return (u16)minagc2level;
-}
-
-static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       int timing_lck = FALSE;
-       s32 i, timingcpt = 0,
-               direction = 1,
-               nb_steps,
-               current_step = 0,
-               tuner_freq;
-       u32 agc2_th,
-               coarse_srate = 0,
-               agc2_integr = 0,
-               currier_step = 1200;
-
-       if (intp->chip_id >= 0x30)
-               agc2_th = 0x2e00;
-       else
-               agc2_th = 0x1f00;
-
-       stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
-       stv0900_write_reg(intp, TMGCFG, 0x12);
-       stv0900_write_reg(intp, TMGTHRISE, 0xf0);
-       stv0900_write_reg(intp, TMGTHFALL, 0xe0);
-       stv0900_write_bits(intp, SCAN_ENABLE, 1);
-       stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
-       stv0900_write_reg(intp, SFRUP1, 0x83);
-       stv0900_write_reg(intp, SFRUP0, 0xc0);
-       stv0900_write_reg(intp, SFRLOW1, 0x82);
-       stv0900_write_reg(intp, SFRLOW0, 0xa0);
-       stv0900_write_reg(intp, DMDT0M, 0x0);
-       stv0900_write_reg(intp, AGC2REF, 0x50);
-
-       if (intp->chip_id >= 0x30) {
-               stv0900_write_reg(intp, CARFREQ, 0x99);
-               stv0900_write_reg(intp, SFRSTEP, 0x98);
-       } else if (intp->chip_id >= 0x20) {
-               stv0900_write_reg(intp, CARFREQ, 0x6a);
-               stv0900_write_reg(intp, SFRSTEP, 0x95);
-       } else {
-               stv0900_write_reg(intp, CARFREQ, 0xed);
-               stv0900_write_reg(intp, SFRSTEP, 0x73);
-       }
-
-       if (intp->symbol_rate[demod] <= 2000000)
-               currier_step = 1000;
-       else if (intp->symbol_rate[demod] <= 5000000)
-               currier_step = 2000;
-       else if (intp->symbol_rate[demod] <= 12000000)
-               currier_step = 3000;
-       else
-                       currier_step = 5000;
-
-       nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
-       nb_steps /= 2;
-       nb_steps = (2 * nb_steps) + 1;
-
-       if (nb_steps < 0)
-               nb_steps = 1;
-       else if (nb_steps > 10) {
-               nb_steps = 11;
-               currier_step = (intp->srch_range[demod] / 1000) / 10;
-       }
-
-       current_step = 0;
-       direction = 1;
-
-       tuner_freq = intp->freq[demod];
-
-       while ((timing_lck == FALSE) && (current_step < nb_steps)) {
-               stv0900_write_reg(intp, DMDISTATE, 0x5f);
-               stv0900_write_bits(intp, DEMOD_MODE, 0);
-
-               msleep(50);
-
-               for (i = 0; i < 10; i++) {
-                       if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
-                               timingcpt++;
-
-                       agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
-                                       stv0900_read_reg(intp, AGC2I0);
-               }
-
-               agc2_integr /= 10;
-               coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
-               current_step++;
-               direction *= -1;
-
-               dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
-                       " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
-                       tuner_freq, agc2_integr, coarse_srate, timingcpt);
-
-               if ((timingcpt >= 5) &&
-                               (agc2_integr < agc2_th) &&
-                               (coarse_srate < 55000000) &&
-                               (coarse_srate > 850000))
-                       timing_lck = TRUE;
-               else if (current_step < nb_steps) {
-                       if (direction > 0)
-                               tuner_freq += (current_step * currier_step);
-                       else
-                               tuner_freq -= (current_step * currier_step);
-
-                       if (intp->tuner_type[demod] == 3)
-                               stv0900_set_tuner_auto(intp, tuner_freq,
-                                               intp->bw[demod], demod);
-                       else
-                               stv0900_set_tuner(fe, tuner_freq,
-                                               intp->bw[demod]);
-               }
-       }
-
-       if (timing_lck == FALSE)
-               coarse_srate = 0;
-       else
-               coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
-
-       return coarse_srate;
-}
-
-static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       u32     coarse_srate,
-               coarse_freq,
-               symb,
-               symbmax,
-               symbmin,
-               symbcomp;
-
-       coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
-
-       if (coarse_srate > 3000000) {
-               symbmax = 13 * (coarse_srate / 10);
-               symbmax = (symbmax / 1000) * 65536;
-               symbmax /= (intp->mclk / 1000);
-
-               symbmin = 10 * (coarse_srate / 13);
-               symbmin = (symbmin / 1000)*65536;
-               symbmin /= (intp->mclk / 1000);
-
-               symb = (coarse_srate / 1000) * 65536;
-               symb /= (intp->mclk / 1000);
-       } else {
-               symbmax = 13 * (coarse_srate / 10);
-               symbmax = (symbmax / 100) * 65536;
-               symbmax /= (intp->mclk / 100);
-
-               symbmin = 10 * (coarse_srate / 14);
-               symbmin = (symbmin / 100) * 65536;
-               symbmin /= (intp->mclk / 100);
-
-               symb = (coarse_srate / 100) * 65536;
-               symb /= (intp->mclk / 100);
-       }
-
-       symbcomp = 13 * (coarse_srate / 10);
-               coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
-                                       | stv0900_read_reg(intp, CFR1);
-
-       if (symbcomp < intp->symbol_rate[demod])
-               coarse_srate = 0;
-       else {
-               stv0900_write_reg(intp, DMDISTATE, 0x1f);
-               stv0900_write_reg(intp, TMGCFG2, 0xc1);
-               stv0900_write_reg(intp, TMGTHRISE, 0x20);
-               stv0900_write_reg(intp, TMGTHFALL, 0x00);
-               stv0900_write_reg(intp, TMGCFG, 0xd2);
-               stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
-               stv0900_write_reg(intp, AGC2REF, 0x38);
-
-               if (intp->chip_id >= 0x30)
-                       stv0900_write_reg(intp, CARFREQ, 0x79);
-               else if (intp->chip_id >= 0x20)
-                       stv0900_write_reg(intp, CARFREQ, 0x49);
-               else
-                       stv0900_write_reg(intp, CARFREQ, 0xed);
-
-               stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
-               stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
-
-               stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
-               stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
-
-               stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
-               stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
-
-               stv0900_write_reg(intp, DMDT0M, 0x20);
-               stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
-               stv0900_write_reg(intp, CFRINIT0, coarse_freq  & 0xff);
-               stv0900_write_reg(intp, DMDISTATE, 0x15);
-       }
-
-       return coarse_srate;
-}
-
-static int stv0900_blind_search_algo(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-       u8      k_ref_tmg,
-               k_ref_tmg_max,
-               k_ref_tmg_min;
-       u32     coarse_srate,
-               agc2_th;
-       int     lock = FALSE,
-               coarse_fail = FALSE;
-       s32     demod_timeout = 500,
-               fec_timeout = 50,
-               fail_cpt,
-               i,
-               agc2_overflow;
-       u16     agc2_int;
-       u8      dstatus2;
-
-       dprintk("%s\n", __func__);
-
-       if (intp->chip_id < 0x20) {
-               k_ref_tmg_max = 233;
-               k_ref_tmg_min = 143;
-       } else {
-               k_ref_tmg_max = 110;
-               k_ref_tmg_min = 10;
-       }
-
-       if (intp->chip_id <= 0x20)
-               agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
-       else
-               agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
-
-       agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
-
-       dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
-       if (agc2_int > agc2_th)
-               return FALSE;
-
-       if (intp->chip_id == 0x10)
-               stv0900_write_reg(intp, CORRELEXP, 0xaa);
-
-       if (intp->chip_id < 0x20)
-               stv0900_write_reg(intp, CARHDR, 0x55);
-       else
-               stv0900_write_reg(intp, CARHDR, 0x20);
-
-       if (intp->chip_id <= 0x20)
-               stv0900_write_reg(intp, CARCFG, 0xc4);
-       else
-               stv0900_write_reg(intp, CARCFG, 0x6);
-
-       stv0900_write_reg(intp, RTCS2, 0x44);
-
-       if (intp->chip_id >= 0x20) {
-               stv0900_write_reg(intp, EQUALCFG, 0x41);
-               stv0900_write_reg(intp, FFECFG, 0x41);
-               stv0900_write_reg(intp, VITSCALE, 0x82);
-               stv0900_write_reg(intp, VAVSRVIT, 0x0);
-       }
-
-       k_ref_tmg = k_ref_tmg_max;
-
-       do {
-               stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
-               if (stv0900_search_srate_coarse(fe) != 0) {
-                       coarse_srate = stv0900_search_srate_fine(fe);
-
-                       if (coarse_srate != 0) {
-                               stv0900_get_lock_timeout(&demod_timeout,
-                                                       &fec_timeout,
-                                                       coarse_srate,
-                                                       STV0900_BLIND_SEARCH);
-                               lock = stv0900_get_demod_lock(intp,
-                                                       demod,
-                                                       demod_timeout);
-                       } else
-                               lock = FALSE;
-               } else {
-                       fail_cpt = 0;
-                       agc2_overflow = 0;
-
-                       for (i = 0; i < 10; i++) {
-                               agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
-                                       | stv0900_read_reg(intp, AGC2I0);
-
-                               if (agc2_int >= 0xff00)
-                                       agc2_overflow++;
-
-                               dstatus2 = stv0900_read_reg(intp, DSTATUS2);
-
-                               if (((dstatus2 & 0x1) == 0x1) &&
-                                               ((dstatus2 >> 7) == 1))
-                                       fail_cpt++;
-                       }
-
-                       if ((fail_cpt > 7) || (agc2_overflow > 7))
-                               coarse_fail = TRUE;
-
-                       lock = FALSE;
-               }
-               k_ref_tmg -= 30;
-       } while ((k_ref_tmg >= k_ref_tmg_min) &&
-                               (lock == FALSE) &&
-                               (coarse_fail == FALSE));
-
-       return lock;
-}
-
-static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-       s32 vth_reg = VTH12;
-
-       dprintk("%s\n", __func__);
-
-       stv0900_write_reg(intp, vth_reg++, 0x96);
-       stv0900_write_reg(intp, vth_reg++, 0x64);
-       stv0900_write_reg(intp, vth_reg++, 0x36);
-       stv0900_write_reg(intp, vth_reg++, 0x23);
-       stv0900_write_reg(intp, vth_reg++, 0x1e);
-       stv0900_write_reg(intp, vth_reg++, 0x19);
-}
-
-static void stv0900_set_search_standard(struct stv0900_internal *intp,
-                                       enum fe_stv0900_demod_num demod)
-{
-
-       dprintk("%s\n", __func__);
-
-       switch (intp->srch_standard[demod]) {
-       case STV0900_SEARCH_DVBS1:
-               dprintk("Search Standard = DVBS1\n");
-               break;
-       case STV0900_SEARCH_DSS:
-               dprintk("Search Standard = DSS\n");
-       case STV0900_SEARCH_DVBS2:
-               break;
-               dprintk("Search Standard = DVBS2\n");
-       case STV0900_AUTO_SEARCH:
-       default:
-               dprintk("Search Standard = AUTO\n");
-               break;
-       }
-
-       switch (intp->srch_standard[demod]) {
-       case STV0900_SEARCH_DVBS1:
-       case STV0900_SEARCH_DSS:
-               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
-               stv0900_write_bits(intp, DVBS2_ENABLE, 0);
-               stv0900_write_bits(intp, STOP_CLKVIT, 0);
-               stv0900_set_dvbs1_track_car_loop(intp,
-                                               demod,
-                                               intp->symbol_rate[demod]);
-               stv0900_write_reg(intp, CAR2CFG, 0x22);
-
-               stv0900_set_viterbi_acq(intp, demod);
-               stv0900_set_viterbi_standard(intp,
-                                       intp->srch_standard[demod],
-                                       intp->fec[demod], demod);
-
-               break;
-       case STV0900_SEARCH_DVBS2:
-               stv0900_write_bits(intp, DVBS1_ENABLE, 0);
-               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
-               stv0900_write_bits(intp, STOP_CLKVIT, 1);
-               stv0900_write_reg(intp, ACLC, 0x1a);
-               stv0900_write_reg(intp, BCLC, 0x09);
-               if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
-                       stv0900_write_reg(intp, CAR2CFG, 0x26);
-               else
-                       stv0900_write_reg(intp, CAR2CFG, 0x66);
-
-               if (intp->demod_mode != STV0900_SINGLE) {
-                       if (intp->chip_id <= 0x11)
-                               stv0900_stop_all_s2_modcod(intp, demod);
-                       else
-                               stv0900_activate_s2_modcod(intp, demod);
-
-               } else
-                       stv0900_activate_s2_modcod_single(intp, demod);
-
-               stv0900_set_viterbi_tracq(intp, demod);
-
-               break;
-       case STV0900_AUTO_SEARCH:
-       default:
-               stv0900_write_bits(intp, DVBS1_ENABLE, 1);
-               stv0900_write_bits(intp, DVBS2_ENABLE, 1);
-               stv0900_write_bits(intp, STOP_CLKVIT, 0);
-               stv0900_write_reg(intp, ACLC, 0x1a);
-               stv0900_write_reg(intp, BCLC, 0x09);
-               stv0900_set_dvbs1_track_car_loop(intp,
-                                               demod,
-                                               intp->symbol_rate[demod]);
-               if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
-                       stv0900_write_reg(intp, CAR2CFG, 0x26);
-               else
-                       stv0900_write_reg(intp, CAR2CFG, 0x66);
-
-               if (intp->demod_mode != STV0900_SINGLE) {
-                       if (intp->chip_id <= 0x11)
-                               stv0900_stop_all_s2_modcod(intp, demod);
-                       else
-                               stv0900_activate_s2_modcod(intp, demod);
-
-               } else
-                       stv0900_activate_s2_modcod_single(intp, demod);
-
-               stv0900_set_viterbi_tracq(intp, demod);
-               stv0900_set_viterbi_standard(intp,
-                                               intp->srch_standard[demod],
-                                               intp->fec[demod], demod);
-
-               break;
-       }
-}
-
-enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
-{
-       struct stv0900_state *state = fe->demodulator_priv;
-       struct stv0900_internal *intp = state->internal;
-       enum fe_stv0900_demod_num demod = state->demod;
-
-       s32 demod_timeout = 500, fec_timeout = 50;
-       s32 aq_power, agc1_power, i;
-
-       int lock = FALSE, low_sr = FALSE;
-
-       enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
-       enum fe_stv0900_search_algo algo;
-       int no_signal = FALSE;
-
-       dprintk("%s\n", __func__);
-
-       algo = intp->srch_algo[demod];
-       stv0900_write_bits(intp, RST_HWARE, 1);
-       stv0900_write_reg(intp, DMDISTATE, 0x5c);
-       if (intp->chip_id >= 0x20) {
-               if (intp->symbol_rate[demod] > 5000000)
-                       stv0900_write_reg(intp, CORRELABS, 0x9e);
-               else
-                       stv0900_write_reg(intp, CORRELABS, 0x82);
-       } else
-               stv0900_write_reg(intp, CORRELABS, 0x88);
-
-       stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
-                               intp->symbol_rate[demod],
-                               intp->srch_algo[demod]);
-
-       if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
-               intp->bw[demod] = 2 * 36000000;
-
-               stv0900_write_reg(intp, TMGCFG2, 0xc0);
-               stv0900_write_reg(intp, CORRELMANT, 0x70);
-
-               stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
-       } else {
-               stv0900_write_reg(intp, DMDT0M, 0x20);
-               stv0900_write_reg(intp, TMGCFG, 0xd2);
-
-               if (intp->symbol_rate[demod] < 2000000)
-                       stv0900_write_reg(intp, CORRELMANT, 0x63);
-               else
-                       stv0900_write_reg(intp, CORRELMANT, 0x70);
-
-               stv0900_write_reg(intp, AGC2REF, 0x38);
-
-               intp->bw[demod] =
-                               stv0900_carrier_width(intp->symbol_rate[demod],
-                                                               intp->rolloff);
-               if (intp->chip_id >= 0x20) {
-                       stv0900_write_reg(intp, KREFTMG, 0x5a);
-
-                       if (intp->srch_algo[demod] == STV0900_COLD_START) {
-                               intp->bw[demod] += 10000000;
-                               intp->bw[demod] *= 15;
-                               intp->bw[demod] /= 10;
-                       } else if (intp->srch_algo[demod] == STV0900_WARM_START)
-                               intp->bw[demod] += 10000000;
-
-               } else {
-                       stv0900_write_reg(intp, KREFTMG, 0xc1);
-                       intp->bw[demod] += 10000000;
-                       intp->bw[demod] *= 15;
-                       intp->bw[demod] /= 10;
-               }
-
-               stv0900_write_reg(intp, TMGCFG2, 0xc1);
-
-               stv0900_set_symbol_rate(intp, intp->mclk,
-                                       intp->symbol_rate[demod], demod);
-               stv0900_set_max_symbol_rate(intp, intp->mclk,
-                                       intp->symbol_rate[demod], demod);
-               stv0900_set_min_symbol_rate(intp, intp->mclk,
-                                       intp->symbol_rate[demod], demod);
-               if (intp->symbol_rate[demod] >= 10000000)
-                       low_sr = FALSE;
-               else
-                       low_sr = TRUE;
-
-       }
-
-       if (intp->tuner_type[demod] == 3)
-               stv0900_set_tuner_auto(intp, intp->freq[demod],
-                               intp->bw[demod], demod);
-       else
-               stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
-
-       agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
-                               stv0900_get_bits(intp, AGCIQ_VALUE0));
-
-       aq_power = 0;
-
-       if (agc1_power == 0) {
-               for (i = 0; i < 5; i++)
-                       aq_power += (stv0900_get_bits(intp, POWER_I) +
-                                       stv0900_get_bits(intp, POWER_Q)) / 2;
-
-               aq_power /= 5;
-       }
-
-       if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
-               intp->result[demod].locked = FALSE;
-               signal_type = STV0900_NOAGC1;
-               dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
-       } else {
-               stv0900_write_bits(intp, SPECINV_CONTROL,
-                                       intp->srch_iq_inv[demod]);
-               if (intp->chip_id <= 0x20) /*cut 2.0*/
-                       stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
-               else /*cut 3.0*/
-                       stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
-
-               stv0900_set_search_standard(intp, demod);
-
-               if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
-                       stv0900_start_search(intp, demod);
-       }
-
-       if (signal_type == STV0900_NOAGC1)
-               return signal_type;
-
-       if (intp->chip_id == 0x12) {
-               stv0900_write_bits(intp, RST_HWARE, 0);
-               msleep(3);
-               stv0900_write_bits(intp, RST_HWARE, 1);
-               stv0900_write_bits(intp, RST_HWARE, 0);
-       }
-
-       if (algo == STV0900_BLIND_SEARCH)
-               lock = stv0900_blind_search_algo(fe);
-       else if (algo == STV0900_COLD_START)
-               lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
-       else if (algo == STV0900_WARM_START)
-               lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
-
-       if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
-               if (low_sr == FALSE) {
-                       if (stv0900_check_timing_lock(intp, demod) == TRUE)
-                               lock = stv0900_sw_algo(intp, demod);
-               }
-       }
-
-       if (lock == TRUE)
-               signal_type = stv0900_get_signal_params(fe);
-
-       if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
-               stv0900_track_optimization(fe);
-               if (intp->chip_id <= 0x11) {
-                       if ((stv0900_get_standard(fe, 0) ==
-                                               STV0900_DVBS1_STANDARD) &&
-                          (stv0900_get_standard(fe, 1) ==
-                                               STV0900_DVBS1_STANDARD)) {
-                               msleep(20);
-                               stv0900_write_bits(intp, RST_HWARE, 0);
-                       } else {
-                               stv0900_write_bits(intp, RST_HWARE, 0);
-                               msleep(3);
-                               stv0900_write_bits(intp, RST_HWARE, 1);
-                               stv0900_write_bits(intp, RST_HWARE, 0);
-                       }
-
-               } else if (intp->chip_id >= 0x20) {
-                       stv0900_write_bits(intp, RST_HWARE, 0);
-                       msleep(3);
-                       stv0900_write_bits(intp, RST_HWARE, 1);
-                       stv0900_write_bits(intp, RST_HWARE, 0);
-               }
-
-               if (stv0900_wait_for_lock(intp, demod,
-                                       fec_timeout, fec_timeout) == TRUE) {
-                       lock = TRUE;
-                       intp->result[demod].locked = TRUE;
-                       if (intp->result[demod].standard ==
-                                               STV0900_DVBS2_STANDARD) {
-                               stv0900_set_dvbs2_rolloff(intp, demod);
-                               stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
-                               stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
-                               stv0900_write_reg(intp, ERRCTRL1, 0x67);
-                       } else {
-                               stv0900_write_reg(intp, ERRCTRL1, 0x75);
-                       }
-
-                       stv0900_write_reg(intp, FBERCPT4, 0);
-                       stv0900_write_reg(intp, ERRCTRL2, 0xc1);
-               } else {
-                       lock = FALSE;
-                       signal_type = STV0900_NODATA;
-                       no_signal = stv0900_check_signal_presence(intp, demod);
-
-                               intp->result[demod].locked = FALSE;
-               }
-       }
-
-       if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
-               return signal_type;
-
-       if (intp->chip_id > 0x11) {
-               intp->result[demod].locked = FALSE;
-               return signal_type;
-       }
-
-       if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
-          (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
-               signal_type = stv0900_dvbs1_acq_workaround(fe);
-
-       return signal_type;
-}
-
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
deleted file mode 100644 (file)
index ea86a56..0000000
+++ /dev/null
@@ -1,4823 +0,0 @@
-/*
-       STV0900/0903 Multistandard Broadcast Frontend driver
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-#include "stv6110x.h" /* for demodulator internal modes */
-
-#include "stv090x_reg.h"
-#include "stv090x.h"
-#include "stv090x_priv.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-
-/* internal params node */
-struct stv090x_dev {
-       /* pointer for internal params, one for each pair of demods */
-       struct stv090x_internal         *internal;
-       struct stv090x_dev              *next_dev;
-};
-
-/* first internal params */
-static struct stv090x_dev *stv090x_first_dev;
-
-/* find chip by i2c adapter and i2c address */
-static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,
-                                       u8 i2c_addr)
-{
-       struct stv090x_dev *temp_dev = stv090x_first_dev;
-
-       /*
-        Search of the last stv0900 chip or
-        find it by i2c adapter and i2c address */
-       while ((temp_dev != NULL) &&
-               ((temp_dev->internal->i2c_adap != i2c_adap) ||
-               (temp_dev->internal->i2c_addr != i2c_addr))) {
-
-               temp_dev = temp_dev->next_dev;
-       }
-
-       return temp_dev;
-}
-
-/* deallocating chip */
-static void remove_dev(struct stv090x_internal *internal)
-{
-       struct stv090x_dev *prev_dev = stv090x_first_dev;
-       struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,
-                                               internal->i2c_addr);
-
-       if (del_dev != NULL) {
-               if (del_dev == stv090x_first_dev) {
-                       stv090x_first_dev = del_dev->next_dev;
-               } else {
-                       while (prev_dev->next_dev != del_dev)
-                               prev_dev = prev_dev->next_dev;
-
-                       prev_dev->next_dev = del_dev->next_dev;
-               }
-
-               kfree(del_dev);
-       }
-}
-
-/* allocating new chip */
-static struct stv090x_dev *append_internal(struct stv090x_internal *internal)
-{
-       struct stv090x_dev *new_dev;
-       struct stv090x_dev *temp_dev;
-
-       new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);
-       if (new_dev != NULL) {
-               new_dev->internal = internal;
-               new_dev->next_dev = NULL;
-
-               /* append to list */
-               if (stv090x_first_dev == NULL) {
-                       stv090x_first_dev = new_dev;
-               } else {
-                       temp_dev = stv090x_first_dev;
-                       while (temp_dev->next_dev != NULL)
-                               temp_dev = temp_dev->next_dev;
-
-                       temp_dev->next_dev = new_dev;
-               }
-       }
-
-       return new_dev;
-}
-
-
-/* DVBS1 and DSS C/N Lookup table */
-static const struct stv090x_tab stv090x_s1cn_tab[] = {
-       {   0, 8917 }, /*  0.0dB */
-       {   5, 8801 }, /*  0.5dB */
-       {  10, 8667 }, /*  1.0dB */
-       {  15, 8522 }, /*  1.5dB */
-       {  20, 8355 }, /*  2.0dB */
-       {  25, 8175 }, /*  2.5dB */
-       {  30, 7979 }, /*  3.0dB */
-       {  35, 7763 }, /*  3.5dB */
-       {  40, 7530 }, /*  4.0dB */
-       {  45, 7282 }, /*  4.5dB */
-       {  50, 7026 }, /*  5.0dB */
-       {  55, 6781 }, /*  5.5dB */
-       {  60, 6514 }, /*  6.0dB */
-       {  65, 6241 }, /*  6.5dB */
-       {  70, 5965 }, /*  7.0dB */
-       {  75, 5690 }, /*  7.5dB */
-       {  80, 5424 }, /*  8.0dB */
-       {  85, 5161 }, /*  8.5dB */
-       {  90, 4902 }, /*  9.0dB */
-       {  95, 4654 }, /*  9.5dB */
-       { 100, 4417 }, /* 10.0dB */
-       { 105, 4186 }, /* 10.5dB */
-       { 110, 3968 }, /* 11.0dB */
-       { 115, 3757 }, /* 11.5dB */
-       { 120, 3558 }, /* 12.0dB */
-       { 125, 3366 }, /* 12.5dB */
-       { 130, 3185 }, /* 13.0dB */
-       { 135, 3012 }, /* 13.5dB */
-       { 140, 2850 }, /* 14.0dB */
-       { 145, 2698 }, /* 14.5dB */
-       { 150, 2550 }, /* 15.0dB */
-       { 160, 2283 }, /* 16.0dB */
-       { 170, 2042 }, /* 17.0dB */
-       { 180, 1827 }, /* 18.0dB */
-       { 190, 1636 }, /* 19.0dB */
-       { 200, 1466 }, /* 20.0dB */
-       { 210, 1315 }, /* 21.0dB */
-       { 220, 1181 }, /* 22.0dB */
-       { 230, 1064 }, /* 23.0dB */
-       { 240,  960 }, /* 24.0dB */
-       { 250,  869 }, /* 25.0dB */
-       { 260,  792 }, /* 26.0dB */
-       { 270,  724 }, /* 27.0dB */
-       { 280,  665 }, /* 28.0dB */
-       { 290,  616 }, /* 29.0dB */
-       { 300,  573 }, /* 30.0dB */
-       { 310,  537 }, /* 31.0dB */
-       { 320,  507 }, /* 32.0dB */
-       { 330,  483 }, /* 33.0dB */
-       { 400,  398 }, /* 40.0dB */
-       { 450,  381 }, /* 45.0dB */
-       { 500,  377 }  /* 50.0dB */
-};
-
-/* DVBS2 C/N Lookup table */
-static const struct stv090x_tab stv090x_s2cn_tab[] = {
-       { -30, 13348 }, /* -3.0dB */
-       { -20, 12640 }, /* -2d.0B */
-       { -10, 11883 }, /* -1.0dB */
-       {   0, 11101 }, /* -0.0dB */
-       {   5, 10718 }, /*  0.5dB */
-       {  10, 10339 }, /*  1.0dB */
-       {  15,  9947 }, /*  1.5dB */
-       {  20,  9552 }, /*  2.0dB */
-       {  25,  9183 }, /*  2.5dB */
-       {  30,  8799 }, /*  3.0dB */
-       {  35,  8422 }, /*  3.5dB */
-       {  40,  8062 }, /*  4.0dB */
-       {  45,  7707 }, /*  4.5dB */
-       {  50,  7353 }, /*  5.0dB */
-       {  55,  7025 }, /*  5.5dB */
-       {  60,  6684 }, /*  6.0dB */
-       {  65,  6331 }, /*  6.5dB */
-       {  70,  6036 }, /*  7.0dB */
-       {  75,  5727 }, /*  7.5dB */
-       {  80,  5437 }, /*  8.0dB */
-       {  85,  5164 }, /*  8.5dB */
-       {  90,  4902 }, /*  9.0dB */
-       {  95,  4653 }, /*  9.5dB */
-       { 100,  4408 }, /* 10.0dB */
-       { 105,  4187 }, /* 10.5dB */
-       { 110,  3961 }, /* 11.0dB */
-       { 115,  3751 }, /* 11.5dB */
-       { 120,  3558 }, /* 12.0dB */
-       { 125,  3368 }, /* 12.5dB */
-       { 130,  3191 }, /* 13.0dB */
-       { 135,  3017 }, /* 13.5dB */
-       { 140,  2862 }, /* 14.0dB */
-       { 145,  2710 }, /* 14.5dB */
-       { 150,  2565 }, /* 15.0dB */
-       { 160,  2300 }, /* 16.0dB */
-       { 170,  2058 }, /* 17.0dB */
-       { 180,  1849 }, /* 18.0dB */
-       { 190,  1663 }, /* 19.0dB */
-       { 200,  1495 }, /* 20.0dB */
-       { 210,  1349 }, /* 21.0dB */
-       { 220,  1222 }, /* 22.0dB */
-       { 230,  1110 }, /* 23.0dB */
-       { 240,  1011 }, /* 24.0dB */
-       { 250,   925 }, /* 25.0dB */
-       { 260,   853 }, /* 26.0dB */
-       { 270,   789 }, /* 27.0dB */
-       { 280,   734 }, /* 28.0dB */
-       { 290,   690 }, /* 29.0dB */
-       { 300,   650 }, /* 30.0dB */
-       { 310,   619 }, /* 31.0dB */
-       { 320,   593 }, /* 32.0dB */
-       { 330,   571 }, /* 33.0dB */
-       { 400,   498 }, /* 40.0dB */
-       { 450,   484 }, /* 45.0dB */
-       { 500,   481 }  /* 50.0dB */
-};
-
-/* RF level C/N lookup table */
-static const struct stv090x_tab stv090x_rf_tab[] = {
-       {  -5, 0xcaa1 }, /*  -5dBm */
-       { -10, 0xc229 }, /* -10dBm */
-       { -15, 0xbb08 }, /* -15dBm */
-       { -20, 0xb4bc }, /* -20dBm */
-       { -25, 0xad5a }, /* -25dBm */
-       { -30, 0xa298 }, /* -30dBm */
-       { -35, 0x98a8 }, /* -35dBm */
-       { -40, 0x8389 }, /* -40dBm */
-       { -45, 0x59be }, /* -45dBm */
-       { -50, 0x3a14 }, /* -50dBm */
-       { -55, 0x2d11 }, /* -55dBm */
-       { -60, 0x210d }, /* -60dBm */
-       { -65, 0xa14f }, /* -65dBm */
-       { -70, 0x07aa }  /* -70dBm */
-};
-
-
-static struct stv090x_reg stv0900_initval[] = {
-
-       { STV090x_OUTCFG,               0x00 },
-       { STV090x_MODECFG,              0xff },
-       { STV090x_AGCRF1CFG,            0x11 },
-       { STV090x_AGCRF2CFG,            0x13 },
-       { STV090x_TSGENERAL1X,          0x14 },
-       { STV090x_TSTTNR2,              0x21 },
-       { STV090x_TSTTNR4,              0x21 },
-       { STV090x_P2_DISTXCTL,          0x22 },
-       { STV090x_P2_F22TX,             0xc0 },
-       { STV090x_P2_F22RX,             0xc0 },
-       { STV090x_P2_DISRXCTL,          0x00 },
-       { STV090x_P2_DMDCFGMD,          0xF9 },
-       { STV090x_P2_DEMOD,             0x08 },
-       { STV090x_P2_DMDCFG3,           0xc4 },
-       { STV090x_P2_CARFREQ,           0xed },
-       { STV090x_P2_LDT,               0xd0 },
-       { STV090x_P2_LDT2,              0xb8 },
-       { STV090x_P2_TMGCFG,            0xd2 },
-       { STV090x_P2_TMGTHRISE,         0x20 },
-       { STV090x_P1_TMGCFG,            0xd2 },
-
-       { STV090x_P2_TMGTHFALL,         0x00 },
-       { STV090x_P2_FECSPY,            0x88 },
-       { STV090x_P2_FSPYDATA,          0x3a },
-       { STV090x_P2_FBERCPT4,          0x00 },
-       { STV090x_P2_FSPYBER,           0x10 },
-       { STV090x_P2_ERRCTRL1,          0x35 },
-       { STV090x_P2_ERRCTRL2,          0xc1 },
-       { STV090x_P2_CFRICFG,           0xf8 },
-       { STV090x_P2_NOSCFG,            0x1c },
-       { STV090x_P2_DMDTOM,            0x20 },
-       { STV090x_P2_CORRELMANT,        0x70 },
-       { STV090x_P2_CORRELABS,         0x88 },
-       { STV090x_P2_AGC2O,             0x5b },
-       { STV090x_P2_AGC2REF,           0x38 },
-       { STV090x_P2_CARCFG,            0xe4 },
-       { STV090x_P2_ACLC,              0x1A },
-       { STV090x_P2_BCLC,              0x09 },
-       { STV090x_P2_CARHDR,            0x08 },
-       { STV090x_P2_KREFTMG,           0xc1 },
-       { STV090x_P2_SFRUPRATIO,        0xf0 },
-       { STV090x_P2_SFRLOWRATIO,       0x70 },
-       { STV090x_P2_SFRSTEP,           0x58 },
-       { STV090x_P2_TMGCFG2,           0x01 },
-       { STV090x_P2_CAR2CFG,           0x26 },
-       { STV090x_P2_BCLC2S2Q,          0x86 },
-       { STV090x_P2_BCLC2S28,          0x86 },
-       { STV090x_P2_SMAPCOEF7,         0x77 },
-       { STV090x_P2_SMAPCOEF6,         0x85 },
-       { STV090x_P2_SMAPCOEF5,         0x77 },
-       { STV090x_P2_TSCFGL,            0x20 },
-       { STV090x_P2_DMDCFG2,           0x3b },
-       { STV090x_P2_MODCODLST0,        0xff },
-       { STV090x_P2_MODCODLST1,        0xff },
-       { STV090x_P2_MODCODLST2,        0xff },
-       { STV090x_P2_MODCODLST3,        0xff },
-       { STV090x_P2_MODCODLST4,        0xff },
-       { STV090x_P2_MODCODLST5,        0xff },
-       { STV090x_P2_MODCODLST6,        0xff },
-       { STV090x_P2_MODCODLST7,        0xcc },
-       { STV090x_P2_MODCODLST8,        0xcc },
-       { STV090x_P2_MODCODLST9,        0xcc },
-       { STV090x_P2_MODCODLSTA,        0xcc },
-       { STV090x_P2_MODCODLSTB,        0xcc },
-       { STV090x_P2_MODCODLSTC,        0xcc },
-       { STV090x_P2_MODCODLSTD,        0xcc },
-       { STV090x_P2_MODCODLSTE,        0xcc },
-       { STV090x_P2_MODCODLSTF,        0xcf },
-       { STV090x_P1_DISTXCTL,          0x22 },
-       { STV090x_P1_F22TX,             0xc0 },
-       { STV090x_P1_F22RX,             0xc0 },
-       { STV090x_P1_DISRXCTL,          0x00 },
-       { STV090x_P1_DMDCFGMD,          0xf9 },
-       { STV090x_P1_DEMOD,             0x08 },
-       { STV090x_P1_DMDCFG3,           0xc4 },
-       { STV090x_P1_DMDTOM,            0x20 },
-       { STV090x_P1_CARFREQ,           0xed },
-       { STV090x_P1_LDT,               0xd0 },
-       { STV090x_P1_LDT2,              0xb8 },
-       { STV090x_P1_TMGCFG,            0xd2 },
-       { STV090x_P1_TMGTHRISE,         0x20 },
-       { STV090x_P1_TMGTHFALL,         0x00 },
-       { STV090x_P1_SFRUPRATIO,        0xf0 },
-       { STV090x_P1_SFRLOWRATIO,       0x70 },
-       { STV090x_P1_TSCFGL,            0x20 },
-       { STV090x_P1_FECSPY,            0x88 },
-       { STV090x_P1_FSPYDATA,          0x3a },
-       { STV090x_P1_FBERCPT4,          0x00 },
-       { STV090x_P1_FSPYBER,           0x10 },
-       { STV090x_P1_ERRCTRL1,          0x35 },
-       { STV090x_P1_ERRCTRL2,          0xc1 },
-       { STV090x_P1_CFRICFG,           0xf8 },
-       { STV090x_P1_NOSCFG,            0x1c },
-       { STV090x_P1_CORRELMANT,        0x70 },
-       { STV090x_P1_CORRELABS,         0x88 },
-       { STV090x_P1_AGC2O,             0x5b },
-       { STV090x_P1_AGC2REF,           0x38 },
-       { STV090x_P1_CARCFG,            0xe4 },
-       { STV090x_P1_ACLC,              0x1A },
-       { STV090x_P1_BCLC,              0x09 },
-       { STV090x_P1_CARHDR,            0x08 },
-       { STV090x_P1_KREFTMG,           0xc1 },
-       { STV090x_P1_SFRSTEP,           0x58 },
-       { STV090x_P1_TMGCFG2,           0x01 },
-       { STV090x_P1_CAR2CFG,           0x26 },
-       { STV090x_P1_BCLC2S2Q,          0x86 },
-       { STV090x_P1_BCLC2S28,          0x86 },
-       { STV090x_P1_SMAPCOEF7,         0x77 },
-       { STV090x_P1_SMAPCOEF6,         0x85 },
-       { STV090x_P1_SMAPCOEF5,         0x77 },
-       { STV090x_P1_DMDCFG2,           0x3b },
-       { STV090x_P1_MODCODLST0,        0xff },
-       { STV090x_P1_MODCODLST1,        0xff },
-       { STV090x_P1_MODCODLST2,        0xff },
-       { STV090x_P1_MODCODLST3,        0xff },
-       { STV090x_P1_MODCODLST4,        0xff },
-       { STV090x_P1_MODCODLST5,        0xff },
-       { STV090x_P1_MODCODLST6,        0xff },
-       { STV090x_P1_MODCODLST7,        0xcc },
-       { STV090x_P1_MODCODLST8,        0xcc },
-       { STV090x_P1_MODCODLST9,        0xcc },
-       { STV090x_P1_MODCODLSTA,        0xcc },
-       { STV090x_P1_MODCODLSTB,        0xcc },
-       { STV090x_P1_MODCODLSTC,        0xcc },
-       { STV090x_P1_MODCODLSTD,        0xcc },
-       { STV090x_P1_MODCODLSTE,        0xcc },
-       { STV090x_P1_MODCODLSTF,        0xcf },
-       { STV090x_GENCFG,               0x1d },
-       { STV090x_NBITER_NF4,           0x37 },
-       { STV090x_NBITER_NF5,           0x29 },
-       { STV090x_NBITER_NF6,           0x37 },
-       { STV090x_NBITER_NF7,           0x33 },
-       { STV090x_NBITER_NF8,           0x31 },
-       { STV090x_NBITER_NF9,           0x2f },
-       { STV090x_NBITER_NF10,          0x39 },
-       { STV090x_NBITER_NF11,          0x3a },
-       { STV090x_NBITER_NF12,          0x29 },
-       { STV090x_NBITER_NF13,          0x37 },
-       { STV090x_NBITER_NF14,          0x33 },
-       { STV090x_NBITER_NF15,          0x2f },
-       { STV090x_NBITER_NF16,          0x39 },
-       { STV090x_NBITER_NF17,          0x3a },
-       { STV090x_NBITERNOERR,          0x04 },
-       { STV090x_GAINLLR_NF4,          0x0C },
-       { STV090x_GAINLLR_NF5,          0x0F },
-       { STV090x_GAINLLR_NF6,          0x11 },
-       { STV090x_GAINLLR_NF7,          0x14 },
-       { STV090x_GAINLLR_NF8,          0x17 },
-       { STV090x_GAINLLR_NF9,          0x19 },
-       { STV090x_GAINLLR_NF10,         0x20 },
-       { STV090x_GAINLLR_NF11,         0x21 },
-       { STV090x_GAINLLR_NF12,         0x0D },
-       { STV090x_GAINLLR_NF13,         0x0F },
-       { STV090x_GAINLLR_NF14,         0x13 },
-       { STV090x_GAINLLR_NF15,         0x1A },
-       { STV090x_GAINLLR_NF16,         0x1F },
-       { STV090x_GAINLLR_NF17,         0x21 },
-       { STV090x_RCCFGH,               0x20 },
-       { STV090x_P1_FECM,              0x01 }, /* disable DSS modes */
-       { STV090x_P2_FECM,              0x01 }, /* disable DSS modes */
-       { STV090x_P1_PRVIT,             0x2F }, /* disable PR 6/7 */
-       { STV090x_P2_PRVIT,             0x2F }, /* disable PR 6/7 */
-};
-
-static struct stv090x_reg stv0903_initval[] = {
-       { STV090x_OUTCFG,               0x00 },
-       { STV090x_AGCRF1CFG,            0x11 },
-       { STV090x_STOPCLK1,             0x48 },
-       { STV090x_STOPCLK2,             0x14 },
-       { STV090x_TSTTNR1,              0x27 },
-       { STV090x_TSTTNR2,              0x21 },
-       { STV090x_P1_DISTXCTL,          0x22 },
-       { STV090x_P1_F22TX,             0xc0 },
-       { STV090x_P1_F22RX,             0xc0 },
-       { STV090x_P1_DISRXCTL,          0x00 },
-       { STV090x_P1_DMDCFGMD,          0xF9 },
-       { STV090x_P1_DEMOD,             0x08 },
-       { STV090x_P1_DMDCFG3,           0xc4 },
-       { STV090x_P1_CARFREQ,           0xed },
-       { STV090x_P1_TNRCFG2,           0x82 },
-       { STV090x_P1_LDT,               0xd0 },
-       { STV090x_P1_LDT2,              0xb8 },
-       { STV090x_P1_TMGCFG,            0xd2 },
-       { STV090x_P1_TMGTHRISE,         0x20 },
-       { STV090x_P1_TMGTHFALL,         0x00 },
-       { STV090x_P1_SFRUPRATIO,        0xf0 },
-       { STV090x_P1_SFRLOWRATIO,       0x70 },
-       { STV090x_P1_TSCFGL,            0x20 },
-       { STV090x_P1_FECSPY,            0x88 },
-       { STV090x_P1_FSPYDATA,          0x3a },
-       { STV090x_P1_FBERCPT4,          0x00 },
-       { STV090x_P1_FSPYBER,           0x10 },
-       { STV090x_P1_ERRCTRL1,          0x35 },
-       { STV090x_P1_ERRCTRL2,          0xc1 },
-       { STV090x_P1_CFRICFG,           0xf8 },
-       { STV090x_P1_NOSCFG,            0x1c },
-       { STV090x_P1_DMDTOM,            0x20 },
-       { STV090x_P1_CORRELMANT,        0x70 },
-       { STV090x_P1_CORRELABS,         0x88 },
-       { STV090x_P1_AGC2O,             0x5b },
-       { STV090x_P1_AGC2REF,           0x38 },
-       { STV090x_P1_CARCFG,            0xe4 },
-       { STV090x_P1_ACLC,              0x1A },
-       { STV090x_P1_BCLC,              0x09 },
-       { STV090x_P1_CARHDR,            0x08 },
-       { STV090x_P1_KREFTMG,           0xc1 },
-       { STV090x_P1_SFRSTEP,           0x58 },
-       { STV090x_P1_TMGCFG2,           0x01 },
-       { STV090x_P1_CAR2CFG,           0x26 },
-       { STV090x_P1_BCLC2S2Q,          0x86 },
-       { STV090x_P1_BCLC2S28,          0x86 },
-       { STV090x_P1_SMAPCOEF7,         0x77 },
-       { STV090x_P1_SMAPCOEF6,         0x85 },
-       { STV090x_P1_SMAPCOEF5,         0x77 },
-       { STV090x_P1_DMDCFG2,           0x3b },
-       { STV090x_P1_MODCODLST0,        0xff },
-       { STV090x_P1_MODCODLST1,        0xff },
-       { STV090x_P1_MODCODLST2,        0xff },
-       { STV090x_P1_MODCODLST3,        0xff },
-       { STV090x_P1_MODCODLST4,        0xff },
-       { STV090x_P1_MODCODLST5,        0xff },
-       { STV090x_P1_MODCODLST6,        0xff },
-       { STV090x_P1_MODCODLST7,        0xcc },
-       { STV090x_P1_MODCODLST8,        0xcc },
-       { STV090x_P1_MODCODLST9,        0xcc },
-       { STV090x_P1_MODCODLSTA,        0xcc },
-       { STV090x_P1_MODCODLSTB,        0xcc },
-       { STV090x_P1_MODCODLSTC,        0xcc },
-       { STV090x_P1_MODCODLSTD,        0xcc },
-       { STV090x_P1_MODCODLSTE,        0xcc },
-       { STV090x_P1_MODCODLSTF,        0xcf },
-       { STV090x_GENCFG,               0x1c },
-       { STV090x_NBITER_NF4,           0x37 },
-       { STV090x_NBITER_NF5,           0x29 },
-       { STV090x_NBITER_NF6,           0x37 },
-       { STV090x_NBITER_NF7,           0x33 },
-       { STV090x_NBITER_NF8,           0x31 },
-       { STV090x_NBITER_NF9,           0x2f },
-       { STV090x_NBITER_NF10,          0x39 },
-       { STV090x_NBITER_NF11,          0x3a },
-       { STV090x_NBITER_NF12,          0x29 },
-       { STV090x_NBITER_NF13,          0x37 },
-       { STV090x_NBITER_NF14,          0x33 },
-       { STV090x_NBITER_NF15,          0x2f },
-       { STV090x_NBITER_NF16,          0x39 },
-       { STV090x_NBITER_NF17,          0x3a },
-       { STV090x_NBITERNOERR,          0x04 },
-       { STV090x_GAINLLR_NF4,          0x0C },
-       { STV090x_GAINLLR_NF5,          0x0F },
-       { STV090x_GAINLLR_NF6,          0x11 },
-       { STV090x_GAINLLR_NF7,          0x14 },
-       { STV090x_GAINLLR_NF8,          0x17 },
-       { STV090x_GAINLLR_NF9,          0x19 },
-       { STV090x_GAINLLR_NF10,         0x20 },
-       { STV090x_GAINLLR_NF11,         0x21 },
-       { STV090x_GAINLLR_NF12,         0x0D },
-       { STV090x_GAINLLR_NF13,         0x0F },
-       { STV090x_GAINLLR_NF14,         0x13 },
-       { STV090x_GAINLLR_NF15,         0x1A },
-       { STV090x_GAINLLR_NF16,         0x1F },
-       { STV090x_GAINLLR_NF17,         0x21 },
-       { STV090x_RCCFGH,               0x20 },
-       { STV090x_P1_FECM,              0x01 }, /*disable the DSS mode */
-       { STV090x_P1_PRVIT,             0x2f }  /*disable puncture rate 6/7*/
-};
-
-static struct stv090x_reg stv0900_cut20_val[] = {
-
-       { STV090x_P2_DMDCFG3,           0xe8 },
-       { STV090x_P2_DMDCFG4,           0x10 },
-       { STV090x_P2_CARFREQ,           0x38 },
-       { STV090x_P2_CARHDR,            0x20 },
-       { STV090x_P2_KREFTMG,           0x5a },
-       { STV090x_P2_SMAPCOEF7,         0x06 },
-       { STV090x_P2_SMAPCOEF6,         0x00 },
-       { STV090x_P2_SMAPCOEF5,         0x04 },
-       { STV090x_P2_NOSCFG,            0x0c },
-       { STV090x_P1_DMDCFG3,           0xe8 },
-       { STV090x_P1_DMDCFG4,           0x10 },
-       { STV090x_P1_CARFREQ,           0x38 },
-       { STV090x_P1_CARHDR,            0x20 },
-       { STV090x_P1_KREFTMG,           0x5a },
-       { STV090x_P1_SMAPCOEF7,         0x06 },
-       { STV090x_P1_SMAPCOEF6,         0x00 },
-       { STV090x_P1_SMAPCOEF5,         0x04 },
-       { STV090x_P1_NOSCFG,            0x0c },
-       { STV090x_GAINLLR_NF4,          0x21 },
-       { STV090x_GAINLLR_NF5,          0x21 },
-       { STV090x_GAINLLR_NF6,          0x20 },
-       { STV090x_GAINLLR_NF7,          0x1F },
-       { STV090x_GAINLLR_NF8,          0x1E },
-       { STV090x_GAINLLR_NF9,          0x1E },
-       { STV090x_GAINLLR_NF10,         0x1D },
-       { STV090x_GAINLLR_NF11,         0x1B },
-       { STV090x_GAINLLR_NF12,         0x20 },
-       { STV090x_GAINLLR_NF13,         0x20 },
-       { STV090x_GAINLLR_NF14,         0x20 },
-       { STV090x_GAINLLR_NF15,         0x20 },
-       { STV090x_GAINLLR_NF16,         0x20 },
-       { STV090x_GAINLLR_NF17,         0x21 },
-};
-
-static struct stv090x_reg stv0903_cut20_val[] = {
-       { STV090x_P1_DMDCFG3,           0xe8 },
-       { STV090x_P1_DMDCFG4,           0x10 },
-       { STV090x_P1_CARFREQ,           0x38 },
-       { STV090x_P1_CARHDR,            0x20 },
-       { STV090x_P1_KREFTMG,           0x5a },
-       { STV090x_P1_SMAPCOEF7,         0x06 },
-       { STV090x_P1_SMAPCOEF6,         0x00 },
-       { STV090x_P1_SMAPCOEF5,         0x04 },
-       { STV090x_P1_NOSCFG,            0x0c },
-       { STV090x_GAINLLR_NF4,          0x21 },
-       { STV090x_GAINLLR_NF5,          0x21 },
-       { STV090x_GAINLLR_NF6,          0x20 },
-       { STV090x_GAINLLR_NF7,          0x1F },
-       { STV090x_GAINLLR_NF8,          0x1E },
-       { STV090x_GAINLLR_NF9,          0x1E },
-       { STV090x_GAINLLR_NF10,         0x1D },
-       { STV090x_GAINLLR_NF11,         0x1B },
-       { STV090x_GAINLLR_NF12,         0x20 },
-       { STV090x_GAINLLR_NF13,         0x20 },
-       { STV090x_GAINLLR_NF14,         0x20 },
-       { STV090x_GAINLLR_NF15,         0x20 },
-       { STV090x_GAINLLR_NF16,         0x20 },
-       { STV090x_GAINLLR_NF17,         0x21 }
-};
-
-/* Cut 2.0 Long Frame Tracking CR loop */
-static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_QPSK_12,  0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },
-       { STV090x_QPSK_35,  0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },
-       { STV090x_QPSK_23,  0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_QPSK_34,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_QPSK_45,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_QPSK_56,  0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_QPSK_89,  0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
-       { STV090x_8PSK_35,  0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },
-       { STV090x_8PSK_23,  0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },
-       { STV090x_8PSK_34,  0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },
-       { STV090x_8PSK_56,  0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
-       { STV090x_8PSK_89,  0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
-       { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
-};
-
-/* Cut 3.0 Long Frame Tracking CR loop */
-static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_QPSK_12,  0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },
-       { STV090x_QPSK_35,  0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
-       { STV090x_QPSK_23,  0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
-       { STV090x_QPSK_34,  0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
-       { STV090x_QPSK_45,  0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
-       { STV090x_QPSK_56,  0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
-       { STV090x_QPSK_89,  0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
-       { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
-       { STV090x_8PSK_35,  0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },
-       { STV090x_8PSK_23,  0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },
-       { STV090x_8PSK_34,  0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },
-       { STV090x_8PSK_56,  0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },
-       { STV090x_8PSK_89,  0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },
-       { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }
-};
-
-/* Cut 2.0 Long Frame Tracking CR Loop */
-static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_16APSK_23,  0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },
-       { STV090x_16APSK_34,  0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },
-       { STV090x_16APSK_45,  0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
-       { STV090x_16APSK_56,  0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
-       { STV090x_16APSK_89,  0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
-       { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
-       { STV090x_32APSK_34,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
-       { STV090x_32APSK_45,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
-       { STV090x_32APSK_56,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
-       { STV090x_32APSK_89,  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
-       { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }
-};
-
-/* Cut 3.0 Long Frame Tracking CR Loop */
-static struct stv090x_long_frame_crloop        stv090x_s2_apsk_crl_cut30[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_16APSK_23,  0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },
-       { STV090x_16APSK_34,  0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },
-       { STV090x_16APSK_45,  0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
-       { STV090x_16APSK_56,  0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
-       { STV090x_16APSK_89,  0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
-       { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
-       { STV090x_32APSK_34,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
-       { STV090x_32APSK_45,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
-       { STV090x_32APSK_56,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
-       { STV090x_32APSK_89,  0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
-       { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }
-};
-
-static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_QPSK_14,  0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },
-       { STV090x_QPSK_13,  0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },
-       { STV090x_QPSK_25,  0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }
-};
-
-static struct stv090x_long_frame_crloop        stv090x_s2_lowqpsk_crl_cut30[] = {
-       /* MODCOD  2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
-       { STV090x_QPSK_14,  0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },
-       { STV090x_QPSK_13,  0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },
-       { STV090x_QPSK_25,  0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }
-};
-
-/* Cut 2.0 Short Frame Tracking CR Loop */
-static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
-       /* MODCOD         2M    5M    10M   20M   30M */
-       { STV090x_QPSK,   0x2f, 0x2e, 0x0e, 0x0e, 0x3d },
-       { STV090x_8PSK,   0x3e, 0x0e, 0x2d, 0x0d, 0x3c },
-       { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },
-       { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }
-};
-
-/* Cut 3.0 Short Frame Tracking CR Loop */
-static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
-       /* MODCOD         2M    5M    10M   20M   30M */
-       { STV090x_QPSK,   0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
-       { STV090x_8PSK,   0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
-       { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
-       { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }
-};
-
-static inline s32 comp2(s32 __x, s32 __width)
-{
-       if (__width == 32)
-               return __x;
-       else
-               return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;
-}
-
-static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
-{
-       const struct stv090x_config *config = state->config;
-       int ret;
-
-       u8 b0[] = { reg >> 8, reg & 0xff };
-       u8 buf;
-
-       struct i2c_msg msg[] = {
-               { .addr = config->address, .flags       = 0,            .buf = b0,   .len = 2 },
-               { .addr = config->address, .flags       = I2C_M_RD,     .buf = &buf, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-       if (ret != 2) {
-               if (ret != -ERESTARTSYS)
-                       dprintk(FE_ERROR, 1,
-                               "Read error, Reg=[0x%02x], Status=%d",
-                               reg, ret);
-
-               return ret < 0 ? ret : -EREMOTEIO;
-       }
-       if (unlikely(*state->verbose >= FE_DEBUGREG))
-               dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
-                       reg, buf);
-
-       return (unsigned int) buf;
-}
-
-static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)
-{
-       const struct stv090x_config *config = state->config;
-       int ret;
-       u8 buf[2 + count];
-       struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
-
-       buf[0] = reg >> 8;
-       buf[1] = reg & 0xff;
-       memcpy(&buf[2], data, count);
-
-       if (unlikely(*state->verbose >= FE_DEBUGREG)) {
-               int i;
-
-               printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
-               for (i = 0; i < count; i++)
-                       printk(" %02x", data[i]);
-               printk("\n");
-       }
-
-       ret = i2c_transfer(state->i2c, &i2c_msg, 1);
-       if (ret != 1) {
-               if (ret != -ERESTARTSYS)
-                       dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
-                               reg, data[0], count, ret);
-               return ret < 0 ? ret : -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
-{
-       return stv090x_write_regs(state, reg, &data, 1);
-}
-
-static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
-{
-       u32 reg;
-
-       /*
-        * NOTE! A lock is used as a FSM to control the state in which
-        * access is serialized between two tuners on the same demod.
-        * This has nothing to do with a lock to protect a critical section
-        * which may in some other cases be confused with protecting I/O
-        * access to the demodulator gate.
-        * In case of any error, the lock is unlocked and exit within the
-        * relevant operations themselves.
-        */
-       if (enable) {
-               if (state->config->tuner_i2c_lock)
-                       state->config->tuner_i2c_lock(&state->frontend, 1);
-               else
-                       mutex_lock(&state->internal->tuner_lock);
-       }
-
-       reg = STV090x_READ_DEMOD(state, I2CRPT);
-       if (enable) {
-               dprintk(FE_DEBUG, 1, "Enable Gate");
-               STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)
-                       goto err;
-
-       } else {
-               dprintk(FE_DEBUG, 1, "Disable Gate");
-               STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);
-               if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
-                       goto err;
-       }
-
-       if (!enable) {
-               if (state->config->tuner_i2c_lock)
-                       state->config->tuner_i2c_lock(&state->frontend, 0);
-               else
-                       mutex_unlock(&state->internal->tuner_lock);
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       if (state->config->tuner_i2c_lock)
-               state->config->tuner_i2c_lock(&state->frontend, 0);
-       else
-               mutex_unlock(&state->internal->tuner_lock);
-       return -1;
-}
-
-static void stv090x_get_lock_tmg(struct stv090x_state *state)
-{
-       switch (state->algo) {
-       case STV090x_BLIND_SEARCH:
-               dprintk(FE_DEBUG, 1, "Blind Search");
-               if (state->srate <= 1500000) {  /*10Msps< SR <=15Msps*/
-                       state->DemodTimeout = 1500;
-                       state->FecTimeout = 400;
-               } else if (state->srate <= 5000000) {  /*10Msps< SR <=15Msps*/
-                       state->DemodTimeout = 1000;
-                       state->FecTimeout = 300;
-               } else {  /*SR >20Msps*/
-                       state->DemodTimeout = 700;
-                       state->FecTimeout = 100;
-               }
-               break;
-
-       case STV090x_COLD_SEARCH:
-       case STV090x_WARM_SEARCH:
-       default:
-               dprintk(FE_DEBUG, 1, "Normal Search");
-               if (state->srate <= 1000000) {  /*SR <=1Msps*/
-                       state->DemodTimeout = 4500;
-                       state->FecTimeout = 1700;
-               } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */
-                       state->DemodTimeout = 2500;
-                       state->FecTimeout = 1100;
-               } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */
-                       state->DemodTimeout = 1000;
-                       state->FecTimeout = 550;
-               } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */
-                       state->DemodTimeout = 700;
-                       state->FecTimeout = 250;
-               } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */
-                       state->DemodTimeout = 400;
-                       state->FecTimeout = 130;
-               } else {   /*SR >20Msps*/
-                       state->DemodTimeout = 300;
-                       state->FecTimeout = 100;
-               }
-               break;
-       }
-
-       if (state->algo == STV090x_WARM_SEARCH)
-               state->DemodTimeout /= 2;
-}
-
-static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
-{
-       u32 sym;
-
-       if (srate > 60000000) {
-               sym  = (srate << 4); /* SR * 2^16 / master_clk */
-               sym /= (state->internal->mclk >> 12);
-       } else if (srate > 6000000) {
-               sym  = (srate << 6);
-               sym /= (state->internal->mclk >> 10);
-       } else {
-               sym  = (srate << 9);
-               sym /= (state->internal->mclk >> 7);
-       }
-
-       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)
-{
-       u32 sym;
-
-       srate = 105 * (srate / 100);
-       if (srate > 60000000) {
-               sym  = (srate << 4); /* SR * 2^16 / master_clk */
-               sym /= (state->internal->mclk >> 12);
-       } else if (srate > 6000000) {
-               sym  = (srate << 6);
-               sym /= (state->internal->mclk >> 10);
-       } else {
-               sym  = (srate << 9);
-               sym /= (state->internal->mclk >> 7);
-       }
-
-       if (sym < 0x7fff) {
-               if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */
-                       goto err;
-       } else {
-               if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */
-                       goto err;
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)
-{
-       u32 sym;
-
-       srate = 95 * (srate / 100);
-       if (srate > 60000000) {
-               sym  = (srate << 4); /* SR * 2^16 / master_clk */
-               sym /= (state->internal->mclk >> 12);
-       } else if (srate > 6000000) {
-               sym  = (srate << 6);
-               sym /= (state->internal->mclk >> 10);
-       } else {
-               sym  = (srate << 9);
-               sym /= (state->internal->mclk >> 7);
-       }
-
-       if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
-               goto err;
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)
-{
-       u32 ro;
-
-       switch (rolloff) {
-       case STV090x_RO_20:
-               ro = 20;
-               break;
-       case STV090x_RO_25:
-               ro = 25;
-               break;
-       case STV090x_RO_35:
-       default:
-               ro = 35;
-               break;
-       }
-
-       return srate + (srate * ro) / 100;
-}
-
-static int stv090x_set_vit_thacq(struct stv090x_state *state)
-{
-       if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)
-               goto err;
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_set_vit_thtracq(struct stv090x_state *state)
-{
-       if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)
-               goto err;
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_set_viterbi(struct stv090x_state *state)
-{
-       switch (state->search_mode) {
-       case STV090x_SEARCH_AUTO:
-               if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */
-                       goto err;
-               break;
-       case STV090x_SEARCH_DVBS1:
-               if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */
-                       goto err;
-               switch (state->fec) {
-               case STV090x_PR12:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR23:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR34:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR56:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR78:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)
-                               goto err;
-                       break;
-
-               default:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */
-                               goto err;
-                       break;
-               }
-               break;
-       case STV090x_SEARCH_DSS:
-               if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)
-                       goto err;
-               switch (state->fec) {
-               case STV090x_PR12:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR23:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
-                               goto err;
-                       break;
-
-               case STV090x_PR67:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)
-                               goto err;
-                       break;
-
-               default:
-                       if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */
-                               goto err;
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_stop_modcod(struct stv090x_state *state)
-{
-       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)
-               goto err;
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_activate_modcod(struct stv090x_state *state)
-{
-       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_activate_modcod_single(struct stv090x_state *state)
-{
-
-       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)
-               goto err;
-
-       return 0;
-
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
-{
-       u32 reg;
-
-       switch (state->demod) {
-       case STV090x_DEMODULATOR_0:
-               mutex_lock(&state->internal->demod_lock);
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               mutex_unlock(&state->internal->demod_lock);
-               break;
-
-       case STV090x_DEMODULATOR_1:
-               mutex_lock(&state->internal->demod_lock);
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               mutex_unlock(&state->internal->demod_lock);
-               break;
-
-       default:
-               dprintk(FE_ERROR, 1, "Wrong demodulator!");
-               break;
-       }
-       return 0;
-err:
-       mutex_unlock(&state->internal->demod_lock);
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_dvbs_track_crl(struct stv090x_state *state)
-{
-       if (state->internal->dev_ver >= 0x30) {
-               /* Set ACLC BCLC optimised value vs SR */
-               if (state->srate >= 15000000) {
-                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)
-                               goto err;
-               } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {
-                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)
-                               goto err;
-               } else if (state->srate < 7000000) {
-                       if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)
-                               goto err;
-               }
-
-       } else {
-               /* Cut 2.0 */
-               if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
-                       goto err;
-       }
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_delivery_search(struct stv090x_state *state)
-{
-       u32 reg;
-
-       switch (state->search_mode) {
-       case STV090x_SEARCH_DVBS1:
-       case STV090x_SEARCH_DSS:
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-
-               /* Activate Viterbi decoder in legacy search,
-                * do not use FRESVIT1, might impact VITERBI2
-                */
-               if (stv090x_vitclk_ctl(state, 0) < 0)
-                       goto err;
-
-               if (stv090x_dvbs_track_crl(state) < 0)
-                       goto err;
-
-               if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */
-                       goto err;
-
-               if (stv090x_set_vit_thacq(state) < 0)
-                       goto err;
-               if (stv090x_set_viterbi(state) < 0)
-                       goto err;
-               break;
-
-       case STV090x_SEARCH_DVBS2:
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-
-               if (stv090x_vitclk_ctl(state, 1) < 0)
-                       goto err;
-
-               if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver <= 0x20) {
-                       /* enable S2 carrier loop */
-                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
-                               goto err;
-               } else {
-                       /* > Cut 3: Stop carrier 3 */
-                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
-                               goto err;
-               }
-
-               if (state->demod_mode != STV090x_SINGLE) {
-                       /* Cut 2: enable link during search */
-                       if (stv090x_activate_modcod(state) < 0)
-                               goto err;
-               } else {
-                       /* Single demodulator
-                        * Authorize SHORT and LONG frames,
-                        * QPSK, 8PSK, 16APSK and 32APSK
-                        */
-                       if (stv090x_activate_modcod_single(state) < 0)
-                               goto err;
-               }
-
-               if (stv090x_set_vit_thtracq(state) < 0)
-                       goto err;
-               break;
-
-       case STV090x_SEARCH_AUTO:
-       default:
-               /* enable DVB-S2 and DVB-S2 in Auto MODE */
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-
-               if (stv090x_vitclk_ctl(state, 0) < 0)
-                       goto err;
-
-               if (stv090x_dvbs_track_crl(state) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver <= 0x20) {
-                       /* enable S2 carrier loop */
-                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
-                               goto err;
-               } else {
-                       /* > Cut 3: Stop carrier 3 */
-                       if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
-                               goto err;
-               }
-
-               if (state->demod_mode != STV090x_SINGLE) {
-                       /* Cut 2: enable link during search */
-                       if (stv090x_activate_modcod(state) < 0)
-                               goto err;
-               } else {
-                       /* Single demodulator
-                        * Authorize SHORT and LONG frames,
-                        * QPSK, 8PSK, 16APSK and 32APSK
-                        */
-                       if (stv090x_activate_modcod_single(state) < 0)
-                               goto err;
-               }
-
-               if (stv090x_set_vit_thacq(state) < 0)
-                       goto err;
-
-               if (stv090x_set_viterbi(state) < 0)
-                       goto err;
-               break;
-       }
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_start_search(struct stv090x_state *state)
-{
-       u32 reg, freq_abs;
-       s16 freq;
-
-       /* Reset demodulator */
-       reg = STV090x_READ_DEMOD(state, DMDISTATE);
-       STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);
-       if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
-               goto err;
-
-       if (state->internal->dev_ver <= 0x20) {
-               if (state->srate <= 5000000) {
-                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)
-                               goto err;
-
-                       /*enlarge the timing bandwidth for Low SR*/
-                       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)
-                               goto err;
-               } else {
-                       /* If the symbol rate is >5 Msps
-                       Set The carrier search up and low to auto mode */
-                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
-                               goto err;
-                       /*reduce the timing bandwidth for high SR*/
-                       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
-                               goto err;
-               }
-       } else {
-               /* >= Cut 3 */
-               if (state->srate <= 5000000) {
-                       /* enlarge the timing bandwidth for Low SR */
-                       STV090x_WRITE_DEMOD(state, RTCS2, 0x68);
-               } else {
-                       /* reduce timing bandwidth for high SR */
-                       STV090x_WRITE_DEMOD(state, RTCS2, 0x44);
-               }
-
-               /* Set CFR min and max to manual mode */
-               STV090x_WRITE_DEMOD(state, CARCFG, 0x46);
-
-               if (state->algo == STV090x_WARM_SEARCH) {
-                       /* WARM Start
-                        * CFR min = -1MHz,
-                        * CFR max = +1MHz
-                        */
-                       freq_abs  = 1000 << 16;
-                       freq_abs /= (state->internal->mclk / 1000);
-                       freq      = (s16) freq_abs;
-               } else {
-                       /* COLD Start
-                        * CFR min =- (SearchRange / 2 + 600KHz)
-                        * CFR max = +(SearchRange / 2 + 600KHz)
-                        * (600KHz for the tuner step size)
-                        */
-                       freq_abs  = (state->search_range / 2000) + 600;
-                       freq_abs  = freq_abs << 16;
-                       freq_abs /= (state->internal->mclk / 1000);
-                       freq      = (s16) freq_abs;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
-                       goto err;
-
-               freq *= -1;
-
-               if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)
-                       goto err;
-
-       }
-
-       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
-               goto err;
-
-       if (state->internal->dev_ver >= 0x20) {
-               if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
-                       goto err;
-
-               if ((state->search_mode == STV090x_SEARCH_DVBS1)        ||
-                       (state->search_mode == STV090x_SEARCH_DSS)      ||
-                       (state->search_mode == STV090x_SEARCH_AUTO)) {
-
-                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)
-                               goto err;
-               }
-       }
-
-       if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)
-               goto err;
-
-       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
-       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-               goto err;
-       reg = STV090x_READ_DEMOD(state, DMDCFG2);
-       STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);
-       if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
-               goto err;
-
-       if (state->internal->dev_ver >= 0x20) {
-               /*Frequency offset detector setting*/
-               if (state->srate < 2000000) {
-                       if (state->internal->dev_ver <= 0x20) {
-                               /* Cut 2 */
-                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
-                                       goto err;
-                       } else {
-                               /* Cut 3 */
-                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
-                                       goto err;
-                       }
-                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
-                               goto err;
-               } else if (state->srate < 10000000) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
-                               goto err;
-               } else {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
-                               goto err;
-               }
-       } else {
-               if (state->srate < 10000000) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)
-                               goto err;
-               } else {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)
-                               goto err;
-               }
-       }
-
-       switch (state->algo) {
-       case STV090x_WARM_SEARCH:
-               /* The symbol rate and the exact
-                * carrier Frequency are known
-                */
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
-                       goto err;
-               break;
-
-       case STV090x_COLD_SEARCH:
-               /* The symbol rate is known */
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
-                       goto err;
-               break;
-
-       default:
-               break;
-       }
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_get_agc2_min_level(struct stv090x_state *state)
-{
-       u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
-       s32 i, j, steps, dir;
-
-       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
-               goto err;
-       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
-       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */
-               goto err;
-       if (stv090x_set_srate(state, 1000000) < 0)
-               goto err;
-
-       steps  = state->search_range / 1000000;
-       if (steps <= 0)
-               steps = 1;
-
-       dir = 1;
-       freq_step = (1000000 * 256) / (state->internal->mclk / 256);
-       freq_init = 0;
-
-       for (i = 0; i < steps; i++) {
-               if (dir > 0)
-                       freq_init = freq_init + (freq_step * i);
-               else
-                       freq_init = freq_init - (freq_step * i);
-
-               dir *= -1;
-
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
-                       goto err;
-               msleep(10);
-
-               agc2 = 0;
-               for (j = 0; j < 10; j++) {
-                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
-                               STV090x_READ_DEMOD(state, AGC2I0);
-               }
-               agc2 /= 10;
-               if (agc2 < agc2_min)
-                       agc2_min = agc2;
-       }
-
-       return agc2_min;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)
-{
-       u8 r3, r2, r1, r0;
-       s32 srate, int_1, int_2, tmp_1, tmp_2;
-
-       r3 = STV090x_READ_DEMOD(state, SFR3);
-       r2 = STV090x_READ_DEMOD(state, SFR2);
-       r1 = STV090x_READ_DEMOD(state, SFR1);
-       r0 = STV090x_READ_DEMOD(state, SFR0);
-
-       srate = ((r3 << 24) | (r2 << 16) | (r1 <<  8) | r0);
-
-       int_1 = clk >> 16;
-       int_2 = srate >> 16;
-
-       tmp_1 = clk % 0x10000;
-       tmp_2 = srate % 0x10000;
-
-       srate = (int_1 * int_2) +
-               ((int_1 * tmp_2) >> 16) +
-               ((int_2 * tmp_1) >> 16);
-
-       return srate;
-}
-
-static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
-{
-       struct dvb_frontend *fe = &state->frontend;
-
-       int tmg_lock = 0, i;
-       s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
-       u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
-       u32 agc2th;
-
-       if (state->internal->dev_ver >= 0x30)
-               agc2th = 0x2e00;
-       else
-               agc2th = 0x1f00;
-
-       reg = STV090x_READ_DEMOD(state, DMDISTATE);
-       STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
-       if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
-               goto err;
-       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-       STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
-       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
-               goto err;
-
-       if (state->internal->dev_ver >= 0x30) {
-               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
-                       goto err;
-
-       } else if (state->internal->dev_ver >= 0x20) {
-               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
-                       goto err;
-       }
-
-       if (state->srate <= 2000000)
-               car_step = 1000;
-       else if (state->srate <= 5000000)
-               car_step = 2000;
-       else if (state->srate <= 12000000)
-               car_step = 3000;
-       else
-               car_step = 5000;
-
-       steps  = -1 + ((state->search_range / 1000) / car_step);
-       steps /= 2;
-       steps  = (2 * steps) + 1;
-       if (steps < 0)
-               steps = 1;
-       else if (steps > 10) {
-               steps = 11;
-               car_step = (state->search_range / 1000) / 10;
-       }
-       cur_step = 0;
-       dir = 1;
-       freq = state->frequency;
-
-       while ((!tmg_lock) && (cur_step < steps)) {
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
-                       goto err;
-               /* trigger acquisition */
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
-                       goto err;
-               msleep(50);
-               for (i = 0; i < 10; i++) {
-                       reg = STV090x_READ_DEMOD(state, DSTATUS);
-                       if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
-                               tmg_cpt++;
-                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
-                               STV090x_READ_DEMOD(state, AGC2I0);
-               }
-               agc2 /= 10;
-               srate_coarse = stv090x_get_srate(state, state->internal->mclk);
-               cur_step++;
-               dir *= -1;
-               if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
-                   (srate_coarse < 50000000) && (srate_coarse > 850000))
-                       tmg_lock = 1;
-               else if (cur_step < steps) {
-                       if (dir > 0)
-                               freq += cur_step * car_step;
-                       else
-                               freq -= cur_step * car_step;
-
-                       /* Setup tuner */
-                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                               goto err;
-
-                       if (state->config->tuner_set_frequency) {
-                               if (state->config->tuner_set_frequency(fe, freq) < 0)
-                                       goto err_gateoff;
-                       }
-
-                       if (state->config->tuner_set_bandwidth) {
-                               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-                                       goto err_gateoff;
-                       }
-
-                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                               goto err;
-
-                       msleep(50);
-
-                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                               goto err;
-
-                       if (state->config->tuner_get_status) {
-                               if (state->config->tuner_get_status(fe, &reg) < 0)
-                                       goto err_gateoff;
-                       }
-
-                       if (reg)
-                               dprintk(FE_DEBUG, 1, "Tuner phase locked");
-                       else
-                               dprintk(FE_DEBUG, 1, "Tuner unlocked");
-
-                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                               goto err;
-
-               }
-       }
-       if (!tmg_lock)
-               srate_coarse = 0;
-       else
-               srate_coarse = stv090x_get_srate(state, state->internal->mclk);
-
-       return srate_coarse;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
-{
-       u32 srate_coarse, freq_coarse, sym, reg;
-
-       srate_coarse = stv090x_get_srate(state, state->internal->mclk);
-       freq_coarse  = STV090x_READ_DEMOD(state, CFR2) << 8;
-       freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
-       sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
-
-       if (sym < state->srate)
-               srate_coarse = 0;
-       else {
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
-                       goto err;
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-
-               if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver >= 0x30) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
-                               goto err;
-               } else if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
-                               goto err;
-               }
-
-               if (srate_coarse > 3000000) {
-                       sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
-                       sym  = (sym / 1000) * 65536;
-                       sym /= (state->internal->mclk / 1000);
-                       if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
-                               goto err;
-                       sym  = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
-                       sym  = (sym / 1000) * 65536;
-                       sym /= (state->internal->mclk / 1000);
-                       if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
-                               goto err;
-                       sym  = (srate_coarse / 1000) * 65536;
-                       sym /= (state->internal->mclk / 1000);
-                       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
-                               goto err;
-               } else {
-                       sym  = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
-                       sym  = (sym / 100) * 65536;
-                       sym /= (state->internal->mclk / 100);
-                       if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
-                               goto err;
-                       sym  = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
-                       sym  = (sym / 100) * 65536;
-                       sym /= (state->internal->mclk / 100);
-                       if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
-                               goto err;
-                       sym  = (srate_coarse / 100) * 65536;
-                       sym /= (state->internal->mclk / 100);
-                       if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
-                               goto err;
-               }
-               if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */
-                       goto err;
-       }
-
-       return srate_coarse;
-
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
-{
-       s32 timer = 0, lock = 0;
-       u32 reg;
-       u8 stat;
-
-       while ((timer < timeout) && (!lock)) {
-               reg = STV090x_READ_DEMOD(state, DMDSTATE);
-               stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
-
-               switch (stat) {
-               case 0: /* searching */
-               case 1: /* first PLH detected */
-               default:
-                       dprintk(FE_DEBUG, 1, "Demodulator searching ..");
-                       lock = 0;
-                       break;
-               case 2: /* DVB-S2 mode */
-               case 3: /* DVB-S1/legacy mode */
-                       reg = STV090x_READ_DEMOD(state, DSTATUS);
-                       lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
-                       break;
-               }
-
-               if (!lock)
-                       msleep(10);
-               else
-                       dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");
-
-               timer += 10;
-       }
-       return lock;
-}
-
-static int stv090x_blind_search(struct stv090x_state *state)
-{
-       u32 agc2, reg, srate_coarse;
-       s32 cpt_fail, agc2_ovflw, i;
-       u8 k_ref, k_max, k_min;
-       int coarse_fail = 0;
-       int lock;
-
-       k_max = 110;
-       k_min = 10;
-
-       agc2 = stv090x_get_agc2_min_level(state);
-
-       if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {
-               lock = 0;
-       } else {
-
-               if (state->internal->dev_ver <= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
-                               goto err;
-               } else {
-                       /* > Cut 3 */
-                       if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)
-                               goto err;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */
-                               goto err;
-               }
-
-               k_ref = k_max;
-               do {
-                       if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)
-                               goto err;
-                       if (stv090x_srate_srch_coarse(state) != 0) {
-                               srate_coarse = stv090x_srate_srch_fine(state);
-                               if (srate_coarse != 0) {
-                                       stv090x_get_lock_tmg(state);
-                                       lock = stv090x_get_dmdlock(state,
-                                                       state->DemodTimeout);
-                               } else {
-                                       lock = 0;
-                               }
-                       } else {
-                               cpt_fail = 0;
-                               agc2_ovflw = 0;
-                               for (i = 0; i < 10; i++) {
-                                       agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
-                                               STV090x_READ_DEMOD(state, AGC2I0);
-                                       if (agc2 >= 0xff00)
-                                               agc2_ovflw++;
-                                       reg = STV090x_READ_DEMOD(state, DSTATUS2);
-                                       if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&
-                                           (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))
-
-                                               cpt_fail++;
-                               }
-                               if ((cpt_fail > 7) || (agc2_ovflw > 7))
-                                       coarse_fail = 1;
-
-                               lock = 0;
-                       }
-                       k_ref -= 20;
-               } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
-       }
-
-       return lock;
-
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_chk_tmg(struct stv090x_state *state)
-{
-       u32 reg;
-       s32 tmg_cpt = 0, i;
-       u8 freq, tmg_thh, tmg_thl;
-       int tmg_lock = 0;
-
-       freq = STV090x_READ_DEMOD(state, CARFREQ);
-       tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
-       tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);
-       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
-               goto err;
-
-       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-       STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */
-       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */
-               goto err;
-       msleep(10);
-
-       for (i = 0; i < 10; i++) {
-               reg = STV090x_READ_DEMOD(state, DSTATUS);
-               if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
-                       tmg_cpt++;
-               msleep(1);
-       }
-       if (tmg_cpt >= 3)
-               tmg_lock = 1;
-
-       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)
-               goto err;
-
-       return  tmg_lock;
-
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
-{
-       struct dvb_frontend *fe = &state->frontend;
-
-       u32 reg;
-       s32 car_step, steps, cur_step, dir, freq, timeout_lock;
-       int lock = 0;
-
-       if (state->srate >= 10000000)
-               timeout_lock = timeout_dmd / 3;
-       else
-               timeout_lock = timeout_dmd / 2;
-
-       lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
-       if (!lock) {
-               if (state->srate >= 10000000) {
-                       if (stv090x_chk_tmg(state)) {
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
-                                       goto err;
-                               lock = stv090x_get_dmdlock(state, timeout_dmd);
-                       } else {
-                               lock = 0;
-                       }
-               } else {
-                       if (state->srate <= 4000000)
-                               car_step = 1000;
-                       else if (state->srate <= 7000000)
-                               car_step = 2000;
-                       else if (state->srate <= 10000000)
-                               car_step = 3000;
-                       else
-                               car_step = 5000;
-
-                       steps  = (state->search_range / 1000) / car_step;
-                       steps /= 2;
-                       steps  = 2 * (steps + 1);
-                       if (steps < 0)
-                               steps = 2;
-                       else if (steps > 12)
-                               steps = 12;
-
-                       cur_step = 1;
-                       dir = 1;
-
-                       if (!lock) {
-                               freq = state->frequency;
-                               state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
-                               while ((cur_step <= steps) && (!lock)) {
-                                       if (dir > 0)
-                                               freq += cur_step * car_step;
-                                       else
-                                               freq -= cur_step * car_step;
-
-                                       /* Setup tuner */
-                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                                               goto err;
-
-                                       if (state->config->tuner_set_frequency) {
-                                               if (state->config->tuner_set_frequency(fe, freq) < 0)
-                                                       goto err_gateoff;
-                                       }
-
-                                       if (state->config->tuner_set_bandwidth) {
-                                               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-                                                       goto err_gateoff;
-                                       }
-
-                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                                               goto err;
-
-                                       msleep(50);
-
-                                       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                                               goto err;
-
-                                       if (state->config->tuner_get_status) {
-                                               if (state->config->tuner_get_status(fe, &reg) < 0)
-                                                       goto err_gateoff;
-                                       }
-
-                                       if (reg)
-                                               dprintk(FE_DEBUG, 1, "Tuner phase locked");
-                                       else
-                                               dprintk(FE_DEBUG, 1, "Tuner unlocked");
-
-                                       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                                               goto err;
-
-                                       STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
-                                       if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
-                                               goto err;
-                                       lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
-
-                                       dir *= -1;
-                                       cur_step++;
-                               }
-                       }
-               }
-       }
-
-       return lock;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)
-{
-       s32 timeout, inc, steps_max, srate, car_max;
-
-       srate = state->srate;
-       car_max = state->search_range / 1000;
-       car_max += car_max / 10;
-       car_max  = 65536 * (car_max / 2);
-       car_max /= (state->internal->mclk / 1000);
-
-       if (car_max > 0x4000)
-               car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
-
-       inc  = srate;
-       inc /= state->internal->mclk / 1000;
-       inc *= 256;
-       inc *= 256;
-       inc /= 1000;
-
-       switch (state->search_mode) {
-       case STV090x_SEARCH_DVBS1:
-       case STV090x_SEARCH_DSS:
-               inc *= 3; /* freq step = 3% of srate */
-               timeout = 20;
-               break;
-
-       case STV090x_SEARCH_DVBS2:
-               inc *= 4;
-               timeout = 25;
-               break;
-
-       case STV090x_SEARCH_AUTO:
-       default:
-               inc *= 3;
-               timeout = 25;
-               break;
-       }
-       inc /= 100;
-       if ((inc > car_max) || (inc < 0))
-               inc = car_max / 2; /* increment <= 1/8 Mclk */
-
-       timeout *= 27500; /* 27.5 Msps reference */
-       if (srate > 0)
-               timeout /= (srate / 1000);
-
-       if ((timeout > 100) || (timeout < 0))
-               timeout = 100;
-
-       steps_max = (car_max / inc) + 1; /* min steps = 3 */
-       if ((steps_max > 100) || (steps_max < 0)) {
-               steps_max = 100; /* max steps <= 100 */
-               inc = car_max / steps_max;
-       }
-       *freq_inc = inc;
-       *timeout_sw = timeout;
-       *steps = steps_max;
-
-       return 0;
-}
-
-static int stv090x_chk_signal(struct stv090x_state *state)
-{
-       s32 offst_car, agc2, car_max;
-       int no_signal;
-
-       offst_car  = STV090x_READ_DEMOD(state, CFR2) << 8;
-       offst_car |= STV090x_READ_DEMOD(state, CFR1);
-       offst_car = comp2(offst_car, 16);
-
-       agc2  = STV090x_READ_DEMOD(state, AGC2I1) << 8;
-       agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
-       car_max = state->search_range / 1000;
-
-       car_max += (car_max / 10); /* 10% margin */
-       car_max  = (65536 * car_max / 2);
-       car_max /= state->internal->mclk / 1000;
-
-       if (car_max > 0x4000)
-               car_max = 0x4000;
-
-       if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {
-               no_signal = 1;
-               dprintk(FE_DEBUG, 1, "No Signal");
-       } else {
-               no_signal = 0;
-               dprintk(FE_DEBUG, 1, "Found Signal");
-       }
-
-       return no_signal;
-}
-
-static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)
-{
-       int no_signal, lock = 0;
-       s32 cpt_step = 0, offst_freq, car_max;
-       u32 reg;
-
-       car_max  = state->search_range / 1000;
-       car_max += (car_max / 10);
-       car_max  = (65536 * car_max / 2);
-       car_max /= (state->internal->mclk / 1000);
-       if (car_max > 0x4000)
-               car_max = 0x4000;
-
-       if (zigzag)
-               offst_freq = 0;
-       else
-               offst_freq = -car_max + inc;
-
-       do {
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
-                       goto err;
-
-               reg = STV090x_READ_DEMOD(state, PDELCTRL1);
-               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */
-               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
-                       goto err;
-
-               if (zigzag) {
-                       if (offst_freq >= 0)
-                               offst_freq = -offst_freq - 2 * inc;
-                       else
-                               offst_freq = -offst_freq;
-               } else {
-                       offst_freq += 2 * inc;
-               }
-
-               cpt_step++;
-
-               lock = stv090x_get_dmdlock(state, timeout);
-               no_signal = stv090x_chk_signal(state);
-
-       } while ((!lock) &&
-                (!no_signal) &&
-                 ((offst_freq - inc) < car_max) &&
-                 ((offst_freq + inc) > -car_max) &&
-                 (cpt_step < steps_max));
-
-       reg = STV090x_READ_DEMOD(state, PDELCTRL1);
-       STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
-                       goto err;
-
-       return lock;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_sw_algo(struct stv090x_state *state)
-{
-       int no_signal, zigzag, lock = 0;
-       u32 reg;
-
-       s32 dvbs2_fly_wheel;
-       s32 inc, timeout_step, trials, steps_max;
-
-       /* get params */
-       stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);
-
-       switch (state->search_mode) {
-       case STV090x_SEARCH_DVBS1:
-       case STV090x_SEARCH_DSS:
-               /* accelerate the frequency detector */
-               if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
-                               goto err;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)
-                       goto err;
-               zigzag = 0;
-               break;
-
-       case STV090x_SEARCH_DVBS2:
-               if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
-                               goto err;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
-                       goto err;
-               zigzag = 1;
-               break;
-
-       case STV090x_SEARCH_AUTO:
-       default:
-               /* accelerate the frequency detector */
-               if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
-                               goto err;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)
-                       goto err;
-               zigzag = 0;
-               break;
-       }
-
-       trials = 0;
-       do {
-               lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);
-               no_signal = stv090x_chk_signal(state);
-               trials++;
-
-               /*run the SW search 2 times maximum*/
-               if (lock || no_signal || (trials == 2)) {
-                       /*Check if the demod is not losing lock in DVBS2*/
-                       if (state->internal->dev_ver >= 0x20) {
-                               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
-                                       goto err;
-                       }
-
-                       reg = STV090x_READ_DEMOD(state, DMDSTATE);
-                       if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {
-                               /*Check if the demod is not losing lock in DVBS2*/
-                               msleep(timeout_step);
-                               reg = STV090x_READ_DEMOD(state, DMDFLYW);
-                               dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
-                               if (dvbs2_fly_wheel < 0xd) {     /*if correct frames is decrementing */
-                                       msleep(timeout_step);
-                                       reg = STV090x_READ_DEMOD(state, DMDFLYW);
-                                       dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
-                               }
-                               if (dvbs2_fly_wheel < 0xd) {
-                                       /*FALSE lock, The demod is losing lock */
-                                       lock = 0;
-                                       if (trials < 2) {
-                                               if (state->internal->dev_ver >= 0x20) {
-                                                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
-                                                               goto err;
-                                               }
-
-                                               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
-                                                       goto err;
-                                       }
-                               }
-                       }
-               }
-       } while ((!lock) && (trials < 2) && (!no_signal));
-
-       return lock;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)
-{
-       u32 reg;
-       enum stv090x_delsys delsys;
-
-       reg = STV090x_READ_DEMOD(state, DMDSTATE);
-       if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)
-               delsys = STV090x_DVBS2;
-       else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {
-               reg = STV090x_READ_DEMOD(state, FECM);
-               if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)
-                       delsys = STV090x_DSS;
-               else
-                       delsys = STV090x_DVBS1;
-       } else {
-               delsys = STV090x_ERROR;
-       }
-
-       return delsys;
-}
-
-/* in Hz */
-static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
-{
-       s32 derot, int_1, int_2, tmp_1, tmp_2;
-
-       derot  = STV090x_READ_DEMOD(state, CFR2) << 16;
-       derot |= STV090x_READ_DEMOD(state, CFR1) <<  8;
-       derot |= STV090x_READ_DEMOD(state, CFR0);
-
-       derot = comp2(derot, 24);
-       int_1 = mclk >> 12;
-       int_2 = derot >> 12;
-
-       /* carrier_frequency = MasterClock * Reg / 2^24 */
-       tmp_1 = mclk % 0x1000;
-       tmp_2 = derot % 0x1000;
-
-       derot = (int_1 * int_2) +
-               ((int_1 * tmp_2) >> 12) +
-               ((int_2 * tmp_1) >> 12);
-
-       return derot;
-}
-
-static int stv090x_get_viterbi(struct stv090x_state *state)
-{
-       u32 reg, rate;
-
-       reg = STV090x_READ_DEMOD(state, VITCURPUN);
-       rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);
-
-       switch (rate) {
-       case 13:
-               state->fec = STV090x_PR12;
-               break;
-
-       case 18:
-               state->fec = STV090x_PR23;
-               break;
-
-       case 21:
-               state->fec = STV090x_PR34;
-               break;
-
-       case 24:
-               state->fec = STV090x_PR56;
-               break;
-
-       case 25:
-               state->fec = STV090x_PR67;
-               break;
-
-       case 26:
-               state->fec = STV090x_PR78;
-               break;
-
-       default:
-               state->fec = STV090x_PRERR;
-               break;
-       }
-
-       return 0;
-}
-
-static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)
-{
-       struct dvb_frontend *fe = &state->frontend;
-
-       u8 tmg;
-       u32 reg;
-       s32 i = 0, offst_freq;
-
-       msleep(5);
-
-       if (state->algo == STV090x_BLIND_SEARCH) {
-               tmg = STV090x_READ_DEMOD(state, TMGREG2);
-               STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);
-               while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {
-                       tmg = STV090x_READ_DEMOD(state, TMGREG2);
-                       msleep(5);
-                       i += 5;
-               }
-       }
-       state->delsys = stv090x_get_std(state);
-
-       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-               goto err;
-
-       if (state->config->tuner_get_frequency) {
-               if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
-                       goto err_gateoff;
-       }
-
-       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-               goto err;
-
-       offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
-       state->frequency += offst_freq;
-
-       if (stv090x_get_viterbi(state) < 0)
-               goto err;
-
-       reg = STV090x_READ_DEMOD(state, DMDMODCOD);
-       state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
-       state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
-       state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;
-       reg = STV090x_READ_DEMOD(state, TMGOBS);
-       state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
-       reg = STV090x_READ_DEMOD(state, FECM);
-       state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);
-
-       if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
-
-               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                       goto err;
-
-               if (state->config->tuner_get_frequency) {
-                       if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
-                               goto err_gateoff;
-               }
-
-               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                       goto err;
-
-               if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
-                       return STV090x_RANGEOK;
-               else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
-                       return STV090x_RANGEOK;
-               else
-                       return STV090x_OUTOFRANGE; /* Out of Range */
-       } else {
-               if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
-                       return STV090x_RANGEOK;
-               else
-                       return STV090x_OUTOFRANGE;
-       }
-
-       return STV090x_OUTOFRANGE;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)
-{
-       s32 offst_tmg;
-
-       offst_tmg  = STV090x_READ_DEMOD(state, TMGREG2) << 16;
-       offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) <<  8;
-       offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);
-
-       offst_tmg = comp2(offst_tmg, 24); /* 2's complement */
-       if (!offst_tmg)
-               offst_tmg = 1;
-
-       offst_tmg  = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);
-       offst_tmg /= 320;
-
-       return offst_tmg;
-}
-
-static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)
-{
-       u8 aclc = 0x29;
-       s32 i;
-       struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
-
-       if (state->internal->dev_ver == 0x20) {
-               car_loop                = stv090x_s2_crl_cut20;
-               car_loop_qpsk_low       = stv090x_s2_lowqpsk_crl_cut20;
-               car_loop_apsk_low       = stv090x_s2_apsk_crl_cut20;
-       } else {
-               /* >= Cut 3 */
-               car_loop                = stv090x_s2_crl_cut30;
-               car_loop_qpsk_low       = stv090x_s2_lowqpsk_crl_cut30;
-               car_loop_apsk_low       = stv090x_s2_apsk_crl_cut30;
-       }
-
-       if (modcod < STV090x_QPSK_12) {
-               i = 0;
-               while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))
-                       i++;
-
-               if (i >= 3)
-                       i = 2;
-
-       } else {
-               i = 0;
-               while ((i < 14) && (modcod != car_loop[i].modcod))
-                       i++;
-
-               if (i >= 14) {
-                       i = 0;
-                       while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))
-                               i++;
-
-                       if (i >= 11)
-                               i = 10;
-               }
-       }
-
-       if (modcod <= STV090x_QPSK_25) {
-               if (pilots) {
-                       if (state->srate <= 3000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_on_2;
-                       else if (state->srate <= 7000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_on_5;
-                       else if (state->srate <= 15000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_on_10;
-                       else if (state->srate <= 25000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_on_20;
-                       else
-                               aclc = car_loop_qpsk_low[i].crl_pilots_on_30;
-               } else {
-                       if (state->srate <= 3000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_off_2;
-                       else if (state->srate <= 7000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_off_5;
-                       else if (state->srate <= 15000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_off_10;
-                       else if (state->srate <= 25000000)
-                               aclc = car_loop_qpsk_low[i].crl_pilots_off_20;
-                       else
-                               aclc = car_loop_qpsk_low[i].crl_pilots_off_30;
-               }
-
-       } else if (modcod <= STV090x_8PSK_910) {
-               if (pilots) {
-                       if (state->srate <= 3000000)
-                               aclc = car_loop[i].crl_pilots_on_2;
-                       else if (state->srate <= 7000000)
-                               aclc = car_loop[i].crl_pilots_on_5;
-                       else if (state->srate <= 15000000)
-                               aclc = car_loop[i].crl_pilots_on_10;
-                       else if (state->srate <= 25000000)
-                               aclc = car_loop[i].crl_pilots_on_20;
-                       else
-                               aclc = car_loop[i].crl_pilots_on_30;
-               } else {
-                       if (state->srate <= 3000000)
-                               aclc = car_loop[i].crl_pilots_off_2;
-                       else if (state->srate <= 7000000)
-                               aclc = car_loop[i].crl_pilots_off_5;
-                       else if (state->srate <= 15000000)
-                               aclc = car_loop[i].crl_pilots_off_10;
-                       else if (state->srate <= 25000000)
-                               aclc = car_loop[i].crl_pilots_off_20;
-                       else
-                               aclc = car_loop[i].crl_pilots_off_30;
-               }
-       } else { /* 16APSK and 32APSK */
-               if (state->srate <= 3000000)
-                       aclc = car_loop_apsk_low[i].crl_pilots_on_2;
-               else if (state->srate <= 7000000)
-                       aclc = car_loop_apsk_low[i].crl_pilots_on_5;
-               else if (state->srate <= 15000000)
-                       aclc = car_loop_apsk_low[i].crl_pilots_on_10;
-               else if (state->srate <= 25000000)
-                       aclc = car_loop_apsk_low[i].crl_pilots_on_20;
-               else
-                       aclc = car_loop_apsk_low[i].crl_pilots_on_30;
-       }
-
-       return aclc;
-}
-
-static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
-{
-       struct stv090x_short_frame_crloop *short_crl = NULL;
-       s32 index = 0;
-       u8 aclc = 0x0b;
-
-       switch (state->modulation) {
-       case STV090x_QPSK:
-       default:
-               index = 0;
-               break;
-       case STV090x_8PSK:
-               index = 1;
-               break;
-       case STV090x_16APSK:
-               index = 2;
-               break;
-       case STV090x_32APSK:
-               index = 3;
-               break;
-       }
-
-       if (state->internal->dev_ver >= 0x30) {
-               /* Cut 3.0 and up */
-               short_crl = stv090x_s2_short_crl_cut30;
-       } else {
-               /* Cut 2.0 and up: we don't support cuts older than 2.0 */
-               short_crl = stv090x_s2_short_crl_cut20;
-       }
-
-       if (state->srate <= 3000000)
-               aclc = short_crl[index].crl_2;
-       else if (state->srate <= 7000000)
-               aclc = short_crl[index].crl_5;
-       else if (state->srate <= 15000000)
-               aclc = short_crl[index].crl_10;
-       else if (state->srate <= 25000000)
-               aclc = short_crl[index].crl_20;
-       else
-               aclc = short_crl[index].crl_30;
-
-       return aclc;
-}
-
-static int stv090x_optimize_track(struct stv090x_state *state)
-{
-       struct dvb_frontend *fe = &state->frontend;
-
-       enum stv090x_modcod modcod;
-
-       s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
-       u32 reg;
-
-       srate  = stv090x_get_srate(state, state->internal->mclk);
-       srate += stv090x_get_tmgoffst(state, srate);
-
-       switch (state->delsys) {
-       case STV090x_DVBS1:
-       case STV090x_DSS:
-               if (state->search_mode == STV090x_SEARCH_AUTO) {
-                       reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-                       STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-                       STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
-                       if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                               goto err;
-               }
-               reg = STV090x_READ_DEMOD(state, DEMOD);
-               STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
-               STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);
-               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver >= 0x30) {
-                       if (stv090x_get_viterbi(state) < 0)
-                               goto err;
-
-                       if (state->fec == STV090x_PR12) {
-                               if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
-                                       goto err;
-                       } else {
-                               if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
-                                       goto err;
-                       }
-               }
-
-               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
-                       goto err;
-               break;
-
-       case STV090x_DVBS2:
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-               if (state->internal->dev_ver >= 0x30) {
-                       if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
-                               goto err;
-               }
-               if (state->frame_len == STV090x_LONG_FRAME) {
-                       reg = STV090x_READ_DEMOD(state, DMDMODCOD);
-                       modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
-                       pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
-                       aclc = stv090x_optimize_carloop(state, modcod, pilots);
-                       if (modcod <= STV090x_QPSK_910) {
-                               STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);
-                       } else if (modcod <= STV090x_8PSK_910) {
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
-                                       goto err;
-                       }
-                       if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {
-                               if (modcod <= STV090x_16APSK_910) {
-                                       if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
-                                               goto err;
-                               } else {
-                                       if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                               goto err;
-                                       if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
-                                               goto err;
-                               }
-                       }
-               } else {
-                       /*Carrier loop setting for short frame*/
-                       aclc = stv090x_optimize_carloop_short(state);
-                       if (state->modulation == STV090x_QPSK) {
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)
-                                       goto err;
-                       } else if (state->modulation == STV090x_8PSK) {
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
-                                       goto err;
-                       } else if (state->modulation == STV090x_16APSK) {
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
-                                       goto err;
-                       } else if (state->modulation == STV090x_32APSK)  {
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
-                                       goto err;
-                       }
-               }
-
-               STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
-               break;
-
-       case STV090x_ERROR:
-       default:
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
-               STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-               break;
-       }
-
-       f_1 = STV090x_READ_DEMOD(state, CFR2);
-       f_0 = STV090x_READ_DEMOD(state, CFR1);
-       reg = STV090x_READ_DEMOD(state, TMGOBS);
-
-       if (state->algo == STV090x_BLIND_SEARCH) {
-               STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
-               reg = STV090x_READ_DEMOD(state, DMDCFGMD);
-               STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);
-               STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
-               if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
-                       goto err;
-
-               if (stv090x_set_srate(state, srate) < 0)
-                       goto err;
-               blind_tune = 1;
-
-               if (stv090x_dvbs_track_crl(state) < 0)
-                       goto err;
-       }
-
-       if (state->internal->dev_ver >= 0x20) {
-               if ((state->search_mode == STV090x_SEARCH_DVBS1)        ||
-                   (state->search_mode == STV090x_SEARCH_DSS)          ||
-                   (state->search_mode == STV090x_SEARCH_AUTO)) {
-
-                       if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)
-                               goto err;
-               }
-       }
-
-       if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
-               goto err;
-
-       /* AUTO tracking MODE */
-       if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)
-               goto err;
-       /* AUTO tracking MODE */
-       if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
-               goto err;
-
-       if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||
-           (state->srate < 10000000)) {
-               /* update initial carrier freq with the found freq offset */
-               if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
-                       goto err;
-               state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
-
-               if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {
-
-                       if (state->algo != STV090x_WARM_SEARCH) {
-
-                               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                                       goto err;
-
-                               if (state->config->tuner_set_bandwidth) {
-                                       if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-                                               goto err_gateoff;
-                               }
-
-                               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                                       goto err;
-
-                       }
-               }
-               if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))
-                       msleep(50); /* blind search: wait 50ms for SR stabilization */
-               else
-                       msleep(5);
-
-               stv090x_get_lock_tmg(state);
-
-               if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {
-                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
-                               goto err;
-
-                       i = 0;
-
-                       while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {
-
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
-                                       goto err;
-                               if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
-                                       goto err;
-                               i++;
-                       }
-               }
-
-       }
-
-       if (state->internal->dev_ver >= 0x20) {
-               if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
-                       goto err;
-       }
-
-       if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))
-               stv090x_set_vit_thtracq(state);
-
-       return 0;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)
-{
-       s32 timer = 0, lock = 0, stat;
-       u32 reg;
-
-       while ((timer < timeout) && (!lock)) {
-               reg = STV090x_READ_DEMOD(state, DMDSTATE);
-               stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
-
-               switch (stat) {
-               case 0: /* searching */
-               case 1: /* first PLH detected */
-               default:
-                       lock = 0;
-                       break;
-
-               case 2: /* DVB-S2 mode */
-                       reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
-                       lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);
-                       break;
-
-               case 3: /* DVB-S1/legacy mode */
-                       reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
-                       lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);
-                       break;
-               }
-               if (!lock) {
-                       msleep(10);
-                       timer += 10;
-               }
-       }
-       return lock;
-}
-
-static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)
-{
-       u32 reg;
-       s32 timer = 0;
-       int lock;
-
-       lock = stv090x_get_dmdlock(state, timeout_dmd);
-       if (lock)
-               lock = stv090x_get_feclock(state, timeout_fec);
-
-       if (lock) {
-               lock = 0;
-
-               while ((timer < timeout_fec) && (!lock)) {
-                       reg = STV090x_READ_DEMOD(state, TSSTATUS);
-                       lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);
-                       msleep(1);
-                       timer++;
-               }
-       }
-
-       return lock;
-}
-
-static int stv090x_set_s2rolloff(struct stv090x_state *state)
-{
-       u32 reg;
-
-       if (state->internal->dev_ver <= 0x20) {
-               /* rolloff to auto mode if DVBS2 */
-               reg = STV090x_READ_DEMOD(state, DEMOD);
-               STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
-               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
-                       goto err;
-       } else {
-               /* DVB-S2 rolloff to auto mode if DVBS2 */
-               reg = STV090x_READ_DEMOD(state, DEMOD);
-               STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);
-               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
-                       goto err;
-       }
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-
-static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
-{
-       struct dvb_frontend *fe = &state->frontend;
-       enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
-       u32 reg;
-       s32 agc1_power, power_iq = 0, i;
-       int lock = 0, low_sr = 0;
-
-       reg = STV090x_READ_DEMOD(state, TSCFGH);
-       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
-       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
-               goto err;
-
-       if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
-               goto err;
-
-       if (state->internal->dev_ver >= 0x20) {
-               if (state->srate > 5000000) {
-                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
-                               goto err;
-               } else {
-                       if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
-                               goto err;
-               }
-       }
-
-       stv090x_get_lock_tmg(state);
-
-       if (state->algo == STV090x_BLIND_SEARCH) {
-               state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */
-               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
-                       goto err;
-               if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */
-                       goto err;
-       } else {
-               /* known srate */
-               if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
-                       goto err;
-               if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
-                       goto err;
-
-               if (state->srate < 2000000) {
-                       /* SR < 2MSPS */
-                       if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)
-                               goto err;
-               } else {
-                       /* SR >= 2Msps */
-                       if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
-                               goto err;
-               }
-
-               if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
-                       goto err;
-
-               if (state->internal->dev_ver >= 0x20) {
-                       if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
-                               goto err;
-                       if (state->algo == STV090x_COLD_SEARCH)
-                               state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;
-                       else if (state->algo == STV090x_WARM_SEARCH)
-                               state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;
-               }
-
-               /* if cold start or warm  (Symbolrate is known)
-                * use a Narrow symbol rate scan range
-                */
-               if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */
-                       goto err;
-
-               if (stv090x_set_srate(state, state->srate) < 0)
-                       goto err;
-
-               if (stv090x_set_max_srate(state, state->internal->mclk,
-                                         state->srate) < 0)
-                       goto err;
-               if (stv090x_set_min_srate(state, state->internal->mclk,
-                                         state->srate) < 0)
-                       goto err;
-
-               if (state->srate >= 10000000)
-                       low_sr = 0;
-               else
-                       low_sr = 1;
-       }
-
-       /* Setup tuner */
-       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-               goto err;
-
-       if (state->config->tuner_set_bbgain) {
-               reg = state->config->tuner_bbgain;
-               if (reg == 0)
-                       reg = 10; /* default: 10dB */
-               if (state->config->tuner_set_bbgain(fe, reg) < 0)
-                       goto err_gateoff;
-       }
-
-       if (state->config->tuner_set_frequency) {
-               if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
-                       goto err_gateoff;
-       }
-
-       if (state->config->tuner_set_bandwidth) {
-               if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
-                       goto err_gateoff;
-       }
-
-       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-               goto err;
-
-       msleep(50);
-
-       if (state->config->tuner_get_status) {
-               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                       goto err;
-               if (state->config->tuner_get_status(fe, &reg) < 0)
-                       goto err_gateoff;
-               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                       goto err;
-
-               if (reg)
-                       dprintk(FE_DEBUG, 1, "Tuner phase locked");
-               else {
-                       dprintk(FE_DEBUG, 1, "Tuner unlocked");
-                       return STV090x_NOCARRIER;
-               }
-       }
-
-       msleep(10);
-       agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
-                               STV090x_READ_DEMOD(state, AGCIQIN0));
-
-       if (agc1_power == 0) {
-               /* If AGC1 integrator value is 0
-                * then read POWERI, POWERQ
-                */
-               for (i = 0; i < 5; i++) {
-                       power_iq += (STV090x_READ_DEMOD(state, POWERI) +
-                                    STV090x_READ_DEMOD(state, POWERQ)) >> 1;
-               }
-               power_iq /= 5;
-       }
-
-       if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
-               dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
-               lock = 0;
-               signal_state = STV090x_NOAGC1;
-       } else {
-               reg = STV090x_READ_DEMOD(state, DEMOD);
-               STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
-
-               if (state->internal->dev_ver <= 0x20) {
-                       /* rolloff to auto mode if DVBS2 */
-                       STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
-               } else {
-                       /* DVB-S2 rolloff to auto mode if DVBS2 */
-                       STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);
-               }
-               if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
-                       goto err;
-
-               if (stv090x_delivery_search(state) < 0)
-                       goto err;
-
-               if (state->algo != STV090x_BLIND_SEARCH) {
-                       if (stv090x_start_search(state) < 0)
-                               goto err;
-               }
-       }
-
-       if (signal_state == STV090x_NOAGC1)
-               return signal_state;
-
-       if (state->algo == STV090x_BLIND_SEARCH)
-               lock = stv090x_blind_search(state);
-
-       else if (state->algo == STV090x_COLD_SEARCH)
-               lock = stv090x_get_coldlock(state, state->DemodTimeout);
-
-       else if (state->algo == STV090x_WARM_SEARCH)
-               lock = stv090x_get_dmdlock(state, state->DemodTimeout);
-
-       if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
-               if (!low_sr) {
-                       if (stv090x_chk_tmg(state))
-                               lock = stv090x_sw_algo(state);
-               }
-       }
-
-       if (lock)
-               signal_state = stv090x_get_sig_params(state);
-
-       if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
-               stv090x_optimize_track(state);
-
-               if (state->internal->dev_ver >= 0x20) {
-                       /* >= Cut 2.0 :release TS reset after
-                        * demod lock and optimized Tracking
-                        */
-                       reg = STV090x_READ_DEMOD(state, TSCFGH);
-                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
-                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
-                               goto err;
-
-                       msleep(3);
-
-                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */
-                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
-                               goto err;
-
-                       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
-                       if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
-                               goto err;
-               }
-
-               lock = stv090x_get_lock(state, state->FecTimeout,
-                               state->FecTimeout);
-               if (lock) {
-                       if (state->delsys == STV090x_DVBS2) {
-                               stv090x_set_s2rolloff(state);
-
-                               reg = STV090x_READ_DEMOD(state, PDELCTRL2);
-                               STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);
-                               if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
-                                       goto err;
-                               /* Reset DVBS2 packet delinator error counter */
-                               reg = STV090x_READ_DEMOD(state, PDELCTRL2);
-                               STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);
-                               if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
-                                       goto err;
-
-                               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */
-                                       goto err;
-                       } else {
-                               if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
-                                       goto err;
-                       }
-                       /* Reset the Total packet counter */
-                       if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)
-                               goto err;
-                       /* Reset the packet Error counter2 */
-                       if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
-                               goto err;
-               } else {
-                       signal_state = STV090x_NODATA;
-                       stv090x_chk_signal(state);
-               }
-       }
-       return signal_state;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       struct dtv_frontend_properties *props = &fe->dtv_property_cache;
-
-       if (props->frequency == 0)
-               return DVBFE_ALGO_SEARCH_INVALID;
-
-       state->delsys = props->delivery_system;
-       state->frequency = props->frequency;
-       state->srate = props->symbol_rate;
-       state->search_mode = STV090x_SEARCH_AUTO;
-       state->algo = STV090x_COLD_SEARCH;
-       state->fec = STV090x_PRERR;
-       if (state->srate > 10000000) {
-               dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
-               state->search_range = 10000000;
-       } else {
-               dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
-               state->search_range = 5000000;
-       }
-
-       if (stv090x_algo(state) == STV090x_RANGEOK) {
-               dprintk(FE_DEBUG, 1, "Search success!");
-               return DVBFE_ALGO_SEARCH_SUCCESS;
-       } else {
-               dprintk(FE_DEBUG, 1, "Search failed!");
-               return DVBFE_ALGO_SEARCH_FAILED;
-       }
-
-       return DVBFE_ALGO_SEARCH_ERROR;
-}
-
-static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg, dstatus;
-       u8 search_state;
-
-       *status = 0;
-
-       dstatus = STV090x_READ_DEMOD(state, DSTATUS);
-       if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD))
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
-
-       reg = STV090x_READ_DEMOD(state, DMDSTATE);
-       search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
-
-       switch (search_state) {
-       case 0: /* searching */
-       case 1: /* first PLH detected */
-       default:
-               dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
-               break;
-
-       case 2: /* DVB-S2 mode */
-               dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
-               if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
-                       reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
-                       if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
-                               *status |= FE_HAS_VITERBI;
-                               reg = STV090x_READ_DEMOD(state, TSSTATUS);
-                               if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))
-                                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-                       }
-               }
-               break;
-
-       case 3: /* DVB-S1/legacy mode */
-               dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
-               if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
-                       reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
-                       if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
-                               *status |= FE_HAS_VITERBI;
-                               reg = STV090x_READ_DEMOD(state, TSSTATUS);
-                               if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))
-                                       *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-                       }
-               }
-               break;
-       }
-
-       return 0;
-}
-
-static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-
-       s32 count_4, count_3, count_2, count_1, count_0, count;
-       u32 reg, h, m, l;
-       enum fe_status status;
-
-       stv090x_read_status(fe, &status);
-       if (!(status & FE_HAS_LOCK)) {
-               *per = 1 << 23; /* Max PER */
-       } else {
-               /* Counter 2 */
-               reg = STV090x_READ_DEMOD(state, ERRCNT22);
-               h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);
-
-               reg = STV090x_READ_DEMOD(state, ERRCNT21);
-               m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);
-
-               reg = STV090x_READ_DEMOD(state, ERRCNT20);
-               l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);
-
-               *per = ((h << 16) | (m << 8) | l);
-
-               count_4 = STV090x_READ_DEMOD(state, FBERCPT4);
-               count_3 = STV090x_READ_DEMOD(state, FBERCPT3);
-               count_2 = STV090x_READ_DEMOD(state, FBERCPT2);
-               count_1 = STV090x_READ_DEMOD(state, FBERCPT1);
-               count_0 = STV090x_READ_DEMOD(state, FBERCPT0);
-
-               if ((!count_4) && (!count_3)) {
-                       count  = (count_2 & 0xff) << 16;
-                       count |= (count_1 & 0xff) <<  8;
-                       count |=  count_0 & 0xff;
-               } else {
-                       count = 1 << 24;
-               }
-               if (count == 0)
-                       *per = 1;
-       }
-       if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
-{
-       int res = 0;
-       int min = 0, med;
-
-       if ((val >= tab[min].read && val < tab[max].read) ||
-           (val >= tab[max].read && val < tab[min].read)) {
-               while ((max - min) > 1) {
-                       med = (max + min) / 2;
-                       if ((val >= tab[min].read && val < tab[med].read) ||
-                           (val >= tab[med].read && val < tab[min].read))
-                               max = med;
-                       else
-                               min = med;
-               }
-               res = ((val - tab[min].read) *
-                      (tab[max].real - tab[min].real) /
-                      (tab[max].read - tab[min].read)) +
-                       tab[min].real;
-       } else {
-               if (tab[min].read < tab[max].read) {
-                       if (val < tab[min].read)
-                               res = tab[min].real;
-                       else if (val >= tab[max].read)
-                               res = tab[max].real;
-               } else {
-                       if (val >= tab[min].read)
-                               res = tab[min].real;
-                       else if (val < tab[max].read)
-                               res = tab[max].real;
-               }
-       }
-
-       return res;
-}
-
-static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg;
-       s32 agc_0, agc_1, agc;
-       s32 str;
-
-       reg = STV090x_READ_DEMOD(state, AGCIQIN1);
-       agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
-       reg = STV090x_READ_DEMOD(state, AGCIQIN0);
-       agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
-       agc = MAKEWORD16(agc_1, agc_0);
-
-       str = stv090x_table_lookup(stv090x_rf_tab,
-               ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
-       if (agc > stv090x_rf_tab[0].read)
-               str = 0;
-       else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
-               str = -100;
-       *strength = (str + 100) * 0xFFFF / 100;
-
-       return 0;
-}
-
-static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg_0, reg_1, reg, i;
-       s32 val_0, val_1, val = 0;
-       u8 lock_f;
-       s32 div;
-       u32 last;
-
-       switch (state->delsys) {
-       case STV090x_DVBS2:
-               reg = STV090x_READ_DEMOD(state, DSTATUS);
-               lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
-               if (lock_f) {
-                       msleep(5);
-                       for (i = 0; i < 16; i++) {
-                               reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
-                               val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
-                               reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
-                               val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
-                               val  += MAKEWORD16(val_1, val_0);
-                               msleep(1);
-                       }
-                       val /= 16;
-                       last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
-                       div = stv090x_s2cn_tab[0].read -
-                             stv090x_s2cn_tab[last].read;
-                       *cnr = 0xFFFF - ((val * 0xFFFF) / div);
-               }
-               break;
-
-       case STV090x_DVBS1:
-       case STV090x_DSS:
-               reg = STV090x_READ_DEMOD(state, DSTATUS);
-               lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
-               if (lock_f) {
-                       msleep(5);
-                       for (i = 0; i < 16; i++) {
-                               reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
-                               val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
-                               reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
-                               val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
-                               val  += MAKEWORD16(val_1, val_0);
-                               msleep(1);
-                       }
-                       val /= 16;
-                       last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
-                       div = stv090x_s1cn_tab[0].read -
-                             stv090x_s1cn_tab[last].read;
-                       *cnr = 0xFFFF - ((val * 0xFFFF) / div);
-               }
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg;
-
-       reg = STV090x_READ_DEMOD(state, DISTXCTL);
-       switch (tone) {
-       case SEC_TONE_ON:
-               STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
-               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-                       goto err;
-               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
-               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-                       goto err;
-               break;
-
-       case SEC_TONE_OFF:
-               STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
-               STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
-               if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-                       goto err;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-
-static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg, idle = 0, fifo_full = 1;
-       int i;
-
-       reg = STV090x_READ_DEMOD(state, DISTXCTL);
-
-       STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
-               (state->config->diseqc_envelope_mode) ? 4 : 2);
-       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       for (i = 0; i < cmd->msg_len; i++) {
-
-               while (fifo_full) {
-                       reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
-                       fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
-               }
-
-               if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)
-                       goto err;
-       }
-       reg = STV090x_READ_DEMOD(state, DISTXCTL);
-       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       i = 0;
-
-       while ((!idle) && (i < 10)) {
-               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
-               idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
-               msleep(10);
-               i++;
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg, idle = 0, fifo_full = 1;
-       u8 mode, value;
-       int i;
-
-       reg = STV090x_READ_DEMOD(state, DISTXCTL);
-
-       if (burst == SEC_MINI_A) {
-               mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
-               value = 0x00;
-       } else {
-               mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
-               value = 0xFF;
-       }
-
-       STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);
-       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-       STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       while (fifo_full) {
-               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
-               fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
-       }
-
-       if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)
-               goto err;
-
-       reg = STV090x_READ_DEMOD(state, DISTXCTL);
-       STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
-       if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
-               goto err;
-
-       i = 0;
-
-       while ((!idle) && (i < 10)) {
-               reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
-               idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
-               msleep(10);
-               i++;
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg = 0, i = 0, rx_end = 0;
-
-       while ((rx_end != 1) && (i < 10)) {
-               msleep(10);
-               i++;
-               reg = STV090x_READ_DEMOD(state, DISRX_ST0);
-               rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);
-       }
-
-       if (rx_end) {
-               reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);
-               for (i = 0; i < reply->msg_len; i++)
-                       reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);
-       }
-
-       return 0;
-}
-
-static int stv090x_sleep(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg;
-       u8 full_standby = 0;
-
-       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-               goto err;
-
-       if (state->config->tuner_sleep) {
-               if (state->config->tuner_sleep(fe) < 0)
-                       goto err_gateoff;
-       }
-
-       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-               goto err;
-
-       dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
-               state->device == STV0900 ? "STV0900" : "STV0903",
-               state->demod);
-
-       mutex_lock(&state->internal->demod_lock);
-
-       switch (state->demod) {
-       case STV090x_DEMODULATOR_0:
-               /* power off ADC 1 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
-               STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
-                       goto err;
-               /* power off DiSEqC 1 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR2);
-               STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
-                       goto err;
-
-               /* check whether path 2 is already sleeping, that is when
-                  ADC2 is off */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
-               if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
-                       full_standby = 1;
-
-               /* stop clocks */
-               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
-               /* packet delineator 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
-               /* ADC 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
-               /* FEC clock is shared between the two paths, only stop it
-                  when full standby is possible */
-               if (full_standby)
-                       STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-                       goto err;
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               /* sampling 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
-               /* viterbi 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
-               /* TS clock is shared between the two paths, only stop it
-                  when full standby is possible */
-               if (full_standby)
-                       STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_DEMODULATOR_1:
-               /* power off ADC 2 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
-               STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
-                       goto err;
-               /* power off DiSEqC 2 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR4);
-               STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
-                       goto err;
-
-               /* check whether path 1 is already sleeping, that is when
-                  ADC1 is off */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
-               if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
-                       full_standby = 1;
-
-               /* stop clocks */
-               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
-               /* packet delineator 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
-               /* ADC 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
-               /* FEC clock is shared between the two paths, only stop it
-                  when full standby is possible */
-               if (full_standby)
-                       STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-                       goto err;
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               /* sampling 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
-               /* viterbi 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
-               /* TS clock is shared between the two paths, only stop it
-                  when full standby is possible */
-               if (full_standby)
-                       STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               break;
-
-       default:
-               dprintk(FE_ERROR, 1, "Wrong demodulator!");
-               break;
-       }
-
-       if (full_standby) {
-               /* general power off */
-               reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
-               STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
-               if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
-                       goto err;
-       }
-
-       mutex_unlock(&state->internal->demod_lock);
-       return 0;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       mutex_unlock(&state->internal->demod_lock);
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_wakeup(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u32 reg;
-
-       dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
-               state->device == STV0900 ? "STV0900" : "STV0903",
-               state->demod);
-
-       mutex_lock(&state->internal->demod_lock);
-
-       /* general power on */
-       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
-       STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
-       if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
-               goto err;
-
-       switch (state->demod) {
-       case STV090x_DEMODULATOR_0:
-               /* power on ADC 1 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR1);
-               STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
-                       goto err;
-               /* power on DiSEqC 1 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR2);
-               STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
-                       goto err;
-
-               /* activate clocks */
-               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
-               /* packet delineator 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
-               /* ADC 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
-               /* FEC clock */
-               STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-                       goto err;
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               /* sampling 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
-               /* viterbi 1 clock */
-               STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
-               /* TS clock */
-               STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_DEMODULATOR_1:
-               /* power on ADC 2 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR3);
-               STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
-                       goto err;
-               /* power on DiSEqC 2 */
-               reg = stv090x_read_reg(state, STV090x_TSTTNR4);
-               STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
-               if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
-                       goto err;
-
-               /* activate clocks */
-               reg = stv090x_read_reg(state, STV090x_STOPCLK1);
-               /* packet delineator 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
-               /* ADC 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
-               /* FEC clock */
-               STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
-                       goto err;
-               reg = stv090x_read_reg(state, STV090x_STOPCLK2);
-               /* sampling 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
-               /* viterbi 2 clock */
-               STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
-               /* TS clock */
-               STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
-               if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
-                       goto err;
-               break;
-
-       default:
-               dprintk(FE_ERROR, 1, "Wrong demodulator!");
-               break;
-       }
-
-       mutex_unlock(&state->internal->demod_lock);
-       return 0;
-err:
-       mutex_unlock(&state->internal->demod_lock);
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static void stv090x_release(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-
-       state->internal->num_used--;
-       if (state->internal->num_used <= 0) {
-
-               dprintk(FE_ERROR, 1, "Actually removing");
-
-               remove_dev(state->internal);
-               kfree(state->internal);
-       }
-
-       kfree(state);
-}
-
-static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)
-{
-       u32 reg = 0;
-
-       reg = stv090x_read_reg(state, STV090x_GENCFG);
-
-       switch (ldpc_mode) {
-       case STV090x_DUAL:
-       default:
-               if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {
-                       /* set LDPC to dual mode */
-                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)
-                               goto err;
-
-                       state->demod_mode = STV090x_DUAL;
-
-                       reg = stv090x_read_reg(state, STV090x_TSTRES0);
-                       STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
-                       if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
-                               goto err;
-                       STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
-                       if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
-                               goto err;
-
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
-                               goto err;
-
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
-                               goto err;
-
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
-                               goto err;
-                       if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
-                               goto err;
-               }
-               break;
-
-       case STV090x_SINGLE:
-               if (stv090x_stop_modcod(state) < 0)
-                       goto err;
-               if (stv090x_activate_modcod_single(state) < 0)
-                       goto err;
-
-               if (state->demod == STV090x_DEMODULATOR_1) {
-                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */
-                               goto err;
-               } else {
-                       if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */
-                               goto err;
-               }
-
-               reg = stv090x_read_reg(state, STV090x_TSTRES0);
-               STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
-               if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
-                       goto err;
-               STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
-               if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
-                       goto err;
-
-               reg = STV090x_READ_DEMOD(state, PDELCTRL1);
-               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);
-               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
-                       goto err;
-               STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);
-               if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
-                       goto err;
-               break;
-       }
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-/* return (Hz), clk in Hz*/
-static u32 stv090x_get_mclk(struct stv090x_state *state)
-{
-       const struct stv090x_config *config = state->config;
-       u32 div, reg;
-       u8 ratio;
-
-       div = stv090x_read_reg(state, STV090x_NCOARSE);
-       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
-       ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;
-
-       return (div + 1) * config->xtal / ratio; /* kHz */
-}
-
-static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
-{
-       const struct stv090x_config *config = state->config;
-       u32 reg, div, clk_sel;
-
-       reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
-       clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);
-
-       div = ((clk_sel * mclk) / config->xtal) - 1;
-
-       reg = stv090x_read_reg(state, STV090x_NCOARSE);
-       STV090x_SETFIELD(reg, M_DIV_FIELD, div);
-       if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
-               goto err;
-
-       state->internal->mclk = stv090x_get_mclk(state);
-
-       /*Set the DiseqC frequency to 22KHz */
-       div = state->internal->mclk / 704000;
-       if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
-               goto err;
-       if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_set_tspath(struct stv090x_state *state)
-{
-       u32 reg;
-
-       if (state->internal->dev_ver >= 0x20) {
-               switch (state->config->ts1_mode) {
-               case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               case STV090x_TSMODE_DVBCI:
-                       switch (state->config->ts2_mode) {
-                       case STV090x_TSMODE_SERIAL_PUNCTURED:
-                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       default:
-                               stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
-                               break;
-
-                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-                       case STV090x_TSMODE_DVBCI:
-                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */
-                                       goto err;
-                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
-                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
-                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
-                                       goto err;
-                               reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
-                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
-                               if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
-                                       goto err;
-                               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
-                                       goto err;
-                               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
-                                       goto err;
-                               break;
-                       }
-                       break;
-
-               case STV090x_TSMODE_SERIAL_PUNCTURED:
-               case STV090x_TSMODE_SERIAL_CONTINUOUS:
-               default:
-                       switch (state->config->ts2_mode) {
-                       case STV090x_TSMODE_SERIAL_PUNCTURED:
-                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       default:
-                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
-                                       goto err;
-                               break;
-
-                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-                       case STV090x_TSMODE_DVBCI:
-                               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)
-                                       goto err;
-                               break;
-                       }
-                       break;
-               }
-       } else {
-               switch (state->config->ts1_mode) {
-               case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               case STV090x_TSMODE_DVBCI:
-                       switch (state->config->ts2_mode) {
-                       case STV090x_TSMODE_SERIAL_PUNCTURED:
-                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       default:
-                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
-                               break;
-
-                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-                       case STV090x_TSMODE_DVBCI:
-                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);
-                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
-                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
-                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
-                                       goto err;
-                               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
-                               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);
-                               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
-                                       goto err;
-                               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
-                                       goto err;
-                               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
-                                       goto err;
-                               break;
-                       }
-                       break;
-
-               case STV090x_TSMODE_SERIAL_PUNCTURED:
-               case STV090x_TSMODE_SERIAL_CONTINUOUS:
-               default:
-                       switch (state->config->ts2_mode) {
-                       case STV090x_TSMODE_SERIAL_PUNCTURED:
-                       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       default:
-                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
-                               break;
-
-                       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-                       case STV090x_TSMODE_DVBCI:
-                               stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);
-                               break;
-                       }
-                       break;
-               }
-       }
-
-       switch (state->config->ts1_mode) {
-       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
-               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_DVBCI:
-               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
-               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_SERIAL_PUNCTURED:
-               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
-               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-               reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
-               if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       default:
-               break;
-       }
-
-       switch (state->config->ts2_mode) {
-       case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
-               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_DVBCI:
-               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
-               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_SERIAL_PUNCTURED:
-               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
-               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       case STV090x_TSMODE_SERIAL_CONTINUOUS:
-               reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
-               STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
-               STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
-               STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
-               if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-                       goto err;
-               break;
-
-       default:
-               break;
-       }
-
-       if (state->config->ts1_clk > 0) {
-               u32 speed;
-
-               switch (state->config->ts1_mode) {
-               case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               case STV090x_TSMODE_DVBCI:
-               default:
-                       speed = state->internal->mclk /
-                               (state->config->ts1_clk / 4);
-                       if (speed < 0x08)
-                               speed = 0x08;
-                       if (speed > 0xFF)
-                               speed = 0xFF;
-                       break;
-               case STV090x_TSMODE_SERIAL_PUNCTURED:
-               case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       speed = state->internal->mclk /
-                               (state->config->ts1_clk / 32);
-                       if (speed < 0x20)
-                               speed = 0x20;
-                       if (speed > 0xFF)
-                               speed = 0xFF;
-                       break;
-               }
-               reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
-               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
-               if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
-                       goto err;
-               if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
-                       goto err;
-       }
-
-       if (state->config->ts2_clk > 0) {
-               u32 speed;
-
-               switch (state->config->ts2_mode) {
-               case STV090x_TSMODE_PARALLEL_PUNCTURED:
-               case STV090x_TSMODE_DVBCI:
-               default:
-                       speed = state->internal->mclk /
-                               (state->config->ts2_clk / 4);
-                       if (speed < 0x08)
-                               speed = 0x08;
-                       if (speed > 0xFF)
-                               speed = 0xFF;
-                       break;
-               case STV090x_TSMODE_SERIAL_PUNCTURED:
-               case STV090x_TSMODE_SERIAL_CONTINUOUS:
-                       speed = state->internal->mclk /
-                               (state->config->ts2_clk / 32);
-                       if (speed < 0x20)
-                               speed = 0x20;
-                       if (speed > 0xFF)
-                               speed = 0xFF;
-                       break;
-               }
-               reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
-               STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
-               if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
-                       goto err;
-               if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
-                       goto err;
-       }
-
-       reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
-       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
-       if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-               goto err;
-       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
-       if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
-               goto err;
-
-       reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
-       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
-       if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-               goto err;
-       STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
-       if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_init(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       const struct stv090x_config *config = state->config;
-       u32 reg;
-
-       if (state->internal->mclk == 0) {
-               /* call tuner init to configure the tuner's clock output
-                  divider directly before setting up the master clock of
-                  the stv090x. */
-               if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-                       goto err;
-
-               if (config->tuner_init) {
-                       if (config->tuner_init(fe) < 0)
-                               goto err_gateoff;
-               }
-
-               if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-                       goto err;
-
-               stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
-               msleep(5);
-               if (stv090x_write_reg(state, STV090x_SYNTCTRL,
-                                     0x20 | config->clk_mode) < 0)
-                       goto err;
-               stv090x_get_mclk(state);
-       }
-
-       if (stv090x_wakeup(fe) < 0) {
-               dprintk(FE_ERROR, 1, "Error waking device");
-               goto err;
-       }
-
-       if (stv090x_ldpc_mode(state, state->demod_mode) < 0)
-               goto err;
-
-       reg = STV090x_READ_DEMOD(state, TNRCFG2);
-       STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);
-       if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)
-               goto err;
-       reg = STV090x_READ_DEMOD(state, DEMOD);
-       STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
-       if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
-               goto err;
-
-       if (stv090x_i2c_gate_ctrl(state, 1) < 0)
-               goto err;
-
-       if (config->tuner_set_mode) {
-               if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
-                       goto err_gateoff;
-       }
-
-       if (config->tuner_init) {
-               if (config->tuner_init(fe) < 0)
-                       goto err_gateoff;
-       }
-
-       if (stv090x_i2c_gate_ctrl(state, 0) < 0)
-               goto err;
-
-       if (stv090x_set_tspath(state) < 0)
-               goto err;
-
-       return 0;
-
-err_gateoff:
-       stv090x_i2c_gate_ctrl(state, 0);
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-static int stv090x_setup(struct dvb_frontend *fe)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       const struct stv090x_config *config = state->config;
-       const struct stv090x_reg *stv090x_initval = NULL;
-       const struct stv090x_reg *stv090x_cut20_val = NULL;
-       unsigned long t1_size = 0, t2_size = 0;
-       u32 reg = 0;
-
-       int i;
-
-       if (state->device == STV0900) {
-               dprintk(FE_DEBUG, 1, "Initializing STV0900");
-               stv090x_initval = stv0900_initval;
-               t1_size = ARRAY_SIZE(stv0900_initval);
-               stv090x_cut20_val = stv0900_cut20_val;
-               t2_size = ARRAY_SIZE(stv0900_cut20_val);
-       } else if (state->device == STV0903) {
-               dprintk(FE_DEBUG, 1, "Initializing STV0903");
-               stv090x_initval = stv0903_initval;
-               t1_size = ARRAY_SIZE(stv0903_initval);
-               stv090x_cut20_val = stv0903_cut20_val;
-               t2_size = ARRAY_SIZE(stv0903_cut20_val);
-       }
-
-       /* STV090x init */
-
-       /* Stop Demod */
-       if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
-               goto err;
-       if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
-               goto err;
-
-       msleep(5);
-
-       /* Set No Tuner Mode */
-       if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
-               goto err;
-       if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
-               goto err;
-
-       /* I2C repeater OFF */
-       STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
-       if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
-               goto err;
-       if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
-               goto err;
-
-       if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
-               goto err;
-       msleep(5);
-       if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */
-               goto err;
-       if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */
-               goto err;
-       msleep(5);
-
-       /* write initval */
-       dprintk(FE_DEBUG, 1, "Setting up initial values");
-       for (i = 0; i < t1_size; i++) {
-               if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)
-                       goto err;
-       }
-
-       state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
-       if (state->internal->dev_ver >= 0x20) {
-               if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
-                       goto err;
-
-               /* write cut20_val*/
-               dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");
-               for (i = 0; i < t2_size; i++) {
-                       if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)
-                               goto err;
-               }
-
-       } else if (state->internal->dev_ver < 0x20) {
-               dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
-                       state->internal->dev_ver);
-
-               goto err;
-       } else if (state->internal->dev_ver > 0x30) {
-               /* we shouldn't bail out from here */
-               dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
-                       state->internal->dev_ver);
-       }
-
-       /* ADC1 range */
-       reg = stv090x_read_reg(state, STV090x_TSTTNR1);
-       STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,
-               (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);
-       if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
-               goto err;
-
-       /* ADC2 range */
-       reg = stv090x_read_reg(state, STV090x_TSTTNR3);
-       STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,
-               (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);
-       if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
-               goto err;
-
-       if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
-               goto err;
-       if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
-               goto err;
-
-       return 0;
-err:
-       dprintk(FE_ERROR, 1, "I/O error");
-       return -1;
-}
-
-int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
-               u8 xor_value)
-{
-       struct stv090x_state *state = fe->demodulator_priv;
-       u8 reg = 0;
-
-       STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
-       STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
-       STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
-
-       return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
-}
-EXPORT_SYMBOL(stv090x_set_gpio);
-
-static struct dvb_frontend_ops stv090x_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
-       .info = {
-               .name                   = "STV090x Multistandard",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 0,
-               .frequency_tolerance    = 0,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-               .caps                   = FE_CAN_INVERSION_AUTO |
-                                         FE_CAN_FEC_AUTO       |
-                                         FE_CAN_QPSK           |
-                                         FE_CAN_2G_MODULATION
-       },
-
-       .release                        = stv090x_release,
-       .init                           = stv090x_init,
-
-       .sleep                          = stv090x_sleep,
-       .get_frontend_algo              = stv090x_frontend_algo,
-
-       .diseqc_send_master_cmd         = stv090x_send_diseqc_msg,
-       .diseqc_send_burst              = stv090x_send_diseqc_burst,
-       .diseqc_recv_slave_reply        = stv090x_recv_slave_reply,
-       .set_tone                       = stv090x_set_tone,
-
-       .search                         = stv090x_search,
-       .read_status                    = stv090x_read_status,
-       .read_ber                       = stv090x_read_per,
-       .read_signal_strength           = stv090x_read_signal_strength,
-       .read_snr                       = stv090x_read_cnr,
-};
-
-
-struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
-                                   struct i2c_adapter *i2c,
-                                   enum stv090x_demodulator demod)
-{
-       struct stv090x_state *state = NULL;
-       struct stv090x_dev *temp_int;
-
-       state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->verbose                          = &verbose;
-       state->config                           = config;
-       state->i2c                              = i2c;
-       state->frontend.ops                     = stv090x_ops;
-       state->frontend.demodulator_priv        = state;
-       state->demod                            = demod;
-       state->demod_mode                       = config->demod_mode; /* Single or Dual mode */
-       state->device                           = config->device;
-       state->rolloff                          = STV090x_RO_35; /* default */
-
-       temp_int = find_dev(state->i2c,
-                               state->config->address);
-
-       if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
-               state->internal = temp_int->internal;
-               state->internal->num_used++;
-               dprintk(FE_INFO, 1, "Found Internal Structure!");
-       } else {
-               state->internal = kmalloc(sizeof(struct stv090x_internal),
-                                         GFP_KERNEL);
-               if (!state->internal)
-                       goto error;
-               temp_int = append_internal(state->internal);
-               if (!temp_int) {
-                       kfree(state->internal);
-                       goto error;
-               }
-               state->internal->num_used = 1;
-               state->internal->mclk = 0;
-               state->internal->dev_ver = 0;
-               state->internal->i2c_adap = state->i2c;
-               state->internal->i2c_addr = state->config->address;
-               dprintk(FE_INFO, 1, "Create New Internal Structure!");
-
-               mutex_init(&state->internal->demod_lock);
-               mutex_init(&state->internal->tuner_lock);
-
-               if (stv090x_setup(&state->frontend) < 0) {
-                       dprintk(FE_ERROR, 1, "Error setting up device");
-                       goto err_remove;
-               }
-       }
-
-       /* workaround for stuck DiSEqC output */
-       if (config->diseqc_envelope_mode)
-               stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
-
-       dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
-              state->device == STV0900 ? "STV0900" : "STV0903",
-              demod,
-              state->internal->dev_ver);
-
-       return &state->frontend;
-
-err_remove:
-       remove_dev(state->internal);
-       kfree(state->internal);
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(stv090x_attach);
-MODULE_PARM_DESC(verbose, "Set Verbosity level");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
deleted file mode 100644 (file)
index 29cdc2b..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-       STV0900/0903 Multistandard Broadcast Frontend driver
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV090x_H
-#define __STV090x_H
-
-enum stv090x_demodulator {
-       STV090x_DEMODULATOR_0 = 1,
-       STV090x_DEMODULATOR_1
-};
-
-enum stv090x_device {
-       STV0903 =  0,
-       STV0900,
-};
-
-enum stv090x_mode {
-       STV090x_DUAL = 0,
-       STV090x_SINGLE
-};
-
-enum stv090x_tsmode {
-       STV090x_TSMODE_SERIAL_PUNCTURED = 1,
-       STV090x_TSMODE_SERIAL_CONTINUOUS,
-       STV090x_TSMODE_PARALLEL_PUNCTURED,
-       STV090x_TSMODE_DVBCI
-};
-
-enum stv090x_clkmode {
-       STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
-       STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
-};
-
-enum stv090x_i2crpt {
-       STV090x_RPTLEVEL_256    = 0,
-       STV090x_RPTLEVEL_128    = 1,
-       STV090x_RPTLEVEL_64     = 2,
-       STV090x_RPTLEVEL_32     = 3,
-       STV090x_RPTLEVEL_16     = 4,
-       STV090x_RPTLEVEL_8      = 5,
-       STV090x_RPTLEVEL_4      = 6,
-       STV090x_RPTLEVEL_2      = 7,
-};
-
-enum stv090x_adc_range {
-       STV090x_ADC_2Vpp        = 0,
-       STV090x_ADC_1Vpp        = 1
-};
-
-struct stv090x_config {
-       enum stv090x_device     device;
-       enum stv090x_mode       demod_mode;
-       enum stv090x_clkmode    clk_mode;
-
-       u32 xtal; /* default: 8000000 */
-       u8 address; /* default: 0x68 */
-
-       u8 ts1_mode;
-       u8 ts2_mode;
-       u32 ts1_clk;
-       u32 ts2_clk;
-
-       u8 ts1_tei : 1;
-       u8 ts2_tei : 1;
-
-       enum stv090x_i2crpt     repeater_level;
-
-       u8                      tuner_bbgain; /* default: 10db */
-       enum stv090x_adc_range  adc1_range; /* default: 2Vpp */
-       enum stv090x_adc_range  adc2_range; /* default: 2Vpp */
-
-       bool diseqc_envelope_mode;
-
-       int (*tuner_init) (struct dvb_frontend *fe);
-       int (*tuner_sleep) (struct dvb_frontend *fe);
-       int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
-       int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
-       int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
-       int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
-       int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
-       int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
-       int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
-       int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk);
-       int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
-       void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
-};
-
-#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
-                                          struct i2c_adapter *i2c,
-                                          enum stv090x_demodulator demod);
-
-/* dir = 0 -> output, dir = 1 -> input/open-drain */
-extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
-               u8 dir, u8 value, u8 xor_value);
-
-#else
-
-static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
-                                                 struct i2c_adapter *i2c,
-                                                 enum stv090x_demodulator demod)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
-               u8 opd, u8 value, u8 xor_value)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -ENODEV;
-}
-#endif /* CONFIG_DVB_STV090x */
-
-#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
deleted file mode 100644 (file)
index 5b780c8..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
-       STV0900/0903 Multistandard Broadcast Frontend driver
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV090x_PRIV_H
-#define __STV090x_PRIV_H
-
-#include "dvb_frontend.h"
-
-#define FE_ERROR                               0
-#define FE_NOTICE                              1
-#define FE_INFO                                        2
-#define FE_DEBUG                               3
-#define FE_DEBUGREG                            4
-
-#define dprintk(__y, __z, format, arg...) do {                                         \
-       if (__z) {                                                                      \
-               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
-               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((verbose > FE_INFO) && (verbose > __y))                        \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
-               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (verbose > __y)                                                      \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while (0)
-
-#define STV090x_READ_DEMOD(__state, __reg) ((                  \
-       (__state)->demod == STV090x_DEMODULATOR_1)      ?       \
-       stv090x_read_reg(__state, STV090x_P2_##__reg) :         \
-       stv090x_read_reg(__state, STV090x_P1_##__reg))
-
-#define STV090x_WRITE_DEMOD(__state, __reg, __data) ((         \
-       (__state)->demod == STV090x_DEMODULATOR_1)      ?       \
-       stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
-       stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
-
-#define STV090x_ADDR_OFFST(__state, __x) ((                    \
-       (__state->demod) == STV090x_DEMODULATOR_1)      ?       \
-               STV090x_P1_##__x :                              \
-               STV090x_P2_##__x)
-
-
-#define STV090x_SETFIELD(mask, bitf, val)      (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
-                                                        STV090x_OFFST_##bitf))) | \
-                                                        (val << STV090x_OFFST_##bitf))
-
-#define STV090x_GETFIELD(val, bitf)            ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
-
-
-#define STV090x_SETFIELD_Px(mask, bitf, val)   (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
-                                                        STV090x_OFFST_Px_##bitf))) | \
-                                                        (val << STV090x_OFFST_Px_##bitf))
-
-#define STV090x_GETFIELD_Px(val, bitf)         ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
-
-#define MAKEWORD16(__a, __b)                   (((__a) << 8) | (__b))
-
-#define MSB(__x)                               ((__x >> 8) & 0xff)
-#define LSB(__x)                               (__x & 0xff)
-
-
-#define STV090x_IQPOWER_THRESHOLD        30
-#define STV090x_SEARCH_AGC2_TH_CUT20    700
-#define STV090x_SEARCH_AGC2_TH_CUT30   1400
-
-#define STV090x_SEARCH_AGC2_TH(__ver)  \
-       ((__ver <= 0x20) ?              \
-       STV090x_SEARCH_AGC2_TH_CUT20 :  \
-       STV090x_SEARCH_AGC2_TH_CUT30)
-
-enum stv090x_signal_state {
-       STV090x_NOAGC1,
-       STV090x_NOCARRIER,
-       STV090x_NODATA,
-       STV090x_DATAOK,
-       STV090x_RANGEOK,
-       STV090x_OUTOFRANGE
-};
-
-enum stv090x_fec {
-       STV090x_PR12 = 0,
-       STV090x_PR23,
-       STV090x_PR34,
-       STV090x_PR45,
-       STV090x_PR56,
-       STV090x_PR67,
-       STV090x_PR78,
-       STV090x_PR89,
-       STV090x_PR910,
-       STV090x_PRERR
-};
-
-enum stv090x_modulation {
-       STV090x_QPSK,
-       STV090x_8PSK,
-       STV090x_16APSK,
-       STV090x_32APSK,
-       STV090x_UNKNOWN
-};
-
-enum stv090x_frame {
-       STV090x_LONG_FRAME,
-       STV090x_SHORT_FRAME
-};
-
-enum stv090x_pilot {
-       STV090x_PILOTS_OFF,
-       STV090x_PILOTS_ON
-};
-
-enum stv090x_rolloff {
-       STV090x_RO_35,
-       STV090x_RO_25,
-       STV090x_RO_20
-};
-
-enum stv090x_inversion {
-       STV090x_IQ_AUTO,
-       STV090x_IQ_NORMAL,
-       STV090x_IQ_SWAP
-};
-
-enum stv090x_modcod {
-       STV090x_DUMMY_PLF = 0,
-       STV090x_QPSK_14,
-       STV090x_QPSK_13,
-       STV090x_QPSK_25,
-       STV090x_QPSK_12,
-       STV090x_QPSK_35,
-       STV090x_QPSK_23,
-       STV090x_QPSK_34,
-       STV090x_QPSK_45,
-       STV090x_QPSK_56,
-       STV090x_QPSK_89,
-       STV090x_QPSK_910,
-       STV090x_8PSK_35,
-       STV090x_8PSK_23,
-       STV090x_8PSK_34,
-       STV090x_8PSK_56,
-       STV090x_8PSK_89,
-       STV090x_8PSK_910,
-       STV090x_16APSK_23,
-       STV090x_16APSK_34,
-       STV090x_16APSK_45,
-       STV090x_16APSK_56,
-       STV090x_16APSK_89,
-       STV090x_16APSK_910,
-       STV090x_32APSK_34,
-       STV090x_32APSK_45,
-       STV090x_32APSK_56,
-       STV090x_32APSK_89,
-       STV090x_32APSK_910,
-       STV090x_MODCODE_UNKNOWN
-};
-
-enum stv090x_search {
-       STV090x_SEARCH_DSS = 0,
-       STV090x_SEARCH_DVBS1,
-       STV090x_SEARCH_DVBS2,
-       STV090x_SEARCH_AUTO
-};
-
-enum stv090x_algo {
-       STV090x_BLIND_SEARCH,
-       STV090x_COLD_SEARCH,
-       STV090x_WARM_SEARCH
-};
-
-enum stv090x_delsys {
-       STV090x_ERROR = 0,
-       STV090x_DVBS1 = 1,
-       STV090x_DVBS2,
-       STV090x_DSS
-};
-
-struct stv090x_long_frame_crloop {
-       enum stv090x_modcod     modcod;
-
-       u8 crl_pilots_on_2;
-       u8 crl_pilots_off_2;
-       u8 crl_pilots_on_5;
-       u8 crl_pilots_off_5;
-       u8 crl_pilots_on_10;
-       u8 crl_pilots_off_10;
-       u8 crl_pilots_on_20;
-       u8 crl_pilots_off_20;
-       u8 crl_pilots_on_30;
-       u8 crl_pilots_off_30;
-};
-
-struct stv090x_short_frame_crloop {
-       enum stv090x_modulation modulation;
-
-       u8 crl_2;  /*      SR <   3M */
-       u8 crl_5;  /*  3 < SR <=  7M */
-       u8 crl_10; /*  7 < SR <= 15M */
-       u8 crl_20; /* 10 < SR <= 25M */
-       u8 crl_30; /* 10 < SR <= 45M */
-};
-
-struct stv090x_reg {
-       u16 addr;
-       u8  data;
-};
-
-struct stv090x_tab {
-       s32 real;
-       s32 read;
-};
-
-struct stv090x_internal {
-       struct i2c_adapter      *i2c_adap;
-       u8                      i2c_addr;
-
-       struct mutex            demod_lock; /* Lock access to shared register */
-       struct mutex            tuner_lock; /* Lock access to tuners */
-       s32                     mclk; /* Masterclock Divider factor */
-       u32                     dev_ver;
-
-       int                     num_used;
-};
-
-struct stv090x_state {
-       enum stv090x_device             device;
-       enum stv090x_demodulator        demod;
-       enum stv090x_mode               demod_mode;
-       struct stv090x_internal         *internal;
-
-       struct i2c_adapter              *i2c;
-       const struct stv090x_config     *config;
-       struct dvb_frontend             frontend;
-
-       u32                             *verbose; /* Cached module verbosity */
-
-       enum stv090x_delsys             delsys;
-       enum stv090x_fec                fec;
-       enum stv090x_modulation         modulation;
-       enum stv090x_modcod             modcod;
-       enum stv090x_search             search_mode;
-       enum stv090x_frame              frame_len;
-       enum stv090x_pilot              pilots;
-       enum stv090x_rolloff            rolloff;
-       enum stv090x_inversion          inversion;
-       enum stv090x_algo               algo;
-
-       u32                             frequency;
-       u32                             srate;
-
-       s32                             tuner_bw;
-
-       s32                             search_range;
-
-       s32                             DemodTimeout;
-       s32                             FecTimeout;
-};
-
-#endif /* __STV090x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
deleted file mode 100644 (file)
index 93741ee..0000000
+++ /dev/null
@@ -1,2371 +0,0 @@
-/*
-       STV0900/0903 Multistandard Broadcast Frontend driver
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV090x_REG_H
-#define __STV090x_REG_H
-
-#define STV090x_MID                            0xf100
-#define STV090x_OFFST_MCHIP_IDENT_FIELD                4
-#define STV090x_WIDTH_MCHIP_IDENT_FIELD                4
-#define STV090x_OFFST_MRELEASE_FIELD           0
-#define STV090x_WIDTH_MRELEASE_FIELD           4
-
-#define STV090x_DACR1                          0xf113
-#define STV090x_OFFST_DACR1_MODE_FIELD         5
-#define STV090x_WIDTH_DACR1_MODE_FIELD         3
-#define STV090x_OFFST_DACR1_VALUE_FIELD                0
-#define STV090x_WIDTH_DACR1_VALUE_FIELD                4
-
-#define STV090x_DACR2                          0xf114
-#define STV090x_OFFST_DACR2_VALUE_FIELD                0
-#define STV090x_WIDTH_DACR2_VALUE_FIELD                8
-
-#define STV090x_OUTCFG                         0xf11c
-#define STV090x_OFFST_OUTSERRS1_HZ_FIELD       6
-#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD       1
-#define STV090x_OFFST_OUTSERRS2_HZ_FIELD       5
-#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD       1
-#define STV090x_OFFST_OUTSERRS3_HZ_FIELD       4
-#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD       1
-#define STV090x_OFFST_OUTPARRS3_HZ_FIELD       3
-#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD       1
-
-#define STV090x_MODECFG                                0xf11d
-
-#define STV090x_IRQSTATUS3                     0xf120
-#define STV090x_OFFST_SPLL_LOCK_FIELD          5
-#define STV090x_WIDTH_SPLL_LOCK_FIELD          1
-#define STV090x_OFFST_SSTREAM_LCK_3_FIELD      4
-#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD      1
-#define STV090x_OFFST_SSTREAM_LCK_2_FIELD      3
-#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD      1
-#define STV090x_OFFST_SSTREAM_LCK_1_FIELD      2
-#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD      1
-#define STV090x_OFFST_SDVBS1_PRF_2_FIELD       1
-#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD       1
-#define STV090x_OFFST_SDVBS1_PRF_1_FIELD       0
-#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD       1
-
-#define STV090x_IRQSTATUS2                     0xf121
-#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD      7
-#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD      1
-#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD      6
-#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD      1
-#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD      5
-#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD      1
-#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD    4
-#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD    1
-#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD    3
-#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD    1
-#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD     2
-#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD     1
-#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD    1
-#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD    1
-#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD    0
-#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD    1
-
-#define STV090x_IRQSTATUS1                     0xf122
-#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD     7
-#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD     1
-#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD     2
-#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD     1
-#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD      1
-#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD      1
-#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD       0
-#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD       1
-
-#define STV090x_IRQSTATUS0                     0xf123
-#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD     7
-#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD     1
-#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD      6
-#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD      1
-#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD       5
-#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD       1
-#define STV090x_OFFST_SBCH_ERRFLAG_FIELD       4
-#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD       1
-#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD     3
-#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD     1
-#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD     2
-#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD     1
-#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD     1
-#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD     1
-#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD     0
-#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD     1
-
-#define STV090x_IRQMASK3                       0xf124
-#define STV090x_OFFST_MPLL_LOCK_FIELD          5
-#define STV090x_WIDTH_MPLL_LOCK_FIELD          1
-#define STV090x_OFFST_MSTREAM_LCK_3_FIELD      4
-#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD      1
-#define STV090x_OFFST_MSTREAM_LCK_2_FIELD      3
-#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD      1
-#define STV090x_OFFST_MSTREAM_LCK_1_FIELD      2
-#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD      1
-#define STV090x_OFFST_MDVBS1_PRF_2_FIELD       1
-#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD       1
-#define STV090x_OFFST_MDVBS1_PRF_1_FIELD       0
-#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD       1
-
-#define STV090x_IRQMASK2                       0xf125
-#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD      7
-#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD      1
-#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD      6
-#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD      1
-#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD      5
-#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD      1
-#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD    4
-#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD    1
-#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD    3
-#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD    1
-#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD     2
-#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD     1
-#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD    1
-#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD    1
-#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD    0
-#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD    1
-
-#define STV090x_IRQMASK1                       0xf126
-#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD     7
-#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD     1
-#define STV090x_OFFST_MEXTPINB2_FIELD          6
-#define STV090x_WIDTH_MEXTPINB2_FIELD          1
-#define STV090x_OFFST_MEXTPIN2_FIELD           5
-#define STV090x_WIDTH_MEXTPIN2_FIELD           1
-#define STV090x_OFFST_MEXTPINB1_FIELD          4
-#define STV090x_WIDTH_MEXTPINB1_FIELD          1
-#define STV090x_OFFST_MEXTPIN1_FIELD           3
-#define STV090x_WIDTH_MEXTPIN1_FIELD           1
-#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD     2
-#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD     1
-#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD      1
-#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD      1
-#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD       0
-#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD       1
-
-#define STV090x_IRQMASK0                       0xf127
-#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD     7
-#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD     1
-#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD      6
-#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD      1
-#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD       5
-#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD       1
-#define STV090x_OFFST_MBCH_ERRFLAG_FIELD       4
-#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD       1
-#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD     3
-#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD     1
-#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD     2
-#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD     1
-#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD     1
-#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD     1
-#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD     0
-#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD     1
-
-#define STV090x_I2CCFG                         0xf129
-#define STV090x_OFFST_12C_FASTMODE_FIELD       3
-#define STV090x_WIDTH_12C_FASTMODE_FIELD       1
-#define STV090x_OFFST_12CADDR_INC_FIELD                0
-#define STV090x_WIDTH_12CADDR_INC_FIELD                2
-
-#define STV090x_Px_I2CRPT(__x)                 (0xf12a + (__x - 1) * 0x1)
-#define STV090x_P1_I2CRPT                      STV090x_Px_I2CRPT(1)
-#define STV090x_P2_I2CRPT                      STV090x_Px_I2CRPT(2)
-#define STV090x_OFFST_Px_I2CT_ON_FIELD         7
-#define STV090x_WIDTH_Px_I2CT_ON_FIELD         1
-#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD    4
-#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD    3
-#define STV090x_OFFST_Px_SCLT_DELAY_FIELD      3
-#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD      1
-#define STV090x_OFFST_Px_STOP_ENABLE_FIELD     2
-#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD     1
-#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD   1
-#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD   1
-
-#define STV090x_CLKI2CFG                       0xf140
-#define STV090x_OFFST_CLKI2_OPD_FIELD          7
-#define STV090x_WIDTH_CLKI2_OPD_FIELD          1
-#define STV090x_OFFST_CLKI2_CONFIG_FIELD       1
-#define STV090x_WIDTH_CLKI2_CONFIG_FIELD       6
-#define STV090x_OFFST_CLKI2_XOR_FIELD          0
-#define STV090x_WIDTH_CLKI2_XOR_FIELD          1
-
-#define STV090x_GPIOxCFG(__x)                  (0xf141 + (__x - 1))
-#define STV090x_GPIO1CFG                       STV090x_GPIOxCFG(1)
-#define STV090x_GPIO2CFG                       STV090x_GPIOxCFG(2)
-#define STV090x_GPIO3CFG                       STV090x_GPIOxCFG(3)
-#define STV090x_GPIO4CFG                       STV090x_GPIOxCFG(4)
-#define STV090x_GPIO5CFG                       STV090x_GPIOxCFG(5)
-#define STV090x_GPIO6CFG                       STV090x_GPIOxCFG(6)
-#define STV090x_GPIO7CFG                       STV090x_GPIOxCFG(7)
-#define STV090x_GPIO8CFG                       STV090x_GPIOxCFG(8)
-#define STV090x_GPIO9CFG                       STV090x_GPIOxCFG(9)
-#define STV090x_GPIO10CFG                      STV090x_GPIOxCFG(10)
-#define STV090x_GPIO11CFG                      STV090x_GPIOxCFG(11)
-#define STV090x_GPIO12CFG                      STV090x_GPIOxCFG(12)
-#define STV090x_GPIO13CFG                      STV090x_GPIOxCFG(13)
-#define STV090x_OFFST_GPIOx_OPD_FIELD          7
-#define STV090x_WIDTH_GPIOx_OPD_FIELD          1
-#define STV090x_OFFST_GPIOx_CONFIG_FIELD       1
-#define STV090x_WIDTH_GPIOx_CONFIG_FIELD       6
-#define STV090x_OFFST_GPIOx_XOR_FIELD          0
-#define STV090x_WIDTH_GPIOx_XOR_FIELD          1
-
-#define STV090x_CSxCFG(__x)                    (0xf14e + __x * 0x1)
-#define STV090x_CS0CFG                         STV090x_CSxCFG(0)
-#define STV090x_CS1CFG                         STV090x_CSxCFG(1)
-#define STV090x_OFFST_CSX_OPD_FIELD            7
-#define STV090x_WIDTH_CSX_OPD_FIELD            1
-#define STV090x_OFFST_CSX_CONFIG_FIELD         1
-#define STV090x_WIDTH_CSX_CONFIG_FIELD         6
-#define STV090x_OFFST_CSX_XOR_FIELD            0
-#define STV090x_WIDTH_CSX_XOR_FIELD            1
-
-
-#define STV090x_STDBYCFG                       0xf150
-#define STV090x_OFFST_STDBY_OPD_FIELD          7
-#define STV090x_WIDTH_STDBY_OPD_FIELD          1
-#define STV090x_OFFST_STDBY_CONFIG_FIELD       1
-#define STV090x_WIDTH_STDBY_CONFIG_FIELD       6
-#define STV090x_OFFST_STDBY_XOR_FIELD          0
-#define STV090x_WIDTH_STDBY_XOR_FIELD          1
-
-#define STV090x_DIRCLKCFG                      0xf151
-#define STV090x_OFFST_DIRCLK_OPD_FIELD         7
-#define STV090x_WIDTH_DIRCLK_OPD_FIELD         1
-#define STV090x_OFFST_DIRCLK_CONFIG_FIELD      1
-#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD      6
-#define STV090x_OFFST_DIRCLK_XOR_FIELD         0
-#define STV090x_WIDTH_DIRCLK_XOR_FIELD         1
-
-
-#define STV090x_AGCRFxCFG(__x)                 (0xf152 + (__x - 1) * 0x4)
-#define STV090x_AGCRF1CFG                      STV090x_AGCRFxCFG(1)
-#define STV090x_AGCRF2CFG                      STV090x_AGCRFxCFG(2)
-#define STV090x_OFFST_AGCRFx_OPD_FIELD         7
-#define STV090x_WIDTH_AGCRFx_OPD_FIELD         1
-#define STV090x_OFFST_AGCRFx_CONFIG_FIELD      1
-#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD      6
-#define STV090x_OFFST_AGCRFx_XOR_FIELD         0
-#define STV090x_WIDTH_AGCRFx_XOR_FIELD         1
-
-#define STV090x_SDATxCFG(__x)                  (0xf153 + (__x - 1) * 0x4)
-#define STV090x_SDAT1CFG                       STV090x_SDATxCFG(1)
-#define STV090x_SDAT2CFG                       STV090x_SDATxCFG(2)
-#define STV090x_OFFST_SDATx_OPD_FIELD          7
-#define STV090x_WIDTH_SDATx_OPD_FIELD          1
-#define STV090x_OFFST_SDATx_CONFIG_FIELD       1
-#define STV090x_WIDTH_SDATx_CONFIG_FIELD       6
-#define STV090x_OFFST_SDATx_XOR_FIELD          0
-#define STV090x_WIDTH_SDATx_XOR_FIELD          1
-
-#define STV090x_SCLTxCFG(__x)                  (0xf154 + (__x - 1) * 0x4)
-#define STV090x_SCLT1CFG                       STV090x_SCLTxCFG(1)
-#define STV090x_SCLT2CFG                       STV090x_SCLTxCFG(2)
-#define STV090x_OFFST_SCLTx_OPD_FIELD          7
-#define STV090x_WIDTH_SCLTx_OPD_FIELD          1
-#define STV090x_OFFST_SCLTx_CONFIG_FIELD       1
-#define STV090x_WIDTH_SCLTx_CONFIG_FIELD       6
-#define STV090x_OFFST_SCLTx_XOR_FIELD          0
-#define STV090x_WIDTH_SCLTx_XOR_FIELD          1
-
-#define STV090x_DISEQCOxCFG(__x)               (0xf155 + (__x - 1) * 0x4)
-#define STV090x_DISEQCO1CFG                    STV090x_DISEQCOxCFG(1)
-#define STV090x_DISEQCO2CFG                    STV090x_DISEQCOxCFG(2)
-#define STV090x_OFFST_DISEQCOx_OPD_FIELD       7
-#define STV090x_WIDTH_DISEQCOx_OPD_FIELD       1
-#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD    1
-#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD    6
-#define STV090x_OFFST_DISEQCOx_XOR_FIELD       0
-#define STV090x_WIDTH_DISEQCOx_XOR_FIELD       1
-
-#define STV090x_CLKOUT27CFG                    0xf15a
-#define STV090x_OFFST_CLKOUT27_OPD_FIELD       7
-#define STV090x_WIDTH_CLKOUT27_OPD_FIELD       1
-#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD    1
-#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD    6
-#define STV090x_OFFST_CLKOUT27_XOR_FIELD       0
-#define STV090x_WIDTH_CLKOUT27_XOR_FIELD       1
-
-#define STV090x_ERRORxCFG(__x)                 (0xf15b + (__x - 1) * 0x5)
-#define STV090x_ERROR1CFG                      STV090x_ERRORxCFG(1)
-#define STV090x_ERROR2CFG                      STV090x_ERRORxCFG(2)
-#define STV090x_ERROR3CFG                      STV090x_ERRORxCFG(3)
-#define STV090x_OFFST_ERRORx_OPD_FIELD         7
-#define STV090x_WIDTH_ERRORx_OPD_FIELD         1
-#define STV090x_OFFST_ERRORx_CONFIG_FIELD      1
-#define STV090x_WIDTH_ERRORx_CONFIG_FIELD      6
-#define STV090x_OFFST_ERRORx_XOR_FIELD         0
-#define STV090x_WIDTH_ERRORx_XOR_FIELD         1
-
-#define STV090x_DPNxCFG(__x)                   (0xf15c + (__x - 1) * 0x5)
-#define STV090x_DPN1CFG                                STV090x_DPNxCFG(1)
-#define STV090x_DPN2CFG                                STV090x_DPNxCFG(2)
-#define STV090x_DPN3CFG                                STV090x_DPNxCFG(3)
-#define STV090x_OFFST_DPNx_OPD_FIELD           7
-#define STV090x_WIDTH_DPNx_OPD_FIELD           1
-#define STV090x_OFFST_DPNx_CONFIG_FIELD                1
-#define STV090x_WIDTH_DPNx_CONFIG_FIELD                6
-#define STV090x_OFFST_DPNx_XOR_FIELD           0
-#define STV090x_WIDTH_DPNx_XOR_FIELD           1
-
-#define STV090x_STROUTxCFG(__x)                        (0xf15d + (__x - 1) * 0x5)
-#define STV090x_STROUT1CFG                     STV090x_STROUTxCFG(1)
-#define STV090x_STROUT2CFG                     STV090x_STROUTxCFG(2)
-#define STV090x_STROUT3CFG                     STV090x_STROUTxCFG(3)
-#define STV090x_OFFST_STROUTx_OPD_FIELD                7
-#define STV090x_WIDTH_STROUTx_OPD_FIELD                1
-#define STV090x_OFFST_STROUTx_CONFIG_FIELD     1
-#define STV090x_WIDTH_STROUTx_CONFIG_FIELD     6
-#define STV090x_OFFST_STROUTx_XOR_FIELD                0
-#define STV090x_WIDTH_STROUTx_XOR_FIELD                1
-
-#define STV090x_CLKOUTxCFG(__x)                        (0xf15e + (__x - 1) * 0x5)
-#define STV090x_CLKOUT1CFG                     STV090x_CLKOUTxCFG(1)
-#define STV090x_CLKOUT2CFG                     STV090x_CLKOUTxCFG(2)
-#define STV090x_CLKOUT3CFG                     STV090x_CLKOUTxCFG(3)
-#define STV090x_OFFST_CLKOUTx_OPD_FIELD                7
-#define STV090x_WIDTH_CLKOUTx_OPD_FIELD                1
-#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD     1
-#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD     6
-#define STV090x_OFFST_CLKOUTx_XOR_FIELD                0
-#define STV090x_WIDTH_CLKOUTx_XOR_FIELD                1
-
-#define STV090x_DATAxCFG(__x)                  (0xf15f + (__x - 71) * 0x5)
-#define STV090x_DATA71CFG                      STV090x_DATAxCFG(71)
-#define STV090x_DATA72CFG                      STV090x_DATAxCFG(72)
-#define STV090x_DATA73CFG                      STV090x_DATAxCFG(73)
-#define STV090x_OFFST_DATAx_OPD_FIELD          7
-#define STV090x_WIDTH_DATAx_OPD_FIELD          1
-#define STV090x_OFFST_DATAx_CONFIG_FIELD       1
-#define STV090x_WIDTH_DATAx_CONFIG_FIELD       6
-#define STV090x_OFFST_DATAx_XOR_FIELD          0
-#define STV090x_WIDTH_DATAx_XOR_FIELD          1
-
-#define STV090x_NCOARSE                                0xf1b3
-#define STV090x_OFFST_M_DIV_FIELD              0
-#define STV090x_WIDTH_M_DIV_FIELD              8
-
-#define STV090x_SYNTCTRL                       0xf1b6
-#define STV090x_OFFST_STANDBY_FIELD            7
-#define STV090x_WIDTH_STANDBY_FIELD            1
-#define STV090x_OFFST_BYPASSPLLCORE_FIELD      6
-#define STV090x_WIDTH_BYPASSPLLCORE_FIELD      1
-#define STV090x_OFFST_SELX1RATIO_FIELD         5
-#define STV090x_WIDTH_SELX1RATIO_FIELD         1
-#define STV090x_OFFST_STOP_PLL_FIELD           3
-#define STV090x_WIDTH_STOP_PLL_FIELD           1
-#define STV090x_OFFST_BYPASSPLLFSK_FIELD       2
-#define STV090x_WIDTH_BYPASSPLLFSK_FIELD       1
-#define STV090x_OFFST_SELOSCI_FIELD            1
-#define STV090x_WIDTH_SELOSCI_FIELD            1
-#define STV090x_OFFST_BYPASSPLLADC_FIELD       0
-#define STV090x_WIDTH_BYPASSPLLADC_FIELD       1
-
-#define STV090x_FILTCTRL                       0xf1b7
-#define STV090x_OFFST_INV_CLK135_FIELD         7
-#define STV090x_WIDTH_INV_CLK135_FIELD         1
-#define STV090x_OFFST_SEL_FSKCKDIV_FIELD       2
-#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD       1
-#define STV090x_OFFST_INV_CLKFSK_FIELD         1
-#define STV090x_WIDTH_INV_CLKFSK_FIELD         1
-#define STV090x_OFFST_BYPASS_APPLI_FIELD       0
-#define STV090x_WIDTH_BYPASS_APPLI_FIELD       1
-
-#define STV090x_PLLSTAT                                0xf1b8
-#define STV090x_OFFST_PLLLOCK_FIELD            0
-#define STV090x_WIDTH_PLLLOCK_FIELD            1
-
-#define STV090x_STOPCLK1                       0xf1c2
-#define STV090x_OFFST_STOP_CLKPKDT2_FIELD      6
-#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD      1
-#define STV090x_OFFST_STOP_CLKPKDT1_FIELD      5
-#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD      1
-#define STV090x_OFFST_STOP_CLKFEC_FIELD                4
-#define STV090x_WIDTH_STOP_CLKFEC_FIELD                1
-#define STV090x_OFFST_STOP_CLKADCI2_FIELD      3
-#define STV090x_WIDTH_STOP_CLKADCI2_FIELD      1
-#define STV090x_OFFST_INV_CLKADCI2_FIELD       2
-#define STV090x_WIDTH_INV_CLKADCI2_FIELD       1
-#define STV090x_OFFST_STOP_CLKADCI1_FIELD      1
-#define STV090x_WIDTH_STOP_CLKADCI1_FIELD      1
-#define STV090x_OFFST_INV_CLKADCI1_FIELD       0
-#define STV090x_WIDTH_INV_CLKADCI1_FIELD       1
-
-#define STV090x_STOPCLK2                       0xf1c3
-#define STV090x_OFFST_STOP_CLKSAMP2_FIELD      4
-#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD      1
-#define STV090x_OFFST_STOP_CLKSAMP1_FIELD      3
-#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD      1
-#define STV090x_OFFST_STOP_CLKVIT2_FIELD       2
-#define STV090x_WIDTH_STOP_CLKVIT2_FIELD       1
-#define STV090x_OFFST_STOP_CLKVIT1_FIELD       1
-#define STV090x_WIDTH_STOP_CLKVIT1_FIELD       1
-#define STV090x_OFFST_STOP_CLKTS_FIELD         0
-#define STV090x_WIDTH_STOP_CLKTS_FIELD         1
-
-#define STV090x_TSTTNR0                                0xf1df
-#define STV090x_OFFST_SEL_FSK_FIELD            7
-#define STV090x_WIDTH_SEL_FSK_FIELD            1
-#define STV090x_OFFST_FSK_PON_FIELD            2
-#define STV090x_WIDTH_FSK_PON_FIELD            1
-
-#define STV090x_TSTTNR1                                0xf1e0
-#define STV090x_OFFST_ADC1_PON_FIELD           1
-#define STV090x_WIDTH_ADC1_PON_FIELD           1
-#define STV090x_OFFST_ADC1_INMODE_FIELD                0
-#define STV090x_WIDTH_ADC1_INMODE_FIELD                1
-
-#define STV090x_TSTTNR2                                0xf1e1
-#define STV090x_OFFST_DISEQC1_PON_FIELD                5
-#define STV090x_WIDTH_DISEQC1_PON_FIELD                1
-
-#define STV090x_TSTTNR3                                0xf1e2
-#define STV090x_OFFST_ADC2_PON_FIELD           1
-#define STV090x_WIDTH_ADC2_PON_FIELD           1
-#define STV090x_OFFST_ADC2_INMODE_FIELD                0
-#define STV090x_WIDTH_ADC2_INMODE_FIELD                1
-
-#define STV090x_TSTTNR4                                0xf1e3
-#define STV090x_OFFST_DISEQC2_PON_FIELD                5
-#define STV090x_WIDTH_DISEQC2_PON_FIELD                1
-
-#define STV090x_FSKTFC2                                0xf170
-#define STV090x_OFFST_FSKT_KMOD_FIELD          2
-#define STV090x_WIDTH_FSKT_KMOD_FIELD          6
-#define STV090x_OFFST_FSKT_CAR_FIELD           0
-#define STV090x_WIDTH_FSKT_CAR_FIELD           2
-
-#define STV090x_FSKTFC1                                0xf171
-#define STV090x_OFFST_FSKTC1_CAR_FIELD         0
-#define STV090x_WIDTH_FSKTC1_CAR_FIELD         8
-
-#define STV090x_FSKTFC0                                0xf172
-#define STV090x_OFFST_FSKTC0_CAR_FIELD         0
-#define STV090x_WIDTH_FSKTC0_CAR_FIELD         8
-
-#define STV090x_FSKTDELTAF1                    0xf173
-#define STV090x_OFFST_FSKTF1_DELTAF_FIELD      0
-#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD      4
-
-#define STV090x_FSKTDELTAF0                    0xf174
-#define STV090x_OFFST_FSKTF0_DELTAF_FIELD      0
-#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD      8
-
-#define STV090x_FSKTCTRL                       0xf175
-#define STV090x_OFFST_FSKT_EN_SGN_FIELD                6
-#define STV090x_WIDTH_FSKT_EN_SGN_FIELD                1
-#define STV090x_OFFST_FSKT_MOD_SGN_FIELD       5
-#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD       1
-#define STV090x_OFFST_FSKT_MOD_EN_FIELD                2
-#define STV090x_WIDTH_FSKT_MOD_EN_FIELD                3
-#define STV090x_OFFST_FSKT_DACMODE_FIELD       0
-#define STV090x_WIDTH_FSKT_DACMODE_FIELD       2
-
-#define STV090x_FSKRFC2                                0xf176
-#define STV090x_OFFST_FSKRC2_DETSGN_FIELD      6
-#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD      1
-#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD      5
-#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD      1
-#define STV090x_OFFST_FSKRC2_KAGC_FIELD                2
-#define STV090x_WIDTH_FSKRC2_KAGC_FIELD                3
-#define STV090x_OFFST_FSKRC2_CAR_FIELD         0
-#define STV090x_WIDTH_FSKRC2_CAR_FIELD         2
-
-#define STV090x_FSKRFC1                                0xf177
-#define STV090x_OFFST_FSKRC1_CAR_FIELD         0
-#define STV090x_WIDTH_FSKRC1_CAR_FIELD         8
-
-#define STV090x_FSKRFC0                                0xf178
-#define STV090x_OFFST_FSKRC0_CAR_FIELD         0
-#define STV090x_WIDTH_FSKRC0_CAR_FIELD         8
-
-#define STV090x_FSKRK1                         0xf179
-#define STV090x_OFFST_FSKR_K1_EXP_FIELD                5
-#define STV090x_WIDTH_FSKR_K1_EXP_FIELD                3
-#define STV090x_OFFST_FSKR_K1_MANT_FIELD       0
-#define STV090x_WIDTH_FSKR_K1_MANT_FIELD       5
-
-#define STV090x_FSKRK2                         0xf17a
-#define STV090x_OFFST_FSKR_K2_EXP_FIELD                5
-#define STV090x_WIDTH_FSKR_K2_EXP_FIELD                3
-#define STV090x_OFFST_FSKR_K2_MANT_FIELD       0
-#define STV090x_WIDTH_FSKR_K2_MANT_FIELD       5
-
-#define STV090x_FSKRAGCR                       0xf17b
-#define STV090x_OFFST_FSKR_OUTCTL_FIELD                6
-#define STV090x_WIDTH_FSKR_OUTCTL_FIELD                2
-#define STV090x_OFFST_FSKR_AGC_REF_FIELD       0
-#define STV090x_WIDTH_FSKR_AGC_REF_FIELD       6
-
-#define STV090x_FSKRAGC                                0xf17c
-#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD      0
-#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD      8
-
-#define STV090x_FSKRALPHA                      0xf17d
-#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD     2
-#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD     3
-#define STV090x_OFFST_FSKR_ALPHA_M_FIELD       0
-#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD       2
-
-#define STV090x_FSKRPLTH1                      0xf17e
-#define STV090x_OFFST_FSKR_BETA_FIELD          4
-#define STV090x_WIDTH_FSKR_BETA_FIELD          4
-#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD    0
-#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD    4
-
-#define STV090x_FSKRPLTH0                      0xf17f
-#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD    0
-#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD    8
-
-#define STV090x_FSKRDF1                                0xf180
-#define STV090x_OFFST_FSKR_DELTAF1_FIELD       0
-#define STV090x_WIDTH_FSKR_DELTAF1_FIELD       5
-
-#define STV090x_FSKRDF0                                0xf181
-#define STV090x_OFFST_FSKR_DELTAF0_FIELD       0
-#define STV090x_WIDTH_FSKR_DELTAF0_FIELD       8
-
-#define STV090x_FSKRSTEPP                      0xf182
-#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD     0
-#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD     8
-
-#define STV090x_FSKRSTEPM                      0xf183
-#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD    0
-#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD    8
-
-#define STV090x_FSKRDET1                       0xf184
-#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD  0
-#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD  4
-
-#define STV090x_FSKRDET0                       0xf185
-#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD  0
-#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD  8
-
-#define STV090x_FSKRDTH1                               0xf186
-#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD       4
-#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD       4
-#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD                0
-#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD                4
-
-#define STV090x_FSKRDTH0                       0xf187
-#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD        0
-#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD        8
-
-#define STV090x_FSKRLOSS                       0xf188
-#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD        0
-#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD        8
-
-#define STV090x_Px_DISTXCTL(__x)               (0xF1A0 - (__x - 1) * 0x10)
-#define STV090x_P1_DISTXCTL                    STV090x_Px_DISTXCTL(1)
-#define STV090x_P2_DISTXCTL                    STV090x_Px_DISTXCTL(2)
-#define STV090x_OFFST_Px_TIM_OFF_FIELD         7
-#define STV090x_WIDTH_Px_TIM_OFF_FIELD         1
-#define STV090x_OFFST_Px_DISEQC_RESET_FIELD    6
-#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD    1
-#define STV090x_OFFST_Px_TIM_CMD_FIELD         4
-#define STV090x_WIDTH_Px_TIM_CMD_FIELD         2
-#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD   3
-#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD   1
-#define STV090x_OFFST_Px_DISTX_MODE_FIELD      0
-#define STV090x_WIDTH_Px_DISTX_MODE_FIELD      3
-
-#define STV090x_Px_DISRXCTL(__x)               (0xf1a1 - (__x - 1) * 0x10)
-#define STV090x_P1_DISRXCTL                    STV090x_Px_DISRXCTL(1)
-#define STV090x_P2_DISRXCTL                    STV090x_Px_DISRXCTL(2)
-#define STV090x_OFFST_Px_RECEIVER_ON_FIELD     7
-#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD     1
-#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD   6
-#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD   1
-#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD     5
-#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD     1
-#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD     4
-#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD     1
-#define STV090x_OFFST_Px_PIN_SELECT_FIELD      2
-#define STV090x_WIDTH_Px_PIN_SELECT_FIELD      2
-#define STV090x_OFFST_Px_IRQ_RXEND_FIELD       1
-#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD       1
-#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD     0
-#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD     1
-
-#define STV090x_Px_DISRX_ST0(__x)              (0xf1a4 - (__x - 1) * 0x10)
-#define STV090x_P1_DISRX_ST0                   STV090x_Px_DISRX_ST0(1)
-#define STV090x_P2_DISRX_ST0                   STV090x_Px_DISRX_ST0(2)
-#define STV090x_OFFST_Px_RX_END_FIELD          7
-#define STV090x_WIDTH_Px_RX_END_FIELD          1
-#define STV090x_OFFST_Px_RX_ACTIVE_FIELD       6
-#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD       1
-#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD     5
-#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD     1
-#define STV090x_OFFST_Px_CONT_TONE_FIELD       4
-#define STV090x_WIDTH_Px_CONT_TONE_FIELD       1
-#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD    3
-#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD    1
-#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD      2
-#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD      1
-#define STV090x_OFFST_Px_ABORT_DISRX_FIELD     0
-#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD     1
-
-#define STV090x_Px_DISRX_ST1(__x)              (0xf1a5 - (__x - 1) * 0x10)
-#define STV090x_P1_DISRX_ST1                   STV090x_Px_DISRX_ST1(1)
-#define STV090x_P2_DISRX_ST1                   STV090x_Px_DISRX_ST1(2)
-#define STV090x_OFFST_Px_RX_FAIL_FIELD         7
-#define STV090x_WIDTH_Px_RX_FAIL_FIELD         1
-#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6
-#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1
-#define STV090x_OFFST_Px_RX_NONBYTE_FIELD      5
-#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD      1
-#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD   4
-#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD   1
-#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD    0
-#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD    4
-
-#define STV090x_Px_DISRXDATA(__x)              (0xf1a6 - (__x - 1) * 0x10)
-#define STV090x_P1_DISRXDATA                   STV090x_Px_DISRXDATA(1)
-#define STV090x_P2_DISRXDATA                   STV090x_Px_DISRXDATA(2)
-#define STV090x_OFFST_Px_DISRX_DATA_FIELD      0
-#define STV090x_WIDTH_Px_DISRX_DATA_FIELD      8
-
-#define STV090x_Px_DISTXDATA(__x)              (0xf1a7 - (__x - 1) * 0x10)
-#define STV090x_P1_DISTXDATA                   STV090x_Px_DISTXDATA(1)
-#define STV090x_P2_DISTXDATA                   STV090x_Px_DISTXDATA(2)
-#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD     0
-#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD     8
-
-#define STV090x_Px_DISTXSTATUS(__x)            (0xf1a8 - (__x - 1) * 0x10)
-#define STV090x_P1_DISTXSTATUS                 STV090x_Px_DISTXSTATUS(1)
-#define STV090x_P2_DISTXSTATUS                 STV090x_Px_DISTXSTATUS(2)
-#define STV090x_OFFST_Px_TX_FAIL_FIELD         7
-#define STV090x_WIDTH_Px_TX_FAIL_FIELD         1
-#define STV090x_OFFST_Px_FIFO_FULL_FIELD       6
-#define STV090x_WIDTH_Px_FIFO_FULL_FIELD       1
-#define STV090x_OFFST_Px_TX_IDLE_FIELD         5
-#define STV090x_WIDTH_Px_TX_IDLE_FIELD         1
-#define STV090x_OFFST_Px_GAP_BURST_FIELD       4
-#define STV090x_WIDTH_Px_GAP_BURST_FIELD       1
-#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD    0
-#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD    4
-
-#define STV090x_Px_F22TX(__x)                  (0xf1a9 - (__x - 1) * 0x10)
-#define STV090x_P1_F22TX                       STV090x_Px_F22TX(1)
-#define STV090x_P2_F22TX                       STV090x_Px_F22TX(2)
-#define STV090x_OFFST_Px_F22_REG_FIELD         0
-#define STV090x_WIDTH_Px_F22_REG_FIELD         8
-
-#define STV090x_Px_F22RX(__x)                  (0xf1aa - (__x - 1) * 0x10)
-#define STV090x_P1_F22RX                       STV090x_Px_F22RX(1)
-#define STV090x_P2_F22RX                       STV090x_Px_F22RX(2)
-#define STV090x_OFFST_Px_F22RX_REG_FIELD       0
-#define STV090x_WIDTH_Px_F22RX_REG_FIELD       8
-
-#define STV090x_Px_ACRPRESC(__x)               (0xf1ac - (__x - 1) * 0x10)
-#define STV090x_P1_ACRPRESC                    STV090x_Px_ACRPRESC(1)
-#define STV090x_P2_ACRPRESC                    STV090x_Px_ACRPRESC(2)
-#define STV090x_OFFST_Px_ACR_PRESC_FIELD       0
-#define STV090x_WIDTH_Px_ACR_PRESC_FIELD       3
-
-#define STV090x_Px_ACRDIV(__x)                 (0xf1ad - (__x - 1) * 0x10)
-#define STV090x_P1_ACRDIV                      STV090x_Px_ACRDIV(1)
-#define STV090x_P2_ACRDIV                      STV090x_Px_ACRDIV(2)
-#define STV090x_OFFST_Px_ACR_DIV_FIELD         0
-#define STV090x_WIDTH_Px_ACR_DIV_FIELD         8
-
-#define STV090x_Px_IQCONST(__x)                        (0xF400 - (__x - 1) * 0x200)
-#define STV090x_P1_IQCONST                     STV090x_Px_IQCONST(1)
-#define STV090x_P2_IQCONST                     STV090x_Px_IQCONST(2)
-#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD  5
-#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD  2
-
-#define STV090x_Px_NOSCFG(__x)                 (0xF401 - (__x - 1) * 0x200)
-#define STV090x_P1_NOSCFG                      STV090x_Px_NOSCFG(1)
-#define STV090x_P2_NOSCFG                      STV090x_Px_NOSCFG(2)
-#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD     3
-#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD     2
-#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD    0
-#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD    3
-
-#define STV090x_Px_ISYMB(__x)                  (0xF402 - (__x - 1) * 0x200)
-#define STV090x_P1_ISYMB                       STV090x_Px_ISYMB(1)
-#define STV090x_P2_ISYMB                       STV090x_Px_ISYMB(2)
-#define STV090x_OFFST_Px_I_SYMBOL_FIELD                0
-#define STV090x_WIDTH_Px_I_SYMBOL_FIELD                8
-
-#define STV090x_Px_QSYMB(__x)                  (0xF403 - (__x - 1) * 0x200)
-#define STV090x_P1_QSYMB                       STV090x_Px_QSYMB(1)
-#define STV090x_P2_QSYMB                       STV090x_Px_QSYMB(2)
-#define STV090x_OFFST_Px_Q_SYMBOL_FIELD                0
-#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD                8
-
-#define STV090x_Px_AGC1CFG(__x)                        (0xF404 - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1CFG                     STV090x_Px_AGC1CFG(1)
-#define STV090x_P2_AGC1CFG                     STV090x_Px_AGC1CFG(2)
-#define STV090x_OFFST_Px_DC_FROZEN_FIELD       7
-#define STV090x_WIDTH_Px_DC_FROZEN_FIELD       1
-#define STV090x_OFFST_Px_DC_CORRECT_FIELD      6
-#define STV090x_WIDTH_Px_DC_CORRECT_FIELD      1
-#define STV090x_OFFST_Px_AMM_FROZEN_FIELD      5
-#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD      1
-#define STV090x_OFFST_Px_AMM_CORRECT_FIELD     4
-#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD     1
-#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD     3
-#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD     1
-#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD    2
-#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD    1
-
-#define STV090x_Px_AGC1CN(__x)                 (0xF406 - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1CN                      STV090x_Px_AGC1CN(1)
-#define STV090x_P2_AGC1CN                      STV090x_Px_AGC1CN(2)
-#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD     7
-#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD     1
-#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD   4
-#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD   1
-#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD     3
-#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD     1
-#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD      0
-#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD      3
-
-#define STV090x_Px_AGC1REF(__x)                        (0xF407 - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1REF                     STV090x_Px_AGC1REF(1)
-#define STV090x_P2_AGC1REF                     STV090x_Px_AGC1REF(2)
-#define STV090x_OFFST_Px_AGCIQ_REF_FIELD       0
-#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD       8
-
-#define STV090x_Px_IDCCOMP(__x)                        (0xF408 - (__x - 1) * 0x200)
-#define STV090x_P1_IDCCOMP                     STV090x_Px_IDCCOMP(1)
-#define STV090x_P2_IDCCOMP                     STV090x_Px_IDCCOMP(2)
-#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD    0
-#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD    8
-
-#define STV090x_Px_QDCCOMP(__x)                        (0xF409 - (__x - 1) * 0x200)
-#define STV090x_P1_QDCCOMP                     STV090x_Px_QDCCOMP(1)
-#define STV090x_P2_QDCCOMP                     STV090x_Px_QDCCOMP(2)
-#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD    0
-#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD    8
-
-#define STV090x_Px_POWERI(__x)                 (0xF40A - (__x - 1) * 0x200)
-#define STV090x_P1_POWERI                      STV090x_Px_POWERI(1)
-#define STV090x_P2_POWERI                      STV090x_Px_POWERI(2)
-#define STV090x_OFFST_Px_POWER_I_FIELD         0
-#define STV090x_WIDTH_Px_POWER_I_FIELD         8
-
-#define STV090x_Px_POWERQ(__x)                 (0xF40B - (__x - 1) * 0x200)
-#define STV090x_P1_POWERQ                      STV090x_Px_POWERQ(1)
-#define STV090x_P2_POWERQ                      STV090x_Px_POWERQ(2)
-#define STV090x_OFFST_Px_POWER_Q_FIELD         0
-#define STV090x_WIDTH_Px_POWER_Q_FIELD         8
-
-#define STV090x_Px_AGC1AMM(__x)                        (0xF40C - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1AMM                     STV090x_Px_AGC1AMM(1)
-#define STV090x_P2_AGC1AMM                     STV090x_Px_AGC1AMM(2)
-#define STV090x_OFFST_Px_AMM_VALUE_FIELD       0
-#define STV090x_WIDTH_Px_AMM_VALUE_FIELD       8
-
-#define STV090x_Px_AGC1QUAD(__x)               (0xF40D - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1QUAD                    STV090x_Px_AGC1QUAD(1)
-#define STV090x_P2_AGC1QUAD                    STV090x_Px_AGC1QUAD(2)
-#define STV090x_OFFST_Px_QUAD_VALUE_FIELD      0
-#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD      8
-
-#define STV090x_Px_AGCIQINy(__x, __y)          (0xF40F - (__x-1) * 0x200 - __y * 0x1)
-#define STV090x_P1_AGCIQIN0                    STV090x_Px_AGCIQINy(1, 0)
-#define STV090x_P1_AGCIQIN1                    STV090x_Px_AGCIQINy(1, 1)
-#define STV090x_P2_AGCIQIN0                    STV090x_Px_AGCIQINy(2, 0)
-#define STV090x_P2_AGCIQIN1                    STV090x_Px_AGCIQINy(2, 1)
-#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD     0
-#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD     8
-
-#define STV090x_Px_DEMOD(__x)                  (0xF410 - (__x - 1) * 0x200)
-#define STV090x_P1_DEMOD                       STV090x_Px_DEMOD(1)
-#define STV090x_P2_DEMOD                       STV090x_Px_DEMOD(2)
-#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD        7
-#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD        1
-#define STV090x_OFFST_Px_DEMOD_STOP_FIELD      6
-#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD      1
-#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4
-#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2
-#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD   3
-#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD   1
-#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD        2
-#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD        1
-#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0
-#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2
-
-#define STV090x_Px_DMDMODCOD(__x)              (0xF411 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDMODCOD                   STV090x_Px_DMDMODCOD(1)
-#define STV090x_P2_DMDMODCOD                   STV090x_Px_DMDMODCOD(2)
-#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD   7
-#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD   1
-#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD    2
-#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD    5
-#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD      0
-#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD      2
-
-#define STV090x_Px_DSTATUS(__x)                        (0xF412 - (__x - 1) * 0x200)
-#define STV090x_P1_DSTATUS                     STV090x_Px_DSTATUS(1)
-#define STV090x_P2_DSTATUS                     STV090x_Px_DSTATUS(2)
-#define STV090x_OFFST_Px_CAR_LOCK_FIELD                7
-#define STV090x_WIDTH_Px_CAR_LOCK_FIELD                1
-#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5
-#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2
-#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD  3
-#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD  1
-
-#define STV090x_Px_DSTATUS2(__x)               (0xF413 - (__x - 1) * 0x200)
-#define STV090x_P1_DSTATUS2                    STV090x_Px_DSTATUS2(1)
-#define STV090x_P2_DSTATUS2                    STV090x_Px_DSTATUS2(2)
-#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD    7
-#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD    1
-#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD        3
-#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD        1
-#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD   2
-#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD   1
-#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD    1
-#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD    1
-#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0
-#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1
-
-#define STV090x_Px_DMDCFGMD(__x)               (0xF414 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDCFGMD                    STV090x_Px_DMDCFGMD(1)
-#define STV090x_P2_DMDCFGMD                    STV090x_Px_DMDCFGMD(2)
-#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD    7
-#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD    1
-#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD    6
-#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD    1
-#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD     4
-#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD     1
-#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD    3
-#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD    1
-#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD  2
-#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD  1
-#define STV090x_OFFST_Px_TUN_RNG_FIELD         0
-#define STV090x_WIDTH_Px_TUN_RNG_FIELD         2
-
-#define STV090x_Px_DMDCFG2(__x)                        (0xF415 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDCFG2                     STV090x_Px_DMDCFG2(1)
-#define STV090x_P2_DMDCFG2                     STV090x_Px_DMDCFG2(2)
-#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6
-#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1
-
-#define STV090x_Px_DMDISTATE(__x)              (0xF416 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDISTATE                   STV090x_Px_DMDISTATE(1)
-#define STV090x_P2_DMDISTATE                   STV090x_Px_DMDISTATE(2)
-#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD  0
-#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD  5
-
-#define STV090x_Px_DMDTOM(__x)                 (0xF417 - (__x - 1) * 0x200) /* check */
-#define STV090x_P1_DMDTOM                      STV090x_Px_DMDTOM(1)
-#define STV090x_P2_DMDTOM                      STV090x_Px_DMDTOM(2)
-
-#define STV090x_Px_DMDSTATE(__x)               (0xF41B - (__x - 1) * 0x200)
-#define STV090x_P1_DMDSTATE                    STV090x_Px_DMDSTATE(1)
-#define STV090x_P2_DMDSTATE                    STV090x_Px_DMDSTATE(2)
-#define STV090x_OFFST_Px_HEADER_MODE_FIELD     5
-#define STV090x_WIDTH_Px_HEADER_MODE_FIELD     2
-
-#define STV090x_Px_DMDFLYW(__x)                        (0xF41C - (__x - 1) * 0x200)
-#define STV090x_P1_DMDFLYW                     STV090x_Px_DMDFLYW(1)
-#define STV090x_P2_DMDFLYW                     STV090x_Px_DMDFLYW(2)
-#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD      4
-#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD      4
-#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD    0
-#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD    4
-
-#define STV090x_Px_DSTATUS3(__x)               (0xF41D - (__x - 1) * 0x200)
-#define STV090x_P1_DSTATUS3                    STV090x_Px_DSTATUS3(1)
-#define STV090x_P2_DSTATUS3                    STV090x_Px_DSTATUS3(2)
-#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD   5
-#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD   2
-
-#define STV090x_Px_DMDCFG3(__x)                        (0xF41E - (__x - 1) * 0x200)
-#define STV090x_P1_DMDCFG3                     STV090x_Px_DMDCFG3(1)
-#define STV090x_P2_DMDCFG3                     STV090x_Px_DMDCFG3(2)
-#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3
-#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1
-
-#define STV090x_Px_DMDCFG4(__x)                        (0xf41f - (__x - 1) * 0x200)
-#define STV090x_P1_DMDCFG4                     STV090x_Px_DMDCFG4(1)
-#define STV090x_P2_DMDCFG4                     STV090x_Px_DMDCFG4(2)
-
-#define STV090x_Px_CORRELMANT(__x)             (0xF420 - (__x - 1) * 0x200)
-#define STV090x_P1_CORRELMANT                  STV090x_Px_CORRELMANT(1)
-#define STV090x_P2_CORRELMANT                  STV090x_Px_CORRELMANT(2)
-#define STV090x_OFFST_Px_CORREL_MANT_FIELD     0
-#define STV090x_WIDTH_Px_CORREL_MANT_FIELD     8
-
-#define STV090x_Px_CORRELABS(__x)              (0xF421 - (__x - 1) * 0x200)
-#define STV090x_P1_CORRELABS                   STV090x_Px_CORRELABS(1)
-#define STV090x_P2_CORRELABS                   STV090x_Px_CORRELABS(2)
-#define STV090x_OFFST_Px_CORREL_ABS_FIELD      0
-#define STV090x_WIDTH_Px_CORREL_ABS_FIELD      8
-
-#define STV090x_Px_CORRELEXP(__x)              (0xF422 - (__x - 1) * 0x200)
-#define STV090x_P1_CORRELEXP                   STV090x_Px_CORRELEXP(1)
-#define STV090x_P2_CORRELEXP                   STV090x_Px_CORRELEXP(2)
-#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD   4
-#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD   4
-#define STV090x_OFFST_Px_CORREL_EXP_FIELD      0
-#define STV090x_WIDTH_Px_CORREL_EXP_FIELD      4
-
-#define STV090x_Px_PLHMODCOD(__x)              (0xF424 - (__x - 1) * 0x200)
-#define STV090x_P1_PLHMODCOD                   STV090x_Px_PLHMODCOD(1)
-#define STV090x_P2_PLHMODCOD                   STV090x_Px_PLHMODCOD(2)
-#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD   7
-#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD   1
-#define STV090x_OFFST_Px_PLH_MODCOD_FIELD      2
-#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD      5
-#define STV090x_OFFST_Px_PLH_TYPE_FIELD                0
-#define STV090x_WIDTH_Px_PLH_TYPE_FIELD                2
-
-#define STV090x_Px_AGCK32(__x)                 (0xf42b - (__x - 1) * 0x200)
-#define STV090x_P1_AGCK32                      STV090x_Px_AGCK32(1)
-#define STV090x_P2_AGCK32                      STV090x_Px_AGCK32(2)
-
-#define STV090x_Px_AGC2O(__x)                  (0xF42C - (__x - 1) * 0x200)
-#define STV090x_P1_AGC2O                       STV090x_Px_AGC2O(1)
-#define STV090x_P2_AGC2O                       STV090x_Px_AGC2O(2)
-
-#define STV090x_Px_AGC2REF(__x)                        (0xF42D - (__x - 1) * 0x200)
-#define STV090x_P1_AGC2REF                     STV090x_Px_AGC2REF(1)
-#define STV090x_P2_AGC2REF                     STV090x_Px_AGC2REF(2)
-#define STV090x_OFFST_Px_AGC2_REF_FIELD                0
-#define STV090x_WIDTH_Px_AGC2_REF_FIELD                8
-
-#define STV090x_Px_AGC1ADJ(__x)                        (0xF42E - (__x - 1) * 0x200)
-#define STV090x_P1_AGC1ADJ                     STV090x_Px_AGC1ADJ(1)
-#define STV090x_P2_AGC1ADJ                     STV090x_Px_AGC1ADJ(2)
-#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD   0
-#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD   7
-
-#define STV090x_Px_AGC2Iy(__x, __y)            (0xF437 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_AGC2I0                      STV090x_Px_AGC2Iy(1, 0)
-#define STV090x_P1_AGC2I1                      STV090x_Px_AGC2Iy(1, 1)
-#define STV090x_P2_AGC2I0                      STV090x_Px_AGC2Iy(2, 0)
-#define STV090x_P2_AGC2I1                      STV090x_Px_AGC2Iy(2, 1)
-#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0
-#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8
-
-#define STV090x_Px_CARCFG(__x)                 (0xF438 - (__x - 1) * 0x200)
-#define STV090x_P1_CARCFG                      STV090x_Px_CARCFG(1)
-#define STV090x_P2_CARCFG                      STV090x_Px_CARCFG(2)
-#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD   5
-#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD   1
-#define STV090x_OFFST_Px_ROTATON_FIELD         2
-#define STV090x_WIDTH_Px_ROTATON_FIELD         1
-#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD     0
-#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD     2
-
-#define STV090x_Px_ACLC(__x)                   (0xF439 - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC                                STV090x_Px_ACLC(1)
-#define STV090x_P2_ACLC                                STV090x_Px_ACLC(2)
-#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD  4
-#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD  2
-#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD   0
-#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD   4
-
-#define STV090x_Px_BCLC(__x)                   (0xF43A - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC                                STV090x_Px_BCLC(1)
-#define STV090x_P2_BCLC                                STV090x_Px_BCLC(2)
-#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD   4
-#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD   2
-#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD    0
-#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD    4
-
-#define STV090x_Px_CARFREQ(__x)                        (0xF43D - (__x - 1) * 0x200)
-#define STV090x_P1_CARFREQ                     STV090x_Px_CARFREQ(1)
-#define STV090x_P2_CARFREQ                     STV090x_Px_CARFREQ(2)
-#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD   4
-#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD   4
-#define STV090x_OFFST_Px_BETA_FREQ_FIELD       0
-#define STV090x_WIDTH_Px_BETA_FREQ_FIELD       4
-
-#define STV090x_Px_CARHDR(__x)                 (0xF43E - (__x - 1) * 0x200)
-#define STV090x_P1_CARHDR                      STV090x_Px_CARHDR(1)
-#define STV090x_P2_CARHDR                      STV090x_Px_CARHDR(2)
-#define STV090x_OFFST_Px_FREQ_HDR_FIELD                0
-#define STV090x_WIDTH_Px_FREQ_HDR_FIELD                8
-
-#define STV090x_Px_LDT(__x)                    (0xF43F - (__x - 1) * 0x200)
-#define STV090x_P1_LDT                         STV090x_Px_LDT(1)
-#define STV090x_P2_LDT                         STV090x_Px_LDT(2)
-#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD   0
-#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD   8
-
-#define STV090x_Px_LDT2(__x)                   (0xF440 - (__x - 1) * 0x200)
-#define STV090x_P1_LDT2                                STV090x_Px_LDT2(1)
-#define STV090x_P2_LDT2                                STV090x_Px_LDT2(2)
-#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD  0
-#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD  8
-
-#define STV090x_Px_CFRICFG(__x)                        (0xF441 - (__x - 1) * 0x200)
-#define STV090x_P1_CFRICFG                     STV090x_Px_CFRICFG(1)
-#define STV090x_P2_CFRICFG                     STV090x_Px_CFRICFG(2)
-#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD     0
-#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD     1
-
-#define STV090x_Pn_CFRUPy(__x, __y)            (0xF443 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_CFRUP0                      STV090x_Pn_CFRUPy(1, 0)
-#define STV090x_P1_CFRUP1                      STV090x_Pn_CFRUPy(1, 1)
-#define STV090x_P2_CFRUP0                      STV090x_Pn_CFRUPy(2, 0)
-#define STV090x_P2_CFRUP1                      STV090x_Pn_CFRUPy(2, 1)
-#define STV090x_OFFST_Px_CFR_UP_FIELD          0
-#define STV090x_WIDTH_Px_CFR_UP_FIELD          8
-
-#define STV090x_Pn_CFRLOWy(__x, __y)           (0xF447 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_CFRLOW0                     STV090x_Pn_CFRLOWy(1, 0)
-#define STV090x_P1_CFRLOW1                     STV090x_Pn_CFRLOWy(1, 1)
-#define STV090x_P2_CFRLOW0                     STV090x_Pn_CFRLOWy(2, 0)
-#define STV090x_P2_CFRLOW1                     STV090x_Pn_CFRLOWy(2, 1)
-#define STV090x_OFFST_Px_CFR_LOW_FIELD         0
-#define STV090x_WIDTH_Px_CFR_LOW_FIELD         8
-
-#define STV090x_Pn_CFRINITy(__x, __y)          (0xF449 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_CFRINIT0                    STV090x_Pn_CFRINITy(1, 0)
-#define STV090x_P1_CFRINIT1                    STV090x_Pn_CFRINITy(1, 1)
-#define STV090x_P2_CFRINIT0                    STV090x_Pn_CFRINITy(2, 0)
-#define STV090x_P2_CFRINIT1                    STV090x_Pn_CFRINITy(2, 1)
-#define STV090x_OFFST_Px_CFR_INIT_FIELD                0
-#define STV090x_WIDTH_Px_CFR_INIT_FIELD                8
-
-#define STV090x_Px_CFRINC1(__x)                        (0xF44A - (__x - 1) * 0x200)
-#define STV090x_P1_CFRINC1                     STV090x_Px_CFRINC1(1)
-#define STV090x_P2_CFRINC1                     STV090x_Px_CFRINC1(2)
-#define STV090x_OFFST_Px_CFR_INC1_FIELD                0
-#define STV090x_WIDTH_Px_CFR_INC1_FIELD                7 /* check */
-
-#define STV090x_Px_CFRINC0(__x)                        (0xF44B - (__x - 1) * 0x200)
-#define STV090x_P1_CFRINC0                     STV090x_Px_CFRINC0(1)
-#define STV090x_P2_CFRINC0                     STV090x_Px_CFRINC0(2)
-#define STV090x_OFFST_Px_CFR_INC0_FIELD                4 /* check */
-#define STV090x_WIDTH_Px_CFR_INC0_FIELD                4
-
-#define STV090x_Pn_CFRy(__x, __y)              (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_CFR0                                STV090x_Pn_CFRy(1, 0)
-#define STV090x_P1_CFR1                                STV090x_Pn_CFRy(1, 1)
-#define STV090x_P1_CFR2                                STV090x_Pn_CFRy(1, 2)
-#define STV090x_P2_CFR0                                STV090x_Pn_CFRy(2, 0)
-#define STV090x_P2_CFR1                                STV090x_Pn_CFRy(2, 1)
-#define STV090x_P2_CFR2                                STV090x_Pn_CFRy(2, 2)
-#define STV090x_OFFST_Px_CAR_FREQ_FIELD                0
-#define STV090x_WIDTH_Px_CAR_FREQ_FIELD                8
-
-#define STV090x_Px_LDI(__x)                    (0xF44F - (__x - 1) * 0x200)
-#define STV090x_P1_LDI                         STV090x_Px_LDI(1)
-#define STV090x_P2_LDI                         STV090x_Px_LDI(2)
-#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0
-#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8
-
-#define STV090x_Px_TMGCFG(__x)                 (0xF450 - (__x - 1) * 0x200)
-#define STV090x_P1_TMGCFG                      STV090x_Px_TMGCFG(1)
-#define STV090x_P2_TMGCFG                      STV090x_Px_TMGCFG(2)
-#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD    6
-#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD    2
-#define STV090x_OFFST_Px_DO_TIMING_FIELD       4
-#define STV090x_WIDTH_Px_DO_TIMING_FIELD       1
-#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD     0
-#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD     2
-
-#define STV090x_Px_RTC(__x)                    (0xF451 - (__x - 1) * 0x200)
-#define STV090x_P1_RTC                         STV090x_Px_RTC(1)
-#define STV090x_P2_RTC                         STV090x_Px_RTC(2)
-#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD    4
-#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD    4
-#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD     0
-#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD     4
-
-#define STV090x_Px_RTCS2(__x)                  (0xF452 - (__x - 1) * 0x200)
-#define STV090x_P1_RTCS2                       STV090x_Px_RTCS2(1)
-#define STV090x_P2_RTCS2                       STV090x_Px_RTCS2(2)
-#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD  4
-#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD  4
-#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD   0
-#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD   4
-
-#define STV090x_Px_TMGTHRISE(__x)              (0xF453 - (__x - 1) * 0x200)
-#define STV090x_P1_TMGTHRISE                   STV090x_Px_TMGTHRISE(1)
-#define STV090x_P2_TMGTHRISE                   STV090x_Px_TMGTHRISE(2)
-#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD  0
-#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD  8
-
-#define STV090x_Px_TMGTHFALL(__x)              (0xF454 - (__x - 1) * 0x200)
-#define STV090x_P1_TMGTHFALL                   STV090x_Px_TMGTHFALL(1)
-#define STV090x_P2_TMGTHFALL                   STV090x_Px_TMGTHFALL(2)
-#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD  0
-#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD  8
-
-#define STV090x_Px_SFRUPRATIO(__x)             (0xF455 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRUPRATIO                  STV090x_Px_SFRUPRATIO(1)
-#define STV090x_P2_SFRUPRATIO                  STV090x_Px_SFRUPRATIO(2)
-#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD     0
-#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD     8
-
-#define STV090x_Px_SFRLOWRATIO(__x)            (0xF456 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRLOWRATIO                 STV090x_Px_SFRLOWRATIO(1)
-#define STV090x_P2_SFRLOWRATIO                 STV090x_Px_SFRLOWRATIO(2)
-#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD    0
-#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD    8
-
-#define STV090x_Px_KREFTMG(__x)                        (0xF458 - (__x - 1) * 0x200)
-#define STV090x_P1_KREFTMG                     STV090x_Px_KREFTMG(1)
-#define STV090x_P2_KREFTMG                     STV090x_Px_KREFTMG(2)
-#define STV090x_OFFST_Px_KREF_TMG_FIELD                0
-#define STV090x_WIDTH_Px_KREF_TMG_FIELD                8
-
-#define STV090x_Px_SFRSTEP(__x)                        (0xF459 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRSTEP                     STV090x_Px_SFRSTEP(1)
-#define STV090x_P2_SFRSTEP                     STV090x_Px_SFRSTEP(2)
-#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD    4
-#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD    4
-#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD  0
-#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD  4
-
-#define STV090x_Px_TMGCFG2(__x)                        (0xF45A - (__x - 1) * 0x200)
-#define STV090x_P1_TMGCFG2                     STV090x_Px_TMGCFG2(1)
-#define STV090x_P2_TMGCFG2                     STV090x_Px_TMGCFG2(2)
-#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD   0
-#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD   1
-
-#define STV090x_Px_SFRINIT1(__x)               (0xF45E - (__x - 1) * 0x200)
-#define STV090x_P1_SFRINIT1                    STV090x_Px_SFRINIT1(1)
-#define STV090x_P2_SFRINIT1                    STV090x_Px_SFRINIT1(2)
-#define STV090x_OFFST_Px_SFR_INIT1_FIELD       0
-#define STV090x_WIDTH_Px_SFR_INIT1_FIELD       7
-
-#define STV090x_Px_SFRINIT0(__x)               (0xF45F - (__x - 1) * 0x200)
-#define STV090x_P1_SFRINIT0                    STV090x_Px_SFRINIT0(1)
-#define STV090x_P2_SFRINIT0                    STV090x_Px_SFRINIT0(2)
-#define STV090x_OFFST_Px_SFR_INIT0_FIELD       0
-#define STV090x_WIDTH_Px_SFR_INIT0_FIELD       8
-
-#define STV090x_Px_SFRUP1(__x)                 (0xF460 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRUP1                      STV090x_Px_SFRUP1(1)
-#define STV090x_P2_SFRUP1                      STV090x_Px_SFRUP1(2)
-#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD   0
-#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD   7
-
-#define STV090x_Px_SFRUP0(__x)                 (0xF461 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRUP0                      STV090x_Px_SFRUP0(1)
-#define STV090x_P2_SFRUP0                      STV090x_Px_SFRUP0(2)
-#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD   0
-#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD   8
-
-#define STV090x_Px_SFRLOW1(__x)                        (0xF462 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRLOW1                     STV090x_Px_SFRLOW1(1)
-#define STV090x_P2_SFRLOW1                     STV090x_Px_SFRLOW1(2)
-#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD  0
-#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD  7
-
-#define STV090x_Px_SFRLOW0(__x)                        (0xF463 - (__x - 1) * 0x200)
-#define STV090x_P1_SFRLOW0                     STV090x_Px_SFRLOW0(1)
-#define STV090x_P2_SFRLOW0                     STV090x_Px_SFRLOW0(2)
-#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD  0
-#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD  8
-
-#define STV090x_Px_SFRy(__x, __y)              (0xF467 - (__x-1) * 0x200 - __y)
-#define STV090x_P1_SFR0                                STV090x_Px_SFRy(1, 0)
-#define STV090x_P1_SFR1                                STV090x_Px_SFRy(1, 1)
-#define STV090x_P1_SFR2                                STV090x_Px_SFRy(1, 2)
-#define STV090x_P1_SFR3                                STV090x_Px_SFRy(1, 3)
-#define STV090x_P2_SFR0                                STV090x_Px_SFRy(2, 0)
-#define STV090x_P2_SFR1                                STV090x_Px_SFRy(2, 1)
-#define STV090x_P2_SFR2                                STV090x_Px_SFRy(2, 2)
-#define STV090x_P2_SFR3                                STV090x_Px_SFRy(2, 3)
-#define STV090x_OFFST_Px_SYMB_FREQ_FIELD       0
-#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD       8
-
-#define STV090x_Px_TMGREG2(__x)                        (0xF468 - (__x - 1) * 0x200)
-#define STV090x_P1_TMGREG2                     STV090x_Px_TMGREG2(1)
-#define STV090x_P2_TMGREG2                     STV090x_Px_TMGREG2(2)
-#define STV090x_OFFST_Px_TMGREG_FIELD          0
-#define STV090x_WIDTH_Px_TMGREG_FIELD          8
-
-#define STV090x_Px_TMGREG1(__x)                        (0xF469 - (__x - 1) * 0x200)
-#define STV090x_P1_TMGREG1                     STV090x_Px_TMGREG1(1)
-#define STV090x_P2_TMGREG1                     STV090x_Px_TMGREG1(2)
-#define STV090x_OFFST_Px_TMGREG_FIELD          0
-#define STV090x_WIDTH_Px_TMGREG_FIELD          8
-
-#define STV090x_Px_TMGREG0(__x)                        (0xF46A - (__x - 1) * 0x200)
-#define STV090x_P1_TMGREG0                     STV090x_Px_TMGREG0(1)
-#define STV090x_P2_TMGREG0                     STV090x_Px_TMGREG0(2)
-#define STV090x_OFFST_Px_TMGREG_FIELD          0
-#define STV090x_WIDTH_Px_TMGREG_FIELD          8
-
-#define STV090x_Px_TMGLOCKy(__x, __y)          (0xF46C - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_TMGLOCK0                    STV090x_Px_TMGLOCKy(1, 0)
-#define STV090x_P1_TMGLOCK1                    STV090x_Px_TMGLOCKy(1, 1)
-#define STV090x_P2_TMGLOCK0                    STV090x_Px_TMGLOCKy(2, 0)
-#define STV090x_P2_TMGLOCK1                    STV090x_Px_TMGLOCKy(2, 1)
-#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD   0
-#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD   8
-
-#define STV090x_Px_TMGOBS(__x)                 (0xF46D - (__x - 1) * 0x200)
-#define STV090x_P1_TMGOBS                      STV090x_Px_TMGOBS(1)
-#define STV090x_P2_TMGOBS                      STV090x_Px_TMGOBS(2)
-#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD  6
-#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD  2
-
-#define STV090x_Px_EQUALCFG(__x)               (0xF46F - (__x - 1) * 0x200)
-#define STV090x_P1_EQUALCFG                    STV090x_Px_EQUALCFG(1)
-#define STV090x_P2_EQUALCFG                    STV090x_Px_EQUALCFG(2)
-#define STV090x_OFFST_Px_EQUAL_ON_FIELD                6
-#define STV090x_WIDTH_Px_EQUAL_ON_FIELD                1
-#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD     0
-#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD     3
-
-#define STV090x_Px_EQUAIy(__x, __y)    (0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
-#define STV090x_P1_EQUAI1                      STV090x_Px_EQUAIy(1, 1)
-#define STV090x_P1_EQUAI2                      STV090x_Px_EQUAIy(1, 2)
-#define STV090x_P1_EQUAI3                      STV090x_Px_EQUAIy(1, 3)
-#define STV090x_P1_EQUAI4                      STV090x_Px_EQUAIy(1, 4)
-#define STV090x_P1_EQUAI5                      STV090x_Px_EQUAIy(1, 5)
-#define STV090x_P1_EQUAI6                      STV090x_Px_EQUAIy(1, 6)
-#define STV090x_P1_EQUAI7                      STV090x_Px_EQUAIy(1, 7)
-#define STV090x_P1_EQUAI8                      STV090x_Px_EQUAIy(1, 8)
-
-#define STV090x_P2_EQUAI1                      STV090x_Px_EQUAIy(2, 1)
-#define STV090x_P2_EQUAI2                      STV090x_Px_EQUAIy(2, 2)
-#define STV090x_P2_EQUAI3                      STV090x_Px_EQUAIy(2, 3)
-#define STV090x_P2_EQUAI4                      STV090x_Px_EQUAIy(2, 4)
-#define STV090x_P2_EQUAI5                      STV090x_Px_EQUAIy(2, 5)
-#define STV090x_P2_EQUAI6                      STV090x_Px_EQUAIy(2, 6)
-#define STV090x_P2_EQUAI7                      STV090x_Px_EQUAIy(2, 7)
-#define STV090x_P2_EQUAI8                      STV090x_Px_EQUAIy(2, 8)
-#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD      0
-#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD      8
-
-#define STV090x_Px_EQUAQy(__x, __y)    (0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
-#define STV090x_P1_EQUAQ1                      STV090x_Px_EQUAQy(1, 1)
-#define STV090x_P1_EQUAQ2                      STV090x_Px_EQUAQy(1, 2)
-#define STV090x_P1_EQUAQ3                      STV090x_Px_EQUAQy(1, 3)
-#define STV090x_P1_EQUAQ4                      STV090x_Px_EQUAQy(1, 4)
-#define STV090x_P1_EQUAQ5                      STV090x_Px_EQUAQy(1, 5)
-#define STV090x_P1_EQUAQ6                      STV090x_Px_EQUAQy(1, 6)
-#define STV090x_P1_EQUAQ7                      STV090x_Px_EQUAQy(1, 7)
-#define STV090x_P1_EQUAQ8                      STV090x_Px_EQUAQy(1, 8)
-
-#define STV090x_P2_EQUAQ1                      STV090x_Px_EQUAQy(2, 1)
-#define STV090x_P2_EQUAQ2                      STV090x_Px_EQUAQy(2, 2)
-#define STV090x_P2_EQUAQ3                      STV090x_Px_EQUAQy(2, 3)
-#define STV090x_P2_EQUAQ4                      STV090x_Px_EQUAQy(2, 4)
-#define STV090x_P2_EQUAQ5                      STV090x_Px_EQUAQy(2, 5)
-#define STV090x_P2_EQUAQ6                      STV090x_Px_EQUAQy(2, 6)
-#define STV090x_P2_EQUAQ7                      STV090x_Px_EQUAQy(2, 7)
-#define STV090x_P2_EQUAQ8                      STV090x_Px_EQUAQy(2, 8)
-#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD      0
-#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD      8
-
-#define STV090x_Px_NNOSDATATy(__x, __y)                (0xf481 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NNOSDATAT0                  STV090x_Px_NNOSDATATy(1, 0)
-#define STV090x_P1_NNOSDATAT1                  STV090x_Px_NNOSDATATy(1, 1)
-#define STV090x_P2_NNOSDATAT0                  STV090x_Px_NNOSDATATy(2, 0)
-#define STV090x_P2_NNOSDATAT1                  STV090x_Px_NNOSDATATy(2, 1)
-#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0
-#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8
-
-#define STV090x_Px_NNOSDATAy(__x, __y)         (0xf483 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NNOSDATA0                   STV090x_Px_NNOSDATAy(1, 0)
-#define STV090x_P1_NNOSDATA1                   STV090x_Px_NNOSDATAy(1, 1)
-#define STV090x_P2_NNOSDATA0                   STV090x_Px_NNOSDATAy(2, 0)
-#define STV090x_P2_NNOSDATA1                   STV090x_Px_NNOSDATAy(2, 1)
-#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD  0
-#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD  8
-
-#define STV090x_Px_NNOSPLHTy(__x, __y)         (0xf485 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NNOSPLHT0                   STV090x_Px_NNOSPLHTy(1, 0)
-#define STV090x_P1_NNOSPLHT1                   STV090x_Px_NNOSPLHTy(1, 1)
-#define STV090x_P2_NNOSPLHT0                   STV090x_Px_NNOSPLHTy(2, 0)
-#define STV090x_P2_NNOSPLHT1                   STV090x_Px_NNOSPLHTy(2, 1)
-#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD  0
-#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD  8
-
-#define STV090x_Px_NNOSPLHy(__x, __y)          (0xf487 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NNOSPLH0                    STV090x_Px_NNOSPLHy(1, 0)
-#define STV090x_P1_NNOSPLH1                    STV090x_Px_NNOSPLHy(1, 1)
-#define STV090x_P2_NNOSPLH0                    STV090x_Px_NNOSPLHy(2, 0)
-#define STV090x_P2_NNOSPLH1                    STV090x_Px_NNOSPLHy(2, 1)
-#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD   0
-#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD   8
-
-#define STV090x_Px_NOSDATATy(__x, __y)                 (0xf489 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NOSDATAT0                           STV090x_Px_NOSDATATy(1, 0)
-#define STV090x_P1_NOSDATAT1                           STV090x_Px_NOSDATATy(1, 1)
-#define STV090x_P2_NOSDATAT0                           STV090x_Px_NOSDATATy(2, 0)
-#define STV090x_P2_NOSDATAT1                           STV090x_Px_NOSDATATy(2, 1)
-#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD       0
-#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD       8
-
-#define STV090x_Px_NOSDATAy(__x, __y)          (0xf48b - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NOSDATA0                    STV090x_Px_NOSDATAy(1, 0)
-#define STV090x_P1_NOSDATA1                    STV090x_Px_NOSDATAy(1, 1)
-#define STV090x_P2_NOSDATA0                    STV090x_Px_NOSDATAy(2, 0)
-#define STV090x_P2_NOSDATA1                    STV090x_Px_NOSDATAy(2, 1)
-#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD        0
-#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD        8
-
-#define STV090x_Px_NOSPLHTy(__x, __y)          (0xf48d - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NOSPLHT0                    STV090x_Px_NOSPLHTy(1, 0)
-#define STV090x_P1_NOSPLHT1                    STV090x_Px_NOSPLHTy(1, 1)
-#define STV090x_P2_NOSPLHT0                    STV090x_Px_NOSPLHTy(2, 0)
-#define STV090x_P2_NOSPLHT1                    STV090x_Px_NOSPLHTy(2, 1)
-#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD        0
-#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD        8
-
-#define STV090x_Px_NOSPLHy(__x, __y)           (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_NOSPLH0                     STV090x_Px_NOSPLHy(1, 0)
-#define STV090x_P1_NOSPLH1                     STV090x_Px_NOSPLHy(1, 1)
-#define STV090x_P2_NOSPLH0                     STV090x_Px_NOSPLHy(2, 0)
-#define STV090x_P2_NOSPLH1                     STV090x_Px_NOSPLHy(2, 1)
-#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
-#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
-
-#define STV090x_Px_CAR2CFG(__x)                        (0xf490 - (__x - 1) * 0x200)
-#define STV090x_P1_CAR2CFG                     STV090x_Px_CAR2CFG(1)
-#define STV090x_P2_CAR2CFG                     STV090x_Px_CAR2CFG(2)
-#define STV090x_OFFST_Px_PN4_SELECT_FIELD      6
-#define STV090x_WIDTH_Px_PN4_SELECT_FIELD      1
-#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD  5
-#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD  1
-#define STV090x_OFFST_Px_ROTA2ON_FIELD         2
-#define STV090x_WIDTH_Px_ROTA2ON_FIELD         1
-#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD    0
-#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD    2
-
-#define STV090x_Px_ACLC2(__x)                  (0xf491 - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC2                       STV090x_Px_ACLC2(1)
-#define STV090x_P2_ACLC2                       STV090x_Px_ACLC2(2)
-#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4
-#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2
-#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD  0
-#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD  4
-
-#define STV090x_Px_BCLC2(__x)                  (0xf492 - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC2                       STV090x_Px_BCLC2(1)
-#define STV090x_P2_BCLC2                       STV090x_Px_BCLC2(2)
-#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD  4
-#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD  2
-#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD   0
-#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD   4
-
-#define STV090x_Px_ACLC2S2Q(__x)               (0xf497 - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC2S2Q                    STV090x_Px_ACLC2S2Q(1)
-#define STV090x_P2_ACLC2S2Q                    STV090x_Px_ACLC2S2Q(2)
-#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD   7
-#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD   1
-#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4
-#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2
-#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0
-#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4
-
-#define STV090x_Px_ACLC2S28(__x)               (0xf498 - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC2S28                    STV090x_Px_ACLC2S28(1)
-#define STV090x_P2_ACLC2S28                    STV090x_Px_ACLC2S28(2)
-#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4
-#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2
-#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0
-#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4
-
-#define STV090x_Px_ACLC2S216A(__x)             (0xf499 - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC2S216A                  STV090x_Px_ACLC2S216A(1)
-#define STV090x_P2_ACLC2S216A                  STV090x_Px_ACLC2S216A(2)
-#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD       4
-#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD       2
-#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD       0
-#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD       4
-
-#define STV090x_Px_ACLC2S232A(__x)             (0xf49A - (__x - 1) * 0x200)
-#define STV090x_P1_ACLC2S232A                  STV090x_Px_ACLC2S232A(1)
-#define STV090x_P2_ACLC2S232A                  STV090x_Px_ACLC2S232A(2)
-#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD       4
-#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD       2
-#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD       0
-#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD       4
-
-#define STV090x_Px_BCLC2S2Q(__x)               (0xf49c - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC2S2Q                    STV090x_Px_BCLC2S2Q(1)
-#define STV090x_P2_BCLC2S2Q                    STV090x_Px_BCLC2S2Q(2)
-#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4
-#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2
-#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0
-#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4
-
-#define STV090x_Px_BCLC2S28(__x)               (0xf49d - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC2S28                    STV090x_Px_BCLC2S28(1)
-#define STV090x_P2_BCLC2S28                    STV090x_Px_BCLC2S28(2)
-#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
-#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
-#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
-#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
-
-#define STV090x_Px_BCLC2S216A(__x)             (0xf49e - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC2S216A                  STV090x_Px_BCLC2S216A(1)
-#define STV090x_P2_BCLC2S216A                  STV090x_Px_BCLC2S216A(2)
-#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD       4
-#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD       2
-#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD       0
-#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD       4
-
-#define STV090x_Px_BCLC2S232A(__x)             (0xf49f - (__x - 1) * 0x200)
-#define STV090x_P1_BCLC2S232A                  STV090x_Px_BCLC2S232A(1)
-#define STV090x_P2_BCLC2S232A                  STV090x_Px_BCLC2S232A(2)
-#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD       4
-#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD       2
-#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD       0
-#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD       4
-
-#define STV090x_Px_PLROOT2(__x)                        (0xf4ac - (__x - 1) * 0x200)
-#define STV090x_P1_PLROOT2                     STV090x_Px_PLROOT2(1)
-#define STV090x_P2_PLROOT2                     STV090x_Px_PLROOT2(2)
-#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD   2
-#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD   2
-#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD   0
-#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD   2
-
-#define STV090x_Px_PLROOT1(__x)                        (0xf4ad - (__x - 1) * 0x200)
-#define STV090x_P1_PLROOT1                     STV090x_Px_PLROOT1(1)
-#define STV090x_P2_PLROOT1                     STV090x_Px_PLROOT1(2)
-#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD  0
-#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD  8
-
-#define STV090x_Px_PLROOT0(__x)                        (0xf4ae - (__x - 1) * 0x200)
-#define STV090x_P1_PLROOT0                     STV090x_Px_PLROOT0(1)
-#define STV090x_P2_PLROOT0                     STV090x_Px_PLROOT0(2)
-#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD  0
-#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD  8
-
-#define STV090x_Px_MODCODLST0(__x)             (0xf4b0 - (__x - 1) * 0x200) /* check */
-#define STV090x_P1_MODCODLST0                  STV090x_Px_MODCODLST0(1)
-#define STV090x_P2_MODCODLST0                  STV090x_Px_MODCODLST0(2)
-
-#define STV090x_Px_MODCODLST1(__x)             (0xf4b1 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST1                  STV090x_Px_MODCODLST1(1)
-#define STV090x_P2_MODCODLST1                  STV090x_Px_MODCODLST1(2)
-#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD    4
-#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD    4
-#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD  0
-#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD  4
-
-#define STV090x_Px_MODCODLST2(__x)             (0xf4b2 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST2                  STV090x_Px_MODCODLST2(1)
-#define STV090x_P2_MODCODLST2                  STV090x_Px_MODCODLST2(2)
-#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD   4
-#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD   4
-#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD   0
-#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD   4
-
-#define STV090x_Px_MODCODLST3(__x)             (0xf4b3 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST3                  STV090x_Px_MODCODLST3(1)
-#define STV090x_P2_MODCODLST3                  STV090x_Px_MODCODLST3(2)
-#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD   4
-#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD   4
-#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD   0
-#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD   4
-
-#define STV090x_Px_MODCODLST4(__x)             (0xf4b4 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST4                  STV090x_Px_MODCODLST4(1)
-#define STV090x_P2_MODCODLST4                  STV090x_Px_MODCODLST4(2)
-#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD  4
-#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD  4
-#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD   0
-#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD   4
-
-#define STV090x_Px_MODCODLST5(__x)             (0xf4b5 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST5                  STV090x_Px_MODCODLST5(1)
-#define STV090x_P2_MODCODLST5                  STV090x_Px_MODCODLST5(2)
-#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD   4
-#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD   4
-#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD   0
-#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD   4
-
-#define STV090x_Px_MODCODLST6(__x)             (0xf4b6 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST6                  STV090x_Px_MODCODLST6(1)
-#define STV090x_P2_MODCODLST6                  STV090x_Px_MODCODLST6(2)
-#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD   4
-#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD   4
-#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD   0
-#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD   4
-
-#define STV090x_Px_MODCODLST7(__x)             (0xf4b7 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST7                  STV090x_Px_MODCODLST7(1)
-#define STV090x_P2_MODCODLST7                  STV090x_Px_MODCODLST7(2)
-#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD     4
-#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD     4
-#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD      0
-#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD      4
-
-#define STV090x_Px_MODCODLST8(__x)             (0xf4b8 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST8                  STV090x_Px_MODCODLST8(1)
-#define STV090x_P2_MODCODLST8                  STV090x_Px_MODCODLST8(2)
-#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD      4
-#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD      4
-#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD      0
-#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD      4
-
-#define STV090x_Px_MODCODLST9(__x)             (0xf4b9 - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLST9                  STV090x_Px_MODCODLST9(1)
-#define STV090x_P2_MODCODLST9                  STV090x_Px_MODCODLST9(2)
-#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD      4
-#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD      4
-#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD      0
-#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD      4
-
-#define STV090x_Px_MODCODLSTA(__x)             (0xf4ba - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTA                  STV090x_Px_MODCODLSTA(1)
-#define STV090x_P2_MODCODLSTA                  STV090x_Px_MODCODLSTA(2)
-#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD     4
-#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD     4
-#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD      0
-#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD      4
-
-#define STV090x_Px_MODCODLSTB(__x)             (0xf4bb - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTB                  STV090x_Px_MODCODLSTB(1)
-#define STV090x_P2_MODCODLSTB                  STV090x_Px_MODCODLSTB(2)
-#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD      4
-#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD      4
-#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD      0
-#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD      4
-
-#define STV090x_Px_MODCODLSTC(__x)             (0xf4bc - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTC                  STV090x_Px_MODCODLSTC(1)
-#define STV090x_P2_MODCODLSTC                  STV090x_Px_MODCODLSTC(2)
-#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD      4
-#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD      4
-#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD      0
-#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD      4
-
-#define STV090x_Px_MODCODLSTD(__x)             (0xf4bd - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTD                  STV090x_Px_MODCODLSTD(1)
-#define STV090x_P2_MODCODLSTD                  STV090x_Px_MODCODLSTD(2)
-#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD      4
-#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD      4
-#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD      0
-#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD      4
-
-#define STV090x_Px_MODCODLSTE(__x)             (0xf4be - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTE                  STV090x_Px_MODCODLSTE(1)
-#define STV090x_P2_MODCODLSTE                  STV090x_Px_MODCODLSTE(2)
-#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD      4
-#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD      4
-#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD      0
-#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD      4
-
-#define STV090x_Px_MODCODLSTF(__x)             (0xf4bf - (__x - 1) * 0x200)
-#define STV090x_P1_MODCODLSTF                  STV090x_Px_MODCODLSTF(1)
-#define STV090x_P2_MODCODLSTF                  STV090x_Px_MODCODLSTF(2)
-#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD      4
-#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD      4
-
-#define STV090x_Px_GAUSSR0(__x)                        (0xf4c0 - (__x - 1) * 0x200)
-#define STV090x_P1_GAUSSR0                     STV090x_Px_GAUSSR0(1)
-#define STV090x_P2_GAUSSR0                     STV090x_Px_GAUSSR0(2)
-#define STV090x_OFFST_Px_EN_CCIMODE_FIELD      7
-#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD      1
-#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD     0
-#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD     7
-
-#define STV090x_Px_CCIR0(__x)                  (0xf4c1 - (__x - 1) * 0x200)
-#define STV090x_P1_CCIR0                       STV090x_Px_CCIR0(1)
-#define STV090x_P2_CCIR0                       STV090x_Px_CCIR0(2)
-#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD   7
-#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD   1
-#define STV090x_OFFST_Px_R0_CCI_FIELD          0
-#define STV090x_WIDTH_Px_R0_CCI_FIELD          7
-
-#define STV090x_Px_CCIQUANT(__x)               (0xf4c2 - (__x - 1) * 0x200)
-#define STV090x_P1_CCIQUANT                    STV090x_Px_CCIQUANT(1)
-#define STV090x_P2_CCIQUANT                    STV090x_Px_CCIQUANT(2)
-#define STV090x_OFFST_Px_CCI_BETA_FIELD                5
-#define STV090x_WIDTH_Px_CCI_BETA_FIELD                3
-#define STV090x_OFFST_Px_CCI_QUANT_FIELD       0
-#define STV090x_WIDTH_Px_CCI_QUANT_FIELD       5
-
-#define STV090x_Px_CCITHRESH(__x)              (0xf4c3 - (__x - 1) * 0x200)
-#define STV090x_P1_CCITHRESH                   STV090x_Px_CCITHRESH(1)
-#define STV090x_P2_CCITHRESH                   STV090x_Px_CCITHRESH(2)
-#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD   0
-#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD   8
-
-#define STV090x_Px_CCIACC(__x)                 (0xf4c4 - (__x - 1) * 0x200)
-#define STV090x_P1_CCIACC                      STV090x_Px_CCIACC(1)
-#define STV090x_P2_CCIACC                      STV090x_Px_CCIACC(2)
-#define STV090x_OFFST_Px_CCI_VALUE_FIELD       0
-#define STV090x_WIDTH_Px_CCI_VALUE_FIELD       8
-
-#define STV090x_Px_DMDRESCFG(__x)              (0xF4C6 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDRESCFG                   STV090x_Px_DMDRESCFG(1)
-#define STV090x_P2_DMDRESCFG                   STV090x_Px_DMDRESCFG(2)
-#define STV090x_OFFST_Px_DMDRES_RESET_FIELD    7
-#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD    1
-
-#define STV090x_Px_DMDRESADR(__x)              (0xF4C7 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDRESADR                   STV090x_Px_DMDRESADR(1)
-#define STV090x_P2_DMDRESADR                   STV090x_Px_DMDRESADR(2)
-#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD   0
-#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD   4
-
-#define STV090x_Px_DMDRESDATAy(__x, __y)       (0xF4C8 - (__x - 1) * 0x200 + (7 - __y))
-#define STV090x_P1_DMDRESDATA0                 STV090x_Px_DMDRESDATAy(1, 0)
-#define STV090x_P1_DMDRESDATA1                 STV090x_Px_DMDRESDATAy(1, 1)
-#define STV090x_P1_DMDRESDATA2                 STV090x_Px_DMDRESDATAy(1, 2)
-#define STV090x_P1_DMDRESDATA3                 STV090x_Px_DMDRESDATAy(1, 3)
-#define STV090x_P1_DMDRESDATA4                 STV090x_Px_DMDRESDATAy(1, 4)
-#define STV090x_P1_DMDRESDATA5                 STV090x_Px_DMDRESDATAy(1, 5)
-#define STV090x_P1_DMDRESDATA6                 STV090x_Px_DMDRESDATAy(1, 6)
-#define STV090x_P1_DMDRESDATA7                 STV090x_Px_DMDRESDATAy(1, 7)
-#define STV090x_P2_DMDRESDATA0                 STV090x_Px_DMDRESDATAy(2, 0)
-#define STV090x_P2_DMDRESDATA1                 STV090x_Px_DMDRESDATAy(2, 1)
-#define STV090x_P2_DMDRESDATA2                 STV090x_Px_DMDRESDATAy(2, 2)
-#define STV090x_P2_DMDRESDATA3                 STV090x_Px_DMDRESDATAy(2, 3)
-#define STV090x_P2_DMDRESDATA4                 STV090x_Px_DMDRESDATAy(2, 4)
-#define STV090x_P2_DMDRESDATA5                 STV090x_Px_DMDRESDATAy(2, 5)
-#define STV090x_P2_DMDRESDATA6                 STV090x_Px_DMDRESDATAy(2, 6)
-#define STV090x_P2_DMDRESDATA7                 STV090x_Px_DMDRESDATAy(2, 7)
-#define STV090x_OFFST_Px_DMDRES_DATA_FIELD     0
-#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD     8
-
-#define STV090x_Px_FFEIy(__x, __y)             (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
-#define STV090x_P1_FFEI1                       STV090x_Px_FFEIy(1, 1)
-#define STV090x_P1_FFEI2                       STV090x_Px_FFEIy(1, 2)
-#define STV090x_P1_FFEI3                       STV090x_Px_FFEIy(1, 3)
-#define STV090x_P1_FFEI4                       STV090x_Px_FFEIy(1, 4)
-#define STV090x_P2_FFEI1                       STV090x_Px_FFEIy(2, 1)
-#define STV090x_P2_FFEI2                       STV090x_Px_FFEIy(2, 2)
-#define STV090x_P2_FFEI3                       STV090x_Px_FFEIy(2, 3)
-#define STV090x_P2_FFEI4                       STV090x_Px_FFEIy(2, 4)
-#define STV090x_OFFST_Px_FFE_ACCIy_FIELD       0
-#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD       8
-
-#define STV090x_Px_FFEQy(__x, __y)             (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
-#define STV090x_P1_FFEQ1                       STV090x_Px_FFEQy(1, 1)
-#define STV090x_P1_FFEQ2                       STV090x_Px_FFEQy(1, 2)
-#define STV090x_P1_FFEQ3                       STV090x_Px_FFEQy(1, 3)
-#define STV090x_P1_FFEQ4                       STV090x_Px_FFEQy(1, 4)
-#define STV090x_P2_FFEQ1                       STV090x_Px_FFEQy(2, 1)
-#define STV090x_P2_FFEQ2                       STV090x_Px_FFEQy(2, 2)
-#define STV090x_P2_FFEQ3                       STV090x_Px_FFEQy(2, 3)
-#define STV090x_P2_FFEQ4                       STV090x_Px_FFEQy(2, 4)
-#define STV090x_OFFST_Px_FFE_ACCQy_FIELD       0
-#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD       8
-
-#define STV090x_Px_FFECFG(__x)                 (0xf4d8 - (__x - 1) * 0x200)
-#define STV090x_P1_FFECFG                      STV090x_Px_FFECFG(1)
-#define STV090x_P2_FFECFG                      STV090x_Px_FFECFG(2)
-#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD     6
-#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD     1
-
-#define STV090x_Px_SMAPCOEF7(__x)              (0xf500 - (__x - 1) * 0x200)
-#define STV090x_P1_SMAPCOEF7                   STV090x_Px_SMAPCOEF7(1)
-#define STV090x_P2_SMAPCOEF7                   STV090x_Px_SMAPCOEF7(2)
-#define STV090x_OFFST_Px_DIS_QSCALE_FIELD      7
-#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD      1
-#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD        0
-#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD        7
-
-#define STV090x_Px_SMAPCOEF6(__x)              (0xf501 - (__x - 1) * 0x200)
-#define STV090x_P1_SMAPCOEF6                   STV090x_Px_SMAPCOEF6(1)
-#define STV090x_P2_SMAPCOEF6                   STV090x_Px_SMAPCOEF6(2)
-#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD    2
-#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD    1
-#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD    1
-#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD    1
-#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD      0
-#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD      1
-
-#define STV090x_Px_SMAPCOEF5(__x)                      (0xf502 - (__x - 1) * 0x200)
-#define STV090x_P1_SMAPCOEF5                           STV090x_Px_SMAPCOEF5(1)
-#define STV090x_P2_SMAPCOEF5                           STV090x_Px_SMAPCOEF5(2)
-#define STV090x_OFFST_Px_DIS_8SCALE_FIELD              7
-#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD              1
-#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD       0
-#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD       7
-
-#define STV090x_Px_DMDPLHSTAT(__x)             (0xF520 - (__x - 1) * 0x200)
-#define STV090x_P1_DMDPLHSTAT                  STV090x_Px_DMDPLHSTAT(1)
-#define STV090x_P2_DMDPLHSTAT                  STV090x_Px_DMDPLHSTAT(2)
-#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD   0
-#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD   8
-
-#define STV090x_Px_LOCKTIMEy(__x, __y)         (0xF525 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_LOCKTIME0                   STV090x_Px_LOCKTIMEy(1, 0)
-#define STV090x_P1_LOCKTIME1                   STV090x_Px_LOCKTIMEy(1, 1)
-#define STV090x_P1_LOCKTIME2                   STV090x_Px_LOCKTIMEy(1, 2)
-#define STV090x_P1_LOCKTIME3                   STV090x_Px_LOCKTIMEy(1, 3)
-#define STV090x_P2_LOCKTIME0                   STV090x_Px_LOCKTIMEy(2, 0)
-#define STV090x_P2_LOCKTIME1                   STV090x_Px_LOCKTIMEy(2, 1)
-#define STV090x_P2_LOCKTIME2                   STV090x_Px_LOCKTIMEy(2, 2)
-#define STV090x_P2_LOCKTIME3                   STV090x_Px_LOCKTIMEy(2, 3)
-#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD  0
-#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD  8
-
-#define STV090x_Px_TNRCFG(__x)                 (0xf4e0 - (__x - 1) * 0x200) /* check */
-#define STV090x_P1_TNRCFG                      STV090x_Px_TNRCFG(1)
-#define STV090x_P2_TNRCFG                      STV090x_Px_TNRCFG(2)
-
-#define STV090x_Px_TNRCFG2(__x)                        (0xf4e1 - (__x - 1) * 0x200)
-#define STV090x_P1_TNRCFG2                     STV090x_Px_TNRCFG2(1)
-#define STV090x_P2_TNRCFG2                     STV090x_Px_TNRCFG2(2)
-#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD      7
-#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD      1
-
-#define STV090x_Px_VITSCALE(__x)               (0xf532 - (__x - 1) * 0x200)
-#define STV090x_P1_VITSCALE                    STV090x_Px_VITSCALE(1)
-#define STV090x_P2_VITSCALE                    STV090x_Px_VITSCALE(2)
-#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD   7
-#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD   1
-#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD  6
-#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD  1
-#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD  3
-#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD  1
-#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD     1
-#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD     1
-
-#define STV090x_Px_FECM(__x)                   (0xf533 - (__x - 1) * 0x200)
-#define STV090x_P1_FECM                                STV090x_Px_FECM(1)
-#define STV090x_P2_FECM                                STV090x_Px_FECM(2)
-#define STV090x_OFFST_Px_DSS_DVB_FIELD         7
-#define STV090x_WIDTH_Px_DSS_DVB_FIELD         1
-#define STV090x_OFFST_Px_DSS_SRCH_FIELD                4
-#define STV090x_WIDTH_Px_DSS_SRCH_FIELD                1
-#define STV090x_OFFST_Px_SYNCVIT_FIELD         1
-#define STV090x_WIDTH_Px_SYNCVIT_FIELD         1
-#define STV090x_OFFST_Px_IQINV_FIELD           0
-#define STV090x_WIDTH_Px_IQINV_FIELD           1
-
-#define STV090x_Px_VTH12(__x)                  (0xf534 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH12                       STV090x_Px_VTH12(1)
-#define STV090x_P2_VTH12                       STV090x_Px_VTH12(2)
-#define STV090x_OFFST_Px_VTH12_FIELD           0
-#define STV090x_WIDTH_Px_VTH12_FIELD           8
-
-#define STV090x_Px_VTH23(__x)                  (0xf535 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH23                       STV090x_Px_VTH23(1)
-#define STV090x_P2_VTH23                       STV090x_Px_VTH23(2)
-#define STV090x_OFFST_Px_VTH23_FIELD           0
-#define STV090x_WIDTH_Px_VTH23_FIELD           8
-
-#define STV090x_Px_VTH34(__x)                  (0xf536 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH34                       STV090x_Px_VTH34(1)
-#define STV090x_P2_VTH34                       STV090x_Px_VTH34(2)
-#define STV090x_OFFST_Px_VTH34_FIELD           0
-#define STV090x_WIDTH_Px_VTH34_FIELD           8
-
-#define STV090x_Px_VTH56(__x)                  (0xf537 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH56                       STV090x_Px_VTH56(1)
-#define STV090x_P2_VTH56                       STV090x_Px_VTH56(2)
-#define STV090x_OFFST_Px_VTH56_FIELD           0
-#define STV090x_WIDTH_Px_VTH56_FIELD           8
-
-#define STV090x_Px_VTH67(__x)                  (0xf538 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH67                       STV090x_Px_VTH67(1)
-#define STV090x_P2_VTH67                       STV090x_Px_VTH67(2)
-#define STV090x_OFFST_Px_VTH67_FIELD           0
-#define STV090x_WIDTH_Px_VTH67_FIELD           8
-
-#define STV090x_Px_VTH78(__x)                  (0xf539 - (__x - 1) * 0x200)
-#define STV090x_P1_VTH78                       STV090x_Px_VTH78(1)
-#define STV090x_P2_VTH78                       STV090x_Px_VTH78(2)
-#define STV090x_OFFST_Px_VTH78_FIELD           0
-#define STV090x_WIDTH_Px_VTH78_FIELD           8
-
-#define STV090x_Px_VITCURPUN(__x)              (0xf53a - (__x - 1) * 0x200)
-#define STV090x_P1_VITCURPUN                   STV090x_Px_VITCURPUN(1)
-#define STV090x_P2_VITCURPUN                   STV090x_Px_VITCURPUN(2)
-#define STV090x_OFFST_Px_VIT_CURPUN_FIELD      0
-#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD      5
-
-#define STV090x_Px_VERROR(__x)                 (0xf53b - (__x - 1) * 0x200)
-#define STV090x_P1_VERROR                      STV090x_Px_VERROR(1)
-#define STV090x_P2_VERROR                      STV090x_Px_VERROR(2)
-#define STV090x_OFFST_Px_REGERR_VIT_FIELD      0
-#define STV090x_WIDTH_Px_REGERR_VIT_FIELD      8
-
-#define STV090x_Px_PRVIT(__x)                  (0xf53c - (__x - 1) * 0x200)
-#define STV090x_P1_PRVIT                       STV090x_Px_PRVIT(1)
-#define STV090x_P2_PRVIT                       STV090x_Px_PRVIT(2)
-#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD     6
-#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD     1
-#define STV090x_OFFST_Px_E7_8VIT_FIELD         5
-#define STV090x_WIDTH_Px_E7_8VIT_FIELD         1
-#define STV090x_OFFST_Px_E6_7VIT_FIELD         4
-#define STV090x_WIDTH_Px_E6_7VIT_FIELD         1
-#define STV090x_OFFST_Px_E5_6VIT_FIELD         3
-#define STV090x_WIDTH_Px_E5_6VIT_FIELD         1
-#define STV090x_OFFST_Px_E3_4VIT_FIELD         2
-#define STV090x_WIDTH_Px_E3_4VIT_FIELD         1
-#define STV090x_OFFST_Px_E2_3VIT_FIELD         1
-#define STV090x_WIDTH_Px_E2_3VIT_FIELD         1
-#define STV090x_OFFST_Px_E1_2VIT_FIELD         0
-#define STV090x_WIDTH_Px_E1_2VIT_FIELD         1
-
-#define STV090x_Px_VAVSRVIT(__x)               (0xf53d - (__x - 1) * 0x200)
-#define STV090x_P1_VAVSRVIT                    STV090x_Px_VAVSRVIT(1)
-#define STV090x_P2_VAVSRVIT                    STV090x_Px_VAVSRVIT(2)
-#define STV090x_OFFST_Px_SNVIT_FIELD           4
-#define STV090x_WIDTH_Px_SNVIT_FIELD           2
-#define STV090x_OFFST_Px_TOVVIT_FIELD          2
-#define STV090x_WIDTH_Px_TOVVIT_FIELD          2
-#define STV090x_OFFST_Px_HYPVIT_FIELD          0
-#define STV090x_WIDTH_Px_HYPVIT_FIELD          2
-
-#define STV090x_Px_VSTATUSVIT(__x)             (0xf53e - (__x - 1) * 0x200)
-#define STV090x_P1_VSTATUSVIT                  STV090x_Px_VSTATUSVIT(1)
-#define STV090x_P2_VSTATUSVIT                  STV090x_Px_VSTATUSVIT(2)
-#define STV090x_OFFST_Px_PRFVIT_FIELD          4
-#define STV090x_WIDTH_Px_PRFVIT_FIELD          1
-#define STV090x_OFFST_Px_LOCKEDVIT_FIELD       3
-#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD       1
-
-#define STV090x_Px_VTHINUSE(__x)               (0xf53f - (__x - 1) * 0x200)
-#define STV090x_P1_VTHINUSE                    STV090x_Px_VTHINUSE(1)
-#define STV090x_P2_VTHINUSE                    STV090x_Px_VTHINUSE(2)
-#define STV090x_OFFST_Px_VIT_INUSE_FIELD       0
-#define STV090x_WIDTH_Px_VIT_INUSE_FIELD       8
-
-#define STV090x_Px_KDIV12(__x)                 (0xf540 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV12                      STV090x_Px_KDIV12(1)
-#define STV090x_P2_KDIV12                      STV090x_Px_KDIV12(2)
-#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD    7
-
-#define STV090x_Px_KDIV23(__x)                 (0xf541 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV23                      STV090x_Px_KDIV23(1)
-#define STV090x_P2_KDIV23                      STV090x_Px_KDIV23(2)
-#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD    7
-
-#define STV090x_Px_KDIV34(__x)                 (0xf542 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV34                      STV090x_Px_KDIV34(1)
-#define STV090x_P2_KDIV34                      STV090x_Px_KDIV34(2)
-#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD    7
-
-#define STV090x_Px_KDIV56(__x)                 (0xf543 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV56                      STV090x_Px_KDIV56(1)
-#define STV090x_P2_KDIV56                      STV090x_Px_KDIV56(2)
-#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD    7
-
-#define STV090x_Px_KDIV67(__x)                 (0xf544 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV67                      STV090x_Px_KDIV67(1)
-#define STV090x_P2_KDIV67                      STV090x_Px_KDIV67(2)
-#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD    7
-
-#define STV090x_Px_KDIV78(__x)                 (0xf545 - (__x - 1) * 0x200)
-#define STV090x_P1_KDIV78                      STV090x_Px_KDIV78(1)
-#define STV090x_P2_KDIV78                      STV090x_Px_KDIV78(2)
-#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD    0
-#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD    7
-
-#define STV090x_Px_PDELCTRL1(__x)              (0xf550 - (__x - 1) * 0x200)
-#define STV090x_P1_PDELCTRL1                   STV090x_Px_PDELCTRL1(1)
-#define STV090x_P2_PDELCTRL1                   STV090x_Px_PDELCTRL1(2)
-#define STV090x_OFFST_Px_INV_MISMASK_FIELD     7
-#define STV090x_WIDTH_Px_INV_MISMASK_FIELD     1
-#define STV090x_OFFST_Px_FILTER_EN_FIELD       5
-#define STV090x_WIDTH_Px_FILTER_EN_FIELD       1
-#define STV090x_OFFST_Px_EN_MIS00_FIELD                1
-#define STV090x_WIDTH_Px_EN_MIS00_FIELD                1
-#define STV090x_OFFST_Px_ALGOSWRST_FIELD       0
-#define STV090x_WIDTH_Px_ALGOSWRST_FIELD       1
-
-#define STV090x_Px_PDELCTRL2(__x)              (0xf551 - (__x - 1) * 0x200)
-#define STV090x_P1_PDELCTRL2                   STV090x_Px_PDELCTRL2(1)
-#define STV090x_P2_PDELCTRL2                   STV090x_Px_PDELCTRL2(2)
-#define STV090x_OFFST_Px_FORCE_CONTINUOUS      7
-#define STV090x_WIDTH_Px_FORCE_CONTINUOUS      1
-#define STV090x_OFFST_Px_RESET_UPKO_COUNT      6
-#define STV090x_WIDTH_Px_RESET_UPKO_COUNT      1
-#define STV090x_OFFST_Px_USER_PKTDELIN_NB      5
-#define STV090x_WIDTH_Px_USER_PKTDELIN_NB      1
-#define STV090x_OFFST_Px_FORCE_LOCKED          4
-#define STV090x_WIDTH_Px_FORCE_LOCKED          1
-#define STV090x_OFFST_Px_DATA_UNBBSCRAM                3
-#define STV090x_WIDTH_Px_DATA_UNBBSCRAM                1
-#define STV090x_OFFST_Px_FORCE_LONGPACKET      2
-#define STV090x_WIDTH_Px_FORCE_LONGPACKET      1
-#define STV090x_OFFST_Px_FRAME_MODE_FIELD      1
-#define STV090x_WIDTH_Px_FRAME_MODE_FIELD      1
-
-#define STV090x_Px_HYSTTHRESH(__x)             (0xf554 - (__x - 1) * 0x200)
-#define STV090x_P1_HYSTTHRESH                  STV090x_Px_HYSTTHRESH(1)
-#define STV090x_P2_HYSTTHRESH                  STV090x_Px_HYSTTHRESH(2)
-#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD    4
-#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD    4
-#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD        0
-#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD        4
-
-#define STV090x_Px_ISIENTRY(__x)               (0xf55e - (__x - 1) * 0x200)
-#define STV090x_P1_ISIENTRY                    STV090x_Px_ISIENTRY(1)
-#define STV090x_P2_ISIENTRY                    STV090x_Px_ISIENTRY(2)
-#define STV090x_OFFST_Px_ISI_ENTRY_FIELD       0
-#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD       8
-
-#define STV090x_Px_ISIBITENA(__x)              (0xf55f - (__x - 1) * 0x200)
-#define STV090x_P1_ISIBITENA                   STV090x_Px_ISIBITENA(1)
-#define STV090x_P2_ISIBITENA                   STV090x_Px_ISIBITENA(2)
-#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD      0
-#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD      8
-
-#define STV090x_Px_MATSTRy(__x, __y)           (0xf561 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_MATSTR0                     STV090x_Px_MATSTRy(1, 0)
-#define STV090x_P1_MATSTR1                     STV090x_Px_MATSTRy(1, 1)
-#define STV090x_P2_MATSTR0                     STV090x_Px_MATSTRy(2, 0)
-#define STV090x_P2_MATSTR1                     STV090x_Px_MATSTRy(2, 1)
-#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD  0
-#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD  8
-
-#define STV090x_Px_UPLSTRy(__x, __y)           (0xf563 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_UPLSTR0                     STV090x_Px_UPLSTRy(1, 0)
-#define STV090x_P1_UPLSTR1                     STV090x_Px_UPLSTRy(1, 1)
-#define STV090x_P2_UPLSTR0                     STV090x_Px_UPLSTRy(2, 0)
-#define STV090x_P2_UPLSTR1                     STV090x_Px_UPLSTRy(2, 1)
-#define STV090x_OFFST_Px_UPL_CURRENT_FIELD     0
-#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD     8
-
-#define STV090x_Px_DFLSTRy(__x, __y)           (0xf565 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_DFLSTR0                     STV090x_Px_DFLSTRy(1, 0)
-#define STV090x_P1_DFLSTR1                     STV090x_Px_DFLSTRy(1, 1)
-#define STV090x_P2_DFLSTR0                     STV090x_Px_DFLSTRy(2, 0)
-#define STV090x_P2_DFLSTR1                     STV090x_Px_DFLSTRy(2, 1)
-#define STV090x_OFFST_Px_DFL_CURRENT_FIELD     0
-#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD     8
-
-#define STV090x_Px_SYNCSTR(__x)                        (0xf566 - (__x - 1) * 0x200)
-#define STV090x_P1_SYNCSTR                     STV090x_Px_SYNCSTR(1)
-#define STV090x_P2_SYNCSTR                     STV090x_Px_SYNCSTR(2)
-#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD    0
-#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD    8
-
-#define STV090x_Px_SYNCDSTRy(__x, __y)         (0xf568 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_SYNCDSTR0                   STV090x_Px_SYNCDSTRy(1, 0)
-#define STV090x_P1_SYNCDSTR1                   STV090x_Px_SYNCDSTRy(1, 1)
-#define STV090x_P2_SYNCDSTR0                   STV090x_Px_SYNCDSTRy(2, 0)
-#define STV090x_P2_SYNCDSTR1                   STV090x_Px_SYNCDSTRy(2, 1)
-#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD   0
-#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD   8
-
-#define STV090x_Px_PDELSTATUS1(__x)            (0xf569 - (__x - 1) * 0x200)
-#define STV090x_P1_PDELSTATUS1                 STV090x_Px_PDELSTATUS1(1)
-#define STV090x_P2_PDELSTATUS1                 STV090x_Px_PDELSTATUS1(2)
-#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD   1
-#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD   1
-#define STV090x_OFFST_Px_FIRST_LOCK_FIELD      0
-#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD      1
-
-#define STV090x_Px_PDELSTATUS2(__x)            (0xf56a - (__x - 1) * 0x200)
-#define STV090x_P1_PDELSTATUS2                 STV090x_Px_PDELSTATUS2(1)
-#define STV090x_P2_PDELSTATUS2                 STV090x_Px_PDELSTATUS2(2)
-#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD    2
-#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD    5
-#define STV090x_OFFST_Px_FRAME_TYPE_FIELD      0
-#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD      2
-
-#define STV090x_Px_BBFCRCKO1(__x)              (0xf56b - (__x - 1) * 0x200)
-#define STV090x_P1_BBFCRCKO1                   STV090x_Px_BBFCRCKO1(1)
-#define STV090x_P2_BBFCRCKO1                   STV090x_Px_BBFCRCKO1(2)
-#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD    0
-#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD    8
-
-#define STV090x_Px_BBFCRCKO0(__x)              (0xf56c - (__x - 1) * 0x200)
-#define STV090x_P1_BBFCRCKO0                   STV090x_Px_BBFCRCKO0(1)
-#define STV090x_P2_BBFCRCKO0                   STV090x_Px_BBFCRCKO0(2)
-#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD    0
-#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD    8
-
-#define STV090x_Px_UPCRCKO1(__x)               (0xf56d - (__x - 1) * 0x200)
-#define STV090x_P1_UPCRCKO1                    STV090x_Px_UPCRCKO1(1)
-#define STV090x_P2_UPCRCKO1                    STV090x_Px_UPCRCKO1(2)
-#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD    0
-#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD    8
-
-#define STV090x_Px_UPCRCKO0(__x)               (0xf56e - (__x - 1) * 0x200)
-#define STV090x_P1_UPCRCKO0                    STV090x_Px_UPCRCKO0(1)
-#define STV090x_P2_UPCRCKO0                    STV090x_Px_UPCRCKO0(2)
-#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD    0
-#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD    8
-
-#define STV090x_NBITER_NFx(__x)                                (0xFA03 + (__x - 4) * 0x1)
-#define STV090x_NBITER_NF4                             STV090x_NBITER_NFx(4)
-#define STV090x_NBITER_NF5                             STV090x_NBITER_NFx(5)
-#define STV090x_NBITER_NF6                             STV090x_NBITER_NFx(6)
-#define STV090x_NBITER_NF7                             STV090x_NBITER_NFx(7)
-#define STV090x_NBITER_NF8                             STV090x_NBITER_NFx(8)
-#define STV090x_NBITER_NF9                             STV090x_NBITER_NFx(9)
-#define STV090x_NBITER_NF10                            STV090x_NBITER_NFx(10)
-#define STV090x_NBITER_NF11                            STV090x_NBITER_NFx(11)
-#define STV090x_NBITER_NF12                            STV090x_NBITER_NFx(12)
-#define STV090x_NBITER_NF13                            STV090x_NBITER_NFx(13)
-#define STV090x_NBITER_NF14                            STV090x_NBITER_NFx(14)
-#define STV090x_NBITER_NF15                            STV090x_NBITER_NFx(15)
-#define STV090x_NBITER_NF16                            STV090x_NBITER_NFx(16)
-#define STV090x_NBITER_NF17                            STV090x_NBITER_NFx(17)
-
-#define STV090x_NBITERNOERR                            0xFA3F
-#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD           0
-#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD           4
-
-#define STV090x_GAINLLR_NFx(__x)                       (0xFA43 + (__x - 4) * 0x1)
-#define STV090x_GAINLLR_NF4                            STV090x_GAINLLR_NFx(4)
-#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD          7
-
-#define STV090x_GAINLLR_NF5                            STV090x_GAINLLR_NFx(5)
-#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD          7
-
-#define STV090x_GAINLLR_NF6                            STV090x_GAINLLR_NFx(6)
-#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD          7
-
-#define STV090x_GAINLLR_NF7                            STV090x_GAINLLR_NFx(7)
-#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD          7
-
-#define STV090x_GAINLLR_NF8                            STV090x_GAINLLR_NFx(8)
-#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD          7
-
-#define STV090x_GAINLLR_NF9                            STV090x_GAINLLR_NFx(9)
-#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD          7
-
-#define STV090x_GAINLLR_NF10                           STV090x_GAINLLR_NFx(10)
-#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD          7
-
-#define STV090x_GAINLLR_NF11                           STV090x_GAINLLR_NFx(11)
-#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD         0
-#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD         7
-
-#define STV090x_GAINLLR_NF12                           STV090x_GAINLLR_NFx(12)
-#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD          7
-
-#define STV090x_GAINLLR_NF13                           STV090x_GAINLLR_NFx(13)
-#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD          7
-
-#define STV090x_GAINLLR_NF14                           STV090x_GAINLLR_NFx(14)
-#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD          7
-
-#define STV090x_GAINLLR_NF15                           STV090x_GAINLLR_NFx(15)
-#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD          7
-
-#define STV090x_GAINLLR_NF16                           STV090x_GAINLLR_NFx(16)
-#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD          0
-#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD          7
-
-#define STV090x_GAINLLR_NF17                           STV090x_GAINLLR_NFx(17)
-#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD         0
-#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD         7
-
-#define STV090x_GENCFG                                 0xFA86
-#define STV090x_OFFST_BROADCAST_FIELD                  4
-#define STV090x_WIDTH_BROADCAST_FIELD                  1
-#define STV090x_OFFST_PRIORITY_FIELD                   1
-#define STV090x_WIDTH_PRIORITY_FIELD                   1
-#define STV090x_OFFST_DDEMOD_FIELD                     0
-#define STV090x_WIDTH_DDEMOD_FIELD                     1
-
-#define STV090x_LDPCERRx(__x)                          (0xFA97 - (__x  * 0x1))
-#define STV090x_LDPCERR0                               STV090x_LDPCERRx(0)
-#define STV090x_LDPCERR1                               STV090x_LDPCERRx(1)
-#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD     0
-#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD     8
-
-#define STV090x_BCHERR                                 0xFA98
-#define STV090x_OFFST_Px_ERRORFLAG_FIELD               4
-#define STV090x_WIDTH_Px_ERRORFLAG_FIELD               1
-#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD      0
-#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD      4
-
-#define STV090x_Px_TSSTATEM(__x)                       (0xF570 - (__x - 1) * 0x200)
-#define STV090x_P1_TSSTATEM                            STV090x_Px_TSSTATEM(1)
-#define STV090x_P2_TSSTATEM                            STV090x_Px_TSSTATEM(2)
-#define STV090x_OFFST_Px_TSDIL_ON_FIELD                        7
-#define STV090x_WIDTH_Px_TSDIL_ON_FIELD                        1
-#define STV090x_OFFST_Px_TSRS_ON_FIELD                 5
-#define STV090x_WIDTH_Px_TSRS_ON_FIELD                 1
-
-#define STV090x_Px_TSCFGH(__x)                         (0xF572 - (__x - 1) * 0x200)
-#define STV090x_P1_TSCFGH                              STV090x_Px_TSCFGH(1)
-#define STV090x_P2_TSCFGH                              STV090x_Px_TSCFGH(2)
-#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD            7
-#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD            1
-#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD           6
-#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD           1
-#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD                5
-#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD                1
-#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD           4
-#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD           1
-#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD         3
-#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD         1
-#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD                1
-#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD                2
-#define STV090x_OFFST_Px_RST_HWARE_FIELD               0
-#define STV090x_WIDTH_Px_RST_HWARE_FIELD               1
-
-#define STV090x_Px_TSCFGM(__x)                         (0xF573 - (__x - 1) * 0x200)
-#define STV090x_P1_TSCFGM                              STV090x_Px_TSCFGM(1)
-#define STV090x_P2_TSCFGM                              STV090x_Px_TSCFGM(2)
-#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD         6
-#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD         2
-#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD         5
-#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD         1
-#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD          0
-#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD          1
-
-#define STV090x_Px_TSCFGL(__x)                         (0xF574 - (__x - 1) * 0x200)
-#define STV090x_P1_TSCFGL                              STV090x_Px_TSCFGL(1)
-#define STV090x_P2_TSCFGL                              STV090x_Px_TSCFGL(2)
-#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD       6
-#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD       2
-#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD           4
-#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD           2
-#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD       3
-#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD       1
-#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD         2
-#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD         1
-#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD          1
-#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD          1
-
-#define STV090x_Px_TSINSDELH(__x)                      (0xF576 - (__x - 1) * 0x200)
-#define STV090x_P1_TSINSDELH                           STV090x_Px_TSINSDELH(1)
-#define STV090x_P2_TSINSDELH                           STV090x_Px_TSINSDELH(2)
-#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD          7
-#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD          1
-#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD          6
-#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD          1
-
-#define STV090x_Px_TSSPEED(__x)                                (0xF580 - (__x - 1) * 0x200)
-#define STV090x_P1_TSSPEED                             STV090x_Px_TSSPEED(1)
-#define STV090x_P2_TSSPEED                             STV090x_Px_TSSPEED(2)
-#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD         0
-#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD         8
-
-#define STV090x_Px_TSSTATUS(__x)                       (0xF581 - (__x - 1) * 0x200)
-#define STV090x_P1_TSSTATUS                            STV090x_Px_TSSTATUS(1)
-#define STV090x_P2_TSSTATUS                            STV090x_Px_TSSTATUS(2)
-#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD           7
-#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD           1
-#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD            6
-#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD            1
-
-#define STV090x_Px_TSSTATUS2(__x)                      (0xF582 - (__x - 1) * 0x200)
-#define STV090x_P1_TSSTATUS2                           STV090x_Px_TSSTATUS2(1)
-#define STV090x_P2_TSSTATUS2                           STV090x_Px_TSSTATUS2(2)
-#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD         7
-#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD         1
-#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD       6
-#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD       1
-#define STV090x_OFFST_Px_DILXX_RESET_FIELD             5
-#define STV090x_WIDTH_Px_DILXX_RESET_FIELD             1
-#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD          4
-#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD          1
-#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD            1
-#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD            1
-
-#define STV090x_Px_TSBITRATEy(__x, __y)                        (0xF584 - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_TSBITRATE0                          STV090x_Px_TSBITRATEy(1, 0)
-#define STV090x_P1_TSBITRATE1                          STV090x_Px_TSBITRATEy(1, 1)
-#define STV090x_P2_TSBITRATE0                          STV090x_Px_TSBITRATEy(2, 0)
-#define STV090x_P2_TSBITRATE1                          STV090x_Px_TSBITRATEy(2, 1)
-#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD          0
-#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD          8
-
-#define STV090x_Px_ERRCTRL1(__x)                       (0xF598 - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCTRL1                            STV090x_Px_ERRCTRL1(1)
-#define STV090x_P2_ERRCTRL1                            STV090x_Px_ERRCTRL1(2)
-#define STV090x_OFFST_Px_ERR_SOURCE_FIELD              4
-#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD              4
-#define STV090x_OFFST_Px_NUM_EVENT_FIELD               0
-#define STV090x_WIDTH_Px_NUM_EVENT_FIELD               3
-
-#define STV090x_Px_ERRCNT12(__x)                       (0xF599 - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT12                            STV090x_Px_ERRCNT12(1)
-#define STV090x_P2_ERRCNT12                            STV090x_Px_ERRCNT12(2)
-#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD                7
-#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD                1
-#define STV090x_OFFST_Px_ERR_CNT12_FIELD               0
-#define STV090x_WIDTH_Px_ERR_CNT12_FIELD               7
-
-#define STV090x_Px_ERRCNT11(__x)                       (0xF59A - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT11                            STV090x_Px_ERRCNT11(1)
-#define STV090x_P2_ERRCNT11                            STV090x_Px_ERRCNT11(2)
-#define STV090x_OFFST_Px_ERR_CNT11_FIELD               0
-#define STV090x_WIDTH_Px_ERR_CNT11_FIELD               8
-
-#define STV090x_Px_ERRCNT10(__x)                       (0xF59B - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT10                            STV090x_Px_ERRCNT10(1)
-#define STV090x_P2_ERRCNT10                            STV090x_Px_ERRCNT10(2)
-#define STV090x_OFFST_Px_ERR_CNT10_FIELD               0
-#define STV090x_WIDTH_Px_ERR_CNT10_FIELD               8
-
-#define STV090x_Px_ERRCTRL2(__x)                       (0xF59C - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCTRL2                            STV090x_Px_ERRCTRL2(1)
-#define STV090x_P2_ERRCTRL2                            STV090x_Px_ERRCTRL2(2)
-#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD             4
-#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD             4
-#define STV090x_OFFST_Px_NUM_EVENT2_FIELD              0
-#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD              3
-
-#define STV090x_Px_ERRCNT22(__x)                       (0xF59D - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT22                            STV090x_Px_ERRCNT22(1)
-#define STV090x_P2_ERRCNT22                            STV090x_Px_ERRCNT22(2)
-#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD                7
-#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD                1
-#define STV090x_OFFST_Px_ERR_CNT2_FIELD                        0
-#define STV090x_WIDTH_Px_ERR_CNT2_FIELD                        7
-
-#define STV090x_Px_ERRCNT21(__x)                       (0xF59E - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT21                            STV090x_Px_ERRCNT21(1)
-#define STV090x_P2_ERRCNT21                            STV090x_Px_ERRCNT21(2)
-#define STV090x_OFFST_Px_ERR_CNT21_FIELD               0
-#define STV090x_WIDTH_Px_ERR_CNT21_FIELD               8
-
-#define STV090x_Px_ERRCNT20(__x)                       (0xF59F - (__x - 1) * 0x200)
-#define STV090x_P1_ERRCNT20                            STV090x_Px_ERRCNT20(1)
-#define STV090x_P2_ERRCNT20                            STV090x_Px_ERRCNT20(2)
-#define STV090x_OFFST_Px_ERR_CNT20_FIELD               0
-#define STV090x_WIDTH_Px_ERR_CNT20_FIELD               8
-
-#define STV090x_Px_FECSPY(__x)                         (0xF5A0 - (__x - 1) * 0x200)
-#define STV090x_P1_FECSPY                              STV090x_Px_FECSPY(1)
-#define STV090x_P2_FECSPY                              STV090x_Px_FECSPY(2)
-#define STV090x_OFFST_Px_SPY_ENABLE_FIELD              7
-#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD              1
-#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD      2
-#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD      2
-
-#define STV090x_Px_FSPYCFG(__x)                                (0xF5A1 - (__x - 1) * 0x200)
-#define STV090x_P1_FSPYCFG                             STV090x_Px_FSPYCFG(1)
-#define STV090x_P2_FSPYCFG                             STV090x_Px_FSPYCFG(2)
-#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD            5
-#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD            1
-#define STV090x_OFFST_Px_ONE_SHOT_FIELD                        4
-#define STV090x_WIDTH_Px_ONE_SHOT_FIELD                        1
-#define STV090x_OFFST_Px_I2C_MODE_FIELD                        2
-#define STV090x_WIDTH_Px_I2C_MODE_FIELD                        2
-
-#define STV090x_Px_FSPYDATA(__x)                       (0xF5A2 - (__x - 1) * 0x200)
-#define STV090x_P1_FSPYDATA                            STV090x_Px_FSPYDATA(1)
-#define STV090x_P2_FSPYDATA                            STV090x_Px_FSPYDATA(2)
-#define STV090x_OFFST_Px_SPY_STUFFING_FIELD            7
-#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD            1
-#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD            5
-#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD            1
-#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD                0
-#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD                5
-
-#define STV090x_Px_FSPYOUT(__x)                                (0xF5A3 - (__x - 1) * 0x200)
-#define STV090x_P1_FSPYOUT                             STV090x_Px_FSPYOUT(1)
-#define STV090x_P2_FSPYOUT                             STV090x_Px_FSPYOUT(2)
-#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD             7
-#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD             1
-#define STV090x_OFFST_Px_STUFF_MODE_FIELD              0
-#define STV090x_WIDTH_Px_STUFF_MODE_FIELD              3
-
-#define STV090x_Px_FSTATUS(__x)                                (0xF5A4 - (__x - 1) * 0x200)
-#define STV090x_P1_FSTATUS                             STV090x_Px_FSTATUS(1)
-#define STV090x_P2_FSTATUS                             STV090x_Px_FSTATUS(2)
-#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD              7
-#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD              1
-#define STV090x_OFFST_Px_VALID_SIM_FIELD               6
-#define STV090x_WIDTH_Px_VALID_SIM_FIELD               1
-#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD            5
-#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD            1
-#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD            4
-#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD            1
-#define STV090x_OFFST_Px_RESULT_STATE_FIELD            0
-#define STV090x_WIDTH_Px_RESULT_STATE_FIELD            4
-
-#define STV090x_Px_FBERCPT4(__x)                       (0xF5A8 - (__x - 1) * 0x200)
-#define STV090x_P1_FBERCPT4                            STV090x_Px_FBERCPT4(1)
-#define STV090x_P2_FBERCPT4                            STV090x_Px_FBERCPT4(2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
-
-#define STV090x_Px_FBERCPT3(__x)                       (0xF5A9 - (__x - 1) * 0x200)
-#define STV090x_P1_FBERCPT3                            STV090x_Px_FBERCPT3(1)
-#define STV090x_P2_FBERCPT3                            STV090x_Px_FBERCPT3(2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
-
-#define STV090x_Px_FBERCPT2(__x)                       (0xF5AA - (__x - 1) * 0x200)
-#define STV090x_P1_FBERCPT2                            STV090x_Px_FBERCPT2(1)
-#define STV090x_P2_FBERCPT2                            STV090x_Px_FBERCPT2(2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
-
-#define STV090x_Px_FBERCPT1(__x)                       (0xF5AB - (__x - 1) * 0x200)
-#define STV090x_P1_FBERCPT1                            STV090x_Px_FBERCPT1(1)
-#define STV090x_P2_FBERCPT1                            STV090x_Px_FBERCPT1(2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
-
-#define STV090x_Px_FBERCPT0(__x)                       (0xF5AC - (__x - 1) * 0x200)
-#define STV090x_P1_FBERCPT0                            STV090x_Px_FBERCPT0(1)
-#define STV090x_P2_FBERCPT0                            STV090x_Px_FBERCPT0(2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD           0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD           8
-
-#define STV090x_Px_FBERERRy(__x, __y)                  (0xF5AF - (__x - 1) * 0x200 - __y * 0x1)
-#define STV090x_P1_FBERERR0                            STV090x_Px_FBERERRy(1, 0)
-#define STV090x_P1_FBERERR1                            STV090x_Px_FBERERRy(1, 1)
-#define STV090x_P1_FBERERR2                            STV090x_Px_FBERERRy(1, 2)
-#define STV090x_P2_FBERERR0                            STV090x_Px_FBERERRy(2, 0)
-#define STV090x_P2_FBERERR1                            STV090x_Px_FBERERRy(2, 1)
-#define STV090x_P2_FBERERR2                            STV090x_Px_FBERERRy(2, 2)
-#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD       0
-#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD       8
-
-#define STV090x_Px_FSPYBER(__x)                                (0xF5B2 - (__x - 1) * 0x200)
-#define STV090x_P1_FSPYBER                             STV090x_Px_FSPYBER(1)
-#define STV090x_P2_FSPYBER                             STV090x_Px_FSPYBER(2)
-#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD                4
-#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD                1
-#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD          3
-#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD          1
-#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD           0
-#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD           3
-
-#define STV090x_RCCFGH                                 0xf600
-
-#define STV090x_TSGENERAL                              0xF630
-#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD           3
-#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD           1
-#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD                1
-#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD                2
-
-#define STV090x_TSGENERAL1X                            0xf670
-#define STV090x_CFGEXT                                 0xfa80
-
-#define STV090x_TSTRES0                                        0xFF11
-#define STV090x_OFFST_FRESFEC_FIELD                    7
-#define STV090x_WIDTH_FRESFEC_FIELD                    1
-
-#define STV090x_Px_TSTDISRX(__x)                       (0xFF67 - (__x - 1) * 0x2)
-#define STV090x_P1_TSTDISRX                            STV090x_Px_TSTDISRX(1)
-#define STV090x_P2_TSTDISRX                            STV090x_Px_TSTDISRX(2)
-#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD         3
-#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD         1
-
-#endif /* __STV090x_REG_H */
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
deleted file mode 100644 (file)
index 20b5fa9..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * stv6110.c
- *
- * Driver for ST STV6110 satellite tuner IC.
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-
-#include <linux/types.h>
-
-#include "stv6110.h"
-
-static int debug;
-
-struct stv6110_priv {
-       int i2c_address;
-       struct i2c_adapter *i2c;
-
-       u32 mclk;
-       u8 clk_div;
-       u8 gain;
-       u8 regs[8];
-};
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG args); \
-       } while (0)
-
-static s32 abssub(s32 a, s32 b)
-{
-       if (a > b)
-               return a - b;
-       else
-               return b - a;
-};
-
-static int stv6110_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
-                                                       int start, int len)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       int rc;
-       u8 cmdbuf[len + 1];
-       struct i2c_msg msg = {
-               .addr   = priv->i2c_address,
-               .flags  = 0,
-               .buf    = cmdbuf,
-               .len    = len + 1
-       };
-
-       dprintk("%s\n", __func__);
-
-       if (start + len > 8)
-               return -EINVAL;
-
-       memcpy(&cmdbuf[1], buf, len);
-       cmdbuf[0] = start;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       rc = i2c_transfer(priv->i2c, &msg, 1);
-       if (rc != 1)
-               dprintk("%s: i2c error\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
-                                                       int start, int len)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       int rc;
-       u8 reg[] = { start };
-       struct i2c_msg msg[] = {
-               {
-                       .addr   = priv->i2c_address,
-                       .flags  = 0,
-                       .buf    = reg,
-                       .len    = 1,
-               }, {
-                       .addr   = priv->i2c_address,
-                       .flags  = I2C_M_RD,
-                       .buf    = regs,
-                       .len    = len,
-               },
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       rc = i2c_transfer(priv->i2c, msg, 2);
-       if (rc != 2)
-               dprintk("%s: i2c error\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       memcpy(&priv->regs[start], regs, len);
-
-       return 0;
-}
-
-static int stv6110_read_reg(struct dvb_frontend *fe, int start)
-{
-       u8 buf[] = { 0 };
-       stv6110_read_regs(fe, buf, start, 1);
-
-       return buf[0];
-}
-
-static int stv6110_sleep(struct dvb_frontend *fe)
-{
-       u8 reg[] = { 0 };
-       stv6110_write_regs(fe, reg, 0, 1);
-
-       return 0;
-}
-
-static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
-{
-       u32 rlf;
-
-       switch (rolloff) {
-       case ROLLOFF_20:
-               rlf = 20;
-               break;
-       case ROLLOFF_25:
-               rlf = 25;
-               break;
-       default:
-               rlf = 35;
-               break;
-       }
-
-       return symbol_rate  + ((symbol_rate * rlf) / 100);
-}
-
-static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       u8 r8, ret = 0x04;
-       int i;
-
-       if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
-               r8 = 31;
-       else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
-               r8 = 0;
-       else /*if 5 < BW/2 < 36*/
-               r8 = (bandwidth / 2) / 1000000 - 5;
-
-       /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
-       /* ctrl3, CF = r8 Set the LPF value */
-       priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
-       priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
-       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
-       /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
-       priv->regs[RSTV6110_STAT1] |= 0x02;
-       stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
-
-       i = 0;
-       /* Wait for CALRCSTRT == 0 */
-       while ((i < 10) && (ret != 0)) {
-               ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
-               mdelay(1);      /* wait for LPF auto calibration */
-               i++;
-       }
-
-       /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
-       priv->regs[RSTV6110_CTRL3] |= (1 << 6);
-       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
-       return 0;
-}
-
-static int stv6110_init(struct dvb_frontend *fe)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
-
-       memcpy(priv->regs, buf0, 8);
-       /* K = (Reference / 1000000) - 16 */
-       priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
-       priv->regs[RSTV6110_CTRL1] |=
-                               ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
-
-       /* divisor value for the output clock */
-       priv->regs[RSTV6110_CTRL2] &= ~0xc0;
-       priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);
-
-       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
-       msleep(1);
-       stv6110_set_bandwidth(fe, 72000000);
-
-       return 0;
-}
-
-static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       u32 nbsteps, divider, psd2, freq;
-       u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-       stv6110_read_regs(fe, regs, 0, 8);
-       /*N*/
-       divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
-       divider += priv->regs[RSTV6110_TUNING1];
-
-       /*R*/
-       nbsteps  = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
-       /*p*/
-       psd2  = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
-
-       freq = divider * (priv->mclk / 1000);
-       freq /= (1 << (nbsteps + psd2));
-       freq /= 4;
-
-       *frequency = freq;
-
-       return 0;
-}
-
-static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 ret = 0x04;
-       u32 divider, ref, p, presc, i, result_freq, vco_freq;
-       s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
-       s32 srate;
-
-       dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
-                                               frequency, priv->mclk);
-
-       /* K = (Reference / 1000000) - 16 */
-       priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
-       priv->regs[RSTV6110_CTRL1] |=
-                               ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
-
-       /* BB_GAIN = db/2 */
-       if (fe->ops.set_property && fe->ops.get_property) {
-               srate = c->symbol_rate;
-               dprintk("%s: Get Frontend parameters: srate=%d\n",
-                                                       __func__, srate);
-       } else
-               srate = 15000000;
-
-       priv->regs[RSTV6110_CTRL2] &= ~0x0f;
-       priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
-
-       if (frequency <= 1023000) {
-               p = 1;
-               presc = 0;
-       } else if (frequency <= 1300000) {
-               p = 1;
-               presc = 1;
-       } else if (frequency <= 2046000) {
-               p = 0;
-               presc = 0;
-       } else {
-               p = 0;
-               presc = 1;
-       }
-       /* DIV4SEL = p*/
-       priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
-       priv->regs[RSTV6110_TUNING2] |= (p << 4);
-
-       /* PRESC32ON = presc */
-       priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
-       priv->regs[RSTV6110_TUNING2] |= (presc << 5);
-
-       p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
-       for (r_div = 0; r_div <= 3; r_div++) {
-               p_calc = (priv->mclk / 100000);
-               p_calc /= (1 << (r_div + 1));
-               if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
-                       r_div_opt = r_div;
-
-               p_calc_opt = (priv->mclk / 100000);
-               p_calc_opt /= (1 << (r_div_opt + 1));
-       }
-
-       ref = priv->mclk / ((1 << (r_div_opt + 1))  * (1 << (p + 1)));
-       divider = (((frequency * 1000) + (ref >> 1)) / ref);
-
-       /* RDIV = r_div_opt */
-       priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
-       priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
-
-       /* NDIV_MSB = MSB(divider) */
-       priv->regs[RSTV6110_TUNING2] &= ~0x0f;
-       priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
-
-       /* NDIV_LSB, LSB(divider) */
-       priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
-
-       /* CALVCOSTRT = 1 VCO Auto Calibration */
-       priv->regs[RSTV6110_STAT1] |= 0x04;
-       stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
-                                               RSTV6110_CTRL1, 8);
-
-       i = 0;
-       /* Wait for CALVCOSTRT == 0 */
-       while ((i < 10) && (ret != 0)) {
-               ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
-               msleep(1); /* wait for VCO auto calibration */
-               i++;
-       }
-
-       ret = stv6110_read_reg(fe, RSTV6110_STAT1);
-       stv6110_get_frequency(fe, &result_freq);
-
-       vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
-       dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
-                                               ret, result_freq, vco_freq);
-
-       return 0;
-}
-
-static int stv6110_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
-
-       stv6110_set_frequency(fe, c->frequency);
-       stv6110_set_bandwidth(fe, bandwidth);
-
-       return 0;
-}
-
-static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct stv6110_priv *priv = fe->tuner_priv;
-       u8 r8 = 0;
-       u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-       stv6110_read_regs(fe, regs, 0, 8);
-
-       /* CF */
-       r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
-       *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
-
-       return 0;
-}
-
-static struct dvb_tuner_ops stv6110_tuner_ops = {
-       .info = {
-               .name = "ST STV6110",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_step = 1000,
-       },
-       .init = stv6110_init,
-       .release = stv6110_release,
-       .sleep = stv6110_sleep,
-       .set_params = stv6110_set_params,
-       .get_frequency = stv6110_get_frequency,
-       .set_frequency = stv6110_set_frequency,
-       .get_bandwidth = stv6110_get_bandwidth,
-       .set_bandwidth = stv6110_set_bandwidth,
-
-};
-
-struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
-                                       const struct stv6110_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       struct stv6110_priv *priv = NULL;
-       u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
-
-       struct i2c_msg msg[] = {
-               {
-                       .addr = config->i2c_address,
-                       .flags = 0,
-                       .buf = reg0,
-                       .len = 9
-               }
-       };
-       int ret;
-
-       /* divisor value for the output clock */
-       reg0[2] &= ~0xc0;
-       reg0[2] |= (config->clk_div << 6);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       ret = i2c_transfer(i2c, msg, 1);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret != 1)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c_address = config->i2c_address;
-       priv->i2c = i2c;
-       priv->mclk = config->mclk;
-       priv->clk_div = config->clk_div;
-       priv->gain = config->gain;
-
-       memcpy(&priv->regs, &reg0[1], 8);
-
-       memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
-                               sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = priv;
-       printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
-
-       return fe;
-}
-EXPORT_SYMBOL(stv6110_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("ST STV6110 driver");
-MODULE_AUTHOR("Igor M. Liplianin");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
deleted file mode 100644 (file)
index fe71bba..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * stv6110.h
- *
- * Driver for ST STV6110 satellite tuner IC.
- *
- * Copyright (C) 2009 NetUP Inc.
- * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __DVB_STV6110_H__
-#define __DVB_STV6110_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/* registers */
-#define RSTV6110_CTRL1         0
-#define RSTV6110_CTRL2         1
-#define RSTV6110_TUNING1       2
-#define RSTV6110_TUNING2       3
-#define RSTV6110_CTRL3         4
-#define RSTV6110_STAT1         5
-#define RSTV6110_STAT2         6
-#define RSTV6110_STAT3         7
-
-struct stv6110_config {
-       u8 i2c_address;
-       u32 mclk;
-       u8 gain;
-       u8 clk_div;     /* divisor value for the output clock */
-};
-
-#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
-                                                       && defined(MODULE))
-extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
-                                       const struct stv6110_config *config,
-                                       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
-                                       const struct stv6110_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
deleted file mode 100644 (file)
index f36cab1..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
-       STV6110(A) Silicon tuner driver
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "dvb_frontend.h"
-
-#include "stv6110x_reg.h"
-#include "stv6110x.h"
-#include "stv6110x_priv.h"
-
-static unsigned int verbose;
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "Set Verbosity level");
-
-static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
-{
-       int ret;
-       const struct stv6110x_config *config = stv6110x->config;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               { .addr = config->addr, .flags = 0,        .buf = b0, .len = 1 },
-               { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
-       };
-
-       ret = i2c_transfer(stv6110x->i2c, msg, 2);
-       if (ret != 2) {
-               dprintk(FE_ERROR, 1, "I/O Error");
-               return -EREMOTEIO;
-       }
-       *data = b1[0];
-
-       return 0;
-}
-
-static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
-{
-       int ret;
-       const struct stv6110x_config *config = stv6110x->config;
-       u8 buf[len + 1];
-       struct i2c_msg msg = {
-               .addr = config->addr,
-               .flags = 0,
-               .buf = buf,
-               .len = len + 1
-       };
-
-       if (start + len > 8)
-               return -EINVAL;
-
-       buf[0] = start;
-       memcpy(&buf[1], data, len);
-
-       ret = i2c_transfer(stv6110x->i2c, &msg, 1);
-       if (ret != 1) {
-               dprintk(FE_ERROR, 1, "I/O Error");
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
-{
-       return stv6110x_write_regs(stv6110x, reg, &data, 1);
-}
-
-static int stv6110x_init(struct dvb_frontend *fe)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-       int ret;
-
-       ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
-                                 ARRAY_SIZE(stv6110x->regs));
-       if (ret < 0) {
-               dprintk(FE_ERROR, 1, "Initialization failed");
-               return -1;
-       }
-
-       return 0;
-}
-
-static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-       u32 rDiv, divider;
-       s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
-       u8 i;
-
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
-
-       if (frequency <= 1023000) {
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
-               pVal = 40;
-       } else if (frequency <= 1300000) {
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
-               pVal = 40;
-       } else if (frequency <= 2046000) {
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
-               pVal = 20;
-       } else {
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
-               pVal = 20;
-       }
-
-       for (rDiv = 0; rDiv <= 3; rDiv++) {
-               pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
-
-               if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
-                       rDivOpt = rDiv;
-
-               pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
-       }
-
-       divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
-       divider = (divider + 5) / 10;
-
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
-
-       /* VCO Auto calibration */
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
-
-       stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
-       stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
-       stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
-       stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
-
-       for (i = 0; i < TRIALS; i++) {
-               stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
-               if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
-                               break;
-               msleep(1);
-       }
-
-       return 0;
-}
-
-static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
-       stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
-
-       *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
-                                STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
-
-       *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
-                            STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
-
-       *frequency >>= 2;
-
-       return 0;
-}
-
-static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-       u32 halfbw;
-       u8 i;
-
-       halfbw = bandwidth >> 1;
-
-       if (halfbw > 36000000)
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
-       else if (halfbw < 5000000)
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
-       else
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
-
-
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
-
-       stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
-       stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
-
-       for (i = 0; i < TRIALS; i++) {
-               stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
-               if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
-                       break;
-               msleep(1);
-       }
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
-       stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
-
-       return 0;
-}
-
-static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
-       *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
-
-       return 0;
-}
-
-static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       /* setup divider */
-       switch (refclock) {
-       default:
-       case 1:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
-               break;
-       case 2:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
-               break;
-       case 4:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
-               break;
-       case 8:
-       case 0:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
-               break;
-       }
-       stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
-
-       return 0;
-}
-
-static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
-       *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
-
-       return 0;
-}
-
-static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
-       stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
-
-       return 0;
-}
-
-static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-       int ret;
-
-       switch (mode) {
-       case TUNER_SLEEP:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
-               break;
-
-       case TUNER_WAKE:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
-               break;
-       }
-
-       ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
-       if (ret < 0) {
-               dprintk(FE_ERROR, 1, "I/O Error");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int stv6110x_sleep(struct dvb_frontend *fe)
-{
-       if (fe->tuner_priv)
-               return stv6110x_set_mode(fe, TUNER_SLEEP);
-
-       return 0;
-}
-
-static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
-
-       if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
-               *status = TUNER_PHASELOCKED;
-       else
-               *status = 0;
-
-       return 0;
-}
-
-
-static int stv6110x_release(struct dvb_frontend *fe)
-{
-       struct stv6110x_state *stv6110x = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(stv6110x);
-
-       return 0;
-}
-
-static struct dvb_tuner_ops stv6110x_ops = {
-       .info = {
-               .name           = "STV6110(A) Silicon Tuner",
-               .frequency_min  =  950000,
-               .frequency_max  = 2150000,
-               .frequency_step = 0,
-       },
-       .release                = stv6110x_release
-};
-
-static struct stv6110x_devctl stv6110x_ctl = {
-       .tuner_init             = stv6110x_init,
-       .tuner_sleep            = stv6110x_sleep,
-       .tuner_set_mode         = stv6110x_set_mode,
-       .tuner_set_frequency    = stv6110x_set_frequency,
-       .tuner_get_frequency    = stv6110x_get_frequency,
-       .tuner_set_bandwidth    = stv6110x_set_bandwidth,
-       .tuner_get_bandwidth    = stv6110x_get_bandwidth,
-       .tuner_set_bbgain       = stv6110x_set_bbgain,
-       .tuner_get_bbgain       = stv6110x_get_bbgain,
-       .tuner_set_refclk       = stv6110x_set_refclock,
-       .tuner_get_status       = stv6110x_get_status,
-};
-
-struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
-                                       const struct stv6110x_config *config,
-                                       struct i2c_adapter *i2c)
-{
-       struct stv6110x_state *stv6110x;
-       u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
-
-       stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
-       if (!stv6110x)
-               return NULL;
-
-       stv6110x->i2c           = i2c;
-       stv6110x->config        = config;
-       stv6110x->devctl        = &stv6110x_ctl;
-       memcpy(stv6110x->regs, default_regs, 8);
-
-       /* setup divider */
-       switch (stv6110x->config->clk_div) {
-       default:
-       case 1:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
-               break;
-       case 2:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
-               break;
-       case 4:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
-               break;
-       case 8:
-       case 0:
-               STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
-               break;
-       }
-
-       fe->tuner_priv          = stv6110x;
-       fe->ops.tuner_ops       = stv6110x_ops;
-
-       printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
-       return stv6110x->devctl;
-}
-EXPORT_SYMBOL(stv6110x_attach);
-
-MODULE_AUTHOR("Manu Abraham");
-MODULE_DESCRIPTION("STV6110x Silicon tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
deleted file mode 100644 (file)
index 4751675..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-       STV6110(A) Silicon tuner driver
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV6110x_H
-#define __STV6110x_H
-
-struct stv6110x_config {
-       u8      addr;
-       u32     refclk;
-       u8      clk_div; /* divisor value for the output clock */
-};
-
-enum tuner_mode {
-       TUNER_SLEEP = 1,
-       TUNER_WAKE,
-};
-
-enum tuner_status {
-       TUNER_PHASELOCKED = 1,
-};
-
-struct stv6110x_devctl {
-       int (*tuner_init) (struct dvb_frontend *fe);
-       int (*tuner_sleep) (struct dvb_frontend *fe);
-       int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
-       int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
-       int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
-       int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
-       int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
-       int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
-       int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
-       int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk);
-       int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
-};
-
-
-#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
-
-extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
-                                              const struct stv6110x_config *config,
-                                              struct i2c_adapter *i2c);
-
-#else
-static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
-                                                     const struct stv6110x_config *config,
-                                                     struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif /* CONFIG_DVB_STV6110x */
-
-#endif /* __STV6110x_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h
deleted file mode 100644 (file)
index 0ec936a..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-       STV6110(A) Silicon tuner driver
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV6110x_PRIV_H
-#define __STV6110x_PRIV_H
-
-#define FE_ERROR                               0
-#define FE_NOTICE                              1
-#define FE_INFO                                        2
-#define FE_DEBUG                               3
-#define FE_DEBUGREG                            4
-
-#define dprintk(__y, __z, format, arg...) do {                                         \
-       if (__z) {                                                                      \
-               if      ((verbose > FE_ERROR) && (verbose > __y))                       \
-                       printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
-               else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
-                       printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
-               else if ((verbose > FE_INFO) && (verbose > __y))                        \
-                       printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
-               else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
-                       printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
-       } else {                                                                        \
-               if (verbose > __y)                                                      \
-                       printk(format, ##arg);                                          \
-       }                                                                               \
-} while (0)
-
-
-#define STV6110x_SETFIELD(mask, bitf, val)                             \
-       (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) <<        \
-                                 STV6110x_OFFST_##bitf))) |            \
-                         (val << STV6110x_OFFST_##bitf))
-
-#define STV6110x_GETFIELD(bitf, val)                                   \
-       ((val >> STV6110x_OFFST_##bitf) &                               \
-       ((1 << STV6110x_WIDTH_##bitf) - 1))
-
-#define MAKEWORD16(a, b)                       (((a) << 8) | (b))
-
-#define LSB(x)                                 ((x & 0xff))
-#define MSB(y)                                 ((y >> 8) & 0xff)
-
-#define TRIALS                                 10
-#define R_DIV(__div)                           (1 << (__div + 1))
-#define REFCLOCK_kHz                           (stv6110x->config->refclk /    1000)
-#define REFCLOCK_MHz                           (stv6110x->config->refclk / 1000000)
-
-struct stv6110x_state {
-       struct i2c_adapter              *i2c;
-       const struct stv6110x_config    *config;
-       u8                              regs[8];
-
-       struct stv6110x_devctl          *devctl;
-};
-
-#endif /* __STV6110x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h
deleted file mode 100644 (file)
index 93e5c70..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-       STV6110(A) Silicon tuner driver
-
-       Copyright (C) Manu Abraham <abraham.manu@gmail.com>
-
-       Copyright (C) ST Microelectronics
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __STV6110x_REG_H
-#define __STV6110x_REG_H
-
-#define STV6110x_CTRL1                         0x00
-#define STV6110x_OFFST_CTRL1_K                 3
-#define STV6110x_WIDTH_CTRL1_K                 5
-#define STV6110x_OFFST_CTRL1_LPT               2
-#define STV6110x_WIDTH_CTRL1_LPT               1
-#define STV6110x_OFFST_CTRL1_RX                        1
-#define STV6110x_WIDTH_CTRL1_RX                        1
-#define STV6110x_OFFST_CTRL1_SYN               0
-#define STV6110x_WIDTH_CTRL1_SYN               1
-
-#define STV6110x_CTRL2                         0x01
-#define STV6110x_OFFST_CTRL2_CO_DIV            6
-#define STV6110x_WIDTH_CTRL2_CO_DIV            2
-#define STV6110x_OFFST_CTRL2_RSVD              5
-#define STV6110x_WIDTH_CTRL2_RSVD              1
-#define STV6110x_OFFST_CTRL2_REFOUT_SEL                4
-#define STV6110x_WIDTH_CTRL2_REFOUT_SEL                1
-#define STV6110x_OFFST_CTRL2_BBGAIN            0
-#define STV6110x_WIDTH_CTRL2_BBGAIN            4
-
-#define STV6110x_TNG0                          0x02
-#define STV6110x_OFFST_TNG0_N_DIV_7_0          0
-#define STV6110x_WIDTH_TNG0_N_DIV_7_0          8
-
-#define STV6110x_TNG1                          0x03
-#define STV6110x_OFFST_TNG1_R_DIV              6
-#define STV6110x_WIDTH_TNG1_R_DIV              2
-#define STV6110x_OFFST_TNG1_PRESC32_ON         5
-#define STV6110x_WIDTH_TNG1_PRESC32_ON         1
-#define STV6110x_OFFST_TNG1_DIV4SEL            4
-#define STV6110x_WIDTH_TNG1_DIV4SEL            1
-#define STV6110x_OFFST_TNG1_N_DIV_11_8         0
-#define STV6110x_WIDTH_TNG1_N_DIV_11_8         4
-
-
-#define STV6110x_CTRL3                         0x04
-#define STV6110x_OFFST_CTRL3_DCLOOP_OFF                7
-#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF                1
-#define STV6110x_OFFST_CTRL3_RCCLK_OFF         6
-#define STV6110x_WIDTH_CTRL3_RCCLK_OFF         1
-#define STV6110x_OFFST_CTRL3_ICP               5
-#define STV6110x_WIDTH_CTRL3_ICP               1
-#define STV6110x_OFFST_CTRL3_CF                        0
-#define STV6110x_WIDTH_CTRL3_CF                        5
-
-#define STV6110x_STAT1                         0x05
-#define STV6110x_OFFST_STAT1_CALVCO_STRT       2
-#define STV6110x_WIDTH_STAT1_CALVCO_STRT       1
-#define STV6110x_OFFST_STAT1_CALRC_STRT                1
-#define STV6110x_WIDTH_STAT1_CALRC_STRT                1
-#define STV6110x_OFFST_STAT1_LOCK              0
-#define STV6110x_WIDTH_STAT1_LOCK              1
-
-#define STV6110x_STAT2                         0x06
-#define STV6110x_STAT3                         0x07
-
-#endif /* __STV6110x_REG_H */
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
deleted file mode 100644 (file)
index 1bff7f4..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
-    TDA10021  - Single Chip Cable Channel Receiver driver module
-              used on the Siemens DVB-C cards
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                  Support for TDA10021
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "tda1002x.h"
-
-
-struct tda10021_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct tda1002x_config* config;
-       struct dvb_frontend frontend;
-
-       u8 pwm;
-       u8 reg0;
-};
-
-
-#if 0
-#define dprintk(x...) printk(x)
-#else
-#define dprintk(x...)
-#endif
-
-static int verbose;
-
-#define XIN 57840000UL
-
-#define FIN (XIN >> 4)
-
-static int tda10021_inittab_size = 0x40;
-static u8 tda10021_inittab[0x40]=
-{
-       0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
-       0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
-       0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
-       0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
-       0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
-       0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
-       0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
-       0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
-};
-
-static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-       int ret;
-
-       ret = i2c_transfer (state->i2c, &msg, 1);
-       if (ret != 1)
-               printk("DVB: TDA10021(%d): %s, writereg error "
-                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       state->frontend.dvb->num, __func__, reg, data, ret);
-
-       msleep(10);
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
-{
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                                 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-       int ret;
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-       // Don't print an error message if the id is read.
-       if (ret != 2 && reg != 0x1a)
-               printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
-                               __func__, ret);
-       return b1[0];
-}
-
-//get access to tuner
-static int lock_tuner(struct tda10021_state* state)
-{
-       u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
-       struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
-
-       if(i2c_transfer(state->i2c, &msg, 1) != 1)
-       {
-               printk("tda10021: lock tuner fails\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-//release access from tuner
-static int unlock_tuner(struct tda10021_state* state)
-{
-       u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
-       struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
-
-       if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
-       {
-               printk("tda10021: unlock tuner fails\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
-                               fe_spectral_inversion_t inversion)
-{
-       reg0 |= state->reg0 & 0x63;
-
-       if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
-               reg0 &= ~0x20;
-       else
-               reg0 |= 0x20;
-
-       _tda10021_writereg (state, 0x00, reg0 & 0xfe);
-       _tda10021_writereg (state, 0x00, reg0 | 0x01);
-
-       state->reg0 = reg0;
-       return 0;
-}
-
-static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
-{
-       s32 BDR;
-       s32 BDRI;
-       s16 SFIL=0;
-       u16 NDEC = 0;
-       u32 tmp, ratio;
-
-       if (symbolrate > XIN/2)
-               symbolrate = XIN/2;
-       if (symbolrate < 500000)
-               symbolrate = 500000;
-
-       if (symbolrate < XIN/16) NDEC = 1;
-       if (symbolrate < XIN/32) NDEC = 2;
-       if (symbolrate < XIN/64) NDEC = 3;
-
-       if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
-       if (symbolrate < (u32)(XIN/16))  SFIL = 0;
-       if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
-       if (symbolrate < (u32)(XIN/32))  SFIL = 0;
-       if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
-       if (symbolrate < (u32)(XIN/64))  SFIL = 0;
-       if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
-
-       symbolrate <<= NDEC;
-       ratio = (symbolrate << 4) / FIN;
-       tmp =  ((symbolrate << 4) % FIN) << 8;
-       ratio = (ratio << 8) + tmp / FIN;
-       tmp = (tmp % FIN) << 8;
-       ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
-
-       BDR = ratio;
-       BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
-
-       if (BDRI > 0xFF)
-               BDRI = 0xFF;
-
-       SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
-
-       NDEC = (NDEC << 6) | tda10021_inittab[0x03];
-
-       _tda10021_writereg (state, 0x03, NDEC);
-       _tda10021_writereg (state, 0x0a, BDR&0xff);
-       _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
-       _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
-
-       _tda10021_writereg (state, 0x0d, BDRI);
-       _tda10021_writereg (state, 0x0e, SFIL);
-
-       return 0;
-}
-
-static int tda10021_init (struct dvb_frontend *fe)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-       int i;
-
-       dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
-
-       //_tda10021_writereg (fe, 0, 0);
-
-       for (i=0; i<tda10021_inittab_size; i++)
-               _tda10021_writereg (state, i, tda10021_inittab[i]);
-
-       _tda10021_writereg (state, 0x34, state->pwm);
-
-       //Comment by markus
-       //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
-       //0x2A[4] == BYPPLL -> Power down mode (default 1)
-       //0x2A[5] == LCK -> PLL Lock Flag
-       //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
-
-       //Activate PLL
-       _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
-       return 0;
-}
-
-struct qam_params {
-       u8 conf, agcref, lthr, mseth, aref;
-};
-
-static int tda10021_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys  = c->delivery_system;
-       unsigned qam = c->modulation;
-       bool is_annex_c;
-       u32 reg0x3d;
-       struct tda10021_state* state = fe->demodulator_priv;
-       static const struct qam_params qam_params[] = {
-               /* Modulation  Conf  AGCref  LTHR  MSETH  AREF */
-               [QPSK]     = { 0x14, 0x78,   0x78, 0x8c,  0x96 },
-               [QAM_16]   = { 0x00, 0x8c,   0x87, 0xa2,  0x91 },
-               [QAM_32]   = { 0x04, 0x8c,   0x64, 0x74,  0x96 },
-               [QAM_64]   = { 0x08, 0x6a,   0x46, 0x43,  0x6a },
-               [QAM_128]  = { 0x0c, 0x78,   0x36, 0x34,  0x7e },
-               [QAM_256]  = { 0x10, 0x5c,   0x26, 0x23,  0x6b },
-       };
-
-       switch (delsys) {
-       case SYS_DVBC_ANNEX_A:
-               is_annex_c = false;
-               break;
-       case SYS_DVBC_ANNEX_C:
-               is_annex_c = true;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /*
-        * gcc optimizes the code bellow the same way as it would code:
-        *           "if (qam > 5) return -EINVAL;"
-        * Yet, the code is clearer, as it shows what QAM standards are
-        * supported by the driver, and avoids the usage of magic numbers on
-        * it.
-        */
-       switch (qam) {
-       case QPSK:
-       case QAM_16:
-       case QAM_32:
-       case QAM_64:
-       case QAM_128:
-       case QAM_256:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF)
-               return -EINVAL;
-
-       /*printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->symbol_rate);*/
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       tda10021_set_symbolrate(state, c->symbol_rate);
-       _tda10021_writereg(state, 0x34, state->pwm);
-
-       _tda10021_writereg(state, 0x01, qam_params[qam].agcref);
-       _tda10021_writereg(state, 0x05, qam_params[qam].lthr);
-       _tda10021_writereg(state, 0x08, qam_params[qam].mseth);
-       _tda10021_writereg(state, 0x09, qam_params[qam].aref);
-
-       /*
-        * Bit 0 == 0 means roll-off = 0.15 (Annex A)
-        *       == 1 means roll-off = 0.13 (Annex C)
-        */
-       reg0x3d = tda10021_readreg (state, 0x3d);
-       if (is_annex_c)
-               _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d);
-       else
-               _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d);
-       tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion);
-
-       return 0;
-}
-
-static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-       int sync;
-
-       *status = 0;
-       //0x11[0] == EQALGO -> Equalizer algorithms state
-       //0x11[1] == CARLOCK -> Carrier locked
-       //0x11[2] == FSYNC -> Frame synchronisation
-       //0x11[3] == FEL -> Front End locked
-       //0x11[6] == NODVB -> DVB Mode Information
-       sync = tda10021_readreg (state, 0x11);
-
-       if (sync & 2)
-               *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
-
-       if (sync & 4)
-               *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
-
-       if (sync & 8)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       u32 _ber = tda10021_readreg(state, 0x14) |
-               (tda10021_readreg(state, 0x15) << 8) |
-               ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
-       _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0)
-                                       | (tda10021_inittab[0x10] & 0xc0));
-       *ber = 10 * _ber;
-
-       return 0;
-}
-
-static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       u8 config = tda10021_readreg(state, 0x02);
-       u8 gain = tda10021_readreg(state, 0x17);
-       if (config & 0x02)
-               /* the agc value is inverted */
-               gain = ~gain;
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       u8 quality = ~tda10021_readreg(state, 0x18);
-       *snr = (quality << 8) | quality;
-
-       return 0;
-}
-
-static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
-       if (*ucblocks == 0x7f)
-               *ucblocks = 0xffffffff;
-
-       /* reset uncorrected block counter */
-       _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
-       _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
-
-       return 0;
-}
-
-static int tda10021_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda10021_state* state = fe->demodulator_priv;
-       int sync;
-       s8 afc = 0;
-
-       sync = tda10021_readreg(state, 0x11);
-       afc = tda10021_readreg(state, 0x19);
-       if (verbose) {
-               /* AFC only valid when carrier has been recovered */
-               printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
-                                 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
-                       state->frontend.dvb->num, afc,
-                      -((s32)p->symbol_rate * afc) >> 10);
-       }
-
-       p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
-       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
-
-       p->fec_inner = FEC_NONE;
-       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
-
-       if (sync & 2)
-               p->frequency -= ((s32)p->symbol_rate * afc) >> 10;
-
-       return 0;
-}
-
-static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               lock_tuner(state);
-       } else {
-               unlock_tuner(state);
-       }
-       return 0;
-}
-
-static int tda10021_sleep(struct dvb_frontend* fe)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-
-       _tda10021_writereg (state, 0x1b, 0x02);  /* pdown ADC */
-       _tda10021_writereg (state, 0x00, 0x80);  /* standby */
-
-       return 0;
-}
-
-static void tda10021_release(struct dvb_frontend* fe)
-{
-       struct tda10021_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda10021_ops;
-
-struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
-                                    struct i2c_adapter* i2c,
-                                    u8 pwm)
-{
-       struct tda10021_state* state = NULL;
-       u8 id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->pwm = pwm;
-       state->reg0 = tda10021_inittab[0];
-
-       /* check if the demod is there */
-       id = tda10021_readreg(state, 0x1a);
-       if ((id & 0xf0) != 0x70) goto error;
-
-       /* Don't claim TDA10023 */
-       if (id == 0x7d)
-               goto error;
-
-       printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
-              state->config->demod_address, id);
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda10021_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
-       .info = {
-               .name = "Philips TDA10021 DVB-C",
-               .frequency_stepsize = 62500,
-               .frequency_min = 47000000,
-               .frequency_max = 862000000,
-               .symbol_rate_min = (XIN/2)/64,     /* SACLK/64 == (XIN/2)/64 */
-               .symbol_rate_max = (XIN/2)/4,      /* SACLK/4 */
-       #if 0
-               .frequency_tolerance = ???,
-               .symbol_rate_tolerance = ???,  /* ppm */  /* == 8% (spec p. 5) */
-       #endif
-               .caps = 0x400 | //FE_CAN_QAM_4
-                       FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
-                       FE_CAN_FEC_AUTO
-       },
-
-       .release = tda10021_release,
-
-       .init = tda10021_init,
-       .sleep = tda10021_sleep,
-       .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
-
-       .set_frontend = tda10021_set_parameters,
-       .get_frontend = tda10021_get_frontend,
-
-       .read_status = tda10021_read_status,
-       .read_ber = tda10021_read_ber,
-       .read_signal_strength = tda10021_read_signal_strength,
-       .read_snr = tda10021_read_snr,
-       .read_ucblocks = tda10021_read_ucblocks,
-};
-
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
-
-MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
-MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
deleted file mode 100644 (file)
index ca1e0d5..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
-    TDA10023  - DVB-C decoder
-    (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
-
-    Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
-    Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
-
-    Remotely based on tda10021.c
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                  Support for TDA10021
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "tda1002x.h"
-
-#define REG0_INIT_VAL 0x23
-
-struct tda10023_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct tda10023_config *config;
-       struct dvb_frontend frontend;
-
-       u8 pwm;
-       u8 reg0;
-
-       /* clock settings */
-       u32 xtal;
-       u8 pll_m;
-       u8 pll_p;
-       u8 pll_n;
-       u32 sysclk;
-};
-
-#define dprintk(x...)
-
-static int verbose;
-
-static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
-{
-       u8 b0 [] = { reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-                                 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-       int ret;
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-       if (ret != 2) {
-               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
-               printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
-                       "(reg == 0x%02x, ret == %i)\n",
-                       num, __func__, reg, ret);
-       }
-       return b1[0];
-}
-
-static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
-{
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-       int ret;
-
-       ret = i2c_transfer (state->i2c, &msg, 1);
-       if (ret != 1) {
-               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
-               printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
-                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       num, __func__, reg, data, ret);
-       }
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-
-static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
-{
-       if (mask==0xff)
-               return tda10023_writereg(state, reg, data);
-       else {
-               u8 val;
-               val=tda10023_readreg(state,reg);
-               val&=~mask;
-               val|=(data&mask);
-               return tda10023_writereg(state, reg, val);
-       }
-}
-
-static void tda10023_writetab(struct tda10023_state* state, u8* tab)
-{
-       u8 r,m,v;
-       while (1) {
-               r=*tab++;
-               m=*tab++;
-               v=*tab++;
-               if (r==0xff) {
-                       if (m==0xff)
-                               break;
-                       else
-                               msleep(m);
-               }
-               else
-                       tda10023_writebit(state,r,m,v);
-       }
-}
-
-//get access to tuner
-static int lock_tuner(struct tda10023_state* state)
-{
-       u8 buf[2] = { 0x0f, 0xc0 };
-       struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
-
-       if(i2c_transfer(state->i2c, &msg, 1) != 1)
-       {
-               printk("tda10023: lock tuner fails\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-//release access from tuner
-static int unlock_tuner(struct tda10023_state* state)
-{
-       u8 buf[2] = { 0x0f, 0x40 };
-       struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
-
-       if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
-       {
-               printk("tda10023: unlock tuner fails\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
-{
-       reg0 |= state->reg0 & 0x63;
-
-       tda10023_writereg (state, 0x00, reg0 & 0xfe);
-       tda10023_writereg (state, 0x00, reg0 | 0x01);
-
-       state->reg0 = reg0;
-       return 0;
-}
-
-static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
-{
-       s32 BDR;
-       s32 BDRI;
-       s16 SFIL=0;
-       u16 NDEC = 0;
-
-       /* avoid floating point operations multiplying syscloc and divider
-          by 10 */
-       u32 sysclk_x_10 = state->sysclk * 10;
-
-       if (sr < (u32)(sysclk_x_10/984)) {
-               NDEC=3;
-               SFIL=1;
-       } else if (sr < (u32)(sysclk_x_10/640)) {
-               NDEC=3;
-               SFIL=0;
-       } else if (sr < (u32)(sysclk_x_10/492)) {
-               NDEC=2;
-               SFIL=1;
-       } else if (sr < (u32)(sysclk_x_10/320)) {
-               NDEC=2;
-               SFIL=0;
-       } else if (sr < (u32)(sysclk_x_10/246)) {
-               NDEC=1;
-               SFIL=1;
-       } else if (sr < (u32)(sysclk_x_10/160)) {
-               NDEC=1;
-               SFIL=0;
-       } else if (sr < (u32)(sysclk_x_10/123)) {
-               NDEC=0;
-               SFIL=1;
-       }
-
-       BDRI = (state->sysclk)*16;
-       BDRI>>=NDEC;
-       BDRI +=sr/2;
-       BDRI /=sr;
-
-       if (BDRI>255)
-               BDRI=255;
-
-       {
-               u64 BDRX;
-
-               BDRX=1<<(24+NDEC);
-               BDRX*=sr;
-               do_div(BDRX, state->sysclk);    /* BDRX/=SYSCLK; */
-
-               BDR=(s32)BDRX;
-       }
-       dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
-               sr, BDR, BDRI, NDEC);
-       tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
-       tda10023_writereg (state, 0x0a, BDR&255);
-       tda10023_writereg (state, 0x0b, (BDR>>8)&255);
-       tda10023_writereg (state, 0x0c, (BDR>>16)&31);
-       tda10023_writereg (state, 0x0d, BDRI);
-       tda10023_writereg (state, 0x3d, (SFIL<<7));
-       return 0;
-}
-
-static int tda10023_init (struct dvb_frontend *fe)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       u8 tda10023_inittab[] = {
-/*        reg  mask val */
-/* 000 */ 0x2a, 0xff, 0x02,  /* PLL3, Bypass, Power Down */
-/* 003 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
-/* 006 */ 0x2a, 0xff, 0x03,  /* PLL3, Bypass, Power Down */
-/* 009 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
-                          /* PLL1 */
-/* 012 */ 0x28, 0xff, (state->pll_m-1),
-                          /* PLL2 */
-/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
-                          /* GPR FSAMPLING=1 */
-/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
-/* 021 */ 0x2a, 0xff, 0x08,  /* PLL3 PSACLK=1 */
-/* 024 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
-/* 027 */ 0x1f, 0xff, 0x00,  /* RESET */
-/* 030 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
-/* 033 */ 0xe6, 0x0c, 0x04,  /* RSCFG_IND */
-/* 036 */ 0x10, 0xc0, 0x80,  /* DECDVBCFG1 PBER=1 */
-
-/* 039 */ 0x0e, 0xff, 0x82,  /* GAIN1 */
-/* 042 */ 0x03, 0x08, 0x08,  /* CLKCONF DYN=1 */
-/* 045 */ 0x2e, 0xbf, 0x30,  /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
-                                      PPWMTUN=0 PPWMIF=0 */
-/* 048 */ 0x01, 0xff, 0x30,  /* AGCREF */
-/* 051 */ 0x1e, 0x84, 0x84,  /* CONTROL SACLK_ON=1 */
-/* 054 */ 0x1b, 0xff, 0xc8,  /* ADC TWOS=1 */
-/* 057 */ 0x3b, 0xff, 0xff,  /* IFMAX */
-/* 060 */ 0x3c, 0xff, 0x00,  /* IFMIN */
-/* 063 */ 0x34, 0xff, 0x00,  /* PWMREF */
-/* 066 */ 0x35, 0xff, 0xff,  /* TUNMAX */
-/* 069 */ 0x36, 0xff, 0x00,  /* TUNMIN */
-/* 072 */ 0x06, 0xff, 0x7f,  /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
-/* 075 */ 0x1c, 0x30, 0x30,  /* EQCONF2 STEPALGO=SGNALGO=1 */
-/* 078 */ 0x37, 0xff, 0xf6,  /* DELTAF_LSB */
-/* 081 */ 0x38, 0xff, 0xff,  /* DELTAF_MSB */
-/* 084 */ 0x02, 0xff, 0x93,  /* AGCCONF1  IFS=1 KAGCIF=2 KAGCTUN=3 */
-/* 087 */ 0x2d, 0xff, 0xf6,  /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
-/* 090 */ 0x04, 0x10, 0x00,  /* SWRAMP=1 */
-/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
-                               INTP1 POCLKP=1 FEL=1 MFS=0 */
-/* 096 */ 0x2b, 0x01, 0xa1,  /* INTS1 */
-/* 099 */ 0x20, 0xff, 0x04,  /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
-/* 102 */ 0x2c, 0xff, 0x0d,  /* INTP/S TRIP=0 TRIS=0 */
-/* 105 */ 0xc4, 0xff, 0x00,
-/* 108 */ 0xc3, 0x30, 0x00,
-/* 111 */ 0xb5, 0xff, 0x19,  /* ERAGC_THD */
-/* 114 */ 0x00, 0x03, 0x01,  /* GPR, CLBS soft reset */
-/* 117 */ 0x00, 0x03, 0x03,  /* GPR, CLBS soft reset */
-/* 120 */ 0xff, 0x64, 0x00,  /* Sleep 100ms */
-/* 123 */ 0xff, 0xff, 0xff
-};
-       dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
-
-       /* override default values if set in config */
-       if (state->config->deltaf) {
-               tda10023_inittab[80] = (state->config->deltaf & 0xff);
-               tda10023_inittab[83] = (state->config->deltaf >> 8);
-       }
-
-       if (state->config->output_mode)
-               tda10023_inittab[95] = state->config->output_mode;
-
-       tda10023_writetab(state, tda10023_inittab);
-
-       return 0;
-}
-
-struct qam_params {
-       u8 qam, lockthr, mseth, aref, agcrefnyq, eragnyq_thd;
-};
-
-static int tda10023_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys  = c->delivery_system;
-       unsigned qam = c->modulation;
-       bool is_annex_c;
-       struct tda10023_state* state = fe->demodulator_priv;
-       static const struct qam_params qam_params[] = {
-               /* Modulation  QAM    LOCKTHR   MSETH   AREF AGCREFNYQ ERAGCNYQ_THD */
-               [QPSK]    = { (5<<2),  0x78,    0x8c,   0x96,   0x78,   0x4c  },
-               [QAM_16]  = { (0<<2),  0x87,    0xa2,   0x91,   0x8c,   0x57  },
-               [QAM_32]  = { (1<<2),  0x64,    0x74,   0x96,   0x8c,   0x57  },
-               [QAM_64]  = { (2<<2),  0x46,    0x43,   0x6a,   0x6a,   0x44  },
-               [QAM_128] = { (3<<2),  0x36,    0x34,   0x7e,   0x78,   0x4c  },
-               [QAM_256] = { (4<<2),  0x26,    0x23,   0x6c,   0x5c,   0x3c  },
-       };
-
-       switch (delsys) {
-       case SYS_DVBC_ANNEX_A:
-               is_annex_c = false;
-               break;
-       case SYS_DVBC_ANNEX_C:
-               is_annex_c = true;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /*
-        * gcc optimizes the code bellow the same way as it would code:
-        *               "if (qam > 5) return -EINVAL;"
-        * Yet, the code is clearer, as it shows what QAM standards are
-        * supported by the driver, and avoids the usage of magic numbers on
-        * it.
-        */
-       switch (qam) {
-       case QPSK:
-       case QAM_16:
-       case QAM_32:
-       case QAM_64:
-       case QAM_128:
-       case QAM_256:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       tda10023_set_symbolrate(state, c->symbol_rate);
-       tda10023_writereg(state, 0x05, qam_params[qam].lockthr);
-       tda10023_writereg(state, 0x08, qam_params[qam].mseth);
-       tda10023_writereg(state, 0x09, qam_params[qam].aref);
-       tda10023_writereg(state, 0xb4, qam_params[qam].agcrefnyq);
-       tda10023_writereg(state, 0xb6, qam_params[qam].eragnyq_thd);
-#if 0
-       tda10023_writereg(state, 0x04, (c->inversion ? 0x12 : 0x32));
-       tda10023_writebit(state, 0x04, 0x60, (c->inversion ? 0 : 0x20));
-#endif
-       tda10023_writebit(state, 0x04, 0x40, 0x40);
-
-       if (is_annex_c)
-               tda10023_writebit(state, 0x3d, 0xfc, 0x03);
-       else
-               tda10023_writebit(state, 0x3d, 0xfc, 0x02);
-
-       tda10023_setup_reg0(state, qam_params[qam].qam);
-
-       return 0;
-}
-
-static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       int sync;
-
-       *status = 0;
-
-       //0x11[1] == CARLOCK -> Carrier locked
-       //0x11[2] == FSYNC -> Frame synchronisation
-       //0x11[3] == FEL -> Front End locked
-       //0x11[6] == NODVB -> DVB Mode Information
-       sync = tda10023_readreg (state, 0x11);
-
-       if (sync & 2)
-               *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
-
-       if (sync & 4)
-               *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
-
-       if (sync & 8)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       u8 a,b,c;
-       a=tda10023_readreg(state, 0x14);
-       b=tda10023_readreg(state, 0x15);
-       c=tda10023_readreg(state, 0x16)&0xf;
-       tda10023_writebit (state, 0x10, 0xc0, 0x00);
-
-       *ber = a | (b<<8)| (c<<16);
-       return 0;
-}
-
-static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       u8 ifgain=tda10023_readreg(state, 0x2f);
-
-       u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
-       // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
-       if (gain>0x90)
-               gain=gain+2*(gain-0x90);
-       if (gain>255)
-               gain=255;
-
-       *strength = (gain<<8)|gain;
-       return 0;
-}
-
-static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-
-       u8 quality = ~tda10023_readreg(state, 0x18);
-       *snr = (quality << 8) | quality;
-       return 0;
-}
-
-static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       u8 a,b,c,d;
-       a= tda10023_readreg (state, 0x74);
-       b= tda10023_readreg (state, 0x75);
-       c= tda10023_readreg (state, 0x76);
-       d= tda10023_readreg (state, 0x77);
-       *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
-
-       tda10023_writebit (state, 0x10, 0x20,0x00);
-       tda10023_writebit (state, 0x10, 0x20,0x20);
-       tda10023_writebit (state, 0x13, 0x01, 0x00);
-
-       return 0;
-}
-
-static int tda10023_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda10023_state* state = fe->demodulator_priv;
-       int sync,inv;
-       s8 afc = 0;
-
-       sync = tda10023_readreg(state, 0x11);
-       afc = tda10023_readreg(state, 0x19);
-       inv = tda10023_readreg(state, 0x04);
-
-       if (verbose) {
-               /* AFC only valid when carrier has been recovered */
-               printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
-                                 "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
-                       state->frontend.dvb->num, afc,
-                      -((s32)p->symbol_rate * afc) >> 10);
-       }
-
-       p->inversion = (inv&0x20?0:1);
-       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
-
-       p->fec_inner = FEC_NONE;
-       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
-
-       if (sync & 2)
-               p->frequency -= ((s32)p->symbol_rate * afc) >> 10;
-
-       return 0;
-}
-
-static int tda10023_sleep(struct dvb_frontend* fe)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-
-       tda10023_writereg (state, 0x1b, 0x02);  /* pdown ADC */
-       tda10023_writereg (state, 0x00, 0x80);  /* standby */
-
-       return 0;
-}
-
-static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               lock_tuner(state);
-       } else {
-               unlock_tuner(state);
-       }
-       return 0;
-}
-
-static void tda10023_release(struct dvb_frontend* fe)
-{
-       struct tda10023_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda10023_ops;
-
-struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
-                                    struct i2c_adapter *i2c,
-                                    u8 pwm)
-{
-       struct tda10023_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* wakeup if in standby */
-       tda10023_writereg (state, 0x00, 0x33);
-       /* check if the demod is there */
-       if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
-       state->pwm = pwm;
-       state->reg0 = REG0_INIT_VAL;
-       if (state->config->xtal) {
-               state->xtal  = state->config->xtal;
-               state->pll_m = state->config->pll_m;
-               state->pll_p = state->config->pll_p;
-               state->pll_n = state->config->pll_n;
-       } else {
-               /* set default values if not defined in config */
-               state->xtal  = 28920000;
-               state->pll_m = 8;
-               state->pll_p = 4;
-               state->pll_n = 1;
-       }
-
-       /* calc sysclk */
-       state->sysclk = (state->xtal * state->pll_m / \
-                       (state->pll_n * state->pll_p));
-
-       state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
-       state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
-
-       dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
-               __func__, state->xtal, state->pll_m, state->pll_p,
-               state->pll_n);
-
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda10023_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C },
-       .info = {
-               .name = "Philips TDA10023 DVB-C",
-               .frequency_stepsize = 62500,
-               .frequency_min =  47000000,
-               .frequency_max = 862000000,
-               .symbol_rate_min = 0,  /* set in tda10023_attach */
-               .symbol_rate_max = 0,  /* set in tda10023_attach */
-               .caps = 0x400 | //FE_CAN_QAM_4
-                       FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 | FE_CAN_QAM_256 |
-                       FE_CAN_FEC_AUTO
-       },
-
-       .release = tda10023_release,
-
-       .init = tda10023_init,
-       .sleep = tda10023_sleep,
-       .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
-
-       .set_frontend = tda10023_set_parameters,
-       .get_frontend = tda10023_get_frontend,
-       .read_status = tda10023_read_status,
-       .read_ber = tda10023_read_ber,
-       .read_signal_strength = tda10023_read_signal_strength,
-       .read_snr = tda10023_read_snr,
-       .read_ucblocks = tda10023_read_ucblocks,
-};
-
-
-MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
-MODULE_AUTHOR("Georg Acher, Hartmut Birr");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda10023_attach);
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
deleted file mode 100644 (file)
index 04d1941..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-    TDA10021/TDA10023  - Single Chip Cable Channel Receiver driver module
-                        used on the the Siemens DVB-C cards
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-    Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                  Support for TDA10021
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef TDA1002x_H
-#define TDA1002x_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda1002x_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-       u8 invert;
-};
-
-enum tda10023_output_mode {
-       TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
-       TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
-       TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
-       TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
-};
-
-struct tda10023_config {
-       /* the demodulator's i2c address */
-       u8 demod_address;
-       u8 invert;
-
-       /* clock settings */
-       u32 xtal; /* defaults: 28920000 */
-       u8 pll_m; /* defaults: 8 */
-       u8 pll_p; /* defaults: 4 */
-       u8 pll_n; /* defaults: 1 */
-
-       /* MPEG2 TS output mode */
-       u8 output_mode;
-
-       /* input freq offset + baseband conversion type */
-       u16 deltaf;
-};
-
-#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
-                                           struct i2c_adapter* i2c, u8 pwm);
-#else
-static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
-                                           struct i2c_adapter* i2c, u8 pwm)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TDA10021
-
-#if defined(CONFIG_DVB_TDA10023) || \
-       (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda10023_attach(
-       const struct tda10023_config *config,
-       struct i2c_adapter *i2c, u8 pwm);
-#else
-static inline struct dvb_frontend *tda10023_attach(
-       const struct tda10023_config *config,
-       struct i2c_adapter *i2c, u8 pwm)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TDA10023
-
-#endif // TDA1002x_H
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
deleted file mode 100644 (file)
index 71fb632..0000000
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
-    NXP TDA10048HN DVB OFDM demodulator driver
-
-    Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/math64.h>
-#include <asm/div64.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "tda10048.h"
-
-#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
-#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878
-
-/* Register name definitions */
-#define TDA10048_IDENTITY          0x00
-#define TDA10048_VERSION           0x01
-#define TDA10048_DSP_CODE_CPT      0x0C
-#define TDA10048_DSP_CODE_IN       0x0E
-#define TDA10048_IN_CONF1          0x10
-#define TDA10048_IN_CONF2          0x11
-#define TDA10048_IN_CONF3          0x12
-#define TDA10048_OUT_CONF1         0x14
-#define TDA10048_OUT_CONF2         0x15
-#define TDA10048_OUT_CONF3         0x16
-#define TDA10048_AUTO              0x18
-#define TDA10048_SYNC_STATUS       0x1A
-#define TDA10048_CONF_C4_1         0x1E
-#define TDA10048_CONF_C4_2         0x1F
-#define TDA10048_CODE_IN_RAM       0x20
-#define TDA10048_CHANNEL_INFO1_R   0x22
-#define TDA10048_CHANNEL_INFO2_R   0x23
-#define TDA10048_CHANNEL_INFO1     0x24
-#define TDA10048_CHANNEL_INFO2     0x25
-#define TDA10048_TIME_ERROR_R      0x26
-#define TDA10048_TIME_ERROR        0x27
-#define TDA10048_FREQ_ERROR_LSB_R  0x28
-#define TDA10048_FREQ_ERROR_MSB_R  0x29
-#define TDA10048_FREQ_ERROR_LSB    0x2A
-#define TDA10048_FREQ_ERROR_MSB    0x2B
-#define TDA10048_IT_SEL            0x30
-#define TDA10048_IT_STAT           0x32
-#define TDA10048_DSP_AD_LSB        0x3C
-#define TDA10048_DSP_AD_MSB        0x3D
-#define TDA10048_DSP_REG_LSB       0x3E
-#define TDA10048_DSP_REG_MSB       0x3F
-#define TDA10048_CONF_TRISTATE1    0x44
-#define TDA10048_CONF_TRISTATE2    0x45
-#define TDA10048_CONF_POLARITY     0x46
-#define TDA10048_GPIO_SP_DS0       0x48
-#define TDA10048_GPIO_SP_DS1       0x49
-#define TDA10048_GPIO_SP_DS2       0x4A
-#define TDA10048_GPIO_SP_DS3       0x4B
-#define TDA10048_GPIO_OUT_SEL      0x4C
-#define TDA10048_GPIO_SELECT       0x4D
-#define TDA10048_IC_MODE           0x4E
-#define TDA10048_CONF_XO           0x50
-#define TDA10048_CONF_PLL1         0x51
-#define TDA10048_CONF_PLL2         0x52
-#define TDA10048_CONF_PLL3         0x53
-#define TDA10048_CONF_ADC          0x54
-#define TDA10048_CONF_ADC_2        0x55
-#define TDA10048_CONF_C1_1         0x60
-#define TDA10048_CONF_C1_3         0x62
-#define TDA10048_AGC_CONF          0x70
-#define TDA10048_AGC_THRESHOLD_LSB 0x72
-#define TDA10048_AGC_THRESHOLD_MSB 0x73
-#define TDA10048_AGC_RENORM        0x74
-#define TDA10048_AGC_GAINS         0x76
-#define TDA10048_AGC_TUN_MIN       0x78
-#define TDA10048_AGC_TUN_MAX       0x79
-#define TDA10048_AGC_IF_MIN        0x7A
-#define TDA10048_AGC_IF_MAX        0x7B
-#define TDA10048_AGC_TUN_LEVEL     0x7E
-#define TDA10048_AGC_IF_LEVEL      0x7F
-#define TDA10048_DIG_AGC_LEVEL     0x81
-#define TDA10048_FREQ_PHY2_LSB     0x86
-#define TDA10048_FREQ_PHY2_MSB     0x87
-#define TDA10048_TIME_INVWREF_LSB  0x88
-#define TDA10048_TIME_INVWREF_MSB  0x89
-#define TDA10048_TIME_WREF_LSB     0x8A
-#define TDA10048_TIME_WREF_MID1    0x8B
-#define TDA10048_TIME_WREF_MID2    0x8C
-#define TDA10048_TIME_WREF_MSB     0x8D
-#define TDA10048_NP_OUT            0xA2
-#define TDA10048_CELL_ID_LSB       0xA4
-#define TDA10048_CELL_ID_MSB       0xA5
-#define TDA10048_EXTTPS_ODD        0xAA
-#define TDA10048_EXTTPS_EVEN       0xAB
-#define TDA10048_TPS_LENGTH        0xAC
-#define TDA10048_FREE_REG_1        0xB2
-#define TDA10048_FREE_REG_2        0xB3
-#define TDA10048_CONF_C3_1         0xC0
-#define TDA10048_CVBER_CTRL        0xC2
-#define TDA10048_CBER_NMAX_LSB     0xC4
-#define TDA10048_CBER_NMAX_MSB     0xC5
-#define TDA10048_CBER_LSB          0xC6
-#define TDA10048_CBER_MSB          0xC7
-#define TDA10048_VBER_LSB          0xC8
-#define TDA10048_VBER_MID          0xC9
-#define TDA10048_VBER_MSB          0xCA
-#define TDA10048_CVBER_LUT         0xCC
-#define TDA10048_UNCOR_CTRL        0xCD
-#define TDA10048_UNCOR_CPT_LSB     0xCE
-#define TDA10048_UNCOR_CPT_MSB     0xCF
-#define TDA10048_SOFT_IT_C3        0xD6
-#define TDA10048_CONF_TS2          0xE0
-#define TDA10048_CONF_TS1          0xE1
-
-static unsigned int debug;
-
-#define dprintk(level, fmt, arg...)\
-       do { if (debug >= level)\
-               printk(KERN_DEBUG "tda10048: " fmt, ## arg);\
-       } while (0)
-
-struct tda10048_state {
-
-       struct i2c_adapter *i2c;
-
-       /* We'll cache and update the attach config settings */
-       struct tda10048_config config;
-       struct dvb_frontend frontend;
-
-       int fwloaded;
-
-       u32 freq_if_hz;
-       u32 xtal_hz;
-       u32 pll_mfactor;
-       u32 pll_nfactor;
-       u32 pll_pfactor;
-       u32 sample_freq;
-
-       u32 bandwidth;
-};
-
-static struct init_tab {
-       u8      reg;
-       u16     data;
-} init_tab[] = {
-       { TDA10048_CONF_PLL1, 0x08 },
-       { TDA10048_CONF_ADC_2, 0x00 },
-       { TDA10048_CONF_C4_1, 0x00 },
-       { TDA10048_CONF_PLL1, 0x0f },
-       { TDA10048_CONF_PLL2, 0x0a },
-       { TDA10048_CONF_PLL3, 0x43 },
-       { TDA10048_FREQ_PHY2_LSB, 0x02 },
-       { TDA10048_FREQ_PHY2_MSB, 0x0a },
-       { TDA10048_TIME_WREF_LSB, 0xbd },
-       { TDA10048_TIME_WREF_MID1, 0xe4 },
-       { TDA10048_TIME_WREF_MID2, 0xa8 },
-       { TDA10048_TIME_WREF_MSB, 0x02 },
-       { TDA10048_TIME_INVWREF_LSB, 0x04 },
-       { TDA10048_TIME_INVWREF_MSB, 0x06 },
-       { TDA10048_CONF_C4_1, 0x00 },
-       { TDA10048_CONF_C1_1, 0xa8 },
-       { TDA10048_AGC_CONF, 0x16 },
-       { TDA10048_CONF_C1_3, 0x0b },
-       { TDA10048_AGC_TUN_MIN, 0x00 },
-       { TDA10048_AGC_TUN_MAX, 0xff },
-       { TDA10048_AGC_IF_MIN, 0x00 },
-       { TDA10048_AGC_IF_MAX, 0xff },
-       { TDA10048_AGC_THRESHOLD_MSB, 0x00 },
-       { TDA10048_AGC_THRESHOLD_LSB, 0x70 },
-       { TDA10048_CVBER_CTRL, 0x38 },
-       { TDA10048_AGC_GAINS, 0x12 },
-       { TDA10048_CONF_XO, 0x00 },
-       { TDA10048_CONF_TS1, 0x07 },
-       { TDA10048_IC_MODE, 0x00 },
-       { TDA10048_CONF_TS2, 0xc0 },
-       { TDA10048_CONF_TRISTATE1, 0x21 },
-       { TDA10048_CONF_TRISTATE2, 0x00 },
-       { TDA10048_CONF_POLARITY, 0x00 },
-       { TDA10048_CONF_C4_2, 0x04 },
-       { TDA10048_CONF_ADC, 0x60 },
-       { TDA10048_CONF_ADC_2, 0x10 },
-       { TDA10048_CONF_ADC, 0x60 },
-       { TDA10048_CONF_ADC_2, 0x00 },
-       { TDA10048_CONF_C1_1, 0xa8 },
-       { TDA10048_UNCOR_CTRL, 0x00 },
-       { TDA10048_CONF_C4_2, 0x04 },
-};
-
-static struct pll_tab {
-       u32     clk_freq_khz;
-       u32     if_freq_khz;
-} pll_tab[] = {
-       { TDA10048_CLK_4000,  TDA10048_IF_36130 },
-       { TDA10048_CLK_16000, TDA10048_IF_3300 },
-       { TDA10048_CLK_16000, TDA10048_IF_3500 },
-       { TDA10048_CLK_16000, TDA10048_IF_3800 },
-       { TDA10048_CLK_16000, TDA10048_IF_4000 },
-       { TDA10048_CLK_16000, TDA10048_IF_4300 },
-       { TDA10048_CLK_16000, TDA10048_IF_4500 },
-       { TDA10048_CLK_16000, TDA10048_IF_5000 },
-       { TDA10048_CLK_16000, TDA10048_IF_36130 },
-};
-
-static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
-{
-       struct tda10048_config *config = &state->config;
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = {
-               .addr = config->demod_address,
-               .flags = 0, .buf = buf, .len = 2 };
-
-       dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk("%s: writereg error (ret == %i)\n", __func__, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
-{
-       struct tda10048_config *config = &state->config;
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               { .addr = config->demod_address,
-                       .flags = 0, .buf = b0, .len = 1 },
-               { .addr = config->demod_address,
-                       .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg);
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk(KERN_ERR "%s: readreg error (ret == %i)\n",
-                       __func__, ret);
-
-       return b1[0];
-}
-
-static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
-                                const u8 *data, u16 len)
-{
-       struct tda10048_config *config = &state->config;
-       int ret = -EREMOTEIO;
-       struct i2c_msg msg;
-       u8 *buf;
-
-       dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len);
-
-       buf = kmalloc(len + 1, GFP_KERNEL);
-       if (buf == NULL) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       *buf = reg;
-       memcpy(buf + 1, data, len);
-
-       msg.addr = config->demod_address;
-       msg.flags = 0;
-       msg.buf = buf;
-       msg.len = len + 1;
-
-       dprintk(2, "%s():  write len = %d\n",
-               __func__, msg.len);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-       if (ret != 1) {
-               printk(KERN_ERR "%s(): writereg error err %i\n",
-                        __func__, ret);
-               ret = -EREMOTEIO;
-       }
-
-error:
-       kfree(buf);
-
-       return ret;
-}
-
-static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz,
-                            u32 if_hz)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u64 t;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (sample_freq_hz == 0)
-               return -EINVAL;
-
-       if (if_hz < (sample_freq_hz / 2)) {
-               /* PHY2 = (if2/fs) * 2^15 */
-               t = if_hz;
-               t *= 10;
-               t *= 32768;
-               do_div(t, sample_freq_hz);
-               t += 5;
-               do_div(t, 10);
-       } else {
-               /* PHY2 = ((IF1-fs)/fs) * 2^15 */
-               t = sample_freq_hz - if_hz;
-               t *= 10;
-               t *= 32768;
-               do_div(t, sample_freq_hz);
-               t += 5;
-               do_div(t, 10);
-               t = ~t + 1;
-       }
-
-       tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t);
-       tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8));
-
-       return 0;
-}
-
-static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz,
-                            u32 bw)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u64 t, z;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (sample_freq_hz == 0)
-               return -EINVAL;
-
-       /* WREF = (B / (7 * fs)) * 2^31 */
-       t = bw * 10;
-       /* avoid warning: this decimal constant is unsigned only in ISO C90 */
-       /* t *= 2147483648 on 32bit platforms */
-       t *= (2048 * 1024);
-       t *= 1024;
-       z = 7 * sample_freq_hz;
-       do_div(t, z);
-       t += 5;
-       do_div(t, 10);
-
-       tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t);
-       tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8));
-       tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16));
-       tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24));
-
-       return 0;
-}
-
-static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz,
-                               u32 bw)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u64 t;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (sample_freq_hz == 0)
-               return -EINVAL;
-
-       /* INVWREF = ((7 * fs) / B) * 2^5 */
-       t = sample_freq_hz;
-       t *= 7;
-       t *= 32;
-       t *= 10;
-       do_div(t, bw);
-       t += 5;
-       do_div(t, 10);
-
-       tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t);
-       tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8));
-
-       return 0;
-}
-
-static int tda10048_set_bandwidth(struct dvb_frontend *fe,
-       u32 bw)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       dprintk(1, "%s(bw=%d)\n", __func__, bw);
-
-       /* Bandwidth setting may need to be adjusted */
-       switch (bw) {
-       case 6000000:
-       case 7000000:
-       case 8000000:
-               tda10048_set_wref(fe, state->sample_freq, bw);
-               tda10048_set_invwref(fe, state->sample_freq, bw);
-               break;
-       default:
-               printk(KERN_ERR "%s() invalid bandwidth\n", __func__);
-               return -EINVAL;
-       }
-
-       state->bandwidth = bw;
-
-       return 0;
-}
-
-static int tda10048_set_if(struct dvb_frontend *fe, u32 bw)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       struct tda10048_config *config = &state->config;
-       int i;
-       u32 if_freq_khz;
-
-       dprintk(1, "%s(bw = %d)\n", __func__, bw);
-
-       /* based on target bandwidth and clk we calculate pll factors */
-       switch (bw) {
-       case 6000000:
-               if_freq_khz = config->dtv6_if_freq_khz;
-               break;
-       case 7000000:
-               if_freq_khz = config->dtv7_if_freq_khz;
-               break;
-       case 8000000:
-               if_freq_khz = config->dtv8_if_freq_khz;
-               break;
-       default:
-               printk(KERN_ERR "%s() no default\n", __func__);
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(pll_tab); i++) {
-               if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) &&
-                       (pll_tab[i].if_freq_khz == if_freq_khz)) {
-
-                       state->freq_if_hz = pll_tab[i].if_freq_khz * 1000;
-                       state->xtal_hz = pll_tab[i].clk_freq_khz * 1000;
-                       break;
-               }
-       }
-       if (i == ARRAY_SIZE(pll_tab)) {
-               printk(KERN_ERR "%s() Incorrect attach settings\n",
-                       __func__);
-               return -EINVAL;
-       }
-
-       dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz);
-       dprintk(1, "- xtal_hz = %d\n", state->xtal_hz);
-       dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor);
-       dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor);
-       dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
-
-       /* Calculate the sample frequency */
-       state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
-       state->sample_freq /= (state->pll_nfactor + 1);
-       state->sample_freq /= (state->pll_pfactor + 4);
-       dprintk(1, "- sample_freq = %d\n", state->sample_freq);
-
-       /* Update the I/F */
-       tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz);
-
-       return 0;
-}
-
-static int tda10048_firmware_upload(struct dvb_frontend *fe)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       struct tda10048_config *config = &state->config;
-       const struct firmware *fw;
-       int ret;
-       int pos = 0;
-       int cnt;
-       u8 wlen = config->fwbulkwritelen;
-
-       if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50))
-               wlen = TDA10048_BULKWRITE_200;
-
-       /* request the firmware, this will block and timeout */
-       printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n",
-               __func__,
-               TDA10048_DEFAULT_FIRMWARE);
-
-       ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
-               state->i2c->dev.parent);
-       if (ret) {
-               printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
-                       __func__);
-               return -EIO;
-       } else {
-               printk(KERN_INFO "%s: firmware read %Zu bytes.\n",
-                       __func__,
-                       fw->size);
-               ret = 0;
-       }
-
-       if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
-               printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
-               ret = -EIO;
-       } else {
-               printk(KERN_INFO "%s: firmware uploading\n", __func__);
-
-               /* Soft reset */
-               tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
-                       tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
-                               & 0xfe);
-               tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
-                       tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
-                               | 0x01);
-
-               /* Put the demod into host download mode */
-               tda10048_writereg(state, TDA10048_CONF_C4_1,
-                       tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9);
-
-               /* Boot the DSP */
-               tda10048_writereg(state, TDA10048_CONF_C4_1,
-                       tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08);
-
-               /* Prepare for download */
-               tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0);
-
-               /* Download the firmware payload */
-               while (pos < fw->size) {
-
-                       if ((fw->size - pos) > wlen)
-                               cnt = wlen;
-                       else
-                               cnt = fw->size - pos;
-
-                       tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN,
-                               &fw->data[pos], cnt);
-
-                       pos += cnt;
-               }
-
-               ret = -EIO;
-               /* Wait up to 250ms for the DSP to boot */
-               for (cnt = 0; cnt < 250 ; cnt += 10) {
-
-                       msleep(10);
-
-                       if (tda10048_readreg(state, TDA10048_SYNC_STATUS)
-                               & 0x40) {
-                               ret = 0;
-                               break;
-                       }
-               }
-       }
-
-       release_firmware(fw);
-
-       if (ret == 0) {
-               printk(KERN_INFO "%s: firmware uploaded\n", __func__);
-               state->fwloaded = 1;
-       } else
-               printk(KERN_ERR "%s: firmware upload failed\n", __func__);
-
-       return ret;
-}
-
-static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-
-       dprintk(1, "%s(%d)\n", __func__, inversion);
-
-       if (inversion == TDA10048_INVERSION_ON)
-               tda10048_writereg(state, TDA10048_CONF_C1_1,
-                       tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20);
-       else
-               tda10048_writereg(state, TDA10048_CONF_C1_1,
-                       tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf);
-
-       return 0;
-}
-
-/* Retrieve the demod settings */
-static int tda10048_get_tps(struct tda10048_state *state,
-       struct dtv_frontend_properties *p)
-{
-       u8 val;
-
-       /* Make sure the TPS regs are valid */
-       if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01))
-               return -EAGAIN;
-
-       val = tda10048_readreg(state, TDA10048_OUT_CONF2);
-       switch ((val & 0x60) >> 5) {
-       case 0:
-               p->modulation = QPSK;
-               break;
-       case 1:
-               p->modulation = QAM_16;
-               break;
-       case 2:
-               p->modulation = QAM_64;
-               break;
-       }
-       switch ((val & 0x18) >> 3) {
-       case 0:
-               p->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               p->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               p->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               p->hierarchy = HIERARCHY_4;
-               break;
-       }
-       switch (val & 0x07) {
-       case 0:
-               p->code_rate_HP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_HP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_HP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_HP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_HP = FEC_7_8;
-               break;
-       }
-
-       val = tda10048_readreg(state, TDA10048_OUT_CONF3);
-       switch (val & 0x07) {
-       case 0:
-               p->code_rate_LP = FEC_1_2;
-               break;
-       case 1:
-               p->code_rate_LP = FEC_2_3;
-               break;
-       case 2:
-               p->code_rate_LP = FEC_3_4;
-               break;
-       case 3:
-               p->code_rate_LP = FEC_5_6;
-               break;
-       case 4:
-               p->code_rate_LP = FEC_7_8;
-               break;
-       }
-
-       val = tda10048_readreg(state, TDA10048_OUT_CONF1);
-       switch ((val & 0x0c) >> 2) {
-       case 0:
-               p->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               p->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               p->guard_interval =  GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               p->guard_interval =  GUARD_INTERVAL_1_4;
-               break;
-       }
-       switch (val & 0x03) {
-       case 0:
-               p->transmission_mode = TRANSMISSION_MODE_2K;
-               break;
-       case 1:
-               p->transmission_mode = TRANSMISSION_MODE_8K;
-               break;
-       }
-
-       return 0;
-}
-
-static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       struct tda10048_config *config = &state->config;
-       dprintk(1, "%s(%d)\n", __func__, enable);
-
-       if (config->disable_gate_access)
-               return 0;
-
-       if (enable)
-               return tda10048_writereg(state, TDA10048_CONF_C4_1,
-                       tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
-       else
-               return tda10048_writereg(state, TDA10048_CONF_C4_1,
-                       tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
-}
-
-static int tda10048_output_mode(struct dvb_frontend *fe, int serial)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       dprintk(1, "%s(%d)\n", __func__, serial);
-
-       /* Ensure pins are out of tri-state */
-       tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21);
-       tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00);
-
-       if (serial) {
-               tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20);
-               tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0);
-       } else {
-               tda10048_writereg(state, TDA10048_IC_MODE, 0x00);
-               tda10048_writereg(state, TDA10048_CONF_TS2, 0x01);
-       }
-
-       return 0;
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-/* TODO: Support manual tuning with specific params */
-static int tda10048_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda10048_state *state = fe->demodulator_priv;
-
-       dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
-
-       /* Update the I/F pll's if the bandwidth changes */
-       if (p->bandwidth_hz != state->bandwidth) {
-               tda10048_set_if(fe, p->bandwidth_hz);
-               tda10048_set_bandwidth(fe, p->bandwidth_hz);
-       }
-
-       if (fe->ops.tuner_ops.set_params) {
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               fe->ops.tuner_ops.set_params(fe);
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* Enable demod TPS auto detection and begin acquisition */
-       tda10048_writereg(state, TDA10048_AUTO, 0x57);
-       /* trigger cber and vber acquisition */
-       tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B);
-
-       return 0;
-}
-
-/* Establish sane defaults and load firmware. */
-static int tda10048_init(struct dvb_frontend *fe)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       struct tda10048_config *config = &state->config;
-       int ret = 0, i;
-
-       dprintk(1, "%s()\n", __func__);
-
-       /* PLL */
-       init_tab[4].data = (u8)(state->pll_mfactor);
-       init_tab[5].data = (u8)(state->pll_nfactor) | 0x40;
-
-       /* Apply register defaults */
-       for (i = 0; i < ARRAY_SIZE(init_tab); i++)
-               tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);
-
-       if (state->fwloaded == 0)
-               ret = tda10048_firmware_upload(fe);
-
-       /* Set either serial or parallel */
-       tda10048_output_mode(fe, config->output_mode);
-
-       /* Set inversion */
-       tda10048_set_inversion(fe, config->inversion);
-
-       /* Establish default RF values */
-       tda10048_set_if(fe, 8000000);
-       tda10048_set_bandwidth(fe, 8000000);
-
-       /* Ensure we leave the gate closed */
-       tda10048_i2c_gate_ctrl(fe, 0);
-
-       return ret;
-}
-
-static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u8 reg;
-
-       *status = 0;
-
-       reg = tda10048_readreg(state, TDA10048_SYNC_STATUS);
-
-       dprintk(1, "%s() status =0x%02x\n", __func__, reg);
-
-       if (reg & 0x02)
-               *status |= FE_HAS_CARRIER;
-
-       if (reg & 0x04)
-               *status |= FE_HAS_SIGNAL;
-
-       if (reg & 0x08) {
-               *status |= FE_HAS_LOCK;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-       }
-
-       return 0;
-}
-
-static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       static u32 cber_current;
-       u32 cber_nmax;
-       u64 cber_tmp;
-
-       dprintk(1, "%s()\n", __func__);
-
-       /* update cber on interrupt */
-       if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) {
-               cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
-                       tda10048_readreg(state, TDA10048_CBER_LSB);
-               cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 |
-                       tda10048_readreg(state, TDA10048_CBER_NMAX_LSB);
-               cber_tmp *= 100000000;
-               cber_tmp *= 2;
-               cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1);
-               cber_current = (u32)cber_tmp;
-               /* retrigger cber acquisition */
-               tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39);
-       }
-       /* actual cber is (*ber)/1e8 */
-       *ber = cber_current;
-
-       return 0;
-}
-
-static int tda10048_read_signal_strength(struct dvb_frontend *fe,
-       u16 *signal_strength)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u8 v;
-
-       dprintk(1, "%s()\n", __func__);
-
-       *signal_strength = 65535;
-
-       v = tda10048_readreg(state, TDA10048_NP_OUT);
-       if (v > 0)
-               *signal_strength -= (v << 8) | v;
-
-       return 0;
-}
-
-/* SNR lookup table */
-static struct snr_tab {
-       u8 val;
-       u8 data;
-} snr_tab[] = {
-       {   0,   0 },
-       {   1, 246 },
-       {   2, 215 },
-       {   3, 198 },
-       {   4, 185 },
-       {   5, 176 },
-       {   6, 168 },
-       {   7, 161 },
-       {   8, 155 },
-       {   9, 150 },
-       {  10, 146 },
-       {  11, 141 },
-       {  12, 138 },
-       {  13, 134 },
-       {  14, 131 },
-       {  15, 128 },
-       {  16, 125 },
-       {  17, 122 },
-       {  18, 120 },
-       {  19, 118 },
-       {  20, 115 },
-       {  21, 113 },
-       {  22, 111 },
-       {  23, 109 },
-       {  24, 107 },
-       {  25, 106 },
-       {  26, 104 },
-       {  27, 102 },
-       {  28, 101 },
-       {  29,  99 },
-       {  30,  98 },
-       {  31,  96 },
-       {  32,  95 },
-       {  33,  94 },
-       {  34,  92 },
-       {  35,  91 },
-       {  36,  90 },
-       {  37,  89 },
-       {  38,  88 },
-       {  39,  86 },
-       {  40,  85 },
-       {  41,  84 },
-       {  42,  83 },
-       {  43,  82 },
-       {  44,  81 },
-       {  45,  80 },
-       {  46,  79 },
-       {  47,  78 },
-       {  48,  77 },
-       {  49,  76 },
-       {  50,  76 },
-       {  51,  75 },
-       {  52,  74 },
-       {  53,  73 },
-       {  54,  72 },
-       {  56,  71 },
-       {  57,  70 },
-       {  58,  69 },
-       {  60,  68 },
-       {  61,  67 },
-       {  63,  66 },
-       {  64,  65 },
-       {  66,  64 },
-       {  67,  63 },
-       {  68,  62 },
-       {  69,  62 },
-       {  70,  61 },
-       {  72,  60 },
-       {  74,  59 },
-       {  75,  58 },
-       {  77,  57 },
-       {  79,  56 },
-       {  81,  55 },
-       {  83,  54 },
-       {  85,  53 },
-       {  87,  52 },
-       {  89,  51 },
-       {  91,  50 },
-       {  93,  49 },
-       {  95,  48 },
-       {  97,  47 },
-       { 100,  46 },
-       { 102,  45 },
-       { 104,  44 },
-       { 107,  43 },
-       { 109,  42 },
-       { 112,  41 },
-       { 114,  40 },
-       { 117,  39 },
-       { 120,  38 },
-       { 123,  37 },
-       { 125,  36 },
-       { 128,  35 },
-       { 131,  34 },
-       { 134,  33 },
-       { 138,  32 },
-       { 141,  31 },
-       { 144,  30 },
-       { 147,  29 },
-       { 151,  28 },
-       { 154,  27 },
-       { 158,  26 },
-       { 162,  25 },
-       { 165,  24 },
-       { 169,  23 },
-       { 173,  22 },
-       { 177,  21 },
-       { 181,  20 },
-       { 186,  19 },
-       { 190,  18 },
-       { 194,  17 },
-       { 199,  16 },
-       { 204,  15 },
-       { 208,  14 },
-       { 213,  13 },
-       { 218,  12 },
-       { 223,  11 },
-       { 229,  10 },
-       { 234,   9 },
-       { 239,   8 },
-       { 245,   7 },
-       { 251,   6 },
-       { 255,   5 },
-};
-
-static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       u8 v;
-       int i, ret = -EINVAL;
-
-       dprintk(1, "%s()\n", __func__);
-
-       v = tda10048_readreg(state, TDA10048_NP_OUT);
-       for (i = 0; i < ARRAY_SIZE(snr_tab); i++) {
-               if (v <= snr_tab[i].val) {
-                       *snr = snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-
-       return ret;
-}
-
-static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-
-       dprintk(1, "%s()\n", __func__);
-
-       *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |
-               tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);
-       /* clear the uncorrected TS packets counter when saturated */
-       if (*ucblocks == 0xFFFF)
-               tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80);
-
-       return 0;
-}
-
-static int tda10048_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda10048_state *state = fe->demodulator_priv;
-
-       dprintk(1, "%s()\n", __func__);
-
-       p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1)
-               & 0x20 ? INVERSION_ON : INVERSION_OFF;
-
-       return tda10048_get_tps(state, p);
-}
-
-static int tda10048_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *tune)
-{
-       tune->min_delay_ms = 1000;
-       return 0;
-}
-
-static void tda10048_release(struct dvb_frontend *fe)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       dprintk(1, "%s()\n", __func__);
-       kfree(state);
-}
-
-static void tda10048_establish_defaults(struct dvb_frontend *fe)
-{
-       struct tda10048_state *state = fe->demodulator_priv;
-       struct tda10048_config *config = &state->config;
-
-       /* Validate/default the config */
-       if (config->dtv6_if_freq_khz == 0) {
-               config->dtv6_if_freq_khz = TDA10048_IF_4300;
-               printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz "
-                       "is not set (defaulting to %d)\n",
-                       __func__,
-                       config->dtv6_if_freq_khz);
-       }
-
-       if (config->dtv7_if_freq_khz == 0) {
-               config->dtv7_if_freq_khz = TDA10048_IF_4300;
-               printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz "
-                       "is not set (defaulting to %d)\n",
-                       __func__,
-                       config->dtv7_if_freq_khz);
-       }
-
-       if (config->dtv8_if_freq_khz == 0) {
-               config->dtv8_if_freq_khz = TDA10048_IF_4300;
-               printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz "
-                       "is not set (defaulting to %d)\n",
-                       __func__,
-                       config->dtv8_if_freq_khz);
-       }
-
-       if (config->clk_freq_khz == 0) {
-               config->clk_freq_khz = TDA10048_CLK_16000;
-               printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz "
-                       "is not set (defaulting to %d)\n",
-                       __func__,
-                       config->clk_freq_khz);
-       }
-}
-
-static struct dvb_frontend_ops tda10048_ops;
-
-struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
-       struct i2c_adapter *i2c)
-{
-       struct tda10048_state *state = NULL;
-
-       dprintk(1, "%s()\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state and clone the config */
-       memcpy(&state->config, config, sizeof(*config));
-       state->i2c = i2c;
-       state->fwloaded = config->no_firmware;
-       state->bandwidth = 8000000;
-
-       /* check if the demod is present */
-       if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10048_ops,
-               sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       /* set pll */
-       if (config->set_pll) {
-               state->pll_mfactor = config->pll_m;
-               state->pll_nfactor = config->pll_n;
-               state->pll_pfactor = config->pll_p;
-       } else {
-               state->pll_mfactor = 10;
-               state->pll_nfactor = 3;
-               state->pll_pfactor = 0;
-       }
-
-       /* Establish any defaults the the user didn't pass */
-       tda10048_establish_defaults(&state->frontend);
-
-       /* Set the xtal and freq defaults */
-       if (tda10048_set_if(&state->frontend, 8000000) != 0)
-               goto error;
-
-       /* Default bandwidth */
-       if (tda10048_set_bandwidth(&state->frontend, 8000000) != 0)
-               goto error;
-
-       /* Leave the gate closed */
-       tda10048_i2c_gate_ctrl(&state->frontend, 0);
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(tda10048_attach);
-
-static struct dvb_frontend_ops tda10048_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "NXP TDA10048HN DVB-T",
-               .frequency_min          = 177000000,
-               .frequency_max          = 858000000,
-               .frequency_stepsize     = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-               FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-               FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
-       },
-
-       .release = tda10048_release,
-       .init = tda10048_init,
-       .i2c_gate_ctrl = tda10048_i2c_gate_ctrl,
-       .set_frontend = tda10048_set_frontend,
-       .get_frontend = tda10048_get_frontend,
-       .get_tune_settings = tda10048_get_tune_settings,
-       .read_status = tda10048_read_status,
-       .read_ber = tda10048_read_ber,
-       .read_signal_strength = tda10048_read_signal_strength,
-       .read_snr = tda10048_read_snr,
-       .read_ucblocks = tda10048_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
deleted file mode 100644 (file)
index fb2ef5a..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-    NXP TDA10048HN DVB OFDM demodulator driver
-
-    Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef TDA10048_H
-#define TDA10048_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct tda10048_config {
-
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* serial/parallel output */
-#define TDA10048_PARALLEL_OUTPUT 0
-#define TDA10048_SERIAL_OUTPUT   1
-       u8 output_mode;
-
-#define TDA10048_BULKWRITE_200 200
-#define TDA10048_BULKWRITE_50  50
-       u8 fwbulkwritelen;
-
-       /* Spectral Inversion */
-#define TDA10048_INVERSION_OFF 0
-#define TDA10048_INVERSION_ON  1
-       u8 inversion;
-
-#define TDA10048_IF_3300  3300
-#define TDA10048_IF_3500  3500
-#define TDA10048_IF_3800  3800
-#define TDA10048_IF_4000  4000
-#define TDA10048_IF_4300  4300
-#define TDA10048_IF_4500  4500
-#define TDA10048_IF_4750  4750
-#define TDA10048_IF_5000  5000
-#define TDA10048_IF_36130 36130
-       u16 dtv6_if_freq_khz;
-       u16 dtv7_if_freq_khz;
-       u16 dtv8_if_freq_khz;
-
-#define TDA10048_CLK_4000  4000
-#define TDA10048_CLK_16000 16000
-       u16 clk_freq_khz;
-
-       /* Disable I2C gate access */
-       u8 disable_gate_access;
-
-       bool no_firmware;
-
-       bool set_pll;
-       u8 pll_m;
-       u8 pll_p;
-       u8 pll_n;
-};
-
-#if defined(CONFIG_DVB_TDA10048) || \
-       (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda10048_attach(
-       const struct tda10048_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *tda10048_attach(
-       const struct tda10048_config *config,
-       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_TDA10048 */
-
-#endif /* TDA10048_H */
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
deleted file mode 100644 (file)
index 35d72b4..0000000
+++ /dev/null
@@ -1,1381 +0,0 @@
-  /*
-     Driver for Philips tda1004xh OFDM Demodulator
-
-     (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   */
-/*
- * This driver needs external firmware. Please use the commands
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
- * download/extract them, and then copy them to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
-#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "tda1004x.h"
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "tda1004x: " args); \
-       } while (0)
-
-#define TDA1004X_CHIPID                 0x00
-#define TDA1004X_AUTO           0x01
-#define TDA1004X_IN_CONF1       0x02
-#define TDA1004X_IN_CONF2       0x03
-#define TDA1004X_OUT_CONF1      0x04
-#define TDA1004X_OUT_CONF2      0x05
-#define TDA1004X_STATUS_CD      0x06
-#define TDA1004X_CONFC4                 0x07
-#define TDA1004X_DSSPARE2       0x0C
-#define TDA10045H_CODE_IN       0x0D
-#define TDA10045H_FWPAGE        0x0E
-#define TDA1004X_SCAN_CPT       0x10
-#define TDA1004X_DSP_CMD        0x11
-#define TDA1004X_DSP_ARG        0x12
-#define TDA1004X_DSP_DATA1      0x13
-#define TDA1004X_DSP_DATA2      0x14
-#define TDA1004X_CONFADC1       0x15
-#define TDA1004X_CONFC1                 0x16
-#define TDA10045H_S_AGC                 0x1a
-#define TDA10046H_AGC_TUN_LEVEL         0x1a
-#define TDA1004X_SNR            0x1c
-#define TDA1004X_CONF_TS1       0x1e
-#define TDA1004X_CONF_TS2       0x1f
-#define TDA1004X_CBER_RESET     0x20
-#define TDA1004X_CBER_MSB       0x21
-#define TDA1004X_CBER_LSB       0x22
-#define TDA1004X_CVBER_LUT      0x23
-#define TDA1004X_VBER_MSB       0x24
-#define TDA1004X_VBER_MID       0x25
-#define TDA1004X_VBER_LSB       0x26
-#define TDA1004X_UNCOR          0x27
-
-#define TDA10045H_CONFPLL_P     0x2D
-#define TDA10045H_CONFPLL_M_MSB         0x2E
-#define TDA10045H_CONFPLL_M_LSB         0x2F
-#define TDA10045H_CONFPLL_N     0x30
-
-#define TDA10046H_CONFPLL1      0x2D
-#define TDA10046H_CONFPLL2      0x2F
-#define TDA10046H_CONFPLL3      0x30
-#define TDA10046H_TIME_WREF1    0x31
-#define TDA10046H_TIME_WREF2    0x32
-#define TDA10046H_TIME_WREF3    0x33
-#define TDA10046H_TIME_WREF4    0x34
-#define TDA10046H_TIME_WREF5    0x35
-
-#define TDA10045H_UNSURW_MSB    0x31
-#define TDA10045H_UNSURW_LSB    0x32
-#define TDA10045H_WREF_MSB      0x33
-#define TDA10045H_WREF_MID      0x34
-#define TDA10045H_WREF_LSB      0x35
-#define TDA10045H_MUXOUT        0x36
-#define TDA1004X_CONFADC2       0x37
-
-#define TDA10045H_IOFFSET       0x38
-
-#define TDA10046H_CONF_TRISTATE1 0x3B
-#define TDA10046H_CONF_TRISTATE2 0x3C
-#define TDA10046H_CONF_POLARITY         0x3D
-#define TDA10046H_FREQ_OFFSET   0x3E
-#define TDA10046H_GPIO_OUT_SEL  0x41
-#define TDA10046H_GPIO_SELECT   0x42
-#define TDA10046H_AGC_CONF      0x43
-#define TDA10046H_AGC_THR       0x44
-#define TDA10046H_AGC_RENORM    0x45
-#define TDA10046H_AGC_GAINS     0x46
-#define TDA10046H_AGC_TUN_MIN   0x47
-#define TDA10046H_AGC_TUN_MAX   0x48
-#define TDA10046H_AGC_IF_MIN    0x49
-#define TDA10046H_AGC_IF_MAX    0x4A
-
-#define TDA10046H_FREQ_PHY2_MSB         0x4D
-#define TDA10046H_FREQ_PHY2_LSB         0x4E
-
-#define TDA10046H_CVBER_CTRL    0x4F
-#define TDA10046H_AGC_IF_LEVEL  0x52
-#define TDA10046H_CODE_CPT      0x57
-#define TDA10046H_CODE_IN       0x58
-
-
-static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
-
-       dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data);
-
-       msg.addr = state->config->demod_address;
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
-                       __func__, reg, data, ret);
-
-       dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
-               reg, data, ret);
-       return (ret != 1) ? -1 : 0;
-}
-
-static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
-                               { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
-
-       dprintk("%s: reg=0x%x\n", __func__, reg);
-
-       msg[0].addr = state->config->demod_address;
-       msg[1].addr = state->config->demod_address;
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
-                       ret);
-               return -EINVAL;
-       }
-
-       dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
-               reg, b1[0], ret);
-       return b1[0];
-}
-
-static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
-{
-       int val;
-       dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg,
-               mask, data);
-
-       // read a byte and check
-       val = tda1004x_read_byte(state, reg);
-       if (val < 0)
-               return val;
-
-       // mask if off
-       val = val & ~mask;
-       val |= data & 0xff;
-
-       // write it out again
-       return tda1004x_write_byteI(state, reg, val);
-}
-
-static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
-{
-       int i;
-       int result;
-
-       dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len);
-
-       result = 0;
-       for (i = 0; i < len; i++) {
-               result = tda1004x_write_byteI(state, reg + i, buf[i]);
-               if (result != 0)
-                       break;
-       }
-
-       return result;
-}
-
-static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
-{
-       int result;
-       dprintk("%s\n", __func__);
-
-       result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
-       msleep(20);
-       return result;
-}
-
-static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
-{
-       dprintk("%s\n", __func__);
-
-       return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
-}
-
-static int tda10045h_set_bandwidth(struct tda1004x_state *state,
-                                  u32 bandwidth)
-{
-       static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
-       static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
-       static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
-
-       switch (bandwidth) {
-       case 6000000:
-               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
-               break;
-
-       case 7000000:
-               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
-               break;
-
-       case 8000000:
-               tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
-
-       return 0;
-}
-
-static int tda10046h_set_bandwidth(struct tda1004x_state *state,
-                                  u32 bandwidth)
-{
-       static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
-       static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
-       static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
-
-       static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
-       static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
-       static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
-       int tda10046_clk53m;
-
-       if ((state->config->if_freq == TDA10046_FREQ_045) ||
-           (state->config->if_freq == TDA10046_FREQ_052))
-               tda10046_clk53m = 0;
-       else
-               tda10046_clk53m = 1;
-       switch (bandwidth) {
-       case 6000000:
-               if (tda10046_clk53m)
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
-                                                 sizeof(bandwidth_6mhz_53M));
-               else
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
-                                                 sizeof(bandwidth_6mhz_48M));
-               if (state->config->if_freq == TDA10046_FREQ_045) {
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
-               }
-               break;
-
-       case 7000000:
-               if (tda10046_clk53m)
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
-                                                 sizeof(bandwidth_7mhz_53M));
-               else
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
-                                                 sizeof(bandwidth_7mhz_48M));
-               if (state->config->if_freq == TDA10046_FREQ_045) {
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
-               }
-               break;
-
-       case 8000000:
-               if (tda10046_clk53m)
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
-                                                 sizeof(bandwidth_8mhz_53M));
-               else
-                       tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
-                                                 sizeof(bandwidth_8mhz_48M));
-               if (state->config->if_freq == TDA10046_FREQ_045) {
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
-                       tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
-               }
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int tda1004x_do_upload(struct tda1004x_state *state,
-                             const unsigned char *mem, unsigned int len,
-                             u8 dspCodeCounterReg, u8 dspCodeInReg)
-{
-       u8 buf[65];
-       struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
-       int tx_size;
-       int pos = 0;
-
-       /* clear code counter */
-       tda1004x_write_byteI(state, dspCodeCounterReg, 0);
-       fw_msg.addr = state->config->demod_address;
-
-       buf[0] = dspCodeInReg;
-       while (pos != len) {
-               // work out how much to send this time
-               tx_size = len - pos;
-               if (tx_size > 0x10)
-                       tx_size = 0x10;
-
-               // send the chunk
-               memcpy(buf + 1, mem + pos, tx_size);
-               fw_msg.len = tx_size + 1;
-               if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
-                       printk(KERN_ERR "tda1004x: Error during firmware upload\n");
-                       return -EIO;
-               }
-               pos += tx_size;
-
-               dprintk("%s: fw_pos=0x%x\n", __func__, pos);
-       }
-       // give the DSP a chance to settle 03/10/05 Hac
-       msleep(100);
-
-       return 0;
-}
-
-static int tda1004x_check_upload_ok(struct tda1004x_state *state)
-{
-       u8 data1, data2;
-       unsigned long timeout;
-
-       if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
-               timeout = jiffies + 2 * HZ;
-               while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
-                       if (time_after(jiffies, timeout)) {
-                               printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
-                               break;
-                       }
-                       msleep(1);
-               }
-       } else
-               msleep(100);
-
-       // check upload was OK
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
-       tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
-
-       data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
-       data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
-       if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
-               printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
-               return -EIO;
-       }
-       printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
-       return 0;
-}
-
-static int tda10045_fwupload(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int ret;
-       const struct firmware *fw;
-
-       /* don't re-upload unless necessary */
-       if (tda1004x_check_upload_ok(state) == 0)
-               return 0;
-
-       /* request the firmware, this will block until someone uploads it */
-       printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
-       ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
-       if (ret) {
-               printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
-               return ret;
-       }
-
-       /* reset chip */
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
-       msleep(10);
-
-       /* set parameters */
-       tda10045h_set_bandwidth(state, 8000000);
-
-       ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
-       release_firmware(fw);
-       if (ret)
-               return ret;
-       printk(KERN_INFO "tda1004x: firmware upload complete\n");
-
-       /* wait for DSP to initialise */
-       /* DSPREADY doesn't seem to work on the TDA10045H */
-       msleep(100);
-
-       return tda1004x_check_upload_ok(state);
-}
-
-static void tda10046_init_plls(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tda10046_clk53m;
-
-       if ((state->config->if_freq == TDA10046_FREQ_045) ||
-           (state->config->if_freq == TDA10046_FREQ_052))
-               tda10046_clk53m = 0;
-       else
-               tda10046_clk53m = 1;
-
-       tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
-       if(tda10046_clk53m) {
-               printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
-               tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
-       } else {
-               printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
-               tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
-       }
-       if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
-               dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__);
-               tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
-       } else {
-               dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__);
-               tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
-       }
-       if(tda10046_clk53m)
-               tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
-       else
-               tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
-       /* Note clock frequency is handled implicitly */
-       switch (state->config->if_freq) {
-       case TDA10046_FREQ_045:
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
-               break;
-       case TDA10046_FREQ_052:
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
-               break;
-       case TDA10046_FREQ_3617:
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
-               break;
-       case TDA10046_FREQ_3613:
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
-               tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
-               break;
-       }
-       tda10046h_set_bandwidth(state, 8000000); /* default bandwidth 8 MHz */
-       /* let the PLLs settle */
-       msleep(120);
-}
-
-static int tda10046_fwupload(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int ret, confc4;
-       const struct firmware *fw;
-
-       /* reset + wake up chip */
-       if (state->config->xtal_freq == TDA10046_XTAL_4M) {
-               confc4 = 0;
-       } else {
-               dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
-               confc4 = 0x80;
-       }
-       tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
-
-       tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
-       /* set GPIO 1 and 3 */
-       if (state->config->gpio_config != TDA10046_GPTRI) {
-               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
-       }
-       /* let the clocks recover from sleep */
-       msleep(10);
-
-       /* The PLLs need to be reprogrammed after sleep */
-       tda10046_init_plls(fe);
-       tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
-
-       /* don't re-upload unless necessary */
-       if (tda1004x_check_upload_ok(state) == 0)
-               return 0;
-
-       /*
-          For i2c normal work, we need to slow down the bus speed.
-          However, the slow down breaks the eeprom firmware load.
-          So, use normal speed for eeprom booting and then restore the
-          i2c speed after that. Tested with MSI TV @nyware A/D board,
-          that comes with firmware version 29 inside their eeprom.
-
-          It should also be noticed that no other I2C transfer should
-          be in course while booting from eeprom, otherwise, tda10046
-          goes into an instable state. So, proper locking are needed
-          at the i2c bus master.
-        */
-       printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
-       tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
-       msleep(300);
-       tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
-
-       /* Checks if eeprom firmware went without troubles */
-       if (tda1004x_check_upload_ok(state) == 0)
-               return 0;
-
-       /* eeprom firmware didn't work. Load one manually. */
-
-       if (state->config->request_firmware != NULL) {
-               /* request the firmware, this will block until someone uploads it */
-               printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
-               ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
-               if (ret) {
-                       /* remain compatible to old bug: try to load with tda10045 image name */
-                       ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
-                       if (ret) {
-                               printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
-                               return ret;
-                       } else {
-                               printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
-                                                 TDA10046_DEFAULT_FIRMWARE);
-                       }
-               }
-       } else {
-               printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
-               return -EIO;
-       }
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
-       ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
-       release_firmware(fw);
-       return tda1004x_check_upload_ok(state);
-}
-
-static int tda1004x_encode_fec(int fec)
-{
-       // convert known FEC values
-       switch (fec) {
-       case FEC_1_2:
-               return 0;
-       case FEC_2_3:
-               return 1;
-       case FEC_3_4:
-               return 2;
-       case FEC_5_6:
-               return 3;
-       case FEC_7_8:
-               return 4;
-       }
-
-       // unsupported
-       return -EINVAL;
-}
-
-static int tda1004x_decode_fec(int tdafec)
-{
-       // convert known FEC values
-       switch (tdafec) {
-       case 0:
-               return FEC_1_2;
-       case 1:
-               return FEC_2_3;
-       case 2:
-               return FEC_3_4;
-       case 3:
-               return FEC_5_6;
-       case 4:
-               return FEC_7_8;
-       }
-
-       // unsupported
-       return -1;
-}
-
-static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-
-       if (len != 2)
-               return -EINVAL;
-
-       return tda1004x_write_byteI(state, buf[0], buf[1]);
-}
-
-static int tda10045_init(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       if (tda10045_fwupload(fe)) {
-               printk("tda1004x: firmware upload failed\n");
-               return -EIO;
-       }
-
-       tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
-
-       // tda setup
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
-       tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
-       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
-       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
-       tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
-       tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
-       tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
-       tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
-       tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
-       tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
-       tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
-
-       tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
-
-       return 0;
-}
-
-static int tda10046_init(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       dprintk("%s\n", __func__);
-
-       if (tda10046_fwupload(fe)) {
-               printk("tda1004x: firmware upload failed\n");
-                       return -EIO;
-       }
-
-       // tda setup
-       tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
-       tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87);    // 100 ppm crystal, select HP stream
-       tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88);      // enable pulse killer
-
-       switch (state->config->agc_config) {
-       case TDA10046_AGC_DEFAULT:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
-               break;
-       case TDA10046_AGC_IFO_AUTO_NEG:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
-               break;
-       case TDA10046_AGC_IFO_AUTO_POS:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00);  // set AGC polarities
-               break;
-       case TDA10046_AGC_TDA827X:
-               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
-               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
-               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60);  // set AGC polarities
-               break;
-       }
-       if (state->config->ts_mode == 0) {
-               tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
-               tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
-       } else {
-               tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
-               tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
-                                                       state->config->invert_oclk << 4);
-       }
-       tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
-       tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
-       tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);    // }
-       tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
-       tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);     // }
-       tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }
-       tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
-       tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
-       tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
-       tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
-       // tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
-
-       return 0;
-}
-
-static int tda1004x_set_fe(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tmp;
-       int inversion;
-
-       dprintk("%s\n", __func__);
-
-       if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
-               // setup auto offset
-               tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
-
-               // disable agc_conf[2]
-               tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
-       }
-
-       // set frequency
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       // Hardcoded to use auto as much as possible on the TDA10045 as it
-       // is very unreliable if AUTO mode is _not_ used.
-       if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
-               fe_params->code_rate_HP = FEC_AUTO;
-               fe_params->guard_interval = GUARD_INTERVAL_AUTO;
-               fe_params->transmission_mode = TRANSMISSION_MODE_AUTO;
-       }
-
-       // Set standard params.. or put them to auto
-       if ((fe_params->code_rate_HP == FEC_AUTO) ||
-               (fe_params->code_rate_LP == FEC_AUTO) ||
-               (fe_params->modulation == QAM_AUTO) ||
-               (fe_params->hierarchy == HIERARCHY_AUTO)) {
-               tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1);        // enable auto
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); /* turn off modulation bits */
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
-               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
-       } else {
-               tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0);        // disable auto
-
-               // set HP FEC
-               tmp = tda1004x_encode_fec(fe_params->code_rate_HP);
-               if (tmp < 0)
-                       return tmp;
-               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
-
-               // set LP FEC
-               tmp = tda1004x_encode_fec(fe_params->code_rate_LP);
-               if (tmp < 0)
-                       return tmp;
-               tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
-
-               /* set modulation */
-               switch (fe_params->modulation) {
-               case QPSK:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
-                       break;
-
-               case QAM_16:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
-                       break;
-
-               case QAM_64:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
-                       break;
-
-               default:
-                       return -EINVAL;
-               }
-
-               // set hierarchy
-               switch (fe_params->hierarchy) {
-               case HIERARCHY_NONE:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
-                       break;
-
-               case HIERARCHY_1:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
-                       break;
-
-               case HIERARCHY_2:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
-                       break;
-
-               case HIERARCHY_4:
-                       tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
-                       break;
-
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       // set bandwidth
-       switch (state->demod_type) {
-       case TDA1004X_DEMOD_TDA10045:
-               tda10045h_set_bandwidth(state, fe_params->bandwidth_hz);
-               break;
-
-       case TDA1004X_DEMOD_TDA10046:
-               tda10046h_set_bandwidth(state, fe_params->bandwidth_hz);
-               break;
-       }
-
-       // set inversion
-       inversion = fe_params->inversion;
-       if (state->config->invert)
-               inversion = inversion ? INVERSION_OFF : INVERSION_ON;
-       switch (inversion) {
-       case INVERSION_OFF:
-               tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
-               break;
-
-       case INVERSION_ON:
-               tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // set guard interval
-       switch (fe_params->guard_interval) {
-       case GUARD_INTERVAL_1_32:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
-               break;
-
-       case GUARD_INTERVAL_1_16:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
-               break;
-
-       case GUARD_INTERVAL_1_8:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
-               break;
-
-       case GUARD_INTERVAL_1_4:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
-               break;
-
-       case GUARD_INTERVAL_AUTO:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // set transmission mode
-       switch (fe_params->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
-               break;
-
-       case TRANSMISSION_MODE_8K:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
-               break;
-
-       case TRANSMISSION_MODE_AUTO:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
-               tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       // start the lock
-       switch (state->demod_type) {
-       case TDA1004X_DEMOD_TDA10045:
-               tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
-               tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
-               break;
-
-       case TDA1004X_DEMOD_TDA10046:
-               tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
-               msleep(1);
-               tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
-               break;
-       }
-
-       msleep(10);
-
-       return 0;
-}
-
-static int tda1004x_get_fe(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
-       struct tda1004x_state* state = fe->demodulator_priv;
-
-       dprintk("%s\n", __func__);
-
-       // inversion status
-       fe_params->inversion = INVERSION_OFF;
-       if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
-               fe_params->inversion = INVERSION_ON;
-       if (state->config->invert)
-               fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
-
-       // bandwidth
-       switch (state->demod_type) {
-       case TDA1004X_DEMOD_TDA10045:
-               switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
-               case 0x14:
-                       fe_params->bandwidth_hz = 8000000;
-                       break;
-               case 0xdb:
-                       fe_params->bandwidth_hz = 7000000;
-                       break;
-               case 0x4f:
-                       fe_params->bandwidth_hz = 6000000;
-                       break;
-               }
-               break;
-       case TDA1004X_DEMOD_TDA10046:
-               switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
-               case 0x5c:
-               case 0x54:
-                       fe_params->bandwidth_hz = 8000000;
-                       break;
-               case 0x6a:
-               case 0x60:
-                       fe_params->bandwidth_hz = 7000000;
-                       break;
-               case 0x7b:
-               case 0x70:
-                       fe_params->bandwidth_hz = 6000000;
-                       break;
-               }
-               break;
-       }
-
-       // FEC
-       fe_params->code_rate_HP =
-           tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
-       fe_params->code_rate_LP =
-           tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
-
-       /* modulation */
-       switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
-       case 0:
-               fe_params->modulation = QPSK;
-               break;
-       case 1:
-               fe_params->modulation = QAM_16;
-               break;
-       case 2:
-               fe_params->modulation = QAM_64;
-               break;
-       }
-
-       // transmission mode
-       fe_params->transmission_mode = TRANSMISSION_MODE_2K;
-       if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)
-               fe_params->transmission_mode = TRANSMISSION_MODE_8K;
-
-       // guard interval
-       switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
-       case 0:
-               fe_params->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               fe_params->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               fe_params->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               fe_params->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       }
-
-       // hierarchy
-       switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
-       case 0:
-               fe_params->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               fe_params->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               fe_params->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               fe_params->hierarchy = HIERARCHY_4;
-               break;
-       }
-
-       return 0;
-}
-
-static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int status;
-       int cber;
-       int vber;
-
-       dprintk("%s\n", __func__);
-
-       // read status
-       status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
-       if (status == -1)
-               return -EIO;
-
-       // decode
-       *fe_status = 0;
-       if (status & 4)
-               *fe_status |= FE_HAS_SIGNAL;
-       if (status & 2)
-               *fe_status |= FE_HAS_CARRIER;
-       if (status & 8)
-               *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-
-       // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
-       // is getting anything valid
-       if (!(*fe_status & FE_HAS_VITERBI)) {
-               // read the CBER
-               cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
-               if (cber == -1)
-                       return -EIO;
-               status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
-               if (status == -1)
-                       return -EIO;
-               cber |= (status << 8);
-               // The address 0x20 should be read to cope with a TDA10046 bug
-               tda1004x_read_byte(state, TDA1004X_CBER_RESET);
-
-               if (cber != 65535)
-                       *fe_status |= FE_HAS_VITERBI;
-       }
-
-       // if we DO have some valid VITERBI output, but don't already have SYNC
-       // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
-       if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
-               // read the VBER
-               vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
-               if (vber == -1)
-                       return -EIO;
-               status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
-               if (status == -1)
-                       return -EIO;
-               vber |= (status << 8);
-               status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
-               if (status == -1)
-                       return -EIO;
-               vber |= (status & 0x0f) << 16;
-               // The CVBER_LUT should be read to cope with TDA10046 hardware bug
-               tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
-
-               // if RS has passed some valid TS packets, then we must be
-               // getting some SYNC bytes
-               if (vber < 16632)
-                       *fe_status |= FE_HAS_SYNC;
-       }
-
-       // success
-       dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
-       return 0;
-}
-
-static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tmp;
-       int reg = 0;
-
-       dprintk("%s\n", __func__);
-
-       // determine the register to use
-       switch (state->demod_type) {
-       case TDA1004X_DEMOD_TDA10045:
-               reg = TDA10045H_S_AGC;
-               break;
-
-       case TDA1004X_DEMOD_TDA10046:
-               reg = TDA10046H_AGC_IF_LEVEL;
-               break;
-       }
-
-       // read it
-       tmp = tda1004x_read_byte(state, reg);
-       if (tmp < 0)
-               return -EIO;
-
-       *signal = (tmp << 8) | tmp;
-       dprintk("%s: signal=0x%x\n", __func__, *signal);
-       return 0;
-}
-
-static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tmp;
-
-       dprintk("%s\n", __func__);
-
-       // read it
-       tmp = tda1004x_read_byte(state, TDA1004X_SNR);
-       if (tmp < 0)
-               return -EIO;
-       tmp = 255 - tmp;
-
-       *snr = ((tmp << 8) | tmp);
-       dprintk("%s: snr=0x%x\n", __func__, *snr);
-       return 0;
-}
-
-static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tmp;
-       int tmp2;
-       int counter;
-
-       dprintk("%s\n", __func__);
-
-       // read the UCBLOCKS and reset
-       counter = 0;
-       tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
-       if (tmp < 0)
-               return -EIO;
-       tmp &= 0x7f;
-       while (counter++ < 5) {
-               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
-               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
-               tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
-
-               tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
-               if (tmp2 < 0)
-                       return -EIO;
-               tmp2 &= 0x7f;
-               if ((tmp2 < tmp) || (tmp2 == 0))
-                       break;
-       }
-
-       if (tmp != 0x7f)
-               *ucblocks = tmp;
-       else
-               *ucblocks = 0xffffffff;
-
-       dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
-       return 0;
-}
-
-static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int tmp;
-
-       dprintk("%s\n", __func__);
-
-       // read it in
-       tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
-       if (tmp < 0)
-               return -EIO;
-       *ber = tmp << 1;
-       tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
-       if (tmp < 0)
-               return -EIO;
-       *ber |= (tmp << 9);
-       // The address 0x20 should be read to cope with a TDA10046 bug
-       tda1004x_read_byte(state, TDA1004X_CBER_RESET);
-
-       dprintk("%s: ber=0x%x\n", __func__, *ber);
-       return 0;
-}
-
-static int tda1004x_sleep(struct dvb_frontend* fe)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-       int gpio_conf;
-
-       switch (state->demod_type) {
-       case TDA1004X_DEMOD_TDA10045:
-               tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
-               break;
-
-       case TDA1004X_DEMOD_TDA10046:
-               /* set outputs to tristate */
-               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
-               /* invert GPIO 1 and 3 if desired*/
-               gpio_conf = state->config->gpio_config;
-               if (gpio_conf >= TDA10046_GP00_I)
-                       tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
-                                                       (gpio_conf & 0x0f) ^ 0x0a);
-
-               tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
-               tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
-               break;
-       }
-
-       return 0;
-}
-
-static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct tda1004x_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return tda1004x_enable_tuner_i2c(state);
-       } else {
-               return tda1004x_disable_tuner_i2c(state);
-       }
-}
-
-static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 800;
-       /* Drift compensation makes no sense for DVB-T */
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void tda1004x_release(struct dvb_frontend* fe)
-{
-       struct tda1004x_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda10045_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Philips TDA10045H DVB-T",
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 166667,
-               .caps =
-                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                   FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                   FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                   FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
-       },
-
-       .release = tda1004x_release,
-
-       .init = tda10045_init,
-       .sleep = tda1004x_sleep,
-       .write = tda1004x_write,
-       .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
-
-       .set_frontend = tda1004x_set_fe,
-       .get_frontend = tda1004x_get_fe,
-       .get_tune_settings = tda1004x_get_tune_settings,
-
-       .read_status = tda1004x_read_status,
-       .read_ber = tda1004x_read_ber,
-       .read_signal_strength = tda1004x_read_signal_strength,
-       .read_snr = tda1004x_read_snr,
-       .read_ucblocks = tda1004x_read_ucblocks,
-};
-
-struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct tda1004x_state *state;
-       int id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (!state) {
-               printk(KERN_ERR "Can't allocate memory for tda10045 state\n");
-               return NULL;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->demod_type = TDA1004X_DEMOD_TDA10045;
-
-       /* check if the demod is there */
-       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
-       if (id < 0) {
-               printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
-               kfree(state);
-               return NULL;
-       }
-
-       if (id != 0x25) {
-               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
-               kfree(state);
-               return NULL;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-static struct dvb_frontend_ops tda10046_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "Philips TDA10046H DVB-T",
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 166667,
-               .caps =
-                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                   FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                   FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                   FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
-       },
-
-       .release = tda1004x_release,
-
-       .init = tda10046_init,
-       .sleep = tda1004x_sleep,
-       .write = tda1004x_write,
-       .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
-
-       .set_frontend = tda1004x_set_fe,
-       .get_frontend = tda1004x_get_fe,
-       .get_tune_settings = tda1004x_get_tune_settings,
-
-       .read_status = tda1004x_read_status,
-       .read_ber = tda1004x_read_ber,
-       .read_signal_strength = tda1004x_read_signal_strength,
-       .read_snr = tda1004x_read_snr,
-       .read_ucblocks = tda1004x_read_ucblocks,
-};
-
-struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct tda1004x_state *state;
-       int id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (!state) {
-               printk(KERN_ERR "Can't allocate memory for tda10046 state\n");
-               return NULL;
-       }
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->demod_type = TDA1004X_DEMOD_TDA10046;
-
-       /* check if the demod is there */
-       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
-       if (id < 0) {
-               printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
-               kfree(state);
-               return NULL;
-       }
-       if (id != 0x46) {
-               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
-               kfree(state);
-               return NULL;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
-MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda10045_attach);
-EXPORT_SYMBOL(tda10046_attach);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
deleted file mode 100644 (file)
index 4e27ffb..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-  /*
-     Driver for Philips tda1004xh OFDM Frontend
-
-     (c) 2004 Andrew de Quincey
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   */
-
-#ifndef TDA1004X_H
-#define TDA1004X_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-enum tda10046_xtal {
-       TDA10046_XTAL_4M,
-       TDA10046_XTAL_16M,
-};
-
-enum tda10046_agc {
-       TDA10046_AGC_DEFAULT,           /* original configuration */
-       TDA10046_AGC_IFO_AUTO_NEG,      /* IF AGC only, automatic, negtive */
-       TDA10046_AGC_IFO_AUTO_POS,      /* IF AGC only, automatic, positive */
-       TDA10046_AGC_TDA827X,           /* IF AGC only, special setup for tda827x */
-};
-
-/* Many (hybrid) boards use GPIO 1 and 3
-       GPIO1   analog - dvb switch
-       GPIO3   firmware eeprom address switch
-*/
-enum tda10046_gpio {
-       TDA10046_GPTRI  = 0x00,         /* All GPIOs tristate */
-       TDA10046_GP00   = 0x40,         /* GPIO3=0, GPIO1=0 */
-       TDA10046_GP01   = 0x42,         /* GPIO3=0, GPIO1=1 */
-       TDA10046_GP10   = 0x48,         /* GPIO3=1, GPIO1=0 */
-       TDA10046_GP11   = 0x4a,         /* GPIO3=1, GPIO1=1 */
-       TDA10046_GP00_I = 0x80,         /* GPIO3=0, GPIO1=0, invert in sleep mode*/
-       TDA10046_GP01_I = 0x82,         /* GPIO3=0, GPIO1=1, invert in sleep mode */
-       TDA10046_GP10_I = 0x88,         /* GPIO3=1, GPIO1=0, invert in sleep mode */
-       TDA10046_GP11_I = 0x8a,         /* GPIO3=1, GPIO1=1, invert in sleep mode */
-};
-
-enum tda10046_if {
-       TDA10046_FREQ_3617,             /* original config, 36,166 MHZ */
-       TDA10046_FREQ_3613,             /* 36,13 MHZ */
-       TDA10046_FREQ_045,              /* low IF, 4.0, 4.5, or 5.0 MHZ */
-       TDA10046_FREQ_052,              /* low IF, 5.1667 MHZ for tda9889 */
-};
-
-enum tda10046_tsout {
-       TDA10046_TS_PARALLEL  = 0x00,   /* parallel transport stream, default */
-       TDA10046_TS_SERIAL    = 0x01,   /* serial transport stream */
-};
-
-struct tda1004x_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* does the "inversion" need inverted? */
-       u8 invert;
-
-       /* Does the OCLK signal need inverted? */
-       u8 invert_oclk;
-
-       /* parallel or serial transport stream */
-       enum tda10046_tsout ts_mode;
-
-       /* Xtal frequency, 4 or 16MHz*/
-       enum tda10046_xtal xtal_freq;
-
-       /* IF frequency */
-       enum tda10046_if if_freq;
-
-       /* AGC configuration */
-       enum tda10046_agc agc_config;
-
-       /* setting of GPIO1 and 3 */
-       enum tda10046_gpio gpio_config;
-
-       /* slave address and configuration of the tuner */
-       u8 tuner_address;
-       u8 antenna_switch;
-
-       /* if the board uses another I2c Bridge (tda8290), its address */
-       u8 i2c_gate;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-enum tda1004x_demod {
-       TDA1004X_DEMOD_TDA10045,
-       TDA1004X_DEMOD_TDA10046,
-};
-
-struct tda1004x_state {
-       struct i2c_adapter* i2c;
-       const struct tda1004x_config* config;
-       struct dvb_frontend frontend;
-
-       /* private demod data */
-       enum tda1004x_demod demod_type;
-};
-
-#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
-                                           struct i2c_adapter* i2c);
-
-extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
-                                           struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
-                                           struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
-                                           struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TDA1004X
-
-static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
-       int r = 0;
-       u8 buf[] = {reg, val};
-       if (fe->ops.write)
-               r = fe->ops.write(fe, buf, 2);
-       return r;
-}
-
-#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda10071.c b/drivers/media/dvb/frontends/tda10071.c
deleted file mode 100644 (file)
index 703c3d0..0000000
+++ /dev/null
@@ -1,1284 +0,0 @@
-/*
- * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#include "tda10071_priv.h"
-
-static struct dvb_frontend_ops tda10071_ops;
-
-/* write multiple registers */
-static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
-       int len)
-{
-       int ret;
-       u8 buf[len+1];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg.i2c_address,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple registers */
-static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
-       int len)
-{
-       int ret;
-       u8 buf[len];
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg.i2c_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = priv->cfg.i2c_address,
-                       .flags = I2C_M_RD,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               memcpy(val, buf, len);
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* write single register */
-static int tda10071_wr_reg(struct tda10071_priv *priv, u8 reg, u8 val)
-{
-       return tda10071_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int tda10071_rd_reg(struct tda10071_priv *priv, u8 reg, u8 *val)
-{
-       return tda10071_rd_regs(priv, reg, val, 1);
-}
-
-/* write single register with mask */
-int tda10071_wr_reg_mask(struct tda10071_priv *priv, u8 reg, u8 val, u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = tda10071_rd_regs(priv, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return tda10071_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register with mask */
-int tda10071_rd_reg_mask(struct tda10071_priv *priv, u8 reg, u8 *val, u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = tda10071_rd_regs(priv, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-/* execute firmware command */
-static int tda10071_cmd_execute(struct tda10071_priv *priv,
-       struct tda10071_cmd *cmd)
-{
-       int ret, i;
-       u8 tmp;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       /* write cmd and args for firmware */
-       ret = tda10071_wr_regs(priv, 0x00, cmd->args, cmd->len);
-       if (ret)
-               goto error;
-
-       /* start cmd execution */
-       ret = tda10071_wr_reg(priv, 0x1f, 1);
-       if (ret)
-               goto error;
-
-       /* wait cmd execution terminate */
-       for (i = 1000, tmp = 1; i && tmp; i--) {
-               ret = tda10071_rd_reg(priv, 0x1f, &tmp);
-               if (ret)
-                       goto error;
-
-               usleep_range(200, 5000);
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
-               goto error;
-       }
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_set_tone(struct dvb_frontend *fe,
-       fe_sec_tone_mode_t fe_sec_tone_mode)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret;
-       u8 tone;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: tone_mode=%d\n", __func__,
-                       fe_sec_tone_mode);
-
-       switch (fe_sec_tone_mode) {
-       case SEC_TONE_ON:
-               tone = 1;
-               break;
-       case SEC_TONE_OFF:
-               tone = 0;
-               break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n",
-                               __func__);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       cmd.args[0] = CMD_LNB_PCB_CONFIG;
-       cmd.args[1] = 0;
-       cmd.args[2] = 0x00;
-       cmd.args[3] = 0x00;
-       cmd.args[4] = tone;
-       cmd.len = 5;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_set_voltage(struct dvb_frontend *fe,
-       fe_sec_voltage_t fe_sec_voltage)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret;
-       u8 voltage;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: voltage=%d\n", __func__, fe_sec_voltage);
-
-       switch (fe_sec_voltage) {
-       case SEC_VOLTAGE_13:
-               voltage = 0;
-               break;
-       case SEC_VOLTAGE_18:
-               voltage = 1;
-               break;
-       case SEC_VOLTAGE_OFF:
-               voltage = 0;
-               break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
-                               __func__);
-               ret = -EINVAL;
-               goto error;
-       };
-
-       cmd.args[0] = CMD_LNB_SET_DC_LEVEL;
-       cmd.args[1] = 0;
-       cmd.args[2] = voltage;
-       cmd.len = 3;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
-       struct dvb_diseqc_master_cmd *diseqc_cmd)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i;
-       u8 tmp;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: msg_len=%d\n", __func__,
-                       diseqc_cmd->msg_len);
-
-       if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* wait LNB TX */
-       for (i = 500, tmp = 0; i && !tmp; i--) {
-               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01);
-               if (ret)
-                       goto error;
-
-               usleep_range(10000, 20000);
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
-               goto error;
-       }
-
-       ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01);
-       if (ret)
-               goto error;
-
-       cmd.args[0] = CMD_LNB_SEND_DISEQC;
-       cmd.args[1] = 0;
-       cmd.args[2] = 0;
-       cmd.args[3] = 0;
-       cmd.args[4] = 2;
-       cmd.args[5] = 0;
-       cmd.args[6] = diseqc_cmd->msg_len;
-       memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len);
-       cmd.len = 7 + diseqc_cmd->msg_len;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
-       struct dvb_diseqc_slave_reply *reply)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i;
-       u8 tmp;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
-
-       /* wait LNB RX */
-       for (i = 500, tmp = 0; i && !tmp; i--) {
-               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x02);
-               if (ret)
-                       goto error;
-
-               usleep_range(10000, 20000);
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
-               goto error;
-       }
-
-       /* reply len */
-       ret = tda10071_rd_reg(priv, 0x46, &tmp);
-       if (ret)
-               goto error;
-
-       reply->msg_len = tmp & 0x1f; /* [4:0] */;
-       if (reply->msg_len > sizeof(reply->msg))
-               reply->msg_len = sizeof(reply->msg); /* truncate API max */
-
-       /* read reply */
-       cmd.args[0] = CMD_LNB_UPDATE_REPLY;
-       cmd.args[1] = 0;
-       cmd.len = 2;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       ret = tda10071_rd_regs(priv, cmd.len, reply->msg, reply->msg_len);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
-       fe_sec_mini_cmd_t fe_sec_mini_cmd)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i;
-       u8 tmp, burst;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
-                       fe_sec_mini_cmd);
-
-       switch (fe_sec_mini_cmd) {
-       case SEC_MINI_A:
-               burst = 0;
-               break;
-       case SEC_MINI_B:
-               burst = 1;
-               break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n",
-                               __func__);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* wait LNB TX */
-       for (i = 500, tmp = 0; i && !tmp; i--) {
-               ret = tda10071_rd_reg_mask(priv, 0x47, &tmp, 0x01);
-               if (ret)
-                       goto error;
-
-               usleep_range(10000, 20000);
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
-               goto error;
-       }
-
-       ret = tda10071_wr_reg_mask(priv, 0x47, 0x00, 0x01);
-       if (ret)
-               goto error;
-
-       cmd.args[0] = CMD_LNB_SEND_TONEBURST;
-       cmd.args[1] = 0;
-       cmd.args[2] = burst;
-       cmd.len = 3;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 tmp;
-
-       *status = 0;
-
-       if (!priv->warm) {
-               ret = 0;
-               goto error;
-       }
-
-       ret = tda10071_rd_reg(priv, 0x39, &tmp);
-       if (ret)
-               goto error;
-
-       if (tmp & 0x01) /* tuner PLL */
-               *status |= FE_HAS_SIGNAL;
-       if (tmp & 0x02) /* demod PLL */
-               *status |= FE_HAS_CARRIER;
-       if (tmp & 0x04) /* viterbi or LDPC*/
-               *status |= FE_HAS_VITERBI;
-       if (tmp & 0x08) /* RS or BCH */
-               *status |= FE_HAS_SYNC | FE_HAS_LOCK;
-
-       priv->fe_status = *status;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       int ret;
-       u8 buf[2];
-
-       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
-               *snr = 0;
-               ret = 0;
-               goto error;
-       }
-
-       ret = tda10071_rd_regs(priv, 0x3a, buf, 2);
-       if (ret)
-               goto error;
-
-       /* Es/No dBx10 */
-       *snr = buf[0] << 8 | buf[1];
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret;
-       u8 tmp;
-
-       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
-               *strength = 0;
-               ret = 0;
-               goto error;
-       }
-
-       cmd.args[0] = CMD_GET_AGCACC;
-       cmd.args[1] = 0;
-       cmd.len = 2;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       /* input power estimate dBm */
-       ret = tda10071_rd_reg(priv, 0x50, &tmp);
-       if (ret)
-               goto error;
-
-       if (tmp < 181)
-               tmp = 181; /* -75 dBm */
-       else if (tmp > 236)
-               tmp = 236; /* -20 dBm */
-
-       /* scale value to 0x0000-0xffff */
-       *strength = (tmp-181) * 0xffff / (236-181);
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i, len;
-       u8 tmp, reg, buf[8];
-
-       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
-               *ber = priv->ber = 0;
-               ret = 0;
-               goto error;
-       }
-
-       switch (priv->delivery_system) {
-       case SYS_DVBS:
-               reg = 0x4c;
-               len = 8;
-               i = 1;
-               break;
-       case SYS_DVBS2:
-               reg = 0x4d;
-               len = 4;
-               i = 0;
-               break;
-       default:
-               *ber = priv->ber = 0;
-               return 0;
-       }
-
-       ret = tda10071_rd_reg(priv, reg, &tmp);
-       if (ret)
-               goto error;
-
-       if (priv->meas_count[i] == tmp) {
-               dev_dbg(&priv->i2c->dev, "%s: meas not ready=%02x\n", __func__,
-                               tmp);
-               *ber = priv->ber;
-               return 0;
-       } else {
-               priv->meas_count[i] = tmp;
-       }
-
-       cmd.args[0] = CMD_BER_UPDATE_COUNTERS;
-       cmd.args[1] = 0;
-       cmd.args[2] = i;
-       cmd.len = 3;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       ret = tda10071_rd_regs(priv, cmd.len, buf, len);
-       if (ret)
-               goto error;
-
-       if (priv->delivery_system == SYS_DVBS) {
-               *ber = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-               priv->ucb += (buf[4] << 8) | buf[5];
-       } else {
-               *ber = (buf[0] << 8) | buf[1];
-       }
-       priv->ber = *ber;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       int ret = 0;
-
-       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
-               *ucblocks = 0;
-               goto error;
-       }
-
-       /* UCB is updated when BER is read. Assume BER is read anyway. */
-
-       *ucblocks = priv->ucb;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_set_frontend(struct dvb_frontend *fe)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       u8 mode, rolloff, pilot, inversion, div;
-
-       dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
-               "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
-               "rolloff=%d\n", __func__, c->delivery_system, c->modulation,
-               c->frequency, c->symbol_rate, c->inversion, c->pilot,
-               c->rolloff);
-
-       priv->delivery_system = SYS_UNDEFINED;
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       switch (c->inversion) {
-       case INVERSION_OFF:
-               inversion = 1;
-               break;
-       case INVERSION_ON:
-               inversion = 0;
-               break;
-       case INVERSION_AUTO:
-               /* 2 = auto; try first on then off
-                * 3 = auto; try first off then on */
-               inversion = 3;
-               break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n", __func__);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       switch (c->delivery_system) {
-       case SYS_DVBS:
-               rolloff = 0;
-               pilot = 2;
-               break;
-       case SYS_DVBS2:
-               switch (c->rolloff) {
-               case ROLLOFF_20:
-                       rolloff = 2;
-                       break;
-               case ROLLOFF_25:
-                       rolloff = 1;
-                       break;
-               case ROLLOFF_35:
-                       rolloff = 0;
-                       break;
-               case ROLLOFF_AUTO:
-               default:
-                       dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n",
-                                       __func__);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
-               switch (c->pilot) {
-               case PILOT_OFF:
-                       pilot = 0;
-                       break;
-               case PILOT_ON:
-                       pilot = 1;
-                       break;
-               case PILOT_AUTO:
-                       pilot = 2;
-                       break;
-               default:
-                       dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
-                                       __func__);
-                       ret = -EINVAL;
-                       goto error;
-               }
-               break;
-       default:
-               dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
-                               __func__);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
-               if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
-                       c->modulation == TDA10071_MODCOD[i].modulation &&
-                       c->fec_inner == TDA10071_MODCOD[i].fec) {
-                       mode = TDA10071_MODCOD[i].val;
-                       dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
-                                       __func__, mode);
-                       break;
-               }
-       }
-
-       if (mode == 0xff) {
-               dev_dbg(&priv->i2c->dev, "%s: invalid parameter combination\n",
-                               __func__);
-               ret = -EINVAL;
-               goto error;
-       }
-
-       if (c->symbol_rate <= 5000000)
-               div = 14;
-       else
-               div = 4;
-
-       ret = tda10071_wr_reg(priv, 0x81, div);
-       if (ret)
-               goto error;
-
-       ret = tda10071_wr_reg(priv, 0xe3, div);
-       if (ret)
-               goto error;
-
-       cmd.args[0] = CMD_CHANGE_CHANNEL;
-       cmd.args[1] = 0;
-       cmd.args[2] = mode;
-       cmd.args[3] = (c->frequency >> 16) & 0xff;
-       cmd.args[4] = (c->frequency >>  8) & 0xff;
-       cmd.args[5] = (c->frequency >>  0) & 0xff;
-       cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff;
-       cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff;
-       cmd.args[8] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff;
-       cmd.args[9] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff;
-       cmd.args[10] = rolloff;
-       cmd.args[11] = inversion;
-       cmd.args[12] = pilot;
-       cmd.args[13] = 0x00;
-       cmd.args[14] = 0x00;
-       cmd.len = 15;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       priv->delivery_system = c->delivery_system;
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_get_frontend(struct dvb_frontend *fe)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       u8 buf[5], tmp;
-
-       if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       ret = tda10071_rd_regs(priv, 0x30, buf, 5);
-       if (ret)
-               goto error;
-
-       tmp = buf[0] & 0x3f;
-       for (i = 0; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
-               if (tmp == TDA10071_MODCOD[i].val) {
-                       c->modulation = TDA10071_MODCOD[i].modulation;
-                       c->fec_inner = TDA10071_MODCOD[i].fec;
-                       c->delivery_system = TDA10071_MODCOD[i].delivery_system;
-               }
-       }
-
-       switch ((buf[1] >> 0) & 0x01) {
-       case 0:
-               c->inversion = INVERSION_OFF;
-               break;
-       case 1:
-               c->inversion = INVERSION_ON;
-               break;
-       }
-
-       switch ((buf[1] >> 7) & 0x01) {
-       case 0:
-               c->pilot = PILOT_OFF;
-               break;
-       case 1:
-               c->pilot = PILOT_ON;
-               break;
-       }
-
-       c->frequency = (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0);
-
-       ret = tda10071_rd_regs(priv, 0x52, buf, 3);
-       if (ret)
-               goto error;
-
-       c->symbol_rate = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0);
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_init(struct dvb_frontend *fe)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i, len, remaining, fw_size;
-       const struct firmware *fw;
-       u8 *fw_file = TDA10071_DEFAULT_FIRMWARE;
-       u8 tmp, buf[4];
-       struct tda10071_reg_val_mask tab[] = {
-               { 0xcd, 0x00, 0x07 },
-               { 0x80, 0x00, 0x02 },
-               { 0xcd, 0x00, 0xc0 },
-               { 0xce, 0x00, 0x1b },
-               { 0x9d, 0x00, 0x01 },
-               { 0x9d, 0x00, 0x02 },
-               { 0x9e, 0x00, 0x01 },
-               { 0x87, 0x00, 0x80 },
-               { 0xce, 0x00, 0x08 },
-               { 0xce, 0x00, 0x10 },
-       };
-       struct tda10071_reg_val_mask tab2[] = {
-               { 0xf1, 0x70, 0xff },
-               { 0x88, priv->cfg.pll_multiplier, 0x3f },
-               { 0x89, 0x00, 0x10 },
-               { 0x89, 0x10, 0x10 },
-               { 0xc0, 0x01, 0x01 },
-               { 0xc0, 0x00, 0x01 },
-               { 0xe0, 0xff, 0xff },
-               { 0xe0, 0x00, 0xff },
-               { 0x96, 0x1e, 0x7e },
-               { 0x8b, 0x08, 0x08 },
-               { 0x8b, 0x00, 0x08 },
-               { 0x8f, 0x1a, 0x7e },
-               { 0x8c, 0x68, 0xff },
-               { 0x8d, 0x08, 0xff },
-               { 0x8e, 0x4c, 0xff },
-               { 0x8f, 0x01, 0x01 },
-               { 0x8b, 0x04, 0x04 },
-               { 0x8b, 0x00, 0x04 },
-               { 0x87, 0x05, 0x07 },
-               { 0x80, 0x00, 0x20 },
-               { 0xc8, 0x01, 0xff },
-               { 0xb4, 0x47, 0xff },
-               { 0xb5, 0x9c, 0xff },
-               { 0xb6, 0x7d, 0xff },
-               { 0xba, 0x00, 0x03 },
-               { 0xb7, 0x47, 0xff },
-               { 0xb8, 0x9c, 0xff },
-               { 0xb9, 0x7d, 0xff },
-               { 0xba, 0x00, 0x0c },
-               { 0xc8, 0x00, 0xff },
-               { 0xcd, 0x00, 0x04 },
-               { 0xcd, 0x00, 0x20 },
-               { 0xe8, 0x02, 0xff },
-               { 0xcf, 0x20, 0xff },
-               { 0x9b, 0xd7, 0xff },
-               { 0x9a, 0x01, 0x03 },
-               { 0xa8, 0x05, 0x0f },
-               { 0xa8, 0x65, 0xf0 },
-               { 0xa6, 0xa0, 0xf0 },
-               { 0x9d, 0x50, 0xfc },
-               { 0x9e, 0x20, 0xe0 },
-               { 0xa3, 0x1c, 0x7c },
-               { 0xd5, 0x03, 0x03 },
-       };
-
-       /* firmware status */
-       ret = tda10071_rd_reg(priv, 0x51, &tmp);
-       if (ret)
-               goto error;
-
-       if (!tmp) {
-               /* warm state - wake up device from sleep */
-               priv->warm = 1;
-
-               for (i = 0; i < ARRAY_SIZE(tab); i++) {
-                       ret = tda10071_wr_reg_mask(priv, tab[i].reg,
-                               tab[i].val, tab[i].mask);
-                       if (ret)
-                               goto error;
-               }
-
-               cmd.args[0] = CMD_SET_SLEEP_MODE;
-               cmd.args[1] = 0;
-               cmd.args[2] = 0;
-               cmd.len = 3;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-       } else {
-               /* cold state - try to download firmware */
-               priv->warm = 0;
-
-               /* request the firmware, this will block and timeout */
-               ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
-               if (ret) {
-                       dev_err(&priv->i2c->dev, "%s: did not find the " \
-                                       "firmware file. (%s) Please see " \
-                                       "linux/Documentation/dvb/ for more " \
-                                       "details on firmware-problems. (%d)\n",
-                                       KBUILD_MODNAME, fw_file, ret);
-                       goto error;
-               }
-
-               /* init */
-               for (i = 0; i < ARRAY_SIZE(tab2); i++) {
-                       ret = tda10071_wr_reg_mask(priv, tab2[i].reg,
-                               tab2[i].val, tab2[i].mask);
-                       if (ret)
-                               goto error_release_firmware;
-               }
-
-               /*  download firmware */
-               ret = tda10071_wr_reg(priv, 0xe0, 0x7f);
-               if (ret)
-                       goto error_release_firmware;
-
-               ret = tda10071_wr_reg(priv, 0xf7, 0x81);
-               if (ret)
-                       goto error_release_firmware;
-
-               ret = tda10071_wr_reg(priv, 0xf8, 0x00);
-               if (ret)
-                       goto error_release_firmware;
-
-               ret = tda10071_wr_reg(priv, 0xf9, 0x00);
-               if (ret)
-                       goto error_release_firmware;
-
-               dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \
-                               "will try to load a firmware\n", KBUILD_MODNAME,
-                               tda10071_ops.info.name);
-               dev_info(&priv->i2c->dev, "%s: downloading firmware from " \
-                               "file '%s'\n", KBUILD_MODNAME, fw_file);
-
-               /* do not download last byte */
-               fw_size = fw->size - 1;
-
-               for (remaining = fw_size; remaining > 0;
-                       remaining -= (priv->cfg.i2c_wr_max - 1)) {
-                       len = remaining;
-                       if (len > (priv->cfg.i2c_wr_max - 1))
-                               len = (priv->cfg.i2c_wr_max - 1);
-
-                       ret = tda10071_wr_regs(priv, 0xfa,
-                               (u8 *) &fw->data[fw_size - remaining], len);
-                       if (ret) {
-                               dev_err(&priv->i2c->dev, "%s: firmware " \
-                                               "download failed=%d\n",
-                                               KBUILD_MODNAME, ret);
-                               if (ret)
-                                       goto error_release_firmware;
-                       }
-               }
-               release_firmware(fw);
-
-               ret = tda10071_wr_reg(priv, 0xf7, 0x0c);
-               if (ret)
-                       goto error;
-
-               ret = tda10071_wr_reg(priv, 0xe0, 0x00);
-               if (ret)
-                       goto error;
-
-               /* wait firmware start */
-               msleep(250);
-
-               /* firmware status */
-               ret = tda10071_rd_reg(priv, 0x51, &tmp);
-               if (ret)
-                       goto error;
-
-               if (tmp) {
-                       dev_info(&priv->i2c->dev, "%s: firmware did not run\n",
-                                       KBUILD_MODNAME);
-                       ret = -EFAULT;
-                       goto error;
-               } else {
-                       priv->warm = 1;
-               }
-
-               cmd.args[0] = CMD_GET_FW_VERSION;
-               cmd.len = 1;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-
-               ret = tda10071_rd_regs(priv, cmd.len, buf, 4);
-               if (ret)
-                       goto error;
-
-               dev_info(&priv->i2c->dev, "%s: firmware version %d.%d.%d.%d\n",
-                               KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]);
-               dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n",
-                               KBUILD_MODNAME, tda10071_ops.info.name);
-
-               ret = tda10071_rd_regs(priv, 0x81, buf, 2);
-               if (ret)
-                       goto error;
-
-               cmd.args[0] = CMD_DEMOD_INIT;
-               cmd.args[1] = ((priv->cfg.xtal / 1000) >> 8) & 0xff;
-               cmd.args[2] = ((priv->cfg.xtal / 1000) >> 0) & 0xff;
-               cmd.args[3] = buf[0];
-               cmd.args[4] = buf[1];
-               cmd.args[5] = priv->cfg.pll_multiplier;
-               cmd.args[6] = priv->cfg.spec_inv;
-               cmd.args[7] = 0x00;
-               cmd.len = 8;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-
-               cmd.args[0] = CMD_TUNER_INIT;
-               cmd.args[1] = 0x00;
-               cmd.args[2] = 0x00;
-               cmd.args[3] = 0x00;
-               cmd.args[4] = 0x00;
-               cmd.args[5] = 0x14;
-               cmd.args[6] = 0x00;
-               cmd.args[7] = 0x03;
-               cmd.args[8] = 0x02;
-               cmd.args[9] = 0x02;
-               cmd.args[10] = 0x00;
-               cmd.args[11] = 0x00;
-               cmd.args[12] = 0x00;
-               cmd.args[13] = 0x00;
-               cmd.args[14] = 0x00;
-               cmd.len = 15;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-
-               cmd.args[0] = CMD_MPEG_CONFIG;
-               cmd.args[1] = 0;
-               cmd.args[2] = priv->cfg.ts_mode;
-               cmd.args[3] = 0x00;
-               cmd.args[4] = 0x04;
-               cmd.args[5] = 0x00;
-               cmd.len = 6;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-
-               ret = tda10071_wr_reg_mask(priv, 0xf0, 0x01, 0x01);
-               if (ret)
-                       goto error;
-
-               cmd.args[0] = CMD_LNB_CONFIG;
-               cmd.args[1] = 0;
-               cmd.args[2] = 150;
-               cmd.args[3] = 3;
-               cmd.args[4] = 22;
-               cmd.args[5] = 1;
-               cmd.args[6] = 1;
-               cmd.args[7] = 30;
-               cmd.args[8] = 30;
-               cmd.args[9] = 30;
-               cmd.args[10] = 30;
-               cmd.len = 11;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-
-               cmd.args[0] = CMD_BER_CONTROL;
-               cmd.args[1] = 0;
-               cmd.args[2] = 14;
-               cmd.args[3] = 14;
-               cmd.len = 4;
-               ret = tda10071_cmd_execute(priv, &cmd);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error_release_firmware:
-       release_firmware(fw);
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_sleep(struct dvb_frontend *fe)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       struct tda10071_cmd cmd;
-       int ret, i;
-       struct tda10071_reg_val_mask tab[] = {
-               { 0xcd, 0x07, 0x07 },
-               { 0x80, 0x02, 0x02 },
-               { 0xcd, 0xc0, 0xc0 },
-               { 0xce, 0x1b, 0x1b },
-               { 0x9d, 0x01, 0x01 },
-               { 0x9d, 0x02, 0x02 },
-               { 0x9e, 0x01, 0x01 },
-               { 0x87, 0x80, 0x80 },
-               { 0xce, 0x08, 0x08 },
-               { 0xce, 0x10, 0x10 },
-       };
-
-       if (!priv->warm) {
-               ret = -EFAULT;
-               goto error;
-       }
-
-       cmd.args[0] = CMD_SET_SLEEP_MODE;
-       cmd.args[1] = 0;
-       cmd.args[2] = 1;
-       cmd.len = 3;
-       ret = tda10071_cmd_execute(priv, &cmd);
-       if (ret)
-               goto error;
-
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = tda10071_wr_reg_mask(priv, tab[i].reg, tab[i].val,
-                       tab[i].mask);
-               if (ret)
-                       goto error;
-       }
-
-       return ret;
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int tda10071_get_tune_settings(struct dvb_frontend *fe,
-       struct dvb_frontend_tune_settings *s)
-{
-       s->min_delay_ms = 8000;
-       s->step_size = 0;
-       s->max_drift = 0;
-
-       return 0;
-}
-
-static void tda10071_release(struct dvb_frontend *fe)
-{
-       struct tda10071_priv *priv = fe->demodulator_priv;
-       kfree(priv);
-}
-
-struct dvb_frontend *tda10071_attach(const struct tda10071_config *config,
-       struct i2c_adapter *i2c)
-{
-       int ret;
-       struct tda10071_priv *priv = NULL;
-       u8 tmp;
-
-       /* allocate memory for the internal priv */
-       priv = kzalloc(sizeof(struct tda10071_priv), GFP_KERNEL);
-       if (priv == NULL) {
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       /* setup the priv */
-       priv->i2c = i2c;
-       memcpy(&priv->cfg, config, sizeof(struct tda10071_config));
-
-       /* chip ID */
-       ret = tda10071_rd_reg(priv, 0xff, &tmp);
-       if (ret || tmp != 0x0f)
-               goto error;
-
-       /* chip type */
-       ret = tda10071_rd_reg(priv, 0xdd, &tmp);
-       if (ret || tmp != 0x00)
-               goto error;
-
-       /* chip version */
-       ret = tda10071_rd_reg(priv, 0xfe, &tmp);
-       if (ret || tmp != 0x01)
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&priv->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-
-       return &priv->fe;
-error:
-       dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(tda10071_attach);
-
-static struct dvb_frontend_ops tda10071_ops = {
-       .delsys = { SYS_DVBS, SYS_DVBS2 },
-       .info = {
-               .name = "NXP TDA10071",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_tolerance = 5000,
-               .symbol_rate_min = 1000000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_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_6_7 |
-                       FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_8_9 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_RECOVER |
-                       FE_CAN_2G_MODULATION
-       },
-
-       .release = tda10071_release,
-
-       .get_tune_settings = tda10071_get_tune_settings,
-
-       .init = tda10071_init,
-       .sleep = tda10071_sleep,
-
-       .set_frontend = tda10071_set_frontend,
-       .get_frontend = tda10071_get_frontend,
-
-       .read_status = tda10071_read_status,
-       .read_snr = tda10071_read_snr,
-       .read_signal_strength = tda10071_read_signal_strength,
-       .read_ber = tda10071_read_ber,
-       .read_ucblocks = tda10071_read_ucblocks,
-
-       .diseqc_send_master_cmd = tda10071_diseqc_send_master_cmd,
-       .diseqc_recv_slave_reply = tda10071_diseqc_recv_slave_reply,
-       .diseqc_send_burst = tda10071_diseqc_send_burst,
-
-       .set_tone = tda10071_set_tone,
-       .set_voltage = tda10071_set_voltage,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda10071.h b/drivers/media/dvb/frontends/tda10071.h
deleted file mode 100644 (file)
index 21163c4..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef TDA10071_H
-#define TDA10071_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda10071_config {
-       /* Demodulator I2C address.
-        * Default: none, must set
-        * Values: 0x55,
-        */
-       u8 i2c_address;
-
-       /* Max bytes I2C provider can write at once.
-        * Note: Buffer is taken from the stack currently!
-        * Default: none, must set
-        * Values:
-        */
-       u16 i2c_wr_max;
-
-       /* TS output mode.
-        * Default: TDA10071_TS_SERIAL
-        * Values:
-        */
-#define TDA10071_TS_SERIAL        0
-#define TDA10071_TS_PARALLEL      1
-       u8 ts_mode;
-
-       /* Input spectrum inversion.
-        * Default: 0
-        * Values: 0, 1
-        */
-       bool spec_inv;
-
-       /* Xtal frequency Hz
-        * Default: none, must set
-        * Values:
-        */
-       u32 xtal;
-
-       /* PLL multiplier.
-        * Default: none, must set
-        * Values:
-        */
-       u8 pll_multiplier;
-};
-
-
-#if defined(CONFIG_DVB_TDA10071) || \
-       (defined(CONFIG_DVB_TDA10071_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda10071_attach(
-       const struct tda10071_config *config, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *tda10071_attach(
-       const struct tda10071_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* TDA10071_H */
diff --git a/drivers/media/dvb/frontends/tda10071_priv.h b/drivers/media/dvb/frontends/tda10071_priv.h
deleted file mode 100644 (file)
index 0fa85cf..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; 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.
- */
-
-#ifndef TDA10071_PRIV
-#define TDA10071_PRIV
-
-#include "dvb_frontend.h"
-#include "tda10071.h"
-#include <linux/firmware.h>
-
-struct tda10071_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct tda10071_config cfg;
-
-       u8 meas_count[2];
-       u32 ber;
-       u32 ucb;
-       fe_status_t fe_status;
-       fe_delivery_system_t delivery_system;
-       bool warm; /* FW running */
-};
-
-static struct tda10071_modcod {
-       fe_delivery_system_t delivery_system;
-       fe_modulation_t modulation;
-       fe_code_rate_t fec;
-       u8 val;
-} TDA10071_MODCOD[] = {
-       /* NBC-QPSK */
-       { SYS_DVBS2, QPSK,  FEC_AUTO, 0x00 },
-       { SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
-       { SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
-       { SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
-       { SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
-       { SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
-       { SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
-       { SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
-       { SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
-       /* 8PSK */
-       { SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
-       { SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
-       { SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
-       { SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
-       { SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
-       { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
-       /* QPSK */
-       { SYS_DVBS,  QPSK,  FEC_AUTO, 0x2d },
-       { SYS_DVBS,  QPSK,  FEC_1_2,  0x2e },
-       { SYS_DVBS,  QPSK,  FEC_2_3,  0x2f },
-       { SYS_DVBS,  QPSK,  FEC_3_4,  0x30 },
-       { SYS_DVBS,  QPSK,  FEC_5_6,  0x31 },
-       { SYS_DVBS,  QPSK,  FEC_7_8,  0x32 },
-};
-
-struct tda10071_reg_val_mask {
-       u8 reg;
-       u8 val;
-       u8 mask;
-};
-
-/* firmware filename */
-#define TDA10071_DEFAULT_FIRMWARE      "dvb-fe-tda10071.fw"
-
-/* firmware commands */
-#define CMD_DEMOD_INIT          0x10
-#define CMD_CHANGE_CHANNEL      0x11
-#define CMD_MPEG_CONFIG         0x13
-#define CMD_TUNER_INIT          0x15
-#define CMD_GET_AGCACC          0x1a
-
-#define CMD_LNB_CONFIG          0x20
-#define CMD_LNB_SEND_DISEQC     0x21
-#define CMD_LNB_SET_DC_LEVEL    0x22
-#define CMD_LNB_PCB_CONFIG      0x23
-#define CMD_LNB_SEND_TONEBURST  0x24
-#define CMD_LNB_UPDATE_REPLY    0x25
-
-#define CMD_GET_FW_VERSION      0x35
-#define CMD_SET_SLEEP_MODE      0x36
-#define CMD_BER_CONTROL         0x3e
-#define CMD_BER_UPDATE_COUNTERS 0x3f
-
-/* firmare command struct */
-#define TDA10071_ARGLEN      30
-struct tda10071_cmd {
-       u8 args[TDA10071_ARGLEN];
-       u8 len;
-};
-
-
-#endif /* TDA10071_PRIV */
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
deleted file mode 100644 (file)
index fcfe2e0..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-  /*
-     Driver for Philips tda10086 DVBS Demodulator
-
-     (c) 2006 Andrew de Quincey
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "tda10086.h"
-
-#define SACLK 96000000
-
-struct tda10086_state {
-       struct i2c_adapter* i2c;
-       const struct tda10086_config* config;
-       struct dvb_frontend frontend;
-
-       /* private demod data */
-       u32 frequency;
-       u32 symbol_rate;
-       bool has_lock;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "tda10086: " args); \
-       } while (0)
-
-static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
-{
-       int ret;
-       u8 b0[] = { reg, data };
-       struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };
-
-       msg.addr = state->config->demod_address;
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
-                       __func__, reg, data, ret);
-
-       return (ret != 1) ? ret : 0;
-}
-
-static int tda10086_read_byte(struct tda10086_state *state, int reg)
-{
-       int ret;
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
-                               { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
-
-       msg[0].addr = state->config->demod_address;
-       msg[1].addr = state->config->demod_address;
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
-                       ret);
-               return ret;
-       }
-
-       return b1[0];
-}
-
-static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
-{
-       int val;
-
-       /* read a byte and check */
-       val = tda10086_read_byte(state, reg);
-       if (val < 0)
-               return val;
-
-       /* mask if off */
-       val = val & ~mask;
-       val |= data & 0xff;
-
-       /* write it out again */
-       return tda10086_write_byte(state, reg, val);
-}
-
-static int tda10086_init(struct dvb_frontend* fe)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 t22k_off = 0x80;
-
-       dprintk ("%s\n", __func__);
-
-       if (state->config->diseqc_tone)
-               t22k_off = 0;
-       /* reset */
-       tda10086_write_byte(state, 0x00, 0x00);
-       msleep(10);
-
-       /* misc setup */
-       tda10086_write_byte(state, 0x01, 0x94);
-       tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */
-       tda10086_write_byte(state, 0x03, 0xe4);
-       tda10086_write_byte(state, 0x04, 0x43);
-       tda10086_write_byte(state, 0x0c, 0x0c);
-       tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */
-       tda10086_write_byte(state, 0x20, 0x89); /* misc */
-       tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */
-       tda10086_write_byte(state, 0x32, 0x00); /* irq off */
-       tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */
-
-       /* setup PLL (this assumes SACLK = 96MHz) */
-       tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */
-       if (state->config->xtal_freq == TDA10086_XTAL_16M) {
-               tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */
-               tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */
-       } else {
-               tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */
-               tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */
-       }
-       tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */
-
-       /* setup TS interface */
-       tda10086_write_byte(state, 0x11, 0x81);
-       tda10086_write_byte(state, 0x12, 0x81);
-       tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */
-       tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */
-       tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */
-       tda10086_write_byte(state, 0x10, 0x2a);
-
-       /* setup ADC */
-       tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */
-       tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */
-
-       /* setup AGC */
-       tda10086_write_byte(state, 0x05, 0x0B);
-       tda10086_write_byte(state, 0x37, 0x63);
-       tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */
-       tda10086_write_byte(state, 0x40, 0x64);
-       tda10086_write_byte(state, 0x41, 0x4f);
-       tda10086_write_byte(state, 0x42, 0x43);
-
-       /* setup viterbi */
-       tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */
-
-       /* setup carrier recovery */
-       tda10086_write_byte(state, 0x3d, 0x80);
-
-       /* setup SEC */
-       tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */
-       tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));
-       tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8);
-
-       return 0;
-}
-
-static void tda10086_diseqc_wait(struct tda10086_state *state)
-{
-       unsigned long timeout = jiffies + msecs_to_jiffies(200);
-       while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
-               if(time_after(jiffies, timeout)) {
-                       printk("%s: diseqc queue not ready, command may be lost.\n", __func__);
-                       break;
-               }
-               msleep(10);
-       }
-}
-
-static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 t22k_off = 0x80;
-
-       dprintk ("%s\n", __func__);
-
-       if (state->config->diseqc_tone)
-               t22k_off = 0;
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               tda10086_write_byte(state, 0x36, t22k_off);
-               break;
-
-       case SEC_TONE_ON:
-               tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
-               break;
-       }
-
-       return 0;
-}
-
-static int tda10086_send_master_cmd (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd* cmd)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       int i;
-       u8 oldval;
-       u8 t22k_off = 0x80;
-
-       dprintk ("%s\n", __func__);
-
-       if (state->config->diseqc_tone)
-               t22k_off = 0;
-
-       if (cmd->msg_len > 6)
-               return -EINVAL;
-       oldval = tda10086_read_byte(state, 0x36);
-
-       for(i=0; i< cmd->msg_len; i++) {
-               tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
-       }
-       tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
-                                       | ((cmd->msg_len - 1) << 4));
-
-       tda10086_diseqc_wait(state);
-
-       tda10086_write_byte(state, 0x36, oldval);
-
-       return 0;
-}
-
-static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 oldval = tda10086_read_byte(state, 0x36);
-       u8 t22k_off = 0x80;
-
-       dprintk ("%s\n", __func__);
-
-       if (state->config->diseqc_tone)
-               t22k_off = 0;
-
-       switch(minicmd) {
-       case SEC_MINI_A:
-               tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
-               break;
-
-       case SEC_MINI_B:
-               tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
-               break;
-       }
-
-       tda10086_diseqc_wait(state);
-
-       tda10086_write_byte(state, 0x36, oldval);
-
-       return 0;
-}
-
-static int tda10086_set_inversion(struct tda10086_state *state,
-                                 struct dtv_frontend_properties *fe_params)
-{
-       u8 invval = 0x80;
-
-       dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert);
-
-       switch(fe_params->inversion) {
-       case INVERSION_OFF:
-               if (state->config->invert)
-                       invval = 0x40;
-               break;
-       case INVERSION_ON:
-               if (!state->config->invert)
-                       invval = 0x40;
-               break;
-       case INVERSION_AUTO:
-               invval = 0x00;
-               break;
-       }
-       tda10086_write_mask(state, 0x0c, 0xc0, invval);
-
-       return 0;
-}
-
-static int tda10086_set_symbol_rate(struct tda10086_state *state,
-                                   struct dtv_frontend_properties *fe_params)
-{
-       u8 dfn = 0;
-       u8 afs = 0;
-       u8 byp = 0;
-       u8 reg37 = 0x43;
-       u8 reg42 = 0x43;
-       u64 big;
-       u32 tmp;
-       u32 bdr;
-       u32 bdri;
-       u32 symbol_rate = fe_params->symbol_rate;
-
-       dprintk ("%s %i\n", __func__, symbol_rate);
-
-       /* setup the decimation and anti-aliasing filters.. */
-       if (symbol_rate < (u32) (SACLK * 0.0137)) {
-               dfn=4;
-               afs=1;
-       } else if (symbol_rate < (u32) (SACLK * 0.0208)) {
-               dfn=4;
-               afs=0;
-       } else if (symbol_rate < (u32) (SACLK * 0.0270)) {
-               dfn=3;
-               afs=1;
-       } else if (symbol_rate < (u32) (SACLK * 0.0416)) {
-               dfn=3;
-               afs=0;
-       } else if (symbol_rate < (u32) (SACLK * 0.0550)) {
-               dfn=2;
-               afs=1;
-       } else if (symbol_rate < (u32) (SACLK * 0.0833)) {
-               dfn=2;
-               afs=0;
-       } else if (symbol_rate < (u32) (SACLK * 0.1100)) {
-               dfn=1;
-               afs=1;
-       } else if (symbol_rate < (u32) (SACLK * 0.1666)) {
-               dfn=1;
-               afs=0;
-       } else if (symbol_rate < (u32) (SACLK * 0.2200)) {
-               dfn=0;
-               afs=1;
-       } else if (symbol_rate < (u32) (SACLK * 0.3333)) {
-               dfn=0;
-               afs=0;
-       } else {
-               reg37 = 0x63;
-               reg42 = 0x4f;
-               byp=1;
-       }
-
-       /* calculate BDR */
-       big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
-       big += ((SACLK/1000ULL)-1ULL);
-       do_div(big, (SACLK/1000ULL));
-       bdr = big & 0xfffff;
-
-       /* calculate BDRI */
-       tmp = (1<<dfn)*(symbol_rate/1000);
-       bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
-
-       tda10086_write_byte(state, 0x21, (afs << 7) | dfn);
-       tda10086_write_mask(state, 0x20, 0x08, byp << 3);
-       tda10086_write_byte(state, 0x06, bdr);
-       tda10086_write_byte(state, 0x07, bdr >> 8);
-       tda10086_write_byte(state, 0x08, bdr >> 16);
-       tda10086_write_byte(state, 0x09, bdri);
-       tda10086_write_byte(state, 0x37, reg37);
-       tda10086_write_byte(state, 0x42, reg42);
-
-       return 0;
-}
-
-static int tda10086_set_fec(struct tda10086_state *state,
-                           struct dtv_frontend_properties *fe_params)
-{
-       u8 fecval;
-
-       dprintk("%s %i\n", __func__, fe_params->fec_inner);
-
-       switch (fe_params->fec_inner) {
-       case FEC_1_2:
-               fecval = 0x00;
-               break;
-       case FEC_2_3:
-               fecval = 0x01;
-               break;
-       case FEC_3_4:
-               fecval = 0x02;
-               break;
-       case FEC_4_5:
-               fecval = 0x03;
-               break;
-       case FEC_5_6:
-               fecval = 0x04;
-               break;
-       case FEC_6_7:
-               fecval = 0x05;
-               break;
-       case FEC_7_8:
-               fecval = 0x06;
-               break;
-       case FEC_8_9:
-               fecval = 0x07;
-               break;
-       case FEC_AUTO:
-               fecval = 0x08;
-               break;
-       default:
-               return -1;
-       }
-       tda10086_write_byte(state, 0x0d, fecval);
-
-       return 0;
-}
-
-static int tda10086_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
-       struct tda10086_state *state = fe->demodulator_priv;
-       int ret;
-       u32 freq = 0;
-       int freqoff;
-
-       dprintk ("%s\n", __func__);
-
-       /* modify parameters for tuning */
-       tda10086_write_byte(state, 0x02, 0x35);
-       state->has_lock = false;
-
-       /* set params */
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-               if (fe->ops.tuner_ops.get_frequency)
-                       fe->ops.tuner_ops.get_frequency(fe, &freq);
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       /* calcluate the frequency offset (in *Hz* not kHz) */
-       freqoff = fe_params->frequency - freq;
-       freqoff = ((1<<16) * freqoff) / (SACLK/1000);
-       tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
-       tda10086_write_byte(state, 0x3e, freqoff);
-
-       if ((ret = tda10086_set_inversion(state, fe_params)) < 0)
-               return ret;
-       if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0)
-               return ret;
-       if ((ret = tda10086_set_fec(state, fe_params)) < 0)
-               return ret;
-
-       /* soft reset + disable TS output until lock */
-       tda10086_write_mask(state, 0x10, 0x40, 0x40);
-       tda10086_write_mask(state, 0x00, 0x01, 0x00);
-
-       state->symbol_rate = fe_params->symbol_rate;
-       state->frequency = fe_params->frequency;
-       return 0;
-}
-
-static int tda10086_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache;
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 val;
-       int tmp;
-       u64 tmp64;
-
-       dprintk ("%s\n", __func__);
-
-       /* check for invalid symbol rate */
-       if (fe_params->symbol_rate < 500000)
-               return -EINVAL;
-
-       /* calculate the updated frequency (note: we convert from Hz->kHz) */
-       tmp64 = tda10086_read_byte(state, 0x52);
-       tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
-       if (tmp64 & 0x8000)
-               tmp64 |= 0xffffffffffff0000ULL;
-       tmp64 = (tmp64 * (SACLK/1000ULL));
-       do_div(tmp64, (1ULL<<15) * (1ULL<<1));
-       fe_params->frequency = (int) state->frequency + (int) tmp64;
-
-       /* the inversion */
-       val = tda10086_read_byte(state, 0x0c);
-       if (val & 0x80) {
-               switch(val & 0x40) {
-               case 0x00:
-                       fe_params->inversion = INVERSION_OFF;
-                       if (state->config->invert)
-                               fe_params->inversion = INVERSION_ON;
-                       break;
-               default:
-                       fe_params->inversion = INVERSION_ON;
-                       if (state->config->invert)
-                               fe_params->inversion = INVERSION_OFF;
-                       break;
-               }
-       } else {
-               tda10086_read_byte(state, 0x0f);
-               switch(val & 0x02) {
-               case 0x00:
-                       fe_params->inversion = INVERSION_OFF;
-                       if (state->config->invert)
-                               fe_params->inversion = INVERSION_ON;
-                       break;
-               default:
-                       fe_params->inversion = INVERSION_ON;
-                       if (state->config->invert)
-                               fe_params->inversion = INVERSION_OFF;
-                       break;
-               }
-       }
-
-       /* calculate the updated symbol rate */
-       tmp = tda10086_read_byte(state, 0x1d);
-       if (tmp & 0x80)
-               tmp |= 0xffffff00;
-       tmp = (tmp * 480 * (1<<1)) / 128;
-       tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
-       fe_params->symbol_rate = state->symbol_rate + tmp;
-
-       /* the FEC */
-       val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
-       switch(val) {
-       case 0x00:
-               fe_params->fec_inner = FEC_1_2;
-               break;
-       case 0x01:
-               fe_params->fec_inner = FEC_2_3;
-               break;
-       case 0x02:
-               fe_params->fec_inner = FEC_3_4;
-               break;
-       case 0x03:
-               fe_params->fec_inner = FEC_4_5;
-               break;
-       case 0x04:
-               fe_params->fec_inner = FEC_5_6;
-               break;
-       case 0x05:
-               fe_params->fec_inner = FEC_6_7;
-               break;
-       case 0x06:
-               fe_params->fec_inner = FEC_7_8;
-               break;
-       case 0x07:
-               fe_params->fec_inner = FEC_8_9;
-               break;
-       }
-
-       return 0;
-}
-
-static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 val;
-
-       dprintk ("%s\n", __func__);
-
-       val = tda10086_read_byte(state, 0x0e);
-       *fe_status = 0;
-       if (val & 0x01)
-               *fe_status |= FE_HAS_SIGNAL;
-       if (val & 0x02)
-               *fe_status |= FE_HAS_CARRIER;
-       if (val & 0x04)
-               *fe_status |= FE_HAS_VITERBI;
-       if (val & 0x08)
-               *fe_status |= FE_HAS_SYNC;
-       if (val & 0x10) {
-               *fe_status |= FE_HAS_LOCK;
-               if (!state->has_lock) {
-                       state->has_lock = true;
-                       /* modify parameters for stable reception */
-                       tda10086_write_byte(state, 0x02, 0x00);
-               }
-       }
-
-       return 0;
-}
-
-static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 _str;
-
-       dprintk ("%s\n", __func__);
-
-       _str = 0xff - tda10086_read_byte(state, 0x43);
-       *signal = (_str << 8) | _str;
-
-       return 0;
-}
-
-static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-       u8 _snr;
-
-       dprintk ("%s\n", __func__);
-
-       _snr = 0xff - tda10086_read_byte(state, 0x1c);
-       *snr = (_snr << 8) | _snr;
-
-       return 0;
-}
-
-static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-
-       dprintk ("%s\n", __func__);
-
-       /* read it */
-       *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
-
-       /* reset counter */
-       tda10086_write_byte(state, 0x18, 0x00);
-       tda10086_write_byte(state, 0x18, 0x80);
-
-       return 0;
-}
-
-static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-
-       dprintk ("%s\n", __func__);
-
-       /* read it */
-       *ber = 0;
-       *ber |= tda10086_read_byte(state, 0x15);
-       *ber |= tda10086_read_byte(state, 0x16) << 8;
-       *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16;
-
-       return 0;
-}
-
-static int tda10086_sleep(struct dvb_frontend* fe)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-
-       dprintk ("%s\n", __func__);
-
-       tda10086_write_mask(state, 0x00, 0x08, 0x08);
-
-       return 0;
-}
-
-static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct tda10086_state* state = fe->demodulator_priv;
-
-       dprintk ("%s\n", __func__);
-
-       if (enable) {
-               tda10086_write_mask(state, 0x00, 0x10, 0x10);
-       } else {
-               tda10086_write_mask(state, 0x00, 0x10, 0x00);
-       }
-
-       return 0;
-}
-
-static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-
-       if (p->symbol_rate > 20000000) {
-               fesettings->min_delay_ms = 50;
-               fesettings->step_size = 2000;
-               fesettings->max_drift = 8000;
-       } else if (p->symbol_rate > 12000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 1500;
-               fesettings->max_drift = 9000;
-       } else if (p->symbol_rate > 8000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 1000;
-               fesettings->max_drift = 8000;
-       } else if (p->symbol_rate > 4000000) {
-               fesettings->min_delay_ms = 100;
-               fesettings->step_size = 500;
-               fesettings->max_drift = 7000;
-       } else if (p->symbol_rate > 2000000) {
-               fesettings->min_delay_ms = 200;
-               fesettings->step_size = p->symbol_rate / 8000;
-               fesettings->max_drift = 14 * fesettings->step_size;
-       } else {
-               fesettings->min_delay_ms = 200;
-               fesettings->step_size =  p->symbol_rate / 8000;
-               fesettings->max_drift = 18 * fesettings->step_size;
-       }
-
-       return 0;
-}
-
-static void tda10086_release(struct dvb_frontend* fe)
-{
-       struct tda10086_state *state = fe->demodulator_priv;
-       tda10086_sleep(fe);
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda10086_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name     = "Philips TDA10086 DVB-S",
-               .frequency_min    = 950000,
-               .frequency_max    = 2150000,
-               .frequency_stepsize = 125,     /* kHz for QPSK frontends */
-               .symbol_rate_min  = 1000000,
-               .symbol_rate_max  = 45000000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK
-       },
-
-       .release = tda10086_release,
-
-       .init = tda10086_init,
-       .sleep = tda10086_sleep,
-       .i2c_gate_ctrl = tda10086_i2c_gate_ctrl,
-
-       .set_frontend = tda10086_set_frontend,
-       .get_frontend = tda10086_get_frontend,
-       .get_tune_settings = tda10086_get_tune_settings,
-
-       .read_status = tda10086_read_status,
-       .read_ber = tda10086_read_ber,
-       .read_signal_strength = tda10086_read_signal_strength,
-       .read_snr = tda10086_read_snr,
-       .read_ucblocks = tda10086_read_ucblocks,
-
-       .diseqc_send_master_cmd = tda10086_send_master_cmd,
-       .diseqc_send_burst = tda10086_send_burst,
-       .set_tone = tda10086_set_tone,
-};
-
-struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct tda10086_state *state;
-
-       dprintk ("%s\n", __func__);
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if (tda10086_read_byte(state, 0x1e) != 0xe1) {
-               kfree(state);
-               return NULL;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-}
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator");
-MODULE_AUTHOR("Andrew de Quincey");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda10086_attach);
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
deleted file mode 100644 (file)
index 61148c5..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-  /*
-     Driver for Philips tda10086 DVBS Frontend
-
-     (c) 2006 Andrew de Quincey
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   */
-
-#ifndef TDA10086_H
-#define TDA10086_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-enum tda10086_xtal {
-       TDA10086_XTAL_16M,
-       TDA10086_XTAL_4M
-};
-
-struct tda10086_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* does the "inversion" need inverted? */
-       u8 invert;
-
-       /* do we need the diseqc signal with carrier? */
-       u8 diseqc_tone;
-
-       /* frequency of the reference xtal */
-       enum tda10086_xtal xtal_freq;
-};
-
-#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
-                                           struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
-                                                  struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_TDA10086 */
-
-#endif /* TDA10086_H */
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c
deleted file mode 100644 (file)
index ad7c72e..0000000
+++ /dev/null
@@ -1,1246 +0,0 @@
-/*
- * tda18271c2dd: Driver for the TDA18271C2 tuner
- *
- * Copyright (C) 2010 Digital Devices GmbH
- *
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/i2c.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-
-struct SStandardParam {
-       s32   m_IFFrequency;
-       u32   m_BandWidth;
-       u8    m_EP3_4_0;
-       u8    m_EB22;
-};
-
-struct SMap {
-       u32   m_Frequency;
-       u8    m_Param;
-};
-
-struct SMapI {
-       u32   m_Frequency;
-       s32    m_Param;
-};
-
-struct SMap2 {
-       u32   m_Frequency;
-       u8    m_Param1;
-       u8    m_Param2;
-};
-
-struct SRFBandMap {
-       u32   m_RF_max;
-       u32   m_RF1_Default;
-       u32   m_RF2_Default;
-       u32   m_RF3_Default;
-};
-
-enum ERegister {
-       ID = 0,
-       TM,
-       PL,
-       EP1, EP2, EP3, EP4, EP5,
-       CPD, CD1, CD2, CD3,
-       MPD, MD1, MD2, MD3,
-       EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
-       EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
-       EB21, EB22, EB23,
-       NUM_REGS
-};
-
-struct tda_state {
-       struct i2c_adapter *i2c;
-       u8 adr;
-
-       u32   m_Frequency;
-       u32   IF;
-
-       u8    m_IFLevelAnalog;
-       u8    m_IFLevelDigital;
-       u8    m_IFLevelDVBC;
-       u8    m_IFLevelDVBT;
-
-       u8    m_EP4;
-       u8    m_EP3_Standby;
-
-       bool  m_bMaster;
-
-       s32   m_SettlingTime;
-
-       u8    m_Regs[NUM_REGS];
-
-       /* Tracking filter settings for band 0..6 */
-       u32   m_RF1[7];
-       s32   m_RF_A1[7];
-       s32   m_RF_B1[7];
-       u32   m_RF2[7];
-       s32   m_RF_A2[7];
-       s32   m_RF_B2[7];
-       u32   m_RF3[7];
-
-       u8    m_TMValue_RFCal;    /* Calibration temperatur */
-
-       bool  m_bFMInput;         /* true to use Pin 8 for FM Radio */
-
-};
-
-static int PowerScan(struct tda_state *state,
-                    u8 RFBand, u32 RF_in,
-                    u32 *pRF_Out, bool *pbcal);
-
-static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
-{
-       struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
-                                  .buf  = data, .len   = len} };
-       return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
-}
-
-static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
-{
-       struct i2c_msg msg = {.addr = adr, .flags = 0,
-                             .buf = data, .len = len};
-
-       if (i2c_transfer(adap, &msg, 1) != 1) {
-               printk(KERN_ERR "tda18271c2dd: i2c write error at addr %i\n", adr);
-               return -1;
-       }
-       return 0;
-}
-
-static int WriteRegs(struct tda_state *state,
-                    u8 SubAddr, u8 *Regs, u16 nRegs)
-{
-       u8 data[nRegs+1];
-
-       data[0] = SubAddr;
-       memcpy(data + 1, Regs, nRegs);
-       return i2c_write(state->i2c, state->adr, data, nRegs+1);
-}
-
-static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
-{
-       u8 msg[2] = {SubAddr, Reg};
-
-       return i2c_write(state->i2c, state->adr, msg, 2);
-}
-
-static int Read(struct tda_state *state, u8 * Regs)
-{
-       return i2c_readn(state->i2c, state->adr, Regs, 16);
-}
-
-static int ReadExtented(struct tda_state *state, u8 * Regs)
-{
-       return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
-}
-
-static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
-{
-       return WriteRegs(state, RegFrom,
-                        &state->m_Regs[RegFrom], RegTo-RegFrom+1);
-}
-static int UpdateReg(struct tda_state *state, u8 Reg)
-{
-       return WriteReg(state, Reg, state->m_Regs[Reg]);
-}
-
-#include "tda18271c2dd_maps.h"
-
-static void reset(struct tda_state *state)
-{
-       u32   ulIFLevelAnalog = 0;
-       u32   ulIFLevelDigital = 2;
-       u32   ulIFLevelDVBC = 7;
-       u32   ulIFLevelDVBT = 6;
-       u32   ulXTOut = 0;
-       u32   ulStandbyMode = 0x06;    /* Send in stdb, but leave osc on */
-       u32   ulSlave = 0;
-       u32   ulFMInput = 0;
-       u32   ulSettlingTime = 100;
-
-       state->m_Frequency         = 0;
-       state->m_SettlingTime = 100;
-       state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
-       state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
-       state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
-       state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
-
-       state->m_EP4 = 0x20;
-       if (ulXTOut != 0)
-               state->m_EP4 |= 0x40;
-
-       state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
-       state->m_bMaster = (ulSlave == 0);
-
-       state->m_SettlingTime = ulSettlingTime;
-
-       state->m_bFMInput = (ulFMInput == 2);
-}
-
-static bool SearchMap1(struct SMap Map[],
-                      u32 Frequency, u8 *pParam)
-{
-       int i = 0;
-
-       while ((Map[i].m_Frequency != 0) && (Frequency > Map[i].m_Frequency))
-               i += 1;
-       if (Map[i].m_Frequency == 0)
-               return false;
-       *pParam = Map[i].m_Param;
-       return true;
-}
-
-static bool SearchMap2(struct SMapI Map[],
-                      u32 Frequency, s32 *pParam)
-{
-       int i = 0;
-
-       while ((Map[i].m_Frequency != 0) &&
-              (Frequency > Map[i].m_Frequency))
-               i += 1;
-       if (Map[i].m_Frequency == 0)
-               return false;
-       *pParam = Map[i].m_Param;
-       return true;
-}
-
-static bool SearchMap3(struct SMap2 Map[], u32 Frequency,
-                      u8 *pParam1, u8 *pParam2)
-{
-       int i = 0;
-
-       while ((Map[i].m_Frequency != 0) &&
-              (Frequency > Map[i].m_Frequency))
-               i += 1;
-       if (Map[i].m_Frequency == 0)
-               return false;
-       *pParam1 = Map[i].m_Param1;
-       *pParam2 = Map[i].m_Param2;
-       return true;
-}
-
-static bool SearchMap4(struct SRFBandMap Map[],
-                      u32 Frequency, u8 *pRFBand)
-{
-       int i = 0;
-
-       while (i < 7 && (Frequency > Map[i].m_RF_max))
-               i += 1;
-       if (i == 7)
-               return false;
-       *pRFBand = i;
-       return true;
-}
-
-static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
-{
-       int status = 0;
-
-       do {
-               u8 Regs[16];
-               state->m_Regs[TM] |= 0x10;
-               status = UpdateReg(state, TM);
-               if (status < 0)
-                       break;
-               status = Read(state, Regs);
-               if (status < 0)
-                       break;
-               if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
-                   ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
-                       state->m_Regs[TM] ^= 0x20;
-                       status = UpdateReg(state, TM);
-                       if (status < 0)
-                               break;
-                       msleep(10);
-                       status = Read(state, Regs);
-                       if (status < 0)
-                               break;
-               }
-               *pTM_Value = (Regs[TM] & 0x20)
-                               ? m_Thermometer_Map_2[Regs[TM] & 0x0F]
-                               : m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
-               state->m_Regs[TM] &= ~0x10;        /* Thermometer off */
-               status = UpdateReg(state, TM);
-               if (status < 0)
-                       break;
-               state->m_Regs[EP4] &= ~0x03;       /* CAL_mode = 0 ????????? */
-               status = UpdateReg(state, EP4);
-               if (status < 0)
-                       break;
-       } while (0);
-
-       return status;
-}
-
-static int StandBy(struct tda_state *state)
-{
-       int status = 0;
-       do {
-               state->m_Regs[EB12] &= ~0x20;  /* PD_AGC1_Det = 0 */
-               status = UpdateReg(state, EB12);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB18] &= ~0x83;  /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
-               status = UpdateReg(state, EB18);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
-               state->m_Regs[EP3] = state->m_EP3_Standby;
-               status = UpdateReg(state, EP3);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
-               status = UpdateRegs(state, EB21, EB23);
-               if (status < 0)
-                       break;
-       } while (0);
-       return status;
-}
-
-static int CalcMainPLL(struct tda_state *state, u32 freq)
-{
-
-       u8  PostDiv;
-       u8  Div;
-       u64 OscFreq;
-       u32 MainDiv;
-
-       if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
-               return -EINVAL;
-
-       OscFreq = (u64) freq * (u64) Div;
-       OscFreq *= (u64) 16384;
-       do_div(OscFreq, (u64)16000000);
-       MainDiv = OscFreq;
-
-       state->m_Regs[MPD] = PostDiv & 0x77;
-       state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
-       state->m_Regs[MD2] = ((MainDiv >>  8) & 0xFF);
-       state->m_Regs[MD3] = (MainDiv & 0xFF);
-
-       return UpdateRegs(state, MPD, MD3);
-}
-
-static int CalcCalPLL(struct tda_state *state, u32 freq)
-{
-       u8 PostDiv;
-       u8 Div;
-       u64 OscFreq;
-       u32 CalDiv;
-
-       if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
-               return -EINVAL;
-
-       OscFreq = (u64)freq * (u64)Div;
-       /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
-       OscFreq *= (u64)16384;
-       do_div(OscFreq, (u64)16000000);
-       CalDiv = OscFreq;
-
-       state->m_Regs[CPD] = PostDiv;
-       state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
-       state->m_Regs[CD2] = ((CalDiv >>  8) & 0xFF);
-       state->m_Regs[CD3] = (CalDiv & 0xFF);
-
-       return UpdateRegs(state, CPD, CD3);
-}
-
-static int CalibrateRF(struct tda_state *state,
-                      u8 RFBand, u32 freq, s32 *pCprog)
-{
-       int status = 0;
-       u8 Regs[NUM_REGS];
-       do {
-               u8 BP_Filter = 0;
-               u8 GainTaper = 0;
-               u8 RFC_K = 0;
-               u8 RFC_M = 0;
-
-               state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
-               status = UpdateReg(state, EP4);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB18] |= 0x03;  /* AGC1_Gain = 3 */
-               status = UpdateReg(state, EB18);
-               if (status < 0)
-                       break;
-
-               /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
-               /* (Readout of Cprog is allways 255) */
-               if (state->m_Regs[ID] != 0x83)    /* C1: ID == 83, C2: ID == 84 */
-                       state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
-
-               if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
-                       SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
-                       SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
-                       return -EINVAL;
-
-               state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
-               state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
-
-               state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
-
-               status = UpdateRegs(state, EP1, EP3);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EB13);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB4] |= 0x20;    /* LO_ForceSrce = 1 */
-               status = UpdateReg(state, EB4);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB7] |= 0x20;    /* CAL_ForceSrce = 1 */
-               status = UpdateReg(state, EB7);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
-               status = UpdateReg(state, EB14);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB20] &= ~0x20;  /* ForceLock = 0; */
-               status = UpdateReg(state, EB20);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EP4] |= 0x03;  /* CAL_Mode = 3 */
-               status = UpdateRegs(state, EP4, EP5);
-               if (status < 0)
-                       break;
-
-               status = CalcCalPLL(state, freq);
-               if (status < 0)
-                       break;
-               status = CalcMainPLL(state, freq + 1000000);
-               if (status < 0)
-                       break;
-
-               msleep(5);
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB4] &= ~0x20;    /* LO_ForceSrce = 0 */
-               status = UpdateReg(state, EB4);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EB7] &= ~0x20;    /* CAL_ForceSrce = 0 */
-               status = UpdateReg(state, EB7);
-               if (status < 0)
-                       break;
-               msleep(10);
-
-               state->m_Regs[EB20] |= 0x20;  /* ForceLock = 1; */
-               status = UpdateReg(state, EB20);
-               if (status < 0)
-                       break;
-               msleep(60);
-
-               state->m_Regs[EP4] &= ~0x03;  /* CAL_Mode = 0 */
-               state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
-               state->m_Regs[EB18] &= ~0x03;  /* AGC1_Gain = 0 */
-               status = UpdateReg(state, EB18);
-               if (status < 0)
-                       break;
-               status = UpdateRegs(state, EP3, EP4);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-
-               status = ReadExtented(state, Regs);
-               if (status < 0)
-                       break;
-
-               *pCprog = Regs[EB14];
-
-       } while (0);
-       return status;
-}
-
-static int RFTrackingFiltersInit(struct tda_state *state,
-                                u8 RFBand)
-{
-       int status = 0;
-
-       u32   RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
-       u32   RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
-       u32   RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
-       bool    bcal = false;
-
-       s32    Cprog_cal1 = 0;
-       s32    Cprog_table1 = 0;
-       s32    Cprog_cal2 = 0;
-       s32    Cprog_table2 = 0;
-       s32    Cprog_cal3 = 0;
-       s32    Cprog_table3 = 0;
-
-       state->m_RF_A1[RFBand] = 0;
-       state->m_RF_B1[RFBand] = 0;
-       state->m_RF_A2[RFBand] = 0;
-       state->m_RF_B2[RFBand] = 0;
-
-       do {
-               status = PowerScan(state, RFBand, RF1, &RF1, &bcal);
-               if (status < 0)
-                       break;
-               if (bcal) {
-                       status = CalibrateRF(state, RFBand, RF1, &Cprog_cal1);
-                       if (status < 0)
-                               break;
-               }
-               SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
-               if (!bcal)
-                       Cprog_cal1 = Cprog_table1;
-               state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
-               /* state->m_RF_A1[RF_Band] = ???? */
-
-               if (RF2 == 0)
-                       break;
-
-               status = PowerScan(state, RFBand, RF2, &RF2, &bcal);
-               if (status < 0)
-                       break;
-               if (bcal) {
-                       status = CalibrateRF(state, RFBand, RF2, &Cprog_cal2);
-                       if (status < 0)
-                               break;
-               }
-               SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
-               if (!bcal)
-                       Cprog_cal2 = Cprog_table2;
-
-               state->m_RF_A1[RFBand] =
-                       (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
-                       ((s32)(RF2) - (s32)(RF1));
-
-               if (RF3 == 0)
-                       break;
-
-               status = PowerScan(state, RFBand, RF3, &RF3, &bcal);
-               if (status < 0)
-                       break;
-               if (bcal) {
-                       status = CalibrateRF(state, RFBand, RF3, &Cprog_cal3);
-                       if (status < 0)
-                               break;
-               }
-               SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
-               if (!bcal)
-                       Cprog_cal3 = Cprog_table3;
-               state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
-               state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
-
-       } while (0);
-
-       state->m_RF1[RFBand] = RF1;
-       state->m_RF2[RFBand] = RF2;
-       state->m_RF3[RFBand] = RF3;
-
-#if 0
-       printk(KERN_ERR "tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
-              RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
-              state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
-#endif
-
-       return status;
-}
-
-static int PowerScan(struct tda_state *state,
-                    u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
-{
-       int status = 0;
-       do {
-               u8   Gain_Taper = 0;
-               s32  RFC_Cprog = 0;
-               u8   CID_Target = 0;
-               u8   CountLimit = 0;
-               u32  freq_MainPLL;
-               u8   Regs[NUM_REGS];
-               u8   CID_Gain;
-               s32  Count = 0;
-               int  sign  = 1;
-               bool wait = false;
-
-               if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
-                     SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
-                     SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
-
-                       printk(KERN_ERR "tda18271c2dd: %s Search map failed\n", __func__);
-                       return -EINVAL;
-               }
-
-               state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
-               state->m_Regs[EB14] = (RFC_Cprog);
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EB14);
-               if (status < 0)
-                       break;
-
-               freq_MainPLL = RF_in + 1000000;
-               status = CalcMainPLL(state, freq_MainPLL);
-               if (status < 0)
-                       break;
-               msleep(5);
-               state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1;    /* CAL_mode = 1 */
-               status = UpdateReg(state, EP4);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP2);  /* Launch power measurement */
-               if (status < 0)
-                       break;
-               status = ReadExtented(state, Regs);
-               if (status < 0)
-                       break;
-               CID_Gain = Regs[EB10] & 0x3F;
-               state->m_Regs[ID] = Regs[ID];  /* Chip version, (needed for C1 workarround in CalibrateRF) */
-
-               *pRF_Out = RF_in;
-
-               while (CID_Gain < CID_Target) {
-                       freq_MainPLL = RF_in + sign * Count + 1000000;
-                       status = CalcMainPLL(state, freq_MainPLL);
-                       if (status < 0)
-                               break;
-                       msleep(wait ? 5 : 1);
-                       wait = false;
-                       status = UpdateReg(state, EP2);  /* Launch power measurement */
-                       if (status < 0)
-                               break;
-                       status = ReadExtented(state, Regs);
-                       if (status < 0)
-                               break;
-                       CID_Gain = Regs[EB10] & 0x3F;
-                       Count += 200000;
-
-                       if (Count < CountLimit * 100000)
-                               continue;
-                       if (sign < 0)
-                               break;
-
-                       sign = -sign;
-                       Count = 200000;
-                       wait = true;
-               }
-               status = status;
-               if (status < 0)
-                       break;
-               if (CID_Gain >= CID_Target) {
-                       *pbcal = true;
-                       *pRF_Out = freq_MainPLL - 1000000;
-               } else
-                       *pbcal = false;
-       } while (0);
-
-       return status;
-}
-
-static int PowerScanInit(struct tda_state *state)
-{
-       int status = 0;
-       do {
-               state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
-               state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
-               status = UpdateRegs(state, EP3, EP4);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
-               status = UpdateReg(state, EB18);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
-               state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
-               status = UpdateRegs(state, EB21, EB23);
-               if (status < 0)
-                       break;
-       } while (0);
-       return status;
-}
-
-static int CalcRFFilterCurve(struct tda_state *state)
-{
-       int status = 0;
-       do {
-               msleep(200);      /* Temperature stabilisation */
-               status = PowerScanInit(state);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 0);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 1);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 2);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 3);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 4);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 5);
-               if (status < 0)
-                       break;
-               status = RFTrackingFiltersInit(state, 6);
-               if (status < 0)
-                       break;
-               status = ThermometerRead(state, &state->m_TMValue_RFCal); /* also switches off Cal mode !!! */
-               if (status < 0)
-                       break;
-       } while (0);
-
-       return status;
-}
-
-static int FixedContentsI2CUpdate(struct tda_state *state)
-{
-       static u8 InitRegs[] = {
-               0x08, 0x80, 0xC6,
-               0xDF, 0x16, 0x60, 0x80,
-               0x80, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00,
-               0xFC, 0x01, 0x84, 0x41,
-               0x01, 0x84, 0x40, 0x07,
-               0x00, 0x00, 0x96, 0x3F,
-               0xC1, 0x00, 0x8F, 0x00,
-               0x00, 0x8C, 0x00, 0x20,
-               0xB3, 0x48, 0xB0,
-       };
-       int status = 0;
-       memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
-       do {
-               status = UpdateRegs(state, TM, EB23);
-               if (status < 0)
-                       break;
-
-               /* AGC1 gain setup */
-               state->m_Regs[EB17] = 0x00;
-               status = UpdateReg(state, EB17);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB17] = 0x03;
-               status = UpdateReg(state, EB17);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB17] = 0x43;
-               status = UpdateReg(state, EB17);
-               if (status < 0)
-                       break;
-               state->m_Regs[EB17] = 0x4C;
-               status = UpdateReg(state, EB17);
-               if (status < 0)
-                       break;
-
-               /* IRC Cal Low band */
-               state->m_Regs[EP3] = 0x1F;
-               state->m_Regs[EP4] = 0x66;
-               state->m_Regs[EP5] = 0x81;
-               state->m_Regs[CPD] = 0xCC;
-               state->m_Regs[CD1] = 0x6C;
-               state->m_Regs[CD2] = 0x00;
-               state->m_Regs[CD3] = 0x00;
-               state->m_Regs[MPD] = 0xC5;
-               state->m_Regs[MD1] = 0x77;
-               state->m_Regs[MD2] = 0x08;
-               state->m_Regs[MD3] = 0x00;
-               status = UpdateRegs(state, EP2, MD3); /* diff between sw and datasheet (ep3-md3) */
-               if (status < 0)
-                       break;
-
-#if 0
-               state->m_Regs[EB4] = 0x61;          /* missing in sw */
-               status = UpdateReg(state, EB4);
-               if (status < 0)
-                       break;
-               msleep(1);
-               state->m_Regs[EB4] = 0x41;
-               status = UpdateReg(state, EB4);
-               if (status < 0)
-                       break;
-#endif
-
-               msleep(5);
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-               msleep(5);
-
-               state->m_Regs[EP5] = 0x85;
-               state->m_Regs[CPD] = 0xCB;
-               state->m_Regs[CD1] = 0x66;
-               state->m_Regs[CD2] = 0x70;
-               status = UpdateRegs(state, EP3, CD3);
-               if (status < 0)
-                       break;
-               msleep(5);
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               msleep(30);
-
-               /* IRC Cal mid band */
-               state->m_Regs[EP5] = 0x82;
-               state->m_Regs[CPD] = 0xA8;
-               state->m_Regs[CD2] = 0x00;
-               state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
-               state->m_Regs[MD1] = 0x73;
-               state->m_Regs[MD2] = 0x1A;
-               status = UpdateRegs(state, EP3, MD3);
-               if (status < 0)
-                       break;
-
-               msleep(5);
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-               msleep(5);
-
-               state->m_Regs[EP5] = 0x86;
-               state->m_Regs[CPD] = 0xA8;
-               state->m_Regs[CD1] = 0x66;
-               state->m_Regs[CD2] = 0xA0;
-               status = UpdateRegs(state, EP3, CD3);
-               if (status < 0)
-                       break;
-               msleep(5);
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               msleep(30);
-
-               /* IRC Cal high band */
-               state->m_Regs[EP5] = 0x83;
-               state->m_Regs[CPD] = 0x98;
-               state->m_Regs[CD1] = 0x65;
-               state->m_Regs[CD2] = 0x00;
-               state->m_Regs[MPD] = 0x91;  /* Datasheet = 0x91 */
-               state->m_Regs[MD1] = 0x71;
-               state->m_Regs[MD2] = 0xCD;
-               status = UpdateRegs(state, EP3, MD3);
-               if (status < 0)
-                       break;
-               msleep(5);
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-               msleep(5);
-               state->m_Regs[EP5] = 0x87;
-               state->m_Regs[CD1] = 0x65;
-               state->m_Regs[CD2] = 0x50;
-               status = UpdateRegs(state, EP3, CD3);
-               if (status < 0)
-                       break;
-               msleep(5);
-               status = UpdateReg(state, EP2);
-               if (status < 0)
-                       break;
-               msleep(30);
-
-               /* Back to normal */
-               state->m_Regs[EP4] = 0x64;
-               status = UpdateReg(state, EP4);
-               if (status < 0)
-                       break;
-               status = UpdateReg(state, EP1);
-               if (status < 0)
-                       break;
-
-       } while (0);
-       return status;
-}
-
-static int InitCal(struct tda_state *state)
-{
-       int status = 0;
-
-       do {
-               status = FixedContentsI2CUpdate(state);
-               if (status < 0)
-                       break;
-               status = CalcRFFilterCurve(state);
-               if (status < 0)
-                       break;
-               status = StandBy(state);
-               if (status < 0)
-                       break;
-               /* m_bInitDone = true; */
-       } while (0);
-       return status;
-};
-
-static int RFTrackingFiltersCorrection(struct tda_state *state,
-                                      u32 Frequency)
-{
-       int status = 0;
-       s32 Cprog_table;
-       u8 RFBand;
-       u8 dCoverdT;
-
-       if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
-           !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
-           !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
-
-               return -EINVAL;
-
-       do {
-               u8 TMValue_Current;
-               u32   RF1 = state->m_RF1[RFBand];
-               u32   RF2 = state->m_RF1[RFBand];
-               u32   RF3 = state->m_RF1[RFBand];
-               s32    RF_A1 = state->m_RF_A1[RFBand];
-               s32    RF_B1 = state->m_RF_B1[RFBand];
-               s32    RF_A2 = state->m_RF_A2[RFBand];
-               s32    RF_B2 = state->m_RF_B2[RFBand];
-               s32 Capprox = 0;
-               int TComp;
-
-               state->m_Regs[EP3] &= ~0xE0;  /* Power up */
-               status = UpdateReg(state, EP3);
-               if (status < 0)
-                       break;
-
-               status = ThermometerRead(state, &TMValue_Current);
-               if (status < 0)
-                       break;
-
-               if (RF3 == 0 || Frequency < RF2)
-                       Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
-               else
-                       Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
-
-               TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
-
-               Capprox += TComp;
-
-               if (Capprox < 0)
-                       Capprox = 0;
-               else if (Capprox > 255)
-                       Capprox = 255;
-
-
-               /* TODO Temperature compensation. There is defenitely a scale factor */
-               /*      missing in the datasheet, so leave it out for now.           */
-               state->m_Regs[EB14] = Capprox;
-
-               status = UpdateReg(state, EB14);
-               if (status < 0)
-                       break;
-
-       } while (0);
-       return status;
-}
-
-static int ChannelConfiguration(struct tda_state *state,
-                               u32 Frequency, int Standard)
-{
-
-       s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
-       int status = 0;
-
-       u8 BP_Filter = 0;
-       u8 RF_Band = 0;
-       u8 GainTaper = 0;
-       u8 IR_Meas = 0;
-
-       state->IF = IntermediateFrequency;
-       /* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
-       /* get values from tables */
-
-       if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
-              SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
-              SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
-              SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
-
-               printk(KERN_ERR "tda18271c2dd: %s SearchMap failed\n", __func__);
-               return -EINVAL;
-       }
-
-       do {
-               state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
-               state->m_Regs[EP3] &= ~0x04;   /* switch RFAGC to high speed mode */
-
-               /* m_EP4 default for XToutOn, CAL_Mode (0) */
-               state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
-               /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
-               if (Standard <= HF_AnalogMax)
-                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
-               else if (Standard <= HF_ATSC)
-                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
-               else if (Standard <= HF_DVBC)
-                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
-               else
-                       state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
-
-               if ((Standard == HF_FM_Radio) && state->m_bFMInput)
-                       state->m_Regs[EP4] |= 80;
-
-               state->m_Regs[MPD] &= ~0x80;
-               if (Standard > HF_AnalogMax)
-                       state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
-
-               state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
-
-               /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
-               if (Standard == HF_FM_Radio)
-                       state->m_Regs[EB23] |=  0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
-               else
-                       state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
-
-               status = UpdateRegs(state, EB22, EB23);
-               if (status < 0)
-                       break;
-
-               state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter;   /* Dis_Power_level = 1, Filter */
-               state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
-               state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
-
-               state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
-                       (state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
-               /* AGC1_always_master = 0 */
-               /* AGC_firstn = 0 */
-               status = UpdateReg(state, EB1);
-               if (status < 0)
-                       break;
-
-               if (state->m_bMaster) {
-                       status = CalcMainPLL(state, Frequency + IntermediateFrequency);
-                       if (status < 0)
-                               break;
-                       status = UpdateRegs(state, TM, EP5);
-                       if (status < 0)
-                               break;
-                       state->m_Regs[EB4] |= 0x20;    /* LO_forceSrce = 1 */
-                       status = UpdateReg(state, EB4);
-                       if (status < 0)
-                               break;
-                       msleep(1);
-                       state->m_Regs[EB4] &= ~0x20;   /* LO_forceSrce = 0 */
-                       status = UpdateReg(state, EB4);
-                       if (status < 0)
-                               break;
-               } else {
-                       u8 PostDiv = 0;
-                       u8 Div;
-                       status = CalcCalPLL(state, Frequency + IntermediateFrequency);
-                       if (status < 0)
-                               break;
-
-                       SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
-                       state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
-                       status = UpdateReg(state, MPD);
-                       if (status < 0)
-                               break;
-                       status = UpdateRegs(state, TM, EP5);
-                       if (status < 0)
-                               break;
-
-                       state->m_Regs[EB7] |= 0x20;    /* CAL_forceSrce = 1 */
-                       status = UpdateReg(state, EB7);
-                       if (status < 0)
-                               break;
-                       msleep(1);
-                       state->m_Regs[EB7] &= ~0x20;   /* CAL_forceSrce = 0 */
-                       status = UpdateReg(state, EB7);
-                       if (status < 0)
-                               break;
-               }
-               msleep(20);
-               if (Standard != HF_FM_Radio)
-                       state->m_Regs[EP3] |= 0x04;    /* RFAGC to normal mode */
-               status = UpdateReg(state, EP3);
-               if (status < 0)
-                       break;
-
-       } while (0);
-       return status;
-}
-
-static int sleep(struct dvb_frontend *fe)
-{
-       struct tda_state *state = fe->tuner_priv;
-
-       StandBy(state);
-       return 0;
-}
-
-static int init(struct dvb_frontend *fe)
-{
-       return 0;
-}
-
-static int release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-
-static int set_params(struct dvb_frontend *fe)
-{
-       struct tda_state *state = fe->tuner_priv;
-       int status = 0;
-       int Standard;
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       u32 delsys  = fe->dtv_property_cache.delivery_system;
-
-       state->m_Frequency = fe->dtv_property_cache.frequency;
-
-       switch (delsys) {
-       case  SYS_DVBT:
-       case  SYS_DVBT2:
-               switch (bw) {
-               case 6000000:
-                       Standard = HF_DVBT_6MHZ;
-                       break;
-               case 7000000:
-                       Standard = HF_DVBT_7MHZ;
-                       break;
-               case 8000000:
-                       Standard = HF_DVBT_8MHZ;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               if (bw <= 6000000)
-                       Standard = HF_DVBC_6MHZ;
-               else if (bw <= 7000000)
-                       Standard = HF_DVBC_7MHZ;
-               else
-                       Standard = HF_DVBC_8MHZ;
-               break;
-       default:
-               return -EINVAL;
-       }
-       do {
-               status = RFTrackingFiltersCorrection(state, state->m_Frequency);
-               if (status < 0)
-                       break;
-               status = ChannelConfiguration(state, state->m_Frequency,
-                                             Standard);
-               if (status < 0)
-                       break;
-
-               msleep(state->m_SettlingTime);  /* Allow AGC's to settle down */
-       } while (0);
-       return status;
-}
-
-#if 0
-static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
-{
-       if (IFAgc < 500) {
-               /* Scale this from 0 to 50000 */
-               *pSignalStrength = IFAgc * 100;
-       } else {
-               /* Scale range 500-1500 to 50000-80000 */
-               *pSignalStrength = 50000 + (IFAgc - 500) * 30;
-       }
-
-       return 0;
-}
-#endif
-
-static int get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda_state *state = fe->tuner_priv;
-
-       *frequency = state->IF;
-       return 0;
-}
-
-static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       /* struct tda_state *state = fe->tuner_priv; */
-       /* *bandwidth = priv->bandwidth; */
-       return 0;
-}
-
-
-static struct dvb_tuner_ops tuner_ops = {
-       .info = {
-               .name = "NXP TDA18271C2D",
-               .frequency_min  =  47125000,
-               .frequency_max  = 865000000,
-               .frequency_step =     62500
-       },
-       .init              = init,
-       .sleep             = sleep,
-       .set_params        = set_params,
-       .release           = release,
-       .get_if_frequency  = get_if_frequency,
-       .get_bandwidth     = get_bandwidth,
-};
-
-struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
-                                        struct i2c_adapter *i2c, u8 adr)
-{
-       struct tda_state *state;
-
-       state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       fe->tuner_priv = state;
-       state->adr = adr;
-       state->i2c = i2c;
-       memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
-       reset(state);
-       InitCal(state);
-
-       return fe;
-}
-EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
-
-MODULE_DESCRIPTION("TDA18271C2 driver");
-MODULE_AUTHOR("DD");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.h b/drivers/media/dvb/frontends/tda18271c2dd.h
deleted file mode 100644 (file)
index 1389c74..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _TDA18271C2DD_H_
-#define _TDA18271C2DD_H_
-#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
-        && defined(MODULE))
-struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
-                                        struct i2c_adapter *i2c, u8 adr);
-#else
-static inline struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
-                                        struct i2c_adapter *i2c, u8 adr)
-{
-        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-        return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/dvb/frontends/tda18271c2dd_maps.h b/drivers/media/dvb/frontends/tda18271c2dd_maps.h
deleted file mode 100644 (file)
index b87661b..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-enum HF_S {
-       HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio,
-       HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ,
-       HF_DVBT, HF_ATSC,  HF_DVBC_6MHZ,  HF_DVBC_7MHZ,
-       HF_DVBC_8MHZ, HF_DVBC
-};
-
-struct SStandardParam m_StandardTable[] = {
-       {       0,        0, 0x00, 0x00 },    /* HF_None */
-       { 6000000,  7000000, 0x1D, 0x2C },    /* HF_B, */
-       { 6900000,  8000000, 0x1E, 0x2C },    /* HF_DK, */
-       { 7100000,  8000000, 0x1E, 0x2C },    /* HF_G, */
-       { 7250000,  8000000, 0x1E, 0x2C },    /* HF_I, */
-       { 6900000,  8000000, 0x1E, 0x2C },    /* HF_L, */
-       { 1250000,  8000000, 0x1E, 0x2C },    /* HF_L1, */
-       { 5400000,  6000000, 0x1C, 0x2C },    /* HF_MN, */
-       { 1250000,   500000, 0x18, 0x2C },    /* HF_FM_Radio, */
-       {       0,        0, 0x00, 0x00 },    /* HF_AnalogMax (Unused) */
-       { 3300000,  6000000, 0x1C, 0x58 },    /* HF_DVBT_6MHZ */
-       { 3500000,  7000000, 0x1C, 0x37 },    /* HF_DVBT_7MHZ */
-       { 4000000,  8000000, 0x1D, 0x37 },    /* HF_DVBT_8MHZ */
-       {       0,        0, 0x00, 0x00 },    /* HF_DVBT (Unused) */
-       { 5000000,  6000000, 0x1C, 0x37 },    /* HF_ATSC  (center = 3.25 MHz) */
-       { 4000000,  6000000, 0x1D, 0x58 },    /* HF_DVBC_6MHZ (Chicago) */
-       { 4500000,  7000000, 0x1E, 0x37 },    /* HF_DVBC_7MHZ (not documented by NXP) */
-       { 5000000,  8000000, 0x1F, 0x37 },    /* HF_DVBC_8MHZ */
-       {       0,        0, 0x00, 0x00 },    /* HF_DVBC (Unused) */
-};
-
-struct SMap  m_BP_Filter_Map[] = {
-       {   62000000,  0x00 },
-       {   84000000,  0x01 },
-       {  100000000,  0x02 },
-       {  140000000,  0x03 },
-       {  170000000,  0x04 },
-       {  180000000,  0x05 },
-       {  865000000,  0x06 },
-       {          0,  0x00 },    /* Table End */
-};
-
-static struct SMapI m_RF_Cal_Map[] = {
-       {   41000000,  0x0F },
-       {   43000000,  0x1C },
-       {   45000000,  0x2F },
-       {   46000000,  0x39 },
-       {   47000000,  0x40 },
-       {   47900000,  0x50 },
-       {   49100000,  0x16 },
-       {   50000000,  0x18 },
-       {   51000000,  0x20 },
-       {   53000000,  0x28 },
-       {   55000000,  0x2B },
-       {   56000000,  0x32 },
-       {   57000000,  0x35 },
-       {   58000000,  0x3E },
-       {   59000000,  0x43 },
-       {   60000000,  0x4E },
-       {   61100000,  0x55 },
-       {   63000000,  0x0F },
-       {   64000000,  0x11 },
-       {   65000000,  0x12 },
-       {   66000000,  0x15 },
-       {   67000000,  0x16 },
-       {   68000000,  0x17 },
-       {   70000000,  0x19 },
-       {   71000000,  0x1C },
-       {   72000000,  0x1D },
-       {   73000000,  0x1F },
-       {   74000000,  0x20 },
-       {   75000000,  0x21 },
-       {   76000000,  0x24 },
-       {   77000000,  0x25 },
-       {   78000000,  0x27 },
-       {   80000000,  0x28 },
-       {   81000000,  0x29 },
-       {   82000000,  0x2D },
-       {   83000000,  0x2E },
-       {   84000000,  0x2F },
-       {   85000000,  0x31 },
-       {   86000000,  0x33 },
-       {   87000000,  0x34 },
-       {   88000000,  0x35 },
-       {   89000000,  0x37 },
-       {   90000000,  0x38 },
-       {   91000000,  0x39 },
-       {   93000000,  0x3C },
-       {   94000000,  0x3E },
-       {   95000000,  0x3F },
-       {   96000000,  0x40 },
-       {   97000000,  0x42 },
-       {   99000000,  0x45 },
-       {  100000000,  0x46 },
-       {  102000000,  0x48 },
-       {  103000000,  0x4A },
-       {  105000000,  0x4D },
-       {  106000000,  0x4E },
-       {  107000000,  0x50 },
-       {  108000000,  0x51 },
-       {  110000000,  0x54 },
-       {  111000000,  0x56 },
-       {  112000000,  0x57 },
-       {  113000000,  0x58 },
-       {  114000000,  0x59 },
-       {  115000000,  0x5C },
-       {  116000000,  0x5D },
-       {  117000000,  0x5F },
-       {  119000000,  0x60 },
-       {  120000000,  0x64 },
-       {  121000000,  0x65 },
-       {  122000000,  0x66 },
-       {  123000000,  0x68 },
-       {  124000000,  0x69 },
-       {  125000000,  0x6C },
-       {  126000000,  0x6D },
-       {  127000000,  0x6E },
-       {  128000000,  0x70 },
-       {  129000000,  0x71 },
-       {  130000000,  0x75 },
-       {  131000000,  0x77 },
-       {  132000000,  0x78 },
-       {  133000000,  0x7B },
-       {  134000000,  0x7E },
-       {  135000000,  0x81 },
-       {  136000000,  0x82 },
-       {  137000000,  0x87 },
-       {  138000000,  0x88 },
-       {  139000000,  0x8D },
-       {  140000000,  0x8E },
-       {  141000000,  0x91 },
-       {  142000000,  0x95 },
-       {  143000000,  0x9A },
-       {  144000000,  0x9D },
-       {  145000000,  0xA1 },
-       {  146000000,  0xA2 },
-       {  147000000,  0xA4 },
-       {  148000000,  0xA9 },
-       {  149000000,  0xAE },
-       {  150000000,  0xB0 },
-       {  151000000,  0xB1 },
-       {  152000000,  0xB7 },
-       {  152600000,  0xBD },
-       {  154000000,  0x20 },
-       {  155000000,  0x22 },
-       {  156000000,  0x24 },
-       {  157000000,  0x25 },
-       {  158000000,  0x27 },
-       {  159000000,  0x29 },
-       {  160000000,  0x2C },
-       {  161000000,  0x2D },
-       {  163000000,  0x2E },
-       {  164000000,  0x2F },
-       {  164700000,  0x30 },
-       {  166000000,  0x11 },
-       {  167000000,  0x12 },
-       {  168000000,  0x13 },
-       {  169000000,  0x14 },
-       {  170000000,  0x15 },
-       {  172000000,  0x16 },
-       {  173000000,  0x17 },
-       {  174000000,  0x18 },
-       {  175000000,  0x1A },
-       {  176000000,  0x1B },
-       {  178000000,  0x1D },
-       {  179000000,  0x1E },
-       {  180000000,  0x1F },
-       {  181000000,  0x20 },
-       {  182000000,  0x21 },
-       {  183000000,  0x22 },
-       {  184000000,  0x24 },
-       {  185000000,  0x25 },
-       {  186000000,  0x26 },
-       {  187000000,  0x27 },
-       {  188000000,  0x29 },
-       {  189000000,  0x2A },
-       {  190000000,  0x2C },
-       {  191000000,  0x2D },
-       {  192000000,  0x2E },
-       {  193000000,  0x2F },
-       {  194000000,  0x30 },
-       {  195000000,  0x33 },
-       {  196000000,  0x35 },
-       {  198000000,  0x36 },
-       {  200000000,  0x38 },
-       {  201000000,  0x3C },
-       {  202000000,  0x3D },
-       {  203500000,  0x3E },
-       {  206000000,  0x0E },
-       {  208000000,  0x0F },
-       {  212000000,  0x10 },
-       {  216000000,  0x11 },
-       {  217000000,  0x12 },
-       {  218000000,  0x13 },
-       {  220000000,  0x14 },
-       {  222000000,  0x15 },
-       {  225000000,  0x16 },
-       {  228000000,  0x17 },
-       {  231000000,  0x18 },
-       {  234000000,  0x19 },
-       {  235000000,  0x1A },
-       {  236000000,  0x1B },
-       {  237000000,  0x1C },
-       {  240000000,  0x1D },
-       {  242000000,  0x1E },
-       {  244000000,  0x1F },
-       {  247000000,  0x20 },
-       {  249000000,  0x21 },
-       {  252000000,  0x22 },
-       {  253000000,  0x23 },
-       {  254000000,  0x24 },
-       {  256000000,  0x25 },
-       {  259000000,  0x26 },
-       {  262000000,  0x27 },
-       {  264000000,  0x28 },
-       {  267000000,  0x29 },
-       {  269000000,  0x2A },
-       {  271000000,  0x2B },
-       {  273000000,  0x2C },
-       {  275000000,  0x2D },
-       {  277000000,  0x2E },
-       {  279000000,  0x2F },
-       {  282000000,  0x30 },
-       {  284000000,  0x31 },
-       {  286000000,  0x32 },
-       {  287000000,  0x33 },
-       {  290000000,  0x34 },
-       {  293000000,  0x35 },
-       {  295000000,  0x36 },
-       {  297000000,  0x37 },
-       {  300000000,  0x38 },
-       {  303000000,  0x39 },
-       {  305000000,  0x3A },
-       {  306000000,  0x3B },
-       {  307000000,  0x3C },
-       {  310000000,  0x3D },
-       {  312000000,  0x3E },
-       {  315000000,  0x3F },
-       {  318000000,  0x40 },
-       {  320000000,  0x41 },
-       {  323000000,  0x42 },
-       {  324000000,  0x43 },
-       {  325000000,  0x44 },
-       {  327000000,  0x45 },
-       {  331000000,  0x46 },
-       {  334000000,  0x47 },
-       {  337000000,  0x48 },
-       {  339000000,  0x49 },
-       {  340000000,  0x4A },
-       {  341000000,  0x4B },
-       {  343000000,  0x4C },
-       {  345000000,  0x4D },
-       {  349000000,  0x4E },
-       {  352000000,  0x4F },
-       {  353000000,  0x50 },
-       {  355000000,  0x51 },
-       {  357000000,  0x52 },
-       {  359000000,  0x53 },
-       {  361000000,  0x54 },
-       {  362000000,  0x55 },
-       {  364000000,  0x56 },
-       {  368000000,  0x57 },
-       {  370000000,  0x58 },
-       {  372000000,  0x59 },
-       {  375000000,  0x5A },
-       {  376000000,  0x5B },
-       {  377000000,  0x5C },
-       {  379000000,  0x5D },
-       {  382000000,  0x5E },
-       {  384000000,  0x5F },
-       {  385000000,  0x60 },
-       {  386000000,  0x61 },
-       {  388000000,  0x62 },
-       {  390000000,  0x63 },
-       {  393000000,  0x64 },
-       {  394000000,  0x65 },
-       {  396000000,  0x66 },
-       {  397000000,  0x67 },
-       {  398000000,  0x68 },
-       {  400000000,  0x69 },
-       {  402000000,  0x6A },
-       {  403000000,  0x6B },
-       {  407000000,  0x6C },
-       {  408000000,  0x6D },
-       {  409000000,  0x6E },
-       {  410000000,  0x6F },
-       {  411000000,  0x70 },
-       {  412000000,  0x71 },
-       {  413000000,  0x72 },
-       {  414000000,  0x73 },
-       {  417000000,  0x74 },
-       {  418000000,  0x75 },
-       {  420000000,  0x76 },
-       {  422000000,  0x77 },
-       {  423000000,  0x78 },
-       {  424000000,  0x79 },
-       {  427000000,  0x7A },
-       {  428000000,  0x7B },
-       {  429000000,  0x7D },
-       {  432000000,  0x7F },
-       {  434000000,  0x80 },
-       {  435000000,  0x81 },
-       {  436000000,  0x83 },
-       {  437000000,  0x84 },
-       {  438000000,  0x85 },
-       {  439000000,  0x86 },
-       {  440000000,  0x87 },
-       {  441000000,  0x88 },
-       {  442000000,  0x89 },
-       {  445000000,  0x8A },
-       {  446000000,  0x8B },
-       {  447000000,  0x8C },
-       {  448000000,  0x8E },
-       {  449000000,  0x8F },
-       {  450000000,  0x90 },
-       {  452000000,  0x91 },
-       {  453000000,  0x93 },
-       {  454000000,  0x94 },
-       {  456000000,  0x96 },
-       {  457800000,  0x98 },
-       {  461000000,  0x11 },
-       {  468000000,  0x12 },
-       {  472000000,  0x13 },
-       {  473000000,  0x14 },
-       {  474000000,  0x15 },
-       {  481000000,  0x16 },
-       {  486000000,  0x17 },
-       {  491000000,  0x18 },
-       {  498000000,  0x19 },
-       {  499000000,  0x1A },
-       {  501000000,  0x1B },
-       {  506000000,  0x1C },
-       {  511000000,  0x1D },
-       {  516000000,  0x1E },
-       {  520000000,  0x1F },
-       {  521000000,  0x20 },
-       {  525000000,  0x21 },
-       {  529000000,  0x22 },
-       {  533000000,  0x23 },
-       {  539000000,  0x24 },
-       {  541000000,  0x25 },
-       {  547000000,  0x26 },
-       {  549000000,  0x27 },
-       {  551000000,  0x28 },
-       {  556000000,  0x29 },
-       {  561000000,  0x2A },
-       {  563000000,  0x2B },
-       {  565000000,  0x2C },
-       {  569000000,  0x2D },
-       {  571000000,  0x2E },
-       {  577000000,  0x2F },
-       {  580000000,  0x30 },
-       {  582000000,  0x31 },
-       {  584000000,  0x32 },
-       {  588000000,  0x33 },
-       {  591000000,  0x34 },
-       {  596000000,  0x35 },
-       {  598000000,  0x36 },
-       {  603000000,  0x37 },
-       {  604000000,  0x38 },
-       {  606000000,  0x39 },
-       {  612000000,  0x3A },
-       {  615000000,  0x3B },
-       {  617000000,  0x3C },
-       {  621000000,  0x3D },
-       {  622000000,  0x3E },
-       {  625000000,  0x3F },
-       {  632000000,  0x40 },
-       {  633000000,  0x41 },
-       {  634000000,  0x42 },
-       {  642000000,  0x43 },
-       {  643000000,  0x44 },
-       {  647000000,  0x45 },
-       {  650000000,  0x46 },
-       {  652000000,  0x47 },
-       {  657000000,  0x48 },
-       {  661000000,  0x49 },
-       {  662000000,  0x4A },
-       {  665000000,  0x4B },
-       {  667000000,  0x4C },
-       {  670000000,  0x4D },
-       {  673000000,  0x4E },
-       {  676000000,  0x4F },
-       {  677000000,  0x50 },
-       {  681000000,  0x51 },
-       {  683000000,  0x52 },
-       {  686000000,  0x53 },
-       {  688000000,  0x54 },
-       {  689000000,  0x55 },
-       {  691000000,  0x56 },
-       {  695000000,  0x57 },
-       {  698000000,  0x58 },
-       {  703000000,  0x59 },
-       {  704000000,  0x5A },
-       {  705000000,  0x5B },
-       {  707000000,  0x5C },
-       {  710000000,  0x5D },
-       {  712000000,  0x5E },
-       {  717000000,  0x5F },
-       {  718000000,  0x60 },
-       {  721000000,  0x61 },
-       {  722000000,  0x62 },
-       {  723000000,  0x63 },
-       {  725000000,  0x64 },
-       {  727000000,  0x65 },
-       {  730000000,  0x66 },
-       {  732000000,  0x67 },
-       {  735000000,  0x68 },
-       {  740000000,  0x69 },
-       {  741000000,  0x6A },
-       {  742000000,  0x6B },
-       {  743000000,  0x6C },
-       {  745000000,  0x6D },
-       {  747000000,  0x6E },
-       {  748000000,  0x6F },
-       {  750000000,  0x70 },
-       {  752000000,  0x71 },
-       {  754000000,  0x72 },
-       {  757000000,  0x73 },
-       {  758000000,  0x74 },
-       {  760000000,  0x75 },
-       {  763000000,  0x76 },
-       {  764000000,  0x77 },
-       {  766000000,  0x78 },
-       {  767000000,  0x79 },
-       {  768000000,  0x7A },
-       {  773000000,  0x7B },
-       {  774000000,  0x7C },
-       {  776000000,  0x7D },
-       {  777000000,  0x7E },
-       {  778000000,  0x7F },
-       {  779000000,  0x80 },
-       {  781000000,  0x81 },
-       {  783000000,  0x82 },
-       {  784000000,  0x83 },
-       {  785000000,  0x84 },
-       {  786000000,  0x85 },
-       {  793000000,  0x86 },
-       {  794000000,  0x87 },
-       {  795000000,  0x88 },
-       {  797000000,  0x89 },
-       {  799000000,  0x8A },
-       {  801000000,  0x8B },
-       {  802000000,  0x8C },
-       {  803000000,  0x8D },
-       {  804000000,  0x8E },
-       {  810000000,  0x90 },
-       {  811000000,  0x91 },
-       {  812000000,  0x92 },
-       {  814000000,  0x93 },
-       {  816000000,  0x94 },
-       {  817000000,  0x96 },
-       {  818000000,  0x97 },
-       {  820000000,  0x98 },
-       {  821000000,  0x99 },
-       {  822000000,  0x9A },
-       {  828000000,  0x9B },
-       {  829000000,  0x9D },
-       {  830000000,  0x9F },
-       {  831000000,  0xA0 },
-       {  833000000,  0xA1 },
-       {  835000000,  0xA2 },
-       {  836000000,  0xA3 },
-       {  837000000,  0xA4 },
-       {  838000000,  0xA6 },
-       {  840000000,  0xA8 },
-       {  842000000,  0xA9 },
-       {  845000000,  0xAA },
-       {  846000000,  0xAB },
-       {  847000000,  0xAD },
-       {  848000000,  0xAE },
-       {  852000000,  0xAF },
-       {  853000000,  0xB0 },
-       {  858000000,  0xB1 },
-       {  860000000,  0xB2 },
-       {  861000000,  0xB3 },
-       {  862000000,  0xB4 },
-       {  863000000,  0xB6 },
-       {  864000000,  0xB8 },
-       {  865000000,  0xB9 },
-       {          0,  0x00 },    /* Table End */
-};
-
-
-static struct SMap2  m_KM_Map[] = {
-       {   47900000,  3, 2 },
-       {   61100000,  3, 1 },
-       {  350000000,  3, 0 },
-       {  720000000,  2, 1 },
-       {  865000000,  3, 3 },
-       {          0,  0x00 },    /* Table End */
-};
-
-static struct SMap2 m_Main_PLL_Map[] = {
-       {  33125000, 0x57, 0xF0 },
-       {  35500000, 0x56, 0xE0 },
-       {  38188000, 0x55, 0xD0 },
-       {  41375000, 0x54, 0xC0 },
-       {  45125000, 0x53, 0xB0 },
-       {  49688000, 0x52, 0xA0 },
-       {  55188000, 0x51, 0x90 },
-       {  62125000, 0x50, 0x80 },
-       {  66250000, 0x47, 0x78 },
-       {  71000000, 0x46, 0x70 },
-       {  76375000, 0x45, 0x68 },
-       {  82750000, 0x44, 0x60 },
-       {  90250000, 0x43, 0x58 },
-       {  99375000, 0x42, 0x50 },
-       { 110375000, 0x41, 0x48 },
-       { 124250000, 0x40, 0x40 },
-       { 132500000, 0x37, 0x3C },
-       { 142000000, 0x36, 0x38 },
-       { 152750000, 0x35, 0x34 },
-       { 165500000, 0x34, 0x30 },
-       { 180500000, 0x33, 0x2C },
-       { 198750000, 0x32, 0x28 },
-       { 220750000, 0x31, 0x24 },
-       { 248500000, 0x30, 0x20 },
-       { 265000000, 0x27, 0x1E },
-       { 284000000, 0x26, 0x1C },
-       { 305500000, 0x25, 0x1A },
-       { 331000000, 0x24, 0x18 },
-       { 361000000, 0x23, 0x16 },
-       { 397500000, 0x22, 0x14 },
-       { 441500000, 0x21, 0x12 },
-       { 497000000, 0x20, 0x10 },
-       { 530000000, 0x17, 0x0F },
-       { 568000000, 0x16, 0x0E },
-       { 611000000, 0x15, 0x0D },
-       { 662000000, 0x14, 0x0C },
-       { 722000000, 0x13, 0x0B },
-       { 795000000, 0x12, 0x0A },
-       { 883000000, 0x11, 0x09 },
-       { 994000000, 0x10, 0x08 },
-       {         0, 0x00, 0x00 },    /* Table End */
-};
-
-static struct SMap2 m_Cal_PLL_Map[] = {
-       {  33813000, 0xDD, 0xD0 },
-       {  36625000, 0xDC, 0xC0 },
-       {  39938000, 0xDB, 0xB0 },
-       {  43938000, 0xDA, 0xA0 },
-       {  48813000, 0xD9, 0x90 },
-       {  54938000, 0xD8, 0x80 },
-       {  62813000, 0xD3, 0x70 },
-       {  67625000, 0xCD, 0x68 },
-       {  73250000, 0xCC, 0x60 },
-       {  79875000, 0xCB, 0x58 },
-       {  87875000, 0xCA, 0x50 },
-       {  97625000, 0xC9, 0x48 },
-       { 109875000, 0xC8, 0x40 },
-       { 125625000, 0xC3, 0x38 },
-       { 135250000, 0xBD, 0x34 },
-       { 146500000, 0xBC, 0x30 },
-       { 159750000, 0xBB, 0x2C },
-       { 175750000, 0xBA, 0x28 },
-       { 195250000, 0xB9, 0x24 },
-       { 219750000, 0xB8, 0x20 },
-       { 251250000, 0xB3, 0x1C },
-       { 270500000, 0xAD, 0x1A },
-       { 293000000, 0xAC, 0x18 },
-       { 319500000, 0xAB, 0x16 },
-       { 351500000, 0xAA, 0x14 },
-       { 390500000, 0xA9, 0x12 },
-       { 439500000, 0xA8, 0x10 },
-       { 502500000, 0xA3, 0x0E },
-       { 541000000, 0x9D, 0x0D },
-       { 586000000, 0x9C, 0x0C },
-       { 639000000, 0x9B, 0x0B },
-       { 703000000, 0x9A, 0x0A },
-       { 781000000, 0x99, 0x09 },
-       { 879000000, 0x98, 0x08 },
-       {         0, 0x00, 0x00 },    /* Table End */
-};
-
-static struct SMap  m_GainTaper_Map[] = {
-       {  45400000, 0x1F },
-       {  45800000, 0x1E },
-       {  46200000, 0x1D },
-       {  46700000, 0x1C },
-       {  47100000, 0x1B },
-       {  47500000, 0x1A },
-       {  47900000, 0x19 },
-       {  49600000, 0x17 },
-       {  51200000, 0x16 },
-       {  52900000, 0x15 },
-       {  54500000, 0x14 },
-       {  56200000, 0x13 },
-       {  57800000, 0x12 },
-       {  59500000, 0x11 },
-       {  61100000, 0x10 },
-       {  67600000, 0x0D },
-       {  74200000, 0x0C },
-       {  80700000, 0x0B },
-       {  87200000, 0x0A },
-       {  93800000, 0x09 },
-       { 100300000, 0x08 },
-       { 106900000, 0x07 },
-       { 113400000, 0x06 },
-       { 119900000, 0x05 },
-       { 126500000, 0x04 },
-       { 133000000, 0x03 },
-       { 139500000, 0x02 },
-       { 146100000, 0x01 },
-       { 152600000, 0x00 },
-       { 154300000, 0x1F },
-       { 156100000, 0x1E },
-       { 157800000, 0x1D },
-       { 159500000, 0x1C },
-       { 161200000, 0x1B },
-       { 163000000, 0x1A },
-       { 164700000, 0x19 },
-       { 170200000, 0x17 },
-       { 175800000, 0x16 },
-       { 181300000, 0x15 },
-       { 186900000, 0x14 },
-       { 192400000, 0x13 },
-       { 198000000, 0x12 },
-       { 203500000, 0x11 },
-       { 216200000, 0x14 },
-       { 228900000, 0x13 },
-       { 241600000, 0x12 },
-       { 254400000, 0x11 },
-       { 267100000, 0x10 },
-       { 279800000, 0x0F },
-       { 292500000, 0x0E },
-       { 305200000, 0x0D },
-       { 317900000, 0x0C },
-       { 330700000, 0x0B },
-       { 343400000, 0x0A },
-       { 356100000, 0x09 },
-       { 368800000, 0x08 },
-       { 381500000, 0x07 },
-       { 394200000, 0x06 },
-       { 406900000, 0x05 },
-       { 419700000, 0x04 },
-       { 432400000, 0x03 },
-       { 445100000, 0x02 },
-       { 457800000, 0x01 },
-       { 476300000, 0x19 },
-       { 494800000, 0x18 },
-       { 513300000, 0x17 },
-       { 531800000, 0x16 },
-       { 550300000, 0x15 },
-       { 568900000, 0x14 },
-       { 587400000, 0x13 },
-       { 605900000, 0x12 },
-       { 624400000, 0x11 },
-       { 642900000, 0x10 },
-       { 661400000, 0x0F },
-       { 679900000, 0x0E },
-       { 698400000, 0x0D },
-       { 716900000, 0x0C },
-       { 735400000, 0x0B },
-       { 753900000, 0x0A },
-       { 772500000, 0x09 },
-       { 791000000, 0x08 },
-       { 809500000, 0x07 },
-       { 828000000, 0x06 },
-       { 846500000, 0x05 },
-       { 865000000, 0x04 },
-       {         0, 0x00 },    /* Table End */
-};
-
-static struct SMap m_RF_Cal_DC_Over_DT_Map[] = {
-       {  47900000, 0x00 },
-       {  55000000, 0x00 },
-       {  61100000, 0x0A },
-       {  64000000, 0x0A },
-       {  82000000, 0x14 },
-       {  84000000, 0x19 },
-       { 119000000, 0x1C },
-       { 124000000, 0x20 },
-       { 129000000, 0x2A },
-       { 134000000, 0x32 },
-       { 139000000, 0x39 },
-       { 144000000, 0x3E },
-       { 149000000, 0x3F },
-       { 152600000, 0x40 },
-       { 154000000, 0x40 },
-       { 164700000, 0x41 },
-       { 203500000, 0x32 },
-       { 353000000, 0x19 },
-       { 356000000, 0x1A },
-       { 359000000, 0x1B },
-       { 363000000, 0x1C },
-       { 366000000, 0x1D },
-       { 369000000, 0x1E },
-       { 373000000, 0x1F },
-       { 376000000, 0x20 },
-       { 379000000, 0x21 },
-       { 383000000, 0x22 },
-       { 386000000, 0x23 },
-       { 389000000, 0x24 },
-       { 393000000, 0x25 },
-       { 396000000, 0x26 },
-       { 399000000, 0x27 },
-       { 402000000, 0x28 },
-       { 404000000, 0x29 },
-       { 407000000, 0x2A },
-       { 409000000, 0x2B },
-       { 412000000, 0x2C },
-       { 414000000, 0x2D },
-       { 417000000, 0x2E },
-       { 419000000, 0x2F },
-       { 422000000, 0x30 },
-       { 424000000, 0x31 },
-       { 427000000, 0x32 },
-       { 429000000, 0x33 },
-       { 432000000, 0x34 },
-       { 434000000, 0x35 },
-       { 437000000, 0x36 },
-       { 439000000, 0x37 },
-       { 442000000, 0x38 },
-       { 444000000, 0x39 },
-       { 447000000, 0x3A },
-       { 449000000, 0x3B },
-       { 457800000, 0x3C },
-       { 465000000, 0x0F },
-       { 477000000, 0x12 },
-       { 483000000, 0x14 },
-       { 502000000, 0x19 },
-       { 508000000, 0x1B },
-       { 519000000, 0x1C },
-       { 522000000, 0x1D },
-       { 524000000, 0x1E },
-       { 534000000, 0x1F },
-       { 549000000, 0x20 },
-       { 554000000, 0x22 },
-       { 584000000, 0x24 },
-       { 589000000, 0x26 },
-       { 658000000, 0x27 },
-       { 664000000, 0x2C },
-       { 669000000, 0x2D },
-       { 699000000, 0x2E },
-       { 704000000, 0x30 },
-       { 709000000, 0x31 },
-       { 714000000, 0x32 },
-       { 724000000, 0x33 },
-       { 729000000, 0x36 },
-       { 739000000, 0x38 },
-       { 744000000, 0x39 },
-       { 749000000, 0x3B },
-       { 754000000, 0x3C },
-       { 759000000, 0x3D },
-       { 764000000, 0x3E },
-       { 769000000, 0x3F },
-       { 774000000, 0x40 },
-       { 779000000, 0x41 },
-       { 784000000, 0x43 },
-       { 789000000, 0x46 },
-       { 794000000, 0x48 },
-       { 799000000, 0x4B },
-       { 804000000, 0x4F },
-       { 809000000, 0x54 },
-       { 814000000, 0x59 },
-       { 819000000, 0x5D },
-       { 824000000, 0x61 },
-       { 829000000, 0x68 },
-       { 834000000, 0x6E },
-       { 839000000, 0x75 },
-       { 844000000, 0x7E },
-       { 849000000, 0x82 },
-       { 854000000, 0x84 },
-       { 859000000, 0x8F },
-       { 865000000, 0x9A },
-       {         0, 0x00 },    /* Table End */
-};
-
-
-static struct SMap  m_IR_Meas_Map[] = {
-       { 200000000, 0x05 },
-       { 400000000, 0x06 },
-       { 865000000, 0x07 },
-       {         0, 0x00 },    /* Table End */
-};
-
-static struct SMap2 m_CID_Target_Map[] = {
-       {  46000000, 0x04, 18 },
-       {  52200000, 0x0A, 15 },
-       {  70100000, 0x01, 40 },
-       { 136800000, 0x18, 40 },
-       { 156700000, 0x18, 40 },
-       { 186250000, 0x0A, 40 },
-       { 230000000, 0x0A, 40 },
-       { 345000000, 0x18, 40 },
-       { 426000000, 0x0E, 40 },
-       { 489500000, 0x1E, 40 },
-       { 697500000, 0x32, 40 },
-       { 842000000, 0x3A, 40 },
-       {         0, 0x00,  0 },    /* Table End */
-};
-
-static struct SRFBandMap  m_RF_Band_Map[7] = {
-       {   47900000,   46000000,           0,          0},
-       {   61100000,   52200000,           0,          0},
-       {  152600000,   70100000,   136800000,          0},
-       {  164700000,  156700000,           0,          0},
-       {  203500000,  186250000,           0,          0},
-       {  457800000,  230000000,   345000000,  426000000},
-       {  865000000,  489500000,   697500000,  842000000},
-};
-
-u8 m_Thermometer_Map_1[16] = {
-       60, 62, 66, 64,
-       74, 72, 68, 70,
-       90, 88, 84, 86,
-       76, 78, 82, 80,
-};
-
-u8 m_Thermometer_Map_2[16] = {
-       92, 94, 98, 96,
-       106, 104, 100, 102,
-       122, 120, 116, 118,
-       108, 110, 114, 112,
-};
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c
deleted file mode 100644 (file)
index 2c1c759..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
-       TDA665x tuner driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "tda665x.h"
-
-struct tda665x_state {
-       struct dvb_frontend             *fe;
-       struct i2c_adapter              *i2c;
-       const struct tda665x_config     *config;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-static int tda665x_read(struct tda665x_state *state, u8 *buf)
-{
-       const struct tda665x_config *config = state->config;
-       int err = 0;
-       struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
-
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1)
-               goto exit;
-
-       return err;
-exit:
-       printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
-       return err;
-}
-
-static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
-{
-       const struct tda665x_config *config = state->config;
-       int err = 0;
-       struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
-
-       err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1)
-               goto exit;
-
-       return err;
-exit:
-       printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
-       return err;
-}
-
-static int tda665x_get_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *tstate)
-{
-       struct tda665x_state *state = fe->tuner_priv;
-       int err = 0;
-
-       switch (param) {
-       case DVBFE_TUNER_FREQUENCY:
-               tstate->frequency = state->frequency;
-               break;
-       case DVBFE_TUNER_BANDWIDTH:
-               break;
-       default:
-               printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
-               err = -EINVAL;
-               break;
-       }
-
-       return err;
-}
-
-static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct tda665x_state *state = fe->tuner_priv;
-       u8 result = 0;
-       int err = 0;
-
-       *status = 0;
-
-       err = tda665x_read(state, &result);
-       if (err < 0)
-               goto exit;
-
-       if ((result >> 6) & 0x01) {
-               printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
-               *status = 1;
-       }
-
-       return err;
-exit:
-       printk(KERN_ERR "%s: I/O Error\n", __func__);
-       return err;
-}
-
-static int tda665x_set_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *tstate)
-{
-       struct tda665x_state *state = fe->tuner_priv;
-       const struct tda665x_config *config = state->config;
-       u32 frequency, status = 0;
-       u8 buf[4];
-       int err = 0;
-
-       if (param & DVBFE_TUNER_FREQUENCY) {
-
-               frequency = tstate->frequency;
-               if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
-                       printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
-                       return -EINVAL;
-               }
-
-               frequency += config->frequency_offst;
-               frequency *= config->ref_multiplier;
-               frequency += config->ref_divider >> 1;
-               frequency /= config->ref_divider;
-
-               buf[0] = (u8) ((frequency & 0x7f00) >> 8);
-               buf[1] = (u8) (frequency & 0x00ff) >> 0;
-               buf[2] = 0x80 | 0x40 | 0x02;
-               buf[3] = 0x00;
-
-               /* restore frequency */
-               frequency = tstate->frequency;
-
-               if (frequency < 153000000) {
-                       /* VHF-L */
-                       buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
-                       if (frequency < 68000000)
-                               buf[3] |= 0x40; /* 83uA */
-                       if (frequency < 1040000000)
-                               buf[3] |= 0x60; /* 122uA */
-                       if (frequency < 1250000000)
-                               buf[3] |= 0x80; /* 163uA */
-                       else
-                               buf[3] |= 0xa0; /* 254uA */
-               } else if (frequency < 438000000) {
-                       /* VHF-H */
-                       buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
-                       if (frequency < 230000000)
-                               buf[3] |= 0x40;
-                       if (frequency < 300000000)
-                               buf[3] |= 0x60;
-                       else
-                               buf[3] |= 0x80;
-               } else {
-                       /* UHF */
-                       buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
-                       if (frequency < 470000000)
-                               buf[3] |= 0x60;
-                       if (frequency < 526000000)
-                               buf[3] |= 0x80;
-                       else
-                               buf[3] |= 0xa0;
-               }
-
-               /* Set params */
-               err = tda665x_write(state, buf, 5);
-               if (err < 0)
-                       goto exit;
-
-               /* sleep for some time */
-               printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
-               msleep(20);
-               /* check status */
-               err = tda665x_get_status(fe, &status);
-               if (err < 0)
-                       goto exit;
-
-               if (status == 1) {
-                       printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
-                       state->frequency = frequency; /* cache successful state */
-               } else {
-                       printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
-               }
-       } else {
-               printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
-               return -EINVAL;
-       }
-
-       return 0;
-exit:
-       printk(KERN_ERR "%s: I/O Error\n", __func__);
-       return err;
-}
-
-static int tda665x_release(struct dvb_frontend *fe)
-{
-       struct tda665x_state *state = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-       return 0;
-}
-
-static struct dvb_tuner_ops tda665x_ops = {
-
-       .set_state      = tda665x_set_state,
-       .get_state      = tda665x_get_state,
-       .get_status     = tda665x_get_status,
-       .release        = tda665x_release
-};
-
-struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
-                                   const struct tda665x_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct tda665x_state *state = NULL;
-       struct dvb_tuner_info *info;
-
-       state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
-       if (state == NULL)
-               goto exit;
-
-       state->config           = config;
-       state->i2c              = i2c;
-       state->fe               = fe;
-       fe->tuner_priv          = state;
-       fe->ops.tuner_ops       = tda665x_ops;
-       info                     = &fe->ops.tuner_ops.info;
-
-       memcpy(info->name, config->name, sizeof(config->name));
-       info->frequency_min     = config->frequency_min;
-       info->frequency_max     = config->frequency_max;
-       info->frequency_step    = config->frequency_offst;
-
-       printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
-
-       return fe;
-
-exit:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(tda665x_attach);
-
-MODULE_DESCRIPTION("TDA665x driver");
-MODULE_AUTHOR("Manu Abraham");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda665x.h b/drivers/media/dvb/frontends/tda665x.h
deleted file mode 100644 (file)
index ec7927a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-       TDA665x tuner driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __TDA665x_H
-#define __TDA665x_H
-
-struct tda665x_config {
-       char name[128];
-
-       u8      addr;
-       u32     frequency_min;
-       u32     frequency_max;
-       u32     frequency_offst;
-       u32     ref_multiplier;
-       u32     ref_divider;
-};
-
-#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
-                                          const struct tda665x_config *config,
-                                          struct i2c_adapter *i2c);
-
-#else
-
-static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
-                                                 const struct tda665x_config *config,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif /* CONFIG_DVB_TDA665x */
-
-#endif /* __TDA665x_H */
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
deleted file mode 100644 (file)
index 15912c9..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
-    Driver for Philips TDA8083 based QPSK Demodulator
-
-    Copyright (C) 2001 Convergence Integrated Media GmbH
-
-    written by Ralph Metzler <ralph@convergence.de>
-
-    adoption to the new DVB frontend API and diagnostic ioctl's
-    by Holger Waechtler <holger@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include "dvb_frontend.h"
-#include "tda8083.h"
-
-
-struct tda8083_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct tda8083_config* config;
-       struct dvb_frontend frontend;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "tda8083: " args); \
-       } while (0)
-
-
-static u8 tda8083_init_tab [] = {
-       0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
-       0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
-       0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
-       0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
-       0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00
-};
-
-
-static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf [] = { reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
-                       __func__, reg, ret);
-
-       return (ret != 1) ? -1 : 0;
-}
-
-static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
-{
-       int ret;
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
-                       __func__, reg1, ret);
-
-       return ret == 2 ? 0 : -1;
-}
-
-static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
-{
-       u8 val;
-
-       tda8083_readregs (state, reg, &val, 1);
-
-       return val;
-}
-
-static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
-{
-       /*  XXX FIXME: implement other modes than FEC_AUTO */
-       if (inversion == INVERSION_AUTO)
-               return 0;
-
-       return -EINVAL;
-}
-
-static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
-{
-       if (fec == FEC_AUTO)
-               return tda8083_writereg (state, 0x07, 0xff);
-
-       if (fec >= FEC_1_2 && fec <= FEC_8_9)
-               return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
-
-       return -EINVAL;
-}
-
-static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
-{
-       u8 index;
-       static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
-                                      FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
-
-       index = tda8083_readreg(state, 0x0e) & 0x07;
-
-       return fec_tab [index];
-}
-
-static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
-{
-       u32 ratio;
-       u32 tmp;
-       u8 filter;
-
-       if (srate > 32000000)
-               srate = 32000000;
-       if (srate < 500000)
-               srate = 500000;
-
-       filter = 0;
-       if (srate < 24000000)
-               filter = 2;
-       if (srate < 16000000)
-               filter = 3;
-
-       tmp = 31250 << 16;
-       ratio = tmp / srate;
-
-       tmp = (tmp % srate) << 8;
-       ratio = (ratio << 8) + tmp / srate;
-
-       tmp = (tmp % srate) << 8;
-       ratio = (ratio << 8) + tmp / srate;
-
-       dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
-
-       tda8083_writereg (state, 0x05, filter);
-       tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
-       tda8083_writereg (state, 0x03, (ratio >>  8) & 0xff);
-       tda8083_writereg (state, 0x04, (ratio      ) & 0xff);
-
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 1;
-}
-
-static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
-{
-       unsigned long start = jiffies;
-
-       while (jiffies - start < timeout &&
-              !(tda8083_readreg(state, 0x02) & 0x80))
-       {
-               msleep(50);
-       };
-}
-
-static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
-{
-       tda8083_writereg (state, 0x26, 0xf1);
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               return tda8083_writereg (state, 0x29, 0x00);
-       case SEC_TONE_ON:
-               return tda8083_writereg (state, 0x29, 0x80);
-       default:
-               return -EINVAL;
-       };
-}
-
-static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
-{
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               return tda8083_writereg (state, 0x20, 0x00);
-       case SEC_VOLTAGE_18:
-               return tda8083_writereg (state, 0x20, 0x11);
-       default:
-               return -EINVAL;
-       };
-}
-
-static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
-{
-       switch (burst) {
-       case SEC_MINI_A:
-               tda8083_writereg (state, 0x29, (5 << 2));  /* send burst A */
-               break;
-       case SEC_MINI_B:
-               tda8083_writereg (state, 0x29, (7 << 2));  /* send B */
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       tda8083_wait_diseqc_fifo (state, 100);
-
-       return 0;
-}
-
-static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
-                                   struct dvb_diseqc_master_cmd *m)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-       int i;
-
-       tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
-
-       for (i=0; i<m->msg_len; i++)
-               tda8083_writereg (state, 0x23 + i, m->msg[i]);
-
-       tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
-
-       tda8083_wait_diseqc_fifo (state, 100);
-
-       return 0;
-}
-
-static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       u8 signal = ~tda8083_readreg (state, 0x01);
-       u8 sync = tda8083_readreg (state, 0x02);
-
-       *status = 0;
-
-       if (signal > 10)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 0x01)
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 0x02)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 0x10)
-               *status |= FE_HAS_SYNC;
-
-       if (sync & 0x20) /* frontend can not lock */
-               *status |= FE_TIMEDOUT;
-
-       if ((sync & 0x1f) == 0x1f)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-
-       if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf))))
-               return ret;
-
-       *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
-
-       return 0;
-}
-
-static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       u8 signal = ~tda8083_readreg (state, 0x01);
-       *strength = (signal << 8) | signal;
-
-       return 0;
-}
-
-static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       u8 _snr = tda8083_readreg (state, 0x08);
-       *snr = (_snr << 8) | _snr;
-
-       return 0;
-}
-
-static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       *ucblocks = tda8083_readreg(state, 0x0f);
-       if (*ucblocks == 0xff)
-               *ucblocks = 0xffffffff;
-
-       return 0;
-}
-
-static int tda8083_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       tda8083_set_inversion (state, p->inversion);
-       tda8083_set_fec(state, p->fec_inner);
-       tda8083_set_symbolrate(state, p->symbol_rate);
-
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 0;
-}
-
-static int tda8083_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       /*  FIXME: get symbolrate & frequency offset...*/
-       /*p->frequency = ???;*/
-       p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
-                       INVERSION_ON : INVERSION_OFF;
-       p->fec_inner = tda8083_get_fec(state);
-       /*p->symbol_rate = tda8083_get_symbolrate (state);*/
-
-       return 0;
-}
-
-static int tda8083_sleep(struct dvb_frontend* fe)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       tda8083_writereg (state, 0x00, 0x02);
-       return 0;
-}
-
-static int tda8083_init(struct dvb_frontend* fe)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-       int i;
-
-       for (i=0; i<44; i++)
-               tda8083_writereg (state, i, tda8083_init_tab[i]);
-
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 0;
-}
-
-static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       tda8083_send_diseqc_burst (state, burst);
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 0;
-}
-
-static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       tda8083_set_tone (state, tone);
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 0;
-}
-
-static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-
-       tda8083_set_voltage (state, voltage);
-       tda8083_writereg (state, 0x00, 0x3c);
-       tda8083_writereg (state, 0x00, 0x04);
-
-       return 0;
-}
-
-static void tda8083_release(struct dvb_frontend* fe)
-{
-       struct tda8083_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda8083_ops;
-
-struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct tda8083_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-
-       /* check if the demod is there */
-       if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda8083_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "Philips TDA8083 DVB-S",
-               .frequency_min          = 920000,     /* TDA8060 */
-               .frequency_max          = 2200000,    /* TDA8060 */
-               .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
-       /*      .frequency_tolerance    = ???,*/
-               .symbol_rate_min        = 12000000,
-               .symbol_rate_max        = 30000000,
-       /*      .symbol_rate_tolerance  = ???,*/
-               .caps = FE_CAN_INVERSION_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_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_MUTE_TS
-       },
-
-       .release = tda8083_release,
-
-       .init = tda8083_init,
-       .sleep = tda8083_sleep,
-
-       .set_frontend = tda8083_set_frontend,
-       .get_frontend = tda8083_get_frontend,
-
-       .read_status = tda8083_read_status,
-       .read_signal_strength = tda8083_read_signal_strength,
-       .read_snr = tda8083_read_snr,
-       .read_ber = tda8083_read_ber,
-       .read_ucblocks = tda8083_read_ucblocks,
-
-       .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
-       .diseqc_send_burst = tda8083_diseqc_send_burst,
-       .set_tone = tda8083_diseqc_set_tone,
-       .set_voltage = tda8083_diseqc_set_voltage,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
-MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
deleted file mode 100644 (file)
index 5a03c14..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-    Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
-
-    Copyright (C) 2001 Convergence Integrated Media GmbH
-
-    written by Ralph Metzler <ralph@convergence.de>
-
-    adoption to the new DVB frontend API and diagnostic ioctl's
-    by Holger Waechtler <holger@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef TDA8083_H
-#define TDA8083_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda8083_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-};
-
-#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TDA8083
-
-#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
deleted file mode 100644 (file)
index 53c7d8f..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
-       TDA8261 8PSK/QPSK tuner driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "tda8261.h"
-
-struct tda8261_state {
-       struct dvb_frontend             *fe;
-       struct i2c_adapter              *i2c;
-       const struct tda8261_config     *config;
-
-       /* state cache */
-       u32 frequency;
-       u32 bandwidth;
-};
-
-static int tda8261_read(struct tda8261_state *state, u8 *buf)
-{
-       const struct tda8261_config *config = state->config;
-       int err = 0;
-       struct i2c_msg msg = { .addr    = config->addr, .flags = I2C_M_RD,.buf = buf,  .len = 1 };
-
-       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
-               printk("%s: read error, err=%d\n", __func__, err);
-
-       return err;
-}
-
-static int tda8261_write(struct tda8261_state *state, u8 *buf)
-{
-       const struct tda8261_config *config = state->config;
-       int err = 0;
-       struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
-
-       if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
-               printk("%s: write error, err=%d\n", __func__, err);
-
-       return err;
-}
-
-static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct tda8261_state *state = fe->tuner_priv;
-       u8 result = 0;
-       int err = 0;
-
-       *status = 0;
-
-       if ((err = tda8261_read(state, &result)) < 0) {
-               printk("%s: I/O Error\n", __func__);
-               return err;
-       }
-       if ((result >> 6) & 0x01) {
-               printk("%s: Tuner Phase Locked\n", __func__);
-               *status = 1;
-       }
-
-       return err;
-}
-
-static const u32 div_tab[] = { 2000, 1000,  500,  250,  125 }; /* kHz */
-static const u8  ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
-
-static int tda8261_get_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *tstate)
-{
-       struct tda8261_state *state = fe->tuner_priv;
-       int err = 0;
-
-       switch (param) {
-       case DVBFE_TUNER_FREQUENCY:
-               tstate->frequency = state->frequency;
-               break;
-       case DVBFE_TUNER_BANDWIDTH:
-               tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
-               break;
-       default:
-               printk("%s: Unknown parameter (param=%d)\n", __func__, param);
-               err = -EINVAL;
-               break;
-       }
-
-       return err;
-}
-
-static int tda8261_set_state(struct dvb_frontend *fe,
-                            enum tuner_param param,
-                            struct tuner_state *tstate)
-{
-       struct tda8261_state *state = fe->tuner_priv;
-       const struct tda8261_config *config = state->config;
-       u32 frequency, N, status = 0;
-       u8 buf[4];
-       int err = 0;
-
-       if (param & DVBFE_TUNER_FREQUENCY) {
-               /**
-                * N = Max VCO Frequency / Channel Spacing
-                * Max VCO Frequency = VCO frequency + (channel spacing - 1)
-                * (to account for half channel spacing on either side)
-                */
-               frequency = tstate->frequency;
-               if ((frequency < 950000) || (frequency > 2150000)) {
-                       printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
-                       return -EINVAL;
-               }
-               N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
-               printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
-                       __func__, config->step_size, div_tab[config->step_size], N, N);
-
-               buf[0] = (N >> 8) & 0xff;
-               buf[1] = N & 0xff;
-               buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
-
-               if (frequency < 1450000)
-                       buf[3] = 0x00;
-               else if (frequency < 2000000)
-                       buf[3] = 0x40;
-               else if (frequency < 2150000)
-                       buf[3] = 0x80;
-
-               /* Set params */
-               if ((err = tda8261_write(state, buf)) < 0) {
-                       printk("%s: I/O Error\n", __func__);
-                       return err;
-               }
-               /* sleep for some time */
-               printk("%s: Waiting to Phase LOCK\n", __func__);
-               msleep(20);
-               /* check status */
-               if ((err = tda8261_get_status(fe, &status)) < 0) {
-                       printk("%s: I/O Error\n", __func__);
-                       return err;
-               }
-               if (status == 1) {
-                       printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
-                       state->frequency = frequency; /* cache successful state */
-               } else {
-                       printk("%s: No Phase lock: status=%d\n", __func__, status);
-               }
-       } else {
-               printk("%s: Unknown parameter (param=%d)\n", __func__, param);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int tda8261_release(struct dvb_frontend *fe)
-{
-       struct tda8261_state *state = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-       return 0;
-}
-
-static struct dvb_tuner_ops tda8261_ops = {
-
-       .info = {
-               .name           = "TDA8261",
-//             .tuner_name     = NULL,
-               .frequency_min  =  950000,
-               .frequency_max  = 2150000,
-               .frequency_step = 0
-       },
-
-       .set_state      = tda8261_set_state,
-       .get_state      = tda8261_get_state,
-       .get_status     = tda8261_get_status,
-       .release        = tda8261_release
-};
-
-struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
-                                   const struct tda8261_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct tda8261_state *state = NULL;
-
-       if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL)
-               goto exit;
-
-       state->config           = config;
-       state->i2c              = i2c;
-       state->fe               = fe;
-       fe->tuner_priv          = state;
-       fe->ops.tuner_ops       = tda8261_ops;
-
-       fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
-//     fe->ops.tuner_ops.tuner_name     = &config->buf;
-
-//     printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
-//             __func__, fe->ops.tuner_ops.tuner_name);
-       printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
-
-       return fe;
-
-exit:
-       kfree(state);
-       return NULL;
-}
-
-EXPORT_SYMBOL(tda8261_attach);
-
-MODULE_AUTHOR("Manu Abraham");
-MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h
deleted file mode 100644 (file)
index 006e453..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-       TDA8261 8PSK/QPSK tuner driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __TDA8261_H
-#define __TDA8261_H
-
-enum tda8261_step {
-       TDA8261_STEP_2000 = 0,  /* 2000 kHz */
-       TDA8261_STEP_1000,      /* 1000 kHz */
-       TDA8261_STEP_500,       /*  500 kHz */
-       TDA8261_STEP_250,       /*  250 kHz */
-       TDA8261_STEP_125        /*  125 kHz */
-};
-
-struct tda8261_config {
-//     u8                      buf[16];
-       u8                      addr;
-       enum tda8261_step       step_size;
-};
-
-#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE))
-
-extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
-                                          const struct tda8261_config *config,
-                                          struct i2c_adapter *i2c);
-
-#else
-
-static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
-                                                 const struct tda8261_config *config,
-                                                 struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-#endif //CONFIG_DVB_TDA8261
-
-#endif// __TDA8261_H
diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h
deleted file mode 100644 (file)
index 1af1ee4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-       TDA8261 8PSK/QPSK tuner driver
-       Copyright (C) Manu Abraham (abraham.manu@gmail.com)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-               *frequency = t_state.frequency;
-               printk("%s: Frequency=%d\n", __func__, t_state.frequency);
-       }
-       return 0;
-}
-
-static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
-{
-       struct dvb_frontend_ops *frontend_ops = NULL;
-       struct dvb_tuner_ops    *tuner_ops = NULL;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       t_state.frequency = frequency;
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->set_state) {
-               if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-       }
-       printk("%s: Frequency=%d\n", __func__, t_state.frequency);
-       return 0;
-}
-
-static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct dvb_frontend_ops *frontend_ops = &fe->ops;
-       struct dvb_tuner_ops    *tuner_ops = &frontend_ops->tuner_ops;
-       struct tuner_state      t_state;
-       int err = 0;
-
-       if (&fe->ops)
-               frontend_ops = &fe->ops;
-       if (&frontend_ops->tuner_ops)
-               tuner_ops = &frontend_ops->tuner_ops;
-       if (tuner_ops->get_state) {
-               if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
-                       printk("%s: Invalid parameter\n", __func__);
-                       return err;
-               }
-               *bandwidth = t_state.bandwidth;
-       }
-       printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
-       return 0;
-}
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
deleted file mode 100644 (file)
index 04bbcc2..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-  /*
-     Driver for Philips tda8262/tda8263 DVBS Silicon tuners
-
-     (c) 2006 Andrew de Quincey
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-  */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <asm/types.h>
-
-#include "tda826x.h"
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "tda826x: " args); \
-       } while (0)
-
-struct tda826x_priv {
-       /* i2c details */
-       int i2c_address;
-       struct i2c_adapter *i2c;
-       u8 has_loopthrough:1;
-       u32 frequency;
-};
-
-static int tda826x_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int tda826x_sleep(struct dvb_frontend *fe)
-{
-       struct tda826x_priv *priv = fe->tuner_priv;
-       int ret;
-       u8 buf [] = { 0x00, 0x8d };
-       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
-
-       dprintk("%s:\n", __func__);
-
-       if (!priv->has_loopthrough)
-               buf[1] = 0xad;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
-               dprintk("%s: i2c error\n", __func__);
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return (ret == 1) ? 0 : ret;
-}
-
-static int tda826x_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct tda826x_priv *priv = fe->tuner_priv;
-       int ret;
-       u32 div;
-       u32 ksyms;
-       u32 bandwidth;
-       u8 buf [11];
-       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
-
-       dprintk("%s:\n", __func__);
-
-       div = (p->frequency + (1000-1)) / 1000;
-
-       /* BW = ((1 + RO) * SR/2 + 5) * 1.3      [SR in MSPS, BW in MHz] */
-       /* with R0 = 0.35 and some transformations: */
-       ksyms = p->symbol_rate / 1000;
-       bandwidth = (878 * ksyms + 6500000) / 1000000 + 1;
-       if (bandwidth < 5)
-               bandwidth = 5;
-       else if (bandwidth > 36)
-               bandwidth = 36;
-
-       buf[0] = 0x00; // subaddress
-       buf[1] = 0x09; // powerdown RSSI + the magic value 1
-       if (!priv->has_loopthrough)
-               buf[1] |= 0x20; // power down loopthrough if not needed
-       buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
-       buf[3] = div >> 7;
-       buf[4] = div << 1;
-       buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */
-       buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
-       buf[7] = 0x83; // charge pumps at high, tests off
-       buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
-       buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
-       buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
-               dprintk("%s: i2c error\n", __func__);
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       priv->frequency = div * 1000;
-
-       return (ret == 1) ? 0 : ret;
-}
-
-static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda826x_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static struct dvb_tuner_ops tda826x_tuner_ops = {
-       .info = {
-               .name = "Philips TDA826X",
-               .frequency_min = 950000,
-               .frequency_max = 2175000
-       },
-       .release = tda826x_release,
-       .sleep = tda826x_sleep,
-       .set_params = tda826x_set_params,
-       .get_frequency = tda826x_get_frequency,
-};
-
-struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
-{
-       struct tda826x_priv *priv = NULL;
-       u8 b1 [] = { 0, 0 };
-       struct i2c_msg msg[2] = {
-               { .addr = addr, .flags = 0,        .buf = NULL, .len = 0 },
-               { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 }
-       };
-       int ret;
-
-       dprintk("%s:\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer (i2c, msg, 2);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret != 2)
-               return NULL;
-       if (!(b1[1] & 0x80))
-               return NULL;
-
-       priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c_address = addr;
-       priv->i2c = i2c;
-       priv->has_loopthrough = has_loopthrough;
-
-       memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-
-       return fe;
-}
-EXPORT_SYMBOL(tda826x_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("DVB TDA826x driver");
-MODULE_AUTHOR("Andrew de Quincey");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h
deleted file mode 100644 (file)
index 89e9792..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-  /*
-     Driver for Philips tda8262/tda8263 DVBS Silicon tuners
-
-     (c) 2006 Andrew de Quincey
-
-     This program is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published by
-     the Free Software Foundation; either version 2 of the License, or
-     (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-     GNU General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-  */
-
-#ifndef __DVB_TDA826X_H__
-#define __DVB_TDA826X_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/**
- * Attach a tda826x tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
- * @return FE pointer on success, NULL on failure.
- */
-#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
-                                          struct i2c_adapter *i2c,
-                                          int has_loopthrough);
-#else
-static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe,
-                                                 int addr,
-                                                 struct i2c_adapter *i2c,
-                                                 int has_loopthrough)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TDA826X
-
-#endif // __DVB_TDA826X_H__
diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h
deleted file mode 100644 (file)
index 1775098..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * tdhd1.h - ALPS TDHD1-204A tuner support
- *
- * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de>
- *
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
- *
- *
- * The project's page is at http://www.linuxtv.org
- */
-
-#ifndef TDHD1_H
-#define TDHD1_H
-
-#include "tda1004x.h"
-
-static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name);
-
-static struct tda1004x_config alps_tdhd1_204a_config = {
-       .demod_address = 0x8,
-       .invert = 1,
-       .invert_oclk = 0,
-       .xtal_freq = TDA10046_XTAL_4M,
-       .agc_config = TDA10046_AGC_DEFAULT,
-       .if_freq = TDA10046_FREQ_3617,
-       .request_firmware = alps_tdhd1_204_request_firmware
-};
-
-static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct i2c_adapter *i2c = fe->tuner_priv;
-       u8 data[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-       u32 div;
-
-       div = (p->frequency + 36166666) / 166666;
-
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x85;
-
-       if (p->frequency >= 174000000 && p->frequency <= 230000000)
-               data[3] = 0x02;
-       else if (p->frequency >= 470000000 && p->frequency <= 823000000)
-               data[3] = 0x0C;
-       else if (p->frequency > 823000000 && p->frequency <= 862000000)
-               data[3] = 0x8C;
-       else
-               return -EINVAL;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(i2c, &msg, 1) != 1)
-               return -EIO;
-
-       return 0;
-}
-
-#endif /* TDHD1_H */
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c
deleted file mode 100644 (file)
index 029384d..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * Driver for Infineon tua6100 pll.
- *
- * (c) 2006 Andrew de Quincey
- *
- * Based on code found in budget-av.c, which has the following:
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
- *                               Andrew de Quincey <adq_dvb@lidskialf.net>
- *
- * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <asm/types.h>
-
-#include "tua6100.h"
-
-struct tua6100_priv {
-       /* i2c details */
-       int i2c_address;
-       struct i2c_adapter *i2c;
-       u32 frequency;
-};
-
-static int tua6100_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int tua6100_sleep(struct dvb_frontend *fe)
-{
-       struct tua6100_priv *priv = fe->tuner_priv;
-       int ret;
-       u8 reg0[] = { 0x00, 0x00 };
-       struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
-               printk("%s: i2c error\n", __func__);
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return (ret == 1) ? 0 : ret;
-}
-
-static int tua6100_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct tua6100_priv *priv = fe->tuner_priv;
-       u32 div;
-       u32 prediv;
-       u8 reg0[] = { 0x00, 0x00 };
-       u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 };
-       u8 reg2[] = { 0x02, 0x00, 0x00 };
-       struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
-       struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
-       struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
-
-#define _R 4
-#define _P 32
-#define _ri 4000000
-
-       // setup register 0
-       if (c->frequency < 2000000)
-               reg0[1] = 0x03;
-       else
-               reg0[1] = 0x07;
-
-       // setup register 1
-       if (c->frequency < 1630000)
-               reg1[1] = 0x2c;
-       else
-               reg1[1] = 0x0c;
-
-       if (_P == 64)
-               reg1[1] |= 0x40;
-       if (c->frequency >= 1525000)
-               reg1[1] |= 0x80;
-
-       // register 2
-       reg2[1] = (_R >> 8) & 0x03;
-       reg2[2] = _R;
-       if (c->frequency < 1455000)
-               reg2[1] |= 0x1c;
-       else if (c->frequency < 1630000)
-               reg2[1] |= 0x0c;
-       else
-               reg2[1] |= 0x1c;
-
-       /*
-        * The N divisor ratio (note: c->frequency is in kHz, but we
-        * need it in Hz)
-        */
-       prediv = (c->frequency * _R) / (_ri / 1000);
-       div = prediv / _P;
-       reg1[1] |= (div >> 9) & 0x03;
-       reg1[2] = div >> 1;
-       reg1[3] = (div << 7);
-       priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
-
-       // Finally, calculate and store the value for A
-       reg1[3] |= (prediv - (div*_P)) & 0x7f;
-
-#undef _R
-#undef _P
-#undef _ri
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(priv->i2c, &msg0, 1) != 1)
-               return -EIO;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(priv->i2c, &msg2, 1) != 1)
-               return -EIO;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (i2c_transfer(priv->i2c, &msg1, 1) != 1)
-               return -EIO;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tua6100_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static struct dvb_tuner_ops tua6100_tuner_ops = {
-       .info = {
-               .name = "Infineon TUA6100",
-               .frequency_min = 950000,
-               .frequency_max = 2150000,
-               .frequency_step = 1000,
-       },
-       .release = tua6100_release,
-       .sleep = tua6100_sleep,
-       .set_params = tua6100_set_params,
-       .get_frequency = tua6100_get_frequency,
-};
-
-struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
-{
-       struct tua6100_priv *priv = NULL;
-       u8 b1 [] = { 0x80 };
-       u8 b2 [] = { 0x00 };
-       struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 },
-                                 { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } };
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer (i2c, msg, 2);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret != 2)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c_address = addr;
-       priv->i2c = i2c;
-
-       memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(tua6100_attach);
-
-MODULE_DESCRIPTION("DVB tua6100 driver");
-MODULE_AUTHOR("Andrew de Quincey");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h
deleted file mode 100644 (file)
index f83dbd5..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Driver for Infineon tua6100 PLL.
- *
- * (c) 2006 Andrew de Quincey
- *
- * Based on code found in budget-av.c, which has the following:
- * Compiled from various sources by Michael Hunold <michael@mihu.de>
- *
- * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
- *                               Andrew de Quincey <adq_dvb@lidskialf.net>
- *
- * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
- *
- * Copyright (C) 1999-2002 Ralph  Metzler
- *                       & Marcus Metzler for convergence integrated media GmbH
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __DVB_TUA6100_H__
-#define __DVB_TUA6100_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TUA6100
-
-#endif
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
deleted file mode 100644 (file)
index bb42b56..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
-    VES1820  - Single Chip Cable Channel Receiver driver module
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "ves1820.h"
-
-
-
-struct ves1820_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct ves1820_config* config;
-       struct dvb_frontend frontend;
-
-       /* private demodulator data */
-       u8 reg0;
-       u8 pwm;
-};
-
-
-static int verbose;
-
-static u8 ves1820_inittab[] = {
-       0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A,
-       0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
-       0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x40
-};
-
-static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
-{
-       u8 buf[] = { 0x00, reg, data };
-       struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
-       int ret;
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               printk("ves1820: %s(): writereg error (reg == 0x%02x, "
-                       "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
-{
-       u8 b0[] = { 0x00, reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
-               {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
-       };
-       int ret;
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               printk("ves1820: %s(): readreg error (reg == 0x%02x, "
-               "ret == %i)\n", __func__, reg, ret);
-
-       return b1[0];
-}
-
-static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
-{
-       reg0 |= state->reg0 & 0x62;
-
-       if (INVERSION_ON == inversion) {
-               if (!state->config->invert) reg0 |= 0x20;
-               else reg0 &= ~0x20;
-       } else if (INVERSION_OFF == inversion) {
-               if (!state->config->invert) reg0 &= ~0x20;
-               else reg0 |= 0x20;
-       }
-
-       ves1820_writereg(state, 0x00, reg0 & 0xfe);
-       ves1820_writereg(state, 0x00, reg0 | 0x01);
-
-       state->reg0 = reg0;
-
-       return 0;
-}
-
-static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
-{
-       s32 BDR;
-       s32 BDRI;
-       s16 SFIL = 0;
-       u16 NDEC = 0;
-       u32 ratio;
-       u32 fin;
-       u32 tmp;
-       u64 fptmp;
-       u64 fpxin;
-
-       if (symbolrate > state->config->xin / 2)
-               symbolrate = state->config->xin / 2;
-
-       if (symbolrate < 500000)
-               symbolrate = 500000;
-
-       if (symbolrate < state->config->xin / 16)
-               NDEC = 1;
-       if (symbolrate < state->config->xin / 32)
-               NDEC = 2;
-       if (symbolrate < state->config->xin / 64)
-               NDEC = 3;
-
-       /* yeuch! */
-       fpxin = state->config->xin * 10;
-       fptmp = fpxin; do_div(fptmp, 123);
-       if (symbolrate < fptmp)
-               SFIL = 1;
-       fptmp = fpxin; do_div(fptmp, 160);
-       if (symbolrate < fptmp)
-               SFIL = 0;
-       fptmp = fpxin; do_div(fptmp, 246);
-       if (symbolrate < fptmp)
-               SFIL = 1;
-       fptmp = fpxin; do_div(fptmp, 320);
-       if (symbolrate < fptmp)
-               SFIL = 0;
-       fptmp = fpxin; do_div(fptmp, 492);
-       if (symbolrate < fptmp)
-               SFIL = 1;
-       fptmp = fpxin; do_div(fptmp, 640);
-       if (symbolrate < fptmp)
-               SFIL = 0;
-       fptmp = fpxin; do_div(fptmp, 984);
-       if (symbolrate < fptmp)
-               SFIL = 1;
-
-       fin = state->config->xin >> 4;
-       symbolrate <<= NDEC;
-       ratio = (symbolrate << 4) / fin;
-       tmp = ((symbolrate << 4) % fin) << 8;
-       ratio = (ratio << 8) + tmp / fin;
-       tmp = (tmp % fin) << 8;
-       ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, fin);
-
-       BDR = ratio;
-       BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
-
-       if (BDRI > 0xFF)
-               BDRI = 0xFF;
-
-       SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
-
-       NDEC = (NDEC << 6) | ves1820_inittab[0x03];
-
-       ves1820_writereg(state, 0x03, NDEC);
-       ves1820_writereg(state, 0x0a, BDR & 0xff);
-       ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
-       ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
-
-       ves1820_writereg(state, 0x0d, BDRI);
-       ves1820_writereg(state, 0x0e, SFIL);
-
-       return 0;
-}
-
-static int ves1820_init(struct dvb_frontend* fe)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-       int i;
-
-       ves1820_writereg(state, 0, 0);
-
-       for (i = 0; i < sizeof(ves1820_inittab); i++)
-               ves1820_writereg(state, i, ves1820_inittab[i]);
-       if (state->config->selagc)
-               ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
-
-       ves1820_writereg(state, 0x34, state->pwm);
-
-       return 0;
-}
-
-static int ves1820_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ves1820_state* state = fe->demodulator_priv;
-       static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
-       static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
-       static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
-       static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
-       static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
-       int real_qam = p->modulation - QAM_16;
-
-       if (real_qam < 0 || real_qam > 4)
-               return -EINVAL;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       ves1820_set_symbolrate(state, p->symbol_rate);
-       ves1820_writereg(state, 0x34, state->pwm);
-
-       ves1820_writereg(state, 0x01, reg0x01[real_qam]);
-       ves1820_writereg(state, 0x05, reg0x05[real_qam]);
-       ves1820_writereg(state, 0x08, reg0x08[real_qam]);
-       ves1820_writereg(state, 0x09, reg0x09[real_qam]);
-
-       ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
-       ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
-       return 0;
-}
-
-static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-       int sync;
-
-       *status = 0;
-       sync = ves1820_readreg(state, 0x11);
-
-       if (sync & 1)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 2)
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 2)   /* XXX FIXME! */
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 4)
-               *status |= FE_HAS_SYNC;
-
-       if (sync & 8)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-
-       u32 _ber = ves1820_readreg(state, 0x14) |
-                       (ves1820_readreg(state, 0x15) << 8) |
-                       ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
-       *ber = 10 * _ber;
-
-       return 0;
-}
-
-static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-
-       u8 gain = ves1820_readreg(state, 0x17);
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-
-       u8 quality = ~ves1820_readreg(state, 0x18);
-       *snr = (quality << 8) | quality;
-
-       return 0;
-}
-
-static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-
-       *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
-       if (*ucblocks == 0x7f)
-               *ucblocks = 0xffffffff;
-
-       /* reset uncorrected block counter */
-       ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
-       ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
-
-       return 0;
-}
-
-static int ves1820_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ves1820_state* state = fe->demodulator_priv;
-       int sync;
-       s8 afc = 0;
-
-       sync = ves1820_readreg(state, 0x11);
-       afc = ves1820_readreg(state, 0x19);
-       if (verbose) {
-               /* AFC only valid when carrier has been recovered */
-               printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
-                       "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->symbol_rate * afc) >> 10);
-       }
-
-       if (!state->config->invert) {
-               p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
-       } else {
-               p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
-       }
-
-       p->modulation = ((state->reg0 >> 2) & 7) + QAM_16;
-
-       p->fec_inner = FEC_NONE;
-
-       p->frequency = ((p->frequency + 31250) / 62500) * 62500;
-       if (sync & 2)
-               p->frequency -= ((s32) p->symbol_rate * afc) >> 10;
-
-       return 0;
-}
-
-static int ves1820_sleep(struct dvb_frontend* fe)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-
-       ves1820_writereg(state, 0x1b, 0x02);    /* pdown ADC */
-       ves1820_writereg(state, 0x00, 0x80);    /* standby */
-
-       return 0;
-}
-
-static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-
-       fesettings->min_delay_ms = 200;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void ves1820_release(struct dvb_frontend* fe)
-{
-       struct ves1820_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops ves1820_ops;
-
-struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
-                                   struct i2c_adapter* i2c,
-                                   u8 pwm)
-{
-       struct ves1820_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->reg0 = ves1820_inittab[0];
-       state->config = config;
-       state->i2c = i2c;
-       state->pwm = pwm;
-
-       /* check if the demod is there */
-       if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
-               goto error;
-
-       if (verbose)
-               printk("ves1820: pwm=0x%02x\n", state->pwm);
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64;      /* SACLK/64 == (XIN/2)/64 */
-       state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4;       /* SACLK/4 */
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops ves1820_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-               .name = "VLSI VES1820 DVB-C",
-               .frequency_stepsize = 62500,
-               .frequency_min = 47000000,
-               .frequency_max = 862000000,
-               .caps = FE_CAN_QAM_16 |
-                       FE_CAN_QAM_32 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 |
-                       FE_CAN_QAM_256 |
-                       FE_CAN_FEC_AUTO
-       },
-
-       .release = ves1820_release,
-
-       .init = ves1820_init,
-       .sleep = ves1820_sleep,
-
-       .set_frontend = ves1820_set_parameters,
-       .get_frontend = ves1820_get_frontend,
-       .get_tune_settings = ves1820_get_tune_settings,
-
-       .read_status = ves1820_read_status,
-       .read_ber = ves1820_read_ber,
-       .read_signal_strength = ves1820_read_signal_strength,
-       .read_snr = ves1820_read_snr,
-       .read_ucblocks = ves1820_read_ucblocks,
-};
-
-module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
-
-MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
-MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
deleted file mode 100644 (file)
index e902ed6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-    VES1820  - Single Chip Cable Channel Receiver driver module
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef VES1820_H
-#define VES1820_H
-
-#include <linux/dvb/frontend.h>
-
-#define VES1820_SELAGC_PWM 0
-#define VES1820_SELAGC_SIGNAMPERR 1
-
-struct ves1820_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* value of XIN to use */
-       u32 xin;
-
-       /* does inversion need inverted? */
-       u8 invert:1;
-
-       /* SELAGC control */
-       u8 selagc:1;
-};
-
-#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE))
-extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
-                                          struct i2c_adapter* i2c, u8 pwm);
-#else
-static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
-                                          struct i2c_adapter* i2c, u8 pwm)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_VES1820
-
-#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
deleted file mode 100644 (file)
index 9c17eac..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
-    Driver for VES1893 and VES1993 QPSK Demodulators
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-    Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
-    Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
-    Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include "dvb_frontend.h"
-#include "ves1x93.h"
-
-
-struct ves1x93_state {
-       struct i2c_adapter* i2c;
-       /* configuration settings */
-       const struct ves1x93_config* config;
-       struct dvb_frontend frontend;
-
-       /* previous uncorrected block counter */
-       fe_spectral_inversion_t inversion;
-       u8 *init_1x93_tab;
-       u8 *init_1x93_wtab;
-       u8 tab_size;
-       u8 demod_type;
-       u32 frequency;
-};
-
-static int debug;
-#define dprintk        if (debug) printk
-
-#define DEMOD_VES1893          0
-#define DEMOD_VES1993          1
-
-static u8 init_1893_tab [] = {
-       0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
-       0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
-       0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
-       0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
-};
-
-static u8 init_1993_tab [] = {
-       0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
-       0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
-       0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
-       0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
-       0x00, 0x00, 0x0e, 0x80, 0x00
-};
-
-static u8 init_1893_wtab[] =
-{
-       1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
-       0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
-       1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
-       1,1,1,0,1,1
-};
-
-static u8 init_1993_wtab[] =
-{
-       1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
-       0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
-       1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
-       1,1,1,0,1,1,1,1, 1,1,1,1,1
-};
-
-static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
-{
-       u8 buf [] = { 0x00, reg, data };
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
-{
-       int ret;
-       u8 b0 [] = { 0x00, reg };
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
-                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer (state->i2c, msg, 2);
-
-       if (ret != 2) return ret;
-
-       return b1[0];
-}
-
-static int ves1x93_clr_bit (struct ves1x93_state* state)
-{
-       msleep(10);
-       ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
-       ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
-       msleep(50);
-       return 0;
-}
-
-static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
-{
-       u8 val;
-
-       /*
-        * inversion on/off are interchanged because i and q seem to
-        * be swapped on the hardware
-        */
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               val = 0xc0;
-               break;
-       case INVERSION_ON:
-               val = 0x80;
-               break;
-       case INVERSION_AUTO:
-               val = 0x00;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
-}
-
-static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
-{
-       if (fec == FEC_AUTO)
-               return ves1x93_writereg (state, 0x0d, 0x08);
-       else if (fec < FEC_1_2 || fec > FEC_8_9)
-               return -EINVAL;
-       else
-               return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
-}
-
-static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
-{
-       return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
-}
-
-static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
-{
-       u32 BDR;
-       u32 ratio;
-       u8  ADCONF, FCONF, FNR, AGCR;
-       u32 BDRI;
-       u32 tmp;
-       u32 FIN;
-
-       dprintk("%s: srate == %d\n", __func__, (unsigned int) srate);
-
-       if (srate > state->config->xin/2)
-               srate = state->config->xin/2;
-
-       if (srate < 500000)
-               srate = 500000;
-
-#define MUL (1UL<<26)
-
-       FIN = (state->config->xin + 6000) >> 4;
-
-       tmp = srate << 6;
-       ratio = tmp / FIN;
-
-       tmp = (tmp % FIN) << 8;
-       ratio = (ratio << 8) + tmp / FIN;
-
-       tmp = (tmp % FIN) << 8;
-       ratio = (ratio << 8) + tmp / FIN;
-
-       FNR = 0xff;
-
-       if (ratio < MUL/3)           FNR = 0;
-       if (ratio < (MUL*11)/50)     FNR = 1;
-       if (ratio < MUL/6)           FNR = 2;
-       if (ratio < MUL/9)           FNR = 3;
-       if (ratio < MUL/12)          FNR = 4;
-       if (ratio < (MUL*11)/200)    FNR = 5;
-       if (ratio < MUL/24)          FNR = 6;
-       if (ratio < (MUL*27)/1000)   FNR = 7;
-       if (ratio < MUL/48)          FNR = 8;
-       if (ratio < (MUL*137)/10000) FNR = 9;
-
-       if (FNR == 0xff) {
-               ADCONF = 0x89;
-               FCONF  = 0x80;
-               FNR     = 0;
-       } else {
-               ADCONF = 0x81;
-               FCONF  = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
-               /*FCONF  = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
-       }
-
-       BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
-       BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
-
-       dprintk("FNR= %d\n", FNR);
-       dprintk("ratio= %08x\n", (unsigned int) ratio);
-       dprintk("BDR= %08x\n", (unsigned int) BDR);
-       dprintk("BDRI= %02x\n", (unsigned int) BDRI);
-
-       if (BDRI > 0xff)
-               BDRI = 0xff;
-
-       ves1x93_writereg (state, 0x06, 0xff & BDR);
-       ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
-       ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
-
-       ves1x93_writereg (state, 0x09, BDRI);
-       ves1x93_writereg (state, 0x20, ADCONF);
-       ves1x93_writereg (state, 0x21, FCONF);
-
-       AGCR = state->init_1x93_tab[0x05];
-       if (state->config->invert_pwm)
-               AGCR |= 0x20;
-
-       if (srate < 6000000)
-               AGCR |= 0x80;
-       else
-               AGCR &= ~0x80;
-
-       ves1x93_writereg (state, 0x05, AGCR);
-
-       /* ves1993 hates this, will lose lock */
-       if (state->demod_type != DEMOD_VES1993)
-               ves1x93_clr_bit (state);
-
-       return 0;
-}
-
-static int ves1x93_init (struct dvb_frontend* fe)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-       int i;
-       int val;
-
-       dprintk("%s: init chip\n", __func__);
-
-       for (i = 0; i < state->tab_size; i++) {
-               if (state->init_1x93_wtab[i]) {
-                       val = state->init_1x93_tab[i];
-
-                       if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
-                       ves1x93_writereg (state, i, val);
-               }
-       }
-
-       return 0;
-}
-
-static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               return ves1x93_writereg (state, 0x1f, 0x20);
-       case SEC_VOLTAGE_18:
-               return ves1x93_writereg (state, 0x1f, 0x30);
-       case SEC_VOLTAGE_OFF:
-               return ves1x93_writereg (state, 0x1f, 0x00);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       u8 sync = ves1x93_readreg (state, 0x0e);
-
-       /*
-        * The ves1893 sometimes returns sync values that make no sense,
-        * because, e.g., the SIGNAL bit is 0, while some of the higher
-        * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
-        * Tests showed that the VITERBI and SYNC bits are returned
-        * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
-        * If such a case occurs, we read the value again, until we get a
-        * valid value.
-        */
-       int maxtry = 10; /* just for safety - let's not get stuck here */
-       while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
-               msleep(10);
-               sync = ves1x93_readreg (state, 0x0e);
-       }
-
-       *status = 0;
-
-       if (sync & 1)
-               *status |= FE_HAS_SIGNAL;
-
-       if (sync & 2)
-               *status |= FE_HAS_CARRIER;
-
-       if (sync & 4)
-               *status |= FE_HAS_VITERBI;
-
-       if (sync & 8)
-               *status |= FE_HAS_SYNC;
-
-       if ((sync & 0x1f) == 0x1f)
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       *ber = ves1x93_readreg (state, 0x15);
-       *ber |= (ves1x93_readreg (state, 0x16) << 8);
-       *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
-       *ber *= 10;
-
-       return 0;
-}
-
-static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       u8 signal = ~ves1x93_readreg (state, 0x0b);
-       *strength = (signal << 8) | signal;
-
-       return 0;
-}
-
-static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       u8 _snr = ~ves1x93_readreg (state, 0x1c);
-       *snr = (_snr << 8) | _snr;
-
-       return 0;
-}
-
-static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
-
-       if (*ucblocks == 0x7f)
-               *ucblocks = 0xffffffff;   /* counter overflow... */
-
-       ves1x93_writereg (state, 0x18, 0x00);  /* reset the counter */
-       ves1x93_writereg (state, 0x18, 0x80);  /* dto. */
-
-       return 0;
-}
-
-static int ves1x93_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       if (fe->ops.tuner_ops.set_params) {
-               fe->ops.tuner_ops.set_params(fe);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-       ves1x93_set_inversion (state, p->inversion);
-       ves1x93_set_fec(state, p->fec_inner);
-       ves1x93_set_symbolrate(state, p->symbol_rate);
-       state->inversion = p->inversion;
-       state->frequency = p->frequency;
-
-       return 0;
-}
-
-static int ves1x93_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct ves1x93_state* state = fe->demodulator_priv;
-       int afc;
-
-       afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
-       afc = (afc * (int)(p->symbol_rate/1000/8))/16;
-
-       p->frequency = state->frequency - afc;
-
-       /*
-        * inversion indicator is only valid
-        * if auto inversion was used
-        */
-       if (state->inversion == INVERSION_AUTO)
-               p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
-                               INVERSION_OFF : INVERSION_ON;
-       p->fec_inner = ves1x93_get_fec(state);
-       /*  XXX FIXME: timing offset !! */
-
-       return 0;
-}
-
-static int ves1x93_sleep(struct dvb_frontend* fe)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       return ves1x93_writereg (state, 0x00, 0x08);
-}
-
-static void ves1x93_release(struct dvb_frontend* fe)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct ves1x93_state* state = fe->demodulator_priv;
-
-       if (enable) {
-               return ves1x93_writereg(state, 0x00, 0x11);
-       } else {
-               return ves1x93_writereg(state, 0x00, 0x01);
-       }
-}
-
-static struct dvb_frontend_ops ves1x93_ops;
-
-struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct ves1x93_state* state = NULL;
-       u8 identity;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       state->inversion = INVERSION_OFF;
-
-       /* check if the demod is there + identify it */
-       identity = ves1x93_readreg(state, 0x1e);
-       switch (identity) {
-       case 0xdc: /* VES1893A rev1 */
-               printk("ves1x93: Detected ves1893a rev1\n");
-               state->demod_type = DEMOD_VES1893;
-               state->init_1x93_tab = init_1893_tab;
-               state->init_1x93_wtab = init_1893_wtab;
-               state->tab_size = sizeof(init_1893_tab);
-               break;
-
-       case 0xdd: /* VES1893A rev2 */
-               printk("ves1x93: Detected ves1893a rev2\n");
-               state->demod_type = DEMOD_VES1893;
-               state->init_1x93_tab = init_1893_tab;
-               state->init_1x93_wtab = init_1893_wtab;
-               state->tab_size = sizeof(init_1893_tab);
-               break;
-
-       case 0xde: /* VES1993 */
-               printk("ves1x93: Detected ves1993\n");
-               state->demod_type = DEMOD_VES1993;
-               state->init_1x93_tab = init_1993_tab;
-               state->init_1x93_wtab = init_1993_wtab;
-               state->tab_size = sizeof(init_1993_tab);
-               break;
-
-       default:
-               goto error;
-       }
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops ves1x93_ops = {
-       .delsys = { SYS_DVBS },
-       .info = {
-               .name                   = "VLSI VES1x93 DVB-S",
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
-               .frequency_stepsize     = 125,           /* kHz for QPSK frontends */
-               .frequency_tolerance    = 29500,
-               .symbol_rate_min        = 1000000,
-               .symbol_rate_max        = 45000000,
-       /*      .symbol_rate_tolerance  =       ???,*/
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK
-       },
-
-       .release = ves1x93_release,
-
-       .init = ves1x93_init,
-       .sleep = ves1x93_sleep,
-       .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,
-
-       .set_frontend = ves1x93_set_frontend,
-       .get_frontend = ves1x93_get_frontend,
-
-       .read_status = ves1x93_read_status,
-       .read_ber = ves1x93_read_ber,
-       .read_signal_strength = ves1x93_read_signal_strength,
-       .read_snr = ves1x93_read_snr,
-       .read_ucblocks = ves1x93_read_ucblocks,
-
-       .set_voltage = ves1x93_set_voltage,
-};
-
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
-MODULE_AUTHOR("Ralph Metzler");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
deleted file mode 100644 (file)
index 8a5a49e..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-    Driver for VES1893 and VES1993 QPSK Demodulators
-
-    Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
-    Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
-    Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
-    Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef VES1X93_H
-#define VES1X93_H
-
-#include <linux/dvb/frontend.h>
-
-struct ves1x93_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* value of XIN to use */
-       u32 xin;
-
-       /* should PWM be inverted? */
-       u8 invert_pwm:1;
-};
-
-#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE))
-extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
-                                          struct i2c_adapter* i2c);
-#else
-static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
-                                          struct i2c_adapter* i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_VES1X93
-
-#endif // VES1X93_H
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
deleted file mode 100644 (file)
index 96d86d6..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* z0194a.h Sharp z0194a tuner support
-*
-* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
-*
-*      This program is free software; you can redistribute it and/or modify it
-*      under the terms of the GNU General Public License as published by the
-*      Free Software Foundation, version 2.
-*
-* see Documentation/dvb/README.dvb-usb for more information
-*/
-
-#ifndef Z0194A
-#define Z0194A
-
-static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
-                                        u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) {
-               aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) {
-               aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) {
-               aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) {
-               aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) {
-               aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) {
-               aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
-
-       return 0;
-}
-
-static u8 sharp_z0194a_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   /* AGC2  0x3d */
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   /* lock detector threshold */
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  /* out imp: normal  out type: parallel FEC mode:0 */
-       0x29, 0x1e,  /* 1/2 threshold */
-       0x2a, 0x14,  /* 2/3 threshold */
-       0x2b, 0x0f,  /* 3/4 threshold */
-       0x2c, 0x09,  /* 5/6 threshold */
-       0x2d, 0x05,  /* 7/8 threshold */
-       0x2e, 0x01,
-       0x31, 0x1f,  /* test all FECs */
-       0x32, 0x19,  /* viterbi and synchro search */
-       0x33, 0xfc,  /* rs control */
-       0x34, 0x93,  /* error control */
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-#endif
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
deleted file mode 100644 (file)
index 0903d46..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-/**
- * Driver for Zarlink zl10036 DVB-S silicon tuner
- *
- * Copyright (C) 2006 Tino Reichardt
- * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- **
- * The data sheet for this tuner can be found at:
- *    http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
- *
- * This one is working: (at my Avermedia DVB-S Pro)
- * - zl10036 (40pin, FTA)
- *
- * A driver for zl10038 should be very similar.
- */
-
-#include <linux/module.h>
-#include <linux/dvb/frontend.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include "zl10036.h"
-
-static int zl10036_debug;
-#define dprintk(level, args...) \
-       do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
-       } while (0)
-
-#define deb_info(args...)  dprintk(0x01, args)
-#define deb_i2c(args...)  dprintk(0x02, args)
-
-struct zl10036_state {
-       struct i2c_adapter *i2c;
-       const struct zl10036_config *config;
-       u32 frequency;
-       u8 br, bf;
-};
-
-
-/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
-#define _XTAL 10111
-
-/* Some of the possible dividers:
- *   64, (write 0x05 to reg), freq step size   158kHz
- *   10, (write 0x0a to reg), freq step size 1.011kHz (used here)
- *    5, (write 0x09 to reg), freq step size 2.022kHz
- */
-
-#define _RDIV 10
-#define _RDIV_REG 0x0a
-#define _FR   (_XTAL/_RDIV)
-
-#define STATUS_POR 0x80 /* Power on Reset */
-#define STATUS_FL  0x40 /* Frequency & Phase Lock */
-
-/* read/write for zl10036 and zl10038 */
-
-static int zl10036_read_status_reg(struct zl10036_state *state)
-{
-       u8 status;
-       struct i2c_msg msg[1] = {
-               { .addr = state->config->tuner_address, .flags = I2C_M_RD,
-                 .buf = &status, .len = sizeof(status) },
-       };
-
-       if (i2c_transfer(state->i2c, msg, 1) != 1) {
-               printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
-                       __func__, state->config->tuner_address);
-               return -EIO;
-       }
-
-       deb_i2c("R(status): %02x  [FL=%d]\n", status,
-               (status & STATUS_FL) ? 1 : 0);
-       if (status & STATUS_POR)
-               deb_info("%s: Power-On-Reset bit enabled - "
-                       "need to initialize the tuner\n", __func__);
-
-       return status;
-}
-
-static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
-{
-       struct i2c_msg msg[1] = {
-               { .addr = state->config->tuner_address, .flags = 0,
-                 .buf = buf, .len = count },
-       };
-       u8 reg = 0;
-       int ret;
-
-       if (zl10036_debug & 0x02) {
-               /* every 8bit-value satisifes this!
-                * so only check for debug log */
-               if ((buf[0] & 0x80) == 0x00)
-                       reg = 2;
-               else if ((buf[0] & 0xc0) == 0x80)
-                       reg = 4;
-               else if ((buf[0] & 0xf0) == 0xc0)
-                       reg = 6;
-               else if ((buf[0] & 0xf0) == 0xd0)
-                       reg = 8;
-               else if ((buf[0] & 0xf0) == 0xe0)
-                       reg = 10;
-               else if ((buf[0] & 0xf0) == 0xf0)
-                       reg = 12;
-
-               deb_i2c("W(%d):", reg);
-               {
-                       int i;
-                       for (i = 0; i < count; i++)
-                               printk(KERN_CONT " %02x", buf[i]);
-                       printk(KERN_CONT "\n");
-               }
-       }
-
-       ret = i2c_transfer(state->i2c, msg, 1);
-       if (ret != 1) {
-               printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int zl10036_release(struct dvb_frontend *fe)
-{
-       struct zl10036_state *state = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-
-       return 0;
-}
-
-static int zl10036_sleep(struct dvb_frontend *fe)
-{
-       struct zl10036_state *state = fe->tuner_priv;
-       u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
-       int ret;
-
-       deb_info("%s\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = zl10036_write(state, buf, sizeof(buf));
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-/**
- * register map of the ZL10036/ZL10038
- *
- * reg[default] content
- *  2[0x00]:   0 | N14 | N13 | N12 | N11 | N10 |  N9 |  N8
- *  3[0x00]:  N7 |  N6 |  N5 |  N4 |  N3 |  N2 |  N1 |  N0
- *  4[0x80]:   1 |   0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
- *  5[0x00]:  P0 |  C1 |  C0 |  R4 |  R3 |  R2 |  R1 |  R0
- *  6[0xc0]:   1 |   1 |   0 |   0 | RSD |   0 |   0 |   0
- *  7[0x20]:  P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 |   0
- *  8[0xdb]:   1 |   1 |   0 |   1 |   0 |  CC |   1 |   1
- *  9[0x30]: VSD |  V2 |  V1 |  V0 |  S3 |  S2 |  S1 |  S0
- * 10[0xe1]:   1 |   1 |   1 |   0 |   0 | LS2 | LS1 | LS0
- * 11[0xf5]:  WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
- * 12[0xf0]:   1 |   1 |   1 |   1 |   0 |   0 |   0 |   0
- * 13[0x28]:  PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR |  TL
- */
-
-static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
-{
-       u8 buf[2];
-       u32 div, foffset;
-
-       div = (frequency + _FR/2) / _FR;
-       state->frequency = div * _FR;
-
-       foffset = frequency - state->frequency;
-
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = (div >> 0) & 0xff;
-
-       deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
-               frequency, state->frequency, foffset, div);
-
-       return zl10036_write(state, buf, sizeof(buf));
-}
-
-static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
-{
-       /* fbw is measured in kHz */
-       u8 br, bf;
-       int ret;
-       u8 buf_bf[] = {
-               0xc0, 0x00, /*   6/7: rsd=0 bf=0 */
-       };
-       u8 buf_br[] = {
-               0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
-       };
-       u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
-
-       /* ensure correct values */
-       if (fbw > 35000)
-               fbw = 35000;
-       if (fbw <  8000)
-               fbw =  8000;
-
-#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
-
-       /* <= 28,82 MHz */
-       if (fbw <= 28820) {
-               br = _BR_MAXIMUM;
-       } else {
-               /**
-                *  f(bw)=34,6MHz f(xtal)=10.111MHz
-                *  br = (10111/34600) * 63 * 1/K = 14;
-                */
-               br = ((_XTAL * 21 * 1000) / (fbw * 419));
-       }
-
-       /* ensure correct values */
-       if (br < 4)
-               br = 4;
-       if (br > _BR_MAXIMUM)
-               br = _BR_MAXIMUM;
-
-       /*
-        * k = 1.257
-        * bf = fbw/_XTAL * br * k - 1 */
-
-       bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
-
-       /* ensure correct values */
-       if (bf > 62)
-               bf = 62;
-
-       buf_bf[1] = (bf << 1) & 0x7e;
-       buf_br[1] = (br << 2) & 0x7c;
-       deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
-
-       if (br != state->br) {
-               ret = zl10036_write(state, buf_br, sizeof(buf_br));
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (bf != state->bf) {
-               ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
-               if (ret < 0)
-                       return ret;
-
-               /* time = br/(32* fxtal) */
-               /* minimal sleep time to be calculated
-                * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
-               msleep(1);
-
-               ret = zl10036_write(state, zl10036_rsd_off,
-                       sizeof(zl10036_rsd_off));
-               if (ret < 0)
-                       return ret;
-       }
-
-       state->br = br;
-       state->bf = bf;
-
-       return 0;
-}
-
-static int zl10036_set_gain_params(struct zl10036_state *state,
-       int c)
-{
-       u8 buf[2];
-       u8 rfg, ba, bg;
-
-       /* default values */
-       rfg = 0; /* enable when using an lna */
-       ba = 1;
-       bg = 1;
-
-       /* reg 4 */
-       buf[0] = 0x80 | ((rfg << 5) & 0x20)
-               | ((ba  << 3) & 0x18) | ((bg  << 1) & 0x06);
-
-       if (!state->config->rf_loop_enable)
-               buf[0] |= 0x01;
-
-       /* P0=0 */
-       buf[1] = _RDIV_REG | ((c << 5) & 0x60);
-
-       deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
-       return zl10036_write(state, buf, sizeof(buf));
-}
-
-static int zl10036_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct zl10036_state *state = fe->tuner_priv;
-       int ret = 0;
-       u32 frequency = p->frequency;
-       u32 fbw;
-       int i;
-       u8 c;
-
-       /* ensure correct values
-        * maybe redundant as core already checks this */
-       if ((frequency < fe->ops.info.frequency_min)
-       ||  (frequency > fe->ops.info.frequency_max))
-               return -EINVAL;
-
-       /**
-        * alpha = 1.35 for dvb-s
-        * fBW = (alpha*symbolrate)/(2*0.8)
-        * 1.35 / (2*0.8) = 27 / 32
-        */
-       fbw = (27 * p->symbol_rate) / 32;
-
-       /* scale to kHz */
-       fbw /= 1000;
-
-       /* Add safe margin of 3MHz */
-       fbw += 3000;
-
-       /* setting the charge pump - guessed values */
-       if (frequency < 950000)
-               return -EINVAL;
-       else if (frequency < 1250000)
-               c = 0;
-       else if (frequency < 1750000)
-               c = 1;
-       else if (frequency < 2175000)
-               c = 2;
-       else
-               return -EINVAL;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = zl10036_set_gain_params(state, c);
-       if (ret < 0)
-               goto error;
-
-       ret = zl10036_set_frequency(state, p->frequency);
-       if (ret < 0)
-               goto error;
-
-       ret = zl10036_set_bandwidth(state, fbw);
-       if (ret < 0)
-               goto error;
-
-       /* wait for tuner lock - no idea if this is really needed */
-       for (i = 0; i < 20; i++) {
-               ret = zl10036_read_status_reg(state);
-               if (ret < 0)
-                       goto error;
-
-               /* check Frequency & Phase Lock Bit */
-               if (ret & STATUS_FL)
-                       break;
-
-               msleep(10);
-       }
-
-error:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct zl10036_state *state = fe->tuner_priv;
-
-       *frequency = state->frequency;
-
-       return 0;
-}
-
-static int zl10036_init_regs(struct zl10036_state *state)
-{
-       int ret;
-       int i;
-
-       /* could also be one block from reg 2 to 13 and additional 10/11 */
-       u8 zl10036_init_tab[][2] = {
-               { 0x04, 0x00 },         /*   2/3: div=0x400 - arbitrary value */
-               { 0x8b, _RDIV_REG },    /*   4/5: rfg=0 ba=1 bg=1 len=? */
-                                       /*        p0=0 c=0 r=_RDIV_REG */
-               { 0xc0, 0x20 },         /*   6/7: rsd=0 bf=0x10 */
-               { 0xd3, 0x40 },         /*   8/9: from datasheet */
-               { 0xe3, 0x5b },         /* 10/11: lock window level */
-               { 0xf0, 0x28 },         /* 12/13: br=0xa clr=0 tl=0*/
-               { 0xe3, 0xf9 },         /* 10/11: unlock window level */
-       };
-
-       /* invalid values to trigger writing */
-       state->br = 0xff;
-       state->bf = 0xff;
-
-       if (!state->config->rf_loop_enable)
-               zl10036_init_tab[1][0] |= 0x01;
-
-       deb_info("%s\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
-               ret = zl10036_write(state, zl10036_init_tab[i], 2);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int zl10036_init(struct dvb_frontend *fe)
-{
-       struct zl10036_state *state = fe->tuner_priv;
-       int ret = 0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = zl10036_read_status_reg(state);
-       if (ret < 0)
-               return ret;
-
-       /* Only init if Power-on-Reset bit is set? */
-       ret = zl10036_init_regs(state);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-static struct dvb_tuner_ops zl10036_tuner_ops = {
-       .info = {
-               .name = "Zarlink ZL10036",
-               .frequency_min = 950000,
-               .frequency_max = 2175000
-       },
-       .init = zl10036_init,
-       .release = zl10036_release,
-       .sleep = zl10036_sleep,
-       .set_params = zl10036_set_params,
-       .get_frequency = zl10036_get_frequency,
-};
-
-struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
-                                   const struct zl10036_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct zl10036_state *state;
-       int ret;
-
-       if (!config) {
-               printk(KERN_ERR "%s: no config specified", __func__);
-               return NULL;
-       }
-
-       state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
-       if (!state)
-               return NULL;
-
-       state->config = config;
-       state->i2c = i2c;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = zl10036_read_status_reg(state);
-       if (ret < 0) {
-               printk(KERN_ERR "%s: No zl10036 found\n", __func__);
-               goto error;
-       }
-
-       ret = zl10036_init_regs(state);
-       if (ret < 0) {
-               printk(KERN_ERR "%s: tuner initialization failed\n",
-                       __func__);
-               goto error;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       fe->tuner_priv = state;
-
-       memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-       printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
-               __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
-
-       return fe;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(zl10036_attach);
-
-module_param_named(debug, zl10036_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-MODULE_DESCRIPTION("DVB ZL10036 driver");
-MODULE_AUTHOR("Tino Reichardt");
-MODULE_AUTHOR("Matthias Schwarzott");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h
deleted file mode 100644 (file)
index d84b8f8..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Driver for Zarlink ZL10036 DVB-S silicon tuner
- *
- * Copyright (C) 2006 Tino Reichardt
- * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef DVB_ZL10036_H
-#define DVB_ZL10036_H
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/**
- * Attach a zl10036 tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param config zl10036_config structure
- * @return FE pointer on success, NULL on failure.
- */
-
-struct zl10036_config {
-       u8 tuner_address;
-       int rf_loop_enable;
-};
-
-#if defined(CONFIG_DVB_ZL10036) || \
-       (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
-extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
-       const struct zl10036_config *config, struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
-       const struct zl10036_config *config, struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c
deleted file mode 100644 (file)
index eff9c5f..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *  Driver for Zarlink ZL10039 DVB-S tuner
- *
- *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/dvb/frontend.h>
-
-#include "dvb_frontend.h"
-#include "zl10039.h"
-
-static int debug;
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG args); \
-       } while (0)
-
-enum zl10039_model_id {
-       ID_ZL10039 = 1
-};
-
-struct zl10039_state {
-       struct i2c_adapter *i2c;
-       u8 i2c_addr;
-       u8 id;
-};
-
-enum zl10039_reg_addr {
-       PLL0 = 0,
-       PLL1,
-       PLL2,
-       PLL3,
-       RFFE,
-       BASE0,
-       BASE1,
-       BASE2,
-       LO0,
-       LO1,
-       LO2,
-       LO3,
-       LO4,
-       LO5,
-       LO6,
-       GENERAL
-};
-
-static int zl10039_read(const struct zl10039_state *state,
-                       const enum zl10039_reg_addr reg, u8 *buf,
-                       const size_t count)
-{
-       u8 regbuf[] = { reg };
-       struct i2c_msg msg[] = {
-               {/* Write register address */
-                       .addr = state->i2c_addr,
-                       .flags = 0,
-                       .buf = regbuf,
-                       .len = 1,
-               }, {/* Read count bytes */
-                       .addr = state->i2c_addr,
-                       .flags = I2C_M_RD,
-                       .buf = buf,
-                       .len = count,
-               },
-       };
-
-       dprintk("%s\n", __func__);
-
-       if (i2c_transfer(state->i2c, msg, 2) != 2) {
-               dprintk("%s: i2c read error\n", __func__);
-               return -EREMOTEIO;
-       }
-
-       return 0; /* Success */
-}
-
-static int zl10039_write(struct zl10039_state *state,
-                       const enum zl10039_reg_addr reg, const u8 *src,
-                       const size_t count)
-{
-       u8 buf[count + 1];
-       struct i2c_msg msg = {
-               .addr = state->i2c_addr,
-               .flags = 0,
-               .buf = buf,
-               .len = count + 1,
-       };
-
-       dprintk("%s\n", __func__);
-       /* Write register address and data in one go */
-       buf[0] = reg;
-       memcpy(&buf[1], src, count);
-       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
-               dprintk("%s: i2c write error\n", __func__);
-               return -EREMOTEIO;
-       }
-
-       return 0; /* Success */
-}
-
-static inline int zl10039_readreg(struct zl10039_state *state,
-                               const enum zl10039_reg_addr reg, u8 *val)
-{
-       return zl10039_read(state, reg, val, 1);
-}
-
-static inline int zl10039_writereg(struct zl10039_state *state,
-                               const enum zl10039_reg_addr reg,
-                               const u8 val)
-{
-       return zl10039_write(state, reg, &val, 1);
-}
-
-static int zl10039_init(struct dvb_frontend *fe)
-{
-       struct zl10039_state *state = fe->tuner_priv;
-       int ret;
-
-       dprintk("%s\n", __func__);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       /* Reset logic */
-       ret = zl10039_writereg(state, GENERAL, 0x40);
-       if (ret < 0) {
-               dprintk("Note: i2c write error normal when resetting the "
-                       "tuner\n");
-       }
-       /* Wake up */
-       ret = zl10039_writereg(state, GENERAL, 0x01);
-       if (ret < 0) {
-               dprintk("Tuner power up failed\n");
-               return ret;
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int zl10039_sleep(struct dvb_frontend *fe)
-{
-       struct zl10039_state *state = fe->tuner_priv;
-       int ret;
-
-       dprintk("%s\n", __func__);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = zl10039_writereg(state, GENERAL, 0x80);
-       if (ret < 0) {
-               dprintk("Tuner sleep failed\n");
-               return ret;
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int zl10039_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct zl10039_state *state = fe->tuner_priv;
-       u8 buf[6];
-       u8 bf;
-       u32 fbw;
-       u32 div;
-       int ret;
-
-       dprintk("%s\n", __func__);
-       dprintk("Set frequency = %d, symbol rate = %d\n",
-                       c->frequency, c->symbol_rate);
-
-       /* Assumed 10.111 MHz crystal oscillator */
-       /* Cancelled num/den 80 to prevent overflow */
-       div = (c->frequency * 1000) / 126387;
-       fbw = (c->symbol_rate * 27) / 32000;
-       /* Cancelled num/den 10 to prevent overflow */
-       bf = ((fbw * 5088) / 1011100) - 1;
-
-       /*PLL divider*/
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = (div >> 0) & 0xff;
-       /*Reference divider*/
-       /* Select reference ratio of 80 */
-       buf[2] = 0x1D;
-       /*PLL test modes*/
-       buf[3] = 0x40;
-       /*RF Control register*/
-       buf[4] = 0x6E; /* Bypass enable */
-       /*Baseband filter cutoff */
-       buf[5] = bf;
-
-       /* Open i2c gate */
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       /* BR = 10, Enable filter adjustment */
-       ret = zl10039_writereg(state, BASE1, 0x0A);
-       if (ret < 0)
-               goto error;
-       /* Write new config values */
-       ret = zl10039_write(state, PLL0, buf, sizeof(buf));
-       if (ret < 0)
-               goto error;
-       /* BR = 10, Disable filter adjustment */
-       ret = zl10039_writereg(state, BASE1, 0x6A);
-       if (ret < 0)
-               goto error;
-
-       /* Close i2c gate */
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-       return 0;
-error:
-       dprintk("Error setting tuner\n");
-       return ret;
-}
-
-static int zl10039_release(struct dvb_frontend *fe)
-{
-       struct zl10039_state *state = fe->tuner_priv;
-
-       dprintk("%s\n", __func__);
-       kfree(state);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static struct dvb_tuner_ops zl10039_ops = {
-       .release = zl10039_release,
-       .init = zl10039_init,
-       .sleep = zl10039_sleep,
-       .set_params = zl10039_set_params,
-};
-
-struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
-               u8 i2c_addr, struct i2c_adapter *i2c)
-{
-       struct zl10039_state *state = NULL;
-
-       dprintk("%s\n", __func__);
-       state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->i2c = i2c;
-       state->i2c_addr = i2c_addr;
-
-       /* Open i2c gate */
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       /* check if this is a valid tuner */
-       if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
-               /* Close i2c gate */
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-               goto error;
-       }
-       /* Close i2c gate */
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       state->id = state->id & 0x0f;
-       switch (state->id) {
-       case ID_ZL10039:
-               strcpy(fe->ops.tuner_ops.info.name,
-                       "Zarlink ZL10039 DVB-S tuner");
-               break;
-       default:
-               dprintk("Chip ID=%x does not match a known type\n", state->id);
-               goto error;
-       }
-
-       memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = state;
-       dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
-       return fe;
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL(zl10039_attach);
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
-MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10039.h b/drivers/media/dvb/frontends/zl10039.h
deleted file mode 100644 (file)
index 5eee7ea..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-    Driver for Zarlink ZL10039 DVB-S tuner
-
-    Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef ZL10039_H
-#define ZL10039_H
-
-#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
-           && defined(MODULE))
-struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
-                                       u8 i2c_addr,
-                                       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
-                                       u8 i2c_addr,
-                                       struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_ZL10039 */
-
-#endif /* ZL10039_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
deleted file mode 100644 (file)
index 82946cd..0000000
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * Driver for Zarlink DVB-T ZL10353 demodulator
- *
- * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "zl10353_priv.h"
-#include "zl10353.h"
-
-struct zl10353_state {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend frontend;
-
-       struct zl10353_config config;
-
-       u32 bandwidth;
-       u32 ucblocks;
-       u32 frequency;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "zl10353: " args); \
-       } while (0)
-
-static int debug_regs;
-
-static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
-                              .buf = buf, .len = 2 };
-       int err = i2c_transfer(state->i2c, &msg, 1);
-       if (err != 1) {
-               printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
-               return err;
-       }
-       return 0;
-}
-
-static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen)
-{
-       int err, i;
-       for (i = 0; i < ilen - 1; i++)
-               if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
-                       return err;
-
-       return 0;
-}
-
-static int zl10353_read_register(struct zl10353_state *state, u8 reg)
-{
-       int ret;
-       u8 b0[1] = { reg };
-       u8 b1[1] = { 0 };
-       struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
-                                   .flags = 0,
-                                   .buf = b0, .len = 1 },
-                                 { .addr = state->config.demod_address,
-                                   .flags = I2C_M_RD,
-                                   .buf = b1, .len = 1 } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2) {
-               printk("%s: readreg error (reg=%d, ret==%i)\n",
-                      __func__, reg, ret);
-               return ret;
-       }
-
-       return b1[0];
-}
-
-static void zl10353_dump_regs(struct dvb_frontend *fe)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       int ret;
-       u8 reg;
-
-       /* Dump all registers. */
-       for (reg = 0; ; reg++) {
-               if (reg % 16 == 0) {
-                       if (reg)
-                               printk(KERN_CONT "\n");
-                       printk(KERN_DEBUG "%02x:", reg);
-               }
-               ret = zl10353_read_register(state, reg);
-               if (ret >= 0)
-                       printk(KERN_CONT " %02x", (u8)ret);
-               else
-                       printk(KERN_CONT " --");
-               if (reg == 0xff)
-                       break;
-       }
-       printk(KERN_CONT "\n");
-}
-
-static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
-                                     u32 bandwidth,
-                                     u16 *nominal_rate)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u32 adc_clock = 450560; /* 45.056 MHz */
-       u64 value;
-       u8 bw = bandwidth / 1000000;
-
-       if (state->config.adc_clock)
-               adc_clock = state->config.adc_clock;
-
-       value = (u64)10 * (1 << 23) / 7 * 125;
-       value = (bw * value) + adc_clock / 2;
-       do_div(value, adc_clock);
-       *nominal_rate = value;
-
-       dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
-               __func__, bw, adc_clock, *nominal_rate);
-}
-
-static void zl10353_calc_input_freq(struct dvb_frontend *fe,
-                                   u16 *input_freq)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u32 adc_clock = 450560; /* 45.056  MHz */
-       int if2 = 361667;       /* 36.1667 MHz */
-       int ife;
-       u64 value;
-
-       if (state->config.adc_clock)
-               adc_clock = state->config.adc_clock;
-       if (state->config.if2)
-               if2 = state->config.if2;
-
-       if (adc_clock >= if2 * 2)
-               ife = if2;
-       else {
-               ife = adc_clock - (if2 % adc_clock);
-               if (ife > adc_clock / 2)
-                       ife = adc_clock - ife;
-       }
-       value = (u64)65536 * ife + adc_clock / 2;
-       do_div(value, adc_clock);
-       *input_freq = -value;
-
-       dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
-               __func__, if2, ife, adc_clock, -(int)value, *input_freq);
-}
-
-static int zl10353_sleep(struct dvb_frontend *fe)
-{
-       static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
-
-       zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
-       return 0;
-}
-
-static int zl10353_set_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct zl10353_state *state = fe->demodulator_priv;
-       u16 nominal_rate, input_freq;
-       u8 pllbuf[6] = { 0x67 }, acq_ctl = 0;
-       u16 tps = 0;
-
-       state->frequency = c->frequency;
-
-       zl10353_single_write(fe, RESET, 0x80);
-       udelay(200);
-       zl10353_single_write(fe, 0xEA, 0x01);
-       udelay(200);
-       zl10353_single_write(fe, 0xEA, 0x00);
-
-       zl10353_single_write(fe, AGC_TARGET, 0x28);
-
-       if (c->transmission_mode != TRANSMISSION_MODE_AUTO)
-               acq_ctl |= (1 << 0);
-       if (c->guard_interval != GUARD_INTERVAL_AUTO)
-               acq_ctl |= (1 << 1);
-       zl10353_single_write(fe, ACQ_CTL, acq_ctl);
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               /* These are extrapolated from the 7 and 8MHz values */
-               zl10353_single_write(fe, MCLK_RATIO, 0x97);
-               zl10353_single_write(fe, 0x64, 0x34);
-               zl10353_single_write(fe, 0xcc, 0xdd);
-               break;
-       case 7000000:
-               zl10353_single_write(fe, MCLK_RATIO, 0x86);
-               zl10353_single_write(fe, 0x64, 0x35);
-               zl10353_single_write(fe, 0xcc, 0x73);
-               break;
-       default:
-               c->bandwidth_hz = 8000000;
-               /* fall though */
-       case 8000000:
-               zl10353_single_write(fe, MCLK_RATIO, 0x75);
-               zl10353_single_write(fe, 0x64, 0x36);
-               zl10353_single_write(fe, 0xcc, 0x73);
-       }
-
-       zl10353_calc_nominal_rate(fe, c->bandwidth_hz, &nominal_rate);
-       zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate));
-       zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate));
-       state->bandwidth = c->bandwidth_hz;
-
-       zl10353_calc_input_freq(fe, &input_freq);
-       zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq));
-       zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq));
-
-       /* Hint at TPS settings */
-       switch (c->code_rate_HP) {
-       case FEC_2_3:
-               tps |= (1 << 7);
-               break;
-       case FEC_3_4:
-               tps |= (2 << 7);
-               break;
-       case FEC_5_6:
-               tps |= (3 << 7);
-               break;
-       case FEC_7_8:
-               tps |= (4 << 7);
-               break;
-       case FEC_1_2:
-       case FEC_AUTO:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (c->code_rate_LP) {
-       case FEC_2_3:
-               tps |= (1 << 4);
-               break;
-       case FEC_3_4:
-               tps |= (2 << 4);
-               break;
-       case FEC_5_6:
-               tps |= (3 << 4);
-               break;
-       case FEC_7_8:
-               tps |= (4 << 4);
-               break;
-       case FEC_1_2:
-       case FEC_AUTO:
-               break;
-       case FEC_NONE:
-               if (c->hierarchy == HIERARCHY_AUTO ||
-                   c->hierarchy == HIERARCHY_NONE)
-                       break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (c->modulation) {
-       case QPSK:
-               break;
-       case QAM_AUTO:
-       case QAM_16:
-               tps |= (1 << 13);
-               break;
-       case QAM_64:
-               tps |= (2 << 13);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (c->transmission_mode) {
-       case TRANSMISSION_MODE_2K:
-       case TRANSMISSION_MODE_AUTO:
-               break;
-       case TRANSMISSION_MODE_8K:
-               tps |= (1 << 0);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (c->guard_interval) {
-       case GUARD_INTERVAL_1_32:
-       case GUARD_INTERVAL_AUTO:
-               break;
-       case GUARD_INTERVAL_1_16:
-               tps |= (1 << 2);
-               break;
-       case GUARD_INTERVAL_1_8:
-               tps |= (2 << 2);
-               break;
-       case GUARD_INTERVAL_1_4:
-               tps |= (3 << 2);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (c->hierarchy) {
-       case HIERARCHY_AUTO:
-       case HIERARCHY_NONE:
-               break;
-       case HIERARCHY_1:
-               tps |= (1 << 10);
-               break;
-       case HIERARCHY_2:
-               tps |= (2 << 10);
-               break;
-       case HIERARCHY_4:
-               tps |= (3 << 10);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       zl10353_single_write(fe, TPS_GIVEN_1, msb(tps));
-       zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps));
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       /*
-        * If there is no tuner attached to the secondary I2C bus, we call
-        * set_params to program a potential tuner attached somewhere else.
-        * Otherwise, we update the PLL registers via calc_regs.
-        */
-       if (state->config.no_tuner) {
-               if (fe->ops.tuner_ops.set_params) {
-                       fe->ops.tuner_ops.set_params(fe);
-                       if (fe->ops.i2c_gate_ctrl)
-                               fe->ops.i2c_gate_ctrl(fe, 0);
-               }
-       } else if (fe->ops.tuner_ops.calc_regs) {
-               fe->ops.tuner_ops.calc_regs(fe, pllbuf + 1, 5);
-               pllbuf[1] <<= 1;
-               zl10353_write(fe, pllbuf, sizeof(pllbuf));
-       }
-
-       zl10353_single_write(fe, 0x5F, 0x13);
-
-       /* If no attached tuner or invalid PLL registers, just start the FSM. */
-       if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL)
-               zl10353_single_write(fe, FSM_GO, 0x01);
-       else
-               zl10353_single_write(fe, TUNER_GO, 0x01);
-
-       return 0;
-}
-
-static int zl10353_get_parameters(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct zl10353_state *state = fe->demodulator_priv;
-       int s6, s9;
-       u16 tps;
-       static const u8 tps_fec_to_api[8] = {
-               FEC_1_2,
-               FEC_2_3,
-               FEC_3_4,
-               FEC_5_6,
-               FEC_7_8,
-               FEC_AUTO,
-               FEC_AUTO,
-               FEC_AUTO
-       };
-
-       s6 = zl10353_read_register(state, STATUS_6);
-       s9 = zl10353_read_register(state, STATUS_9);
-       if (s6 < 0 || s9 < 0)
-               return -EREMOTEIO;
-       if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0)
-               return -EINVAL; /* no FE or TPS lock */
-
-       tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 |
-             zl10353_read_register(state, TPS_RECEIVED_0);
-
-       c->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
-       c->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
-
-       switch ((tps >> 13) & 3) {
-       case 0:
-               c->modulation = QPSK;
-               break;
-       case 1:
-               c->modulation = QAM_16;
-               break;
-       case 2:
-               c->modulation = QAM_64;
-               break;
-       default:
-               c->modulation = QAM_AUTO;
-               break;
-       }
-
-       c->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K :
-                                              TRANSMISSION_MODE_2K;
-
-       switch ((tps >> 2) & 3) {
-       case 0:
-               c->guard_interval = GUARD_INTERVAL_1_32;
-               break;
-       case 1:
-               c->guard_interval = GUARD_INTERVAL_1_16;
-               break;
-       case 2:
-               c->guard_interval = GUARD_INTERVAL_1_8;
-               break;
-       case 3:
-               c->guard_interval = GUARD_INTERVAL_1_4;
-               break;
-       default:
-               c->guard_interval = GUARD_INTERVAL_AUTO;
-               break;
-       }
-
-       switch ((tps >> 10) & 7) {
-       case 0:
-               c->hierarchy = HIERARCHY_NONE;
-               break;
-       case 1:
-               c->hierarchy = HIERARCHY_1;
-               break;
-       case 2:
-               c->hierarchy = HIERARCHY_2;
-               break;
-       case 3:
-               c->hierarchy = HIERARCHY_4;
-               break;
-       default:
-               c->hierarchy = HIERARCHY_AUTO;
-               break;
-       }
-
-       c->frequency = state->frequency;
-       c->bandwidth_hz = state->bandwidth;
-       c->inversion = INVERSION_AUTO;
-
-       return 0;
-}
-
-static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       int s6, s7, s8;
-
-       if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
-               return -EREMOTEIO;
-       if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
-               return -EREMOTEIO;
-       if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
-               return -EREMOTEIO;
-
-       *status = 0;
-       if (s6 & (1 << 2))
-               *status |= FE_HAS_CARRIER;
-       if (s6 & (1 << 1))
-               *status |= FE_HAS_VITERBI;
-       if (s6 & (1 << 5))
-               *status |= FE_HAS_LOCK;
-       if (s7 & (1 << 4))
-               *status |= FE_HAS_SYNC;
-       if (s8 & (1 << 6))
-               *status |= FE_HAS_SIGNAL;
-
-       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
-           (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
-               *status &= ~FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-
-       *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 |
-              zl10353_read_register(state, RS_ERR_CNT_1) << 8 |
-              zl10353_read_register(state, RS_ERR_CNT_0);
-
-       return 0;
-}
-
-static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-
-       u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 |
-                    zl10353_read_register(state, AGC_GAIN_0) << 2 | 3;
-
-       *strength = ~signal;
-
-       return 0;
-}
-
-static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u8 _snr;
-
-       if (debug_regs)
-               zl10353_dump_regs(fe);
-
-       _snr = zl10353_read_register(state, SNR);
-       *snr = 10 * _snr / 8;
-
-       return 0;
-}
-
-static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u32 ubl = 0;
-
-       ubl = zl10353_read_register(state, RS_UBC_1) << 8 |
-            zl10353_read_register(state, RS_UBC_0);
-
-       state->ucblocks += ubl;
-       *ucblocks = state->ucblocks;
-
-       return 0;
-}
-
-static int zl10353_get_tune_settings(struct dvb_frontend *fe,
-                                    struct dvb_frontend_tune_settings
-                                        *fe_tune_settings)
-{
-       fe_tune_settings->min_delay_ms = 1000;
-       fe_tune_settings->step_size = 0;
-       fe_tune_settings->max_drift = 0;
-
-       return 0;
-}
-
-static int zl10353_init(struct dvb_frontend *fe)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
-
-       if (debug_regs)
-               zl10353_dump_regs(fe);
-       if (state->config.parallel_ts)
-               zl10353_reset_attach[2] &= ~0x20;
-       if (state->config.clock_ctl_1)
-               zl10353_reset_attach[3] = state->config.clock_ctl_1;
-       if (state->config.pll_0)
-               zl10353_reset_attach[4] = state->config.pll_0;
-
-       /* Do a "hard" reset if not already done */
-       if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
-           zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
-               zl10353_write(fe, zl10353_reset_attach,
-                                  sizeof(zl10353_reset_attach));
-               if (debug_regs)
-                       zl10353_dump_regs(fe);
-       }
-
-       return 0;
-}
-
-static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       u8 val = 0x0a;
-
-       if (state->config.disable_i2c_gate_ctrl) {
-               /* No tuner attached to the internal I2C bus */
-               /* If set enable I2C bridge, the main I2C bus stopped hardly */
-               return 0;
-       }
-
-       if (enable)
-               val |= 0x10;
-
-       return zl10353_single_write(fe, 0x62, val);
-}
-
-static void zl10353_release(struct dvb_frontend *fe)
-{
-       struct zl10353_state *state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops zl10353_ops;
-
-struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
-                                   struct i2c_adapter *i2c)
-{
-       struct zl10353_state *state = NULL;
-       int id;
-
-       /* allocate memory for the internal state */
-       state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       /* setup the state */
-       state->i2c = i2c;
-       memcpy(&state->config, config, sizeof(struct zl10353_config));
-
-       /* check if the demod is there */
-       id = zl10353_read_register(state, CHIP_ID);
-       if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
-               goto error;
-
-       /* create dvb_frontend */
-       memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
-       state->frontend.demodulator_priv = state;
-
-       return &state->frontend;
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops zl10353_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name                   = "Zarlink ZL10353 DVB-T",
-               .frequency_min          = 174000000,
-               .frequency_max          = 862000000,
-               .frequency_stepsize     = 166667,
-               .frequency_tolerance    = 0,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
-                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-                       FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = zl10353_release,
-
-       .init = zl10353_init,
-       .sleep = zl10353_sleep,
-       .i2c_gate_ctrl = zl10353_i2c_gate_ctrl,
-       .write = zl10353_write,
-
-       .set_frontend = zl10353_set_parameters,
-       .get_frontend = zl10353_get_parameters,
-       .get_tune_settings = zl10353_get_tune_settings,
-
-       .read_status = zl10353_read_status,
-       .read_ber = zl10353_read_ber,
-       .read_signal_strength = zl10353_read_signal_strength,
-       .read_snr = zl10353_read_snr,
-       .read_ucblocks = zl10353_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-module_param(debug_regs, int, 0644);
-MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
-
-MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
-MODULE_AUTHOR("Chris Pascoe");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(zl10353_attach);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
deleted file mode 100644 (file)
index 6e3ca9e..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Driver for Zarlink DVB-T ZL10353 demodulator
- *
- *  Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef ZL10353_H
-#define ZL10353_H
-
-#include <linux/dvb/frontend.h>
-
-struct zl10353_config
-{
-       /* demodulator's I2C address */
-       u8 demod_address;
-
-       /* frequencies in units of 0.1kHz */
-       int adc_clock;  /* default: 450560 (45.056  MHz) */
-       int if2;        /* default: 361667 (36.1667 MHz) */
-
-       /* set if no pll is connected to the secondary i2c bus */
-       int no_tuner;
-
-       /* set if parallel ts output is required */
-       int parallel_ts;
-
-       /* set if i2c_gate_ctrl disable is required */
-       u8 disable_i2c_gate_ctrl:1;
-
-       /* clock control registers (0x51-0x54) */
-       u8 clock_ctl_1;  /* default: 0x46 */
-       u8 pll_0;        /* default: 0x15 */
-};
-
-#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
-extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
-                                          struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
-                                          struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_ZL10353 */
-
-#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
deleted file mode 100644 (file)
index e0dd1d3..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Driver for Zarlink DVB-T ZL10353 demodulator
- *
- *  Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _ZL10353_PRIV_
-#define _ZL10353_PRIV_
-
-#define ID_ZL10353     0x14 /* Zarlink ZL10353 */
-#define ID_CE6230      0x18 /* Intel CE6230 */
-#define ID_CE6231      0x19 /* Intel CE6231 */
-
-#define msb(x) (((x) >> 8) & 0xff)
-#define lsb(x) ((x) & 0xff)
-
-enum zl10353_reg_addr {
-       INTERRUPT_0        = 0x00,
-       INTERRUPT_1        = 0x01,
-       INTERRUPT_2        = 0x02,
-       INTERRUPT_3        = 0x03,
-       INTERRUPT_4        = 0x04,
-       INTERRUPT_5        = 0x05,
-       STATUS_6           = 0x06,
-       STATUS_7           = 0x07,
-       STATUS_8           = 0x08,
-       STATUS_9           = 0x09,
-       AGC_GAIN_1         = 0x0A,
-       AGC_GAIN_0         = 0x0B,
-       SNR                = 0x10,
-       RS_ERR_CNT_2       = 0x11,
-       RS_ERR_CNT_1       = 0x12,
-       RS_ERR_CNT_0       = 0x13,
-       RS_UBC_1           = 0x14,
-       RS_UBC_0           = 0x15,
-       TPS_RECEIVED_1     = 0x1D,
-       TPS_RECEIVED_0     = 0x1E,
-       TPS_CURRENT_1      = 0x1F,
-       TPS_CURRENT_0      = 0x20,
-       CLOCK_CTL_0        = 0x51,
-       CLOCK_CTL_1        = 0x52,
-       PLL_0              = 0x53,
-       PLL_1              = 0x54,
-       RESET              = 0x55,
-       AGC_TARGET         = 0x56,
-       MCLK_RATIO         = 0x5C,
-       ACQ_CTL            = 0x5E,
-       TRL_NOMINAL_RATE_1 = 0x65,
-       TRL_NOMINAL_RATE_0 = 0x66,
-       INPUT_FREQ_1       = 0x6C,
-       INPUT_FREQ_0       = 0x6D,
-       TPS_GIVEN_1        = 0x6E,
-       TPS_GIVEN_0        = 0x6F,
-       TUNER_GO           = 0x70,
-       FSM_GO             = 0x71,
-       CHIP_ID            = 0x7F,
-       CHAN_STEP_1        = 0xE4,
-       CHAN_STEP_0        = 0xE5,
-       OFDM_LOCK_TIME     = 0xE7,
-       FEC_LOCK_TIME      = 0xE8,
-       ACQ_DELAY          = 0xE9,
-};
-
-#endif                          /* _ZL10353_PRIV_ */
index 33841191736196c3aa16ffa71d3047bc9b5d2c48..f715051e4453bfd6a5319146d84913f5c982fe54 100644 (file)
@@ -25,4 +25,4 @@ obj-$(CONFIG_MANTIS_CORE)     += mantis_core.o
 obj-$(CONFIG_DVB_MANTIS)       += mantis.o
 obj-$(CONFIG_DVB_HOPPER)       += hopper.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
index dae76597fc3196bb860102d4d24a854a41fac3bd..63997089f9d1f09d03f194149f221b25ba1bf700 100644 (file)
@@ -7,7 +7,7 @@ ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
 obj-$(CONFIG_DVB_NGENE) += ngene.o
 
 ccflags-y += -Idrivers/media/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/common/tuners/
 
 # For the staging CI driver cxd2099
index 14fa5789c748babe1f40185d31bf7f1cf05f9dfc..524bf841f42b80b07875f6a1864b321b3af8e44e 100644 (file)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
index c80492a1039e80ba6a9dc11cb91217eae522d74c..98e391295afeb676e72c702c77cd18229a96f2c2 100644 (file)
@@ -2,4 +2,4 @@ earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
 
 obj-$(CONFIG_DVB_PT1) += earth-pt1.o
 
-ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends
index b0ddb4544cb7d8fbb54ca6bc2c14aef9f6eab1d4..22a235f3cc48264524d481edb5938e16306258d2 100644 (file)
@@ -17,5 +17,5 @@ obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
 obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
 obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/common/tuners
index c5abe78ae04f27d4e6b6a1c3037d0cb8aac05309..f47bbf62dcde131c4e2c91d981732a70b4bfb59a 100644 (file)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
index f5036d1ec7c37b1b352e638e1c29aad461819a05..74b65ea00f6371333857f75b52c61df3f499a120 100644 (file)
@@ -30,6 +30,6 @@ obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
 obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 
index 9f4b063f03dafbfe087ce28eca643074a9285d0e..98160ce77d8d2311f098cf02ee6db316f411b1c7 100644 (file)
@@ -191,5 +191,5 @@ obj-y       += davinci/
 obj-$(CONFIG_ARCH_OMAP)        += omap/
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
index 59d15b31f23fd8cf0bc60d9b68293c042258fcbb..61b69e68d950cc2b7a6ab504f60e7f1e8c7274ca 100644 (file)
@@ -4,6 +4,6 @@ obj-$(CONFIG_VIDEO_AU0828) += au0828.o
 
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
index e0701e92f4eebf2eadef8cdffe814f880019a395..db5ab12d84a3115212d664e6879d31a459d1da13 100644 (file)
@@ -9,5 +9,5 @@ obj-$(CONFIG_VIDEO_CX18) += cx18.o
 obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
 
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/common/tuners
index 2151c3d1275b3d210164679a5168a6985fecd6d4..3ba13f9aaf7c17684cbab4290b46d9a1454b468f 100644 (file)
@@ -11,5 +11,5 @@ obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb/dvb-usb
index 3608f327a4b0f237ca301318cb13c8e21caa9cf3..8f82e01a6675d87ac34c517e1cd9eeb389ab51f9 100644 (file)
@@ -10,6 +10,6 @@ obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
index 1628aa3b13fb4e1e2aafaab7d020164d082dba34..af23e0c77e1636c8bf2c26a4730786899e10d432 100644 (file)
@@ -10,4 +10,4 @@ obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
 ccflags-y := -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
index 1902366f9b81695377ddae01582f02e9d39df141..5c4d3064d4947c848ba81d677fd1af4b264d73a3 100644 (file)
@@ -13,4 +13,4 @@ obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
index b00298a02d5d095a96d072574d95e130e54d4478..f4118d23a70beb3b5ab65a431c333bfd9e7ffb1b 100644 (file)
@@ -12,4 +12,4 @@ obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
index c54cfe12e20257e4ebb6905ed2d3b4571b5fa58d..0015bd46f6674c8e340e26ded7a7044b7959f4bc 100644 (file)
@@ -10,5 +10,5 @@ obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
 ccflags-y += -I$(srctree)/drivers/media/video
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 
index 298a9306e767d5239b71196868d043ae90378544..1458797bafd209e4e8d0679a4a2c15e3bfa6f96f 100644 (file)
@@ -19,4 +19,4 @@ obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
index 364891fb8e355e0319d9a0d0b4245bb08bb7ae09..7af78a868b1935bc04ee0b7596d84dc25d28fdf4 100644 (file)
@@ -13,4 +13,4 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 ccflags-y += -I$(srctree)/drivers/media/video
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
index 50e19f943e78fe08ffb8bd0a679e14e6c81a236b..d8ed33d6b853c474d6554c997d23cfb97b36a012 100644 (file)
@@ -7,6 +7,6 @@ obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
 ccflags-y += -I$(srctree)/drivers/media/video
 ccflags-y += -I$(srctree)/drivers/media/common/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
index f0f4f6a221805c1b306dac10d3d2b5ecc4843be3..268d8251f0e974c59fe7ac237872cbffab7dd7b6 100644 (file)
@@ -5,5 +5,5 @@ obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
 ccflags-y += -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 
index b797a8a8bae4fb92bb994e9d4761e0f81d95b445..56cbcba778f633a9d7637849c999cdecde4ed88d 100644 (file)
@@ -12,4 +12,4 @@ obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
 ccflags-y := -Idrivers/media/video
 ccflags-y += -Idrivers/media/common/tuners
 ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
index b0833fa361bee10ab7482959e3540ad4db98ff2a..eb6bc595f1ac0785e513a434e3b6b4d4baf9da4b 100644 (file)
@@ -1,5 +1,5 @@
 obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
 
 ccflags-y += -Idrivers/media/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/common/tuners/
index eea1e72dfa0969397bead2d5f1b97691a73713a9..f654ddcb2c6e39030610de915727997813ff5748 100644 (file)
@@ -26,5 +26,5 @@ s2250-y := s2250-board.o
 # S2250 needs cypress ezusb loader from dvb-usb
 ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/dvb/dvb-usb
 
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/dvb-core