diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:21:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 13:21:51 -0400 |
commit | ab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (patch) | |
tree | 987ec6c263f3dfa4a7a6f9ce4d5ece47cbc12e29 /drivers/media/dvb/frontends | |
parent | f9369910a6225b8d4892c3f20ae740a711cd5ace (diff) | |
parent | 71006fb22b0f5a2045605b3887ee99a0e9adafe4 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- some V4L2 API updates needed by embedded devices
- DVB API extensions for ATSC-MH delivery system, used in US for mobile
TV
- new tuners for fc0011/0012/0013 and tua9001
- a new dvb driver for af9033/9035
- a new ATSC-MH frontend (lg2160)
- new remote controller keymaps
- Removal of a few legacy webcam driver that got replaced by gspca on
several kernel versions ago
- a new driver for Exynos 4/5 webcams(s5pp fimc-lite)
- a new webcam sensor driver (smiapp)
- a new video input driver for embedded (sta2x1xx)
- several improvements, fixes, cleanups, etc inside the drivers.
Manually fix up conflicts due to err() -> dev_err() conversion in
drivers/staging/media/easycap/easycap_main.c
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits)
[media] saa7134-cards: Remove a PCI entry added by mistake
[media] radio-sf16fmi: add support for SF16-FMD
[media] rc-loopback: remove duplicate line
[media] patch for Asus My Cinema PS3-100 (1043:48cd)
[media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS
[media] em28xx: simple comment fix
[media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2
[media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom()
[media] smiapp: Add support for 8-bit uncompressed formats
[media] smiapp: Allow generic quirk registers
[media] smiapp: Use non-binning limits if the binning limit is zero
[media] smiapp: Initialise rval in smiapp_read_nvm()
[media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check
[media] smiapp: Use 8-bit reads only before identifying the sensor
[media] smiapp: Quirk for sensors that only do 8-bit reads
[media] smiapp: Pass struct sensor to register writing commands instead of i2c_client
[media] smiapp: Allow using external clock from the clock framework
[media] zl10353: change .read_snr() to report SNR as a 0.1 dB
[media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300)
[media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try
...
Diffstat (limited to 'drivers/media/dvb/frontends')
30 files changed, 3713 insertions, 363 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 21246707fbfb..b98ebb264e29 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -531,6 +531,14 @@ config DVB_LGDT3305 | |||
531 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 531 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
532 | to support this frontend. | 532 | to support this frontend. |
533 | 533 | ||
534 | config DVB_LG2160 | ||
535 | tristate "LG Electronics LG216x based" | ||
536 | depends on DVB_CORE && I2C | ||
537 | default m if DVB_FE_CUSTOMISE | ||
538 | help | ||
539 | An ATSC/MH demodulator module. Say Y when you want | ||
540 | to support this frontend. | ||
541 | |||
534 | config DVB_S5H1409 | 542 | config DVB_S5H1409 |
535 | tristate "Samsung S5H1409 based" | 543 | tristate "Samsung S5H1409 based" |
536 | depends on DVB_CORE && I2C | 544 | depends on DVB_CORE && I2C |
@@ -540,12 +548,26 @@ config DVB_S5H1409 | |||
540 | to support this frontend. | 548 | to support this frontend. |
541 | 549 | ||
542 | config DVB_AU8522 | 550 | config DVB_AU8522 |
543 | tristate "Auvitek AU8522 based" | 551 | depends on I2C |
544 | depends on DVB_CORE && I2C && VIDEO_V4L2 | 552 | tristate |
553 | |||
554 | config DVB_AU8522_DTV | ||
555 | tristate "Auvitek AU8522 based DTV demod" | ||
556 | depends on DVB_CORE && I2C | ||
557 | select DVB_AU8522 | ||
545 | default m if DVB_FE_CUSTOMISE | 558 | default m if DVB_FE_CUSTOMISE |
546 | help | 559 | help |
547 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 560 | An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when |
548 | to support this frontend. | 561 | you want to enable DTV demodulation support for this frontend. |
562 | |||
563 | config DVB_AU8522_V4L | ||
564 | tristate "Auvitek AU8522 based ATV demod" | ||
565 | depends on VIDEO_V4L2 && I2C | ||
566 | select DVB_AU8522 | ||
567 | default m if DVB_FE_CUSTOMISE | ||
568 | help | ||
569 | An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when | ||
570 | you want to enable ATV demodulation support for this frontend. | ||
549 | 571 | ||
550 | config DVB_S5H1411 | 572 | config DVB_S5H1411 |
551 | tristate "Samsung S5H1411 based" | 573 | tristate "Samsung S5H1411 based" |
@@ -713,6 +735,11 @@ config DVB_M88RS2000 | |||
713 | A DVB-S tuner module. | 735 | A DVB-S tuner module. |
714 | Say Y when you want to support this frontend. | 736 | Say Y when you want to support this frontend. |
715 | 737 | ||
738 | config DVB_AF9033 | ||
739 | tristate "Afatech AF9033 DVB-T demodulator" | ||
740 | depends on DVB_CORE && I2C | ||
741 | default m if DVB_FE_CUSTOMISE | ||
742 | |||
716 | comment "Tools to develop new frontends" | 743 | comment "Tools to develop new frontends" |
717 | 744 | ||
718 | config DVB_DUMMY_FE | 745 | config DVB_DUMMY_FE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 86fa808bf589..cd1ac2fd5774 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -7,7 +7,6 @@ ccflags-y += -I$(srctree)/drivers/media/common/tuners/ | |||
7 | 7 | ||
8 | stb0899-objs = stb0899_drv.o stb0899_algo.o | 8 | stb0899-objs = stb0899_drv.o stb0899_algo.o |
9 | stv0900-objs = stv0900_core.o stv0900_sw.o | 9 | stv0900-objs = stv0900_core.o stv0900_sw.o |
10 | au8522-objs = au8522_dig.o au8522_decoder.o | ||
11 | drxd-objs = drxd_firm.o drxd_hard.o | 10 | drxd-objs = drxd_firm.o drxd_hard.o |
12 | cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o | 11 | cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o |
13 | drxk-objs := drxk_hard.o | 12 | drxk-objs := drxk_hard.o |
@@ -50,6 +49,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | |||
50 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 49 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
51 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 50 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
52 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o | 51 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o |
52 | obj-$(CONFIG_DVB_LG2160) += lg2160.o | ||
53 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 53 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
54 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | 54 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o |
55 | obj-$(CONFIG_DVB_LNBP22) += lnbp22.o | 55 | obj-$(CONFIG_DVB_LNBP22) += lnbp22.o |
@@ -63,7 +63,9 @@ obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o | |||
63 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 63 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
64 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o | 64 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o |
65 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o | 65 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o |
66 | obj-$(CONFIG_DVB_AU8522) += au8522.o | 66 | obj-$(CONFIG_DVB_AU8522) += au8522_common.o |
67 | obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o | ||
68 | obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o | ||
67 | obj-$(CONFIG_DVB_TDA10048) += tda10048.o | 69 | obj-$(CONFIG_DVB_TDA10048) += tda10048.o |
68 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o | 70 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o |
69 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o | 71 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o |
@@ -98,4 +100,5 @@ obj-$(CONFIG_DVB_A8293) += a8293.o | |||
98 | obj-$(CONFIG_DVB_TDA10071) += tda10071.o | 100 | obj-$(CONFIG_DVB_TDA10071) += tda10071.o |
99 | obj-$(CONFIG_DVB_RTL2830) += rtl2830.o | 101 | obj-$(CONFIG_DVB_RTL2830) += rtl2830.o |
100 | obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o | 102 | obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o |
103 | obj-$(CONFIG_DVB_AF9033) += af9033.o | ||
101 | 104 | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 6bcbcf543b38..5bc570d77846 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -514,7 +514,6 @@ err: | |||
514 | 514 | ||
515 | static void af9013_statistics_work(struct work_struct *work) | 515 | static void af9013_statistics_work(struct work_struct *work) |
516 | { | 516 | { |
517 | int ret; | ||
518 | struct af9013_state *state = container_of(work, | 517 | struct af9013_state *state = container_of(work, |
519 | struct af9013_state, statistics_work.work); | 518 | struct af9013_state, statistics_work.work); |
520 | unsigned int next_msec; | 519 | unsigned int next_msec; |
@@ -530,27 +529,27 @@ static void af9013_statistics_work(struct work_struct *work) | |||
530 | default: | 529 | default: |
531 | state->statistics_step = 0; | 530 | state->statistics_step = 0; |
532 | case 0: | 531 | case 0: |
533 | ret = af9013_statistics_signal_strength(&state->fe); | 532 | af9013_statistics_signal_strength(&state->fe); |
534 | state->statistics_step++; | 533 | state->statistics_step++; |
535 | next_msec = 300; | 534 | next_msec = 300; |
536 | break; | 535 | break; |
537 | case 1: | 536 | case 1: |
538 | ret = af9013_statistics_snr_start(&state->fe); | 537 | af9013_statistics_snr_start(&state->fe); |
539 | state->statistics_step++; | 538 | state->statistics_step++; |
540 | next_msec = 200; | 539 | next_msec = 200; |
541 | break; | 540 | break; |
542 | case 2: | 541 | case 2: |
543 | ret = af9013_statistics_ber_unc_start(&state->fe); | 542 | af9013_statistics_ber_unc_start(&state->fe); |
544 | state->statistics_step++; | 543 | state->statistics_step++; |
545 | next_msec = 1000; | 544 | next_msec = 1000; |
546 | break; | 545 | break; |
547 | case 3: | 546 | case 3: |
548 | ret = af9013_statistics_snr_result(&state->fe); | 547 | af9013_statistics_snr_result(&state->fe); |
549 | state->statistics_step++; | 548 | state->statistics_step++; |
550 | next_msec = 400; | 549 | next_msec = 400; |
551 | break; | 550 | break; |
552 | case 4: | 551 | case 4: |
553 | ret = af9013_statistics_ber_unc_result(&state->fe); | 552 | af9013_statistics_ber_unc_result(&state->fe); |
554 | state->statistics_step++; | 553 | state->statistics_step++; |
555 | next_msec = 100; | 554 | next_msec = 100; |
556 | break; | 555 | break; |
@@ -558,8 +557,6 @@ static void af9013_statistics_work(struct work_struct *work) | |||
558 | 557 | ||
559 | schedule_delayed_work(&state->statistics_work, | 558 | schedule_delayed_work(&state->statistics_work, |
560 | msecs_to_jiffies(next_msec)); | 559 | msecs_to_jiffies(next_msec)); |
561 | |||
562 | return; | ||
563 | } | 560 | } |
564 | 561 | ||
565 | static int af9013_get_tune_settings(struct dvb_frontend *fe, | 562 | static int af9013_get_tune_settings(struct dvb_frontend *fe, |
diff --git a/drivers/media/dvb/frontends/af9033.c b/drivers/media/dvb/frontends/af9033.c new file mode 100644 index 000000000000..a38998286260 --- /dev/null +++ b/drivers/media/dvb/frontends/af9033.c | |||
@@ -0,0 +1,980 @@ | |||
1 | /* | ||
2 | * Afatech AF9033 demodulator driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> | ||
5 | * Copyright (C) 2012 Antti Palosaari <crope@iki.fi> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
20 | */ | ||
21 | |||
22 | #include "af9033_priv.h" | ||
23 | |||
24 | struct af9033_state { | ||
25 | struct i2c_adapter *i2c; | ||
26 | struct dvb_frontend fe; | ||
27 | struct af9033_config cfg; | ||
28 | |||
29 | u32 bandwidth_hz; | ||
30 | bool ts_mode_parallel; | ||
31 | bool ts_mode_serial; | ||
32 | |||
33 | u32 ber; | ||
34 | u32 ucb; | ||
35 | unsigned long last_stat_check; | ||
36 | }; | ||
37 | |||
38 | /* write multiple registers */ | ||
39 | static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val, | ||
40 | int len) | ||
41 | { | ||
42 | int ret; | ||
43 | u8 buf[3 + len]; | ||
44 | struct i2c_msg msg[1] = { | ||
45 | { | ||
46 | .addr = state->cfg.i2c_addr, | ||
47 | .flags = 0, | ||
48 | .len = sizeof(buf), | ||
49 | .buf = buf, | ||
50 | } | ||
51 | }; | ||
52 | |||
53 | buf[0] = (reg >> 16) & 0xff; | ||
54 | buf[1] = (reg >> 8) & 0xff; | ||
55 | buf[2] = (reg >> 0) & 0xff; | ||
56 | memcpy(&buf[3], val, len); | ||
57 | |||
58 | ret = i2c_transfer(state->i2c, msg, 1); | ||
59 | if (ret == 1) { | ||
60 | ret = 0; | ||
61 | } else { | ||
62 | printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n", | ||
63 | __func__, ret, reg, len); | ||
64 | ret = -EREMOTEIO; | ||
65 | } | ||
66 | |||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | /* read multiple registers */ | ||
71 | static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len) | ||
72 | { | ||
73 | int ret; | ||
74 | u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff, | ||
75 | (reg >> 0) & 0xff }; | ||
76 | struct i2c_msg msg[2] = { | ||
77 | { | ||
78 | .addr = state->cfg.i2c_addr, | ||
79 | .flags = 0, | ||
80 | .len = sizeof(buf), | ||
81 | .buf = buf | ||
82 | }, { | ||
83 | .addr = state->cfg.i2c_addr, | ||
84 | .flags = I2C_M_RD, | ||
85 | .len = len, | ||
86 | .buf = val | ||
87 | } | ||
88 | }; | ||
89 | |||
90 | ret = i2c_transfer(state->i2c, msg, 2); | ||
91 | if (ret == 2) { | ||
92 | ret = 0; | ||
93 | } else { | ||
94 | printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n", | ||
95 | __func__, ret, reg, len); | ||
96 | ret = -EREMOTEIO; | ||
97 | } | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | |||
103 | /* write single register */ | ||
104 | static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val) | ||
105 | { | ||
106 | return af9033_wr_regs(state, reg, &val, 1); | ||
107 | } | ||
108 | |||
109 | /* read single register */ | ||
110 | static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val) | ||
111 | { | ||
112 | return af9033_rd_regs(state, reg, val, 1); | ||
113 | } | ||
114 | |||
115 | /* write single register with mask */ | ||
116 | static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val, | ||
117 | u8 mask) | ||
118 | { | ||
119 | int ret; | ||
120 | u8 tmp; | ||
121 | |||
122 | /* no need for read if whole reg is written */ | ||
123 | if (mask != 0xff) { | ||
124 | ret = af9033_rd_regs(state, reg, &tmp, 1); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | val &= mask; | ||
129 | tmp &= ~mask; | ||
130 | val |= tmp; | ||
131 | } | ||
132 | |||
133 | return af9033_wr_regs(state, reg, &val, 1); | ||
134 | } | ||
135 | |||
136 | /* read single register with mask */ | ||
137 | static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val, | ||
138 | u8 mask) | ||
139 | { | ||
140 | int ret, i; | ||
141 | u8 tmp; | ||
142 | |||
143 | ret = af9033_rd_regs(state, reg, &tmp, 1); | ||
144 | if (ret) | ||
145 | return ret; | ||
146 | |||
147 | tmp &= mask; | ||
148 | |||
149 | /* find position of the first bit */ | ||
150 | for (i = 0; i < 8; i++) { | ||
151 | if ((mask >> i) & 0x01) | ||
152 | break; | ||
153 | } | ||
154 | *val = tmp >> i; | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static u32 af9033_div(u32 a, u32 b, u32 x) | ||
160 | { | ||
161 | u32 r = 0, c = 0, i; | ||
162 | |||
163 | pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x); | ||
164 | |||
165 | if (a > b) { | ||
166 | c = a / b; | ||
167 | a = a - c * b; | ||
168 | } | ||
169 | |||
170 | for (i = 0; i < x; i++) { | ||
171 | if (a >= b) { | ||
172 | r += 1; | ||
173 | a -= b; | ||
174 | } | ||
175 | a <<= 1; | ||
176 | r <<= 1; | ||
177 | } | ||
178 | r = (c << (u32)x) + r; | ||
179 | |||
180 | pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r); | ||
181 | |||
182 | return r; | ||
183 | } | ||
184 | |||
185 | static void af9033_release(struct dvb_frontend *fe) | ||
186 | { | ||
187 | struct af9033_state *state = fe->demodulator_priv; | ||
188 | |||
189 | kfree(state); | ||
190 | } | ||
191 | |||
192 | static int af9033_init(struct dvb_frontend *fe) | ||
193 | { | ||
194 | struct af9033_state *state = fe->demodulator_priv; | ||
195 | int ret, i, len; | ||
196 | const struct reg_val *init; | ||
197 | u8 buf[4]; | ||
198 | u32 adc_cw, clock_cw; | ||
199 | struct reg_val_mask tab[] = { | ||
200 | { 0x80fb24, 0x00, 0x08 }, | ||
201 | { 0x80004c, 0x00, 0xff }, | ||
202 | { 0x00f641, state->cfg.tuner, 0xff }, | ||
203 | { 0x80f5ca, 0x01, 0x01 }, | ||
204 | { 0x80f715, 0x01, 0x01 }, | ||
205 | { 0x00f41f, 0x04, 0x04 }, | ||
206 | { 0x00f41a, 0x01, 0x01 }, | ||
207 | { 0x80f731, 0x00, 0x01 }, | ||
208 | { 0x00d91e, 0x00, 0x01 }, | ||
209 | { 0x00d919, 0x00, 0x01 }, | ||
210 | { 0x80f732, 0x00, 0x01 }, | ||
211 | { 0x00d91f, 0x00, 0x01 }, | ||
212 | { 0x00d91a, 0x00, 0x01 }, | ||
213 | { 0x80f730, 0x00, 0x01 }, | ||
214 | { 0x80f778, 0x00, 0xff }, | ||
215 | { 0x80f73c, 0x01, 0x01 }, | ||
216 | { 0x80f776, 0x00, 0x01 }, | ||
217 | { 0x00d8fd, 0x01, 0xff }, | ||
218 | { 0x00d830, 0x01, 0xff }, | ||
219 | { 0x00d831, 0x00, 0xff }, | ||
220 | { 0x00d832, 0x00, 0xff }, | ||
221 | { 0x80f985, state->ts_mode_serial, 0x01 }, | ||
222 | { 0x80f986, state->ts_mode_parallel, 0x01 }, | ||
223 | { 0x00d827, 0x00, 0xff }, | ||
224 | { 0x00d829, 0x00, 0xff }, | ||
225 | }; | ||
226 | |||
227 | /* program clock control */ | ||
228 | clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul); | ||
229 | buf[0] = (clock_cw >> 0) & 0xff; | ||
230 | buf[1] = (clock_cw >> 8) & 0xff; | ||
231 | buf[2] = (clock_cw >> 16) & 0xff; | ||
232 | buf[3] = (clock_cw >> 24) & 0xff; | ||
233 | |||
234 | pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock, | ||
235 | clock_cw); | ||
236 | |||
237 | ret = af9033_wr_regs(state, 0x800025, buf, 4); | ||
238 | if (ret < 0) | ||
239 | goto err; | ||
240 | |||
241 | /* program ADC control */ | ||
242 | for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) { | ||
243 | if (clock_adc_lut[i].clock == state->cfg.clock) | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul); | ||
248 | buf[0] = (adc_cw >> 0) & 0xff; | ||
249 | buf[1] = (adc_cw >> 8) & 0xff; | ||
250 | buf[2] = (adc_cw >> 16) & 0xff; | ||
251 | |||
252 | pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc, | ||
253 | adc_cw); | ||
254 | |||
255 | ret = af9033_wr_regs(state, 0x80f1cd, buf, 3); | ||
256 | if (ret < 0) | ||
257 | goto err; | ||
258 | |||
259 | /* program register table */ | ||
260 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | ||
261 | ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val, | ||
262 | tab[i].mask); | ||
263 | if (ret < 0) | ||
264 | goto err; | ||
265 | } | ||
266 | |||
267 | /* settings for TS interface */ | ||
268 | if (state->cfg.ts_mode == AF9033_TS_MODE_USB) { | ||
269 | ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01); | ||
270 | if (ret < 0) | ||
271 | goto err; | ||
272 | |||
273 | ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01); | ||
274 | if (ret < 0) | ||
275 | goto err; | ||
276 | } else { | ||
277 | ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01); | ||
278 | if (ret < 0) | ||
279 | goto err; | ||
280 | |||
281 | ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01); | ||
282 | if (ret < 0) | ||
283 | goto err; | ||
284 | } | ||
285 | |||
286 | /* load OFSM settings */ | ||
287 | pr_debug("%s: load ofsm settings\n", __func__); | ||
288 | len = ARRAY_SIZE(ofsm_init); | ||
289 | init = ofsm_init; | ||
290 | for (i = 0; i < len; i++) { | ||
291 | ret = af9033_wr_reg(state, init[i].reg, init[i].val); | ||
292 | if (ret < 0) | ||
293 | goto err; | ||
294 | } | ||
295 | |||
296 | /* load tuner specific settings */ | ||
297 | pr_debug("%s: load tuner specific settings\n", | ||
298 | __func__); | ||
299 | switch (state->cfg.tuner) { | ||
300 | case AF9033_TUNER_TUA9001: | ||
301 | len = ARRAY_SIZE(tuner_init_tua9001); | ||
302 | init = tuner_init_tua9001; | ||
303 | break; | ||
304 | case AF9033_TUNER_FC0011: | ||
305 | len = ARRAY_SIZE(tuner_init_fc0011); | ||
306 | init = tuner_init_fc0011; | ||
307 | break; | ||
308 | case AF9033_TUNER_MXL5007T: | ||
309 | len = ARRAY_SIZE(tuner_init_mxl5007t); | ||
310 | init = tuner_init_mxl5007t; | ||
311 | break; | ||
312 | case AF9033_TUNER_TDA18218: | ||
313 | len = ARRAY_SIZE(tuner_init_tda18218); | ||
314 | init = tuner_init_tda18218; | ||
315 | break; | ||
316 | default: | ||
317 | pr_debug("%s: unsupported tuner ID=%d\n", __func__, | ||
318 | state->cfg.tuner); | ||
319 | ret = -ENODEV; | ||
320 | goto err; | ||
321 | } | ||
322 | |||
323 | for (i = 0; i < len; i++) { | ||
324 | ret = af9033_wr_reg(state, init[i].reg, init[i].val); | ||
325 | if (ret < 0) | ||
326 | goto err; | ||
327 | } | ||
328 | |||
329 | state->bandwidth_hz = 0; /* force to program all parameters */ | ||
330 | |||
331 | return 0; | ||
332 | |||
333 | err: | ||
334 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
335 | |||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int af9033_sleep(struct dvb_frontend *fe) | ||
340 | { | ||
341 | struct af9033_state *state = fe->demodulator_priv; | ||
342 | int ret, i; | ||
343 | u8 tmp; | ||
344 | |||
345 | ret = af9033_wr_reg(state, 0x80004c, 1); | ||
346 | if (ret < 0) | ||
347 | goto err; | ||
348 | |||
349 | ret = af9033_wr_reg(state, 0x800000, 0); | ||
350 | if (ret < 0) | ||
351 | goto err; | ||
352 | |||
353 | for (i = 100, tmp = 1; i && tmp; i--) { | ||
354 | ret = af9033_rd_reg(state, 0x80004c, &tmp); | ||
355 | if (ret < 0) | ||
356 | goto err; | ||
357 | |||
358 | usleep_range(200, 10000); | ||
359 | } | ||
360 | |||
361 | pr_debug("%s: loop=%d\n", __func__, i); | ||
362 | |||
363 | if (i == 0) { | ||
364 | ret = -ETIMEDOUT; | ||
365 | goto err; | ||
366 | } | ||
367 | |||
368 | ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08); | ||
369 | if (ret < 0) | ||
370 | goto err; | ||
371 | |||
372 | /* prevent current leak (?) */ | ||
373 | if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) { | ||
374 | /* enable parallel TS */ | ||
375 | ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01); | ||
376 | if (ret < 0) | ||
377 | goto err; | ||
378 | |||
379 | ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01); | ||
380 | if (ret < 0) | ||
381 | goto err; | ||
382 | } | ||
383 | |||
384 | return 0; | ||
385 | |||
386 | err: | ||
387 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int af9033_get_tune_settings(struct dvb_frontend *fe, | ||
393 | struct dvb_frontend_tune_settings *fesettings) | ||
394 | { | ||
395 | fesettings->min_delay_ms = 800; | ||
396 | fesettings->step_size = 0; | ||
397 | fesettings->max_drift = 0; | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int af9033_set_frontend(struct dvb_frontend *fe) | ||
403 | { | ||
404 | struct af9033_state *state = fe->demodulator_priv; | ||
405 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
406 | int ret, i, spec_inv; | ||
407 | u8 tmp, buf[3], bandwidth_reg_val; | ||
408 | u32 if_frequency, freq_cw, adc_freq; | ||
409 | |||
410 | pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency, | ||
411 | c->bandwidth_hz); | ||
412 | |||
413 | /* check bandwidth */ | ||
414 | switch (c->bandwidth_hz) { | ||
415 | case 6000000: | ||
416 | bandwidth_reg_val = 0x00; | ||
417 | break; | ||
418 | case 7000000: | ||
419 | bandwidth_reg_val = 0x01; | ||
420 | break; | ||
421 | case 8000000: | ||
422 | bandwidth_reg_val = 0x02; | ||
423 | break; | ||
424 | default: | ||
425 | pr_debug("%s: invalid bandwidth_hz\n", __func__); | ||
426 | ret = -EINVAL; | ||
427 | goto err; | ||
428 | } | ||
429 | |||
430 | /* program tuner */ | ||
431 | if (fe->ops.tuner_ops.set_params) | ||
432 | fe->ops.tuner_ops.set_params(fe); | ||
433 | |||
434 | /* program CFOE coefficients */ | ||
435 | if (c->bandwidth_hz != state->bandwidth_hz) { | ||
436 | for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) { | ||
437 | if (coeff_lut[i].clock == state->cfg.clock && | ||
438 | coeff_lut[i].bandwidth_hz == c->bandwidth_hz) { | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | ret = af9033_wr_regs(state, 0x800001, | ||
443 | coeff_lut[i].val, sizeof(coeff_lut[i].val)); | ||
444 | } | ||
445 | |||
446 | /* program frequency control */ | ||
447 | if (c->bandwidth_hz != state->bandwidth_hz) { | ||
448 | spec_inv = state->cfg.spec_inv ? -1 : 1; | ||
449 | |||
450 | for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) { | ||
451 | if (clock_adc_lut[i].clock == state->cfg.clock) | ||
452 | break; | ||
453 | } | ||
454 | adc_freq = clock_adc_lut[i].adc; | ||
455 | |||
456 | /* get used IF frequency */ | ||
457 | if (fe->ops.tuner_ops.get_if_frequency) | ||
458 | fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); | ||
459 | else | ||
460 | if_frequency = 0; | ||
461 | |||
462 | while (if_frequency > (adc_freq / 2)) | ||
463 | if_frequency -= adc_freq; | ||
464 | |||
465 | if (if_frequency >= 0) | ||
466 | spec_inv *= -1; | ||
467 | else | ||
468 | if_frequency *= -1; | ||
469 | |||
470 | freq_cw = af9033_div(if_frequency, adc_freq, 23ul); | ||
471 | |||
472 | if (spec_inv == -1) | ||
473 | freq_cw *= -1; | ||
474 | |||
475 | /* get adc multiplies */ | ||
476 | ret = af9033_rd_reg(state, 0x800045, &tmp); | ||
477 | if (ret < 0) | ||
478 | goto err; | ||
479 | |||
480 | if (tmp == 1) | ||
481 | freq_cw /= 2; | ||
482 | |||
483 | buf[0] = (freq_cw >> 0) & 0xff; | ||
484 | buf[1] = (freq_cw >> 8) & 0xff; | ||
485 | buf[2] = (freq_cw >> 16) & 0x7f; | ||
486 | ret = af9033_wr_regs(state, 0x800029, buf, 3); | ||
487 | if (ret < 0) | ||
488 | goto err; | ||
489 | |||
490 | state->bandwidth_hz = c->bandwidth_hz; | ||
491 | } | ||
492 | |||
493 | ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03); | ||
494 | if (ret < 0) | ||
495 | goto err; | ||
496 | |||
497 | ret = af9033_wr_reg(state, 0x800040, 0x00); | ||
498 | if (ret < 0) | ||
499 | goto err; | ||
500 | |||
501 | ret = af9033_wr_reg(state, 0x800047, 0x00); | ||
502 | if (ret < 0) | ||
503 | goto err; | ||
504 | |||
505 | ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01); | ||
506 | if (ret < 0) | ||
507 | goto err; | ||
508 | |||
509 | if (c->frequency <= 230000000) | ||
510 | tmp = 0x00; /* VHF */ | ||
511 | else | ||
512 | tmp = 0x01; /* UHF */ | ||
513 | |||
514 | ret = af9033_wr_reg(state, 0x80004b, tmp); | ||
515 | if (ret < 0) | ||
516 | goto err; | ||
517 | |||
518 | ret = af9033_wr_reg(state, 0x800000, 0x00); | ||
519 | if (ret < 0) | ||
520 | goto err; | ||
521 | |||
522 | return 0; | ||
523 | |||
524 | err: | ||
525 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
526 | |||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | static int af9033_get_frontend(struct dvb_frontend *fe) | ||
531 | { | ||
532 | struct af9033_state *state = fe->demodulator_priv; | ||
533 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
534 | int ret; | ||
535 | u8 buf[8]; | ||
536 | |||
537 | pr_debug("%s\n", __func__); | ||
538 | |||
539 | /* read all needed registers */ | ||
540 | ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf)); | ||
541 | if (ret < 0) | ||
542 | goto err; | ||
543 | |||
544 | switch ((buf[0] >> 0) & 3) { | ||
545 | case 0: | ||
546 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
547 | break; | ||
548 | case 1: | ||
549 | c->transmission_mode = TRANSMISSION_MODE_8K; | ||
550 | break; | ||
551 | } | ||
552 | |||
553 | switch ((buf[1] >> 0) & 3) { | ||
554 | case 0: | ||
555 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
556 | break; | ||
557 | case 1: | ||
558 | c->guard_interval = GUARD_INTERVAL_1_16; | ||
559 | break; | ||
560 | case 2: | ||
561 | c->guard_interval = GUARD_INTERVAL_1_8; | ||
562 | break; | ||
563 | case 3: | ||
564 | c->guard_interval = GUARD_INTERVAL_1_4; | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | switch ((buf[2] >> 0) & 7) { | ||
569 | case 0: | ||
570 | c->hierarchy = HIERARCHY_NONE; | ||
571 | break; | ||
572 | case 1: | ||
573 | c->hierarchy = HIERARCHY_1; | ||
574 | break; | ||
575 | case 2: | ||
576 | c->hierarchy = HIERARCHY_2; | ||
577 | break; | ||
578 | case 3: | ||
579 | c->hierarchy = HIERARCHY_4; | ||
580 | break; | ||
581 | } | ||
582 | |||
583 | switch ((buf[3] >> 0) & 3) { | ||
584 | case 0: | ||
585 | c->modulation = QPSK; | ||
586 | break; | ||
587 | case 1: | ||
588 | c->modulation = QAM_16; | ||
589 | break; | ||
590 | case 2: | ||
591 | c->modulation = QAM_64; | ||
592 | break; | ||
593 | } | ||
594 | |||
595 | switch ((buf[4] >> 0) & 3) { | ||
596 | case 0: | ||
597 | c->bandwidth_hz = 6000000; | ||
598 | break; | ||
599 | case 1: | ||
600 | c->bandwidth_hz = 7000000; | ||
601 | break; | ||
602 | case 2: | ||
603 | c->bandwidth_hz = 8000000; | ||
604 | break; | ||
605 | } | ||
606 | |||
607 | switch ((buf[6] >> 0) & 7) { | ||
608 | case 0: | ||
609 | c->code_rate_HP = FEC_1_2; | ||
610 | break; | ||
611 | case 1: | ||
612 | c->code_rate_HP = FEC_2_3; | ||
613 | break; | ||
614 | case 2: | ||
615 | c->code_rate_HP = FEC_3_4; | ||
616 | break; | ||
617 | case 3: | ||
618 | c->code_rate_HP = FEC_5_6; | ||
619 | break; | ||
620 | case 4: | ||
621 | c->code_rate_HP = FEC_7_8; | ||
622 | break; | ||
623 | case 5: | ||
624 | c->code_rate_HP = FEC_NONE; | ||
625 | break; | ||
626 | } | ||
627 | |||
628 | switch ((buf[7] >> 0) & 7) { | ||
629 | case 0: | ||
630 | c->code_rate_LP = FEC_1_2; | ||
631 | break; | ||
632 | case 1: | ||
633 | c->code_rate_LP = FEC_2_3; | ||
634 | break; | ||
635 | case 2: | ||
636 | c->code_rate_LP = FEC_3_4; | ||
637 | break; | ||
638 | case 3: | ||
639 | c->code_rate_LP = FEC_5_6; | ||
640 | break; | ||
641 | case 4: | ||
642 | c->code_rate_LP = FEC_7_8; | ||
643 | break; | ||
644 | case 5: | ||
645 | c->code_rate_LP = FEC_NONE; | ||
646 | break; | ||
647 | } | ||
648 | |||
649 | return 0; | ||
650 | |||
651 | err: | ||
652 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
653 | |||
654 | return ret; | ||
655 | } | ||
656 | |||
657 | static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
658 | { | ||
659 | struct af9033_state *state = fe->demodulator_priv; | ||
660 | int ret; | ||
661 | u8 tmp; | ||
662 | |||
663 | *status = 0; | ||
664 | |||
665 | /* radio channel status, 0=no result, 1=has signal, 2=no signal */ | ||
666 | ret = af9033_rd_reg(state, 0x800047, &tmp); | ||
667 | if (ret < 0) | ||
668 | goto err; | ||
669 | |||
670 | /* has signal */ | ||
671 | if (tmp == 0x01) | ||
672 | *status |= FE_HAS_SIGNAL; | ||
673 | |||
674 | if (tmp != 0x02) { | ||
675 | /* TPS lock */ | ||
676 | ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01); | ||
677 | if (ret < 0) | ||
678 | goto err; | ||
679 | |||
680 | if (tmp) | ||
681 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
682 | FE_HAS_VITERBI; | ||
683 | |||
684 | /* full lock */ | ||
685 | ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01); | ||
686 | if (ret < 0) | ||
687 | goto err; | ||
688 | |||
689 | if (tmp) | ||
690 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
691 | FE_HAS_VITERBI | FE_HAS_SYNC | | ||
692 | FE_HAS_LOCK; | ||
693 | } | ||
694 | |||
695 | return 0; | ||
696 | |||
697 | err: | ||
698 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
699 | |||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
704 | { | ||
705 | struct af9033_state *state = fe->demodulator_priv; | ||
706 | int ret, i, len; | ||
707 | u8 buf[3], tmp; | ||
708 | u32 snr_val; | ||
709 | const struct val_snr *uninitialized_var(snr_lut); | ||
710 | |||
711 | /* read value */ | ||
712 | ret = af9033_rd_regs(state, 0x80002c, buf, 3); | ||
713 | if (ret < 0) | ||
714 | goto err; | ||
715 | |||
716 | snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
717 | |||
718 | /* read current modulation */ | ||
719 | ret = af9033_rd_reg(state, 0x80f903, &tmp); | ||
720 | if (ret < 0) | ||
721 | goto err; | ||
722 | |||
723 | switch ((tmp >> 0) & 3) { | ||
724 | case 0: | ||
725 | len = ARRAY_SIZE(qpsk_snr_lut); | ||
726 | snr_lut = qpsk_snr_lut; | ||
727 | break; | ||
728 | case 1: | ||
729 | len = ARRAY_SIZE(qam16_snr_lut); | ||
730 | snr_lut = qam16_snr_lut; | ||
731 | break; | ||
732 | case 2: | ||
733 | len = ARRAY_SIZE(qam64_snr_lut); | ||
734 | snr_lut = qam64_snr_lut; | ||
735 | break; | ||
736 | default: | ||
737 | goto err; | ||
738 | } | ||
739 | |||
740 | for (i = 0; i < len; i++) { | ||
741 | tmp = snr_lut[i].snr; | ||
742 | |||
743 | if (snr_val < snr_lut[i].val) | ||
744 | break; | ||
745 | } | ||
746 | |||
747 | *snr = tmp * 10; /* dB/10 */ | ||
748 | |||
749 | return 0; | ||
750 | |||
751 | err: | ||
752 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
753 | |||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
758 | { | ||
759 | struct af9033_state *state = fe->demodulator_priv; | ||
760 | int ret; | ||
761 | u8 strength2; | ||
762 | |||
763 | /* read signal strength of 0-100 scale */ | ||
764 | ret = af9033_rd_reg(state, 0x800048, &strength2); | ||
765 | if (ret < 0) | ||
766 | goto err; | ||
767 | |||
768 | /* scale value to 0x0000-0xffff */ | ||
769 | *strength = strength2 * 0xffff / 100; | ||
770 | |||
771 | return 0; | ||
772 | |||
773 | err: | ||
774 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
775 | |||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | static int af9033_update_ch_stat(struct af9033_state *state) | ||
780 | { | ||
781 | int ret = 0; | ||
782 | u32 err_cnt, bit_cnt; | ||
783 | u16 abort_cnt; | ||
784 | u8 buf[7]; | ||
785 | |||
786 | /* only update data every half second */ | ||
787 | if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) { | ||
788 | ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf)); | ||
789 | if (ret < 0) | ||
790 | goto err; | ||
791 | /* in 8 byte packets? */ | ||
792 | abort_cnt = (buf[1] << 8) + buf[0]; | ||
793 | /* in bits */ | ||
794 | err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2]; | ||
795 | /* in 8 byte packets? always(?) 0x2710 = 10000 */ | ||
796 | bit_cnt = (buf[6] << 8) + buf[5]; | ||
797 | |||
798 | if (bit_cnt < abort_cnt) { | ||
799 | abort_cnt = 1000; | ||
800 | state->ber = 0xffffffff; | ||
801 | } else { | ||
802 | /* 8 byte packets, that have not been rejected already */ | ||
803 | bit_cnt -= (u32)abort_cnt; | ||
804 | if (bit_cnt == 0) { | ||
805 | state->ber = 0xffffffff; | ||
806 | } else { | ||
807 | err_cnt -= (u32)abort_cnt * 8 * 8; | ||
808 | bit_cnt *= 8 * 8; | ||
809 | state->ber = err_cnt * (0xffffffff / bit_cnt); | ||
810 | } | ||
811 | } | ||
812 | state->ucb += abort_cnt; | ||
813 | state->last_stat_check = jiffies; | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | err: | ||
818 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
819 | return ret; | ||
820 | } | ||
821 | |||
822 | static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
823 | { | ||
824 | struct af9033_state *state = fe->demodulator_priv; | ||
825 | int ret; | ||
826 | |||
827 | ret = af9033_update_ch_stat(state); | ||
828 | if (ret < 0) | ||
829 | return ret; | ||
830 | |||
831 | *ber = state->ber; | ||
832 | |||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
837 | { | ||
838 | struct af9033_state *state = fe->demodulator_priv; | ||
839 | int ret; | ||
840 | |||
841 | ret = af9033_update_ch_stat(state); | ||
842 | if (ret < 0) | ||
843 | return ret; | ||
844 | |||
845 | *ucblocks = state->ucb; | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
851 | { | ||
852 | struct af9033_state *state = fe->demodulator_priv; | ||
853 | int ret; | ||
854 | |||
855 | pr_debug("%s: enable=%d\n", __func__, enable); | ||
856 | |||
857 | ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01); | ||
858 | if (ret < 0) | ||
859 | goto err; | ||
860 | |||
861 | return 0; | ||
862 | |||
863 | err: | ||
864 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
865 | |||
866 | return ret; | ||
867 | } | ||
868 | |||
869 | static struct dvb_frontend_ops af9033_ops; | ||
870 | |||
871 | struct dvb_frontend *af9033_attach(const struct af9033_config *config, | ||
872 | struct i2c_adapter *i2c) | ||
873 | { | ||
874 | int ret; | ||
875 | struct af9033_state *state; | ||
876 | u8 buf[8]; | ||
877 | |||
878 | pr_debug("%s:\n", __func__); | ||
879 | |||
880 | /* allocate memory for the internal state */ | ||
881 | state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL); | ||
882 | if (state == NULL) | ||
883 | goto err; | ||
884 | |||
885 | /* setup the state */ | ||
886 | state->i2c = i2c; | ||
887 | memcpy(&state->cfg, config, sizeof(struct af9033_config)); | ||
888 | |||
889 | if (state->cfg.clock != 12000000) { | ||
890 | printk(KERN_INFO "af9033: unsupported clock=%d, only " \ | ||
891 | "12000000 Hz is supported currently\n", | ||
892 | state->cfg.clock); | ||
893 | goto err; | ||
894 | } | ||
895 | |||
896 | /* firmware version */ | ||
897 | ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4); | ||
898 | if (ret < 0) | ||
899 | goto err; | ||
900 | |||
901 | ret = af9033_rd_regs(state, 0x804191, &buf[4], 4); | ||
902 | if (ret < 0) | ||
903 | goto err; | ||
904 | |||
905 | printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \ | ||
906 | "OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3], | ||
907 | buf[4], buf[5], buf[6], buf[7]); | ||
908 | |||
909 | /* configure internal TS mode */ | ||
910 | switch (state->cfg.ts_mode) { | ||
911 | case AF9033_TS_MODE_PARALLEL: | ||
912 | state->ts_mode_parallel = true; | ||
913 | break; | ||
914 | case AF9033_TS_MODE_SERIAL: | ||
915 | state->ts_mode_serial = true; | ||
916 | break; | ||
917 | case AF9033_TS_MODE_USB: | ||
918 | /* usb mode for AF9035 */ | ||
919 | default: | ||
920 | break; | ||
921 | } | ||
922 | |||
923 | /* create dvb_frontend */ | ||
924 | memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops)); | ||
925 | state->fe.demodulator_priv = state; | ||
926 | |||
927 | return &state->fe; | ||
928 | |||
929 | err: | ||
930 | kfree(state); | ||
931 | return NULL; | ||
932 | } | ||
933 | EXPORT_SYMBOL(af9033_attach); | ||
934 | |||
935 | static struct dvb_frontend_ops af9033_ops = { | ||
936 | .delsys = { SYS_DVBT }, | ||
937 | .info = { | ||
938 | .name = "Afatech AF9033 (DVB-T)", | ||
939 | .frequency_min = 174000000, | ||
940 | .frequency_max = 862000000, | ||
941 | .frequency_stepsize = 250000, | ||
942 | .frequency_tolerance = 0, | ||
943 | .caps = FE_CAN_FEC_1_2 | | ||
944 | FE_CAN_FEC_2_3 | | ||
945 | FE_CAN_FEC_3_4 | | ||
946 | FE_CAN_FEC_5_6 | | ||
947 | FE_CAN_FEC_7_8 | | ||
948 | FE_CAN_FEC_AUTO | | ||
949 | FE_CAN_QPSK | | ||
950 | FE_CAN_QAM_16 | | ||
951 | FE_CAN_QAM_64 | | ||
952 | FE_CAN_QAM_AUTO | | ||
953 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
954 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
955 | FE_CAN_HIERARCHY_AUTO | | ||
956 | FE_CAN_RECOVER | | ||
957 | FE_CAN_MUTE_TS | ||
958 | }, | ||
959 | |||
960 | .release = af9033_release, | ||
961 | |||
962 | .init = af9033_init, | ||
963 | .sleep = af9033_sleep, | ||
964 | |||
965 | .get_tune_settings = af9033_get_tune_settings, | ||
966 | .set_frontend = af9033_set_frontend, | ||
967 | .get_frontend = af9033_get_frontend, | ||
968 | |||
969 | .read_status = af9033_read_status, | ||
970 | .read_snr = af9033_read_snr, | ||
971 | .read_signal_strength = af9033_read_signal_strength, | ||
972 | .read_ber = af9033_read_ber, | ||
973 | .read_ucblocks = af9033_read_ucblocks, | ||
974 | |||
975 | .i2c_gate_ctrl = af9033_i2c_gate_ctrl, | ||
976 | }; | ||
977 | |||
978 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
979 | MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver"); | ||
980 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/af9033.h b/drivers/media/dvb/frontends/af9033.h new file mode 100644 index 000000000000..9e302c3f0f7d --- /dev/null +++ b/drivers/media/dvb/frontends/af9033.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Afatech AF9033 demodulator driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> | ||
5 | * Copyright (C) 2012 Antti Palosaari <crope@iki.fi> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef AF9033_H | ||
23 | #define AF9033_H | ||
24 | |||
25 | struct af9033_config { | ||
26 | /* | ||
27 | * I2C address | ||
28 | */ | ||
29 | u8 i2c_addr; | ||
30 | |||
31 | /* | ||
32 | * clock Hz | ||
33 | * 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000, | ||
34 | * 30000000, 36000000, 20480000, 16384000 | ||
35 | */ | ||
36 | u32 clock; | ||
37 | |||
38 | /* | ||
39 | * tuner | ||
40 | */ | ||
41 | #define AF9033_TUNER_TUA9001 0x27 /* Infineon TUA 9001 */ | ||
42 | #define AF9033_TUNER_FC0011 0x28 /* Fitipower FC0011 */ | ||
43 | #define AF9033_TUNER_MXL5007T 0xa0 /* MaxLinear MxL5007T */ | ||
44 | #define AF9033_TUNER_TDA18218 0xa1 /* NXP TDA 18218HN */ | ||
45 | u8 tuner; | ||
46 | |||
47 | /* | ||
48 | * TS settings | ||
49 | */ | ||
50 | #define AF9033_TS_MODE_USB 0 | ||
51 | #define AF9033_TS_MODE_PARALLEL 1 | ||
52 | #define AF9033_TS_MODE_SERIAL 2 | ||
53 | u8 ts_mode:2; | ||
54 | |||
55 | /* | ||
56 | * input spectrum inversion | ||
57 | */ | ||
58 | bool spec_inv; | ||
59 | }; | ||
60 | |||
61 | |||
62 | #if defined(CONFIG_DVB_AF9033) || \ | ||
63 | (defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE)) | ||
64 | extern struct dvb_frontend *af9033_attach(const struct af9033_config *config, | ||
65 | struct i2c_adapter *i2c); | ||
66 | #else | ||
67 | static inline struct dvb_frontend *af9033_attach( | ||
68 | const struct af9033_config *config, struct i2c_adapter *i2c) | ||
69 | { | ||
70 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
71 | return NULL; | ||
72 | } | ||
73 | #endif | ||
74 | |||
75 | #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 index 000000000000..0b783b9ed75e --- /dev/null +++ b/drivers/media/dvb/frontends/af9033_priv.h | |||
@@ -0,0 +1,470 @@ | |||
1 | /* | ||
2 | * Afatech AF9033 demodulator driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> | ||
5 | * Copyright (C) 2012 Antti Palosaari <crope@iki.fi> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef AF9033_PRIV_H | ||
23 | #define AF9033_PRIV_H | ||
24 | |||
25 | #include "dvb_frontend.h" | ||
26 | #include "af9033.h" | ||
27 | |||
28 | struct reg_val { | ||
29 | u32 reg; | ||
30 | u8 val; | ||
31 | }; | ||
32 | |||
33 | struct reg_val_mask { | ||
34 | u32 reg; | ||
35 | u8 val; | ||
36 | u8 mask; | ||
37 | }; | ||
38 | |||
39 | struct coeff { | ||
40 | u32 clock; | ||
41 | u32 bandwidth_hz; | ||
42 | u8 val[36]; | ||
43 | }; | ||
44 | |||
45 | struct clock_adc { | ||
46 | u32 clock; | ||
47 | u32 adc; | ||
48 | }; | ||
49 | |||
50 | struct val_snr { | ||
51 | u32 val; | ||
52 | u8 snr; | ||
53 | }; | ||
54 | |||
55 | /* Xtal clock vs. ADC clock lookup table */ | ||
56 | static const struct clock_adc clock_adc_lut[] = { | ||
57 | { 16384000, 20480000 }, | ||
58 | { 20480000, 20480000 }, | ||
59 | { 36000000, 20250000 }, | ||
60 | { 30000000, 20156250 }, | ||
61 | { 26000000, 20583333 }, | ||
62 | { 28000000, 20416667 }, | ||
63 | { 32000000, 20500000 }, | ||
64 | { 34000000, 20187500 }, | ||
65 | { 24000000, 20500000 }, | ||
66 | { 22000000, 20625000 }, | ||
67 | { 12000000, 20250000 }, | ||
68 | }; | ||
69 | |||
70 | /* pre-calculated coeff lookup table */ | ||
71 | static const struct coeff coeff_lut[] = { | ||
72 | /* 12.000 MHz */ | ||
73 | { 12000000, 8000000, { | ||
74 | 0x01, 0xce, 0x55, 0xc9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73, | ||
75 | 0x99, 0x0f, 0x00, 0x73, 0x95, 0x72, 0x00, 0x73, 0x91, 0xd5, | ||
76 | 0x00, 0x39, 0xca, 0xb9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73, | ||
77 | 0x95, 0x72, 0x37, 0x02, 0xce, 0x01 } | ||
78 | }, | ||
79 | { 12000000, 7000000, { | ||
80 | 0x01, 0x94, 0x8b, 0x10, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65, | ||
81 | 0x25, 0xed, 0x00, 0x65, 0x22, 0xc4, 0x00, 0x65, 0x1f, 0x9b, | ||
82 | 0x00, 0x32, 0x91, 0x62, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65, | ||
83 | 0x22, 0xc4, 0x88, 0x02, 0x95, 0x01 } | ||
84 | }, | ||
85 | { 12000000, 6000000, { | ||
86 | 0x01, 0x5a, 0xc0, 0x56, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56, | ||
87 | 0xb2, 0xcb, 0x00, 0x56, 0xb0, 0x15, 0x00, 0x56, 0xad, 0x60, | ||
88 | 0x00, 0x2b, 0x58, 0x0b, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56, | ||
89 | 0xb0, 0x15, 0xf4, 0x02, 0x5b, 0x01 } | ||
90 | }, | ||
91 | }; | ||
92 | |||
93 | /* QPSK SNR lookup table */ | ||
94 | static const struct val_snr qpsk_snr_lut[] = { | ||
95 | { 0x0b4771, 0 }, | ||
96 | { 0x0c1aed, 1 }, | ||
97 | { 0x0d0d27, 2 }, | ||
98 | { 0x0e4d19, 3 }, | ||
99 | { 0x0e5da8, 4 }, | ||
100 | { 0x107097, 5 }, | ||
101 | { 0x116975, 6 }, | ||
102 | { 0x1252d9, 7 }, | ||
103 | { 0x131fa4, 8 }, | ||
104 | { 0x13d5e1, 9 }, | ||
105 | { 0x148e53, 10 }, | ||
106 | { 0x15358b, 11 }, | ||
107 | { 0x15dd29, 12 }, | ||
108 | { 0x168112, 13 }, | ||
109 | { 0x170b61, 14 }, | ||
110 | { 0x17a532, 15 }, | ||
111 | { 0x180f94, 16 }, | ||
112 | { 0x186ed2, 17 }, | ||
113 | { 0x18b271, 18 }, | ||
114 | { 0x18e118, 19 }, | ||
115 | { 0x18ff4b, 20 }, | ||
116 | { 0x190af1, 21 }, | ||
117 | { 0x191451, 22 }, | ||
118 | { 0xffffff, 23 }, | ||
119 | }; | ||
120 | |||
121 | /* QAM16 SNR lookup table */ | ||
122 | static const struct val_snr qam16_snr_lut[] = { | ||
123 | { 0x04f0d5, 0 }, | ||
124 | { 0x05387a, 1 }, | ||
125 | { 0x0573a4, 2 }, | ||
126 | { 0x05a99e, 3 }, | ||
127 | { 0x05cc80, 4 }, | ||
128 | { 0x05eb62, 5 }, | ||
129 | { 0x05fecf, 6 }, | ||
130 | { 0x060b80, 7 }, | ||
131 | { 0x062501, 8 }, | ||
132 | { 0x064865, 9 }, | ||
133 | { 0x069604, 10 }, | ||
134 | { 0x06f356, 11 }, | ||
135 | { 0x07706a, 12 }, | ||
136 | { 0x0804d3, 13 }, | ||
137 | { 0x089d1a, 14 }, | ||
138 | { 0x093e3d, 15 }, | ||
139 | { 0x09e35d, 16 }, | ||
140 | { 0x0a7c3c, 17 }, | ||
141 | { 0x0afaf8, 18 }, | ||
142 | { 0x0b719d, 19 }, | ||
143 | { 0x0bda6a, 20 }, | ||
144 | { 0x0c0c75, 21 }, | ||
145 | { 0x0c3f7d, 22 }, | ||
146 | { 0x0c5e62, 23 }, | ||
147 | { 0x0c6c31, 24 }, | ||
148 | { 0x0c7925, 25 }, | ||
149 | { 0xffffff, 26 }, | ||
150 | }; | ||
151 | |||
152 | /* QAM64 SNR lookup table */ | ||
153 | static const struct val_snr qam64_snr_lut[] = { | ||
154 | { 0x0256d0, 0 }, | ||
155 | { 0x027a65, 1 }, | ||
156 | { 0x029873, 2 }, | ||
157 | { 0x02b7fe, 3 }, | ||
158 | { 0x02cf1e, 4 }, | ||
159 | { 0x02e234, 5 }, | ||
160 | { 0x02f409, 6 }, | ||
161 | { 0x030046, 7 }, | ||
162 | { 0x030844, 8 }, | ||
163 | { 0x030a02, 9 }, | ||
164 | { 0x030cde, 10 }, | ||
165 | { 0x031031, 11 }, | ||
166 | { 0x03144c, 12 }, | ||
167 | { 0x0315dd, 13 }, | ||
168 | { 0x031920, 14 }, | ||
169 | { 0x0322d0, 15 }, | ||
170 | { 0x0339fc, 16 }, | ||
171 | { 0x0364a1, 17 }, | ||
172 | { 0x038bcc, 18 }, | ||
173 | { 0x03c7d3, 19 }, | ||
174 | { 0x0408cc, 20 }, | ||
175 | { 0x043bed, 21 }, | ||
176 | { 0x048061, 22 }, | ||
177 | { 0x04be95, 23 }, | ||
178 | { 0x04fa7d, 24 }, | ||
179 | { 0x052405, 25 }, | ||
180 | { 0x05570d, 26 }, | ||
181 | { 0x059feb, 27 }, | ||
182 | { 0x05bf38, 28 }, | ||
183 | { 0xffffff, 29 }, | ||
184 | }; | ||
185 | |||
186 | static const struct reg_val ofsm_init[] = { | ||
187 | { 0x800051, 0x01 }, | ||
188 | { 0x800070, 0x0a }, | ||
189 | { 0x80007e, 0x04 }, | ||
190 | { 0x800081, 0x0a }, | ||
191 | { 0x80008a, 0x01 }, | ||
192 | { 0x80008e, 0x01 }, | ||
193 | { 0x800092, 0x06 }, | ||
194 | { 0x800099, 0x01 }, | ||
195 | { 0x80009f, 0xe1 }, | ||
196 | { 0x8000a0, 0xcf }, | ||
197 | { 0x8000a3, 0x01 }, | ||
198 | { 0x8000a5, 0x01 }, | ||
199 | { 0x8000a6, 0x01 }, | ||
200 | { 0x8000a9, 0x00 }, | ||
201 | { 0x8000aa, 0x01 }, | ||
202 | { 0x8000ab, 0x01 }, | ||
203 | { 0x8000b0, 0x01 }, | ||
204 | { 0x8000c0, 0x05 }, | ||
205 | { 0x8000c4, 0x19 }, | ||
206 | { 0x80f000, 0x0f }, | ||
207 | { 0x80f016, 0x10 }, | ||
208 | { 0x80f017, 0x04 }, | ||
209 | { 0x80f018, 0x05 }, | ||
210 | { 0x80f019, 0x04 }, | ||
211 | { 0x80f01a, 0x05 }, | ||
212 | { 0x80f021, 0x03 }, | ||
213 | { 0x80f022, 0x0a }, | ||
214 | { 0x80f023, 0x0a }, | ||
215 | { 0x80f02b, 0x00 }, | ||
216 | { 0x80f02c, 0x01 }, | ||
217 | { 0x80f064, 0x03 }, | ||
218 | { 0x80f065, 0xf9 }, | ||
219 | { 0x80f066, 0x03 }, | ||
220 | { 0x80f067, 0x01 }, | ||
221 | { 0x80f06f, 0xe0 }, | ||
222 | { 0x80f070, 0x03 }, | ||
223 | { 0x80f072, 0x0f }, | ||
224 | { 0x80f073, 0x03 }, | ||
225 | { 0x80f078, 0x00 }, | ||
226 | { 0x80f087, 0x00 }, | ||
227 | { 0x80f09b, 0x3f }, | ||
228 | { 0x80f09c, 0x00 }, | ||
229 | { 0x80f09d, 0x20 }, | ||
230 | { 0x80f09e, 0x00 }, | ||
231 | { 0x80f09f, 0x0c }, | ||
232 | { 0x80f0a0, 0x00 }, | ||
233 | { 0x80f130, 0x04 }, | ||
234 | { 0x80f132, 0x04 }, | ||
235 | { 0x80f144, 0x1a }, | ||
236 | { 0x80f146, 0x00 }, | ||
237 | { 0x80f14a, 0x01 }, | ||
238 | { 0x80f14c, 0x00 }, | ||
239 | { 0x80f14d, 0x00 }, | ||
240 | { 0x80f14f, 0x04 }, | ||
241 | { 0x80f158, 0x7f }, | ||
242 | { 0x80f15a, 0x00 }, | ||
243 | { 0x80f15b, 0x08 }, | ||
244 | { 0x80f15d, 0x03 }, | ||
245 | { 0x80f15e, 0x05 }, | ||
246 | { 0x80f163, 0x05 }, | ||
247 | { 0x80f166, 0x01 }, | ||
248 | { 0x80f167, 0x40 }, | ||
249 | { 0x80f168, 0x0f }, | ||
250 | { 0x80f17a, 0x00 }, | ||
251 | { 0x80f17b, 0x00 }, | ||
252 | { 0x80f183, 0x01 }, | ||
253 | { 0x80f19d, 0x40 }, | ||
254 | { 0x80f1bc, 0x36 }, | ||
255 | { 0x80f1bd, 0x00 }, | ||
256 | { 0x80f1cb, 0xa0 }, | ||
257 | { 0x80f1cc, 0x01 }, | ||
258 | { 0x80f204, 0x10 }, | ||
259 | { 0x80f214, 0x00 }, | ||
260 | { 0x80f40e, 0x0a }, | ||
261 | { 0x80f40f, 0x40 }, | ||
262 | { 0x80f410, 0x08 }, | ||
263 | { 0x80f55f, 0x0a }, | ||
264 | { 0x80f561, 0x15 }, | ||
265 | { 0x80f562, 0x20 }, | ||
266 | { 0x80f5df, 0xfb }, | ||
267 | { 0x80f5e0, 0x00 }, | ||
268 | { 0x80f5e3, 0x09 }, | ||
269 | { 0x80f5e4, 0x01 }, | ||
270 | { 0x80f5e5, 0x01 }, | ||
271 | { 0x80f5f8, 0x01 }, | ||
272 | { 0x80f5fd, 0x01 }, | ||
273 | { 0x80f600, 0x05 }, | ||
274 | { 0x80f601, 0x08 }, | ||
275 | { 0x80f602, 0x0b }, | ||
276 | { 0x80f603, 0x0e }, | ||
277 | { 0x80f604, 0x11 }, | ||
278 | { 0x80f605, 0x14 }, | ||
279 | { 0x80f606, 0x17 }, | ||
280 | { 0x80f607, 0x1f }, | ||
281 | { 0x80f60e, 0x00 }, | ||
282 | { 0x80f60f, 0x04 }, | ||
283 | { 0x80f610, 0x32 }, | ||
284 | { 0x80f611, 0x10 }, | ||
285 | { 0x80f707, 0xfc }, | ||
286 | { 0x80f708, 0x00 }, | ||
287 | { 0x80f709, 0x37 }, | ||
288 | { 0x80f70a, 0x00 }, | ||
289 | { 0x80f78b, 0x01 }, | ||
290 | { 0x80f80f, 0x40 }, | ||
291 | { 0x80f810, 0x54 }, | ||
292 | { 0x80f811, 0x5a }, | ||
293 | { 0x80f905, 0x01 }, | ||
294 | { 0x80fb06, 0x03 }, | ||
295 | { 0x80fd8b, 0x00 }, | ||
296 | }; | ||
297 | |||
298 | /* Infineon TUA 9001 tuner init | ||
299 | AF9033_TUNER_TUA9001 = 0x27 */ | ||
300 | static const struct reg_val tuner_init_tua9001[] = { | ||
301 | { 0x800046, 0x27 }, | ||
302 | { 0x800057, 0x00 }, | ||
303 | { 0x800058, 0x01 }, | ||
304 | { 0x80005f, 0x00 }, | ||
305 | { 0x800060, 0x00 }, | ||
306 | { 0x80006d, 0x00 }, | ||
307 | { 0x800071, 0x05 }, | ||
308 | { 0x800072, 0x02 }, | ||
309 | { 0x800074, 0x01 }, | ||
310 | { 0x800075, 0x03 }, | ||
311 | { 0x800076, 0x02 }, | ||
312 | { 0x800077, 0x00 }, | ||
313 | { 0x800078, 0x01 }, | ||
314 | { 0x800079, 0x00 }, | ||
315 | { 0x80007a, 0x7e }, | ||
316 | { 0x80007b, 0x3e }, | ||
317 | { 0x800093, 0x00 }, | ||
318 | { 0x800094, 0x01 }, | ||
319 | { 0x800095, 0x02 }, | ||
320 | { 0x800096, 0x01 }, | ||
321 | { 0x800098, 0x0a }, | ||
322 | { 0x80009b, 0x05 }, | ||
323 | { 0x80009c, 0x80 }, | ||
324 | { 0x8000b3, 0x00 }, | ||
325 | { 0x8000c1, 0x01 }, | ||
326 | { 0x8000c2, 0x00 }, | ||
327 | { 0x80f007, 0x00 }, | ||
328 | { 0x80f01f, 0x82 }, | ||
329 | { 0x80f020, 0x00 }, | ||
330 | { 0x80f029, 0x82 }, | ||
331 | { 0x80f02a, 0x00 }, | ||
332 | { 0x80f047, 0x00 }, | ||
333 | { 0x80f054, 0x00 }, | ||
334 | { 0x80f055, 0x00 }, | ||
335 | { 0x80f077, 0x01 }, | ||
336 | { 0x80f1e6, 0x00 }, | ||
337 | }; | ||
338 | |||
339 | /* Fitipower fc0011 tuner init | ||
340 | AF9033_TUNER_FC0011 = 0x28 */ | ||
341 | static const struct reg_val tuner_init_fc0011[] = { | ||
342 | { 0x800046, AF9033_TUNER_FC0011 }, | ||
343 | { 0x800057, 0x00 }, | ||
344 | { 0x800058, 0x01 }, | ||
345 | { 0x80005f, 0x00 }, | ||
346 | { 0x800060, 0x00 }, | ||
347 | { 0x800068, 0xa5 }, | ||
348 | { 0x80006e, 0x01 }, | ||
349 | { 0x800071, 0x0A }, | ||
350 | { 0x800072, 0x02 }, | ||
351 | { 0x800074, 0x01 }, | ||
352 | { 0x800079, 0x01 }, | ||
353 | { 0x800093, 0x00 }, | ||
354 | { 0x800094, 0x00 }, | ||
355 | { 0x800095, 0x00 }, | ||
356 | { 0x800096, 0x00 }, | ||
357 | { 0x80009b, 0x2D }, | ||
358 | { 0x80009c, 0x60 }, | ||
359 | { 0x80009d, 0x23 }, | ||
360 | { 0x8000a4, 0x50 }, | ||
361 | { 0x8000ad, 0x50 }, | ||
362 | { 0x8000b3, 0x01 }, | ||
363 | { 0x8000b7, 0x88 }, | ||
364 | { 0x8000b8, 0xa6 }, | ||
365 | { 0x8000c3, 0x01 }, | ||
366 | { 0x8000c4, 0x01 }, | ||
367 | { 0x8000c7, 0x69 }, | ||
368 | { 0x80F007, 0x00 }, | ||
369 | { 0x80F00A, 0x1B }, | ||
370 | { 0x80F00B, 0x1B }, | ||
371 | { 0x80F00C, 0x1B }, | ||
372 | { 0x80F00D, 0x1B }, | ||
373 | { 0x80F00E, 0xFF }, | ||
374 | { 0x80F00F, 0x01 }, | ||
375 | { 0x80F010, 0x00 }, | ||
376 | { 0x80F011, 0x02 }, | ||
377 | { 0x80F012, 0xFF }, | ||
378 | { 0x80F013, 0x01 }, | ||
379 | { 0x80F014, 0x00 }, | ||
380 | { 0x80F015, 0x02 }, | ||
381 | { 0x80F01B, 0xEF }, | ||
382 | { 0x80F01C, 0x01 }, | ||
383 | { 0x80F01D, 0x0f }, | ||
384 | { 0x80F01E, 0x02 }, | ||
385 | { 0x80F01F, 0x6E }, | ||
386 | { 0x80F020, 0x00 }, | ||
387 | { 0x80F025, 0xDE }, | ||
388 | { 0x80F026, 0x00 }, | ||
389 | { 0x80F027, 0x0A }, | ||
390 | { 0x80F028, 0x03 }, | ||
391 | { 0x80F029, 0x6E }, | ||
392 | { 0x80F02A, 0x00 }, | ||
393 | { 0x80F047, 0x00 }, | ||
394 | { 0x80F054, 0x00 }, | ||
395 | { 0x80F055, 0x00 }, | ||
396 | { 0x80F077, 0x01 }, | ||
397 | { 0x80F1E6, 0x00 }, | ||
398 | }; | ||
399 | |||
400 | /* MaxLinear MxL5007T tuner init | ||
401 | AF9033_TUNER_MXL5007T = 0xa0 */ | ||
402 | static const struct reg_val tuner_init_mxl5007t[] = { | ||
403 | { 0x800046, 0x1b }, | ||
404 | { 0x800057, 0x01 }, | ||
405 | { 0x800058, 0x01 }, | ||
406 | { 0x80005f, 0x00 }, | ||
407 | { 0x800060, 0x00 }, | ||
408 | { 0x800068, 0x96 }, | ||
409 | { 0x800071, 0x05 }, | ||
410 | { 0x800072, 0x02 }, | ||
411 | { 0x800074, 0x01 }, | ||
412 | { 0x800079, 0x01 }, | ||
413 | { 0x800093, 0x00 }, | ||
414 | { 0x800094, 0x00 }, | ||
415 | { 0x800095, 0x00 }, | ||
416 | { 0x800096, 0x00 }, | ||
417 | { 0x8000b3, 0x01 }, | ||
418 | { 0x8000c1, 0x01 }, | ||
419 | { 0x8000c2, 0x00 }, | ||
420 | { 0x80f007, 0x00 }, | ||
421 | { 0x80f00c, 0x19 }, | ||
422 | { 0x80f00d, 0x1a }, | ||
423 | { 0x80f012, 0xda }, | ||
424 | { 0x80f013, 0x00 }, | ||
425 | { 0x80f014, 0x00 }, | ||
426 | { 0x80f015, 0x02 }, | ||
427 | { 0x80f01f, 0x82 }, | ||
428 | { 0x80f020, 0x00 }, | ||
429 | { 0x80f029, 0x82 }, | ||
430 | { 0x80f02a, 0x00 }, | ||
431 | { 0x80f077, 0x02 }, | ||
432 | { 0x80f1e6, 0x00 }, | ||
433 | }; | ||
434 | |||
435 | /* NXP TDA 18218HN tuner init | ||
436 | AF9033_TUNER_TDA18218 = 0xa1 */ | ||
437 | static const struct reg_val tuner_init_tda18218[] = { | ||
438 | {0x800046, 0xa1}, | ||
439 | {0x800057, 0x01}, | ||
440 | {0x800058, 0x01}, | ||
441 | {0x80005f, 0x00}, | ||
442 | {0x800060, 0x00}, | ||
443 | {0x800071, 0x05}, | ||
444 | {0x800072, 0x02}, | ||
445 | {0x800074, 0x01}, | ||
446 | {0x800079, 0x01}, | ||
447 | {0x800093, 0x00}, | ||
448 | {0x800094, 0x00}, | ||
449 | {0x800095, 0x00}, | ||
450 | {0x800096, 0x00}, | ||
451 | {0x8000b3, 0x01}, | ||
452 | {0x8000c3, 0x01}, | ||
453 | {0x8000c4, 0x00}, | ||
454 | {0x80f007, 0x00}, | ||
455 | {0x80f00c, 0x19}, | ||
456 | {0x80f00d, 0x1a}, | ||
457 | {0x80f012, 0xda}, | ||
458 | {0x80f013, 0x00}, | ||
459 | {0x80f014, 0x00}, | ||
460 | {0x80f015, 0x02}, | ||
461 | {0x80f01f, 0x82}, | ||
462 | {0x80f020, 0x00}, | ||
463 | {0x80f029, 0x82}, | ||
464 | {0x80f02a, 0x00}, | ||
465 | {0x80f077, 0x02}, | ||
466 | {0x80f1e6, 0x00}, | ||
467 | }; | ||
468 | |||
469 | #endif /* AF9033_PRIV_H */ | ||
470 | |||
diff --git a/drivers/media/dvb/frontends/au8522_common.c b/drivers/media/dvb/frontends/au8522_common.c new file mode 100644 index 000000000000..5cfe151ee394 --- /dev/null +++ b/drivers/media/dvb/frontends/au8522_common.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | Auvitek AU8522 QAM/8VSB demodulator driver | ||
3 | |||
4 | Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> | ||
5 | Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org> | ||
6 | Copyright (C) 2005-2008 Auvitek International, Ltd. | ||
7 | Copyright (C) 2012 Michael Krufky <mkrufky@linuxtv.org> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include <linux/i2c.h> | ||
26 | #include "dvb_frontend.h" | ||
27 | #include "au8522_priv.h" | ||
28 | |||
29 | MODULE_LICENSE("GPL"); | ||
30 | |||
31 | static int debug; | ||
32 | |||
33 | #define dprintk(arg...)\ | ||
34 | do { if (debug)\ | ||
35 | printk(arg);\ | ||
36 | } while (0) | ||
37 | |||
38 | /* Despite the name "hybrid_tuner", the framework works just as well for | ||
39 | hybrid demodulators as well... */ | ||
40 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
41 | static DEFINE_MUTEX(au8522_list_mutex); | ||
42 | |||
43 | /* 16 bit registers, 8 bit values */ | ||
44 | int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) | ||
45 | { | ||
46 | int ret; | ||
47 | u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; | ||
48 | |||
49 | struct i2c_msg msg = { .addr = state->config->demod_address, | ||
50 | .flags = 0, .buf = buf, .len = 3 }; | ||
51 | |||
52 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
53 | |||
54 | if (ret != 1) | ||
55 | printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " | ||
56 | "ret == %i)\n", __func__, reg, data, ret); | ||
57 | |||
58 | return (ret != 1) ? -1 : 0; | ||
59 | } | ||
60 | EXPORT_SYMBOL(au8522_writereg); | ||
61 | |||
62 | u8 au8522_readreg(struct au8522_state *state, u16 reg) | ||
63 | { | ||
64 | int ret; | ||
65 | u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; | ||
66 | u8 b1[] = { 0 }; | ||
67 | |||
68 | struct i2c_msg msg[] = { | ||
69 | { .addr = state->config->demod_address, .flags = 0, | ||
70 | .buf = b0, .len = 2 }, | ||
71 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
72 | .buf = b1, .len = 1 } }; | ||
73 | |||
74 | ret = i2c_transfer(state->i2c, msg, 2); | ||
75 | |||
76 | if (ret != 2) | ||
77 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | ||
78 | __func__, ret); | ||
79 | return b1[0]; | ||
80 | } | ||
81 | EXPORT_SYMBOL(au8522_readreg); | ||
82 | |||
83 | int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
84 | { | ||
85 | struct au8522_state *state = fe->demodulator_priv; | ||
86 | |||
87 | dprintk("%s(%d)\n", __func__, enable); | ||
88 | |||
89 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
90 | /* We're being asked to manage the gate even though we're | ||
91 | not in digital mode. This can occur if we get switched | ||
92 | over to analog mode before the dvb_frontend kernel thread | ||
93 | has completely shutdown */ | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | if (enable) | ||
98 | return au8522_writereg(state, 0x106, 1); | ||
99 | else | ||
100 | return au8522_writereg(state, 0x106, 0); | ||
101 | } | ||
102 | EXPORT_SYMBOL(au8522_i2c_gate_ctrl); | ||
103 | |||
104 | /* Reset the demod hardware and reset all of the configuration registers | ||
105 | to a default state. */ | ||
106 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | ||
107 | u8 client_address) | ||
108 | { | ||
109 | int ret; | ||
110 | |||
111 | mutex_lock(&au8522_list_mutex); | ||
112 | ret = hybrid_tuner_request_state(struct au8522_state, (*state), | ||
113 | hybrid_tuner_instance_list, | ||
114 | i2c, client_address, "au8522"); | ||
115 | mutex_unlock(&au8522_list_mutex); | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | EXPORT_SYMBOL(au8522_get_state); | ||
120 | |||
121 | void au8522_release_state(struct au8522_state *state) | ||
122 | { | ||
123 | mutex_lock(&au8522_list_mutex); | ||
124 | if (state != NULL) | ||
125 | hybrid_tuner_release_state(state); | ||
126 | mutex_unlock(&au8522_list_mutex); | ||
127 | } | ||
128 | EXPORT_SYMBOL(au8522_release_state); | ||
129 | |||
130 | static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) | ||
131 | { | ||
132 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
133 | u8 val; | ||
134 | |||
135 | /* bail out if we can't control an LED */ | ||
136 | if (!led_config || !led_config->gpio_output || | ||
137 | !led_config->gpio_output_enable || !led_config->gpio_output_disable) | ||
138 | return 0; | ||
139 | |||
140 | val = au8522_readreg(state, 0x4000 | | ||
141 | (led_config->gpio_output & ~0xc000)); | ||
142 | if (onoff) { | ||
143 | /* enable GPIO output */ | ||
144 | val &= ~((led_config->gpio_output_enable >> 8) & 0xff); | ||
145 | val |= (led_config->gpio_output_enable & 0xff); | ||
146 | } else { | ||
147 | /* disable GPIO output */ | ||
148 | val &= ~((led_config->gpio_output_disable >> 8) & 0xff); | ||
149 | val |= (led_config->gpio_output_disable & 0xff); | ||
150 | } | ||
151 | return au8522_writereg(state, 0x8000 | | ||
152 | (led_config->gpio_output & ~0xc000), val); | ||
153 | } | ||
154 | |||
155 | /* led = 0 | off | ||
156 | * led = 1 | signal ok | ||
157 | * led = 2 | signal strong | ||
158 | * led < 0 | only light led if leds are currently off | ||
159 | */ | ||
160 | int au8522_led_ctrl(struct au8522_state *state, int led) | ||
161 | { | ||
162 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
163 | int i, ret = 0; | ||
164 | |||
165 | /* bail out if we can't control an LED */ | ||
166 | if (!led_config || !led_config->gpio_leds || | ||
167 | !led_config->num_led_states || !led_config->led_states) | ||
168 | return 0; | ||
169 | |||
170 | if (led < 0) { | ||
171 | /* if LED is already lit, then leave it as-is */ | ||
172 | if (state->led_state) | ||
173 | return 0; | ||
174 | else | ||
175 | led *= -1; | ||
176 | } | ||
177 | |||
178 | /* toggle LED if changing state */ | ||
179 | if (state->led_state != led) { | ||
180 | u8 val; | ||
181 | |||
182 | dprintk("%s: %d\n", __func__, led); | ||
183 | |||
184 | au8522_led_gpio_enable(state, 1); | ||
185 | |||
186 | val = au8522_readreg(state, 0x4000 | | ||
187 | (led_config->gpio_leds & ~0xc000)); | ||
188 | |||
189 | /* start with all leds off */ | ||
190 | for (i = 0; i < led_config->num_led_states; i++) | ||
191 | val &= ~led_config->led_states[i]; | ||
192 | |||
193 | /* set selected LED state */ | ||
194 | if (led < led_config->num_led_states) | ||
195 | val |= led_config->led_states[led]; | ||
196 | else if (led_config->num_led_states) | ||
197 | val |= | ||
198 | led_config->led_states[led_config->num_led_states - 1]; | ||
199 | |||
200 | ret = au8522_writereg(state, 0x8000 | | ||
201 | (led_config->gpio_leds & ~0xc000), val); | ||
202 | if (ret < 0) | ||
203 | return ret; | ||
204 | |||
205 | state->led_state = led; | ||
206 | |||
207 | if (led == 0) | ||
208 | au8522_led_gpio_enable(state, 0); | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | EXPORT_SYMBOL(au8522_led_ctrl); | ||
214 | |||
215 | int au8522_init(struct dvb_frontend *fe) | ||
216 | { | ||
217 | struct au8522_state *state = fe->demodulator_priv; | ||
218 | dprintk("%s()\n", __func__); | ||
219 | |||
220 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
221 | |||
222 | /* Clear out any state associated with the digital side of the | ||
223 | chip, so that when it gets powered back up it won't think | ||
224 | that it is already tuned */ | ||
225 | state->current_frequency = 0; | ||
226 | |||
227 | au8522_writereg(state, 0xa4, 1 << 5); | ||
228 | |||
229 | au8522_i2c_gate_ctrl(fe, 1); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | EXPORT_SYMBOL(au8522_init); | ||
234 | |||
235 | int au8522_sleep(struct dvb_frontend *fe) | ||
236 | { | ||
237 | struct au8522_state *state = fe->demodulator_priv; | ||
238 | dprintk("%s()\n", __func__); | ||
239 | |||
240 | /* Only power down if the digital side is currently using the chip */ | ||
241 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
242 | /* We're not in one of the expected power modes, which means | ||
243 | that the DVB thread is probably telling us to go to sleep | ||
244 | even though the analog frontend has already started using | ||
245 | the chip. So ignore the request */ | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* turn off led */ | ||
250 | au8522_led_ctrl(state, 0); | ||
251 | |||
252 | /* Power down the chip */ | ||
253 | au8522_writereg(state, 0xa4, 1 << 5); | ||
254 | |||
255 | state->current_frequency = 0; | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | EXPORT_SYMBOL(au8522_sleep); | ||
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 25f650934c73..5fc70d6cd04f 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c | |||
@@ -30,74 +30,11 @@ | |||
30 | 30 | ||
31 | static int debug; | 31 | static int debug; |
32 | 32 | ||
33 | /* Despite the name "hybrid_tuner", the framework works just as well for | ||
34 | hybrid demodulators as well... */ | ||
35 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
36 | static DEFINE_MUTEX(au8522_list_mutex); | ||
37 | |||
38 | #define dprintk(arg...)\ | 33 | #define dprintk(arg...)\ |
39 | do { if (debug)\ | 34 | do { if (debug)\ |
40 | printk(arg);\ | 35 | printk(arg);\ |
41 | } while (0) | 36 | } while (0) |
42 | 37 | ||
43 | /* 16 bit registers, 8 bit values */ | ||
44 | int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) | ||
45 | { | ||
46 | int ret; | ||
47 | u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; | ||
48 | |||
49 | struct i2c_msg msg = { .addr = state->config->demod_address, | ||
50 | .flags = 0, .buf = buf, .len = 3 }; | ||
51 | |||
52 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
53 | |||
54 | if (ret != 1) | ||
55 | printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " | ||
56 | "ret == %i)\n", __func__, reg, data, ret); | ||
57 | |||
58 | return (ret != 1) ? -1 : 0; | ||
59 | } | ||
60 | |||
61 | u8 au8522_readreg(struct au8522_state *state, u16 reg) | ||
62 | { | ||
63 | int ret; | ||
64 | u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; | ||
65 | u8 b1[] = { 0 }; | ||
66 | |||
67 | struct i2c_msg msg[] = { | ||
68 | { .addr = state->config->demod_address, .flags = 0, | ||
69 | .buf = b0, .len = 2 }, | ||
70 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
71 | .buf = b1, .len = 1 } }; | ||
72 | |||
73 | ret = i2c_transfer(state->i2c, msg, 2); | ||
74 | |||
75 | if (ret != 2) | ||
76 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | ||
77 | __func__, ret); | ||
78 | return b1[0]; | ||
79 | } | ||
80 | |||
81 | static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
82 | { | ||
83 | struct au8522_state *state = fe->demodulator_priv; | ||
84 | |||
85 | dprintk("%s(%d)\n", __func__, enable); | ||
86 | |||
87 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
88 | /* We're being asked to manage the gate even though we're | ||
89 | not in digital mode. This can occur if we get switched | ||
90 | over to analog mode before the dvb_frontend kernel thread | ||
91 | has completely shutdown */ | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | if (enable) | ||
96 | return au8522_writereg(state, 0x106, 1); | ||
97 | else | ||
98 | return au8522_writereg(state, 0x106, 0); | ||
99 | } | ||
100 | |||
101 | struct mse2snr_tab { | 38 | struct mse2snr_tab { |
102 | u16 val; | 39 | u16 val; |
103 | u16 data; | 40 | u16 data; |
@@ -609,136 +546,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe) | |||
609 | return 0; | 546 | return 0; |
610 | } | 547 | } |
611 | 548 | ||
612 | /* Reset the demod hardware and reset all of the configuration registers | ||
613 | to a default state. */ | ||
614 | int au8522_init(struct dvb_frontend *fe) | ||
615 | { | ||
616 | struct au8522_state *state = fe->demodulator_priv; | ||
617 | dprintk("%s()\n", __func__); | ||
618 | |||
619 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
620 | |||
621 | /* Clear out any state associated with the digital side of the | ||
622 | chip, so that when it gets powered back up it won't think | ||
623 | that it is already tuned */ | ||
624 | state->current_frequency = 0; | ||
625 | |||
626 | au8522_writereg(state, 0xa4, 1 << 5); | ||
627 | |||
628 | au8522_i2c_gate_ctrl(fe, 1); | ||
629 | |||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) | ||
634 | { | ||
635 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
636 | u8 val; | ||
637 | |||
638 | /* bail out if we can't control an LED */ | ||
639 | if (!led_config || !led_config->gpio_output || | ||
640 | !led_config->gpio_output_enable || !led_config->gpio_output_disable) | ||
641 | return 0; | ||
642 | |||
643 | val = au8522_readreg(state, 0x4000 | | ||
644 | (led_config->gpio_output & ~0xc000)); | ||
645 | if (onoff) { | ||
646 | /* enable GPIO output */ | ||
647 | val &= ~((led_config->gpio_output_enable >> 8) & 0xff); | ||
648 | val |= (led_config->gpio_output_enable & 0xff); | ||
649 | } else { | ||
650 | /* disable GPIO output */ | ||
651 | val &= ~((led_config->gpio_output_disable >> 8) & 0xff); | ||
652 | val |= (led_config->gpio_output_disable & 0xff); | ||
653 | } | ||
654 | return au8522_writereg(state, 0x8000 | | ||
655 | (led_config->gpio_output & ~0xc000), val); | ||
656 | } | ||
657 | |||
658 | /* led = 0 | off | ||
659 | * led = 1 | signal ok | ||
660 | * led = 2 | signal strong | ||
661 | * led < 0 | only light led if leds are currently off | ||
662 | */ | ||
663 | static int au8522_led_ctrl(struct au8522_state *state, int led) | ||
664 | { | ||
665 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
666 | int i, ret = 0; | ||
667 | |||
668 | /* bail out if we can't control an LED */ | ||
669 | if (!led_config || !led_config->gpio_leds || | ||
670 | !led_config->num_led_states || !led_config->led_states) | ||
671 | return 0; | ||
672 | |||
673 | if (led < 0) { | ||
674 | /* if LED is already lit, then leave it as-is */ | ||
675 | if (state->led_state) | ||
676 | return 0; | ||
677 | else | ||
678 | led *= -1; | ||
679 | } | ||
680 | |||
681 | /* toggle LED if changing state */ | ||
682 | if (state->led_state != led) { | ||
683 | u8 val; | ||
684 | |||
685 | dprintk("%s: %d\n", __func__, led); | ||
686 | |||
687 | au8522_led_gpio_enable(state, 1); | ||
688 | |||
689 | val = au8522_readreg(state, 0x4000 | | ||
690 | (led_config->gpio_leds & ~0xc000)); | ||
691 | |||
692 | /* start with all leds off */ | ||
693 | for (i = 0; i < led_config->num_led_states; i++) | ||
694 | val &= ~led_config->led_states[i]; | ||
695 | |||
696 | /* set selected LED state */ | ||
697 | if (led < led_config->num_led_states) | ||
698 | val |= led_config->led_states[led]; | ||
699 | else if (led_config->num_led_states) | ||
700 | val |= | ||
701 | led_config->led_states[led_config->num_led_states - 1]; | ||
702 | |||
703 | ret = au8522_writereg(state, 0x8000 | | ||
704 | (led_config->gpio_leds & ~0xc000), val); | ||
705 | if (ret < 0) | ||
706 | return ret; | ||
707 | |||
708 | state->led_state = led; | ||
709 | |||
710 | if (led == 0) | ||
711 | au8522_led_gpio_enable(state, 0); | ||
712 | } | ||
713 | |||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | int au8522_sleep(struct dvb_frontend *fe) | ||
718 | { | ||
719 | struct au8522_state *state = fe->demodulator_priv; | ||
720 | dprintk("%s()\n", __func__); | ||
721 | |||
722 | /* Only power down if the digital side is currently using the chip */ | ||
723 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
724 | /* We're not in one of the expected power modes, which means | ||
725 | that the DVB thread is probably telling us to go to sleep | ||
726 | even though the analog frontend has already started using | ||
727 | the chip. So ignore the request */ | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | /* turn off led */ | ||
732 | au8522_led_ctrl(state, 0); | ||
733 | |||
734 | /* Power down the chip */ | ||
735 | au8522_writereg(state, 0xa4, 1 << 5); | ||
736 | |||
737 | state->current_frequency = 0; | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) | 549 | static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) |
743 | { | 550 | { |
744 | struct au8522_state *state = fe->demodulator_priv; | 551 | struct au8522_state *state = fe->demodulator_priv; |
@@ -931,28 +738,6 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, | |||
931 | 738 | ||
932 | static struct dvb_frontend_ops au8522_ops; | 739 | static struct dvb_frontend_ops au8522_ops; |
933 | 740 | ||
934 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | ||
935 | u8 client_address) | ||
936 | { | ||
937 | int ret; | ||
938 | |||
939 | mutex_lock(&au8522_list_mutex); | ||
940 | ret = hybrid_tuner_request_state(struct au8522_state, (*state), | ||
941 | hybrid_tuner_instance_list, | ||
942 | i2c, client_address, "au8522"); | ||
943 | mutex_unlock(&au8522_list_mutex); | ||
944 | |||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | void au8522_release_state(struct au8522_state *state) | ||
949 | { | ||
950 | mutex_lock(&au8522_list_mutex); | ||
951 | if (state != NULL) | ||
952 | hybrid_tuner_release_state(state); | ||
953 | mutex_unlock(&au8522_list_mutex); | ||
954 | } | ||
955 | |||
956 | 741 | ||
957 | static void au8522_release(struct dvb_frontend *fe) | 742 | static void au8522_release(struct dvb_frontend *fe) |
958 | { | 743 | { |
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h index 751e17d692a9..6e4a438732b5 100644 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ b/drivers/media/dvb/frontends/au8522_priv.h | |||
@@ -81,6 +81,8 @@ int au8522_sleep(struct dvb_frontend *fe); | |||
81 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | 81 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, |
82 | u8 client_address); | 82 | u8 client_address); |
83 | void au8522_release_state(struct au8522_state *state); | 83 | void au8522_release_state(struct au8522_state *state); |
84 | int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable); | ||
85 | int au8522_led_ctrl(struct au8522_state *state, int led); | ||
84 | 86 | ||
85 | /* REGISTERS */ | 87 | /* REGISTERS */ |
86 | #define AU8522_INPUT_CONTROL_REG081H 0x081 | 88 | #define AU8522_INPUT_CONTROL_REG081H 0x081 |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 5101f10f2d7a..98ecaf0900d6 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -512,14 +512,13 @@ static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) | |||
512 | static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 512 | static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
513 | { | 513 | { |
514 | struct cx24110_state *state = fe->demodulator_priv; | 514 | struct cx24110_state *state = fe->demodulator_priv; |
515 | u32 lastbyer; | ||
516 | 515 | ||
517 | if(cx24110_readreg(state,0x10)&0x40) { | 516 | if(cx24110_readreg(state,0x10)&0x40) { |
518 | /* the RS error counter has finished one counting window */ | 517 | /* the RS error counter has finished one counting window */ |
519 | cx24110_writereg(state,0x10,0x60); /* select the byer reg */ | 518 | cx24110_writereg(state,0x10,0x60); /* select the byer reg */ |
520 | lastbyer=cx24110_readreg(state,0x12)| | 519 | cx24110_readreg(state, 0x12) | |
521 | (cx24110_readreg(state,0x13)<<8)| | 520 | (cx24110_readreg(state, 0x13) << 8) | |
522 | (cx24110_readreg(state,0x14)<<16); | 521 | (cx24110_readreg(state, 0x14) << 16); |
523 | cx24110_writereg(state,0x10,0x70); /* select the bler reg */ | 522 | cx24110_writereg(state,0x10,0x70); /* select the bler reg */ |
524 | state->lastbler=cx24110_readreg(state,0x12)| | 523 | state->lastbler=cx24110_readreg(state,0x12)| |
525 | (cx24110_readreg(state,0x13)<<8)| | 524 | (cx24110_readreg(state,0x13)<<8)| |
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 5c7c2aaf9bf5..3bba37d74f57 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c | |||
@@ -526,12 +526,12 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
526 | if (ret) | 526 | if (ret) |
527 | goto error; | 527 | goto error; |
528 | 528 | ||
529 | if (status & FE_HAS_SIGNAL) | 529 | if (status & FE_HAS_LOCK) |
530 | break; | 530 | break; |
531 | } | 531 | } |
532 | 532 | ||
533 | /* check if we have a valid signal */ | 533 | /* check if we have a valid signal */ |
534 | if (status) { | 534 | if (status & FE_HAS_LOCK) { |
535 | priv->last_tune_failed = 0; | 535 | priv->last_tune_failed = 0; |
536 | return DVBFE_ALGO_SEARCH_SUCCESS; | 536 | return DVBFE_ALGO_SEARCH_SUCCESS; |
537 | } else { | 537 | } else { |
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 5ceadc285b3a..3e1eefada0e8 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c | |||
@@ -2396,11 +2396,6 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, | |||
2396 | more common) */ | 2396 | more common) */ |
2397 | st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; | 2397 | st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; |
2398 | 2398 | ||
2399 | /* FIXME: make sure the dev.parent field is initialized, or else | ||
2400 | request_firmware() will hit an OOPS (this should be moved somewhere | ||
2401 | more common) */ | ||
2402 | st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; | ||
2403 | |||
2404 | dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); | 2399 | dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); |
2405 | 2400 | ||
2406 | /* init 7090 tuner adapter */ | 2401 | /* init 7090 tuner adapter */ |
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index 80848b4c15d4..6201c59a78dd 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c | |||
@@ -31,13 +31,6 @@ struct i2c_device { | |||
31 | u8 *i2c_write_buffer; | 31 | u8 *i2c_write_buffer; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | /* lock */ | ||
35 | #define DIB_LOCK struct mutex | ||
36 | #define DibAcquireLock(lock) mutex_lock_interruptible(lock) | ||
37 | #define DibReleaseLock(lock) mutex_unlock(lock) | ||
38 | #define DibInitLock(lock) mutex_init(lock) | ||
39 | #define DibFreeLock(lock) | ||
40 | |||
41 | struct dib9000_pid_ctrl { | 34 | struct dib9000_pid_ctrl { |
42 | #define DIB9000_PID_FILTER_CTRL 0 | 35 | #define DIB9000_PID_FILTER_CTRL 0 |
43 | #define DIB9000_PID_FILTER 1 | 36 | #define DIB9000_PID_FILTER 1 |
@@ -82,11 +75,11 @@ struct dib9000_state { | |||
82 | } fe_mm[18]; | 75 | } fe_mm[18]; |
83 | u8 memcmd; | 76 | u8 memcmd; |
84 | 77 | ||
85 | DIB_LOCK mbx_if_lock; /* to protect read/write operations */ | 78 | struct mutex mbx_if_lock; /* to protect read/write operations */ |
86 | DIB_LOCK mbx_lock; /* to protect the whole mailbox handling */ | 79 | struct mutex mbx_lock; /* to protect the whole mailbox handling */ |
87 | 80 | ||
88 | DIB_LOCK mem_lock; /* to protect the memory accesses */ | 81 | struct mutex mem_lock; /* to protect the memory accesses */ |
89 | DIB_LOCK mem_mbx_lock; /* to protect the memory-based mailbox */ | 82 | struct mutex mem_mbx_lock; /* to protect the memory-based mailbox */ |
90 | 83 | ||
91 | #define MBX_MAX_WORDS (256 - 200 - 2) | 84 | #define MBX_MAX_WORDS (256 - 200 - 2) |
92 | #define DIB9000_MSG_CACHE_SIZE 2 | 85 | #define DIB9000_MSG_CACHE_SIZE 2 |
@@ -108,7 +101,7 @@ struct dib9000_state { | |||
108 | struct i2c_msg msg[2]; | 101 | struct i2c_msg msg[2]; |
109 | u8 i2c_write_buffer[255]; | 102 | u8 i2c_write_buffer[255]; |
110 | u8 i2c_read_buffer[255]; | 103 | u8 i2c_read_buffer[255]; |
111 | DIB_LOCK demod_lock; | 104 | struct mutex demod_lock; |
112 | u8 get_frontend_internal; | 105 | u8 get_frontend_internal; |
113 | struct dib9000_pid_ctrl pid_ctrl[10]; | 106 | struct dib9000_pid_ctrl pid_ctrl[10]; |
114 | s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */ | 107 | s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */ |
@@ -446,13 +439,13 @@ static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u1 | |||
446 | if (!state->platform.risc.fw_is_running) | 439 | if (!state->platform.risc.fw_is_running) |
447 | return -EIO; | 440 | return -EIO; |
448 | 441 | ||
449 | if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { | 442 | if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) { |
450 | dprintk("could not get the lock"); | 443 | dprintk("could not get the lock"); |
451 | return -EINTR; | 444 | return -EINTR; |
452 | } | 445 | } |
453 | dib9000_risc_mem_setup(state, cmd | 0x80); | 446 | dib9000_risc_mem_setup(state, cmd | 0x80); |
454 | dib9000_risc_mem_read_chunks(state, b, len); | 447 | dib9000_risc_mem_read_chunks(state, b, len); |
455 | DibReleaseLock(&state->platform.risc.mem_lock); | 448 | mutex_unlock(&state->platform.risc.mem_lock); |
456 | return 0; | 449 | return 0; |
457 | } | 450 | } |
458 | 451 | ||
@@ -462,13 +455,13 @@ static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 | |||
462 | if (!state->platform.risc.fw_is_running) | 455 | if (!state->platform.risc.fw_is_running) |
463 | return -EIO; | 456 | return -EIO; |
464 | 457 | ||
465 | if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { | 458 | if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) { |
466 | dprintk("could not get the lock"); | 459 | dprintk("could not get the lock"); |
467 | return -EINTR; | 460 | return -EINTR; |
468 | } | 461 | } |
469 | dib9000_risc_mem_setup(state, cmd); | 462 | dib9000_risc_mem_setup(state, cmd); |
470 | dib9000_risc_mem_write_chunks(state, b, m->size); | 463 | dib9000_risc_mem_write_chunks(state, b, m->size); |
471 | DibReleaseLock(&state->platform.risc.mem_lock); | 464 | mutex_unlock(&state->platform.risc.mem_lock); |
472 | return 0; | 465 | return 0; |
473 | } | 466 | } |
474 | 467 | ||
@@ -537,7 +530,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, | |||
537 | if (!state->platform.risc.fw_is_running) | 530 | if (!state->platform.risc.fw_is_running) |
538 | return -EINVAL; | 531 | return -EINVAL; |
539 | 532 | ||
540 | if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { | 533 | if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) { |
541 | dprintk("could not get the lock"); | 534 | dprintk("could not get the lock"); |
542 | return -EINTR; | 535 | return -EINTR; |
543 | } | 536 | } |
@@ -584,7 +577,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, | |||
584 | ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr); | 577 | ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr); |
585 | 578 | ||
586 | out: | 579 | out: |
587 | DibReleaseLock(&state->platform.risc.mbx_if_lock); | 580 | mutex_unlock(&state->platform.risc.mbx_if_lock); |
588 | 581 | ||
589 | return ret; | 582 | return ret; |
590 | } | 583 | } |
@@ -602,7 +595,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, | |||
602 | if (!state->platform.risc.fw_is_running) | 595 | if (!state->platform.risc.fw_is_running) |
603 | return 0; | 596 | return 0; |
604 | 597 | ||
605 | if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { | 598 | if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) { |
606 | dprintk("could not get the lock"); | 599 | dprintk("could not get the lock"); |
607 | return 0; | 600 | return 0; |
608 | } | 601 | } |
@@ -643,7 +636,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, | |||
643 | /* Update register nb_mes_in_TX */ | 636 | /* Update register nb_mes_in_TX */ |
644 | dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr); | 637 | dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr); |
645 | 638 | ||
646 | DibReleaseLock(&state->platform.risc.mbx_if_lock); | 639 | mutex_unlock(&state->platform.risc.mbx_if_lock); |
647 | 640 | ||
648 | return size + 1; | 641 | return size + 1; |
649 | } | 642 | } |
@@ -708,12 +701,11 @@ static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr) | |||
708 | static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) | 701 | static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) |
709 | { | 702 | { |
710 | int ret = 0; | 703 | int ret = 0; |
711 | u16 tmp; | ||
712 | 704 | ||
713 | if (!state->platform.risc.fw_is_running) | 705 | if (!state->platform.risc.fw_is_running) |
714 | return -1; | 706 | return -1; |
715 | 707 | ||
716 | if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) { | 708 | if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) { |
717 | dprintk("could not get the lock"); | 709 | dprintk("could not get the lock"); |
718 | return -1; | 710 | return -1; |
719 | } | 711 | } |
@@ -721,10 +713,10 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) | |||
721 | if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ | 713 | if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ |
722 | ret = dib9000_mbx_fetch_to_cache(state, attr); | 714 | ret = dib9000_mbx_fetch_to_cache(state, attr); |
723 | 715 | ||
724 | tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */ | 716 | dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */ |
725 | /* if (tmp) */ | 717 | /* if (tmp) */ |
726 | /* dprintk( "cleared IRQ: %x", tmp); */ | 718 | /* dprintk( "cleared IRQ: %x", tmp); */ |
727 | DibReleaseLock(&state->platform.risc.mbx_lock); | 719 | mutex_unlock(&state->platform.risc.mbx_lock); |
728 | 720 | ||
729 | return ret; | 721 | return ret; |
730 | } | 722 | } |
@@ -1193,7 +1185,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe) | |||
1193 | struct dibDVBTChannel *ch; | 1185 | struct dibDVBTChannel *ch; |
1194 | int ret = 0; | 1186 | int ret = 0; |
1195 | 1187 | ||
1196 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 1188 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
1197 | dprintk("could not get the lock"); | 1189 | dprintk("could not get the lock"); |
1198 | return -EINTR; | 1190 | return -EINTR; |
1199 | } | 1191 | } |
@@ -1323,7 +1315,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe) | |||
1323 | } | 1315 | } |
1324 | 1316 | ||
1325 | error: | 1317 | error: |
1326 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 1318 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
1327 | return ret; | 1319 | return ret; |
1328 | } | 1320 | } |
1329 | 1321 | ||
@@ -1678,7 +1670,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2 | |||
1678 | p[12] = 0; | 1670 | p[12] = 0; |
1679 | } | 1671 | } |
1680 | 1672 | ||
1681 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 1673 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
1682 | dprintk("could not get the lock"); | 1674 | dprintk("could not get the lock"); |
1683 | return 0; | 1675 | return 0; |
1684 | } | 1676 | } |
@@ -1692,7 +1684,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2 | |||
1692 | 1684 | ||
1693 | /* do the transaction */ | 1685 | /* do the transaction */ |
1694 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) { | 1686 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) { |
1695 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 1687 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
1696 | return 0; | 1688 | return 0; |
1697 | } | 1689 | } |
1698 | 1690 | ||
@@ -1700,7 +1692,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2 | |||
1700 | if ((num > 1) && (msg[1].flags & I2C_M_RD)) | 1692 | if ((num > 1) && (msg[1].flags & I2C_M_RD)) |
1701 | dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len); | 1693 | dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len); |
1702 | 1694 | ||
1703 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 1695 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
1704 | 1696 | ||
1705 | return num; | 1697 | return num; |
1706 | } | 1698 | } |
@@ -1789,7 +1781,7 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) | |||
1789 | return 0; | 1781 | return 0; |
1790 | } | 1782 | } |
1791 | 1783 | ||
1792 | if (DibAcquireLock(&state->demod_lock) < 0) { | 1784 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
1793 | dprintk("could not get the lock"); | 1785 | dprintk("could not get the lock"); |
1794 | return -EINTR; | 1786 | return -EINTR; |
1795 | } | 1787 | } |
@@ -1799,7 +1791,7 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) | |||
1799 | 1791 | ||
1800 | dprintk("PID filter enabled %d", onoff); | 1792 | dprintk("PID filter enabled %d", onoff); |
1801 | ret = dib9000_write_word(state, 294 + 1, val); | 1793 | ret = dib9000_write_word(state, 294 + 1, val); |
1802 | DibReleaseLock(&state->demod_lock); | 1794 | mutex_unlock(&state->demod_lock); |
1803 | return ret; | 1795 | return ret; |
1804 | 1796 | ||
1805 | } | 1797 | } |
@@ -1824,14 +1816,14 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) | |||
1824 | return 0; | 1816 | return 0; |
1825 | } | 1817 | } |
1826 | 1818 | ||
1827 | if (DibAcquireLock(&state->demod_lock) < 0) { | 1819 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
1828 | dprintk("could not get the lock"); | 1820 | dprintk("could not get the lock"); |
1829 | return -EINTR; | 1821 | return -EINTR; |
1830 | } | 1822 | } |
1831 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); | 1823 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); |
1832 | ret = dib9000_write_word(state, 300 + 1 + id, | 1824 | ret = dib9000_write_word(state, 300 + 1 + id, |
1833 | onoff ? (1 << 13) | pid : 0); | 1825 | onoff ? (1 << 13) | pid : 0); |
1834 | DibReleaseLock(&state->demod_lock); | 1826 | mutex_unlock(&state->demod_lock); |
1835 | return ret; | 1827 | return ret; |
1836 | } | 1828 | } |
1837 | EXPORT_SYMBOL(dib9000_fw_pid_filter); | 1829 | EXPORT_SYMBOL(dib9000_fw_pid_filter); |
@@ -1851,11 +1843,6 @@ static void dib9000_release(struct dvb_frontend *demod) | |||
1851 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) | 1843 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) |
1852 | dvb_frontend_detach(st->fe[index_frontend]); | 1844 | dvb_frontend_detach(st->fe[index_frontend]); |
1853 | 1845 | ||
1854 | DibFreeLock(&state->platform.risc.mbx_if_lock); | ||
1855 | DibFreeLock(&state->platform.risc.mbx_lock); | ||
1856 | DibFreeLock(&state->platform.risc.mem_lock); | ||
1857 | DibFreeLock(&state->platform.risc.mem_mbx_lock); | ||
1858 | DibFreeLock(&state->demod_lock); | ||
1859 | dibx000_exit_i2c_master(&st->i2c_master); | 1846 | dibx000_exit_i2c_master(&st->i2c_master); |
1860 | 1847 | ||
1861 | i2c_del_adapter(&st->tuner_adap); | 1848 | i2c_del_adapter(&st->tuner_adap); |
@@ -1875,7 +1862,7 @@ static int dib9000_sleep(struct dvb_frontend *fe) | |||
1875 | u8 index_frontend; | 1862 | u8 index_frontend; |
1876 | int ret = 0; | 1863 | int ret = 0; |
1877 | 1864 | ||
1878 | if (DibAcquireLock(&state->demod_lock) < 0) { | 1865 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
1879 | dprintk("could not get the lock"); | 1866 | dprintk("could not get the lock"); |
1880 | return -EINTR; | 1867 | return -EINTR; |
1881 | } | 1868 | } |
@@ -1887,7 +1874,7 @@ static int dib9000_sleep(struct dvb_frontend *fe) | |||
1887 | ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0); | 1874 | ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0); |
1888 | 1875 | ||
1889 | error: | 1876 | error: |
1890 | DibReleaseLock(&state->demod_lock); | 1877 | mutex_unlock(&state->demod_lock); |
1891 | return ret; | 1878 | return ret; |
1892 | } | 1879 | } |
1893 | 1880 | ||
@@ -1905,7 +1892,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe) | |||
1905 | int ret = 0; | 1892 | int ret = 0; |
1906 | 1893 | ||
1907 | if (state->get_frontend_internal == 0) { | 1894 | if (state->get_frontend_internal == 0) { |
1908 | if (DibAcquireLock(&state->demod_lock) < 0) { | 1895 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
1909 | dprintk("could not get the lock"); | 1896 | dprintk("could not get the lock"); |
1910 | return -EINTR; | 1897 | return -EINTR; |
1911 | } | 1898 | } |
@@ -1964,7 +1951,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe) | |||
1964 | 1951 | ||
1965 | return_value: | 1952 | return_value: |
1966 | if (state->get_frontend_internal == 0) | 1953 | if (state->get_frontend_internal == 0) |
1967 | DibReleaseLock(&state->demod_lock); | 1954 | mutex_unlock(&state->demod_lock); |
1968 | return ret; | 1955 | return ret; |
1969 | } | 1956 | } |
1970 | 1957 | ||
@@ -2012,7 +1999,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe) | |||
2012 | } | 1999 | } |
2013 | 2000 | ||
2014 | state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ | 2001 | state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ |
2015 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2002 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2016 | dprintk("could not get the lock"); | 2003 | dprintk("could not get the lock"); |
2017 | return 0; | 2004 | return 0; |
2018 | } | 2005 | } |
@@ -2081,7 +2068,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe) | |||
2081 | /* check the tune result */ | 2068 | /* check the tune result */ |
2082 | if (exit_condition == 1) { /* tune failed */ | 2069 | if (exit_condition == 1) { /* tune failed */ |
2083 | dprintk("tune failed"); | 2070 | dprintk("tune failed"); |
2084 | DibReleaseLock(&state->demod_lock); | 2071 | mutex_unlock(&state->demod_lock); |
2085 | /* tune failed; put all the pid filtering cmd to junk */ | 2072 | /* tune failed; put all the pid filtering cmd to junk */ |
2086 | state->pid_ctrl_index = -1; | 2073 | state->pid_ctrl_index = -1; |
2087 | return 0; | 2074 | return 0; |
@@ -2137,7 +2124,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe) | |||
2137 | /* turn off the diversity for the last frontend */ | 2124 | /* turn off the diversity for the last frontend */ |
2138 | dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0); | 2125 | dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0); |
2139 | 2126 | ||
2140 | DibReleaseLock(&state->demod_lock); | 2127 | mutex_unlock(&state->demod_lock); |
2141 | if (state->pid_ctrl_index >= 0) { | 2128 | if (state->pid_ctrl_index >= 0) { |
2142 | u8 index_pid_filter_cmd; | 2129 | u8 index_pid_filter_cmd; |
2143 | u8 pid_ctrl_index = state->pid_ctrl_index; | 2130 | u8 pid_ctrl_index = state->pid_ctrl_index; |
@@ -2175,7 +2162,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
2175 | u8 index_frontend; | 2162 | u8 index_frontend; |
2176 | u16 lock = 0, lock_slave = 0; | 2163 | u16 lock = 0, lock_slave = 0; |
2177 | 2164 | ||
2178 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2165 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2179 | dprintk("could not get the lock"); | 2166 | dprintk("could not get the lock"); |
2180 | return -EINTR; | 2167 | return -EINTR; |
2181 | } | 2168 | } |
@@ -2197,7 +2184,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
2197 | if ((lock & 0x0008) || (lock_slave & 0x0008)) | 2184 | if ((lock & 0x0008) || (lock_slave & 0x0008)) |
2198 | *stat |= FE_HAS_LOCK; | 2185 | *stat |= FE_HAS_LOCK; |
2199 | 2186 | ||
2200 | DibReleaseLock(&state->demod_lock); | 2187 | mutex_unlock(&state->demod_lock); |
2201 | 2188 | ||
2202 | return 0; | 2189 | return 0; |
2203 | } | 2190 | } |
@@ -2208,30 +2195,30 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) | |||
2208 | u16 *c; | 2195 | u16 *c; |
2209 | int ret = 0; | 2196 | int ret = 0; |
2210 | 2197 | ||
2211 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2198 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2212 | dprintk("could not get the lock"); | 2199 | dprintk("could not get the lock"); |
2213 | return -EINTR; | 2200 | return -EINTR; |
2214 | } | 2201 | } |
2215 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 2202 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
2216 | dprintk("could not get the lock"); | 2203 | dprintk("could not get the lock"); |
2217 | ret = -EINTR; | 2204 | ret = -EINTR; |
2218 | goto error; | 2205 | goto error; |
2219 | } | 2206 | } |
2220 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { | 2207 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { |
2221 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2208 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2222 | ret = -EIO; | 2209 | ret = -EIO; |
2223 | goto error; | 2210 | goto error; |
2224 | } | 2211 | } |
2225 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, | 2212 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, |
2226 | state->i2c_read_buffer, 16 * 2); | 2213 | state->i2c_read_buffer, 16 * 2); |
2227 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2214 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2228 | 2215 | ||
2229 | c = (u16 *)state->i2c_read_buffer; | 2216 | c = (u16 *)state->i2c_read_buffer; |
2230 | 2217 | ||
2231 | *ber = c[10] << 16 | c[11]; | 2218 | *ber = c[10] << 16 | c[11]; |
2232 | 2219 | ||
2233 | error: | 2220 | error: |
2234 | DibReleaseLock(&state->demod_lock); | 2221 | mutex_unlock(&state->demod_lock); |
2235 | return ret; | 2222 | return ret; |
2236 | } | 2223 | } |
2237 | 2224 | ||
@@ -2243,7 +2230,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2243 | u16 val; | 2230 | u16 val; |
2244 | int ret = 0; | 2231 | int ret = 0; |
2245 | 2232 | ||
2246 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2233 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2247 | dprintk("could not get the lock"); | 2234 | dprintk("could not get the lock"); |
2248 | return -EINTR; | 2235 | return -EINTR; |
2249 | } | 2236 | } |
@@ -2256,18 +2243,18 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2256 | *strength += val; | 2243 | *strength += val; |
2257 | } | 2244 | } |
2258 | 2245 | ||
2259 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 2246 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
2260 | dprintk("could not get the lock"); | 2247 | dprintk("could not get the lock"); |
2261 | ret = -EINTR; | 2248 | ret = -EINTR; |
2262 | goto error; | 2249 | goto error; |
2263 | } | 2250 | } |
2264 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { | 2251 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { |
2265 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2252 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2266 | ret = -EIO; | 2253 | ret = -EIO; |
2267 | goto error; | 2254 | goto error; |
2268 | } | 2255 | } |
2269 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); | 2256 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2270 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2257 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2271 | 2258 | ||
2272 | val = 65535 - c[4]; | 2259 | val = 65535 - c[4]; |
2273 | if (val > 65535 - *strength) | 2260 | if (val > 65535 - *strength) |
@@ -2276,7 +2263,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2276 | *strength += val; | 2263 | *strength += val; |
2277 | 2264 | ||
2278 | error: | 2265 | error: |
2279 | DibReleaseLock(&state->demod_lock); | 2266 | mutex_unlock(&state->demod_lock); |
2280 | return ret; | 2267 | return ret; |
2281 | } | 2268 | } |
2282 | 2269 | ||
@@ -2287,16 +2274,16 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe) | |||
2287 | u32 n, s, exp; | 2274 | u32 n, s, exp; |
2288 | u16 val; | 2275 | u16 val; |
2289 | 2276 | ||
2290 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 2277 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
2291 | dprintk("could not get the lock"); | 2278 | dprintk("could not get the lock"); |
2292 | return 0; | 2279 | return 0; |
2293 | } | 2280 | } |
2294 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { | 2281 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { |
2295 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2282 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2296 | return 0; | 2283 | return 0; |
2297 | } | 2284 | } |
2298 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); | 2285 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2299 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2286 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2300 | 2287 | ||
2301 | val = c[7]; | 2288 | val = c[7]; |
2302 | n = (val >> 4) & 0xff; | 2289 | n = (val >> 4) & 0xff; |
@@ -2326,7 +2313,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) | |||
2326 | u8 index_frontend; | 2313 | u8 index_frontend; |
2327 | u32 snr_master; | 2314 | u32 snr_master; |
2328 | 2315 | ||
2329 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2316 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2330 | dprintk("could not get the lock"); | 2317 | dprintk("could not get the lock"); |
2331 | return -EINTR; | 2318 | return -EINTR; |
2332 | } | 2319 | } |
@@ -2340,7 +2327,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) | |||
2340 | } else | 2327 | } else |
2341 | *snr = 0; | 2328 | *snr = 0; |
2342 | 2329 | ||
2343 | DibReleaseLock(&state->demod_lock); | 2330 | mutex_unlock(&state->demod_lock); |
2344 | 2331 | ||
2345 | return 0; | 2332 | return 0; |
2346 | } | 2333 | } |
@@ -2351,27 +2338,27 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | |||
2351 | u16 *c = (u16 *)state->i2c_read_buffer; | 2338 | u16 *c = (u16 *)state->i2c_read_buffer; |
2352 | int ret = 0; | 2339 | int ret = 0; |
2353 | 2340 | ||
2354 | if (DibAcquireLock(&state->demod_lock) < 0) { | 2341 | if (mutex_lock_interruptible(&state->demod_lock) < 0) { |
2355 | dprintk("could not get the lock"); | 2342 | dprintk("could not get the lock"); |
2356 | return -EINTR; | 2343 | return -EINTR; |
2357 | } | 2344 | } |
2358 | if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { | 2345 | if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) { |
2359 | dprintk("could not get the lock"); | 2346 | dprintk("could not get the lock"); |
2360 | ret = -EINTR; | 2347 | ret = -EINTR; |
2361 | goto error; | 2348 | goto error; |
2362 | } | 2349 | } |
2363 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { | 2350 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { |
2364 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2351 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2365 | ret = -EIO; | 2352 | ret = -EIO; |
2366 | goto error; | 2353 | goto error; |
2367 | } | 2354 | } |
2368 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); | 2355 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2369 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2356 | mutex_unlock(&state->platform.risc.mem_mbx_lock); |
2370 | 2357 | ||
2371 | *unc = c[12]; | 2358 | *unc = c[12]; |
2372 | 2359 | ||
2373 | error: | 2360 | error: |
2374 | DibReleaseLock(&state->demod_lock); | 2361 | mutex_unlock(&state->demod_lock); |
2375 | return ret; | 2362 | return ret; |
2376 | } | 2363 | } |
2377 | 2364 | ||
@@ -2514,11 +2501,11 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c | |||
2514 | st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; | 2501 | st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; |
2515 | st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS; | 2502 | st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS; |
2516 | 2503 | ||
2517 | DibInitLock(&st->platform.risc.mbx_if_lock); | 2504 | mutex_init(&st->platform.risc.mbx_if_lock); |
2518 | DibInitLock(&st->platform.risc.mbx_lock); | 2505 | mutex_init(&st->platform.risc.mbx_lock); |
2519 | DibInitLock(&st->platform.risc.mem_lock); | 2506 | mutex_init(&st->platform.risc.mem_lock); |
2520 | DibInitLock(&st->platform.risc.mem_mbx_lock); | 2507 | mutex_init(&st->platform.risc.mem_mbx_lock); |
2521 | DibInitLock(&st->demod_lock); | 2508 | mutex_init(&st->demod_lock); |
2522 | st->get_frontend_internal = 0; | 2509 | st->get_frontend_internal = 0; |
2523 | 2510 | ||
2524 | st->pid_ctrl_index = -2; | 2511 | st->pid_ctrl_index = -2; |
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h index 34398738f9bc..216c8c3702f8 100644 --- a/drivers/media/dvb/frontends/drxd.h +++ b/drivers/media/dvb/frontends/drxd.h | |||
@@ -51,9 +51,23 @@ struct drxd_config { | |||
51 | s16(*osc_deviation) (void *priv, s16 dev, int flag); | 51 | s16(*osc_deviation) (void *priv, s16 dev, int flag); |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #if defined(CONFIG_DVB_DRXD) || \ | ||
55 | (defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE)) | ||
54 | extern | 56 | extern |
55 | struct dvb_frontend *drxd_attach(const struct drxd_config *config, | 57 | struct dvb_frontend *drxd_attach(const struct drxd_config *config, |
56 | void *priv, struct i2c_adapter *i2c, | 58 | void *priv, struct i2c_adapter *i2c, |
57 | struct device *dev); | 59 | struct device *dev); |
60 | #else | ||
61 | static inline | ||
62 | struct dvb_frontend *drxd_attach(const struct drxd_config *config, | ||
63 | void *priv, struct i2c_adapter *i2c, | ||
64 | struct device *dev) | ||
65 | { | ||
66 | printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", | ||
67 | __func__); | ||
68 | return NULL; | ||
69 | } | ||
70 | #endif | ||
71 | |||
58 | extern int drxd_config_i2c(struct dvb_frontend *, int); | 72 | extern int drxd_config_i2c(struct dvb_frontend *, int); |
59 | #endif | 73 | #endif |
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index a414b1f2b6a5..60b868faeacf 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c | |||
@@ -1380,20 +1380,20 @@ static int DownloadMicrocode(struct drxk_state *state, | |||
1380 | const u8 pMCImage[], u32 Length) | 1380 | const u8 pMCImage[], u32 Length) |
1381 | { | 1381 | { |
1382 | const u8 *pSrc = pMCImage; | 1382 | const u8 *pSrc = pMCImage; |
1383 | u16 Flags; | ||
1384 | u16 Drain; | ||
1385 | u32 Address; | 1383 | u32 Address; |
1386 | u16 nBlocks; | 1384 | u16 nBlocks; |
1387 | u16 BlockSize; | 1385 | u16 BlockSize; |
1388 | u16 BlockCRC; | ||
1389 | u32 offset = 0; | 1386 | u32 offset = 0; |
1390 | u32 i; | 1387 | u32 i; |
1391 | int status = 0; | 1388 | int status = 0; |
1392 | 1389 | ||
1393 | dprintk(1, "\n"); | 1390 | dprintk(1, "\n"); |
1394 | 1391 | ||
1395 | /* down the drain (we don care about MAGIC_WORD) */ | 1392 | /* down the drain (we don't care about MAGIC_WORD) */ |
1393 | #if 0 | ||
1394 | /* For future reference */ | ||
1396 | Drain = (pSrc[0] << 8) | pSrc[1]; | 1395 | Drain = (pSrc[0] << 8) | pSrc[1]; |
1396 | #endif | ||
1397 | pSrc += sizeof(u16); | 1397 | pSrc += sizeof(u16); |
1398 | offset += sizeof(u16); | 1398 | offset += sizeof(u16); |
1399 | nBlocks = (pSrc[0] << 8) | pSrc[1]; | 1399 | nBlocks = (pSrc[0] << 8) | pSrc[1]; |
@@ -1410,11 +1410,17 @@ static int DownloadMicrocode(struct drxk_state *state, | |||
1410 | pSrc += sizeof(u16); | 1410 | pSrc += sizeof(u16); |
1411 | offset += sizeof(u16); | 1411 | offset += sizeof(u16); |
1412 | 1412 | ||
1413 | #if 0 | ||
1414 | /* For future reference */ | ||
1413 | Flags = (pSrc[0] << 8) | pSrc[1]; | 1415 | Flags = (pSrc[0] << 8) | pSrc[1]; |
1416 | #endif | ||
1414 | pSrc += sizeof(u16); | 1417 | pSrc += sizeof(u16); |
1415 | offset += sizeof(u16); | 1418 | offset += sizeof(u16); |
1416 | 1419 | ||
1420 | #if 0 | ||
1421 | /* For future reference */ | ||
1417 | BlockCRC = (pSrc[0] << 8) | pSrc[1]; | 1422 | BlockCRC = (pSrc[0] << 8) | pSrc[1]; |
1423 | #endif | ||
1418 | pSrc += sizeof(u16); | 1424 | pSrc += sizeof(u16); |
1419 | offset += sizeof(u16); | 1425 | offset += sizeof(u16); |
1420 | 1426 | ||
@@ -5829,7 +5835,7 @@ static int WriteGPIO(struct drxk_state *state) | |||
5829 | } | 5835 | } |
5830 | if (state->UIO_mask & 0x0002) { /* UIO-2 */ | 5836 | if (state->UIO_mask & 0x0002) { /* UIO-2 */ |
5831 | /* write to io pad configuration register - output mode */ | 5837 | /* write to io pad configuration register - output mode */ |
5832 | status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); | 5838 | status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg); |
5833 | if (status < 0) | 5839 | if (status < 0) |
5834 | goto error; | 5840 | goto error; |
5835 | 5841 | ||
@@ -5848,7 +5854,7 @@ static int WriteGPIO(struct drxk_state *state) | |||
5848 | } | 5854 | } |
5849 | if (state->UIO_mask & 0x0004) { /* UIO-3 */ | 5855 | if (state->UIO_mask & 0x0004) { /* UIO-3 */ |
5850 | /* write to io pad configuration register - output mode */ | 5856 | /* write to io pad configuration register - output mode */ |
5851 | status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); | 5857 | status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg); |
5852 | if (status < 0) | 5858 | if (status < 0) |
5853 | goto error; | 5859 | goto error; |
5854 | 5860 | ||
diff --git a/drivers/media/dvb/frontends/drxk_map.h b/drivers/media/dvb/frontends/drxk_map.h index 9b11a8328869..23e16c12f234 100644 --- a/drivers/media/dvb/frontends/drxk_map.h +++ b/drivers/media/dvb/frontends/drxk_map.h | |||
@@ -432,6 +432,7 @@ | |||
432 | #define SIO_PDR_UIO_OUT_LO__A 0x7F0016 | 432 | #define SIO_PDR_UIO_OUT_LO__A 0x7F0016 |
433 | #define SIO_PDR_OHW_CFG__A 0x7F001F | 433 | #define SIO_PDR_OHW_CFG__A 0x7F001F |
434 | #define SIO_PDR_OHW_CFG_FREF_SEL__M 0x3 | 434 | #define SIO_PDR_OHW_CFG_FREF_SEL__M 0x3 |
435 | #define SIO_PDR_GPIO_CFG__A 0x7F0021 | ||
435 | #define SIO_PDR_MSTRT_CFG__A 0x7F0025 | 436 | #define SIO_PDR_MSTRT_CFG__A 0x7F0025 |
436 | #define SIO_PDR_MERR_CFG__A 0x7F0026 | 437 | #define SIO_PDR_MERR_CFG__A 0x7F0026 |
437 | #define SIO_PDR_MCLK_CFG__A 0x7F0028 | 438 | #define SIO_PDR_MCLK_CFG__A 0x7F0028 |
@@ -446,4 +447,5 @@ | |||
446 | #define SIO_PDR_MD5_CFG__A 0x7F0030 | 447 | #define SIO_PDR_MD5_CFG__A 0x7F0030 |
447 | #define SIO_PDR_MD6_CFG__A 0x7F0031 | 448 | #define SIO_PDR_MD6_CFG__A 0x7F0031 |
448 | #define SIO_PDR_MD7_CFG__A 0x7F0032 | 449 | #define SIO_PDR_MD7_CFG__A 0x7F0032 |
450 | #define SIO_PDR_SMA_RX_CFG__A 0x7F0037 | ||
449 | #define SIO_PDR_SMA_TX_CFG__A 0x7F0038 | 451 | #define SIO_PDR_SMA_TX_CFG__A 0x7F0038 |
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index af65d013db11..4c8ac2657c4a 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c | |||
@@ -1114,7 +1114,10 @@ static int ds3000_set_frontend(struct dvb_frontend *fe) | |||
1114 | ds3000_writereg(state, | 1114 | ds3000_writereg(state, |
1115 | ds3000_dvbs2_init_tab[i], | 1115 | ds3000_dvbs2_init_tab[i], |
1116 | ds3000_dvbs2_init_tab[i + 1]); | 1116 | ds3000_dvbs2_init_tab[i + 1]); |
1117 | ds3000_writereg(state, 0xfe, 0x98); | 1117 | if (c->symbol_rate >= 30000000) |
1118 | ds3000_writereg(state, 0xfe, 0x54); | ||
1119 | else | ||
1120 | ds3000_writereg(state, 0xfe, 0x98); | ||
1118 | break; | 1121 | break; |
1119 | default: | 1122 | default: |
1120 | return 1; | 1123 | return 1; |
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index 84df03c29179..708cbf197913 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c | |||
@@ -633,10 +633,9 @@ static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
633 | static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) | 633 | static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) |
634 | { | 634 | { |
635 | struct it913x_fe_state *state = fe->demodulator_priv; | 635 | struct it913x_fe_state *state = fe->demodulator_priv; |
636 | int ret; | ||
637 | u8 reg[5]; | 636 | u8 reg[5]; |
638 | /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */ | 637 | /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */ |
639 | ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg)); | 638 | it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg)); |
640 | state->ucblocks += (u32)(reg[1] << 8) | reg[0]; | 639 | state->ucblocks += (u32)(reg[1] << 8) | reg[0]; |
641 | *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2]; | 640 | *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2]; |
642 | return 0; | 641 | return 0; |
@@ -658,10 +657,9 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe) | |||
658 | { | 657 | { |
659 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | 658 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
660 | struct it913x_fe_state *state = fe->demodulator_priv; | 659 | struct it913x_fe_state *state = fe->demodulator_priv; |
661 | int ret; | ||
662 | u8 reg[8]; | 660 | u8 reg[8]; |
663 | 661 | ||
664 | ret = it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg)); | 662 | it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg)); |
665 | 663 | ||
666 | if (reg[3] < 3) | 664 | if (reg[3] < 3) |
667 | p->modulation = fe_con[reg[3]]; | 665 | p->modulation = fe_con[reg[3]]; |
@@ -691,25 +689,25 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe) | |||
691 | { | 689 | { |
692 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | 690 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
693 | struct it913x_fe_state *state = fe->demodulator_priv; | 691 | struct it913x_fe_state *state = fe->demodulator_priv; |
694 | int ret, i; | 692 | int i; |
695 | u8 empty_ch, last_ch; | 693 | u8 empty_ch, last_ch; |
696 | 694 | ||
697 | state->it913x_status = 0; | 695 | state->it913x_status = 0; |
698 | 696 | ||
699 | /* Set bw*/ | 697 | /* Set bw*/ |
700 | ret = it913x_fe_select_bw(state, p->bandwidth_hz, | 698 | it913x_fe_select_bw(state, p->bandwidth_hz, |
701 | state->adcFrequency); | 699 | state->adcFrequency); |
702 | 700 | ||
703 | /* Training Mode Off */ | 701 | /* Training Mode Off */ |
704 | ret = it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0); | 702 | it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0); |
705 | 703 | ||
706 | /* Clear Empty Channel */ | 704 | /* Clear Empty Channel */ |
707 | ret = it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0); | 705 | it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0); |
708 | 706 | ||
709 | /* Clear bits */ | 707 | /* Clear bits */ |
710 | ret = it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0); | 708 | it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0); |
711 | /* LED on */ | 709 | /* LED on */ |
712 | ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1); | 710 | it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1); |
713 | /* Select Band*/ | 711 | /* Select Band*/ |
714 | if ((p->frequency >= 51000000) && (p->frequency <= 230000000)) | 712 | if ((p->frequency >= 51000000) && (p->frequency <= 230000000)) |
715 | i = 0; | 713 | i = 0; |
@@ -720,7 +718,7 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe) | |||
720 | else | 718 | else |
721 | return -EOPNOTSUPP; | 719 | return -EOPNOTSUPP; |
722 | 720 | ||
723 | ret = it913x_write_reg(state, PRO_DMOD, FREE_BAND, i); | 721 | it913x_write_reg(state, PRO_DMOD, FREE_BAND, i); |
724 | 722 | ||
725 | deb_info("Frontend Set Tuner Type %02x", state->tuner_type); | 723 | deb_info("Frontend Set Tuner Type %02x", state->tuner_type); |
726 | switch (state->tuner_type) { | 724 | switch (state->tuner_type) { |
@@ -730,7 +728,7 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe) | |||
730 | case IT9135_60: | 728 | case IT9135_60: |
731 | case IT9135_61: | 729 | case IT9135_61: |
732 | case IT9135_62: | 730 | case IT9135_62: |
733 | ret = it9137_set_tuner(state, | 731 | it9137_set_tuner(state, |
734 | p->bandwidth_hz, p->frequency); | 732 | p->bandwidth_hz, p->frequency); |
735 | break; | 733 | break; |
736 | default: | 734 | default: |
@@ -742,9 +740,9 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe) | |||
742 | break; | 740 | break; |
743 | } | 741 | } |
744 | /* LED off */ | 742 | /* LED off */ |
745 | ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0); | 743 | it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0); |
746 | /* Trigger ofsm */ | 744 | /* Trigger ofsm */ |
747 | ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0); | 745 | it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0); |
748 | last_ch = 2; | 746 | last_ch = 2; |
749 | for (i = 0; i < 40; ++i) { | 747 | for (i = 0; i < 40; ++i) { |
750 | empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS); | 748 | empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS); |
diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c new file mode 100644 index 000000000000..a3ab1a5b6597 --- /dev/null +++ b/drivers/media/dvb/frontends/lg2160.c | |||
@@ -0,0 +1,1468 @@ | |||
1 | /* | ||
2 | * Support for LG2160 - ATSC/MH | ||
3 | * | ||
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/jiffies.h> | ||
23 | #include <linux/dvb/frontend.h> | ||
24 | #include "lg2160.h" | ||
25 | |||
26 | static int debug; | ||
27 | module_param(debug, int, 0644); | ||
28 | MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); | ||
29 | |||
30 | #define DBG_INFO 1 | ||
31 | #define DBG_REG 2 | ||
32 | |||
33 | #define lg_printk(kern, fmt, arg...) \ | ||
34 | printk(kern "%s: " fmt, __func__, ##arg) | ||
35 | |||
36 | #define lg_info(fmt, arg...) printk(KERN_INFO "lg2160: " fmt, ##arg) | ||
37 | #define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) | ||
38 | #define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) | ||
39 | #define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ | ||
40 | lg_printk(KERN_DEBUG, fmt, ##arg) | ||
41 | #define lg_reg(fmt, arg...) if (debug & DBG_REG) \ | ||
42 | lg_printk(KERN_DEBUG, fmt, ##arg) | ||
43 | |||
44 | #define lg_fail(ret) \ | ||
45 | ({ \ | ||
46 | int __ret; \ | ||
47 | __ret = (ret < 0); \ | ||
48 | if (__ret) \ | ||
49 | lg_err("error %d on line %d\n", ret, __LINE__); \ | ||
50 | __ret; \ | ||
51 | }) | ||
52 | |||
53 | struct lg216x_state { | ||
54 | struct i2c_adapter *i2c_adap; | ||
55 | const struct lg2160_config *cfg; | ||
56 | |||
57 | struct dvb_frontend frontend; | ||
58 | |||
59 | u32 current_frequency; | ||
60 | u8 parade_id; | ||
61 | u8 fic_ver; | ||
62 | unsigned int last_reset; | ||
63 | }; | ||
64 | |||
65 | /* ------------------------------------------------------------------------ */ | ||
66 | |||
67 | static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val) | ||
68 | { | ||
69 | int ret; | ||
70 | u8 buf[] = { reg >> 8, reg & 0xff, val }; | ||
71 | struct i2c_msg msg = { | ||
72 | .addr = state->cfg->i2c_addr, .flags = 0, | ||
73 | .buf = buf, .len = 3, | ||
74 | }; | ||
75 | |||
76 | lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); | ||
77 | |||
78 | ret = i2c_transfer(state->i2c_adap, &msg, 1); | ||
79 | |||
80 | if (ret != 1) { | ||
81 | lg_err("error (addr %02x %02x <- %02x, err = %i)\n", | ||
82 | msg.buf[0], msg.buf[1], msg.buf[2], ret); | ||
83 | if (ret < 0) | ||
84 | return ret; | ||
85 | else | ||
86 | return -EREMOTEIO; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val) | ||
92 | { | ||
93 | int ret; | ||
94 | u8 reg_buf[] = { reg >> 8, reg & 0xff }; | ||
95 | struct i2c_msg msg[] = { | ||
96 | { .addr = state->cfg->i2c_addr, | ||
97 | .flags = 0, .buf = reg_buf, .len = 2 }, | ||
98 | { .addr = state->cfg->i2c_addr, | ||
99 | .flags = I2C_M_RD, .buf = val, .len = 1 }, | ||
100 | }; | ||
101 | |||
102 | lg_reg("reg: 0x%04x\n", reg); | ||
103 | |||
104 | ret = i2c_transfer(state->i2c_adap, msg, 2); | ||
105 | |||
106 | if (ret != 2) { | ||
107 | lg_err("error (addr %02x reg %04x error (ret == %i)\n", | ||
108 | state->cfg->i2c_addr, reg, ret); | ||
109 | if (ret < 0) | ||
110 | return ret; | ||
111 | else | ||
112 | return -EREMOTEIO; | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | struct lg216x_reg { | ||
118 | u16 reg; | ||
119 | u8 val; | ||
120 | }; | ||
121 | |||
122 | static int lg216x_write_regs(struct lg216x_state *state, | ||
123 | struct lg216x_reg *regs, int len) | ||
124 | { | ||
125 | int i, ret; | ||
126 | |||
127 | lg_reg("writing %d registers...\n", len); | ||
128 | |||
129 | for (i = 0; i < len - 1; i++) { | ||
130 | ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); | ||
131 | if (lg_fail(ret)) | ||
132 | return ret; | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int lg216x_set_reg_bit(struct lg216x_state *state, | ||
138 | u16 reg, int bit, int onoff) | ||
139 | { | ||
140 | u8 val; | ||
141 | int ret; | ||
142 | |||
143 | lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); | ||
144 | |||
145 | ret = lg216x_read_reg(state, reg, &val); | ||
146 | if (lg_fail(ret)) | ||
147 | goto fail; | ||
148 | |||
149 | val &= ~(1 << bit); | ||
150 | val |= (onoff & 1) << bit; | ||
151 | |||
152 | ret = lg216x_write_reg(state, reg, val); | ||
153 | lg_fail(ret); | ||
154 | fail: | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | /* ------------------------------------------------------------------------ */ | ||
159 | |||
160 | static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
161 | { | ||
162 | struct lg216x_state *state = fe->demodulator_priv; | ||
163 | int ret; | ||
164 | |||
165 | if (state->cfg->deny_i2c_rptr) | ||
166 | return 0; | ||
167 | |||
168 | lg_dbg("(%d)\n", enable); | ||
169 | |||
170 | ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1); | ||
171 | |||
172 | msleep(1); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static int lg216x_soft_reset(struct lg216x_state *state) | ||
178 | { | ||
179 | int ret; | ||
180 | |||
181 | lg_dbg("\n"); | ||
182 | |||
183 | ret = lg216x_write_reg(state, 0x0002, 0x00); | ||
184 | if (lg_fail(ret)) | ||
185 | goto fail; | ||
186 | |||
187 | msleep(20); | ||
188 | ret = lg216x_write_reg(state, 0x0002, 0x01); | ||
189 | if (lg_fail(ret)) | ||
190 | goto fail; | ||
191 | |||
192 | state->last_reset = jiffies_to_msecs(jiffies); | ||
193 | fail: | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static int lg216x_initialize(struct lg216x_state *state) | ||
198 | { | ||
199 | int ret; | ||
200 | |||
201 | static struct lg216x_reg lg2160_init[] = { | ||
202 | #if 0 | ||
203 | { .reg = 0x0015, .val = 0xe6 }, | ||
204 | #else | ||
205 | { .reg = 0x0015, .val = 0xf7 }, | ||
206 | { .reg = 0x001b, .val = 0x52 }, | ||
207 | { .reg = 0x0208, .val = 0x00 }, | ||
208 | { .reg = 0x0209, .val = 0x82 }, | ||
209 | { .reg = 0x0210, .val = 0xf9 }, | ||
210 | { .reg = 0x020a, .val = 0x00 }, | ||
211 | { .reg = 0x020b, .val = 0x82 }, | ||
212 | { .reg = 0x020d, .val = 0x28 }, | ||
213 | { .reg = 0x020f, .val = 0x14 }, | ||
214 | #endif | ||
215 | }; | ||
216 | |||
217 | static struct lg216x_reg lg2161_init[] = { | ||
218 | { .reg = 0x0000, .val = 0x41 }, | ||
219 | { .reg = 0x0001, .val = 0xfb }, | ||
220 | { .reg = 0x0216, .val = 0x00 }, | ||
221 | { .reg = 0x0219, .val = 0x00 }, | ||
222 | { .reg = 0x021b, .val = 0x55 }, | ||
223 | { .reg = 0x0606, .val = 0x0a }, | ||
224 | }; | ||
225 | |||
226 | switch (state->cfg->lg_chip) { | ||
227 | case LG2160: | ||
228 | ret = lg216x_write_regs(state, | ||
229 | lg2160_init, ARRAY_SIZE(lg2160_init)); | ||
230 | break; | ||
231 | case LG2161: | ||
232 | ret = lg216x_write_regs(state, | ||
233 | lg2161_init, ARRAY_SIZE(lg2161_init)); | ||
234 | break; | ||
235 | default: | ||
236 | ret = -EINVAL; | ||
237 | break; | ||
238 | } | ||
239 | if (lg_fail(ret)) | ||
240 | goto fail; | ||
241 | |||
242 | ret = lg216x_soft_reset(state); | ||
243 | lg_fail(ret); | ||
244 | fail: | ||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | /* ------------------------------------------------------------------------ */ | ||
249 | |||
250 | static int lg216x_set_if(struct lg216x_state *state) | ||
251 | { | ||
252 | u8 val; | ||
253 | int ret; | ||
254 | |||
255 | lg_dbg("%d KHz\n", state->cfg->if_khz); | ||
256 | |||
257 | ret = lg216x_read_reg(state, 0x0132, &val); | ||
258 | if (lg_fail(ret)) | ||
259 | goto fail; | ||
260 | |||
261 | val &= 0xfb; | ||
262 | val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00; | ||
263 | |||
264 | ret = lg216x_write_reg(state, 0x0132, val); | ||
265 | lg_fail(ret); | ||
266 | |||
267 | /* if NOT zero IF, 6 MHz is the default */ | ||
268 | fail: | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | /* ------------------------------------------------------------------------ */ | ||
273 | |||
274 | static int lg2160_agc_fix(struct lg216x_state *state, | ||
275 | int if_agc_fix, int rf_agc_fix) | ||
276 | { | ||
277 | u8 val; | ||
278 | int ret; | ||
279 | |||
280 | ret = lg216x_read_reg(state, 0x0100, &val); | ||
281 | if (lg_fail(ret)) | ||
282 | goto fail; | ||
283 | |||
284 | val &= 0xf3; | ||
285 | val |= (if_agc_fix) ? 0x08 : 0x00; | ||
286 | val |= (rf_agc_fix) ? 0x04 : 0x00; | ||
287 | |||
288 | ret = lg216x_write_reg(state, 0x0100, val); | ||
289 | lg_fail(ret); | ||
290 | fail: | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | #if 0 | ||
295 | static int lg2160_agc_freeze(struct lg216x_state *state, | ||
296 | int if_agc_freeze, int rf_agc_freeze) | ||
297 | { | ||
298 | u8 val; | ||
299 | int ret; | ||
300 | |||
301 | ret = lg216x_read_reg(state, 0x0100, &val); | ||
302 | if (lg_fail(ret)) | ||
303 | goto fail; | ||
304 | |||
305 | val &= 0xcf; | ||
306 | val |= (if_agc_freeze) ? 0x20 : 0x00; | ||
307 | val |= (rf_agc_freeze) ? 0x10 : 0x00; | ||
308 | |||
309 | ret = lg216x_write_reg(state, 0x0100, val); | ||
310 | lg_fail(ret); | ||
311 | fail: | ||
312 | return ret; | ||
313 | } | ||
314 | #endif | ||
315 | |||
316 | static int lg2160_agc_polarity(struct lg216x_state *state, | ||
317 | int if_agc_polarity, int rf_agc_polarity) | ||
318 | { | ||
319 | u8 val; | ||
320 | int ret; | ||
321 | |||
322 | ret = lg216x_read_reg(state, 0x0100, &val); | ||
323 | if (lg_fail(ret)) | ||
324 | goto fail; | ||
325 | |||
326 | val &= 0xfc; | ||
327 | val |= (if_agc_polarity) ? 0x02 : 0x00; | ||
328 | val |= (rf_agc_polarity) ? 0x01 : 0x00; | ||
329 | |||
330 | ret = lg216x_write_reg(state, 0x0100, val); | ||
331 | lg_fail(ret); | ||
332 | fail: | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state, | ||
337 | int polarity) | ||
338 | { | ||
339 | u8 val; | ||
340 | int ret; | ||
341 | |||
342 | ret = lg216x_read_reg(state, 0x0008, &val); | ||
343 | if (lg_fail(ret)) | ||
344 | goto fail; | ||
345 | |||
346 | val &= 0xfe; | ||
347 | val |= (polarity) ? 0x01 : 0x00; | ||
348 | |||
349 | ret = lg216x_write_reg(state, 0x0008, val); | ||
350 | lg_fail(ret); | ||
351 | fail: | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | static int lg2160_spectrum_polarity(struct lg216x_state *state, | ||
356 | int inverted) | ||
357 | { | ||
358 | u8 val; | ||
359 | int ret; | ||
360 | |||
361 | ret = lg216x_read_reg(state, 0x0132, &val); | ||
362 | if (lg_fail(ret)) | ||
363 | goto fail; | ||
364 | |||
365 | val &= 0xfd; | ||
366 | val |= (inverted) ? 0x02 : 0x00; | ||
367 | |||
368 | ret = lg216x_write_reg(state, 0x0132, val); | ||
369 | lg_fail(ret); | ||
370 | fail: | ||
371 | return lg216x_soft_reset(state); | ||
372 | } | ||
373 | |||
374 | static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff) | ||
375 | { | ||
376 | u8 val; | ||
377 | int ret; | ||
378 | |||
379 | ret = lg216x_read_reg(state, 0x0007, &val); | ||
380 | if (lg_fail(ret)) | ||
381 | goto fail; | ||
382 | |||
383 | val &= 0xbf; | ||
384 | val |= (onoff) ? 0x40 : 0x00; | ||
385 | |||
386 | ret = lg216x_write_reg(state, 0x0007, val); | ||
387 | lg_fail(ret); | ||
388 | fail: | ||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int lg216x_set_parade(struct lg216x_state *state, int id) | ||
393 | { | ||
394 | int ret; | ||
395 | |||
396 | ret = lg216x_write_reg(state, 0x013e, id & 0x7f); | ||
397 | if (lg_fail(ret)) | ||
398 | goto fail; | ||
399 | |||
400 | state->parade_id = id & 0x7f; | ||
401 | fail: | ||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | static int lg216x_set_ensemble(struct lg216x_state *state, int id) | ||
406 | { | ||
407 | int ret; | ||
408 | u16 reg; | ||
409 | u8 val; | ||
410 | |||
411 | switch (state->cfg->lg_chip) { | ||
412 | case LG2160: | ||
413 | reg = 0x0400; | ||
414 | break; | ||
415 | case LG2161: | ||
416 | default: | ||
417 | reg = 0x0500; | ||
418 | break; | ||
419 | } | ||
420 | |||
421 | ret = lg216x_read_reg(state, reg, &val); | ||
422 | if (lg_fail(ret)) | ||
423 | goto fail; | ||
424 | |||
425 | val &= 0xfe; | ||
426 | val |= (id) ? 0x01 : 0x00; | ||
427 | |||
428 | ret = lg216x_write_reg(state, reg, val); | ||
429 | lg_fail(ret); | ||
430 | fail: | ||
431 | return ret; | ||
432 | } | ||
433 | |||
434 | static int lg2160_set_spi_clock(struct lg216x_state *state) | ||
435 | { | ||
436 | u8 val; | ||
437 | int ret; | ||
438 | |||
439 | ret = lg216x_read_reg(state, 0x0014, &val); | ||
440 | if (lg_fail(ret)) | ||
441 | goto fail; | ||
442 | |||
443 | val &= 0xf3; | ||
444 | val |= (state->cfg->spi_clock << 2); | ||
445 | |||
446 | ret = lg216x_write_reg(state, 0x0014, val); | ||
447 | lg_fail(ret); | ||
448 | fail: | ||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | static int lg2161_set_output_interface(struct lg216x_state *state) | ||
453 | { | ||
454 | u8 val; | ||
455 | int ret; | ||
456 | |||
457 | ret = lg216x_read_reg(state, 0x0014, &val); | ||
458 | if (lg_fail(ret)) | ||
459 | goto fail; | ||
460 | |||
461 | val &= ~0x07; | ||
462 | val |= state->cfg->output_if; /* FIXME: needs sanity check */ | ||
463 | |||
464 | ret = lg216x_write_reg(state, 0x0014, val); | ||
465 | lg_fail(ret); | ||
466 | fail: | ||
467 | return ret; | ||
468 | } | ||
469 | |||
470 | static int lg216x_enable_fic(struct lg216x_state *state, int onoff) | ||
471 | { | ||
472 | int ret; | ||
473 | |||
474 | ret = lg216x_write_reg(state, 0x0017, 0x23); | ||
475 | if (lg_fail(ret)) | ||
476 | goto fail; | ||
477 | |||
478 | ret = lg216x_write_reg(state, 0x0016, 0xfc); | ||
479 | if (lg_fail(ret)) | ||
480 | goto fail; | ||
481 | |||
482 | switch (state->cfg->lg_chip) { | ||
483 | case LG2160: | ||
484 | ret = lg216x_write_reg(state, 0x0016, | ||
485 | 0xfc | ((onoff) ? 0x02 : 0x00)); | ||
486 | break; | ||
487 | case LG2161: | ||
488 | ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00); | ||
489 | break; | ||
490 | } | ||
491 | if (lg_fail(ret)) | ||
492 | goto fail; | ||
493 | |||
494 | ret = lg216x_initialize(state); | ||
495 | if (lg_fail(ret)) | ||
496 | goto fail; | ||
497 | |||
498 | if (onoff) { | ||
499 | ret = lg216x_write_reg(state, 0x0017, 0x03); | ||
500 | lg_fail(ret); | ||
501 | } | ||
502 | fail: | ||
503 | return ret; | ||
504 | } | ||
505 | |||
506 | /* ------------------------------------------------------------------------ */ | ||
507 | |||
508 | static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver) | ||
509 | { | ||
510 | u8 val; | ||
511 | int ret; | ||
512 | |||
513 | *ficver = 0xff; /* invalid value */ | ||
514 | |||
515 | ret = lg216x_read_reg(state, 0x0128, &val); | ||
516 | if (lg_fail(ret)) | ||
517 | goto fail; | ||
518 | |||
519 | *ficver = (val >> 3) & 0x1f; | ||
520 | fail: | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | #if 0 | ||
525 | static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id) | ||
526 | { | ||
527 | u8 val; | ||
528 | int ret; | ||
529 | |||
530 | *id = 0xff; /* invalid value */ | ||
531 | |||
532 | ret = lg216x_read_reg(state, 0x0123, &val); | ||
533 | if (lg_fail(ret)) | ||
534 | goto fail; | ||
535 | |||
536 | *id = val & 0x7f; | ||
537 | fail: | ||
538 | return ret; | ||
539 | } | ||
540 | #endif | ||
541 | |||
542 | static int lg216x_get_nog(struct lg216x_state *state, u8 *nog) | ||
543 | { | ||
544 | u8 val; | ||
545 | int ret; | ||
546 | |||
547 | *nog = 0xff; /* invalid value */ | ||
548 | |||
549 | ret = lg216x_read_reg(state, 0x0124, &val); | ||
550 | if (lg_fail(ret)) | ||
551 | goto fail; | ||
552 | |||
553 | *nog = ((val >> 4) & 0x07) + 1; | ||
554 | fail: | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog) | ||
559 | { | ||
560 | u8 val; | ||
561 | int ret; | ||
562 | |||
563 | *tnog = 0xff; /* invalid value */ | ||
564 | |||
565 | ret = lg216x_read_reg(state, 0x0125, &val); | ||
566 | if (lg_fail(ret)) | ||
567 | goto fail; | ||
568 | |||
569 | *tnog = val & 0x1f; | ||
570 | fail: | ||
571 | return ret; | ||
572 | } | ||
573 | |||
574 | static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn) | ||
575 | { | ||
576 | u8 val; | ||
577 | int ret; | ||
578 | |||
579 | *sgn = 0xff; /* invalid value */ | ||
580 | |||
581 | ret = lg216x_read_reg(state, 0x0124, &val); | ||
582 | if (lg_fail(ret)) | ||
583 | goto fail; | ||
584 | |||
585 | *sgn = val & 0x0f; | ||
586 | fail: | ||
587 | return ret; | ||
588 | } | ||
589 | |||
590 | static int lg216x_get_prc(struct lg216x_state *state, u8 *prc) | ||
591 | { | ||
592 | u8 val; | ||
593 | int ret; | ||
594 | |||
595 | *prc = 0xff; /* invalid value */ | ||
596 | |||
597 | ret = lg216x_read_reg(state, 0x0125, &val); | ||
598 | if (lg_fail(ret)) | ||
599 | goto fail; | ||
600 | |||
601 | *prc = ((val >> 5) & 0x07) + 1; | ||
602 | fail: | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | /* ------------------------------------------------------------------------ */ | ||
607 | |||
608 | static int lg216x_get_rs_frame_mode(struct lg216x_state *state, | ||
609 | enum atscmh_rs_frame_mode *rs_framemode) | ||
610 | { | ||
611 | u8 val; | ||
612 | int ret; | ||
613 | |||
614 | switch (state->cfg->lg_chip) { | ||
615 | case LG2160: | ||
616 | ret = lg216x_read_reg(state, 0x0410, &val); | ||
617 | break; | ||
618 | case LG2161: | ||
619 | ret = lg216x_read_reg(state, 0x0513, &val); | ||
620 | break; | ||
621 | default: | ||
622 | ret = -EINVAL; | ||
623 | } | ||
624 | if (lg_fail(ret)) | ||
625 | goto fail; | ||
626 | |||
627 | switch ((val >> 4) & 0x03) { | ||
628 | #if 1 | ||
629 | default: | ||
630 | #endif | ||
631 | case 0x00: | ||
632 | *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY; | ||
633 | break; | ||
634 | case 0x01: | ||
635 | *rs_framemode = ATSCMH_RSFRAME_PRI_SEC; | ||
636 | break; | ||
637 | #if 0 | ||
638 | default: | ||
639 | *rs_framemode = ATSCMH_RSFRAME_RES; | ||
640 | break; | ||
641 | #endif | ||
642 | } | ||
643 | fail: | ||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | static | ||
648 | int lg216x_get_rs_frame_ensemble(struct lg216x_state *state, | ||
649 | enum atscmh_rs_frame_ensemble *rs_frame_ens) | ||
650 | { | ||
651 | u8 val; | ||
652 | int ret; | ||
653 | |||
654 | switch (state->cfg->lg_chip) { | ||
655 | case LG2160: | ||
656 | ret = lg216x_read_reg(state, 0x0400, &val); | ||
657 | break; | ||
658 | case LG2161: | ||
659 | ret = lg216x_read_reg(state, 0x0500, &val); | ||
660 | break; | ||
661 | default: | ||
662 | ret = -EINVAL; | ||
663 | } | ||
664 | if (lg_fail(ret)) | ||
665 | goto fail; | ||
666 | |||
667 | val &= 0x01; | ||
668 | *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val; | ||
669 | fail: | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | static int lg216x_get_rs_code_mode(struct lg216x_state *state, | ||
674 | enum atscmh_rs_code_mode *rs_code_pri, | ||
675 | enum atscmh_rs_code_mode *rs_code_sec) | ||
676 | { | ||
677 | u8 val; | ||
678 | int ret; | ||
679 | |||
680 | switch (state->cfg->lg_chip) { | ||
681 | case LG2160: | ||
682 | ret = lg216x_read_reg(state, 0x0410, &val); | ||
683 | break; | ||
684 | case LG2161: | ||
685 | ret = lg216x_read_reg(state, 0x0513, &val); | ||
686 | break; | ||
687 | default: | ||
688 | ret = -EINVAL; | ||
689 | } | ||
690 | if (lg_fail(ret)) | ||
691 | goto fail; | ||
692 | |||
693 | *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03); | ||
694 | *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03); | ||
695 | fail: | ||
696 | return ret; | ||
697 | } | ||
698 | |||
699 | static int lg216x_get_sccc_block_mode(struct lg216x_state *state, | ||
700 | enum atscmh_sccc_block_mode *sccc_block) | ||
701 | { | ||
702 | u8 val; | ||
703 | int ret; | ||
704 | |||
705 | switch (state->cfg->lg_chip) { | ||
706 | case LG2160: | ||
707 | ret = lg216x_read_reg(state, 0x0315, &val); | ||
708 | break; | ||
709 | case LG2161: | ||
710 | ret = lg216x_read_reg(state, 0x0511, &val); | ||
711 | break; | ||
712 | default: | ||
713 | ret = -EINVAL; | ||
714 | } | ||
715 | if (lg_fail(ret)) | ||
716 | goto fail; | ||
717 | |||
718 | switch (val & 0x03) { | ||
719 | case 0x00: | ||
720 | *sccc_block = ATSCMH_SCCC_BLK_SEP; | ||
721 | break; | ||
722 | case 0x01: | ||
723 | *sccc_block = ATSCMH_SCCC_BLK_COMB; | ||
724 | break; | ||
725 | default: | ||
726 | *sccc_block = ATSCMH_SCCC_BLK_RES; | ||
727 | break; | ||
728 | } | ||
729 | fail: | ||
730 | return ret; | ||
731 | } | ||
732 | |||
733 | static int lg216x_get_sccc_code_mode(struct lg216x_state *state, | ||
734 | enum atscmh_sccc_code_mode *mode_a, | ||
735 | enum atscmh_sccc_code_mode *mode_b, | ||
736 | enum atscmh_sccc_code_mode *mode_c, | ||
737 | enum atscmh_sccc_code_mode *mode_d) | ||
738 | { | ||
739 | u8 val; | ||
740 | int ret; | ||
741 | |||
742 | switch (state->cfg->lg_chip) { | ||
743 | case LG2160: | ||
744 | ret = lg216x_read_reg(state, 0x0316, &val); | ||
745 | break; | ||
746 | case LG2161: | ||
747 | ret = lg216x_read_reg(state, 0x0512, &val); | ||
748 | break; | ||
749 | default: | ||
750 | ret = -EINVAL; | ||
751 | } | ||
752 | if (lg_fail(ret)) | ||
753 | goto fail; | ||
754 | |||
755 | switch ((val >> 6) & 0x03) { | ||
756 | case 0x00: | ||
757 | *mode_a = ATSCMH_SCCC_CODE_HLF; | ||
758 | break; | ||
759 | case 0x01: | ||
760 | *mode_a = ATSCMH_SCCC_CODE_QTR; | ||
761 | break; | ||
762 | default: | ||
763 | *mode_a = ATSCMH_SCCC_CODE_RES; | ||
764 | break; | ||
765 | } | ||
766 | |||
767 | switch ((val >> 4) & 0x03) { | ||
768 | case 0x00: | ||
769 | *mode_b = ATSCMH_SCCC_CODE_HLF; | ||
770 | break; | ||
771 | case 0x01: | ||
772 | *mode_b = ATSCMH_SCCC_CODE_QTR; | ||
773 | break; | ||
774 | default: | ||
775 | *mode_b = ATSCMH_SCCC_CODE_RES; | ||
776 | break; | ||
777 | } | ||
778 | |||
779 | switch ((val >> 2) & 0x03) { | ||
780 | case 0x00: | ||
781 | *mode_c = ATSCMH_SCCC_CODE_HLF; | ||
782 | break; | ||
783 | case 0x01: | ||
784 | *mode_c = ATSCMH_SCCC_CODE_QTR; | ||
785 | break; | ||
786 | default: | ||
787 | *mode_c = ATSCMH_SCCC_CODE_RES; | ||
788 | break; | ||
789 | } | ||
790 | |||
791 | switch (val & 0x03) { | ||
792 | case 0x00: | ||
793 | *mode_d = ATSCMH_SCCC_CODE_HLF; | ||
794 | break; | ||
795 | case 0x01: | ||
796 | *mode_d = ATSCMH_SCCC_CODE_QTR; | ||
797 | break; | ||
798 | default: | ||
799 | *mode_d = ATSCMH_SCCC_CODE_RES; | ||
800 | break; | ||
801 | } | ||
802 | fail: | ||
803 | return ret; | ||
804 | } | ||
805 | |||
806 | /* ------------------------------------------------------------------------ */ | ||
807 | |||
808 | #if 0 | ||
809 | static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err) | ||
810 | { | ||
811 | u8 fic_err; | ||
812 | int ret; | ||
813 | |||
814 | *err = 0; | ||
815 | |||
816 | switch (state->cfg->lg_chip) { | ||
817 | case LG2160: | ||
818 | ret = lg216x_read_reg(state, 0x0012, &fic_err); | ||
819 | break; | ||
820 | case LG2161: | ||
821 | ret = lg216x_read_reg(state, 0x001e, &fic_err); | ||
822 | break; | ||
823 | } | ||
824 | if (lg_fail(ret)) | ||
825 | goto fail; | ||
826 | |||
827 | *err = fic_err; | ||
828 | fail: | ||
829 | return ret; | ||
830 | } | ||
831 | |||
832 | static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err) | ||
833 | { | ||
834 | u8 crc_err1, crc_err2; | ||
835 | int ret; | ||
836 | |||
837 | *err = 0; | ||
838 | |||
839 | ret = lg216x_read_reg(state, 0x0411, &crc_err1); | ||
840 | if (lg_fail(ret)) | ||
841 | goto fail; | ||
842 | |||
843 | ret = lg216x_read_reg(state, 0x0412, &crc_err2); | ||
844 | if (lg_fail(ret)) | ||
845 | goto fail; | ||
846 | |||
847 | *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1); | ||
848 | fail: | ||
849 | return ret; | ||
850 | } | ||
851 | |||
852 | static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err) | ||
853 | { | ||
854 | u8 crc_err; | ||
855 | int ret; | ||
856 | |||
857 | *err = 0; | ||
858 | |||
859 | ret = lg216x_read_reg(state, 0x0612, &crc_err); | ||
860 | if (lg_fail(ret)) | ||
861 | goto fail; | ||
862 | |||
863 | *err = (u16)crc_err; | ||
864 | fail: | ||
865 | return ret; | ||
866 | } | ||
867 | |||
868 | static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err) | ||
869 | { | ||
870 | int ret; | ||
871 | switch (state->cfg->lg_chip) { | ||
872 | case LG2160: | ||
873 | ret = lg2160_read_crc_err_count(state, err); | ||
874 | break; | ||
875 | case LG2161: | ||
876 | ret = lg2161_read_crc_err_count(state, err); | ||
877 | break; | ||
878 | default: | ||
879 | ret = -EINVAL; | ||
880 | break; | ||
881 | } | ||
882 | return ret; | ||
883 | } | ||
884 | |||
885 | static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err) | ||
886 | { | ||
887 | u8 rs_err1, rs_err2; | ||
888 | int ret; | ||
889 | |||
890 | *err = 0; | ||
891 | |||
892 | ret = lg216x_read_reg(state, 0x0413, &rs_err1); | ||
893 | if (lg_fail(ret)) | ||
894 | goto fail; | ||
895 | |||
896 | ret = lg216x_read_reg(state, 0x0414, &rs_err2); | ||
897 | if (lg_fail(ret)) | ||
898 | goto fail; | ||
899 | |||
900 | *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1); | ||
901 | fail: | ||
902 | return ret; | ||
903 | } | ||
904 | |||
905 | static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err) | ||
906 | { | ||
907 | u8 rs_err1, rs_err2; | ||
908 | int ret; | ||
909 | |||
910 | *err = 0; | ||
911 | |||
912 | ret = lg216x_read_reg(state, 0x0613, &rs_err1); | ||
913 | if (lg_fail(ret)) | ||
914 | goto fail; | ||
915 | |||
916 | ret = lg216x_read_reg(state, 0x0614, &rs_err2); | ||
917 | if (lg_fail(ret)) | ||
918 | goto fail; | ||
919 | |||
920 | *err = (u16)((rs_err1 << 8) | rs_err2); | ||
921 | fail: | ||
922 | return ret; | ||
923 | } | ||
924 | |||
925 | static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err) | ||
926 | { | ||
927 | int ret; | ||
928 | switch (state->cfg->lg_chip) { | ||
929 | case LG2160: | ||
930 | ret = lg2160_read_rs_err_count(state, err); | ||
931 | break; | ||
932 | case LG2161: | ||
933 | ret = lg2161_read_rs_err_count(state, err); | ||
934 | break; | ||
935 | default: | ||
936 | ret = -EINVAL; | ||
937 | break; | ||
938 | } | ||
939 | return ret; | ||
940 | } | ||
941 | #endif | ||
942 | |||
943 | /* ------------------------------------------------------------------------ */ | ||
944 | |||
945 | static int lg216x_get_frontend(struct dvb_frontend *fe) | ||
946 | { | ||
947 | struct lg216x_state *state = fe->demodulator_priv; | ||
948 | int ret; | ||
949 | |||
950 | lg_dbg("\n"); | ||
951 | |||
952 | fe->dtv_property_cache.modulation = VSB_8; | ||
953 | fe->dtv_property_cache.frequency = state->current_frequency; | ||
954 | fe->dtv_property_cache.delivery_system = SYS_ATSCMH; | ||
955 | |||
956 | ret = lg216x_get_fic_version(state, | ||
957 | &fe->dtv_property_cache.atscmh_fic_ver); | ||
958 | if (lg_fail(ret)) | ||
959 | goto fail; | ||
960 | if (state->fic_ver != fe->dtv_property_cache.atscmh_fic_ver) { | ||
961 | state->fic_ver = fe->dtv_property_cache.atscmh_fic_ver; | ||
962 | |||
963 | #if 0 | ||
964 | ret = lg2160_get_parade_id(state, | ||
965 | &fe->dtv_property_cache.atscmh_parade_id); | ||
966 | if (lg_fail(ret)) | ||
967 | goto fail; | ||
968 | /* #else */ | ||
969 | fe->dtv_property_cache.atscmh_parade_id = state->parade_id; | ||
970 | #endif | ||
971 | ret = lg216x_get_nog(state, | ||
972 | &fe->dtv_property_cache.atscmh_nog); | ||
973 | if (lg_fail(ret)) | ||
974 | goto fail; | ||
975 | ret = lg216x_get_tnog(state, | ||
976 | &fe->dtv_property_cache.atscmh_tnog); | ||
977 | if (lg_fail(ret)) | ||
978 | goto fail; | ||
979 | ret = lg216x_get_sgn(state, | ||
980 | &fe->dtv_property_cache.atscmh_sgn); | ||
981 | if (lg_fail(ret)) | ||
982 | goto fail; | ||
983 | ret = lg216x_get_prc(state, | ||
984 | &fe->dtv_property_cache.atscmh_prc); | ||
985 | if (lg_fail(ret)) | ||
986 | goto fail; | ||
987 | |||
988 | ret = lg216x_get_rs_frame_mode(state, | ||
989 | (enum atscmh_rs_frame_mode *) | ||
990 | &fe->dtv_property_cache.atscmh_rs_frame_mode); | ||
991 | if (lg_fail(ret)) | ||
992 | goto fail; | ||
993 | ret = lg216x_get_rs_frame_ensemble(state, | ||
994 | (enum atscmh_rs_frame_ensemble *) | ||
995 | &fe->dtv_property_cache.atscmh_rs_frame_ensemble); | ||
996 | if (lg_fail(ret)) | ||
997 | goto fail; | ||
998 | ret = lg216x_get_rs_code_mode(state, | ||
999 | (enum atscmh_rs_code_mode *) | ||
1000 | &fe->dtv_property_cache.atscmh_rs_code_mode_pri, | ||
1001 | (enum atscmh_rs_code_mode *) | ||
1002 | &fe->dtv_property_cache.atscmh_rs_code_mode_sec); | ||
1003 | if (lg_fail(ret)) | ||
1004 | goto fail; | ||
1005 | ret = lg216x_get_sccc_block_mode(state, | ||
1006 | (enum atscmh_sccc_block_mode *) | ||
1007 | &fe->dtv_property_cache.atscmh_sccc_block_mode); | ||
1008 | if (lg_fail(ret)) | ||
1009 | goto fail; | ||
1010 | ret = lg216x_get_sccc_code_mode(state, | ||
1011 | (enum atscmh_sccc_code_mode *) | ||
1012 | &fe->dtv_property_cache.atscmh_sccc_code_mode_a, | ||
1013 | (enum atscmh_sccc_code_mode *) | ||
1014 | &fe->dtv_property_cache.atscmh_sccc_code_mode_b, | ||
1015 | (enum atscmh_sccc_code_mode *) | ||
1016 | &fe->dtv_property_cache.atscmh_sccc_code_mode_c, | ||
1017 | (enum atscmh_sccc_code_mode *) | ||
1018 | &fe->dtv_property_cache.atscmh_sccc_code_mode_d); | ||
1019 | if (lg_fail(ret)) | ||
1020 | goto fail; | ||
1021 | } | ||
1022 | #if 0 | ||
1023 | ret = lg216x_read_fic_err_count(state, | ||
1024 | (u8 *)&fe->dtv_property_cache.atscmh_fic_err); | ||
1025 | if (lg_fail(ret)) | ||
1026 | goto fail; | ||
1027 | ret = lg216x_read_crc_err_count(state, | ||
1028 | &fe->dtv_property_cache.atscmh_crc_err); | ||
1029 | if (lg_fail(ret)) | ||
1030 | goto fail; | ||
1031 | ret = lg216x_read_rs_err_count(state, | ||
1032 | &fe->dtv_property_cache.atscmh_rs_err); | ||
1033 | if (lg_fail(ret)) | ||
1034 | goto fail; | ||
1035 | |||
1036 | switch (state->cfg->lg_chip) { | ||
1037 | case LG2160: | ||
1038 | if (((fe->dtv_property_cache.atscmh_rs_err >= 240) && | ||
1039 | (fe->dtv_property_cache.atscmh_crc_err >= 240)) && | ||
1040 | ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000)) | ||
1041 | ret = lg216x_soft_reset(state); | ||
1042 | break; | ||
1043 | case LG2161: | ||
1044 | /* no fix needed here (as far as we know) */ | ||
1045 | ret = 0; | ||
1046 | break; | ||
1047 | } | ||
1048 | lg_fail(ret); | ||
1049 | #endif | ||
1050 | fail: | ||
1051 | return ret; | ||
1052 | } | ||
1053 | |||
1054 | static int lg216x_get_property(struct dvb_frontend *fe, | ||
1055 | struct dtv_property *tvp) | ||
1056 | { | ||
1057 | return (DTV_ATSCMH_FIC_VER == tvp->cmd) ? | ||
1058 | lg216x_get_frontend(fe) : 0; | ||
1059 | } | ||
1060 | |||
1061 | |||
1062 | static int lg2160_set_frontend(struct dvb_frontend *fe) | ||
1063 | { | ||
1064 | struct lg216x_state *state = fe->demodulator_priv; | ||
1065 | int ret; | ||
1066 | |||
1067 | lg_dbg("(%d)\n", fe->dtv_property_cache.frequency); | ||
1068 | |||
1069 | if (fe->ops.tuner_ops.set_params) { | ||
1070 | ret = fe->ops.tuner_ops.set_params(fe); | ||
1071 | if (fe->ops.i2c_gate_ctrl) | ||
1072 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1073 | if (lg_fail(ret)) | ||
1074 | goto fail; | ||
1075 | state->current_frequency = fe->dtv_property_cache.frequency; | ||
1076 | } | ||
1077 | |||
1078 | ret = lg2160_agc_fix(state, 0, 0); | ||
1079 | if (lg_fail(ret)) | ||
1080 | goto fail; | ||
1081 | ret = lg2160_agc_polarity(state, 0, 0); | ||
1082 | if (lg_fail(ret)) | ||
1083 | goto fail; | ||
1084 | ret = lg2160_tuner_pwr_save_polarity(state, 1); | ||
1085 | if (lg_fail(ret)) | ||
1086 | goto fail; | ||
1087 | ret = lg216x_set_if(state); | ||
1088 | if (lg_fail(ret)) | ||
1089 | goto fail; | ||
1090 | ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion); | ||
1091 | if (lg_fail(ret)) | ||
1092 | goto fail; | ||
1093 | |||
1094 | /* be tuned before this point */ | ||
1095 | ret = lg216x_soft_reset(state); | ||
1096 | if (lg_fail(ret)) | ||
1097 | goto fail; | ||
1098 | |||
1099 | ret = lg2160_tuner_pwr_save(state, 0); | ||
1100 | if (lg_fail(ret)) | ||
1101 | goto fail; | ||
1102 | |||
1103 | switch (state->cfg->lg_chip) { | ||
1104 | case LG2160: | ||
1105 | ret = lg2160_set_spi_clock(state); | ||
1106 | if (lg_fail(ret)) | ||
1107 | goto fail; | ||
1108 | break; | ||
1109 | case LG2161: | ||
1110 | ret = lg2161_set_output_interface(state); | ||
1111 | if (lg_fail(ret)) | ||
1112 | goto fail; | ||
1113 | break; | ||
1114 | } | ||
1115 | |||
1116 | ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id); | ||
1117 | if (lg_fail(ret)) | ||
1118 | goto fail; | ||
1119 | |||
1120 | ret = lg216x_set_ensemble(state, | ||
1121 | fe->dtv_property_cache.atscmh_rs_frame_ensemble); | ||
1122 | if (lg_fail(ret)) | ||
1123 | goto fail; | ||
1124 | |||
1125 | ret = lg216x_initialize(state); | ||
1126 | if (lg_fail(ret)) | ||
1127 | goto fail; | ||
1128 | |||
1129 | ret = lg216x_enable_fic(state, 1); | ||
1130 | lg_fail(ret); | ||
1131 | |||
1132 | lg216x_get_frontend(fe); | ||
1133 | fail: | ||
1134 | return ret; | ||
1135 | } | ||
1136 | |||
1137 | /* ------------------------------------------------------------------------ */ | ||
1138 | |||
1139 | static int lg2160_read_lock_status(struct lg216x_state *state, | ||
1140 | int *acq_lock, int *sync_lock) | ||
1141 | { | ||
1142 | u8 val; | ||
1143 | int ret; | ||
1144 | |||
1145 | *acq_lock = 0; | ||
1146 | *sync_lock = 0; | ||
1147 | |||
1148 | ret = lg216x_read_reg(state, 0x011b, &val); | ||
1149 | if (lg_fail(ret)) | ||
1150 | goto fail; | ||
1151 | |||
1152 | *sync_lock = (val & 0x20) ? 0 : 1; | ||
1153 | *acq_lock = (val & 0x40) ? 0 : 1; | ||
1154 | fail: | ||
1155 | return ret; | ||
1156 | } | ||
1157 | |||
1158 | #ifdef USE_LG2161_LOCK_BITS | ||
1159 | static int lg2161_read_lock_status(struct lg216x_state *state, | ||
1160 | int *acq_lock, int *sync_lock) | ||
1161 | { | ||
1162 | u8 val; | ||
1163 | int ret; | ||
1164 | |||
1165 | *acq_lock = 0; | ||
1166 | *sync_lock = 0; | ||
1167 | |||
1168 | ret = lg216x_read_reg(state, 0x0304, &val); | ||
1169 | if (lg_fail(ret)) | ||
1170 | goto fail; | ||
1171 | |||
1172 | *sync_lock = (val & 0x80) ? 0 : 1; | ||
1173 | |||
1174 | ret = lg216x_read_reg(state, 0x011b, &val); | ||
1175 | if (lg_fail(ret)) | ||
1176 | goto fail; | ||
1177 | |||
1178 | *acq_lock = (val & 0x40) ? 0 : 1; | ||
1179 | fail: | ||
1180 | return ret; | ||
1181 | } | ||
1182 | #endif | ||
1183 | |||
1184 | static int lg216x_read_lock_status(struct lg216x_state *state, | ||
1185 | int *acq_lock, int *sync_lock) | ||
1186 | { | ||
1187 | #ifdef USE_LG2161_LOCK_BITS | ||
1188 | int ret; | ||
1189 | switch (state->cfg->lg_chip) { | ||
1190 | case LG2160: | ||
1191 | ret = lg2160_read_lock_status(state, acq_lock, sync_lock); | ||
1192 | break; | ||
1193 | case LG2161: | ||
1194 | ret = lg2161_read_lock_status(state, acq_lock, sync_lock); | ||
1195 | break; | ||
1196 | default: | ||
1197 | ret = -EINVAL; | ||
1198 | break; | ||
1199 | } | ||
1200 | return ret; | ||
1201 | #else | ||
1202 | return lg2160_read_lock_status(state, acq_lock, sync_lock); | ||
1203 | #endif | ||
1204 | } | ||
1205 | |||
1206 | static int lg216x_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
1207 | { | ||
1208 | struct lg216x_state *state = fe->demodulator_priv; | ||
1209 | int ret, acq_lock, sync_lock; | ||
1210 | |||
1211 | *status = 0; | ||
1212 | |||
1213 | ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock); | ||
1214 | if (lg_fail(ret)) | ||
1215 | goto fail; | ||
1216 | |||
1217 | lg_dbg("%s%s\n", | ||
1218 | acq_lock ? "SIGNALEXIST " : "", | ||
1219 | sync_lock ? "SYNCLOCK" : ""); | ||
1220 | |||
1221 | if (acq_lock) | ||
1222 | *status |= FE_HAS_SIGNAL; | ||
1223 | if (sync_lock) | ||
1224 | *status |= FE_HAS_SYNC; | ||
1225 | |||
1226 | if (*status) | ||
1227 | *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; | ||
1228 | |||
1229 | fail: | ||
1230 | return ret; | ||
1231 | } | ||
1232 | |||
1233 | /* ------------------------------------------------------------------------ */ | ||
1234 | |||
1235 | static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1236 | { | ||
1237 | struct lg216x_state *state = fe->demodulator_priv; | ||
1238 | u8 snr1, snr2; | ||
1239 | int ret; | ||
1240 | |||
1241 | *snr = 0; | ||
1242 | |||
1243 | ret = lg216x_read_reg(state, 0x0202, &snr1); | ||
1244 | if (lg_fail(ret)) | ||
1245 | goto fail; | ||
1246 | |||
1247 | ret = lg216x_read_reg(state, 0x0203, &snr2); | ||
1248 | if (lg_fail(ret)) | ||
1249 | goto fail; | ||
1250 | |||
1251 | if ((snr1 == 0xba) || (snr2 == 0xdf)) | ||
1252 | *snr = 0; | ||
1253 | else | ||
1254 | #if 1 | ||
1255 | *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4); | ||
1256 | #else /* BCD */ | ||
1257 | *snr = (snr2 | (snr1 << 8)); | ||
1258 | #endif | ||
1259 | fail: | ||
1260 | return ret; | ||
1261 | } | ||
1262 | |||
1263 | static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1264 | { | ||
1265 | struct lg216x_state *state = fe->demodulator_priv; | ||
1266 | u8 snr1, snr2; | ||
1267 | int ret; | ||
1268 | |||
1269 | *snr = 0; | ||
1270 | |||
1271 | ret = lg216x_read_reg(state, 0x0302, &snr1); | ||
1272 | if (lg_fail(ret)) | ||
1273 | goto fail; | ||
1274 | |||
1275 | ret = lg216x_read_reg(state, 0x0303, &snr2); | ||
1276 | if (lg_fail(ret)) | ||
1277 | goto fail; | ||
1278 | |||
1279 | if ((snr1 == 0xba) || (snr2 == 0xfd)) | ||
1280 | *snr = 0; | ||
1281 | else | ||
1282 | |||
1283 | *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f); | ||
1284 | fail: | ||
1285 | return ret; | ||
1286 | } | ||
1287 | |||
1288 | static int lg216x_read_signal_strength(struct dvb_frontend *fe, | ||
1289 | u16 *strength) | ||
1290 | { | ||
1291 | #if 0 | ||
1292 | /* borrowed from lgdt330x.c | ||
1293 | * | ||
1294 | * Calculate strength from SNR up to 35dB | ||
1295 | * Even though the SNR can go higher than 35dB, | ||
1296 | * there is some comfort factor in having a range of | ||
1297 | * strong signals that can show at 100% | ||
1298 | */ | ||
1299 | struct lg216x_state *state = fe->demodulator_priv; | ||
1300 | u16 snr; | ||
1301 | int ret; | ||
1302 | #endif | ||
1303 | *strength = 0; | ||
1304 | #if 0 | ||
1305 | ret = fe->ops.read_snr(fe, &snr); | ||
1306 | if (lg_fail(ret)) | ||
1307 | goto fail; | ||
1308 | /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ | ||
1309 | /* scale the range 0 - 35*2^24 into 0 - 65535 */ | ||
1310 | if (state->snr >= 8960 * 0x10000) | ||
1311 | *strength = 0xffff; | ||
1312 | else | ||
1313 | *strength = state->snr / 8960; | ||
1314 | fail: | ||
1315 | return ret; | ||
1316 | #else | ||
1317 | return 0; | ||
1318 | #endif | ||
1319 | } | ||
1320 | |||
1321 | /* ------------------------------------------------------------------------ */ | ||
1322 | |||
1323 | static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
1324 | { | ||
1325 | #if 0 | ||
1326 | struct lg216x_state *state = fe->demodulator_priv; | ||
1327 | int ret; | ||
1328 | |||
1329 | ret = lg216x_read_rs_err_count(state, | ||
1330 | &fe->dtv_property_cache.atscmh_rs_err); | ||
1331 | if (lg_fail(ret)) | ||
1332 | goto fail; | ||
1333 | |||
1334 | *ucblocks = fe->dtv_property_cache.atscmh_rs_err; | ||
1335 | fail: | ||
1336 | #else | ||
1337 | *ucblocks = 0; | ||
1338 | #endif | ||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static int lg216x_get_tune_settings(struct dvb_frontend *fe, | ||
1343 | struct dvb_frontend_tune_settings | ||
1344 | *fe_tune_settings) | ||
1345 | { | ||
1346 | fe_tune_settings->min_delay_ms = 500; | ||
1347 | lg_dbg("\n"); | ||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | static void lg216x_release(struct dvb_frontend *fe) | ||
1352 | { | ||
1353 | struct lg216x_state *state = fe->demodulator_priv; | ||
1354 | lg_dbg("\n"); | ||
1355 | kfree(state); | ||
1356 | } | ||
1357 | |||
1358 | static struct dvb_frontend_ops lg2160_ops = { | ||
1359 | .delsys = { SYS_ATSCMH }, | ||
1360 | .info = { | ||
1361 | .name = "LG Electronics LG2160 ATSC/MH Frontend", | ||
1362 | .frequency_min = 54000000, | ||
1363 | .frequency_max = 858000000, | ||
1364 | .frequency_stepsize = 62500, | ||
1365 | }, | ||
1366 | .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, | ||
1367 | #if 0 | ||
1368 | .init = lg216x_init, | ||
1369 | .sleep = lg216x_sleep, | ||
1370 | #endif | ||
1371 | .get_property = lg216x_get_property, | ||
1372 | |||
1373 | .set_frontend = lg2160_set_frontend, | ||
1374 | .get_frontend = lg216x_get_frontend, | ||
1375 | .get_tune_settings = lg216x_get_tune_settings, | ||
1376 | .read_status = lg216x_read_status, | ||
1377 | #if 0 | ||
1378 | .read_ber = lg216x_read_ber, | ||
1379 | #endif | ||
1380 | .read_signal_strength = lg216x_read_signal_strength, | ||
1381 | .read_snr = lg2160_read_snr, | ||
1382 | .read_ucblocks = lg216x_read_ucblocks, | ||
1383 | .release = lg216x_release, | ||
1384 | }; | ||
1385 | |||
1386 | static struct dvb_frontend_ops lg2161_ops = { | ||
1387 | .delsys = { SYS_ATSCMH }, | ||
1388 | .info = { | ||
1389 | .name = "LG Electronics LG2161 ATSC/MH Frontend", | ||
1390 | .frequency_min = 54000000, | ||
1391 | .frequency_max = 858000000, | ||
1392 | .frequency_stepsize = 62500, | ||
1393 | }, | ||
1394 | .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, | ||
1395 | #if 0 | ||
1396 | .init = lg216x_init, | ||
1397 | .sleep = lg216x_sleep, | ||
1398 | #endif | ||
1399 | .get_property = lg216x_get_property, | ||
1400 | |||
1401 | .set_frontend = lg2160_set_frontend, | ||
1402 | .get_frontend = lg216x_get_frontend, | ||
1403 | .get_tune_settings = lg216x_get_tune_settings, | ||
1404 | .read_status = lg216x_read_status, | ||
1405 | #if 0 | ||
1406 | .read_ber = lg216x_read_ber, | ||
1407 | #endif | ||
1408 | .read_signal_strength = lg216x_read_signal_strength, | ||
1409 | .read_snr = lg2161_read_snr, | ||
1410 | .read_ucblocks = lg216x_read_ucblocks, | ||
1411 | .release = lg216x_release, | ||
1412 | }; | ||
1413 | |||
1414 | struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, | ||
1415 | struct i2c_adapter *i2c_adap) | ||
1416 | { | ||
1417 | struct lg216x_state *state = NULL; | ||
1418 | |||
1419 | lg_dbg("(%d-%04x)\n", | ||
1420 | i2c_adap ? i2c_adapter_id(i2c_adap) : 0, | ||
1421 | config ? config->i2c_addr : 0); | ||
1422 | |||
1423 | state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL); | ||
1424 | if (state == NULL) | ||
1425 | goto fail; | ||
1426 | |||
1427 | state->cfg = config; | ||
1428 | state->i2c_adap = i2c_adap; | ||
1429 | state->fic_ver = 0xff; | ||
1430 | state->parade_id = 0xff; | ||
1431 | |||
1432 | switch (config->lg_chip) { | ||
1433 | default: | ||
1434 | lg_warn("invalid chip requested, defaulting to LG2160"); | ||
1435 | /* fall-thru */ | ||
1436 | case LG2160: | ||
1437 | memcpy(&state->frontend.ops, &lg2160_ops, | ||
1438 | sizeof(struct dvb_frontend_ops)); | ||
1439 | break; | ||
1440 | case LG2161: | ||
1441 | memcpy(&state->frontend.ops, &lg2161_ops, | ||
1442 | sizeof(struct dvb_frontend_ops)); | ||
1443 | break; | ||
1444 | } | ||
1445 | |||
1446 | state->frontend.demodulator_priv = state; | ||
1447 | state->current_frequency = -1; | ||
1448 | /* parade 1 by default */ | ||
1449 | state->frontend.dtv_property_cache.atscmh_parade_id = 1; | ||
1450 | |||
1451 | return &state->frontend; | ||
1452 | fail: | ||
1453 | lg_warn("unable to detect LG216x hardware\n"); | ||
1454 | kfree(state); | ||
1455 | return NULL; | ||
1456 | } | ||
1457 | EXPORT_SYMBOL(lg2160_attach); | ||
1458 | |||
1459 | MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); | ||
1460 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | ||
1461 | MODULE_LICENSE("GPL"); | ||
1462 | MODULE_VERSION("0.3"); | ||
1463 | |||
1464 | /* | ||
1465 | * Local variables: | ||
1466 | * c-basic-offset: 8 | ||
1467 | * End: | ||
1468 | */ | ||
diff --git a/drivers/media/dvb/frontends/lg2160.h b/drivers/media/dvb/frontends/lg2160.h new file mode 100644 index 000000000000..9e2c0f41199a --- /dev/null +++ b/drivers/media/dvb/frontends/lg2160.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Support for LG2160 - ATSC/MH | ||
3 | * | ||
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef _LG2160_H_ | ||
23 | #define _LG2160_H_ | ||
24 | |||
25 | #include <linux/i2c.h> | ||
26 | #include "dvb_frontend.h" | ||
27 | |||
28 | enum lg_chip_type { | ||
29 | LG2160 = 0, | ||
30 | LG2161 = 1, | ||
31 | }; | ||
32 | |||
33 | #define LG2161_1019 LG2161 | ||
34 | #define LG2161_1040 LG2161 | ||
35 | |||
36 | enum lg2160_spi_clock { | ||
37 | LG2160_SPI_3_125_MHZ = 0, | ||
38 | LG2160_SPI_6_25_MHZ = 1, | ||
39 | LG2160_SPI_12_5_MHZ = 2, | ||
40 | }; | ||
41 | |||
42 | #if 0 | ||
43 | enum lg2161_oif { | ||
44 | LG2161_OIF_EBI2_SLA = 1, | ||
45 | LG2161_OIF_SDIO_SLA = 2, | ||
46 | LG2161_OIF_SPI_SLA = 3, | ||
47 | LG2161_OIF_SPI_MAS = 4, | ||
48 | LG2161_OIF_SERIAL_TS = 7, | ||
49 | }; | ||
50 | #endif | ||
51 | |||
52 | struct lg2160_config { | ||
53 | u8 i2c_addr; | ||
54 | |||
55 | /* user defined IF frequency in KHz */ | ||
56 | u16 if_khz; | ||
57 | |||
58 | /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ | ||
59 | int deny_i2c_rptr:1; | ||
60 | |||
61 | /* spectral inversion - 0:disabled 1:enabled */ | ||
62 | int spectral_inversion:1; | ||
63 | |||
64 | unsigned int output_if; | ||
65 | enum lg2160_spi_clock spi_clock; | ||
66 | enum lg_chip_type lg_chip; | ||
67 | }; | ||
68 | |||
69 | #if defined(CONFIG_DVB_LG2160) || (defined(CONFIG_DVB_LG2160_MODULE) && \ | ||
70 | defined(MODULE)) | ||
71 | extern | ||
72 | struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, | ||
73 | struct i2c_adapter *i2c_adap); | ||
74 | #else | ||
75 | static inline | ||
76 | struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, | ||
77 | struct i2c_adapter *i2c_adap) | ||
78 | { | ||
79 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
80 | return NULL; | ||
81 | } | ||
82 | #endif /* CONFIG_DVB_LG2160 */ | ||
83 | |||
84 | #endif /* _LG2160_H_ */ | ||
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index 4de1d3520cd2..568363a10a31 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c | |||
@@ -262,7 +262,6 @@ static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) | |||
262 | 262 | ||
263 | static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) | 263 | static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) |
264 | { | 264 | { |
265 | int ret = 0; | ||
266 | u8 t; | 265 | u8 t; |
267 | 266 | ||
268 | if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { | 267 | if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { |
@@ -296,7 +295,7 @@ static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) | |||
296 | if (priv->config->prod == LGS8GXX_PROD_LGS8913) | 295 | if (priv->config->prod == LGS8GXX_PROD_LGS8913) |
297 | lgs8gxx_write_reg(priv, 0xC1, 0); | 296 | lgs8gxx_write_reg(priv, 0xC1, 0); |
298 | 297 | ||
299 | ret = lgs8gxx_read_reg(priv, 0xC5, &t); | 298 | lgs8gxx_read_reg(priv, 0xC5, &t); |
300 | t = (t & 0xE0) | 0x06; | 299 | t = (t & 0xE0) | 0x06; |
301 | lgs8gxx_write_reg(priv, 0xC5, t); | 300 | lgs8gxx_write_reg(priv, 0xC5, t); |
302 | 301 | ||
diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c index 045ee5a6f7ae..312588e84dae 100644 --- a/drivers/media/dvb/frontends/m88rs2000.c +++ b/drivers/media/dvb/frontends/m88rs2000.c | |||
@@ -416,9 +416,25 @@ static int m88rs2000_tab_set(struct m88rs2000_state *state, | |||
416 | 416 | ||
417 | static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) | 417 | static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) |
418 | { | 418 | { |
419 | deb_info("%s: %s\n", __func__, | 419 | struct m88rs2000_state *state = fe->demodulator_priv; |
420 | volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : | 420 | u8 data; |
421 | volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); | 421 | |
422 | data = m88rs2000_demod_read(state, 0xb2); | ||
423 | data |= 0x03; /* bit0 V/H, bit1 off/on */ | ||
424 | |||
425 | switch (volt) { | ||
426 | case SEC_VOLTAGE_18: | ||
427 | data &= ~0x03; | ||
428 | break; | ||
429 | case SEC_VOLTAGE_13: | ||
430 | data &= ~0x03; | ||
431 | data |= 0x01; | ||
432 | break; | ||
433 | case SEC_VOLTAGE_OFF: | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | m88rs2000_demod_write(state, 0xb2, data); | ||
422 | 438 | ||
423 | return 0; | 439 | return 0; |
424 | } | 440 | } |
@@ -654,7 +670,6 @@ static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset) | |||
654 | static int m88rs2000_set_fec(struct m88rs2000_state *state, | 670 | static int m88rs2000_set_fec(struct m88rs2000_state *state, |
655 | fe_code_rate_t fec) | 671 | fe_code_rate_t fec) |
656 | { | 672 | { |
657 | int ret; | ||
658 | u16 fec_set; | 673 | u16 fec_set; |
659 | switch (fec) { | 674 | switch (fec) { |
660 | /* This is not confirmed kept for reference */ | 675 | /* This is not confirmed kept for reference */ |
@@ -677,7 +692,7 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state, | |||
677 | default: | 692 | default: |
678 | fec_set = 0x08; | 693 | fec_set = 0x08; |
679 | } | 694 | } |
680 | ret = m88rs2000_demod_write(state, 0x76, fec_set); | 695 | m88rs2000_demod_write(state, 0x76, fec_set); |
681 | 696 | ||
682 | return 0; | 697 | return 0; |
683 | } | 698 | } |
@@ -772,13 +787,13 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe) | |||
772 | return -ENODEV; | 787 | return -ENODEV; |
773 | 788 | ||
774 | for (i = 0; i < 25; i++) { | 789 | for (i = 0; i < 25; i++) { |
775 | u8 reg = m88rs2000_demod_read(state, 0x8c); | 790 | reg = m88rs2000_demod_read(state, 0x8c); |
776 | if ((reg & 0x7) == 0x7) { | 791 | if ((reg & 0x7) == 0x7) { |
777 | status = FE_HAS_LOCK; | 792 | status = FE_HAS_LOCK; |
778 | break; | 793 | break; |
779 | } | 794 | } |
780 | state->no_lock_count++; | 795 | state->no_lock_count++; |
781 | if (state->no_lock_count > 15) { | 796 | if (state->no_lock_count == 15) { |
782 | reg = m88rs2000_demod_read(state, 0x70); | 797 | reg = m88rs2000_demod_read(state, 0x70); |
783 | reg ^= 0x4; | 798 | reg ^= 0x4; |
784 | m88rs2000_demod_write(state, 0x70, reg); | 799 | m88rs2000_demod_write(state, 0x70, reg); |
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb/frontends/rtl2830.c index 45196c5b0736..93612ebac519 100644 --- a/drivers/media/dvb/frontends/rtl2830.c +++ b/drivers/media/dvb/frontends/rtl2830.c | |||
@@ -374,6 +374,118 @@ err: | |||
374 | return ret; | 374 | return ret; |
375 | } | 375 | } |
376 | 376 | ||
377 | static int rtl2830_get_frontend(struct dvb_frontend *fe) | ||
378 | { | ||
379 | struct rtl2830_priv *priv = fe->demodulator_priv; | ||
380 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
381 | int ret; | ||
382 | u8 buf[3]; | ||
383 | |||
384 | if (priv->sleeping) | ||
385 | return 0; | ||
386 | |||
387 | ret = rtl2830_rd_regs(priv, 0x33c, buf, 2); | ||
388 | if (ret) | ||
389 | goto err; | ||
390 | |||
391 | ret = rtl2830_rd_reg(priv, 0x351, &buf[2]); | ||
392 | if (ret) | ||
393 | goto err; | ||
394 | |||
395 | dbg("%s: TPS=%02x %02x %02x", __func__, buf[0], buf[1], buf[2]); | ||
396 | |||
397 | switch ((buf[0] >> 2) & 3) { | ||
398 | case 0: | ||
399 | c->modulation = QPSK; | ||
400 | break; | ||
401 | case 1: | ||
402 | c->modulation = QAM_16; | ||
403 | break; | ||
404 | case 2: | ||
405 | c->modulation = QAM_64; | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | switch ((buf[2] >> 2) & 1) { | ||
410 | case 0: | ||
411 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
412 | break; | ||
413 | case 1: | ||
414 | c->transmission_mode = TRANSMISSION_MODE_8K; | ||
415 | } | ||
416 | |||
417 | switch ((buf[2] >> 0) & 3) { | ||
418 | case 0: | ||
419 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
420 | break; | ||
421 | case 1: | ||
422 | c->guard_interval = GUARD_INTERVAL_1_16; | ||
423 | break; | ||
424 | case 2: | ||
425 | c->guard_interval = GUARD_INTERVAL_1_8; | ||
426 | break; | ||
427 | case 3: | ||
428 | c->guard_interval = GUARD_INTERVAL_1_4; | ||
429 | break; | ||
430 | } | ||
431 | |||
432 | switch ((buf[0] >> 4) & 7) { | ||
433 | case 0: | ||
434 | c->hierarchy = HIERARCHY_NONE; | ||
435 | break; | ||
436 | case 1: | ||
437 | c->hierarchy = HIERARCHY_1; | ||
438 | break; | ||
439 | case 2: | ||
440 | c->hierarchy = HIERARCHY_2; | ||
441 | break; | ||
442 | case 3: | ||
443 | c->hierarchy = HIERARCHY_4; | ||
444 | break; | ||
445 | } | ||
446 | |||
447 | switch ((buf[1] >> 3) & 7) { | ||
448 | case 0: | ||
449 | c->code_rate_HP = FEC_1_2; | ||
450 | break; | ||
451 | case 1: | ||
452 | c->code_rate_HP = FEC_2_3; | ||
453 | break; | ||
454 | case 2: | ||
455 | c->code_rate_HP = FEC_3_4; | ||
456 | break; | ||
457 | case 3: | ||
458 | c->code_rate_HP = FEC_5_6; | ||
459 | break; | ||
460 | case 4: | ||
461 | c->code_rate_HP = FEC_7_8; | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | switch ((buf[1] >> 0) & 7) { | ||
466 | case 0: | ||
467 | c->code_rate_LP = FEC_1_2; | ||
468 | break; | ||
469 | case 1: | ||
470 | c->code_rate_LP = FEC_2_3; | ||
471 | break; | ||
472 | case 2: | ||
473 | c->code_rate_LP = FEC_3_4; | ||
474 | break; | ||
475 | case 3: | ||
476 | c->code_rate_LP = FEC_5_6; | ||
477 | break; | ||
478 | case 4: | ||
479 | c->code_rate_LP = FEC_7_8; | ||
480 | break; | ||
481 | } | ||
482 | |||
483 | return 0; | ||
484 | err: | ||
485 | dbg("%s: failed=%d", __func__, ret); | ||
486 | return ret; | ||
487 | } | ||
488 | |||
377 | static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) | 489 | static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) |
378 | { | 490 | { |
379 | struct rtl2830_priv *priv = fe->demodulator_priv; | 491 | struct rtl2830_priv *priv = fe->demodulator_priv; |
@@ -404,14 +516,72 @@ err: | |||
404 | 516 | ||
405 | static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr) | 517 | static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr) |
406 | { | 518 | { |
407 | *snr = 0; | 519 | struct rtl2830_priv *priv = fe->demodulator_priv; |
520 | int ret, hierarchy, constellation; | ||
521 | u8 buf[2], tmp; | ||
522 | u16 tmp16; | ||
523 | #define CONSTELLATION_NUM 3 | ||
524 | #define HIERARCHY_NUM 4 | ||
525 | static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = { | ||
526 | { 70705899, 70705899, 70705899, 70705899 }, | ||
527 | { 82433173, 82433173, 87483115, 94445660 }, | ||
528 | { 92888734, 92888734, 95487525, 99770748 }, | ||
529 | }; | ||
530 | |||
531 | if (priv->sleeping) | ||
532 | return 0; | ||
533 | |||
534 | /* reports SNR in resolution of 0.1 dB */ | ||
535 | |||
536 | ret = rtl2830_rd_reg(priv, 0x33c, &tmp); | ||
537 | if (ret) | ||
538 | goto err; | ||
539 | |||
540 | constellation = (tmp >> 2) & 0x03; /* [3:2] */ | ||
541 | if (constellation > CONSTELLATION_NUM - 1) | ||
542 | goto err; | ||
543 | |||
544 | hierarchy = (tmp >> 4) & 0x07; /* [6:4] */ | ||
545 | if (hierarchy > HIERARCHY_NUM - 1) | ||
546 | goto err; | ||
547 | |||
548 | ret = rtl2830_rd_regs(priv, 0x40c, buf, 2); | ||
549 | if (ret) | ||
550 | goto err; | ||
551 | |||
552 | tmp16 = buf[0] << 8 | buf[1]; | ||
553 | |||
554 | if (tmp16) | ||
555 | *snr = (snr_constant[constellation][hierarchy] - | ||
556 | intlog10(tmp16)) / ((1 << 24) / 100); | ||
557 | else | ||
558 | *snr = 0; | ||
559 | |||
408 | return 0; | 560 | return 0; |
561 | err: | ||
562 | dbg("%s: failed=%d", __func__, ret); | ||
563 | return ret; | ||
409 | } | 564 | } |
410 | 565 | ||
411 | static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber) | 566 | static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber) |
412 | { | 567 | { |
413 | *ber = 0; | 568 | struct rtl2830_priv *priv = fe->demodulator_priv; |
569 | int ret; | ||
570 | u8 buf[2]; | ||
571 | |||
572 | if (priv->sleeping) | ||
573 | return 0; | ||
574 | |||
575 | ret = rtl2830_rd_regs(priv, 0x34e, buf, 2); | ||
576 | if (ret) | ||
577 | goto err; | ||
578 | |||
579 | *ber = buf[0] << 8 | buf[1]; | ||
580 | |||
414 | return 0; | 581 | return 0; |
582 | err: | ||
583 | dbg("%s: failed=%d", __func__, ret); | ||
584 | return ret; | ||
415 | } | 585 | } |
416 | 586 | ||
417 | static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 587 | static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
@@ -422,8 +592,32 @@ static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | |||
422 | 592 | ||
423 | static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 593 | static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
424 | { | 594 | { |
425 | *strength = 0; | 595 | struct rtl2830_priv *priv = fe->demodulator_priv; |
596 | int ret; | ||
597 | u8 buf[2]; | ||
598 | u16 if_agc_raw, if_agc; | ||
599 | |||
600 | if (priv->sleeping) | ||
601 | return 0; | ||
602 | |||
603 | ret = rtl2830_rd_regs(priv, 0x359, buf, 2); | ||
604 | if (ret) | ||
605 | goto err; | ||
606 | |||
607 | if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff; | ||
608 | |||
609 | if (if_agc_raw & (1 << 9)) | ||
610 | if_agc = -(~(if_agc_raw - 1) & 0x1ff); | ||
611 | else | ||
612 | if_agc = if_agc_raw; | ||
613 | |||
614 | *strength = (u8) (55 - if_agc / 182); | ||
615 | *strength |= *strength << 8; | ||
616 | |||
426 | return 0; | 617 | return 0; |
618 | err: | ||
619 | dbg("%s: failed=%d", __func__, ret); | ||
620 | return ret; | ||
427 | } | 621 | } |
428 | 622 | ||
429 | static struct dvb_frontend_ops rtl2830_ops; | 623 | static struct dvb_frontend_ops rtl2830_ops; |
@@ -549,6 +743,7 @@ static struct dvb_frontend_ops rtl2830_ops = { | |||
549 | .get_tune_settings = rtl2830_get_tune_settings, | 743 | .get_tune_settings = rtl2830_get_tune_settings, |
550 | 744 | ||
551 | .set_frontend = rtl2830_set_frontend, | 745 | .set_frontend = rtl2830_set_frontend, |
746 | .get_frontend = rtl2830_get_frontend, | ||
552 | 747 | ||
553 | .read_status = rtl2830_read_status, | 748 | .read_status = rtl2830_read_status, |
554 | .read_snr = rtl2830_read_snr, | 749 | .read_snr = rtl2830_read_snr, |
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb/frontends/rtl2830_priv.h index 4a464761b5b8..9b20557ccf6c 100644 --- a/drivers/media/dvb/frontends/rtl2830_priv.h +++ b/drivers/media/dvb/frontends/rtl2830_priv.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define RTL2830_PRIV_H | 22 | #define RTL2830_PRIV_H |
23 | 23 | ||
24 | #include "dvb_frontend.h" | 24 | #include "dvb_frontend.h" |
25 | #include "dvb_math.h" | ||
25 | #include "rtl2830.h" | 26 | #include "rtl2830.h" |
26 | 27 | ||
27 | #define LOG_PREFIX "rtl2830" | 28 | #define LOG_PREFIX "rtl2830" |
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index dd08f4ac64a8..8b0dc74a3298 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c | |||
@@ -637,11 +637,9 @@ static void stb0899_init_calc(struct stb0899_state *state) | |||
637 | struct stb0899_internal *internal = &state->internal; | 637 | struct stb0899_internal *internal = &state->internal; |
638 | int master_clk; | 638 | int master_clk; |
639 | u8 agc[2]; | 639 | u8 agc[2]; |
640 | u8 agc1cn; | ||
641 | u32 reg; | 640 | u32 reg; |
642 | 641 | ||
643 | /* Read registers (in burst mode) */ | 642 | /* Read registers (in burst mode) */ |
644 | agc1cn = stb0899_read_reg(state, STB0899_AGC1CN); | ||
645 | stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ | 643 | stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ |
646 | 644 | ||
647 | /* Initial calculations */ | 645 | /* Initial calculations */ |
@@ -823,15 +821,12 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t | |||
823 | 821 | ||
824 | static int stb0899_diseqc_init(struct stb0899_state *state) | 822 | static int stb0899_diseqc_init(struct stb0899_state *state) |
825 | { | 823 | { |
826 | struct dvb_diseqc_master_cmd tx_data; | ||
827 | /* | 824 | /* |
828 | struct dvb_diseqc_slave_reply rx_data; | 825 | struct dvb_diseqc_slave_reply rx_data; |
829 | */ | 826 | */ |
830 | u8 f22_tx, f22_rx, reg; | 827 | u8 f22_tx, reg; |
831 | 828 | ||
832 | u32 mclk, tx_freq = 22000;/* count = 0, i; */ | 829 | u32 mclk, tx_freq = 22000;/* count = 0, i; */ |
833 | tx_data.msg[0] = 0xe2; | ||
834 | tx_data.msg_len = 3; | ||
835 | reg = stb0899_read_reg(state, STB0899_DISCNTRL2); | 830 | reg = stb0899_read_reg(state, STB0899_DISCNTRL2); |
836 | STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); | 831 | STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); |
837 | stb0899_write_reg(state, STB0899_DISCNTRL2, reg); | 832 | stb0899_write_reg(state, STB0899_DISCNTRL2, reg); |
@@ -849,7 +844,6 @@ static int stb0899_diseqc_init(struct stb0899_state *state) | |||
849 | f22_tx = mclk / (tx_freq * 32); | 844 | f22_tx = mclk / (tx_freq * 32); |
850 | stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ | 845 | stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ |
851 | state->rx_freq = 20000; | 846 | state->rx_freq = 20000; |
852 | f22_rx = mclk / (state->rx_freq * 32); | ||
853 | 847 | ||
854 | return 0; | 848 | return 0; |
855 | } | 849 | } |
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index def88abb30bf..2e93e65d2cdb 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c | |||
@@ -158,7 +158,6 @@ static int stb6100_read_regs(struct stb6100_state *state, u8 regs[]) | |||
158 | static int stb6100_read_reg(struct stb6100_state *state, u8 reg) | 158 | static int stb6100_read_reg(struct stb6100_state *state, u8 reg) |
159 | { | 159 | { |
160 | u8 regs[STB6100_NUMREGS]; | 160 | u8 regs[STB6100_NUMREGS]; |
161 | int rc; | ||
162 | 161 | ||
163 | struct i2c_msg msg = { | 162 | struct i2c_msg msg = { |
164 | .addr = state->config->tuner_address + reg, | 163 | .addr = state->config->tuner_address + reg, |
@@ -167,7 +166,7 @@ static int stb6100_read_reg(struct stb6100_state *state, u8 reg) | |||
167 | .len = 1 | 166 | .len = 1 |
168 | }; | 167 | }; |
169 | 168 | ||
170 | rc = i2c_transfer(state->i2c, &msg, 1); | 169 | i2c_transfer(state->i2c, &msg, 1); |
171 | 170 | ||
172 | if (unlikely(reg >= STB6100_NUMREGS)) { | 171 | if (unlikely(reg >= STB6100_NUMREGS)) { |
173 | dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); | 172 | dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); |
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 85c157a1fe5e..d40f226160ef 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c | |||
@@ -414,7 +414,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe) | |||
414 | int delay; | 414 | int delay; |
415 | int sweeprate; | 415 | int sweeprate; |
416 | int carrieroffset; | 416 | int carrieroffset; |
417 | unsigned long starttime; | ||
418 | unsigned long timeout; | 417 | unsigned long timeout; |
419 | fe_spectral_inversion_t inversion; | 418 | fe_spectral_inversion_t inversion; |
420 | 419 | ||
@@ -543,7 +542,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe) | |||
543 | stv0297_writereg_mask(state, 0x43, 0x10, 0x10); | 542 | stv0297_writereg_mask(state, 0x43, 0x10, 0x10); |
544 | 543 | ||
545 | /* wait for WGAGC lock */ | 544 | /* wait for WGAGC lock */ |
546 | starttime = jiffies; | ||
547 | timeout = jiffies + msecs_to_jiffies(2000); | 545 | timeout = jiffies + msecs_to_jiffies(2000); |
548 | while (time_before(jiffies, timeout)) { | 546 | while (time_before(jiffies, timeout)) { |
549 | msleep(10); | 547 | msleep(10); |
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c index ba0709b2d433..4af20780fb9c 100644 --- a/drivers/media/dvb/frontends/stv0900_sw.c +++ b/drivers/media/dvb/frontends/stv0900_sw.c | |||
@@ -835,7 +835,6 @@ static void stv0900_track_optimization(struct dvb_frontend *fe) | |||
835 | blind_tun_sw = 0, | 835 | blind_tun_sw = 0, |
836 | modulation; | 836 | modulation; |
837 | 837 | ||
838 | enum fe_stv0900_rolloff rolloff; | ||
839 | enum fe_stv0900_modcode foundModcod; | 838 | enum fe_stv0900_modcode foundModcod; |
840 | 839 | ||
841 | dprintk("%s\n", __func__); | 840 | dprintk("%s\n", __func__); |
@@ -940,7 +939,6 @@ static void stv0900_track_optimization(struct dvb_frontend *fe) | |||
940 | 939 | ||
941 | freq1 = stv0900_read_reg(intp, CFR2); | 940 | freq1 = stv0900_read_reg(intp, CFR2); |
942 | freq0 = stv0900_read_reg(intp, CFR1); | 941 | freq0 = stv0900_read_reg(intp, CFR1); |
943 | rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); | ||
944 | if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { | 942 | if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { |
945 | stv0900_write_reg(intp, SFRSTEP, 0x00); | 943 | stv0900_write_reg(intp, SFRSTEP, 0x00); |
946 | stv0900_write_bits(intp, SCAN_ENABLE, 0); | 944 | stv0900_write_bits(intp, SCAN_ENABLE, 0); |
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 4aef1877ed42..d79e69f65cbb 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -2842,7 +2842,6 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2842 | { | 2842 | { |
2843 | struct dvb_frontend *fe = &state->frontend; | 2843 | struct dvb_frontend *fe = &state->frontend; |
2844 | 2844 | ||
2845 | enum stv090x_rolloff rolloff; | ||
2846 | enum stv090x_modcod modcod; | 2845 | enum stv090x_modcod modcod; |
2847 | 2846 | ||
2848 | s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; | 2847 | s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; |
@@ -2966,7 +2965,6 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2966 | f_1 = STV090x_READ_DEMOD(state, CFR2); | 2965 | f_1 = STV090x_READ_DEMOD(state, CFR2); |
2967 | f_0 = STV090x_READ_DEMOD(state, CFR1); | 2966 | f_0 = STV090x_READ_DEMOD(state, CFR1); |
2968 | reg = STV090x_READ_DEMOD(state, TMGOBS); | 2967 | reg = STV090x_READ_DEMOD(state, TMGOBS); |
2969 | rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); | ||
2970 | 2968 | ||
2971 | if (state->algo == STV090x_BLIND_SEARCH) { | 2969 | if (state->algo == STV090x_BLIND_SEARCH) { |
2972 | STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); | 2970 | STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); |
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index ac7237891374..82946cd517f5 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
@@ -525,7 +525,7 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
525 | zl10353_dump_regs(fe); | 525 | zl10353_dump_regs(fe); |
526 | 526 | ||
527 | _snr = zl10353_read_register(state, SNR); | 527 | _snr = zl10353_read_register(state, SNR); |
528 | *snr = (_snr << 8) | _snr; | 528 | *snr = 10 * _snr / 8; |
529 | 529 | ||
530 | return 0; | 530 | return 0; |
531 | } | 531 | } |
@@ -559,7 +559,6 @@ static int zl10353_init(struct dvb_frontend *fe) | |||
559 | { | 559 | { |
560 | struct zl10353_state *state = fe->demodulator_priv; | 560 | struct zl10353_state *state = fe->demodulator_priv; |
561 | u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; | 561 | u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; |
562 | int rc = 0; | ||
563 | 562 | ||
564 | if (debug_regs) | 563 | if (debug_regs) |
565 | zl10353_dump_regs(fe); | 564 | zl10353_dump_regs(fe); |
@@ -573,7 +572,7 @@ static int zl10353_init(struct dvb_frontend *fe) | |||
573 | /* Do a "hard" reset if not already done */ | 572 | /* Do a "hard" reset if not already done */ |
574 | if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || | 573 | if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || |
575 | zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) { | 574 | zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) { |
576 | rc = zl10353_write(fe, zl10353_reset_attach, | 575 | zl10353_write(fe, zl10353_reset_attach, |
577 | sizeof(zl10353_reset_attach)); | 576 | sizeof(zl10353_reset_attach)); |
578 | if (debug_regs) | 577 | if (debug_regs) |
579 | zl10353_dump_regs(fe); | 578 | zl10353_dump_regs(fe); |