aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2011-01-10 04:36:13 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:44 -0400
commit5fec18574fec3eaffcab596c1a4e943e2d413cc3 (patch)
tree0e694ed67a65e339d835dac9e6dfd119cfc667fc
parentac9725d224544954a8d3413a2a66bdf49f735d8b (diff)
[media] ngene: Support up to 4 tuners
Support up to 4 tuners for cineS2 v5, duoflex & mystique v2. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c174
1 files changed, 143 insertions, 31 deletions
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 4692a41ad95..5e6b85c3c0f 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -48,20 +48,27 @@
48 48
49static int tuner_attach_stv6110(struct ngene_channel *chan) 49static int tuner_attach_stv6110(struct ngene_channel *chan)
50{ 50{
51 struct i2c_adapter *i2c;
51 struct stv090x_config *feconf = (struct stv090x_config *) 52 struct stv090x_config *feconf = (struct stv090x_config *)
52 chan->dev->card_info->fe_config[chan->number]; 53 chan->dev->card_info->fe_config[chan->number];
53 struct stv6110x_config *tunerconf = (struct stv6110x_config *) 54 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
54 chan->dev->card_info->tuner_config[chan->number]; 55 chan->dev->card_info->tuner_config[chan->number];
55 struct stv6110x_devctl *ctl; 56 struct stv6110x_devctl *ctl;
56 57
57 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, 58 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
58 &chan->i2c_adapter); 59 if (chan->number < 2)
60 i2c = &chan->dev->channel[0].i2c_adapter;
61 else
62 i2c = &chan->dev->channel[1].i2c_adapter;
63
64 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
59 if (ctl == NULL) { 65 if (ctl == NULL) {
60 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); 66 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
61 return -ENODEV; 67 return -ENODEV;
62 } 68 }
63 69
64 feconf->tuner_init = ctl->tuner_init; 70 feconf->tuner_init = ctl->tuner_init;
71 feconf->tuner_sleep = ctl->tuner_sleep;
65 feconf->tuner_set_mode = ctl->tuner_set_mode; 72 feconf->tuner_set_mode = ctl->tuner_set_mode;
66 feconf->tuner_set_frequency = ctl->tuner_set_frequency; 73 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
67 feconf->tuner_get_frequency = ctl->tuner_get_frequency; 74 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
@@ -78,20 +85,31 @@ static int tuner_attach_stv6110(struct ngene_channel *chan)
78 85
79static int demod_attach_stv0900(struct ngene_channel *chan) 86static int demod_attach_stv0900(struct ngene_channel *chan)
80{ 87{
88 struct i2c_adapter *i2c;
81 struct stv090x_config *feconf = (struct stv090x_config *) 89 struct stv090x_config *feconf = (struct stv090x_config *)
82 chan->dev->card_info->fe_config[chan->number]; 90 chan->dev->card_info->fe_config[chan->number];
83 91
84 chan->fe = dvb_attach(stv090x_attach, 92 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
85 feconf, 93 /* Note: Both adapters share the same i2c bus, but the demod */
86 &chan->i2c_adapter, 94 /* driver requires that each demod has its own i2c adapter */
87 chan->number == 0 ? STV090x_DEMODULATOR_0 : 95 if (chan->number < 2)
88 STV090x_DEMODULATOR_1); 96 i2c = &chan->dev->channel[0].i2c_adapter;
97 else
98 i2c = &chan->dev->channel[1].i2c_adapter;
99
100 chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
101 (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
102 : STV090x_DEMODULATOR_1);
89 if (chan->fe == NULL) { 103 if (chan->fe == NULL) {
90 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); 104 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
91 return -ENODEV; 105 return -ENODEV;
92 } 106 }
93 107
94 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0, 108 /* store channel info */
109 if (feconf->tuner_i2c_lock)
110 chan->fe->analog_demod_priv = chan;
111
112 if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
95 0, chan->dev->card_info->lnb[chan->number])) { 113 0, chan->dev->card_info->lnb[chan->number])) {
96 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); 114 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
97 dvb_frontend_detach(chan->fe); 115 dvb_frontend_detach(chan->fe);
@@ -101,6 +119,71 @@ static int demod_attach_stv0900(struct ngene_channel *chan)
101 return 0; 119 return 0;
102} 120}
103 121
122static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
123{
124 struct ngene_channel *chan = fe->analog_demod_priv;
125
126 if (lock)
127 down(&chan->dev->pll_mutex);
128 else
129 up(&chan->dev->pll_mutex);
130}
131
132static int cineS2_probe(struct ngene_channel *chan)
133{
134 struct i2c_adapter *i2c;
135 struct stv090x_config *fe_conf;
136 u8 buf[3];
137 struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
138 int rc;
139
140 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
141 if (chan->number < 2)
142 i2c = &chan->dev->channel[0].i2c_adapter;
143 else
144 i2c = &chan->dev->channel[1].i2c_adapter;
145
146 fe_conf = chan->dev->card_info->fe_config[chan->number];
147 i2c_msg.addr = fe_conf->address;
148
149 /* probe demod */
150 i2c_msg.len = 2;
151 buf[0] = 0xf1;
152 buf[1] = 0x00;
153 rc = i2c_transfer(i2c, &i2c_msg, 1);
154 if (rc != 1)
155 return -ENODEV;
156
157 /* demod found, attach it */
158 rc = demod_attach_stv0900(chan);
159 if (rc < 0 || chan->number < 2)
160 return rc;
161
162 /* demod #2: reprogram outputs DPN1 & DPN2 */
163 i2c_msg.len = 3;
164 buf[0] = 0xf1;
165 switch (chan->number) {
166 case 2:
167 buf[1] = 0x5c;
168 buf[2] = 0xc2;
169 break;
170 case 3:
171 buf[1] = 0x61;
172 buf[2] = 0xcc;
173 break;
174 default:
175 return -ENODEV;
176 }
177 rc = i2c_transfer(i2c, &i2c_msg, 1);
178 if (rc != 1) {
179 printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
180 return -EIO;
181 }
182
183 return 0;
184}
185
186
104static struct lgdt330x_config aver_m780 = { 187static struct lgdt330x_config aver_m780 = {
105 .demod_address = 0xb2 >> 1, 188 .demod_address = 0xb2 >> 1,
106 .demod_chip = LGDT3303, 189 .demod_chip = LGDT3303,
@@ -151,6 +234,29 @@ static struct stv090x_config fe_cineS2 = {
151 .adc2_range = STV090x_ADC_1Vpp, 234 .adc2_range = STV090x_ADC_1Vpp,
152 235
153 .diseqc_envelope_mode = true, 236 .diseqc_envelope_mode = true,
237
238 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
239};
240
241static struct stv090x_config fe_cineS2_2 = {
242 .device = STV0900,
243 .demod_mode = STV090x_DUAL,
244 .clk_mode = STV090x_CLK_EXT,
245
246 .xtal = 27000000,
247 .address = 0x69,
248
249 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
250 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
251
252 .repeater_level = STV090x_RPTLEVEL_16,
253
254 .adc1_range = STV090x_ADC_1Vpp,
255 .adc2_range = STV090x_ADC_1Vpp,
256
257 .diseqc_envelope_mode = true,
258
259 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
154}; 260};
155 261
156static struct stv6110x_config tuner_cineS2_0 = { 262static struct stv6110x_config tuner_cineS2_0 = {
@@ -175,7 +281,8 @@ static struct ngene_info ngene_info_cineS2 = {
175 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 281 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
176 .lnb = {0x0b, 0x08}, 282 .lnb = {0x0b, 0x08},
177 .tsf = {3, 3}, 283 .tsf = {3, 3},
178 .fw_version = 15, 284 .fw_version = 18,
285 .msi_supported = true,
179}; 286};
180 287
181static struct ngene_info ngene_info_satixS2 = { 288static struct ngene_info ngene_info_satixS2 = {
@@ -188,46 +295,51 @@ static struct ngene_info ngene_info_satixS2 = {
188 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 295 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
189 .lnb = {0x0b, 0x08}, 296 .lnb = {0x0b, 0x08},
190 .tsf = {3, 3}, 297 .tsf = {3, 3},
191 .fw_version = 15, 298 .fw_version = 18,
299 .msi_supported = true,
192}; 300};
193 301
194static struct ngene_info ngene_info_satixS2v2 = { 302static struct ngene_info ngene_info_satixS2v2 = {
195 .type = NGENE_SIDEWINDER, 303 .type = NGENE_SIDEWINDER,
196 .name = "Mystique SaTiX-S2 Dual (v2)", 304 .name = "Mystique SaTiX-S2 Dual (v2)",
197 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 305 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN},
198 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 306 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
199 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 307 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
200 .fe_config = {&fe_cineS2, &fe_cineS2}, 308 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
201 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 309 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
202 .lnb = {0x0a, 0x08}, 310 .lnb = {0x0a, 0x08, 0x0b, 0x09},
203 .tsf = {3, 3}, 311 .tsf = {3, 3},
204 .fw_version = 15, 312 .fw_version = 18,
313 .msi_supported = true,
205}; 314};
206 315
207static struct ngene_info ngene_info_cineS2v5 = { 316static struct ngene_info ngene_info_cineS2v5 = {
208 .type = NGENE_SIDEWINDER, 317 .type = NGENE_SIDEWINDER,
209 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", 318 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
210 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 319 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN},
211 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 320 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
212 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 321 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
213 .fe_config = {&fe_cineS2, &fe_cineS2}, 322 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
214 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 323 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
215 .lnb = {0x0a, 0x08}, 324 .lnb = {0x0a, 0x08, 0x0b, 0x09},
216 .tsf = {3, 3}, 325 .tsf = {3, 3},
217 .fw_version = 15, 326 .fw_version = 18,
327 .msi_supported = true,
218}; 328};
219 329
330
220static struct ngene_info ngene_info_duoFlexS2 = { 331static struct ngene_info ngene_info_duoFlexS2 = {
221 .type = NGENE_SIDEWINDER, 332 .type = NGENE_SIDEWINDER,
222 .name = "Digital Devices DuoFlex S2 miniPCIe", 333 .name = "Digital Devices DuoFlex S2 miniPCIe",
223 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 334 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN},
224 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 335 .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
225 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 336 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
226 .fe_config = {&fe_cineS2, &fe_cineS2}, 337 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
227 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 338 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
228 .lnb = {0x0a, 0x08}, 339 .lnb = {0x0a, 0x08, 0x0b, 0x09},
229 .tsf = {3, 3}, 340 .tsf = {3, 3},
230 .fw_version = 15, 341 .fw_version = 18,
342 .msi_supported = true,
231}; 343};
232 344
233static struct ngene_info ngene_info_m780 = { 345static struct ngene_info ngene_info_m780 = {