1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Driver for the Conexant CX23885 PCIe bridge
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include "cx23885.h"
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/fs.h>
14*4882a593Smuzhiyun #include <linux/kthread.h>
15*4882a593Smuzhiyun #include <linux/file.h>
16*4882a593Smuzhiyun #include <linux/suspend.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <media/v4l2-common.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <media/dvb_ca_en50221.h>
21*4882a593Smuzhiyun #include "s5h1409.h"
22*4882a593Smuzhiyun #include "s5h1411.h"
23*4882a593Smuzhiyun #include "mt2131.h"
24*4882a593Smuzhiyun #include "tda8290.h"
25*4882a593Smuzhiyun #include "tda18271.h"
26*4882a593Smuzhiyun #include "lgdt330x.h"
27*4882a593Smuzhiyun #include "xc4000.h"
28*4882a593Smuzhiyun #include "xc5000.h"
29*4882a593Smuzhiyun #include "max2165.h"
30*4882a593Smuzhiyun #include "tda10048.h"
31*4882a593Smuzhiyun #include "tuner-xc2028.h"
32*4882a593Smuzhiyun #include "tuner-simple.h"
33*4882a593Smuzhiyun #include "dib7000p.h"
34*4882a593Smuzhiyun #include "dib0070.h"
35*4882a593Smuzhiyun #include "dibx000_common.h"
36*4882a593Smuzhiyun #include "zl10353.h"
37*4882a593Smuzhiyun #include "stv0900.h"
38*4882a593Smuzhiyun #include "stv0900_reg.h"
39*4882a593Smuzhiyun #include "stv6110.h"
40*4882a593Smuzhiyun #include "lnbh24.h"
41*4882a593Smuzhiyun #include "cx24116.h"
42*4882a593Smuzhiyun #include "cx24117.h"
43*4882a593Smuzhiyun #include "cimax2.h"
44*4882a593Smuzhiyun #include "lgs8gxx.h"
45*4882a593Smuzhiyun #include "netup-eeprom.h"
46*4882a593Smuzhiyun #include "netup-init.h"
47*4882a593Smuzhiyun #include "lgdt3305.h"
48*4882a593Smuzhiyun #include "atbm8830.h"
49*4882a593Smuzhiyun #include "ts2020.h"
50*4882a593Smuzhiyun #include "ds3000.h"
51*4882a593Smuzhiyun #include "cx23885-f300.h"
52*4882a593Smuzhiyun #include "altera-ci.h"
53*4882a593Smuzhiyun #include "stv0367.h"
54*4882a593Smuzhiyun #include "drxk.h"
55*4882a593Smuzhiyun #include "mt2063.h"
56*4882a593Smuzhiyun #include "stv090x.h"
57*4882a593Smuzhiyun #include "stb6100.h"
58*4882a593Smuzhiyun #include "stb6100_cfg.h"
59*4882a593Smuzhiyun #include "tda10071.h"
60*4882a593Smuzhiyun #include "a8293.h"
61*4882a593Smuzhiyun #include "mb86a20s.h"
62*4882a593Smuzhiyun #include "si2165.h"
63*4882a593Smuzhiyun #include "si2168.h"
64*4882a593Smuzhiyun #include "si2157.h"
65*4882a593Smuzhiyun #include "sp2.h"
66*4882a593Smuzhiyun #include "m88ds3103.h"
67*4882a593Smuzhiyun #include "m88rs6000t.h"
68*4882a593Smuzhiyun #include "lgdt3306a.h"
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static unsigned int debug;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun #define dprintk(level, fmt, arg...)\
73*4882a593Smuzhiyun do { if (debug >= level)\
74*4882a593Smuzhiyun printk(KERN_DEBUG pr_fmt("%s dvb: " fmt), \
75*4882a593Smuzhiyun __func__, ##arg); \
76*4882a593Smuzhiyun } while (0)
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* ------------------------------------------------------------------ */
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun static unsigned int alt_tuner;
81*4882a593Smuzhiyun module_param(alt_tuner, int, 0644);
82*4882a593Smuzhiyun MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration");
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* ------------------------------------------------------------------ */
87*4882a593Smuzhiyun
queue_setup(struct vb2_queue * q,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_devs[])88*4882a593Smuzhiyun static int queue_setup(struct vb2_queue *q,
89*4882a593Smuzhiyun unsigned int *num_buffers, unsigned int *num_planes,
90*4882a593Smuzhiyun unsigned int sizes[], struct device *alloc_devs[])
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun struct cx23885_tsport *port = q->drv_priv;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun port->ts_packet_size = 188 * 4;
95*4882a593Smuzhiyun port->ts_packet_count = 32;
96*4882a593Smuzhiyun *num_planes = 1;
97*4882a593Smuzhiyun sizes[0] = port->ts_packet_size * port->ts_packet_count;
98*4882a593Smuzhiyun *num_buffers = 32;
99*4882a593Smuzhiyun return 0;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun
buffer_prepare(struct vb2_buffer * vb)103*4882a593Smuzhiyun static int buffer_prepare(struct vb2_buffer *vb)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
106*4882a593Smuzhiyun struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
107*4882a593Smuzhiyun struct cx23885_buffer *buf =
108*4882a593Smuzhiyun container_of(vbuf, struct cx23885_buffer, vb);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun return cx23885_buf_prepare(buf, port);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
buffer_finish(struct vb2_buffer * vb)113*4882a593Smuzhiyun static void buffer_finish(struct vb2_buffer *vb)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
116*4882a593Smuzhiyun struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
117*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
118*4882a593Smuzhiyun struct cx23885_buffer *buf = container_of(vbuf,
119*4882a593Smuzhiyun struct cx23885_buffer, vb);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun cx23885_free_buffer(dev, buf);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
buffer_queue(struct vb2_buffer * vb)124*4882a593Smuzhiyun static void buffer_queue(struct vb2_buffer *vb)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
127*4882a593Smuzhiyun struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
128*4882a593Smuzhiyun struct cx23885_buffer *buf = container_of(vbuf,
129*4882a593Smuzhiyun struct cx23885_buffer, vb);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun cx23885_buf_queue(port, buf);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
cx23885_dvb_gate_ctrl(struct cx23885_tsport * port,int open)134*4882a593Smuzhiyun static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun struct vb2_dvb_frontends *f;
137*4882a593Smuzhiyun struct vb2_dvb_frontend *fe;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun f = &port->frontends;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (f->gate <= 1) /* undefined or fe0 */
142*4882a593Smuzhiyun fe = vb2_dvb_get_frontend(f, 1);
143*4882a593Smuzhiyun else
144*4882a593Smuzhiyun fe = vb2_dvb_get_frontend(f, f->gate);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
147*4882a593Smuzhiyun fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
cx23885_start_streaming(struct vb2_queue * q,unsigned int count)150*4882a593Smuzhiyun static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun struct cx23885_tsport *port = q->drv_priv;
153*4882a593Smuzhiyun struct cx23885_dmaqueue *dmaq = &port->mpegq;
154*4882a593Smuzhiyun struct cx23885_buffer *buf = list_entry(dmaq->active.next,
155*4882a593Smuzhiyun struct cx23885_buffer, queue);
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun cx23885_start_dma(port, dmaq, buf);
158*4882a593Smuzhiyun return 0;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
cx23885_stop_streaming(struct vb2_queue * q)161*4882a593Smuzhiyun static void cx23885_stop_streaming(struct vb2_queue *q)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct cx23885_tsport *port = q->drv_priv;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun cx23885_cancel_buffers(port);
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun static const struct vb2_ops dvb_qops = {
169*4882a593Smuzhiyun .queue_setup = queue_setup,
170*4882a593Smuzhiyun .buf_prepare = buffer_prepare,
171*4882a593Smuzhiyun .buf_finish = buffer_finish,
172*4882a593Smuzhiyun .buf_queue = buffer_queue,
173*4882a593Smuzhiyun .wait_prepare = vb2_ops_wait_prepare,
174*4882a593Smuzhiyun .wait_finish = vb2_ops_wait_finish,
175*4882a593Smuzhiyun .start_streaming = cx23885_start_streaming,
176*4882a593Smuzhiyun .stop_streaming = cx23885_stop_streaming,
177*4882a593Smuzhiyun };
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static struct s5h1409_config hauppauge_generic_config = {
180*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
181*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
182*4882a593Smuzhiyun .gpio = S5H1409_GPIO_ON,
183*4882a593Smuzhiyun .qam_if = 44000,
184*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_OFF,
185*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
186*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun static struct tda10048_config hauppauge_hvr1200_config = {
190*4882a593Smuzhiyun .demod_address = 0x10 >> 1,
191*4882a593Smuzhiyun .output_mode = TDA10048_SERIAL_OUTPUT,
192*4882a593Smuzhiyun .fwbulkwritelen = TDA10048_BULKWRITE_200,
193*4882a593Smuzhiyun .inversion = TDA10048_INVERSION_ON,
194*4882a593Smuzhiyun .dtv6_if_freq_khz = TDA10048_IF_3300,
195*4882a593Smuzhiyun .dtv7_if_freq_khz = TDA10048_IF_3800,
196*4882a593Smuzhiyun .dtv8_if_freq_khz = TDA10048_IF_4300,
197*4882a593Smuzhiyun .clk_freq_khz = TDA10048_CLK_16000,
198*4882a593Smuzhiyun };
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun static struct tda10048_config hauppauge_hvr1210_config = {
201*4882a593Smuzhiyun .demod_address = 0x10 >> 1,
202*4882a593Smuzhiyun .output_mode = TDA10048_SERIAL_OUTPUT,
203*4882a593Smuzhiyun .fwbulkwritelen = TDA10048_BULKWRITE_200,
204*4882a593Smuzhiyun .inversion = TDA10048_INVERSION_ON,
205*4882a593Smuzhiyun .dtv6_if_freq_khz = TDA10048_IF_3300,
206*4882a593Smuzhiyun .dtv7_if_freq_khz = TDA10048_IF_3500,
207*4882a593Smuzhiyun .dtv8_if_freq_khz = TDA10048_IF_4000,
208*4882a593Smuzhiyun .clk_freq_khz = TDA10048_CLK_16000,
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun static struct s5h1409_config hauppauge_ezqam_config = {
212*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
213*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
214*4882a593Smuzhiyun .gpio = S5H1409_GPIO_OFF,
215*4882a593Smuzhiyun .qam_if = 4000,
216*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_ON,
217*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
218*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun static struct s5h1409_config hauppauge_hvr1800lp_config = {
222*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
223*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
224*4882a593Smuzhiyun .gpio = S5H1409_GPIO_OFF,
225*4882a593Smuzhiyun .qam_if = 44000,
226*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_OFF,
227*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
228*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun static struct s5h1409_config hauppauge_hvr1500_config = {
232*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
233*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
234*4882a593Smuzhiyun .gpio = S5H1409_GPIO_OFF,
235*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_OFF,
236*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
237*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
238*4882a593Smuzhiyun };
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun static struct mt2131_config hauppauge_generic_tunerconfig = {
241*4882a593Smuzhiyun 0x61
242*4882a593Smuzhiyun };
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun static struct lgdt330x_config fusionhdtv_5_express = {
245*4882a593Smuzhiyun .demod_chip = LGDT3303,
246*4882a593Smuzhiyun .serial_mpeg = 0x40,
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun static struct s5h1409_config hauppauge_hvr1500q_config = {
250*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
251*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
252*4882a593Smuzhiyun .gpio = S5H1409_GPIO_ON,
253*4882a593Smuzhiyun .qam_if = 44000,
254*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_OFF,
255*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
256*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
257*4882a593Smuzhiyun };
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun static struct s5h1409_config dvico_s5h1409_config = {
260*4882a593Smuzhiyun .demod_address = 0x32 >> 1,
261*4882a593Smuzhiyun .output_mode = S5H1409_SERIAL_OUTPUT,
262*4882a593Smuzhiyun .gpio = S5H1409_GPIO_ON,
263*4882a593Smuzhiyun .qam_if = 44000,
264*4882a593Smuzhiyun .inversion = S5H1409_INVERSION_OFF,
265*4882a593Smuzhiyun .status_mode = S5H1409_DEMODLOCKING,
266*4882a593Smuzhiyun .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
267*4882a593Smuzhiyun };
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun static struct s5h1411_config dvico_s5h1411_config = {
270*4882a593Smuzhiyun .output_mode = S5H1411_SERIAL_OUTPUT,
271*4882a593Smuzhiyun .gpio = S5H1411_GPIO_ON,
272*4882a593Smuzhiyun .qam_if = S5H1411_IF_44000,
273*4882a593Smuzhiyun .vsb_if = S5H1411_IF_44000,
274*4882a593Smuzhiyun .inversion = S5H1411_INVERSION_OFF,
275*4882a593Smuzhiyun .status_mode = S5H1411_DEMODLOCKING,
276*4882a593Smuzhiyun .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun static struct s5h1411_config hcw_s5h1411_config = {
280*4882a593Smuzhiyun .output_mode = S5H1411_SERIAL_OUTPUT,
281*4882a593Smuzhiyun .gpio = S5H1411_GPIO_OFF,
282*4882a593Smuzhiyun .vsb_if = S5H1411_IF_44000,
283*4882a593Smuzhiyun .qam_if = S5H1411_IF_4000,
284*4882a593Smuzhiyun .inversion = S5H1411_INVERSION_ON,
285*4882a593Smuzhiyun .status_mode = S5H1411_DEMODLOCKING,
286*4882a593Smuzhiyun .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
287*4882a593Smuzhiyun };
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
290*4882a593Smuzhiyun .i2c_address = 0x61,
291*4882a593Smuzhiyun .if_khz = 5380,
292*4882a593Smuzhiyun };
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun static struct xc5000_config dvico_xc5000_tunerconfig = {
295*4882a593Smuzhiyun .i2c_address = 0x64,
296*4882a593Smuzhiyun .if_khz = 5380,
297*4882a593Smuzhiyun };
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun static struct tda829x_config tda829x_no_probe = {
300*4882a593Smuzhiyun .probe_tuner = TDA829X_DONT_PROBE,
301*4882a593Smuzhiyun };
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun static struct tda18271_std_map hauppauge_tda18271_std_map = {
304*4882a593Smuzhiyun .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
305*4882a593Smuzhiyun .if_lvl = 6, .rfagc_top = 0x37 },
306*4882a593Smuzhiyun .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
307*4882a593Smuzhiyun .if_lvl = 6, .rfagc_top = 0x37 },
308*4882a593Smuzhiyun };
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
311*4882a593Smuzhiyun .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
312*4882a593Smuzhiyun .if_lvl = 1, .rfagc_top = 0x37, },
313*4882a593Smuzhiyun .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
314*4882a593Smuzhiyun .if_lvl = 1, .rfagc_top = 0x37, },
315*4882a593Smuzhiyun .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
316*4882a593Smuzhiyun .if_lvl = 1, .rfagc_top = 0x37, },
317*4882a593Smuzhiyun };
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun static struct tda18271_config hauppauge_tda18271_config = {
320*4882a593Smuzhiyun .std_map = &hauppauge_tda18271_std_map,
321*4882a593Smuzhiyun .gate = TDA18271_GATE_ANALOG,
322*4882a593Smuzhiyun .output_opt = TDA18271_OUTPUT_LT_OFF,
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun static struct tda18271_config hauppauge_hvr1200_tuner_config = {
326*4882a593Smuzhiyun .std_map = &hauppauge_hvr1200_tda18271_std_map,
327*4882a593Smuzhiyun .gate = TDA18271_GATE_ANALOG,
328*4882a593Smuzhiyun .output_opt = TDA18271_OUTPUT_LT_OFF,
329*4882a593Smuzhiyun };
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun static struct tda18271_config hauppauge_hvr1210_tuner_config = {
332*4882a593Smuzhiyun .gate = TDA18271_GATE_DIGITAL,
333*4882a593Smuzhiyun .output_opt = TDA18271_OUTPUT_LT_OFF,
334*4882a593Smuzhiyun };
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun static struct tda18271_config hauppauge_hvr4400_tuner_config = {
337*4882a593Smuzhiyun .gate = TDA18271_GATE_DIGITAL,
338*4882a593Smuzhiyun .output_opt = TDA18271_OUTPUT_LT_OFF,
339*4882a593Smuzhiyun };
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun static struct tda18271_std_map hauppauge_hvr127x_std_map = {
342*4882a593Smuzhiyun .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
343*4882a593Smuzhiyun .if_lvl = 1, .rfagc_top = 0x58 },
344*4882a593Smuzhiyun .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
345*4882a593Smuzhiyun .if_lvl = 1, .rfagc_top = 0x58 },
346*4882a593Smuzhiyun };
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun static struct tda18271_config hauppauge_hvr127x_config = {
349*4882a593Smuzhiyun .std_map = &hauppauge_hvr127x_std_map,
350*4882a593Smuzhiyun .output_opt = TDA18271_OUTPUT_LT_OFF,
351*4882a593Smuzhiyun };
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun static struct lgdt3305_config hauppauge_lgdt3305_config = {
354*4882a593Smuzhiyun .i2c_addr = 0x0e,
355*4882a593Smuzhiyun .mpeg_mode = LGDT3305_MPEG_SERIAL,
356*4882a593Smuzhiyun .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
357*4882a593Smuzhiyun .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
358*4882a593Smuzhiyun .deny_i2c_rptr = 1,
359*4882a593Smuzhiyun .spectral_inversion = 1,
360*4882a593Smuzhiyun .qam_if_khz = 4000,
361*4882a593Smuzhiyun .vsb_if_khz = 3250,
362*4882a593Smuzhiyun };
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun static struct dibx000_agc_config xc3028_agc_config = {
365*4882a593Smuzhiyun BAND_VHF | BAND_UHF, /* band_caps */
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
368*4882a593Smuzhiyun * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
369*4882a593Smuzhiyun * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0,
370*4882a593Smuzhiyun * P_agc_nb_est=2, P_agc_write=0
371*4882a593Smuzhiyun */
372*4882a593Smuzhiyun (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
373*4882a593Smuzhiyun (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun 712, /* inv_gain */
376*4882a593Smuzhiyun 21, /* time_stabiliz */
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun 0, /* alpha_level */
379*4882a593Smuzhiyun 118, /* thlock */
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun 0, /* wbd_inv */
382*4882a593Smuzhiyun 2867, /* wbd_ref */
383*4882a593Smuzhiyun 0, /* wbd_sel */
384*4882a593Smuzhiyun 2, /* wbd_alpha */
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun 0, /* agc1_max */
387*4882a593Smuzhiyun 0, /* agc1_min */
388*4882a593Smuzhiyun 39718, /* agc2_max */
389*4882a593Smuzhiyun 9930, /* agc2_min */
390*4882a593Smuzhiyun 0, /* agc1_pt1 */
391*4882a593Smuzhiyun 0, /* agc1_pt2 */
392*4882a593Smuzhiyun 0, /* agc1_pt3 */
393*4882a593Smuzhiyun 0, /* agc1_slope1 */
394*4882a593Smuzhiyun 0, /* agc1_slope2 */
395*4882a593Smuzhiyun 0, /* agc2_pt1 */
396*4882a593Smuzhiyun 128, /* agc2_pt2 */
397*4882a593Smuzhiyun 29, /* agc2_slope1 */
398*4882a593Smuzhiyun 29, /* agc2_slope2 */
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun 17, /* alpha_mant */
401*4882a593Smuzhiyun 27, /* alpha_exp */
402*4882a593Smuzhiyun 23, /* beta_mant */
403*4882a593Smuzhiyun 51, /* beta_exp */
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun 1, /* perform_agc_softsplit */
406*4882a593Smuzhiyun };
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun /* PLL Configuration for COFDM BW_MHz = 8.000000
409*4882a593Smuzhiyun * With external clock = 30.000000 */
410*4882a593Smuzhiyun static struct dibx000_bandwidth_config xc3028_bw_config = {
411*4882a593Smuzhiyun 60000, /* internal */
412*4882a593Smuzhiyun 30000, /* sampling */
413*4882a593Smuzhiyun 1, /* pll_cfg: prediv */
414*4882a593Smuzhiyun 8, /* pll_cfg: ratio */
415*4882a593Smuzhiyun 3, /* pll_cfg: range */
416*4882a593Smuzhiyun 1, /* pll_cfg: reset */
417*4882a593Smuzhiyun 0, /* pll_cfg: bypass */
418*4882a593Smuzhiyun 0, /* misc: refdiv */
419*4882a593Smuzhiyun 0, /* misc: bypclk_div */
420*4882a593Smuzhiyun 1, /* misc: IO_CLK_en_core */
421*4882a593Smuzhiyun 1, /* misc: ADClkSrc */
422*4882a593Smuzhiyun 0, /* misc: modulo */
423*4882a593Smuzhiyun (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
424*4882a593Smuzhiyun (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
425*4882a593Smuzhiyun 20452225, /* timf */
426*4882a593Smuzhiyun 30000000 /* xtal_hz */
427*4882a593Smuzhiyun };
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun static struct dib7000p_config hauppauge_hvr1400_dib7000_config = {
430*4882a593Smuzhiyun .output_mpeg2_in_188_bytes = 1,
431*4882a593Smuzhiyun .hostbus_diversity = 1,
432*4882a593Smuzhiyun .tuner_is_baseband = 0,
433*4882a593Smuzhiyun .update_lna = NULL,
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun .agc_config_count = 1,
436*4882a593Smuzhiyun .agc = &xc3028_agc_config,
437*4882a593Smuzhiyun .bw = &xc3028_bw_config,
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
440*4882a593Smuzhiyun .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
441*4882a593Smuzhiyun .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun .pwm_freq_div = 0,
444*4882a593Smuzhiyun .agc_control = NULL,
445*4882a593Smuzhiyun .spur_protect = 0,
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun .output_mode = OUTMODE_MPEG2_SERIAL,
448*4882a593Smuzhiyun };
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun static struct zl10353_config dvico_fusionhdtv_xc3028 = {
451*4882a593Smuzhiyun .demod_address = 0x0f,
452*4882a593Smuzhiyun .if2 = 45600,
453*4882a593Smuzhiyun .no_tuner = 1,
454*4882a593Smuzhiyun .disable_i2c_gate_ctrl = 1,
455*4882a593Smuzhiyun };
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun static struct stv0900_reg stv0900_ts_regs[] = {
458*4882a593Smuzhiyun { R0900_TSGENERAL, 0x00 },
459*4882a593Smuzhiyun { R0900_P1_TSSPEED, 0x40 },
460*4882a593Smuzhiyun { R0900_P2_TSSPEED, 0x40 },
461*4882a593Smuzhiyun { R0900_P1_TSCFGM, 0xc0 },
462*4882a593Smuzhiyun { R0900_P2_TSCFGM, 0xc0 },
463*4882a593Smuzhiyun { R0900_P1_TSCFGH, 0xe0 },
464*4882a593Smuzhiyun { R0900_P2_TSCFGH, 0xe0 },
465*4882a593Smuzhiyun { R0900_P1_TSCFGL, 0x20 },
466*4882a593Smuzhiyun { R0900_P2_TSCFGL, 0x20 },
467*4882a593Smuzhiyun { 0xffff, 0xff }, /* terminate */
468*4882a593Smuzhiyun };
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun static struct stv0900_config netup_stv0900_config = {
471*4882a593Smuzhiyun .demod_address = 0x68,
472*4882a593Smuzhiyun .demod_mode = 1, /* dual */
473*4882a593Smuzhiyun .xtal = 8000000,
474*4882a593Smuzhiyun .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
475*4882a593Smuzhiyun .diseqc_mode = 2,/* 2/3 PWM */
476*4882a593Smuzhiyun .ts_config_regs = stv0900_ts_regs,
477*4882a593Smuzhiyun .tun1_maddress = 0,/* 0x60 */
478*4882a593Smuzhiyun .tun2_maddress = 3,/* 0x63 */
479*4882a593Smuzhiyun .tun1_adc = 1,/* 1 Vpp */
480*4882a593Smuzhiyun .tun2_adc = 1,/* 1 Vpp */
481*4882a593Smuzhiyun };
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun static struct stv6110_config netup_stv6110_tunerconfig_a = {
484*4882a593Smuzhiyun .i2c_address = 0x60,
485*4882a593Smuzhiyun .mclk = 16000000,
486*4882a593Smuzhiyun .clk_div = 1,
487*4882a593Smuzhiyun .gain = 8, /* +16 dB - maximum gain */
488*4882a593Smuzhiyun };
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun static struct stv6110_config netup_stv6110_tunerconfig_b = {
491*4882a593Smuzhiyun .i2c_address = 0x63,
492*4882a593Smuzhiyun .mclk = 16000000,
493*4882a593Smuzhiyun .clk_div = 1,
494*4882a593Smuzhiyun .gain = 8, /* +16 dB - maximum gain */
495*4882a593Smuzhiyun };
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun static struct cx24116_config tbs_cx24116_config = {
498*4882a593Smuzhiyun .demod_address = 0x55,
499*4882a593Smuzhiyun };
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun static struct cx24117_config tbs_cx24117_config = {
502*4882a593Smuzhiyun .demod_address = 0x55,
503*4882a593Smuzhiyun };
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun static struct ds3000_config tevii_ds3000_config = {
506*4882a593Smuzhiyun .demod_address = 0x68,
507*4882a593Smuzhiyun };
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun static struct ts2020_config tevii_ts2020_config = {
510*4882a593Smuzhiyun .tuner_address = 0x60,
511*4882a593Smuzhiyun .clk_out_div = 1,
512*4882a593Smuzhiyun .frequency_div = 1146000,
513*4882a593Smuzhiyun };
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun static struct cx24116_config dvbworld_cx24116_config = {
516*4882a593Smuzhiyun .demod_address = 0x05,
517*4882a593Smuzhiyun };
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = {
520*4882a593Smuzhiyun .prod = LGS8GXX_PROD_LGS8GL5,
521*4882a593Smuzhiyun .demod_address = 0x19,
522*4882a593Smuzhiyun .serial_ts = 0,
523*4882a593Smuzhiyun .ts_clk_pol = 1,
524*4882a593Smuzhiyun .ts_clk_gated = 1,
525*4882a593Smuzhiyun .if_clk_freq = 30400, /* 30.4 MHz */
526*4882a593Smuzhiyun .if_freq = 5380, /* 5.38 MHz */
527*4882a593Smuzhiyun .if_neg_center = 1,
528*4882a593Smuzhiyun .ext_adc = 0,
529*4882a593Smuzhiyun .adc_signed = 0,
530*4882a593Smuzhiyun .if_neg_edge = 0,
531*4882a593Smuzhiyun };
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun static struct xc5000_config mygica_x8506_xc5000_config = {
534*4882a593Smuzhiyun .i2c_address = 0x61,
535*4882a593Smuzhiyun .if_khz = 5380,
536*4882a593Smuzhiyun };
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun static struct mb86a20s_config mygica_x8507_mb86a20s_config = {
539*4882a593Smuzhiyun .demod_address = 0x10,
540*4882a593Smuzhiyun };
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun static struct xc5000_config mygica_x8507_xc5000_config = {
543*4882a593Smuzhiyun .i2c_address = 0x61,
544*4882a593Smuzhiyun .if_khz = 4000,
545*4882a593Smuzhiyun };
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun static struct stv090x_config prof_8000_stv090x_config = {
548*4882a593Smuzhiyun .device = STV0903,
549*4882a593Smuzhiyun .demod_mode = STV090x_SINGLE,
550*4882a593Smuzhiyun .clk_mode = STV090x_CLK_EXT,
551*4882a593Smuzhiyun .xtal = 27000000,
552*4882a593Smuzhiyun .address = 0x6A,
553*4882a593Smuzhiyun .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,
554*4882a593Smuzhiyun .repeater_level = STV090x_RPTLEVEL_64,
555*4882a593Smuzhiyun .adc1_range = STV090x_ADC_2Vpp,
556*4882a593Smuzhiyun .diseqc_envelope_mode = false,
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun .tuner_get_frequency = stb6100_get_frequency,
559*4882a593Smuzhiyun .tuner_set_frequency = stb6100_set_frequency,
560*4882a593Smuzhiyun .tuner_set_bandwidth = stb6100_set_bandwidth,
561*4882a593Smuzhiyun .tuner_get_bandwidth = stb6100_get_bandwidth,
562*4882a593Smuzhiyun };
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun static struct stb6100_config prof_8000_stb6100_config = {
565*4882a593Smuzhiyun .tuner_address = 0x60,
566*4882a593Smuzhiyun .refclock = 27000000,
567*4882a593Smuzhiyun };
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun static struct lgdt3306a_config hauppauge_quadHD_ATSC_a_config = {
570*4882a593Smuzhiyun .i2c_addr = 0x59,
571*4882a593Smuzhiyun .qam_if_khz = 4000,
572*4882a593Smuzhiyun .vsb_if_khz = 3250,
573*4882a593Smuzhiyun .deny_i2c_rptr = 1, /* Disabled */
574*4882a593Smuzhiyun .spectral_inversion = 0, /* Disabled */
575*4882a593Smuzhiyun .mpeg_mode = LGDT3306A_MPEG_SERIAL,
576*4882a593Smuzhiyun .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE,
577*4882a593Smuzhiyun .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH,
578*4882a593Smuzhiyun .xtalMHz = 25, /* 24 or 25 */
579*4882a593Smuzhiyun };
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun static struct lgdt3306a_config hauppauge_quadHD_ATSC_b_config = {
582*4882a593Smuzhiyun .i2c_addr = 0x0e,
583*4882a593Smuzhiyun .qam_if_khz = 4000,
584*4882a593Smuzhiyun .vsb_if_khz = 3250,
585*4882a593Smuzhiyun .deny_i2c_rptr = 1, /* Disabled */
586*4882a593Smuzhiyun .spectral_inversion = 0, /* Disabled */
587*4882a593Smuzhiyun .mpeg_mode = LGDT3306A_MPEG_SERIAL,
588*4882a593Smuzhiyun .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE,
589*4882a593Smuzhiyun .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH,
590*4882a593Smuzhiyun .xtalMHz = 25, /* 24 or 25 */
591*4882a593Smuzhiyun };
592*4882a593Smuzhiyun
p8000_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)593*4882a593Smuzhiyun static int p8000_set_voltage(struct dvb_frontend *fe,
594*4882a593Smuzhiyun enum fe_sec_voltage voltage)
595*4882a593Smuzhiyun {
596*4882a593Smuzhiyun struct cx23885_tsport *port = fe->dvb->priv;
597*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun if (voltage == SEC_VOLTAGE_18)
600*4882a593Smuzhiyun cx_write(MC417_RWD, 0x00001e00);
601*4882a593Smuzhiyun else if (voltage == SEC_VOLTAGE_13)
602*4882a593Smuzhiyun cx_write(MC417_RWD, 0x00001a00);
603*4882a593Smuzhiyun else
604*4882a593Smuzhiyun cx_write(MC417_RWD, 0x00001800);
605*4882a593Smuzhiyun return 0;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun
dvbsky_t9580_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)608*4882a593Smuzhiyun static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
609*4882a593Smuzhiyun enum fe_sec_voltage voltage)
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun struct cx23885_tsport *port = fe->dvb->priv;
612*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1);
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun switch (voltage) {
617*4882a593Smuzhiyun case SEC_VOLTAGE_13:
618*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_1);
619*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_0);
620*4882a593Smuzhiyun break;
621*4882a593Smuzhiyun case SEC_VOLTAGE_18:
622*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_1);
623*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_0);
624*4882a593Smuzhiyun break;
625*4882a593Smuzhiyun case SEC_VOLTAGE_OFF:
626*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_1);
627*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_0);
628*4882a593Smuzhiyun break;
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun /* call the frontend set_voltage function */
632*4882a593Smuzhiyun port->fe_set_voltage(fe, voltage);
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun return 0;
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
dvbsky_s952_portc_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)637*4882a593Smuzhiyun static int dvbsky_s952_portc_set_voltage(struct dvb_frontend *fe,
638*4882a593Smuzhiyun enum fe_sec_voltage voltage)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun struct cx23885_tsport *port = fe->dvb->priv;
641*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun cx23885_gpio_enable(dev, GPIO_12 | GPIO_13, 1);
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun switch (voltage) {
646*4882a593Smuzhiyun case SEC_VOLTAGE_13:
647*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_13);
648*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_12);
649*4882a593Smuzhiyun break;
650*4882a593Smuzhiyun case SEC_VOLTAGE_18:
651*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_13);
652*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_12);
653*4882a593Smuzhiyun break;
654*4882a593Smuzhiyun case SEC_VOLTAGE_OFF:
655*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_13);
656*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_12);
657*4882a593Smuzhiyun break;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun /* call the frontend set_voltage function */
660*4882a593Smuzhiyun return port->fe_set_voltage(fe, voltage);
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun
cx23885_sp2_ci_ctrl(void * priv,u8 read,int addr,u8 data,int * mem)663*4882a593Smuzhiyun static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr,
664*4882a593Smuzhiyun u8 data, int *mem)
665*4882a593Smuzhiyun {
666*4882a593Smuzhiyun /* MC417 */
667*4882a593Smuzhiyun #define SP2_DATA 0x000000ff
668*4882a593Smuzhiyun #define SP2_WR 0x00008000
669*4882a593Smuzhiyun #define SP2_RD 0x00004000
670*4882a593Smuzhiyun #define SP2_ACK 0x00001000
671*4882a593Smuzhiyun #define SP2_ADHI 0x00000800
672*4882a593Smuzhiyun #define SP2_ADLO 0x00000400
673*4882a593Smuzhiyun #define SP2_CS1 0x00000200
674*4882a593Smuzhiyun #define SP2_CS0 0x00000100
675*4882a593Smuzhiyun #define SP2_EN_ALL 0x00001000
676*4882a593Smuzhiyun #define SP2_CTRL_OFF (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD)
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun struct cx23885_tsport *port = priv;
679*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
680*4882a593Smuzhiyun int ret;
681*4882a593Smuzhiyun int tmp = 0;
682*4882a593Smuzhiyun unsigned long timeout;
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun mutex_lock(&dev->gpio_lock);
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun /* write addr */
687*4882a593Smuzhiyun cx_write(MC417_OEN, SP2_EN_ALL);
688*4882a593Smuzhiyun cx_write(MC417_RWD, SP2_CTRL_OFF |
689*4882a593Smuzhiyun SP2_ADLO | (0xff & addr));
690*4882a593Smuzhiyun cx_clear(MC417_RWD, SP2_ADLO);
691*4882a593Smuzhiyun cx_write(MC417_RWD, SP2_CTRL_OFF |
692*4882a593Smuzhiyun SP2_ADHI | (0xff & (addr >> 8)));
693*4882a593Smuzhiyun cx_clear(MC417_RWD, SP2_ADHI);
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun if (read)
696*4882a593Smuzhiyun /* data in */
697*4882a593Smuzhiyun cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA);
698*4882a593Smuzhiyun else
699*4882a593Smuzhiyun /* data out */
700*4882a593Smuzhiyun cx_write(MC417_RWD, SP2_CTRL_OFF | data);
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun /* chip select 0 */
703*4882a593Smuzhiyun cx_clear(MC417_RWD, SP2_CS0);
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun /* read/write */
706*4882a593Smuzhiyun cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR);
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun /* wait for a maximum of 1 msec */
709*4882a593Smuzhiyun timeout = jiffies + msecs_to_jiffies(1);
710*4882a593Smuzhiyun while (!time_after(jiffies, timeout)) {
711*4882a593Smuzhiyun tmp = cx_read(MC417_RWD);
712*4882a593Smuzhiyun if ((tmp & SP2_ACK) == 0)
713*4882a593Smuzhiyun break;
714*4882a593Smuzhiyun usleep_range(50, 100);
715*4882a593Smuzhiyun }
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun cx_set(MC417_RWD, SP2_CTRL_OFF);
718*4882a593Smuzhiyun *mem = tmp & 0xff;
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun mutex_unlock(&dev->gpio_lock);
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun if (!read) {
723*4882a593Smuzhiyun if (*mem < 0) {
724*4882a593Smuzhiyun ret = -EREMOTEIO;
725*4882a593Smuzhiyun goto err;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun return 0;
730*4882a593Smuzhiyun err:
731*4882a593Smuzhiyun return ret;
732*4882a593Smuzhiyun }
733*4882a593Smuzhiyun
cx23885_dvb_set_frontend(struct dvb_frontend * fe)734*4882a593Smuzhiyun static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
737*4882a593Smuzhiyun struct cx23885_tsport *port = fe->dvb->priv;
738*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun switch (dev->board) {
741*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1275:
742*4882a593Smuzhiyun switch (p->modulation) {
743*4882a593Smuzhiyun case VSB_8:
744*4882a593Smuzhiyun cx23885_gpio_clear(dev, GPIO_5);
745*4882a593Smuzhiyun break;
746*4882a593Smuzhiyun case QAM_64:
747*4882a593Smuzhiyun case QAM_256:
748*4882a593Smuzhiyun default:
749*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_5);
750*4882a593Smuzhiyun break;
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun break;
753*4882a593Smuzhiyun case CX23885_BOARD_MYGICA_X8506:
754*4882a593Smuzhiyun case CX23885_BOARD_MYGICA_X8507:
755*4882a593Smuzhiyun case CX23885_BOARD_MAGICPRO_PROHDTVE2:
756*4882a593Smuzhiyun /* Select Digital TV */
757*4882a593Smuzhiyun cx23885_gpio_set(dev, GPIO_0);
758*4882a593Smuzhiyun break;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun /* Call the real set_frontend */
762*4882a593Smuzhiyun if (port->set_frontend)
763*4882a593Smuzhiyun return port->set_frontend(fe);
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun return 0;
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
cx23885_set_frontend_hook(struct cx23885_tsport * port,struct dvb_frontend * fe)768*4882a593Smuzhiyun static void cx23885_set_frontend_hook(struct cx23885_tsport *port,
769*4882a593Smuzhiyun struct dvb_frontend *fe)
770*4882a593Smuzhiyun {
771*4882a593Smuzhiyun port->set_frontend = fe->ops.set_frontend;
772*4882a593Smuzhiyun fe->ops.set_frontend = cx23885_dvb_set_frontend;
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
776*4882a593Smuzhiyun .prod = LGS8GXX_PROD_LGS8G75,
777*4882a593Smuzhiyun .demod_address = 0x19,
778*4882a593Smuzhiyun .serial_ts = 0,
779*4882a593Smuzhiyun .ts_clk_pol = 1,
780*4882a593Smuzhiyun .ts_clk_gated = 1,
781*4882a593Smuzhiyun .if_clk_freq = 30400, /* 30.4 MHz */
782*4882a593Smuzhiyun .if_freq = 6500, /* 6.50 MHz */
783*4882a593Smuzhiyun .if_neg_center = 1,
784*4882a593Smuzhiyun .ext_adc = 0,
785*4882a593Smuzhiyun .adc_signed = 1,
786*4882a593Smuzhiyun .adc_vpp = 2, /* 1.6 Vpp */
787*4882a593Smuzhiyun .if_neg_edge = 1,
788*4882a593Smuzhiyun };
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
791*4882a593Smuzhiyun .i2c_address = 0x61,
792*4882a593Smuzhiyun .if_khz = 6500,
793*4882a593Smuzhiyun };
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
796*4882a593Smuzhiyun .prod = ATBM8830_PROD_8830,
797*4882a593Smuzhiyun .demod_address = 0x44,
798*4882a593Smuzhiyun .serial_ts = 0,
799*4882a593Smuzhiyun .ts_sampling_edge = 1,
800*4882a593Smuzhiyun .ts_clk_gated = 0,
801*4882a593Smuzhiyun .osc_clk_freq = 30400, /* in kHz */
802*4882a593Smuzhiyun .if_freq = 0, /* zero IF */
803*4882a593Smuzhiyun .zif_swap_iq = 1,
804*4882a593Smuzhiyun .agc_min = 0x2E,
805*4882a593Smuzhiyun .agc_max = 0xFF,
806*4882a593Smuzhiyun .agc_hold_loop = 0,
807*4882a593Smuzhiyun };
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
810*4882a593Smuzhiyun .i2c_address = 0x60,
811*4882a593Smuzhiyun .osc_clk = 20
812*4882a593Smuzhiyun };
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
815*4882a593Smuzhiyun .prod = ATBM8830_PROD_8830,
816*4882a593Smuzhiyun .demod_address = 0x44,
817*4882a593Smuzhiyun .serial_ts = 1,
818*4882a593Smuzhiyun .ts_sampling_edge = 1,
819*4882a593Smuzhiyun .ts_clk_gated = 0,
820*4882a593Smuzhiyun .osc_clk_freq = 30400, /* in kHz */
821*4882a593Smuzhiyun .if_freq = 0, /* zero IF */
822*4882a593Smuzhiyun .zif_swap_iq = 1,
823*4882a593Smuzhiyun .agc_min = 0x2E,
824*4882a593Smuzhiyun .agc_max = 0xFF,
825*4882a593Smuzhiyun .agc_hold_loop = 0,
826*4882a593Smuzhiyun };
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
829*4882a593Smuzhiyun .i2c_address = 0x60,
830*4882a593Smuzhiyun .osc_clk = 20
831*4882a593Smuzhiyun };
832*4882a593Smuzhiyun static struct stv0367_config netup_stv0367_config[] = {
833*4882a593Smuzhiyun {
834*4882a593Smuzhiyun .demod_address = 0x1c,
835*4882a593Smuzhiyun .xtal = 27000000,
836*4882a593Smuzhiyun .if_khz = 4500,
837*4882a593Smuzhiyun .if_iq_mode = 0,
838*4882a593Smuzhiyun .ts_mode = 1,
839*4882a593Smuzhiyun .clk_pol = 0,
840*4882a593Smuzhiyun }, {
841*4882a593Smuzhiyun .demod_address = 0x1d,
842*4882a593Smuzhiyun .xtal = 27000000,
843*4882a593Smuzhiyun .if_khz = 4500,
844*4882a593Smuzhiyun .if_iq_mode = 0,
845*4882a593Smuzhiyun .ts_mode = 1,
846*4882a593Smuzhiyun .clk_pol = 0,
847*4882a593Smuzhiyun },
848*4882a593Smuzhiyun };
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun static struct xc5000_config netup_xc5000_config[] = {
851*4882a593Smuzhiyun {
852*4882a593Smuzhiyun .i2c_address = 0x61,
853*4882a593Smuzhiyun .if_khz = 4500,
854*4882a593Smuzhiyun }, {
855*4882a593Smuzhiyun .i2c_address = 0x64,
856*4882a593Smuzhiyun .if_khz = 4500,
857*4882a593Smuzhiyun },
858*4882a593Smuzhiyun };
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun static struct drxk_config terratec_drxk_config[] = {
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun .adr = 0x29,
863*4882a593Smuzhiyun .no_i2c_bridge = 1,
864*4882a593Smuzhiyun }, {
865*4882a593Smuzhiyun .adr = 0x2a,
866*4882a593Smuzhiyun .no_i2c_bridge = 1,
867*4882a593Smuzhiyun },
868*4882a593Smuzhiyun };
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun static struct mt2063_config terratec_mt2063_config[] = {
871*4882a593Smuzhiyun {
872*4882a593Smuzhiyun .tuner_address = 0x60,
873*4882a593Smuzhiyun }, {
874*4882a593Smuzhiyun .tuner_address = 0x67,
875*4882a593Smuzhiyun },
876*4882a593Smuzhiyun };
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun static const struct tda10071_platform_data hauppauge_tda10071_pdata = {
879*4882a593Smuzhiyun .clk = 40444000, /* 40.444 MHz */
880*4882a593Smuzhiyun .i2c_wr_max = 64,
881*4882a593Smuzhiyun .ts_mode = TDA10071_TS_SERIAL,
882*4882a593Smuzhiyun .pll_multiplier = 20,
883*4882a593Smuzhiyun .tuner_i2c_addr = 0x54,
884*4882a593Smuzhiyun };
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun static const struct m88ds3103_config dvbsky_t9580_m88ds3103_config = {
887*4882a593Smuzhiyun .i2c_addr = 0x68,
888*4882a593Smuzhiyun .clock = 27000000,
889*4882a593Smuzhiyun .i2c_wr_max = 33,
890*4882a593Smuzhiyun .clock_out = 0,
891*4882a593Smuzhiyun .ts_mode = M88DS3103_TS_PARALLEL,
892*4882a593Smuzhiyun .ts_clk = 16000,
893*4882a593Smuzhiyun .ts_clk_pol = 1,
894*4882a593Smuzhiyun .lnb_en_pol = 1,
895*4882a593Smuzhiyun .lnb_hv_pol = 0,
896*4882a593Smuzhiyun .agc = 0x99,
897*4882a593Smuzhiyun };
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun static const struct m88ds3103_config dvbsky_s950c_m88ds3103_config = {
900*4882a593Smuzhiyun .i2c_addr = 0x68,
901*4882a593Smuzhiyun .clock = 27000000,
902*4882a593Smuzhiyun .i2c_wr_max = 33,
903*4882a593Smuzhiyun .clock_out = 0,
904*4882a593Smuzhiyun .ts_mode = M88DS3103_TS_CI,
905*4882a593Smuzhiyun .ts_clk = 10000,
906*4882a593Smuzhiyun .ts_clk_pol = 1,
907*4882a593Smuzhiyun .lnb_en_pol = 1,
908*4882a593Smuzhiyun .lnb_hv_pol = 0,
909*4882a593Smuzhiyun .agc = 0x99,
910*4882a593Smuzhiyun };
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun static const struct m88ds3103_config hauppauge_hvr5525_m88ds3103_config = {
913*4882a593Smuzhiyun .i2c_addr = 0x69,
914*4882a593Smuzhiyun .clock = 27000000,
915*4882a593Smuzhiyun .i2c_wr_max = 33,
916*4882a593Smuzhiyun .ts_mode = M88DS3103_TS_PARALLEL,
917*4882a593Smuzhiyun .ts_clk = 16000,
918*4882a593Smuzhiyun .ts_clk_pol = 1,
919*4882a593Smuzhiyun .agc = 0x99,
920*4882a593Smuzhiyun };
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun static struct lgdt3306a_config hauppauge_hvr1265k4_config = {
923*4882a593Smuzhiyun .i2c_addr = 0x59,
924*4882a593Smuzhiyun .qam_if_khz = 4000,
925*4882a593Smuzhiyun .vsb_if_khz = 3250,
926*4882a593Smuzhiyun .deny_i2c_rptr = 1, /* Disabled */
927*4882a593Smuzhiyun .spectral_inversion = 0, /* Disabled */
928*4882a593Smuzhiyun .mpeg_mode = LGDT3306A_MPEG_SERIAL,
929*4882a593Smuzhiyun .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE,
930*4882a593Smuzhiyun .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH,
931*4882a593Smuzhiyun .xtalMHz = 25, /* 24 or 25 */
932*4882a593Smuzhiyun };
933*4882a593Smuzhiyun
netup_altera_fpga_rw(void * device,int flag,int data,int read)934*4882a593Smuzhiyun static int netup_altera_fpga_rw(void *device, int flag, int data, int read)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun struct cx23885_dev *dev = (struct cx23885_dev *)device;
937*4882a593Smuzhiyun unsigned long timeout = jiffies + msecs_to_jiffies(1);
938*4882a593Smuzhiyun uint32_t mem = 0;
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun mem = cx_read(MC417_RWD);
941*4882a593Smuzhiyun if (read)
942*4882a593Smuzhiyun cx_set(MC417_OEN, ALT_DATA);
943*4882a593Smuzhiyun else {
944*4882a593Smuzhiyun cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */
945*4882a593Smuzhiyun mem &= ~ALT_DATA;
946*4882a593Smuzhiyun mem |= (data & ALT_DATA);
947*4882a593Smuzhiyun }
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun if (flag)
950*4882a593Smuzhiyun mem |= ALT_AD_RG;
951*4882a593Smuzhiyun else
952*4882a593Smuzhiyun mem &= ~ALT_AD_RG;
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun mem &= ~ALT_CS;
955*4882a593Smuzhiyun if (read)
956*4882a593Smuzhiyun mem = (mem & ~ALT_RD) | ALT_WR;
957*4882a593Smuzhiyun else
958*4882a593Smuzhiyun mem = (mem & ~ALT_WR) | ALT_RD;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun cx_write(MC417_RWD, mem); /* start RW cycle */
961*4882a593Smuzhiyun
962*4882a593Smuzhiyun for (;;) {
963*4882a593Smuzhiyun mem = cx_read(MC417_RWD);
964*4882a593Smuzhiyun if ((mem & ALT_RDY) == 0)
965*4882a593Smuzhiyun break;
966*4882a593Smuzhiyun if (time_after(jiffies, timeout))
967*4882a593Smuzhiyun break;
968*4882a593Smuzhiyun udelay(1);
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
972*4882a593Smuzhiyun if (read)
973*4882a593Smuzhiyun return mem & ALT_DATA;
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun return 0;
976*4882a593Smuzhiyun };
977*4882a593Smuzhiyun
dib7070_tuner_reset(struct dvb_frontend * fe,int onoff)978*4882a593Smuzhiyun static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
979*4882a593Smuzhiyun {
980*4882a593Smuzhiyun struct dib7000p_ops *dib7000p_ops = fe->sec_priv;
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun return dib7000p_ops->set_gpio(fe, 8, 0, !onoff);
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun
dib7070_tuner_sleep(struct dvb_frontend * fe,int onoff)985*4882a593Smuzhiyun static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun return 0;
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun static struct dib0070_config dib7070p_dib0070_config = {
991*4882a593Smuzhiyun .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
992*4882a593Smuzhiyun .reset = dib7070_tuner_reset,
993*4882a593Smuzhiyun .sleep = dib7070_tuner_sleep,
994*4882a593Smuzhiyun .clock_khz = 12000,
995*4882a593Smuzhiyun .freq_offset_khz_vhf = 550,
996*4882a593Smuzhiyun /* .flip_chip = 1, */
997*4882a593Smuzhiyun };
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun /* DIB7070 generic */
1000*4882a593Smuzhiyun static struct dibx000_agc_config dib7070_agc_config = {
1001*4882a593Smuzhiyun .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun /*
1004*4882a593Smuzhiyun * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
1005*4882a593Smuzhiyun * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1006*4882a593Smuzhiyun * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
1007*4882a593Smuzhiyun */
1008*4882a593Smuzhiyun .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
1009*4882a593Smuzhiyun (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1010*4882a593Smuzhiyun .inv_gain = 600,
1011*4882a593Smuzhiyun .time_stabiliz = 10,
1012*4882a593Smuzhiyun .alpha_level = 0,
1013*4882a593Smuzhiyun .thlock = 118,
1014*4882a593Smuzhiyun .wbd_inv = 0,
1015*4882a593Smuzhiyun .wbd_ref = 3530,
1016*4882a593Smuzhiyun .wbd_sel = 1,
1017*4882a593Smuzhiyun .wbd_alpha = 5,
1018*4882a593Smuzhiyun .agc1_max = 65535,
1019*4882a593Smuzhiyun .agc1_min = 0,
1020*4882a593Smuzhiyun .agc2_max = 65535,
1021*4882a593Smuzhiyun .agc2_min = 0,
1022*4882a593Smuzhiyun .agc1_pt1 = 0,
1023*4882a593Smuzhiyun .agc1_pt2 = 40,
1024*4882a593Smuzhiyun .agc1_pt3 = 183,
1025*4882a593Smuzhiyun .agc1_slope1 = 206,
1026*4882a593Smuzhiyun .agc1_slope2 = 255,
1027*4882a593Smuzhiyun .agc2_pt1 = 72,
1028*4882a593Smuzhiyun .agc2_pt2 = 152,
1029*4882a593Smuzhiyun .agc2_slope1 = 88,
1030*4882a593Smuzhiyun .agc2_slope2 = 90,
1031*4882a593Smuzhiyun .alpha_mant = 17,
1032*4882a593Smuzhiyun .alpha_exp = 27,
1033*4882a593Smuzhiyun .beta_mant = 23,
1034*4882a593Smuzhiyun .beta_exp = 51,
1035*4882a593Smuzhiyun .perform_agc_softsplit = 0,
1036*4882a593Smuzhiyun };
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1039*4882a593Smuzhiyun .internal = 60000,
1040*4882a593Smuzhiyun .sampling = 15000,
1041*4882a593Smuzhiyun .pll_prediv = 1,
1042*4882a593Smuzhiyun .pll_ratio = 20,
1043*4882a593Smuzhiyun .pll_range = 3,
1044*4882a593Smuzhiyun .pll_reset = 1,
1045*4882a593Smuzhiyun .pll_bypass = 0,
1046*4882a593Smuzhiyun .enable_refdiv = 0,
1047*4882a593Smuzhiyun .bypclk_div = 0,
1048*4882a593Smuzhiyun .IO_CLK_en_core = 1,
1049*4882a593Smuzhiyun .ADClkSrc = 1,
1050*4882a593Smuzhiyun .modulo = 2,
1051*4882a593Smuzhiyun /* refsel, sel, freq_15k */
1052*4882a593Smuzhiyun .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1053*4882a593Smuzhiyun .ifreq = (0 << 25) | 0,
1054*4882a593Smuzhiyun .timf = 20452225,
1055*4882a593Smuzhiyun .xtal_hz = 12000000,
1056*4882a593Smuzhiyun };
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun static struct dib7000p_config dib7070p_dib7000p_config = {
1059*4882a593Smuzhiyun /* .output_mode = OUTMODE_MPEG2_FIFO, */
1060*4882a593Smuzhiyun .output_mode = OUTMODE_MPEG2_SERIAL,
1061*4882a593Smuzhiyun /* .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, */
1062*4882a593Smuzhiyun .output_mpeg2_in_188_bytes = 1,
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun .agc_config_count = 1,
1065*4882a593Smuzhiyun .agc = &dib7070_agc_config,
1066*4882a593Smuzhiyun .bw = &dib7070_bw_config_12_mhz,
1067*4882a593Smuzhiyun .tuner_is_baseband = 1,
1068*4882a593Smuzhiyun .spur_protect = 1,
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun .gpio_dir = 0xfcef, /* DIB7000P_GPIO_DEFAULT_DIRECTIONS, */
1071*4882a593Smuzhiyun .gpio_val = 0x0110, /* DIB7000P_GPIO_DEFAULT_VALUES, */
1072*4882a593Smuzhiyun .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1073*4882a593Smuzhiyun
1074*4882a593Smuzhiyun .hostbus_diversity = 1,
1075*4882a593Smuzhiyun };
1076*4882a593Smuzhiyun
dvb_register_ci_mac(struct cx23885_tsport * port)1077*4882a593Smuzhiyun static int dvb_register_ci_mac(struct cx23885_tsport *port)
1078*4882a593Smuzhiyun {
1079*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
1080*4882a593Smuzhiyun struct i2c_client *client_ci = NULL;
1081*4882a593Smuzhiyun struct vb2_dvb_frontend *fe0;
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
1084*4882a593Smuzhiyun if (!fe0)
1085*4882a593Smuzhiyun return -EINVAL;
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun switch (dev->board) {
1088*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
1089*4882a593Smuzhiyun static struct netup_card_info cinfo;
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
1092*4882a593Smuzhiyun memcpy(port->frontends.adapter.proposed_mac,
1093*4882a593Smuzhiyun cinfo.port[port->nr - 1].mac, 6);
1094*4882a593Smuzhiyun pr_info("NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
1095*4882a593Smuzhiyun port->nr, port->frontends.adapter.proposed_mac);
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun netup_ci_init(port);
1098*4882a593Smuzhiyun return 0;
1099*4882a593Smuzhiyun }
1100*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1101*4882a593Smuzhiyun struct altera_ci_config netup_ci_cfg = {
1102*4882a593Smuzhiyun .dev = dev,/* magic number to identify*/
1103*4882a593Smuzhiyun .adapter = &port->frontends.adapter,/* for CI */
1104*4882a593Smuzhiyun .demux = &fe0->dvb.demux,/* for hw pid filter */
1105*4882a593Smuzhiyun .fpga_rw = netup_altera_fpga_rw,
1106*4882a593Smuzhiyun };
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun altera_ci_init(&netup_ci_cfg, port->nr);
1109*4882a593Smuzhiyun return 0;
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun case CX23885_BOARD_TEVII_S470: {
1112*4882a593Smuzhiyun u8 eeprom[256]; /* 24C02 i2c eeprom */
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun if (port->nr != 1)
1115*4882a593Smuzhiyun return 0;
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun /* Read entire EEPROM */
1118*4882a593Smuzhiyun dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
1119*4882a593Smuzhiyun tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
1120*4882a593Smuzhiyun pr_info("TeVii S470 MAC= %pM\n", eeprom + 0xa0);
1121*4882a593Smuzhiyun memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6);
1122*4882a593Smuzhiyun return 0;
1123*4882a593Smuzhiyun }
1124*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T9580:
1125*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S950:
1126*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S952:
1127*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T982: {
1128*4882a593Smuzhiyun u8 eeprom[256]; /* 24C02 i2c eeprom */
1129*4882a593Smuzhiyun
1130*4882a593Smuzhiyun if (port->nr > 2)
1131*4882a593Smuzhiyun return 0;
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun /* Read entire EEPROM */
1134*4882a593Smuzhiyun dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
1135*4882a593Smuzhiyun tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
1136*4882a593Smuzhiyun sizeof(eeprom));
1137*4882a593Smuzhiyun pr_info("%s port %d MAC address: %pM\n",
1138*4882a593Smuzhiyun cx23885_boards[dev->board].name, port->nr,
1139*4882a593Smuzhiyun eeprom + 0xc0 + (port->nr-1) * 8);
1140*4882a593Smuzhiyun memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 +
1141*4882a593Smuzhiyun (port->nr-1) * 8, 6);
1142*4882a593Smuzhiyun return 0;
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S950C:
1145*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T980C:
1146*4882a593Smuzhiyun case CX23885_BOARD_TT_CT2_4500_CI: {
1147*4882a593Smuzhiyun u8 eeprom[256]; /* 24C02 i2c eeprom */
1148*4882a593Smuzhiyun struct sp2_config sp2_config;
1149*4882a593Smuzhiyun struct i2c_board_info info;
1150*4882a593Smuzhiyun struct cx23885_i2c *i2c_bus = &dev->i2c_bus[0];
1151*4882a593Smuzhiyun
1152*4882a593Smuzhiyun /* attach CI */
1153*4882a593Smuzhiyun memset(&sp2_config, 0, sizeof(sp2_config));
1154*4882a593Smuzhiyun sp2_config.dvb_adap = &port->frontends.adapter;
1155*4882a593Smuzhiyun sp2_config.priv = port;
1156*4882a593Smuzhiyun sp2_config.ci_control = cx23885_sp2_ci_ctrl;
1157*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
1158*4882a593Smuzhiyun strscpy(info.type, "sp2", I2C_NAME_SIZE);
1159*4882a593Smuzhiyun info.addr = 0x40;
1160*4882a593Smuzhiyun info.platform_data = &sp2_config;
1161*4882a593Smuzhiyun request_module(info.type);
1162*4882a593Smuzhiyun client_ci = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1163*4882a593Smuzhiyun if (!i2c_client_has_driver(client_ci))
1164*4882a593Smuzhiyun return -ENODEV;
1165*4882a593Smuzhiyun if (!try_module_get(client_ci->dev.driver->owner)) {
1166*4882a593Smuzhiyun i2c_unregister_device(client_ci);
1167*4882a593Smuzhiyun return -ENODEV;
1168*4882a593Smuzhiyun }
1169*4882a593Smuzhiyun port->i2c_client_ci = client_ci;
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun if (port->nr != 1)
1172*4882a593Smuzhiyun return 0;
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun /* Read entire EEPROM */
1175*4882a593Smuzhiyun dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
1176*4882a593Smuzhiyun tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
1177*4882a593Smuzhiyun sizeof(eeprom));
1178*4882a593Smuzhiyun pr_info("%s MAC address: %pM\n",
1179*4882a593Smuzhiyun cx23885_boards[dev->board].name, eeprom + 0xc0);
1180*4882a593Smuzhiyun memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6);
1181*4882a593Smuzhiyun return 0;
1182*4882a593Smuzhiyun }
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun return 0;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun
dvb_register(struct cx23885_tsport * port)1187*4882a593Smuzhiyun static int dvb_register(struct cx23885_tsport *port)
1188*4882a593Smuzhiyun {
1189*4882a593Smuzhiyun struct dib7000p_ops dib7000p_ops;
1190*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
1191*4882a593Smuzhiyun struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
1192*4882a593Smuzhiyun struct vb2_dvb_frontend *fe0, *fe1 = NULL;
1193*4882a593Smuzhiyun struct si2168_config si2168_config;
1194*4882a593Smuzhiyun struct si2165_platform_data si2165_pdata;
1195*4882a593Smuzhiyun struct si2157_config si2157_config;
1196*4882a593Smuzhiyun struct ts2020_config ts2020_config;
1197*4882a593Smuzhiyun struct m88ds3103_platform_data m88ds3103_pdata;
1198*4882a593Smuzhiyun struct m88rs6000t_config m88rs6000t_config = {};
1199*4882a593Smuzhiyun struct a8293_platform_data a8293_pdata = {};
1200*4882a593Smuzhiyun struct i2c_board_info info;
1201*4882a593Smuzhiyun struct i2c_adapter *adapter;
1202*4882a593Smuzhiyun struct i2c_client *client_demod = NULL, *client_tuner = NULL;
1203*4882a593Smuzhiyun struct i2c_client *client_sec = NULL;
1204*4882a593Smuzhiyun int (*p_set_voltage)(struct dvb_frontend *fe,
1205*4882a593Smuzhiyun enum fe_sec_voltage voltage) = NULL;
1206*4882a593Smuzhiyun int mfe_shared = 0; /* bus not shared by default */
1207*4882a593Smuzhiyun int ret;
1208*4882a593Smuzhiyun
1209*4882a593Smuzhiyun /* Get the first frontend */
1210*4882a593Smuzhiyun fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
1211*4882a593Smuzhiyun if (!fe0)
1212*4882a593Smuzhiyun return -EINVAL;
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun /* init struct vb2_dvb */
1215*4882a593Smuzhiyun fe0->dvb.name = dev->name;
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun /* multi-frontend gate control is undefined or defaults to fe0 */
1218*4882a593Smuzhiyun port->frontends.gate = 0;
1219*4882a593Smuzhiyun
1220*4882a593Smuzhiyun /* Sets the gate control callback to be used by i2c command calls */
1221*4882a593Smuzhiyun port->gate_ctrl = cx23885_dvb_gate_ctrl;
1222*4882a593Smuzhiyun
1223*4882a593Smuzhiyun /* init frontend */
1224*4882a593Smuzhiyun switch (dev->board) {
1225*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1250:
1226*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1227*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1228*4882a593Smuzhiyun &hauppauge_generic_config,
1229*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1230*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1231*4882a593Smuzhiyun break;
1232*4882a593Smuzhiyun dvb_attach(mt2131_attach, fe0->dvb.frontend,
1233*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1234*4882a593Smuzhiyun &hauppauge_generic_tunerconfig, 0);
1235*4882a593Smuzhiyun break;
1236*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1270:
1237*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1275:
1238*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1239*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
1240*4882a593Smuzhiyun &hauppauge_lgdt3305_config,
1241*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1242*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1243*4882a593Smuzhiyun break;
1244*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1245*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1246*4882a593Smuzhiyun &hauppauge_hvr127x_config);
1247*4882a593Smuzhiyun if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1275)
1248*4882a593Smuzhiyun cx23885_set_frontend_hook(port, fe0->dvb.frontend);
1249*4882a593Smuzhiyun break;
1250*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1255:
1251*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1255_22111:
1252*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1253*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1254*4882a593Smuzhiyun &hcw_s5h1411_config,
1255*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1256*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1257*4882a593Smuzhiyun break;
1258*4882a593Smuzhiyun
1259*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1260*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1261*4882a593Smuzhiyun &hauppauge_tda18271_config);
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun tda18271_attach(&dev->ts1.analog_fe,
1264*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1265*4882a593Smuzhiyun &hauppauge_tda18271_config);
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun break;
1268*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1800:
1269*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1270*4882a593Smuzhiyun switch (alt_tuner) {
1271*4882a593Smuzhiyun case 1:
1272*4882a593Smuzhiyun fe0->dvb.frontend =
1273*4882a593Smuzhiyun dvb_attach(s5h1409_attach,
1274*4882a593Smuzhiyun &hauppauge_ezqam_config,
1275*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1276*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1277*4882a593Smuzhiyun break;
1278*4882a593Smuzhiyun
1279*4882a593Smuzhiyun dvb_attach(tda829x_attach, fe0->dvb.frontend,
1280*4882a593Smuzhiyun &dev->i2c_bus[1].i2c_adap, 0x42,
1281*4882a593Smuzhiyun &tda829x_no_probe);
1282*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1283*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1284*4882a593Smuzhiyun &hauppauge_tda18271_config);
1285*4882a593Smuzhiyun break;
1286*4882a593Smuzhiyun case 0:
1287*4882a593Smuzhiyun default:
1288*4882a593Smuzhiyun fe0->dvb.frontend =
1289*4882a593Smuzhiyun dvb_attach(s5h1409_attach,
1290*4882a593Smuzhiyun &hauppauge_generic_config,
1291*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1292*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1293*4882a593Smuzhiyun break;
1294*4882a593Smuzhiyun dvb_attach(mt2131_attach, fe0->dvb.frontend,
1295*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1296*4882a593Smuzhiyun &hauppauge_generic_tunerconfig, 0);
1297*4882a593Smuzhiyun }
1298*4882a593Smuzhiyun break;
1299*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
1300*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1301*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1302*4882a593Smuzhiyun &hauppauge_hvr1800lp_config,
1303*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1304*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1305*4882a593Smuzhiyun break;
1306*4882a593Smuzhiyun dvb_attach(mt2131_attach, fe0->dvb.frontend,
1307*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1308*4882a593Smuzhiyun &hauppauge_generic_tunerconfig, 0);
1309*4882a593Smuzhiyun break;
1310*4882a593Smuzhiyun case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
1311*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1312*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1313*4882a593Smuzhiyun &fusionhdtv_5_express,
1314*4882a593Smuzhiyun 0x0e,
1315*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1316*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1317*4882a593Smuzhiyun break;
1318*4882a593Smuzhiyun dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1319*4882a593Smuzhiyun &i2c_bus->i2c_adap, 0x61,
1320*4882a593Smuzhiyun TUNER_LG_TDVS_H06XF);
1321*4882a593Smuzhiyun break;
1322*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
1323*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1324*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1325*4882a593Smuzhiyun &hauppauge_hvr1500q_config,
1326*4882a593Smuzhiyun &dev->i2c_bus[0].i2c_adap);
1327*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1328*4882a593Smuzhiyun break;
1329*4882a593Smuzhiyun dvb_attach(xc5000_attach, fe0->dvb.frontend,
1330*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1331*4882a593Smuzhiyun &hauppauge_hvr1500q_tunerconfig);
1332*4882a593Smuzhiyun break;
1333*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1500:
1334*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1335*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1336*4882a593Smuzhiyun &hauppauge_hvr1500_config,
1337*4882a593Smuzhiyun &dev->i2c_bus[0].i2c_adap);
1338*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1339*4882a593Smuzhiyun struct dvb_frontend *fe;
1340*4882a593Smuzhiyun struct xc2028_config cfg = {
1341*4882a593Smuzhiyun .i2c_adap = &i2c_bus->i2c_adap,
1342*4882a593Smuzhiyun .i2c_addr = 0x61,
1343*4882a593Smuzhiyun };
1344*4882a593Smuzhiyun static struct xc2028_ctrl ctl = {
1345*4882a593Smuzhiyun .fname = XC2028_DEFAULT_FIRMWARE,
1346*4882a593Smuzhiyun .max_len = 64,
1347*4882a593Smuzhiyun .demod = XC3028_FE_OREN538,
1348*4882a593Smuzhiyun };
1349*4882a593Smuzhiyun
1350*4882a593Smuzhiyun fe = dvb_attach(xc2028_attach,
1351*4882a593Smuzhiyun fe0->dvb.frontend, &cfg);
1352*4882a593Smuzhiyun if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1353*4882a593Smuzhiyun fe->ops.tuner_ops.set_config(fe, &ctl);
1354*4882a593Smuzhiyun }
1355*4882a593Smuzhiyun break;
1356*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1200:
1357*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1700:
1358*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1359*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(tda10048_attach,
1360*4882a593Smuzhiyun &hauppauge_hvr1200_config,
1361*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1362*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1363*4882a593Smuzhiyun break;
1364*4882a593Smuzhiyun dvb_attach(tda829x_attach, fe0->dvb.frontend,
1365*4882a593Smuzhiyun &dev->i2c_bus[1].i2c_adap, 0x42,
1366*4882a593Smuzhiyun &tda829x_no_probe);
1367*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1368*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1369*4882a593Smuzhiyun &hauppauge_hvr1200_tuner_config);
1370*4882a593Smuzhiyun break;
1371*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1210:
1372*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1373*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(tda10048_attach,
1374*4882a593Smuzhiyun &hauppauge_hvr1210_config,
1375*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1376*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1377*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1378*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1379*4882a593Smuzhiyun &hauppauge_hvr1210_tuner_config);
1380*4882a593Smuzhiyun }
1381*4882a593Smuzhiyun break;
1382*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1400:
1383*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1384*4882a593Smuzhiyun
1385*4882a593Smuzhiyun if (!dvb_attach(dib7000p_attach, &dib7000p_ops))
1386*4882a593Smuzhiyun return -ENODEV;
1387*4882a593Smuzhiyun
1388*4882a593Smuzhiyun fe0->dvb.frontend = dib7000p_ops.init(&i2c_bus->i2c_adap,
1389*4882a593Smuzhiyun 0x12, &hauppauge_hvr1400_dib7000_config);
1390*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1391*4882a593Smuzhiyun struct dvb_frontend *fe;
1392*4882a593Smuzhiyun struct xc2028_config cfg = {
1393*4882a593Smuzhiyun .i2c_adap = &dev->i2c_bus[1].i2c_adap,
1394*4882a593Smuzhiyun .i2c_addr = 0x64,
1395*4882a593Smuzhiyun };
1396*4882a593Smuzhiyun static struct xc2028_ctrl ctl = {
1397*4882a593Smuzhiyun .fname = XC3028L_DEFAULT_FIRMWARE,
1398*4882a593Smuzhiyun .max_len = 64,
1399*4882a593Smuzhiyun .demod = XC3028_FE_DIBCOM52,
1400*4882a593Smuzhiyun /* This is true for all demods with
1401*4882a593Smuzhiyun v36 firmware? */
1402*4882a593Smuzhiyun .type = XC2028_D2633,
1403*4882a593Smuzhiyun };
1404*4882a593Smuzhiyun
1405*4882a593Smuzhiyun fe = dvb_attach(xc2028_attach,
1406*4882a593Smuzhiyun fe0->dvb.frontend, &cfg);
1407*4882a593Smuzhiyun if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1408*4882a593Smuzhiyun fe->ops.tuner_ops.set_config(fe, &ctl);
1409*4882a593Smuzhiyun }
1410*4882a593Smuzhiyun break;
1411*4882a593Smuzhiyun case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
1412*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[port->nr - 1];
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1415*4882a593Smuzhiyun &dvico_s5h1409_config,
1416*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1417*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1418*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1419*4882a593Smuzhiyun &dvico_s5h1411_config,
1420*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1421*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL)
1422*4882a593Smuzhiyun dvb_attach(xc5000_attach, fe0->dvb.frontend,
1423*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1424*4882a593Smuzhiyun &dvico_xc5000_tunerconfig);
1425*4882a593Smuzhiyun break;
1426*4882a593Smuzhiyun case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
1427*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[port->nr - 1];
1428*4882a593Smuzhiyun
1429*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(zl10353_attach,
1430*4882a593Smuzhiyun &dvico_fusionhdtv_xc3028,
1431*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1432*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1433*4882a593Smuzhiyun struct dvb_frontend *fe;
1434*4882a593Smuzhiyun struct xc2028_config cfg = {
1435*4882a593Smuzhiyun .i2c_adap = &i2c_bus->i2c_adap,
1436*4882a593Smuzhiyun .i2c_addr = 0x61,
1437*4882a593Smuzhiyun };
1438*4882a593Smuzhiyun static struct xc2028_ctrl ctl = {
1439*4882a593Smuzhiyun .fname = XC2028_DEFAULT_FIRMWARE,
1440*4882a593Smuzhiyun .max_len = 64,
1441*4882a593Smuzhiyun .demod = XC3028_FE_ZARLINK456,
1442*4882a593Smuzhiyun };
1443*4882a593Smuzhiyun
1444*4882a593Smuzhiyun fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
1445*4882a593Smuzhiyun &cfg);
1446*4882a593Smuzhiyun if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1447*4882a593Smuzhiyun fe->ops.tuner_ops.set_config(fe, &ctl);
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun break;
1450*4882a593Smuzhiyun }
1451*4882a593Smuzhiyun case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2: {
1452*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[port->nr - 1];
1453*4882a593Smuzhiyun /* cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); */
1454*4882a593Smuzhiyun /* cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); */
1455*4882a593Smuzhiyun
1456*4882a593Smuzhiyun if (!dvb_attach(dib7000p_attach, &dib7000p_ops))
1457*4882a593Smuzhiyun return -ENODEV;
1458*4882a593Smuzhiyun
1459*4882a593Smuzhiyun if (dib7000p_ops.i2c_enumeration(&i2c_bus->i2c_adap, 1, 0x12, &dib7070p_dib7000p_config) < 0) {
1460*4882a593Smuzhiyun pr_warn("Unable to enumerate dib7000p\n");
1461*4882a593Smuzhiyun return -ENODEV;
1462*4882a593Smuzhiyun }
1463*4882a593Smuzhiyun fe0->dvb.frontend = dib7000p_ops.init(&i2c_bus->i2c_adap, 0x80, &dib7070p_dib7000p_config);
1464*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1465*4882a593Smuzhiyun struct i2c_adapter *tun_i2c;
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun fe0->dvb.frontend->sec_priv = kmemdup(&dib7000p_ops, sizeof(dib7000p_ops), GFP_KERNEL);
1468*4882a593Smuzhiyun if (!fe0->dvb.frontend->sec_priv)
1469*4882a593Smuzhiyun return -ENOMEM;
1470*4882a593Smuzhiyun tun_i2c = dib7000p_ops.get_i2c_master(fe0->dvb.frontend, DIBX000_I2C_INTERFACE_TUNER, 1);
1471*4882a593Smuzhiyun if (!dvb_attach(dib0070_attach, fe0->dvb.frontend, tun_i2c, &dib7070p_dib0070_config))
1472*4882a593Smuzhiyun return -ENODEV;
1473*4882a593Smuzhiyun }
1474*4882a593Smuzhiyun break;
1475*4882a593Smuzhiyun }
1476*4882a593Smuzhiyun case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
1477*4882a593Smuzhiyun case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
1478*4882a593Smuzhiyun case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1479*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1480*4882a593Smuzhiyun
1481*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(zl10353_attach,
1482*4882a593Smuzhiyun &dvico_fusionhdtv_xc3028,
1483*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1484*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1485*4882a593Smuzhiyun struct dvb_frontend *fe;
1486*4882a593Smuzhiyun struct xc2028_config cfg = {
1487*4882a593Smuzhiyun .i2c_adap = &dev->i2c_bus[1].i2c_adap,
1488*4882a593Smuzhiyun .i2c_addr = 0x61,
1489*4882a593Smuzhiyun };
1490*4882a593Smuzhiyun static struct xc2028_ctrl ctl = {
1491*4882a593Smuzhiyun .fname = XC2028_DEFAULT_FIRMWARE,
1492*4882a593Smuzhiyun .max_len = 64,
1493*4882a593Smuzhiyun .demod = XC3028_FE_ZARLINK456,
1494*4882a593Smuzhiyun };
1495*4882a593Smuzhiyun
1496*4882a593Smuzhiyun fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
1497*4882a593Smuzhiyun &cfg);
1498*4882a593Smuzhiyun if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1499*4882a593Smuzhiyun fe->ops.tuner_ops.set_config(fe, &ctl);
1500*4882a593Smuzhiyun }
1501*4882a593Smuzhiyun break;
1502*4882a593Smuzhiyun case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
1503*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(zl10353_attach,
1506*4882a593Smuzhiyun &dvico_fusionhdtv_xc3028,
1507*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1508*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1509*4882a593Smuzhiyun struct dvb_frontend *fe;
1510*4882a593Smuzhiyun struct xc4000_config cfg = {
1511*4882a593Smuzhiyun .i2c_address = 0x61,
1512*4882a593Smuzhiyun .default_pm = 0,
1513*4882a593Smuzhiyun .dvb_amplitude = 134,
1514*4882a593Smuzhiyun .set_smoothedcvbs = 1,
1515*4882a593Smuzhiyun .if_khz = 4560
1516*4882a593Smuzhiyun };
1517*4882a593Smuzhiyun
1518*4882a593Smuzhiyun fe = dvb_attach(xc4000_attach, fe0->dvb.frontend,
1519*4882a593Smuzhiyun &dev->i2c_bus[1].i2c_adap, &cfg);
1520*4882a593Smuzhiyun if (!fe) {
1521*4882a593Smuzhiyun pr_err("%s/2: xc4000 attach failed\n",
1522*4882a593Smuzhiyun dev->name);
1523*4882a593Smuzhiyun goto frontend_detach;
1524*4882a593Smuzhiyun }
1525*4882a593Smuzhiyun }
1526*4882a593Smuzhiyun break;
1527*4882a593Smuzhiyun case CX23885_BOARD_TBS_6920:
1528*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1529*4882a593Smuzhiyun
1530*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(cx24116_attach,
1531*4882a593Smuzhiyun &tbs_cx24116_config,
1532*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1533*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL)
1534*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
1535*4882a593Smuzhiyun
1536*4882a593Smuzhiyun break;
1537*4882a593Smuzhiyun case CX23885_BOARD_TBS_6980:
1538*4882a593Smuzhiyun case CX23885_BOARD_TBS_6981:
1539*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1540*4882a593Smuzhiyun
1541*4882a593Smuzhiyun switch (port->nr) {
1542*4882a593Smuzhiyun /* PORT B */
1543*4882a593Smuzhiyun case 1:
1544*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(cx24117_attach,
1545*4882a593Smuzhiyun &tbs_cx24117_config,
1546*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1547*4882a593Smuzhiyun break;
1548*4882a593Smuzhiyun /* PORT C */
1549*4882a593Smuzhiyun case 2:
1550*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(cx24117_attach,
1551*4882a593Smuzhiyun &tbs_cx24117_config,
1552*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1553*4882a593Smuzhiyun break;
1554*4882a593Smuzhiyun }
1555*4882a593Smuzhiyun break;
1556*4882a593Smuzhiyun case CX23885_BOARD_TEVII_S470:
1557*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1558*4882a593Smuzhiyun
1559*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(ds3000_attach,
1560*4882a593Smuzhiyun &tevii_ds3000_config,
1561*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1562*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1563*4882a593Smuzhiyun dvb_attach(ts2020_attach, fe0->dvb.frontend,
1564*4882a593Smuzhiyun &tevii_ts2020_config, &i2c_bus->i2c_adap);
1565*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage = f300_set_voltage;
1566*4882a593Smuzhiyun }
1567*4882a593Smuzhiyun
1568*4882a593Smuzhiyun break;
1569*4882a593Smuzhiyun case CX23885_BOARD_DVBWORLD_2005:
1570*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1571*4882a593Smuzhiyun
1572*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(cx24116_attach,
1573*4882a593Smuzhiyun &dvbworld_cx24116_config,
1574*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1575*4882a593Smuzhiyun break;
1576*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1577*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1578*4882a593Smuzhiyun switch (port->nr) {
1579*4882a593Smuzhiyun /* port B */
1580*4882a593Smuzhiyun case 1:
1581*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(stv0900_attach,
1582*4882a593Smuzhiyun &netup_stv0900_config,
1583*4882a593Smuzhiyun &i2c_bus->i2c_adap, 0);
1584*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1585*4882a593Smuzhiyun if (dvb_attach(stv6110_attach,
1586*4882a593Smuzhiyun fe0->dvb.frontend,
1587*4882a593Smuzhiyun &netup_stv6110_tunerconfig_a,
1588*4882a593Smuzhiyun &i2c_bus->i2c_adap)) {
1589*4882a593Smuzhiyun if (!dvb_attach(lnbh24_attach,
1590*4882a593Smuzhiyun fe0->dvb.frontend,
1591*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1592*4882a593Smuzhiyun LNBH24_PCL | LNBH24_TTX,
1593*4882a593Smuzhiyun LNBH24_TEN, 0x09))
1594*4882a593Smuzhiyun pr_err("No LNBH24 found!\n");
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyun }
1597*4882a593Smuzhiyun }
1598*4882a593Smuzhiyun break;
1599*4882a593Smuzhiyun /* port C */
1600*4882a593Smuzhiyun case 2:
1601*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(stv0900_attach,
1602*4882a593Smuzhiyun &netup_stv0900_config,
1603*4882a593Smuzhiyun &i2c_bus->i2c_adap, 1);
1604*4882a593Smuzhiyun if (fe0->dvb.frontend != NULL) {
1605*4882a593Smuzhiyun if (dvb_attach(stv6110_attach,
1606*4882a593Smuzhiyun fe0->dvb.frontend,
1607*4882a593Smuzhiyun &netup_stv6110_tunerconfig_b,
1608*4882a593Smuzhiyun &i2c_bus->i2c_adap)) {
1609*4882a593Smuzhiyun if (!dvb_attach(lnbh24_attach,
1610*4882a593Smuzhiyun fe0->dvb.frontend,
1611*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1612*4882a593Smuzhiyun LNBH24_PCL | LNBH24_TTX,
1613*4882a593Smuzhiyun LNBH24_TEN, 0x0a))
1614*4882a593Smuzhiyun pr_err("No LNBH24 found!\n");
1615*4882a593Smuzhiyun
1616*4882a593Smuzhiyun }
1617*4882a593Smuzhiyun }
1618*4882a593Smuzhiyun break;
1619*4882a593Smuzhiyun }
1620*4882a593Smuzhiyun break;
1621*4882a593Smuzhiyun case CX23885_BOARD_MYGICA_X8506:
1622*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1623*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1624*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
1625*4882a593Smuzhiyun &mygica_x8506_lgs8gl5_config,
1626*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1627*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1628*4882a593Smuzhiyun break;
1629*4882a593Smuzhiyun dvb_attach(xc5000_attach, fe0->dvb.frontend,
1630*4882a593Smuzhiyun &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config);
1631*4882a593Smuzhiyun cx23885_set_frontend_hook(port, fe0->dvb.frontend);
1632*4882a593Smuzhiyun break;
1633*4882a593Smuzhiyun case CX23885_BOARD_MYGICA_X8507:
1634*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1635*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1636*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
1637*4882a593Smuzhiyun &mygica_x8507_mb86a20s_config,
1638*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1639*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1640*4882a593Smuzhiyun break;
1641*4882a593Smuzhiyun
1642*4882a593Smuzhiyun dvb_attach(xc5000_attach, fe0->dvb.frontend,
1643*4882a593Smuzhiyun &i2c_bus2->i2c_adap,
1644*4882a593Smuzhiyun &mygica_x8507_xc5000_config);
1645*4882a593Smuzhiyun cx23885_set_frontend_hook(port, fe0->dvb.frontend);
1646*4882a593Smuzhiyun break;
1647*4882a593Smuzhiyun case CX23885_BOARD_MAGICPRO_PROHDTVE2:
1648*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1649*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1650*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
1651*4882a593Smuzhiyun &magicpro_prohdtve2_lgs8g75_config,
1652*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1653*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1654*4882a593Smuzhiyun break;
1655*4882a593Smuzhiyun dvb_attach(xc5000_attach, fe0->dvb.frontend,
1656*4882a593Smuzhiyun &i2c_bus2->i2c_adap,
1657*4882a593Smuzhiyun &magicpro_prohdtve2_xc5000_config);
1658*4882a593Smuzhiyun cx23885_set_frontend_hook(port, fe0->dvb.frontend);
1659*4882a593Smuzhiyun break;
1660*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1850:
1661*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1662*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1663*4882a593Smuzhiyun &hcw_s5h1411_config,
1664*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1665*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1666*4882a593Smuzhiyun break;
1667*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1668*4882a593Smuzhiyun 0x60, &dev->i2c_bus[0].i2c_adap,
1669*4882a593Smuzhiyun &hauppauge_tda18271_config);
1670*4882a593Smuzhiyun
1671*4882a593Smuzhiyun tda18271_attach(&dev->ts1.analog_fe,
1672*4882a593Smuzhiyun 0x60, &dev->i2c_bus[1].i2c_adap,
1673*4882a593Smuzhiyun &hauppauge_tda18271_config);
1674*4882a593Smuzhiyun
1675*4882a593Smuzhiyun break;
1676*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1290:
1677*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1678*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1679*4882a593Smuzhiyun &hcw_s5h1411_config,
1680*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1681*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1682*4882a593Smuzhiyun break;
1683*4882a593Smuzhiyun dvb_attach(tda18271_attach, fe0->dvb.frontend,
1684*4882a593Smuzhiyun 0x60, &dev->i2c_bus[0].i2c_adap,
1685*4882a593Smuzhiyun &hauppauge_tda18271_config);
1686*4882a593Smuzhiyun break;
1687*4882a593Smuzhiyun case CX23885_BOARD_MYGICA_X8558PRO:
1688*4882a593Smuzhiyun switch (port->nr) {
1689*4882a593Smuzhiyun /* port B */
1690*4882a593Smuzhiyun case 1:
1691*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1692*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(atbm8830_attach,
1693*4882a593Smuzhiyun &mygica_x8558pro_atbm8830_cfg1,
1694*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1695*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1696*4882a593Smuzhiyun break;
1697*4882a593Smuzhiyun dvb_attach(max2165_attach, fe0->dvb.frontend,
1698*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1699*4882a593Smuzhiyun &mygic_x8558pro_max2165_cfg1);
1700*4882a593Smuzhiyun break;
1701*4882a593Smuzhiyun /* port C */
1702*4882a593Smuzhiyun case 2:
1703*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1704*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(atbm8830_attach,
1705*4882a593Smuzhiyun &mygica_x8558pro_atbm8830_cfg2,
1706*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1707*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1708*4882a593Smuzhiyun break;
1709*4882a593Smuzhiyun dvb_attach(max2165_attach, fe0->dvb.frontend,
1710*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1711*4882a593Smuzhiyun &mygic_x8558pro_max2165_cfg2);
1712*4882a593Smuzhiyun }
1713*4882a593Smuzhiyun break;
1714*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1715*4882a593Smuzhiyun if (port->nr > 2)
1716*4882a593Smuzhiyun return 0;
1717*4882a593Smuzhiyun
1718*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1719*4882a593Smuzhiyun mfe_shared = 1;/* MFE */
1720*4882a593Smuzhiyun port->frontends.gate = 0;/* not clear for me yet */
1721*4882a593Smuzhiyun /* ports B, C */
1722*4882a593Smuzhiyun /* MFE frontend 1 DVB-T */
1723*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(stv0367ter_attach,
1724*4882a593Smuzhiyun &netup_stv0367_config[port->nr - 1],
1725*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1726*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1727*4882a593Smuzhiyun break;
1728*4882a593Smuzhiyun if (NULL == dvb_attach(xc5000_attach, fe0->dvb.frontend,
1729*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1730*4882a593Smuzhiyun &netup_xc5000_config[port->nr - 1]))
1731*4882a593Smuzhiyun goto frontend_detach;
1732*4882a593Smuzhiyun /* load xc5000 firmware */
1733*4882a593Smuzhiyun fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
1734*4882a593Smuzhiyun
1735*4882a593Smuzhiyun /* MFE frontend 2 */
1736*4882a593Smuzhiyun fe1 = vb2_dvb_get_frontend(&port->frontends, 2);
1737*4882a593Smuzhiyun if (fe1 == NULL)
1738*4882a593Smuzhiyun goto frontend_detach;
1739*4882a593Smuzhiyun /* DVB-C init */
1740*4882a593Smuzhiyun fe1->dvb.frontend = dvb_attach(stv0367cab_attach,
1741*4882a593Smuzhiyun &netup_stv0367_config[port->nr - 1],
1742*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1743*4882a593Smuzhiyun if (fe1->dvb.frontend == NULL)
1744*4882a593Smuzhiyun break;
1745*4882a593Smuzhiyun
1746*4882a593Smuzhiyun fe1->dvb.frontend->id = 1;
1747*4882a593Smuzhiyun if (NULL == dvb_attach(xc5000_attach,
1748*4882a593Smuzhiyun fe1->dvb.frontend,
1749*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1750*4882a593Smuzhiyun &netup_xc5000_config[port->nr - 1]))
1751*4882a593Smuzhiyun goto frontend_detach;
1752*4882a593Smuzhiyun break;
1753*4882a593Smuzhiyun case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
1754*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1755*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1756*4882a593Smuzhiyun
1757*4882a593Smuzhiyun switch (port->nr) {
1758*4882a593Smuzhiyun /* port b */
1759*4882a593Smuzhiyun case 1:
1760*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(drxk_attach,
1761*4882a593Smuzhiyun &terratec_drxk_config[0],
1762*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1763*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1764*4882a593Smuzhiyun break;
1765*4882a593Smuzhiyun if (!dvb_attach(mt2063_attach,
1766*4882a593Smuzhiyun fe0->dvb.frontend,
1767*4882a593Smuzhiyun &terratec_mt2063_config[0],
1768*4882a593Smuzhiyun &i2c_bus2->i2c_adap))
1769*4882a593Smuzhiyun goto frontend_detach;
1770*4882a593Smuzhiyun break;
1771*4882a593Smuzhiyun /* port c */
1772*4882a593Smuzhiyun case 2:
1773*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(drxk_attach,
1774*4882a593Smuzhiyun &terratec_drxk_config[1],
1775*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1776*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1777*4882a593Smuzhiyun break;
1778*4882a593Smuzhiyun if (!dvb_attach(mt2063_attach,
1779*4882a593Smuzhiyun fe0->dvb.frontend,
1780*4882a593Smuzhiyun &terratec_mt2063_config[1],
1781*4882a593Smuzhiyun &i2c_bus2->i2c_adap))
1782*4882a593Smuzhiyun goto frontend_detach;
1783*4882a593Smuzhiyun break;
1784*4882a593Smuzhiyun }
1785*4882a593Smuzhiyun break;
1786*4882a593Smuzhiyun case CX23885_BOARD_TEVII_S471:
1787*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
1788*4882a593Smuzhiyun
1789*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(ds3000_attach,
1790*4882a593Smuzhiyun &tevii_ds3000_config,
1791*4882a593Smuzhiyun &i2c_bus->i2c_adap);
1792*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1793*4882a593Smuzhiyun break;
1794*4882a593Smuzhiyun dvb_attach(ts2020_attach, fe0->dvb.frontend,
1795*4882a593Smuzhiyun &tevii_ts2020_config, &i2c_bus->i2c_adap);
1796*4882a593Smuzhiyun break;
1797*4882a593Smuzhiyun case CX23885_BOARD_PROF_8000:
1798*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1799*4882a593Smuzhiyun
1800*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(stv090x_attach,
1801*4882a593Smuzhiyun &prof_8000_stv090x_config,
1802*4882a593Smuzhiyun &i2c_bus->i2c_adap,
1803*4882a593Smuzhiyun STV090x_DEMODULATOR_0);
1804*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1805*4882a593Smuzhiyun break;
1806*4882a593Smuzhiyun if (!dvb_attach(stb6100_attach,
1807*4882a593Smuzhiyun fe0->dvb.frontend,
1808*4882a593Smuzhiyun &prof_8000_stb6100_config,
1809*4882a593Smuzhiyun &i2c_bus->i2c_adap))
1810*4882a593Smuzhiyun goto frontend_detach;
1811*4882a593Smuzhiyun
1812*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
1813*4882a593Smuzhiyun break;
1814*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR4400: {
1815*4882a593Smuzhiyun struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata;
1816*4882a593Smuzhiyun struct a8293_platform_data a8293_pdata = {};
1817*4882a593Smuzhiyun
1818*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1819*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1820*4882a593Smuzhiyun switch (port->nr) {
1821*4882a593Smuzhiyun /* port b */
1822*4882a593Smuzhiyun case 1:
1823*4882a593Smuzhiyun /* attach demod + tuner combo */
1824*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
1825*4882a593Smuzhiyun strscpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
1826*4882a593Smuzhiyun info.addr = 0x05;
1827*4882a593Smuzhiyun info.platform_data = &tda10071_pdata;
1828*4882a593Smuzhiyun request_module("tda10071");
1829*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1830*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
1831*4882a593Smuzhiyun goto frontend_detach;
1832*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
1833*4882a593Smuzhiyun i2c_unregister_device(client_demod);
1834*4882a593Smuzhiyun goto frontend_detach;
1835*4882a593Smuzhiyun }
1836*4882a593Smuzhiyun fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod);
1837*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
1838*4882a593Smuzhiyun
1839*4882a593Smuzhiyun /* attach SEC */
1840*4882a593Smuzhiyun a8293_pdata.dvb_frontend = fe0->dvb.frontend;
1841*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
1842*4882a593Smuzhiyun strscpy(info.type, "a8293", I2C_NAME_SIZE);
1843*4882a593Smuzhiyun info.addr = 0x0b;
1844*4882a593Smuzhiyun info.platform_data = &a8293_pdata;
1845*4882a593Smuzhiyun request_module("a8293");
1846*4882a593Smuzhiyun client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1847*4882a593Smuzhiyun if (!i2c_client_has_driver(client_sec))
1848*4882a593Smuzhiyun goto frontend_detach;
1849*4882a593Smuzhiyun if (!try_module_get(client_sec->dev.driver->owner)) {
1850*4882a593Smuzhiyun i2c_unregister_device(client_sec);
1851*4882a593Smuzhiyun goto frontend_detach;
1852*4882a593Smuzhiyun }
1853*4882a593Smuzhiyun port->i2c_client_sec = client_sec;
1854*4882a593Smuzhiyun break;
1855*4882a593Smuzhiyun /* port c */
1856*4882a593Smuzhiyun case 2:
1857*4882a593Smuzhiyun /* attach frontend */
1858*4882a593Smuzhiyun memset(&si2165_pdata, 0, sizeof(si2165_pdata));
1859*4882a593Smuzhiyun si2165_pdata.fe = &fe0->dvb.frontend;
1860*4882a593Smuzhiyun si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
1861*4882a593Smuzhiyun si2165_pdata.ref_freq_hz = 16000000;
1862*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
1863*4882a593Smuzhiyun strscpy(info.type, "si2165", I2C_NAME_SIZE);
1864*4882a593Smuzhiyun info.addr = 0x64;
1865*4882a593Smuzhiyun info.platform_data = &si2165_pdata;
1866*4882a593Smuzhiyun request_module(info.type);
1867*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1868*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
1869*4882a593Smuzhiyun goto frontend_detach;
1870*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
1871*4882a593Smuzhiyun i2c_unregister_device(client_demod);
1872*4882a593Smuzhiyun goto frontend_detach;
1873*4882a593Smuzhiyun }
1874*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
1875*4882a593Smuzhiyun
1876*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1877*4882a593Smuzhiyun break;
1878*4882a593Smuzhiyun fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1879*4882a593Smuzhiyun if (!dvb_attach(tda18271_attach,
1880*4882a593Smuzhiyun fe0->dvb.frontend,
1881*4882a593Smuzhiyun 0x60, &i2c_bus2->i2c_adap,
1882*4882a593Smuzhiyun &hauppauge_hvr4400_tuner_config))
1883*4882a593Smuzhiyun goto frontend_detach;
1884*4882a593Smuzhiyun break;
1885*4882a593Smuzhiyun }
1886*4882a593Smuzhiyun break;
1887*4882a593Smuzhiyun }
1888*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_STARBURST: {
1889*4882a593Smuzhiyun struct tda10071_platform_data tda10071_pdata = hauppauge_tda10071_pdata;
1890*4882a593Smuzhiyun struct a8293_platform_data a8293_pdata = {};
1891*4882a593Smuzhiyun
1892*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1893*4882a593Smuzhiyun
1894*4882a593Smuzhiyun /* attach demod + tuner combo */
1895*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
1896*4882a593Smuzhiyun strscpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
1897*4882a593Smuzhiyun info.addr = 0x05;
1898*4882a593Smuzhiyun info.platform_data = &tda10071_pdata;
1899*4882a593Smuzhiyun request_module("tda10071");
1900*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1901*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
1902*4882a593Smuzhiyun goto frontend_detach;
1903*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
1904*4882a593Smuzhiyun i2c_unregister_device(client_demod);
1905*4882a593Smuzhiyun goto frontend_detach;
1906*4882a593Smuzhiyun }
1907*4882a593Smuzhiyun fe0->dvb.frontend = tda10071_pdata.get_dvb_frontend(client_demod);
1908*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
1909*4882a593Smuzhiyun
1910*4882a593Smuzhiyun /* attach SEC */
1911*4882a593Smuzhiyun a8293_pdata.dvb_frontend = fe0->dvb.frontend;
1912*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
1913*4882a593Smuzhiyun strscpy(info.type, "a8293", I2C_NAME_SIZE);
1914*4882a593Smuzhiyun info.addr = 0x0b;
1915*4882a593Smuzhiyun info.platform_data = &a8293_pdata;
1916*4882a593Smuzhiyun request_module("a8293");
1917*4882a593Smuzhiyun client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1918*4882a593Smuzhiyun if (!i2c_client_has_driver(client_sec))
1919*4882a593Smuzhiyun goto frontend_detach;
1920*4882a593Smuzhiyun if (!try_module_get(client_sec->dev.driver->owner)) {
1921*4882a593Smuzhiyun i2c_unregister_device(client_sec);
1922*4882a593Smuzhiyun goto frontend_detach;
1923*4882a593Smuzhiyun }
1924*4882a593Smuzhiyun port->i2c_client_sec = client_sec;
1925*4882a593Smuzhiyun break;
1926*4882a593Smuzhiyun }
1927*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T9580:
1928*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S950:
1929*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
1930*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
1931*4882a593Smuzhiyun switch (port->nr) {
1932*4882a593Smuzhiyun /* port b - satellite */
1933*4882a593Smuzhiyun case 1:
1934*4882a593Smuzhiyun /* attach frontend */
1935*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
1936*4882a593Smuzhiyun &dvbsky_t9580_m88ds3103_config,
1937*4882a593Smuzhiyun &i2c_bus2->i2c_adap, &adapter);
1938*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
1939*4882a593Smuzhiyun break;
1940*4882a593Smuzhiyun
1941*4882a593Smuzhiyun /* attach tuner */
1942*4882a593Smuzhiyun memset(&ts2020_config, 0, sizeof(ts2020_config));
1943*4882a593Smuzhiyun ts2020_config.fe = fe0->dvb.frontend;
1944*4882a593Smuzhiyun ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
1945*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
1946*4882a593Smuzhiyun strscpy(info.type, "ts2020", I2C_NAME_SIZE);
1947*4882a593Smuzhiyun info.addr = 0x60;
1948*4882a593Smuzhiyun info.platform_data = &ts2020_config;
1949*4882a593Smuzhiyun request_module(info.type);
1950*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
1951*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
1952*4882a593Smuzhiyun goto frontend_detach;
1953*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
1954*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
1955*4882a593Smuzhiyun goto frontend_detach;
1956*4882a593Smuzhiyun }
1957*4882a593Smuzhiyun
1958*4882a593Smuzhiyun /* delegate signal strength measurement to tuner */
1959*4882a593Smuzhiyun fe0->dvb.frontend->ops.read_signal_strength =
1960*4882a593Smuzhiyun fe0->dvb.frontend->ops.tuner_ops.get_rf_strength;
1961*4882a593Smuzhiyun
1962*4882a593Smuzhiyun /*
1963*4882a593Smuzhiyun * for setting the voltage we need to set GPIOs on
1964*4882a593Smuzhiyun * the card.
1965*4882a593Smuzhiyun */
1966*4882a593Smuzhiyun port->fe_set_voltage =
1967*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage;
1968*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage =
1969*4882a593Smuzhiyun dvbsky_t9580_set_voltage;
1970*4882a593Smuzhiyun
1971*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
1972*4882a593Smuzhiyun
1973*4882a593Smuzhiyun break;
1974*4882a593Smuzhiyun /* port c - terrestrial/cable */
1975*4882a593Smuzhiyun case 2:
1976*4882a593Smuzhiyun /* attach frontend */
1977*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
1978*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
1979*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
1980*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_SERIAL;
1981*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
1982*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
1983*4882a593Smuzhiyun info.addr = 0x64;
1984*4882a593Smuzhiyun info.platform_data = &si2168_config;
1985*4882a593Smuzhiyun request_module(info.type);
1986*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
1987*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
1988*4882a593Smuzhiyun goto frontend_detach;
1989*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
1990*4882a593Smuzhiyun i2c_unregister_device(client_demod);
1991*4882a593Smuzhiyun goto frontend_detach;
1992*4882a593Smuzhiyun }
1993*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
1994*4882a593Smuzhiyun
1995*4882a593Smuzhiyun /* attach tuner */
1996*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
1997*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
1998*4882a593Smuzhiyun si2157_config.if_port = 1;
1999*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2000*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2001*4882a593Smuzhiyun info.addr = 0x60;
2002*4882a593Smuzhiyun info.platform_data = &si2157_config;
2003*4882a593Smuzhiyun request_module(info.type);
2004*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2005*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2006*4882a593Smuzhiyun goto frontend_detach;
2007*4882a593Smuzhiyun
2008*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2009*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2010*4882a593Smuzhiyun goto frontend_detach;
2011*4882a593Smuzhiyun }
2012*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2013*4882a593Smuzhiyun break;
2014*4882a593Smuzhiyun }
2015*4882a593Smuzhiyun break;
2016*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T980C:
2017*4882a593Smuzhiyun case CX23885_BOARD_TT_CT2_4500_CI:
2018*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2019*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun /* attach frontend */
2022*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
2023*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
2024*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
2025*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_PARALLEL;
2026*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2027*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
2028*4882a593Smuzhiyun info.addr = 0x64;
2029*4882a593Smuzhiyun info.platform_data = &si2168_config;
2030*4882a593Smuzhiyun request_module(info.type);
2031*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
2032*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2033*4882a593Smuzhiyun goto frontend_detach;
2034*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2035*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2036*4882a593Smuzhiyun goto frontend_detach;
2037*4882a593Smuzhiyun }
2038*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2039*4882a593Smuzhiyun
2040*4882a593Smuzhiyun /* attach tuner */
2041*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2042*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2043*4882a593Smuzhiyun si2157_config.if_port = 1;
2044*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2045*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2046*4882a593Smuzhiyun info.addr = 0x60;
2047*4882a593Smuzhiyun info.platform_data = &si2157_config;
2048*4882a593Smuzhiyun request_module(info.type);
2049*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2050*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2051*4882a593Smuzhiyun goto frontend_detach;
2052*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2053*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2054*4882a593Smuzhiyun goto frontend_detach;
2055*4882a593Smuzhiyun }
2056*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2057*4882a593Smuzhiyun break;
2058*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S950C:
2059*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2060*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
2061*4882a593Smuzhiyun
2062*4882a593Smuzhiyun /* attach frontend */
2063*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
2064*4882a593Smuzhiyun &dvbsky_s950c_m88ds3103_config,
2065*4882a593Smuzhiyun &i2c_bus2->i2c_adap, &adapter);
2066*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
2067*4882a593Smuzhiyun break;
2068*4882a593Smuzhiyun
2069*4882a593Smuzhiyun /* attach tuner */
2070*4882a593Smuzhiyun memset(&ts2020_config, 0, sizeof(ts2020_config));
2071*4882a593Smuzhiyun ts2020_config.fe = fe0->dvb.frontend;
2072*4882a593Smuzhiyun ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
2073*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2074*4882a593Smuzhiyun strscpy(info.type, "ts2020", I2C_NAME_SIZE);
2075*4882a593Smuzhiyun info.addr = 0x60;
2076*4882a593Smuzhiyun info.platform_data = &ts2020_config;
2077*4882a593Smuzhiyun request_module(info.type);
2078*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2079*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2080*4882a593Smuzhiyun goto frontend_detach;
2081*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2082*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2083*4882a593Smuzhiyun goto frontend_detach;
2084*4882a593Smuzhiyun }
2085*4882a593Smuzhiyun
2086*4882a593Smuzhiyun /* delegate signal strength measurement to tuner */
2087*4882a593Smuzhiyun fe0->dvb.frontend->ops.read_signal_strength =
2088*4882a593Smuzhiyun fe0->dvb.frontend->ops.tuner_ops.get_rf_strength;
2089*4882a593Smuzhiyun
2090*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2091*4882a593Smuzhiyun break;
2092*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_S952:
2093*4882a593Smuzhiyun /* attach frontend */
2094*4882a593Smuzhiyun memset(&m88ds3103_pdata, 0, sizeof(m88ds3103_pdata));
2095*4882a593Smuzhiyun m88ds3103_pdata.clk = 27000000;
2096*4882a593Smuzhiyun m88ds3103_pdata.i2c_wr_max = 33;
2097*4882a593Smuzhiyun m88ds3103_pdata.agc = 0x99;
2098*4882a593Smuzhiyun m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_DISABLED;
2099*4882a593Smuzhiyun m88ds3103_pdata.lnb_en_pol = 1;
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun switch (port->nr) {
2102*4882a593Smuzhiyun /* port b */
2103*4882a593Smuzhiyun case 1:
2104*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
2105*4882a593Smuzhiyun m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
2106*4882a593Smuzhiyun m88ds3103_pdata.ts_clk = 16000;
2107*4882a593Smuzhiyun m88ds3103_pdata.ts_clk_pol = 1;
2108*4882a593Smuzhiyun p_set_voltage = dvbsky_t9580_set_voltage;
2109*4882a593Smuzhiyun break;
2110*4882a593Smuzhiyun /* port c */
2111*4882a593Smuzhiyun case 2:
2112*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2113*4882a593Smuzhiyun m88ds3103_pdata.ts_mode = M88DS3103_TS_SERIAL;
2114*4882a593Smuzhiyun m88ds3103_pdata.ts_clk = 96000;
2115*4882a593Smuzhiyun m88ds3103_pdata.ts_clk_pol = 0;
2116*4882a593Smuzhiyun p_set_voltage = dvbsky_s952_portc_set_voltage;
2117*4882a593Smuzhiyun break;
2118*4882a593Smuzhiyun default:
2119*4882a593Smuzhiyun return 0;
2120*4882a593Smuzhiyun }
2121*4882a593Smuzhiyun
2122*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
2123*4882a593Smuzhiyun strscpy(info.type, "m88ds3103", I2C_NAME_SIZE);
2124*4882a593Smuzhiyun info.addr = 0x68;
2125*4882a593Smuzhiyun info.platform_data = &m88ds3103_pdata;
2126*4882a593Smuzhiyun request_module(info.type);
2127*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
2128*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2129*4882a593Smuzhiyun goto frontend_detach;
2130*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2131*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2132*4882a593Smuzhiyun goto frontend_detach;
2133*4882a593Smuzhiyun }
2134*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2135*4882a593Smuzhiyun adapter = m88ds3103_pdata.get_i2c_adapter(client_demod);
2136*4882a593Smuzhiyun fe0->dvb.frontend = m88ds3103_pdata.get_dvb_frontend(client_demod);
2137*4882a593Smuzhiyun
2138*4882a593Smuzhiyun /* attach tuner */
2139*4882a593Smuzhiyun memset(&ts2020_config, 0, sizeof(ts2020_config));
2140*4882a593Smuzhiyun ts2020_config.fe = fe0->dvb.frontend;
2141*4882a593Smuzhiyun ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
2142*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2143*4882a593Smuzhiyun strscpy(info.type, "ts2020", I2C_NAME_SIZE);
2144*4882a593Smuzhiyun info.addr = 0x60;
2145*4882a593Smuzhiyun info.platform_data = &ts2020_config;
2146*4882a593Smuzhiyun request_module(info.type);
2147*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2148*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2149*4882a593Smuzhiyun goto frontend_detach;
2150*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2151*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2152*4882a593Smuzhiyun goto frontend_detach;
2153*4882a593Smuzhiyun }
2154*4882a593Smuzhiyun
2155*4882a593Smuzhiyun /* delegate signal strength measurement to tuner */
2156*4882a593Smuzhiyun fe0->dvb.frontend->ops.read_signal_strength =
2157*4882a593Smuzhiyun fe0->dvb.frontend->ops.tuner_ops.get_rf_strength;
2158*4882a593Smuzhiyun
2159*4882a593Smuzhiyun /*
2160*4882a593Smuzhiyun * for setting the voltage we need to set GPIOs on
2161*4882a593Smuzhiyun * the card.
2162*4882a593Smuzhiyun */
2163*4882a593Smuzhiyun port->fe_set_voltage =
2164*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage;
2165*4882a593Smuzhiyun fe0->dvb.frontend->ops.set_voltage = p_set_voltage;
2166*4882a593Smuzhiyun
2167*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2168*4882a593Smuzhiyun break;
2169*4882a593Smuzhiyun case CX23885_BOARD_DVBSKY_T982:
2170*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
2171*4882a593Smuzhiyun switch (port->nr) {
2172*4882a593Smuzhiyun /* port b */
2173*4882a593Smuzhiyun case 1:
2174*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[1];
2175*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_PARALLEL;
2176*4882a593Smuzhiyun break;
2177*4882a593Smuzhiyun /* port c */
2178*4882a593Smuzhiyun case 2:
2179*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2180*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_SERIAL;
2181*4882a593Smuzhiyun break;
2182*4882a593Smuzhiyun }
2183*4882a593Smuzhiyun
2184*4882a593Smuzhiyun /* attach frontend */
2185*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
2186*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
2187*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2188*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
2189*4882a593Smuzhiyun info.addr = 0x64;
2190*4882a593Smuzhiyun info.platform_data = &si2168_config;
2191*4882a593Smuzhiyun request_module(info.type);
2192*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
2193*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2194*4882a593Smuzhiyun goto frontend_detach;
2195*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2196*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2197*4882a593Smuzhiyun goto frontend_detach;
2198*4882a593Smuzhiyun }
2199*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2200*4882a593Smuzhiyun
2201*4882a593Smuzhiyun /* attach tuner */
2202*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2203*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2204*4882a593Smuzhiyun si2157_config.if_port = 1;
2205*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2206*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2207*4882a593Smuzhiyun info.addr = 0x60;
2208*4882a593Smuzhiyun info.platform_data = &si2157_config;
2209*4882a593Smuzhiyun request_module(info.type);
2210*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2211*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2212*4882a593Smuzhiyun goto frontend_detach;
2213*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2214*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2215*4882a593Smuzhiyun goto frontend_detach;
2216*4882a593Smuzhiyun }
2217*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2218*4882a593Smuzhiyun break;
2219*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_STARBURST2:
2220*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR5525:
2221*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2222*4882a593Smuzhiyun i2c_bus2 = &dev->i2c_bus[1];
2223*4882a593Smuzhiyun
2224*4882a593Smuzhiyun switch (port->nr) {
2225*4882a593Smuzhiyun
2226*4882a593Smuzhiyun /* port b - satellite */
2227*4882a593Smuzhiyun case 1:
2228*4882a593Smuzhiyun /* attach frontend */
2229*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
2230*4882a593Smuzhiyun &hauppauge_hvr5525_m88ds3103_config,
2231*4882a593Smuzhiyun &i2c_bus->i2c_adap, &adapter);
2232*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
2233*4882a593Smuzhiyun break;
2234*4882a593Smuzhiyun
2235*4882a593Smuzhiyun /* attach SEC */
2236*4882a593Smuzhiyun a8293_pdata.dvb_frontend = fe0->dvb.frontend;
2237*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
2238*4882a593Smuzhiyun strscpy(info.type, "a8293", I2C_NAME_SIZE);
2239*4882a593Smuzhiyun info.addr = 0x0b;
2240*4882a593Smuzhiyun info.platform_data = &a8293_pdata;
2241*4882a593Smuzhiyun request_module("a8293");
2242*4882a593Smuzhiyun client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
2243*4882a593Smuzhiyun if (!i2c_client_has_driver(client_sec))
2244*4882a593Smuzhiyun goto frontend_detach;
2245*4882a593Smuzhiyun if (!try_module_get(client_sec->dev.driver->owner)) {
2246*4882a593Smuzhiyun i2c_unregister_device(client_sec);
2247*4882a593Smuzhiyun goto frontend_detach;
2248*4882a593Smuzhiyun }
2249*4882a593Smuzhiyun port->i2c_client_sec = client_sec;
2250*4882a593Smuzhiyun
2251*4882a593Smuzhiyun /* attach tuner */
2252*4882a593Smuzhiyun memset(&m88rs6000t_config, 0, sizeof(m88rs6000t_config));
2253*4882a593Smuzhiyun m88rs6000t_config.fe = fe0->dvb.frontend;
2254*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2255*4882a593Smuzhiyun strscpy(info.type, "m88rs6000t", I2C_NAME_SIZE);
2256*4882a593Smuzhiyun info.addr = 0x21;
2257*4882a593Smuzhiyun info.platform_data = &m88rs6000t_config;
2258*4882a593Smuzhiyun request_module("%s", info.type);
2259*4882a593Smuzhiyun client_tuner = i2c_new_client_device(adapter, &info);
2260*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2261*4882a593Smuzhiyun goto frontend_detach;
2262*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2263*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2264*4882a593Smuzhiyun goto frontend_detach;
2265*4882a593Smuzhiyun }
2266*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2267*4882a593Smuzhiyun
2268*4882a593Smuzhiyun /* delegate signal strength measurement to tuner */
2269*4882a593Smuzhiyun fe0->dvb.frontend->ops.read_signal_strength =
2270*4882a593Smuzhiyun fe0->dvb.frontend->ops.tuner_ops.get_rf_strength;
2271*4882a593Smuzhiyun break;
2272*4882a593Smuzhiyun /* port c - terrestrial/cable */
2273*4882a593Smuzhiyun case 2:
2274*4882a593Smuzhiyun /* attach frontend */
2275*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
2276*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
2277*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
2278*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_SERIAL;
2279*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2280*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
2281*4882a593Smuzhiyun info.addr = 0x64;
2282*4882a593Smuzhiyun info.platform_data = &si2168_config;
2283*4882a593Smuzhiyun request_module("%s", info.type);
2284*4882a593Smuzhiyun client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
2285*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2286*4882a593Smuzhiyun goto frontend_detach;
2287*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2288*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2289*4882a593Smuzhiyun goto frontend_detach;
2290*4882a593Smuzhiyun }
2291*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2292*4882a593Smuzhiyun
2293*4882a593Smuzhiyun /* attach tuner */
2294*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2295*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2296*4882a593Smuzhiyun si2157_config.if_port = 1;
2297*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2298*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2299*4882a593Smuzhiyun info.addr = 0x60;
2300*4882a593Smuzhiyun info.platform_data = &si2157_config;
2301*4882a593Smuzhiyun request_module("%s", info.type);
2302*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
2303*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner)) {
2304*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2305*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2306*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2307*4882a593Smuzhiyun goto frontend_detach;
2308*4882a593Smuzhiyun }
2309*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2310*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2311*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2312*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2313*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2314*4882a593Smuzhiyun goto frontend_detach;
2315*4882a593Smuzhiyun }
2316*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2317*4882a593Smuzhiyun
2318*4882a593Smuzhiyun dev->ts1.analog_fe.tuner_priv = client_tuner;
2319*4882a593Smuzhiyun memcpy(&dev->ts1.analog_fe.ops.tuner_ops,
2320*4882a593Smuzhiyun &fe0->dvb.frontend->ops.tuner_ops,
2321*4882a593Smuzhiyun sizeof(struct dvb_tuner_ops));
2322*4882a593Smuzhiyun
2323*4882a593Smuzhiyun break;
2324*4882a593Smuzhiyun }
2325*4882a593Smuzhiyun break;
2326*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB:
2327*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885:
2328*4882a593Smuzhiyun pr_info("%s(): board=%d port=%d\n", __func__,
2329*4882a593Smuzhiyun dev->board, port->nr);
2330*4882a593Smuzhiyun switch (port->nr) {
2331*4882a593Smuzhiyun /* port b - Terrestrial/cable */
2332*4882a593Smuzhiyun case 1:
2333*4882a593Smuzhiyun /* attach frontend */
2334*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
2335*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
2336*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
2337*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_SERIAL;
2338*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2339*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
2340*4882a593Smuzhiyun info.addr = 0x64;
2341*4882a593Smuzhiyun info.platform_data = &si2168_config;
2342*4882a593Smuzhiyun request_module("%s", info.type);
2343*4882a593Smuzhiyun client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
2344*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2345*4882a593Smuzhiyun goto frontend_detach;
2346*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2347*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2348*4882a593Smuzhiyun goto frontend_detach;
2349*4882a593Smuzhiyun }
2350*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2351*4882a593Smuzhiyun
2352*4882a593Smuzhiyun /* attach tuner */
2353*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2354*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2355*4882a593Smuzhiyun si2157_config.if_port = 1;
2356*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2357*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2358*4882a593Smuzhiyun info.addr = 0x60;
2359*4882a593Smuzhiyun info.platform_data = &si2157_config;
2360*4882a593Smuzhiyun request_module("%s", info.type);
2361*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
2362*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner)) {
2363*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2364*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2365*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2366*4882a593Smuzhiyun goto frontend_detach;
2367*4882a593Smuzhiyun }
2368*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2369*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2370*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2371*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2372*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2373*4882a593Smuzhiyun goto frontend_detach;
2374*4882a593Smuzhiyun }
2375*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2376*4882a593Smuzhiyun
2377*4882a593Smuzhiyun /* we only attach tuner for analog on the 888 version */
2378*4882a593Smuzhiyun if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) {
2379*4882a593Smuzhiyun pr_info("%s(): QUADHD_DVB analog setup\n",
2380*4882a593Smuzhiyun __func__);
2381*4882a593Smuzhiyun dev->ts1.analog_fe.tuner_priv = client_tuner;
2382*4882a593Smuzhiyun memcpy(&dev->ts1.analog_fe.ops.tuner_ops,
2383*4882a593Smuzhiyun &fe0->dvb.frontend->ops.tuner_ops,
2384*4882a593Smuzhiyun sizeof(struct dvb_tuner_ops));
2385*4882a593Smuzhiyun }
2386*4882a593Smuzhiyun break;
2387*4882a593Smuzhiyun
2388*4882a593Smuzhiyun /* port c - terrestrial/cable */
2389*4882a593Smuzhiyun case 2:
2390*4882a593Smuzhiyun /* attach frontend */
2391*4882a593Smuzhiyun memset(&si2168_config, 0, sizeof(si2168_config));
2392*4882a593Smuzhiyun si2168_config.i2c_adapter = &adapter;
2393*4882a593Smuzhiyun si2168_config.fe = &fe0->dvb.frontend;
2394*4882a593Smuzhiyun si2168_config.ts_mode = SI2168_TS_SERIAL;
2395*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2396*4882a593Smuzhiyun strscpy(info.type, "si2168", I2C_NAME_SIZE);
2397*4882a593Smuzhiyun info.addr = 0x66;
2398*4882a593Smuzhiyun info.platform_data = &si2168_config;
2399*4882a593Smuzhiyun request_module("%s", info.type);
2400*4882a593Smuzhiyun client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
2401*4882a593Smuzhiyun if (!i2c_client_has_driver(client_demod))
2402*4882a593Smuzhiyun goto frontend_detach;
2403*4882a593Smuzhiyun if (!try_module_get(client_demod->dev.driver->owner)) {
2404*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2405*4882a593Smuzhiyun goto frontend_detach;
2406*4882a593Smuzhiyun }
2407*4882a593Smuzhiyun port->i2c_client_demod = client_demod;
2408*4882a593Smuzhiyun
2409*4882a593Smuzhiyun /* attach tuner */
2410*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2411*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2412*4882a593Smuzhiyun si2157_config.if_port = 1;
2413*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2414*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2415*4882a593Smuzhiyun info.addr = 0x62;
2416*4882a593Smuzhiyun info.platform_data = &si2157_config;
2417*4882a593Smuzhiyun request_module("%s", info.type);
2418*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
2419*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner)) {
2420*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2421*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2422*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2423*4882a593Smuzhiyun goto frontend_detach;
2424*4882a593Smuzhiyun }
2425*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2426*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2427*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2428*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2429*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2430*4882a593Smuzhiyun goto frontend_detach;
2431*4882a593Smuzhiyun }
2432*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2433*4882a593Smuzhiyun break;
2434*4882a593Smuzhiyun }
2435*4882a593Smuzhiyun break;
2436*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC:
2437*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885:
2438*4882a593Smuzhiyun pr_info("%s(): board=%d port=%d\n", __func__,
2439*4882a593Smuzhiyun dev->board, port->nr);
2440*4882a593Smuzhiyun switch (port->nr) {
2441*4882a593Smuzhiyun /* port b - Terrestrial/cable */
2442*4882a593Smuzhiyun case 1:
2443*4882a593Smuzhiyun /* attach frontend */
2444*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2445*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgdt3306a_attach,
2446*4882a593Smuzhiyun &hauppauge_quadHD_ATSC_a_config, &i2c_bus->i2c_adap);
2447*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
2448*4882a593Smuzhiyun break;
2449*4882a593Smuzhiyun
2450*4882a593Smuzhiyun /* attach tuner */
2451*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2452*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2453*4882a593Smuzhiyun si2157_config.if_port = 1;
2454*4882a593Smuzhiyun si2157_config.inversion = 1;
2455*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2456*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2457*4882a593Smuzhiyun info.addr = 0x60;
2458*4882a593Smuzhiyun info.platform_data = &si2157_config;
2459*4882a593Smuzhiyun request_module("%s", info.type);
2460*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
2461*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner)) {
2462*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2463*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2464*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2465*4882a593Smuzhiyun goto frontend_detach;
2466*4882a593Smuzhiyun }
2467*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2468*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2469*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2470*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2471*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2472*4882a593Smuzhiyun goto frontend_detach;
2473*4882a593Smuzhiyun }
2474*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2475*4882a593Smuzhiyun
2476*4882a593Smuzhiyun /* we only attach tuner for analog on the 888 version */
2477*4882a593Smuzhiyun if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) {
2478*4882a593Smuzhiyun pr_info("%s(): QUADHD_ATSC analog setup\n",
2479*4882a593Smuzhiyun __func__);
2480*4882a593Smuzhiyun dev->ts1.analog_fe.tuner_priv = client_tuner;
2481*4882a593Smuzhiyun memcpy(&dev->ts1.analog_fe.ops.tuner_ops,
2482*4882a593Smuzhiyun &fe0->dvb.frontend->ops.tuner_ops,
2483*4882a593Smuzhiyun sizeof(struct dvb_tuner_ops));
2484*4882a593Smuzhiyun }
2485*4882a593Smuzhiyun break;
2486*4882a593Smuzhiyun
2487*4882a593Smuzhiyun /* port c - terrestrial/cable */
2488*4882a593Smuzhiyun case 2:
2489*4882a593Smuzhiyun /* attach frontend */
2490*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2491*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgdt3306a_attach,
2492*4882a593Smuzhiyun &hauppauge_quadHD_ATSC_b_config, &i2c_bus->i2c_adap);
2493*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
2494*4882a593Smuzhiyun break;
2495*4882a593Smuzhiyun
2496*4882a593Smuzhiyun /* attach tuner */
2497*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2498*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2499*4882a593Smuzhiyun si2157_config.if_port = 1;
2500*4882a593Smuzhiyun si2157_config.inversion = 1;
2501*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2502*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2503*4882a593Smuzhiyun info.addr = 0x62;
2504*4882a593Smuzhiyun info.platform_data = &si2157_config;
2505*4882a593Smuzhiyun request_module("%s", info.type);
2506*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
2507*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner)) {
2508*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2509*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2510*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2511*4882a593Smuzhiyun goto frontend_detach;
2512*4882a593Smuzhiyun }
2513*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2514*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2515*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2516*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2517*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2518*4882a593Smuzhiyun goto frontend_detach;
2519*4882a593Smuzhiyun }
2520*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2521*4882a593Smuzhiyun break;
2522*4882a593Smuzhiyun }
2523*4882a593Smuzhiyun break;
2524*4882a593Smuzhiyun case CX23885_BOARD_HAUPPAUGE_HVR1265_K4:
2525*4882a593Smuzhiyun switch (port->nr) {
2526*4882a593Smuzhiyun /* port c - Terrestrial/cable */
2527*4882a593Smuzhiyun case 2:
2528*4882a593Smuzhiyun /* attach frontend */
2529*4882a593Smuzhiyun i2c_bus = &dev->i2c_bus[0];
2530*4882a593Smuzhiyun fe0->dvb.frontend = dvb_attach(lgdt3306a_attach,
2531*4882a593Smuzhiyun &hauppauge_hvr1265k4_config,
2532*4882a593Smuzhiyun &i2c_bus->i2c_adap);
2533*4882a593Smuzhiyun if (fe0->dvb.frontend == NULL)
2534*4882a593Smuzhiyun break;
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun /* attach tuner */
2537*4882a593Smuzhiyun memset(&si2157_config, 0, sizeof(si2157_config));
2538*4882a593Smuzhiyun si2157_config.fe = fe0->dvb.frontend;
2539*4882a593Smuzhiyun si2157_config.if_port = 1;
2540*4882a593Smuzhiyun si2157_config.inversion = 1;
2541*4882a593Smuzhiyun memset(&info, 0, sizeof(struct i2c_board_info));
2542*4882a593Smuzhiyun strscpy(info.type, "si2157", I2C_NAME_SIZE);
2543*4882a593Smuzhiyun info.addr = 0x60;
2544*4882a593Smuzhiyun info.platform_data = &si2157_config;
2545*4882a593Smuzhiyun request_module("%s", info.type);
2546*4882a593Smuzhiyun client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
2547*4882a593Smuzhiyun if (!i2c_client_has_driver(client_tuner))
2548*4882a593Smuzhiyun goto frontend_detach;
2549*4882a593Smuzhiyun
2550*4882a593Smuzhiyun if (!try_module_get(client_tuner->dev.driver->owner)) {
2551*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2552*4882a593Smuzhiyun client_tuner = NULL;
2553*4882a593Smuzhiyun goto frontend_detach;
2554*4882a593Smuzhiyun }
2555*4882a593Smuzhiyun port->i2c_client_tuner = client_tuner;
2556*4882a593Smuzhiyun
2557*4882a593Smuzhiyun dev->ts1.analog_fe.tuner_priv = client_tuner;
2558*4882a593Smuzhiyun memcpy(&dev->ts1.analog_fe.ops.tuner_ops,
2559*4882a593Smuzhiyun &fe0->dvb.frontend->ops.tuner_ops,
2560*4882a593Smuzhiyun sizeof(struct dvb_tuner_ops));
2561*4882a593Smuzhiyun break;
2562*4882a593Smuzhiyun }
2563*4882a593Smuzhiyun break;
2564*4882a593Smuzhiyun default:
2565*4882a593Smuzhiyun pr_info("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
2566*4882a593Smuzhiyun dev->name);
2567*4882a593Smuzhiyun break;
2568*4882a593Smuzhiyun }
2569*4882a593Smuzhiyun
2570*4882a593Smuzhiyun if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
2571*4882a593Smuzhiyun pr_err("%s: frontend initialization failed\n",
2572*4882a593Smuzhiyun dev->name);
2573*4882a593Smuzhiyun goto frontend_detach;
2574*4882a593Smuzhiyun }
2575*4882a593Smuzhiyun
2576*4882a593Smuzhiyun /* define general-purpose callback pointer */
2577*4882a593Smuzhiyun fe0->dvb.frontend->callback = cx23885_tuner_callback;
2578*4882a593Smuzhiyun if (fe1)
2579*4882a593Smuzhiyun fe1->dvb.frontend->callback = cx23885_tuner_callback;
2580*4882a593Smuzhiyun #if 0
2581*4882a593Smuzhiyun /* Ensure all frontends negotiate bus access */
2582*4882a593Smuzhiyun fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
2583*4882a593Smuzhiyun if (fe1)
2584*4882a593Smuzhiyun fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
2585*4882a593Smuzhiyun #endif
2586*4882a593Smuzhiyun
2587*4882a593Smuzhiyun /* Put the tuner in standby to keep it quiet */
2588*4882a593Smuzhiyun call_all(dev, tuner, standby);
2589*4882a593Smuzhiyun
2590*4882a593Smuzhiyun if (fe0->dvb.frontend->ops.analog_ops.standby)
2591*4882a593Smuzhiyun fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
2592*4882a593Smuzhiyun
2593*4882a593Smuzhiyun /* register everything */
2594*4882a593Smuzhiyun ret = vb2_dvb_register_bus(&port->frontends, THIS_MODULE, port,
2595*4882a593Smuzhiyun &dev->pci->dev, NULL,
2596*4882a593Smuzhiyun adapter_nr, mfe_shared);
2597*4882a593Smuzhiyun if (ret)
2598*4882a593Smuzhiyun goto frontend_detach;
2599*4882a593Smuzhiyun
2600*4882a593Smuzhiyun ret = dvb_register_ci_mac(port);
2601*4882a593Smuzhiyun if (ret)
2602*4882a593Smuzhiyun goto frontend_detach;
2603*4882a593Smuzhiyun
2604*4882a593Smuzhiyun return 0;
2605*4882a593Smuzhiyun
2606*4882a593Smuzhiyun frontend_detach:
2607*4882a593Smuzhiyun /* remove I2C client for SEC */
2608*4882a593Smuzhiyun client_sec = port->i2c_client_sec;
2609*4882a593Smuzhiyun if (client_sec) {
2610*4882a593Smuzhiyun module_put(client_sec->dev.driver->owner);
2611*4882a593Smuzhiyun i2c_unregister_device(client_sec);
2612*4882a593Smuzhiyun port->i2c_client_sec = NULL;
2613*4882a593Smuzhiyun }
2614*4882a593Smuzhiyun
2615*4882a593Smuzhiyun /* remove I2C client for tuner */
2616*4882a593Smuzhiyun client_tuner = port->i2c_client_tuner;
2617*4882a593Smuzhiyun if (client_tuner) {
2618*4882a593Smuzhiyun module_put(client_tuner->dev.driver->owner);
2619*4882a593Smuzhiyun i2c_unregister_device(client_tuner);
2620*4882a593Smuzhiyun port->i2c_client_tuner = NULL;
2621*4882a593Smuzhiyun }
2622*4882a593Smuzhiyun
2623*4882a593Smuzhiyun /* remove I2C client for demodulator */
2624*4882a593Smuzhiyun client_demod = port->i2c_client_demod;
2625*4882a593Smuzhiyun if (client_demod) {
2626*4882a593Smuzhiyun module_put(client_demod->dev.driver->owner);
2627*4882a593Smuzhiyun i2c_unregister_device(client_demod);
2628*4882a593Smuzhiyun port->i2c_client_demod = NULL;
2629*4882a593Smuzhiyun }
2630*4882a593Smuzhiyun
2631*4882a593Smuzhiyun port->gate_ctrl = NULL;
2632*4882a593Smuzhiyun vb2_dvb_dealloc_frontends(&port->frontends);
2633*4882a593Smuzhiyun return -EINVAL;
2634*4882a593Smuzhiyun }
2635*4882a593Smuzhiyun
cx23885_dvb_register(struct cx23885_tsport * port)2636*4882a593Smuzhiyun int cx23885_dvb_register(struct cx23885_tsport *port)
2637*4882a593Smuzhiyun {
2638*4882a593Smuzhiyun
2639*4882a593Smuzhiyun struct vb2_dvb_frontend *fe0;
2640*4882a593Smuzhiyun struct cx23885_dev *dev = port->dev;
2641*4882a593Smuzhiyun int err, i;
2642*4882a593Smuzhiyun
2643*4882a593Smuzhiyun /* Here we need to allocate the correct number of frontends,
2644*4882a593Smuzhiyun * as reflected in the cards struct. The reality is that currently
2645*4882a593Smuzhiyun * no cx23885 boards support this - yet. But, if we don't modify this
2646*4882a593Smuzhiyun * code then the second frontend would never be allocated (later)
2647*4882a593Smuzhiyun * and fail with error before the attach in dvb_register().
2648*4882a593Smuzhiyun * Without these changes we risk an OOPS later. The changes here
2649*4882a593Smuzhiyun * are for safety, and should provide a good foundation for the
2650*4882a593Smuzhiyun * future addition of any multi-frontend cx23885 based boards.
2651*4882a593Smuzhiyun */
2652*4882a593Smuzhiyun pr_info("%s() allocating %d frontend(s)\n", __func__,
2653*4882a593Smuzhiyun port->num_frontends);
2654*4882a593Smuzhiyun
2655*4882a593Smuzhiyun for (i = 1; i <= port->num_frontends; i++) {
2656*4882a593Smuzhiyun struct vb2_queue *q;
2657*4882a593Smuzhiyun
2658*4882a593Smuzhiyun if (vb2_dvb_alloc_frontend(
2659*4882a593Smuzhiyun &port->frontends, i) == NULL) {
2660*4882a593Smuzhiyun pr_err("%s() failed to alloc\n", __func__);
2661*4882a593Smuzhiyun return -ENOMEM;
2662*4882a593Smuzhiyun }
2663*4882a593Smuzhiyun
2664*4882a593Smuzhiyun fe0 = vb2_dvb_get_frontend(&port->frontends, i);
2665*4882a593Smuzhiyun if (!fe0)
2666*4882a593Smuzhiyun return -EINVAL;
2667*4882a593Smuzhiyun
2668*4882a593Smuzhiyun dprintk(1, "%s\n", __func__);
2669*4882a593Smuzhiyun dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n",
2670*4882a593Smuzhiyun dev->board,
2671*4882a593Smuzhiyun dev->name,
2672*4882a593Smuzhiyun dev->pci_bus,
2673*4882a593Smuzhiyun dev->pci_slot);
2674*4882a593Smuzhiyun
2675*4882a593Smuzhiyun /* dvb stuff */
2676*4882a593Smuzhiyun /* We have to init the queue for each frontend on a port. */
2677*4882a593Smuzhiyun pr_info("%s: cx23885 based dvb card\n", dev->name);
2678*4882a593Smuzhiyun q = &fe0->dvb.dvbq;
2679*4882a593Smuzhiyun q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2680*4882a593Smuzhiyun q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
2681*4882a593Smuzhiyun q->gfp_flags = GFP_DMA32;
2682*4882a593Smuzhiyun q->min_buffers_needed = 2;
2683*4882a593Smuzhiyun q->drv_priv = port;
2684*4882a593Smuzhiyun q->buf_struct_size = sizeof(struct cx23885_buffer);
2685*4882a593Smuzhiyun q->ops = &dvb_qops;
2686*4882a593Smuzhiyun q->mem_ops = &vb2_dma_sg_memops;
2687*4882a593Smuzhiyun q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2688*4882a593Smuzhiyun q->lock = &dev->lock;
2689*4882a593Smuzhiyun q->dev = &dev->pci->dev;
2690*4882a593Smuzhiyun
2691*4882a593Smuzhiyun err = vb2_queue_init(q);
2692*4882a593Smuzhiyun if (err < 0)
2693*4882a593Smuzhiyun return err;
2694*4882a593Smuzhiyun }
2695*4882a593Smuzhiyun err = dvb_register(port);
2696*4882a593Smuzhiyun if (err != 0)
2697*4882a593Smuzhiyun pr_err("%s() dvb_register failed err = %d\n",
2698*4882a593Smuzhiyun __func__, err);
2699*4882a593Smuzhiyun
2700*4882a593Smuzhiyun return err;
2701*4882a593Smuzhiyun }
2702*4882a593Smuzhiyun
cx23885_dvb_unregister(struct cx23885_tsport * port)2703*4882a593Smuzhiyun int cx23885_dvb_unregister(struct cx23885_tsport *port)
2704*4882a593Smuzhiyun {
2705*4882a593Smuzhiyun struct vb2_dvb_frontend *fe0;
2706*4882a593Smuzhiyun struct i2c_client *client;
2707*4882a593Smuzhiyun
2708*4882a593Smuzhiyun fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
2709*4882a593Smuzhiyun
2710*4882a593Smuzhiyun if (fe0 && fe0->dvb.frontend)
2711*4882a593Smuzhiyun vb2_dvb_unregister_bus(&port->frontends);
2712*4882a593Smuzhiyun
2713*4882a593Smuzhiyun /* remove I2C client for CI */
2714*4882a593Smuzhiyun client = port->i2c_client_ci;
2715*4882a593Smuzhiyun if (client) {
2716*4882a593Smuzhiyun module_put(client->dev.driver->owner);
2717*4882a593Smuzhiyun i2c_unregister_device(client);
2718*4882a593Smuzhiyun }
2719*4882a593Smuzhiyun
2720*4882a593Smuzhiyun /* remove I2C client for SEC */
2721*4882a593Smuzhiyun client = port->i2c_client_sec;
2722*4882a593Smuzhiyun if (client) {
2723*4882a593Smuzhiyun module_put(client->dev.driver->owner);
2724*4882a593Smuzhiyun i2c_unregister_device(client);
2725*4882a593Smuzhiyun }
2726*4882a593Smuzhiyun
2727*4882a593Smuzhiyun /* remove I2C client for tuner */
2728*4882a593Smuzhiyun client = port->i2c_client_tuner;
2729*4882a593Smuzhiyun if (client) {
2730*4882a593Smuzhiyun module_put(client->dev.driver->owner);
2731*4882a593Smuzhiyun i2c_unregister_device(client);
2732*4882a593Smuzhiyun }
2733*4882a593Smuzhiyun
2734*4882a593Smuzhiyun /* remove I2C client for demodulator */
2735*4882a593Smuzhiyun client = port->i2c_client_demod;
2736*4882a593Smuzhiyun if (client) {
2737*4882a593Smuzhiyun module_put(client->dev.driver->owner);
2738*4882a593Smuzhiyun i2c_unregister_device(client);
2739*4882a593Smuzhiyun }
2740*4882a593Smuzhiyun
2741*4882a593Smuzhiyun switch (port->dev->board) {
2742*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
2743*4882a593Smuzhiyun netup_ci_exit(port);
2744*4882a593Smuzhiyun break;
2745*4882a593Smuzhiyun case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
2746*4882a593Smuzhiyun altera_ci_release(port->dev, port->nr);
2747*4882a593Smuzhiyun break;
2748*4882a593Smuzhiyun }
2749*4882a593Smuzhiyun
2750*4882a593Smuzhiyun port->gate_ctrl = NULL;
2751*4882a593Smuzhiyun
2752*4882a593Smuzhiyun return 0;
2753*4882a593Smuzhiyun }
2754