diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/media/dvb/ngene/ngene-cards.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-cards.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 179 |
1 files changed, 148 insertions, 31 deletions
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 4692a41ad95b..fcf4be901ec8 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c | |||
@@ -48,20 +48,27 @@ | |||
48 | 48 | ||
49 | static int tuner_attach_stv6110(struct ngene_channel *chan) | 49 | static 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,29 +85,106 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) | |||
78 | 85 | ||
79 | static int demod_attach_stv0900(struct ngene_channel *chan) | 86 | static 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); |
116 | chan->fe = NULL; | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) | ||
124 | { | ||
125 | struct ngene_channel *chan = fe->analog_demod_priv; | ||
126 | |||
127 | if (lock) | ||
128 | down(&chan->dev->pll_mutex); | ||
129 | else | ||
130 | up(&chan->dev->pll_mutex); | ||
131 | } | ||
132 | |||
133 | static int cineS2_probe(struct ngene_channel *chan) | ||
134 | { | ||
135 | struct i2c_adapter *i2c; | ||
136 | struct stv090x_config *fe_conf; | ||
137 | u8 buf[3]; | ||
138 | struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; | ||
139 | int rc; | ||
140 | |||
141 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
142 | if (chan->number < 2) | ||
143 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
144 | else | ||
145 | i2c = &chan->dev->channel[1].i2c_adapter; | ||
146 | |||
147 | fe_conf = chan->dev->card_info->fe_config[chan->number]; | ||
148 | i2c_msg.addr = fe_conf->address; | ||
149 | |||
150 | /* probe demod */ | ||
151 | i2c_msg.len = 2; | ||
152 | buf[0] = 0xf1; | ||
153 | buf[1] = 0x00; | ||
154 | rc = i2c_transfer(i2c, &i2c_msg, 1); | ||
155 | if (rc != 1) | ||
156 | return -ENODEV; | ||
157 | |||
158 | /* demod found, attach it */ | ||
159 | rc = demod_attach_stv0900(chan); | ||
160 | if (rc < 0 || chan->number < 2) | ||
161 | return rc; | ||
162 | |||
163 | /* demod #2: reprogram outputs DPN1 & DPN2 */ | ||
164 | i2c_msg.len = 3; | ||
165 | buf[0] = 0xf1; | ||
166 | switch (chan->number) { | ||
167 | case 2: | ||
168 | buf[1] = 0x5c; | ||
169 | buf[2] = 0xc2; | ||
170 | break; | ||
171 | case 3: | ||
172 | buf[1] = 0x61; | ||
173 | buf[2] = 0xcc; | ||
174 | break; | ||
175 | default: | ||
98 | return -ENODEV; | 176 | return -ENODEV; |
99 | } | 177 | } |
178 | rc = i2c_transfer(i2c, &i2c_msg, 1); | ||
179 | if (rc != 1) { | ||
180 | printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); | ||
181 | return -EIO; | ||
182 | } | ||
100 | 183 | ||
101 | return 0; | 184 | return 0; |
102 | } | 185 | } |
103 | 186 | ||
187 | |||
104 | static struct lgdt330x_config aver_m780 = { | 188 | static struct lgdt330x_config aver_m780 = { |
105 | .demod_address = 0xb2 >> 1, | 189 | .demod_address = 0xb2 >> 1, |
106 | .demod_chip = LGDT3303, | 190 | .demod_chip = LGDT3303, |
@@ -151,6 +235,29 @@ static struct stv090x_config fe_cineS2 = { | |||
151 | .adc2_range = STV090x_ADC_1Vpp, | 235 | .adc2_range = STV090x_ADC_1Vpp, |
152 | 236 | ||
153 | .diseqc_envelope_mode = true, | 237 | .diseqc_envelope_mode = true, |
238 | |||
239 | .tuner_i2c_lock = cineS2_tuner_i2c_lock, | ||
240 | }; | ||
241 | |||
242 | static struct stv090x_config fe_cineS2_2 = { | ||
243 | .device = STV0900, | ||
244 | .demod_mode = STV090x_DUAL, | ||
245 | .clk_mode = STV090x_CLK_EXT, | ||
246 | |||
247 | .xtal = 27000000, | ||
248 | .address = 0x69, | ||
249 | |||
250 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
251 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
252 | |||
253 | .repeater_level = STV090x_RPTLEVEL_16, | ||
254 | |||
255 | .adc1_range = STV090x_ADC_1Vpp, | ||
256 | .adc2_range = STV090x_ADC_1Vpp, | ||
257 | |||
258 | .diseqc_envelope_mode = true, | ||
259 | |||
260 | .tuner_i2c_lock = cineS2_tuner_i2c_lock, | ||
154 | }; | 261 | }; |
155 | 262 | ||
156 | static struct stv6110x_config tuner_cineS2_0 = { | 263 | static struct stv6110x_config tuner_cineS2_0 = { |
@@ -175,7 +282,8 @@ static struct ngene_info ngene_info_cineS2 = { | |||
175 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | 282 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, |
176 | .lnb = {0x0b, 0x08}, | 283 | .lnb = {0x0b, 0x08}, |
177 | .tsf = {3, 3}, | 284 | .tsf = {3, 3}, |
178 | .fw_version = 15, | 285 | .fw_version = 18, |
286 | .msi_supported = true, | ||
179 | }; | 287 | }; |
180 | 288 | ||
181 | static struct ngene_info ngene_info_satixS2 = { | 289 | static struct ngene_info ngene_info_satixS2 = { |
@@ -188,46 +296,54 @@ static struct ngene_info ngene_info_satixS2 = { | |||
188 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | 296 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, |
189 | .lnb = {0x0b, 0x08}, | 297 | .lnb = {0x0b, 0x08}, |
190 | .tsf = {3, 3}, | 298 | .tsf = {3, 3}, |
191 | .fw_version = 15, | 299 | .fw_version = 18, |
300 | .msi_supported = true, | ||
192 | }; | 301 | }; |
193 | 302 | ||
194 | static struct ngene_info ngene_info_satixS2v2 = { | 303 | static struct ngene_info ngene_info_satixS2v2 = { |
195 | .type = NGENE_SIDEWINDER, | 304 | .type = NGENE_SIDEWINDER, |
196 | .name = "Mystique SaTiX-S2 Dual (v2)", | 305 | .name = "Mystique SaTiX-S2 Dual (v2)", |
197 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | 306 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, |
198 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | 307 | NGENE_IO_TSOUT}, |
199 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | 308 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, |
200 | .fe_config = {&fe_cineS2, &fe_cineS2}, | 309 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, |
201 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | 310 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, |
202 | .lnb = {0x0a, 0x08}, | 311 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, |
312 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
203 | .tsf = {3, 3}, | 313 | .tsf = {3, 3}, |
204 | .fw_version = 15, | 314 | .fw_version = 18, |
315 | .msi_supported = true, | ||
205 | }; | 316 | }; |
206 | 317 | ||
207 | static struct ngene_info ngene_info_cineS2v5 = { | 318 | static struct ngene_info ngene_info_cineS2v5 = { |
208 | .type = NGENE_SIDEWINDER, | 319 | .type = NGENE_SIDEWINDER, |
209 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", | 320 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", |
210 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | 321 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, |
211 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | 322 | NGENE_IO_TSOUT}, |
212 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | 323 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, |
213 | .fe_config = {&fe_cineS2, &fe_cineS2}, | 324 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, |
214 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | 325 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, |
215 | .lnb = {0x0a, 0x08}, | 326 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, |
327 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
216 | .tsf = {3, 3}, | 328 | .tsf = {3, 3}, |
217 | .fw_version = 15, | 329 | .fw_version = 18, |
330 | .msi_supported = true, | ||
218 | }; | 331 | }; |
219 | 332 | ||
333 | |||
220 | static struct ngene_info ngene_info_duoFlexS2 = { | 334 | static struct ngene_info ngene_info_duoFlexS2 = { |
221 | .type = NGENE_SIDEWINDER, | 335 | .type = NGENE_SIDEWINDER, |
222 | .name = "Digital Devices DuoFlex S2 miniPCIe", | 336 | .name = "Digital Devices DuoFlex S2 miniPCIe", |
223 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | 337 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, |
224 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | 338 | NGENE_IO_TSOUT}, |
225 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | 339 | .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe}, |
226 | .fe_config = {&fe_cineS2, &fe_cineS2}, | 340 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, |
227 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | 341 | .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, |
228 | .lnb = {0x0a, 0x08}, | 342 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, |
343 | .lnb = {0x0a, 0x08, 0x0b, 0x09}, | ||
229 | .tsf = {3, 3}, | 344 | .tsf = {3, 3}, |
230 | .fw_version = 15, | 345 | .fw_version = 18, |
346 | .msi_supported = true, | ||
231 | }; | 347 | }; |
232 | 348 | ||
233 | static struct ngene_info ngene_info_m780 = { | 349 | static struct ngene_info ngene_info_m780 = { |
@@ -321,6 +437,7 @@ static struct pci_driver ngene_pci_driver = { | |||
321 | .probe = ngene_probe, | 437 | .probe = ngene_probe, |
322 | .remove = __devexit_p(ngene_remove), | 438 | .remove = __devexit_p(ngene_remove), |
323 | .err_handler = &ngene_errors, | 439 | .err_handler = &ngene_errors, |
440 | .shutdown = ngene_shutdown, | ||
324 | }; | 441 | }; |
325 | 442 | ||
326 | static __init int module_init_ngene(void) | 443 | static __init int module_init_ngene(void) |