diff options
author | Devin Heitmueller <dheitmueller@kernellabs.com> | 2010-03-13 15:53:58 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:59:08 -0400 |
commit | cbddcba695563ba6c0cba35b647b6bf53ec54333 (patch) | |
tree | 1b5e74f17e02885818911e06f312ce7f2093f79d /drivers/media/dvb/ngene/ngene-cards.c | |
parent | cb1c0f8e7099ef5ba20c046df3a3790b5683c573 (diff) |
V4L/DVB: ngene: split out card specific code into a separate file
Split out the card profiles into a new file called ngene-cards.c. This is
part of a larger refactoring of the driver in preparation for adding analog
support.
Note that this patch makes *no* functional change - all I did was cut/paste the
code and add the function prototypes to ngene.h as needed.
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-cards.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c new file mode 100644 index 000000000000..692c3e226e83 --- /dev/null +++ b/drivers/media/dvb/ngene/ngene-cards.c | |||
@@ -0,0 +1,328 @@ | |||
1 | /* | ||
2 | * ngene-cards.c: nGene PCIe bridge driver - card specific info | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/pci_ids.h> | ||
34 | |||
35 | #include "ngene.h" | ||
36 | |||
37 | /* demods/tuners */ | ||
38 | #include "stv6110x.h" | ||
39 | #include "stv090x.h" | ||
40 | #include "lnbh24.h" | ||
41 | #include "lgdt330x.h" | ||
42 | #include "mt2131.h" | ||
43 | |||
44 | |||
45 | /****************************************************************************/ | ||
46 | /* Demod/tuner attachment ***************************************************/ | ||
47 | /****************************************************************************/ | ||
48 | |||
49 | static int tuner_attach_stv6110(struct ngene_channel *chan) | ||
50 | { | ||
51 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
52 | chan->dev->card_info->fe_config[chan->number]; | ||
53 | struct stv6110x_config *tunerconf = (struct stv6110x_config *) | ||
54 | chan->dev->card_info->tuner_config[chan->number]; | ||
55 | struct stv6110x_devctl *ctl; | ||
56 | |||
57 | ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, | ||
58 | &chan->i2c_adapter); | ||
59 | if (ctl == NULL) { | ||
60 | printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); | ||
61 | return -ENODEV; | ||
62 | } | ||
63 | |||
64 | feconf->tuner_init = ctl->tuner_init; | ||
65 | feconf->tuner_set_mode = ctl->tuner_set_mode; | ||
66 | feconf->tuner_set_frequency = ctl->tuner_set_frequency; | ||
67 | feconf->tuner_get_frequency = ctl->tuner_get_frequency; | ||
68 | feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
69 | feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
70 | feconf->tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
71 | feconf->tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
72 | feconf->tuner_set_refclk = ctl->tuner_set_refclk; | ||
73 | feconf->tuner_get_status = ctl->tuner_get_status; | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | |||
79 | static int demod_attach_stv0900(struct ngene_channel *chan) | ||
80 | { | ||
81 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
82 | chan->dev->card_info->fe_config[chan->number]; | ||
83 | |||
84 | chan->fe = dvb_attach(stv090x_attach, | ||
85 | feconf, | ||
86 | &chan->i2c_adapter, | ||
87 | chan->number == 0 ? STV090x_DEMODULATOR_0 : | ||
88 | STV090x_DEMODULATOR_1); | ||
89 | if (chan->fe == NULL) { | ||
90 | printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); | ||
91 | return -ENODEV; | ||
92 | } | ||
93 | |||
94 | if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0, | ||
95 | 0, chan->dev->card_info->lnb[chan->number])) { | ||
96 | printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); | ||
97 | dvb_frontend_detach(chan->fe); | ||
98 | return -ENODEV; | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static struct lgdt330x_config aver_m780 = { | ||
105 | .demod_address = 0xb2 >> 1, | ||
106 | .demod_chip = LGDT3303, | ||
107 | .serial_mpeg = 0x00, /* PARALLEL */ | ||
108 | .clock_polarity_flip = 1, | ||
109 | }; | ||
110 | |||
111 | static struct mt2131_config m780_tunerconfig = { | ||
112 | 0xc0 >> 1 | ||
113 | }; | ||
114 | |||
115 | /* A single func to attach the demo and tuner, rather than | ||
116 | * use two sep funcs like the current design mandates. | ||
117 | */ | ||
118 | static int demod_attach_lg330x(struct ngene_channel *chan) | ||
119 | { | ||
120 | chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter); | ||
121 | if (chan->fe == NULL) { | ||
122 | printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n"); | ||
123 | return -ENODEV; | ||
124 | } | ||
125 | |||
126 | dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter, | ||
127 | &m780_tunerconfig, 0); | ||
128 | |||
129 | return (chan->fe) ? 0 : -ENODEV; | ||
130 | } | ||
131 | |||
132 | /****************************************************************************/ | ||
133 | /* Switch control (I2C gates, etc.) *****************************************/ | ||
134 | /****************************************************************************/ | ||
135 | |||
136 | |||
137 | static struct stv090x_config fe_cineS2 = { | ||
138 | .device = STV0900, | ||
139 | .demod_mode = STV090x_DUAL, | ||
140 | .clk_mode = STV090x_CLK_EXT, | ||
141 | |||
142 | .xtal = 27000000, | ||
143 | .address = 0x68, | ||
144 | |||
145 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
146 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
147 | |||
148 | .repeater_level = STV090x_RPTLEVEL_16, | ||
149 | |||
150 | .adc1_range = STV090x_ADC_1Vpp, | ||
151 | .adc2_range = STV090x_ADC_1Vpp, | ||
152 | |||
153 | .diseqc_envelope_mode = true, | ||
154 | }; | ||
155 | |||
156 | static struct stv6110x_config tuner_cineS2_0 = { | ||
157 | .addr = 0x60, | ||
158 | .refclk = 27000000, | ||
159 | .clk_div = 1, | ||
160 | }; | ||
161 | |||
162 | static struct stv6110x_config tuner_cineS2_1 = { | ||
163 | .addr = 0x63, | ||
164 | .refclk = 27000000, | ||
165 | .clk_div = 1, | ||
166 | }; | ||
167 | |||
168 | static struct ngene_info ngene_info_cineS2 = { | ||
169 | .type = NGENE_SIDEWINDER, | ||
170 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner", | ||
171 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
172 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
173 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
174 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
175 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
176 | .lnb = {0x0b, 0x08}, | ||
177 | .tsf = {3, 3}, | ||
178 | .fw_version = 15, | ||
179 | }; | ||
180 | |||
181 | static struct ngene_info ngene_info_satixS2 = { | ||
182 | .type = NGENE_SIDEWINDER, | ||
183 | .name = "Mystique SaTiX-S2 Dual", | ||
184 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
185 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
186 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
187 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
188 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
189 | .lnb = {0x0b, 0x08}, | ||
190 | .tsf = {3, 3}, | ||
191 | .fw_version = 15, | ||
192 | }; | ||
193 | |||
194 | static struct ngene_info ngene_info_satixS2v2 = { | ||
195 | .type = NGENE_SIDEWINDER, | ||
196 | .name = "Mystique SaTiX-S2 Dual (v2)", | ||
197 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
198 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
199 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
200 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
201 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
202 | .lnb = {0x0a, 0x08}, | ||
203 | .tsf = {3, 3}, | ||
204 | .fw_version = 15, | ||
205 | }; | ||
206 | |||
207 | static struct ngene_info ngene_info_cineS2v5 = { | ||
208 | .type = NGENE_SIDEWINDER, | ||
209 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", | ||
210 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
211 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
212 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
213 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
214 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
215 | .lnb = {0x0a, 0x08}, | ||
216 | .tsf = {3, 3}, | ||
217 | .fw_version = 15, | ||
218 | }; | ||
219 | |||
220 | static struct ngene_info ngene_info_m780 = { | ||
221 | .type = NGENE_APP, | ||
222 | .name = "Aver M780 ATSC/QAM-B", | ||
223 | |||
224 | /* Channel 0 is analog, which is currently unsupported */ | ||
225 | .io_type = { NGENE_IO_NONE, NGENE_IO_TSIN }, | ||
226 | .demod_attach = { NULL, demod_attach_lg330x }, | ||
227 | |||
228 | /* Ensure these are NULL else the frame will call them (as funcs) */ | ||
229 | .tuner_attach = { 0, 0, 0, 0 }, | ||
230 | .fe_config = { NULL, &aver_m780 }, | ||
231 | .avf = { 0 }, | ||
232 | |||
233 | /* A custom electrical interface config for the demod to bridge */ | ||
234 | .tsf = { 4, 4 }, | ||
235 | .fw_version = 15, | ||
236 | }; | ||
237 | |||
238 | /****************************************************************************/ | ||
239 | |||
240 | |||
241 | |||
242 | /****************************************************************************/ | ||
243 | /* PCI Subsystem ID *********************************************************/ | ||
244 | /****************************************************************************/ | ||
245 | |||
246 | #define NGENE_ID(_subvend, _subdev, _driverdata) { \ | ||
247 | .vendor = NGENE_VID, .device = NGENE_PID, \ | ||
248 | .subvendor = _subvend, .subdevice = _subdev, \ | ||
249 | .driver_data = (unsigned long) &_driverdata } | ||
250 | |||
251 | /****************************************************************************/ | ||
252 | |||
253 | static const struct pci_device_id ngene_id_tbl[] __devinitdata = { | ||
254 | NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), | ||
255 | NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), | ||
256 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), | ||
257 | NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), | ||
258 | NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), | ||
259 | NGENE_ID(0x1461, 0x062e, ngene_info_m780), | ||
260 | {0} | ||
261 | }; | ||
262 | MODULE_DEVICE_TABLE(pci, ngene_id_tbl); | ||
263 | |||
264 | /****************************************************************************/ | ||
265 | /* Init/Exit ****************************************************************/ | ||
266 | /****************************************************************************/ | ||
267 | |||
268 | static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, | ||
269 | enum pci_channel_state state) | ||
270 | { | ||
271 | printk(KERN_ERR DEVICE_NAME ": PCI error\n"); | ||
272 | if (state == pci_channel_io_perm_failure) | ||
273 | return PCI_ERS_RESULT_DISCONNECT; | ||
274 | if (state == pci_channel_io_frozen) | ||
275 | return PCI_ERS_RESULT_NEED_RESET; | ||
276 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
277 | } | ||
278 | |||
279 | static pci_ers_result_t ngene_link_reset(struct pci_dev *dev) | ||
280 | { | ||
281 | printk(KERN_INFO DEVICE_NAME ": link reset\n"); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) | ||
286 | { | ||
287 | printk(KERN_INFO DEVICE_NAME ": slot reset\n"); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static void ngene_resume(struct pci_dev *dev) | ||
292 | { | ||
293 | printk(KERN_INFO DEVICE_NAME ": resume\n"); | ||
294 | } | ||
295 | |||
296 | static struct pci_error_handlers ngene_errors = { | ||
297 | .error_detected = ngene_error_detected, | ||
298 | .link_reset = ngene_link_reset, | ||
299 | .slot_reset = ngene_slot_reset, | ||
300 | .resume = ngene_resume, | ||
301 | }; | ||
302 | |||
303 | static struct pci_driver ngene_pci_driver = { | ||
304 | .name = "ngene", | ||
305 | .id_table = ngene_id_tbl, | ||
306 | .probe = ngene_probe, | ||
307 | .remove = __devexit_p(ngene_remove), | ||
308 | .err_handler = &ngene_errors, | ||
309 | }; | ||
310 | |||
311 | static __init int module_init_ngene(void) | ||
312 | { | ||
313 | printk(KERN_INFO | ||
314 | "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n"); | ||
315 | return pci_register_driver(&ngene_pci_driver); | ||
316 | } | ||
317 | |||
318 | static __exit void module_exit_ngene(void) | ||
319 | { | ||
320 | pci_unregister_driver(&ngene_pci_driver); | ||
321 | } | ||
322 | |||
323 | module_init(module_init_ngene); | ||
324 | module_exit(module_exit_ngene); | ||
325 | |||
326 | MODULE_DESCRIPTION("nGene"); | ||
327 | MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel"); | ||
328 | MODULE_LICENSE("GPL"); | ||