diff options
Diffstat (limited to 'drivers/media/dvb/ngene')
-rw-r--r-- | drivers/media/dvb/ngene/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-cards.c | 179 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 250 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-dvb.c | 72 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 24 |
6 files changed, 430 insertions, 100 deletions
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile index 0608aabb14ee..2bc96874d044 100644 --- a/drivers/media/dvb/ngene/Makefile +++ b/drivers/media/dvb/ngene/Makefile | |||
@@ -9,3 +9,6 @@ obj-$(CONFIG_DVB_NGENE) += ngene.o | |||
9 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ | 9 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ |
10 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ | 10 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ |
11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners/ | 11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners/ |
12 | |||
13 | # For the staging CI driver cxd2099 | ||
14 | EXTRA_CFLAGS += -Idrivers/staging/cxd2099/ | ||
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) |
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 4caeb163a666..6927c726ce35 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <asm/div64.h> | 35 | #include <asm/div64.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
39 | #include <linux/byteorder/generic.h> | 38 | #include <linux/byteorder/generic.h> |
40 | #include <linux/firmware.h> | 39 | #include <linux/firmware.h> |
@@ -46,6 +45,9 @@ static int one_adapter = 1; | |||
46 | module_param(one_adapter, int, 0444); | 45 | module_param(one_adapter, int, 0444); |
47 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); | 46 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); |
48 | 47 | ||
48 | static int shutdown_workaround; | ||
49 | module_param(shutdown_workaround, int, 0644); | ||
50 | MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets."); | ||
49 | 51 | ||
50 | static int debug; | 52 | static int debug; |
51 | module_param(debug, int, 0444); | 53 | module_param(debug, int, 0444); |
@@ -120,7 +122,7 @@ static void demux_tasklet(unsigned long data) | |||
120 | Cur->ngeneBuffer.SR.Flags &= | 122 | Cur->ngeneBuffer.SR.Flags &= |
121 | ~0x40; | 123 | ~0x40; |
122 | break; | 124 | break; |
123 | /* Stop proccessing stream */ | 125 | /* Stop processing stream */ |
124 | } | 126 | } |
125 | } else { | 127 | } else { |
126 | /* We got a valid buffer, | 128 | /* We got a valid buffer, |
@@ -131,7 +133,7 @@ static void demux_tasklet(unsigned long data) | |||
131 | printk(KERN_ERR DEVICE_NAME ": OOPS\n"); | 133 | printk(KERN_ERR DEVICE_NAME ": OOPS\n"); |
132 | if (chan->HWState == HWSTATE_RUN) { | 134 | if (chan->HWState == HWSTATE_RUN) { |
133 | Cur->ngeneBuffer.SR.Flags &= ~0x40; | 135 | Cur->ngeneBuffer.SR.Flags &= ~0x40; |
134 | break; /* Stop proccessing stream */ | 136 | break; /* Stop processing stream */ |
135 | } | 137 | } |
136 | } | 138 | } |
137 | if (chan->AudioDTOUpdated) { | 139 | if (chan->AudioDTOUpdated) { |
@@ -144,7 +146,7 @@ static void demux_tasklet(unsigned long data) | |||
144 | } | 146 | } |
145 | } else { | 147 | } else { |
146 | if (chan->HWState == HWSTATE_RUN) { | 148 | if (chan->HWState == HWSTATE_RUN) { |
147 | u32 Flags = 0; | 149 | u32 Flags = chan->DataFormatFlags; |
148 | IBufferExchange *exch1 = chan->pBufferExchange; | 150 | IBufferExchange *exch1 = chan->pBufferExchange; |
149 | IBufferExchange *exch2 = chan->pBufferExchange2; | 151 | IBufferExchange *exch2 = chan->pBufferExchange2; |
150 | if (Cur->ngeneBuffer.SR.Flags & 0x01) | 152 | if (Cur->ngeneBuffer.SR.Flags & 0x01) |
@@ -475,9 +477,9 @@ static u8 SPDIFConfiguration[10] = { | |||
475 | 477 | ||
476 | /* Set NGENE I2S Config to transport stream compatible mode */ | 478 | /* Set NGENE I2S Config to transport stream compatible mode */ |
477 | 479 | ||
478 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/ | 480 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 }; |
479 | 481 | ||
480 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 }; | 482 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 }; |
481 | 483 | ||
482 | static u8 ITUDecoderSetup[4][16] = { | 484 | static u8 ITUDecoderSetup[4][16] = { |
483 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ | 485 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ |
@@ -750,13 +752,11 @@ void set_transfer(struct ngene_channel *chan, int state) | |||
750 | if (chan->mode & NGENE_IO_TSOUT) { | 752 | if (chan->mode & NGENE_IO_TSOUT) { |
751 | chan->pBufferExchange = tsout_exchange; | 753 | chan->pBufferExchange = tsout_exchange; |
752 | /* 0x66666666 = 50MHz *2^33 /250MHz */ | 754 | /* 0x66666666 = 50MHz *2^33 /250MHz */ |
753 | chan->AudioDTOValue = 0x66666666; | 755 | chan->AudioDTOValue = 0x80000000; |
754 | /* set_dto(chan, 38810700+1000); */ | 756 | chan->AudioDTOUpdated = 1; |
755 | /* set_dto(chan, 19392658); */ | ||
756 | } | 757 | } |
757 | if (chan->mode & NGENE_IO_TSIN) | 758 | if (chan->mode & NGENE_IO_TSIN) |
758 | chan->pBufferExchange = tsin_exchange; | 759 | chan->pBufferExchange = tsin_exchange; |
759 | /* ngwritel(0, 0x9310); */ | ||
760 | spin_unlock_irq(&chan->state_lock); | 760 | spin_unlock_irq(&chan->state_lock); |
761 | } else | 761 | } else |
762 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | 762 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", |
@@ -1169,6 +1169,7 @@ static void ngene_release_buffers(struct ngene *dev) | |||
1169 | iounmap(dev->iomem); | 1169 | iounmap(dev->iomem); |
1170 | free_common_buffers(dev); | 1170 | free_common_buffers(dev); |
1171 | vfree(dev->tsout_buf); | 1171 | vfree(dev->tsout_buf); |
1172 | vfree(dev->tsin_buf); | ||
1172 | vfree(dev->ain_buf); | 1173 | vfree(dev->ain_buf); |
1173 | vfree(dev->vin_buf); | 1174 | vfree(dev->vin_buf); |
1174 | vfree(dev); | 1175 | vfree(dev); |
@@ -1185,6 +1186,13 @@ static int ngene_get_buffers(struct ngene *dev) | |||
1185 | dvb_ringbuffer_init(&dev->tsout_rbuf, | 1186 | dvb_ringbuffer_init(&dev->tsout_rbuf, |
1186 | dev->tsout_buf, TSOUT_BUF_SIZE); | 1187 | dev->tsout_buf, TSOUT_BUF_SIZE); |
1187 | } | 1188 | } |
1189 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN) { | ||
1190 | dev->tsin_buf = vmalloc(TSIN_BUF_SIZE); | ||
1191 | if (!dev->tsin_buf) | ||
1192 | return -ENOMEM; | ||
1193 | dvb_ringbuffer_init(&dev->tsin_rbuf, | ||
1194 | dev->tsin_buf, TSIN_BUF_SIZE); | ||
1195 | } | ||
1188 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { | 1196 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { |
1189 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); | 1197 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); |
1190 | if (!dev->ain_buf) | 1198 | if (!dev->ain_buf) |
@@ -1258,6 +1266,10 @@ static int ngene_load_firm(struct ngene *dev) | |||
1258 | fw_name = "ngene_17.fw"; | 1266 | fw_name = "ngene_17.fw"; |
1259 | dev->cmd_timeout_workaround = true; | 1267 | dev->cmd_timeout_workaround = true; |
1260 | break; | 1268 | break; |
1269 | case 18: | ||
1270 | size = 0; | ||
1271 | fw_name = "ngene_18.fw"; | ||
1272 | break; | ||
1261 | } | 1273 | } |
1262 | 1274 | ||
1263 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { | 1275 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { |
@@ -1267,6 +1279,8 @@ static int ngene_load_firm(struct ngene *dev) | |||
1267 | ": Copy %s to your hotplug directory!\n", fw_name); | 1279 | ": Copy %s to your hotplug directory!\n", fw_name); |
1268 | return -1; | 1280 | return -1; |
1269 | } | 1281 | } |
1282 | if (size == 0) | ||
1283 | size = fw->size; | ||
1270 | if (size != fw->size) { | 1284 | if (size != fw->size) { |
1271 | printk(KERN_ERR DEVICE_NAME | 1285 | printk(KERN_ERR DEVICE_NAME |
1272 | ": Firmware %s has invalid size!", fw_name); | 1286 | ": Firmware %s has invalid size!", fw_name); |
@@ -1302,10 +1316,38 @@ static void ngene_stop(struct ngene *dev) | |||
1302 | #endif | 1316 | #endif |
1303 | } | 1317 | } |
1304 | 1318 | ||
1319 | static int ngene_buffer_config(struct ngene *dev) | ||
1320 | { | ||
1321 | int stat; | ||
1322 | |||
1323 | if (dev->card_info->fw_version >= 17) { | ||
1324 | u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }; | ||
1325 | u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 }; | ||
1326 | u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 }; | ||
1327 | u8 *bconf = tsin12_config; | ||
1328 | |||
1329 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN && | ||
1330 | dev->card_info->io_type[3]&NGENE_IO_TSIN) { | ||
1331 | bconf = tsin1234_config; | ||
1332 | if (dev->card_info->io_type[4]&NGENE_IO_TSOUT && | ||
1333 | dev->ci.en) | ||
1334 | bconf = tsio1235_config; | ||
1335 | } | ||
1336 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1337 | } else { | ||
1338 | int bconf = BUFFER_CONFIG_4422; | ||
1339 | |||
1340 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1341 | bconf = BUFFER_CONFIG_3333; | ||
1342 | stat = ngene_command_config_buf(dev, bconf); | ||
1343 | } | ||
1344 | return stat; | ||
1345 | } | ||
1346 | |||
1347 | |||
1305 | static int ngene_start(struct ngene *dev) | 1348 | static int ngene_start(struct ngene *dev) |
1306 | { | 1349 | { |
1307 | int stat; | 1350 | int stat; |
1308 | unsigned long flags; | ||
1309 | int i; | 1351 | int i; |
1310 | 1352 | ||
1311 | pci_set_master(dev->pci_dev); | 1353 | pci_set_master(dev->pci_dev); |
@@ -1338,6 +1380,8 @@ static int ngene_start(struct ngene *dev) | |||
1338 | #ifdef CONFIG_PCI_MSI | 1380 | #ifdef CONFIG_PCI_MSI |
1339 | /* enable MSI if kernel and card support it */ | 1381 | /* enable MSI if kernel and card support it */ |
1340 | if (pci_msi_enabled() && dev->card_info->msi_supported) { | 1382 | if (pci_msi_enabled() && dev->card_info->msi_supported) { |
1383 | unsigned long flags; | ||
1384 | |||
1341 | ngwritel(0, NGENE_INT_ENABLE); | 1385 | ngwritel(0, NGENE_INT_ENABLE); |
1342 | free_irq(dev->pci_dev->irq, dev); | 1386 | free_irq(dev->pci_dev->irq, dev); |
1343 | stat = pci_enable_msi(dev->pci_dev); | 1387 | stat = pci_enable_msi(dev->pci_dev); |
@@ -1365,23 +1409,6 @@ static int ngene_start(struct ngene *dev) | |||
1365 | if (stat < 0) | 1409 | if (stat < 0) |
1366 | goto fail; | 1410 | goto fail; |
1367 | 1411 | ||
1368 | if (dev->card_info->fw_version == 17) { | ||
1369 | u8 tsin4_config[6] = { | ||
1370 | 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0}; | ||
1371 | u8 default_config[6] = { | ||
1372 | 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0}; | ||
1373 | u8 *bconf = default_config; | ||
1374 | |||
1375 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1376 | bconf = tsin4_config; | ||
1377 | dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n"); | ||
1378 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1379 | } else { | ||
1380 | int bconf = BUFFER_CONFIG_4422; | ||
1381 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1382 | bconf = BUFFER_CONFIG_3333; | ||
1383 | stat = ngene_command_config_buf(dev, bconf); | ||
1384 | } | ||
1385 | if (!stat) | 1412 | if (!stat) |
1386 | return stat; | 1413 | return stat; |
1387 | 1414 | ||
@@ -1397,9 +1424,6 @@ fail2: | |||
1397 | return stat; | 1424 | return stat; |
1398 | } | 1425 | } |
1399 | 1426 | ||
1400 | |||
1401 | |||
1402 | |||
1403 | /****************************************************************************/ | 1427 | /****************************************************************************/ |
1404 | /****************************************************************************/ | 1428 | /****************************************************************************/ |
1405 | /****************************************************************************/ | 1429 | /****************************************************************************/ |
@@ -1408,20 +1432,25 @@ static void release_channel(struct ngene_channel *chan) | |||
1408 | { | 1432 | { |
1409 | struct dvb_demux *dvbdemux = &chan->demux; | 1433 | struct dvb_demux *dvbdemux = &chan->demux; |
1410 | struct ngene *dev = chan->dev; | 1434 | struct ngene *dev = chan->dev; |
1411 | struct ngene_info *ni = dev->card_info; | ||
1412 | int io = ni->io_type[chan->number]; | ||
1413 | 1435 | ||
1414 | if (chan->dev->cmd_timeout_workaround && chan->running) | 1436 | if (chan->running) |
1415 | set_transfer(chan, 0); | 1437 | set_transfer(chan, 0); |
1416 | 1438 | ||
1417 | tasklet_kill(&chan->demux_tasklet); | 1439 | tasklet_kill(&chan->demux_tasklet); |
1418 | 1440 | ||
1419 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1441 | if (chan->ci_dev) { |
1420 | if (chan->fe) { | 1442 | dvb_unregister_device(chan->ci_dev); |
1421 | dvb_unregister_frontend(chan->fe); | 1443 | chan->ci_dev = NULL; |
1422 | dvb_frontend_detach(chan->fe); | 1444 | } |
1423 | chan->fe = NULL; | 1445 | |
1424 | } | 1446 | if (chan->fe) { |
1447 | dvb_unregister_frontend(chan->fe); | ||
1448 | dvb_frontend_detach(chan->fe); | ||
1449 | chan->fe = NULL; | ||
1450 | } | ||
1451 | |||
1452 | if (chan->has_demux) { | ||
1453 | dvb_net_release(&chan->dvbnet); | ||
1425 | dvbdemux->dmx.close(&dvbdemux->dmx); | 1454 | dvbdemux->dmx.close(&dvbdemux->dmx); |
1426 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | 1455 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, |
1427 | &chan->hw_frontend); | 1456 | &chan->hw_frontend); |
@@ -1429,9 +1458,12 @@ static void release_channel(struct ngene_channel *chan) | |||
1429 | &chan->mem_frontend); | 1458 | &chan->mem_frontend); |
1430 | dvb_dmxdev_release(&chan->dmxdev); | 1459 | dvb_dmxdev_release(&chan->dmxdev); |
1431 | dvb_dmx_release(&chan->demux); | 1460 | dvb_dmx_release(&chan->demux); |
1461 | chan->has_demux = false; | ||
1462 | } | ||
1432 | 1463 | ||
1433 | if (chan->number == 0 || !one_adapter) | 1464 | if (chan->has_adapter) { |
1434 | dvb_unregister_adapter(&dev->adapter[chan->number]); | 1465 | dvb_unregister_adapter(&dev->adapter[chan->number]); |
1466 | chan->has_adapter = false; | ||
1435 | } | 1467 | } |
1436 | } | 1468 | } |
1437 | 1469 | ||
@@ -1449,9 +1481,27 @@ static int init_channel(struct ngene_channel *chan) | |||
1449 | chan->type = io; | 1481 | chan->type = io; |
1450 | chan->mode = chan->type; /* for now only one mode */ | 1482 | chan->mode = chan->type; /* for now only one mode */ |
1451 | 1483 | ||
1484 | if (io & NGENE_IO_TSIN) { | ||
1485 | chan->fe = NULL; | ||
1486 | if (ni->demod_attach[nr]) { | ||
1487 | ret = ni->demod_attach[nr](chan); | ||
1488 | if (ret < 0) | ||
1489 | goto err; | ||
1490 | } | ||
1491 | if (chan->fe && ni->tuner_attach[nr]) { | ||
1492 | ret = ni->tuner_attach[nr](chan); | ||
1493 | if (ret < 0) | ||
1494 | goto err; | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | if (!dev->ci.en && (io & NGENE_IO_TSOUT)) | ||
1499 | return 0; | ||
1500 | |||
1452 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1501 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
1453 | if (nr >= STREAM_AUDIOIN1) | 1502 | if (nr >= STREAM_AUDIOIN1) |
1454 | chan->DataFormatFlags = DF_SWAP32; | 1503 | chan->DataFormatFlags = DF_SWAP32; |
1504 | |||
1455 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { | 1505 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { |
1456 | adapter = &dev->adapter[nr]; | 1506 | adapter = &dev->adapter[nr]; |
1457 | ret = dvb_register_adapter(adapter, "nGene", | 1507 | ret = dvb_register_adapter(adapter, "nGene", |
@@ -1459,40 +1509,51 @@ static int init_channel(struct ngene_channel *chan) | |||
1459 | &chan->dev->pci_dev->dev, | 1509 | &chan->dev->pci_dev->dev, |
1460 | adapter_nr); | 1510 | adapter_nr); |
1461 | if (ret < 0) | 1511 | if (ret < 0) |
1462 | return ret; | 1512 | goto err; |
1463 | if (dev->first_adapter == NULL) | 1513 | if (dev->first_adapter == NULL) |
1464 | dev->first_adapter = adapter; | 1514 | dev->first_adapter = adapter; |
1465 | } else { | 1515 | chan->has_adapter = true; |
1516 | } else | ||
1466 | adapter = dev->first_adapter; | 1517 | adapter = dev->first_adapter; |
1467 | } | 1518 | } |
1519 | |||
1520 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { | ||
1521 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | ||
1522 | set_transfer(chan, 1); | ||
1523 | chan->dev->channel[2].DataFormatFlags = DF_SWAP32; | ||
1524 | set_transfer(&chan->dev->channel[2], 1); | ||
1525 | dvb_register_device(adapter, &chan->ci_dev, | ||
1526 | &ngene_dvbdev_ci, (void *) chan, | ||
1527 | DVB_DEVICE_SEC); | ||
1528 | if (!chan->ci_dev) | ||
1529 | goto err; | ||
1530 | } | ||
1468 | 1531 | ||
1532 | if (chan->fe) { | ||
1533 | if (dvb_register_frontend(adapter, chan->fe) < 0) | ||
1534 | goto err; | ||
1535 | chan->has_demux = true; | ||
1536 | } | ||
1537 | |||
1538 | if (chan->has_demux) { | ||
1469 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", | 1539 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", |
1470 | ngene_start_feed, | 1540 | ngene_start_feed, |
1471 | ngene_stop_feed, chan); | 1541 | ngene_stop_feed, chan); |
1472 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, | 1542 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, |
1473 | &chan->hw_frontend, | 1543 | &chan->hw_frontend, |
1474 | &chan->mem_frontend, adapter); | 1544 | &chan->mem_frontend, adapter); |
1545 | ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx); | ||
1475 | } | 1546 | } |
1476 | 1547 | ||
1477 | if (io & NGENE_IO_TSIN) { | 1548 | return ret; |
1549 | |||
1550 | err: | ||
1551 | if (chan->fe) { | ||
1552 | dvb_frontend_detach(chan->fe); | ||
1478 | chan->fe = NULL; | 1553 | chan->fe = NULL; |
1479 | if (ni->demod_attach[nr]) | ||
1480 | ni->demod_attach[nr](chan); | ||
1481 | if (chan->fe) { | ||
1482 | if (dvb_register_frontend(adapter, chan->fe) < 0) { | ||
1483 | if (chan->fe->ops.release) | ||
1484 | chan->fe->ops.release(chan->fe); | ||
1485 | chan->fe = NULL; | ||
1486 | } | ||
1487 | } | ||
1488 | if (chan->fe && ni->tuner_attach[nr]) | ||
1489 | if (ni->tuner_attach[nr] (chan) < 0) { | ||
1490 | printk(KERN_ERR DEVICE_NAME | ||
1491 | ": Tuner attach failed on channel %d!\n", | ||
1492 | nr); | ||
1493 | } | ||
1494 | } | 1554 | } |
1495 | return ret; | 1555 | release_channel(chan); |
1556 | return 0; | ||
1496 | } | 1557 | } |
1497 | 1558 | ||
1498 | static int init_channels(struct ngene *dev) | 1559 | static int init_channels(struct ngene *dev) |
@@ -1510,18 +1571,71 @@ static int init_channels(struct ngene *dev) | |||
1510 | return 0; | 1571 | return 0; |
1511 | } | 1572 | } |
1512 | 1573 | ||
1574 | static void cxd_attach(struct ngene *dev) | ||
1575 | { | ||
1576 | struct ngene_ci *ci = &dev->ci; | ||
1577 | |||
1578 | ci->en = cxd2099_attach(0x40, dev, &dev->channel[0].i2c_adapter); | ||
1579 | ci->dev = dev; | ||
1580 | return; | ||
1581 | } | ||
1582 | |||
1583 | static void cxd_detach(struct ngene *dev) | ||
1584 | { | ||
1585 | struct ngene_ci *ci = &dev->ci; | ||
1586 | |||
1587 | dvb_ca_en50221_release(ci->en); | ||
1588 | kfree(ci->en); | ||
1589 | ci->en = 0; | ||
1590 | } | ||
1591 | |||
1592 | /***********************************/ | ||
1593 | /* workaround for shutdown failure */ | ||
1594 | /***********************************/ | ||
1595 | |||
1596 | static void ngene_unlink(struct ngene *dev) | ||
1597 | { | ||
1598 | struct ngene_command com; | ||
1599 | |||
1600 | com.cmd.hdr.Opcode = CMD_MEM_WRITE; | ||
1601 | com.cmd.hdr.Length = 3; | ||
1602 | com.cmd.MemoryWrite.address = 0x910c; | ||
1603 | com.cmd.MemoryWrite.data = 0xff; | ||
1604 | com.in_len = 3; | ||
1605 | com.out_len = 1; | ||
1606 | |||
1607 | down(&dev->cmd_mutex); | ||
1608 | ngwritel(0, NGENE_INT_ENABLE); | ||
1609 | ngene_command_mutex(dev, &com); | ||
1610 | up(&dev->cmd_mutex); | ||
1611 | } | ||
1612 | |||
1613 | void ngene_shutdown(struct pci_dev *pdev) | ||
1614 | { | ||
1615 | struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); | ||
1616 | |||
1617 | if (!dev || !shutdown_workaround) | ||
1618 | return; | ||
1619 | |||
1620 | printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n"); | ||
1621 | ngene_unlink(dev); | ||
1622 | pci_disable_device(pdev); | ||
1623 | } | ||
1624 | |||
1513 | /****************************************************************************/ | 1625 | /****************************************************************************/ |
1514 | /* device probe/remove calls ************************************************/ | 1626 | /* device probe/remove calls ************************************************/ |
1515 | /****************************************************************************/ | 1627 | /****************************************************************************/ |
1516 | 1628 | ||
1517 | void __devexit ngene_remove(struct pci_dev *pdev) | 1629 | void __devexit ngene_remove(struct pci_dev *pdev) |
1518 | { | 1630 | { |
1519 | struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); | 1631 | struct ngene *dev = pci_get_drvdata(pdev); |
1520 | int i; | 1632 | int i; |
1521 | 1633 | ||
1522 | tasklet_kill(&dev->event_tasklet); | 1634 | tasklet_kill(&dev->event_tasklet); |
1523 | for (i = MAX_STREAM - 1; i >= 0; i--) | 1635 | for (i = MAX_STREAM - 1; i >= 0; i--) |
1524 | release_channel(&dev->channel[i]); | 1636 | release_channel(&dev->channel[i]); |
1637 | if (dev->ci.en) | ||
1638 | cxd_detach(dev); | ||
1525 | ngene_stop(dev); | 1639 | ngene_stop(dev); |
1526 | ngene_release_buffers(dev); | 1640 | ngene_release_buffers(dev); |
1527 | pci_set_drvdata(pdev, NULL); | 1641 | pci_set_drvdata(pdev, NULL); |
@@ -1537,12 +1651,11 @@ int __devinit ngene_probe(struct pci_dev *pci_dev, | |||
1537 | if (pci_enable_device(pci_dev) < 0) | 1651 | if (pci_enable_device(pci_dev) < 0) |
1538 | return -ENODEV; | 1652 | return -ENODEV; |
1539 | 1653 | ||
1540 | dev = vmalloc(sizeof(struct ngene)); | 1654 | dev = vzalloc(sizeof(struct ngene)); |
1541 | if (dev == NULL) { | 1655 | if (dev == NULL) { |
1542 | stat = -ENOMEM; | 1656 | stat = -ENOMEM; |
1543 | goto fail0; | 1657 | goto fail0; |
1544 | } | 1658 | } |
1545 | memset(dev, 0, sizeof(struct ngene)); | ||
1546 | 1659 | ||
1547 | dev->pci_dev = pci_dev; | 1660 | dev->pci_dev = pci_dev; |
1548 | dev->card_info = (struct ngene_info *)id->driver_data; | 1661 | dev->card_info = (struct ngene_info *)id->driver_data; |
@@ -1558,6 +1671,13 @@ int __devinit ngene_probe(struct pci_dev *pci_dev, | |||
1558 | if (stat < 0) | 1671 | if (stat < 0) |
1559 | goto fail1; | 1672 | goto fail1; |
1560 | 1673 | ||
1674 | cxd_attach(dev); | ||
1675 | |||
1676 | stat = ngene_buffer_config(dev); | ||
1677 | if (stat < 0) | ||
1678 | goto fail1; | ||
1679 | |||
1680 | |||
1561 | dev->i2c_current_bus = -1; | 1681 | dev->i2c_current_bus = -1; |
1562 | 1682 | ||
1563 | /* Register DVB adapters and devices for both channels */ | 1683 | /* Register DVB adapters and devices for both channels */ |
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 48f980b21d66..0b4943233166 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
36 | #include <asm/div64.h> | 36 | #include <asm/div64.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/timer.h> | 38 | #include <linux/timer.h> |
40 | #include <linux/byteorder/generic.h> | 39 | #include <linux/byteorder/generic.h> |
41 | #include <linux/firmware.h> | 40 | #include <linux/firmware.h> |
@@ -48,6 +47,64 @@ | |||
48 | /* COMMAND API interface ****************************************************/ | 47 | /* COMMAND API interface ****************************************************/ |
49 | /****************************************************************************/ | 48 | /****************************************************************************/ |
50 | 49 | ||
50 | static ssize_t ts_write(struct file *file, const char *buf, | ||
51 | size_t count, loff_t *ppos) | ||
52 | { | ||
53 | struct dvb_device *dvbdev = file->private_data; | ||
54 | struct ngene_channel *chan = dvbdev->priv; | ||
55 | struct ngene *dev = chan->dev; | ||
56 | |||
57 | if (wait_event_interruptible(dev->tsout_rbuf.queue, | ||
58 | dvb_ringbuffer_free | ||
59 | (&dev->tsout_rbuf) >= count) < 0) | ||
60 | return 0; | ||
61 | |||
62 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); | ||
63 | |||
64 | return count; | ||
65 | } | ||
66 | |||
67 | static ssize_t ts_read(struct file *file, char *buf, | ||
68 | size_t count, loff_t *ppos) | ||
69 | { | ||
70 | struct dvb_device *dvbdev = file->private_data; | ||
71 | struct ngene_channel *chan = dvbdev->priv; | ||
72 | struct ngene *dev = chan->dev; | ||
73 | int left, avail; | ||
74 | |||
75 | left = count; | ||
76 | while (left) { | ||
77 | if (wait_event_interruptible( | ||
78 | dev->tsin_rbuf.queue, | ||
79 | dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0) | ||
80 | return -EAGAIN; | ||
81 | avail = dvb_ringbuffer_avail(&dev->tsin_rbuf); | ||
82 | if (avail > left) | ||
83 | avail = left; | ||
84 | dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail); | ||
85 | left -= avail; | ||
86 | buf += avail; | ||
87 | } | ||
88 | return count; | ||
89 | } | ||
90 | |||
91 | static const struct file_operations ci_fops = { | ||
92 | .owner = THIS_MODULE, | ||
93 | .read = ts_read, | ||
94 | .write = ts_write, | ||
95 | .open = dvb_generic_open, | ||
96 | .release = dvb_generic_release, | ||
97 | }; | ||
98 | |||
99 | struct dvb_device ngene_dvbdev_ci = { | ||
100 | .priv = 0, | ||
101 | .readers = -1, | ||
102 | .writers = -1, | ||
103 | .users = -1, | ||
104 | .fops = &ci_fops, | ||
105 | }; | ||
106 | |||
107 | |||
51 | /****************************************************************************/ | 108 | /****************************************************************************/ |
52 | /* DVB functions and API interface ******************************************/ | 109 | /* DVB functions and API interface ******************************************/ |
53 | /****************************************************************************/ | 110 | /****************************************************************************/ |
@@ -64,10 +121,21 @@ static void swap_buffer(u32 *p, u32 len) | |||
64 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | 121 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) |
65 | { | 122 | { |
66 | struct ngene_channel *chan = priv; | 123 | struct ngene_channel *chan = priv; |
124 | struct ngene *dev = chan->dev; | ||
67 | 125 | ||
68 | 126 | ||
69 | if (chan->users > 0) | 127 | if (flags & DF_SWAP32) |
128 | swap_buffer(buf, len); | ||
129 | if (dev->ci.en && chan->number == 2) { | ||
130 | if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { | ||
131 | dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len); | ||
132 | wake_up_interruptible(&dev->tsin_rbuf.queue); | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | if (chan->users > 0) { | ||
70 | dvb_dmx_swfilter(&chan->demux, buf, len); | 137 | dvb_dmx_swfilter(&chan->demux, buf, len); |
138 | } | ||
71 | return NULL; | 139 | return NULL; |
72 | } | 140 | } |
73 | 141 | ||
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c index 477fe0aade86..d28554f8ce99 100644 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ b/drivers/media/dvb/ngene/ngene-i2c.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/div64.h> | 37 | #include <asm/div64.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/pci_ids.h> | 39 | #include <linux/pci_ids.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/timer.h> | 40 | #include <linux/timer.h> |
42 | #include <linux/byteorder/generic.h> | 41 | #include <linux/byteorder/generic.h> |
43 | #include <linux/firmware.h> | 42 | #include <linux/firmware.h> |
@@ -165,7 +164,6 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr) | |||
165 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); | 164 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); |
166 | 165 | ||
167 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); | 166 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); |
168 | adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG; | ||
169 | 167 | ||
170 | strcpy(adap->name, "nGene"); | 168 | strcpy(adap->name, "nGene"); |
171 | 169 | ||
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 8fb4200f83f8..40fce9e3ae66 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h | |||
@@ -36,8 +36,11 @@ | |||
36 | #include "dmxdev.h" | 36 | #include "dmxdev.h" |
37 | #include "dvbdev.h" | 37 | #include "dvbdev.h" |
38 | #include "dvb_demux.h" | 38 | #include "dvb_demux.h" |
39 | #include "dvb_ca_en50221.h" | ||
39 | #include "dvb_frontend.h" | 40 | #include "dvb_frontend.h" |
40 | #include "dvb_ringbuffer.h" | 41 | #include "dvb_ringbuffer.h" |
42 | #include "dvb_net.h" | ||
43 | #include "cxd2099.h" | ||
41 | 44 | ||
42 | #define DEVICE_NAME "ngene" | 45 | #define DEVICE_NAME "ngene" |
43 | 46 | ||
@@ -636,14 +639,18 @@ struct ngene_channel { | |||
636 | int number; | 639 | int number; |
637 | int type; | 640 | int type; |
638 | int mode; | 641 | int mode; |
642 | bool has_adapter; | ||
643 | bool has_demux; | ||
639 | 644 | ||
640 | struct dvb_frontend *fe; | 645 | struct dvb_frontend *fe; |
641 | struct dmxdev dmxdev; | 646 | struct dmxdev dmxdev; |
642 | struct dvb_demux demux; | 647 | struct dvb_demux demux; |
648 | struct dvb_net dvbnet; | ||
643 | struct dmx_frontend hw_frontend; | 649 | struct dmx_frontend hw_frontend; |
644 | struct dmx_frontend mem_frontend; | 650 | struct dmx_frontend mem_frontend; |
645 | int users; | 651 | int users; |
646 | struct video_device *v4l_dev; | 652 | struct video_device *v4l_dev; |
653 | struct dvb_device *ci_dev; | ||
647 | struct tasklet_struct demux_tasklet; | 654 | struct tasklet_struct demux_tasklet; |
648 | 655 | ||
649 | struct SBufferHeader *nextBuffer; | 656 | struct SBufferHeader *nextBuffer; |
@@ -710,6 +717,15 @@ struct ngene_channel { | |||
710 | int running; | 717 | int running; |
711 | }; | 718 | }; |
712 | 719 | ||
720 | |||
721 | struct ngene_ci { | ||
722 | struct device device; | ||
723 | struct i2c_adapter i2c_adapter; | ||
724 | |||
725 | struct ngene *dev; | ||
726 | struct dvb_ca_en50221 *en; | ||
727 | }; | ||
728 | |||
713 | struct ngene; | 729 | struct ngene; |
714 | 730 | ||
715 | typedef void (rx_cb_t)(struct ngene *, u32, u8); | 731 | typedef void (rx_cb_t)(struct ngene *, u32, u8); |
@@ -774,6 +790,10 @@ struct ngene { | |||
774 | #define TSOUT_BUF_SIZE (512*188*8) | 790 | #define TSOUT_BUF_SIZE (512*188*8) |
775 | struct dvb_ringbuffer tsout_rbuf; | 791 | struct dvb_ringbuffer tsout_rbuf; |
776 | 792 | ||
793 | u8 *tsin_buf; | ||
794 | #define TSIN_BUF_SIZE (512*188*8) | ||
795 | struct dvb_ringbuffer tsin_rbuf; | ||
796 | |||
777 | u8 *ain_buf; | 797 | u8 *ain_buf; |
778 | #define AIN_BUF_SIZE (128*1024) | 798 | #define AIN_BUF_SIZE (128*1024) |
779 | struct dvb_ringbuffer ain_rbuf; | 799 | struct dvb_ringbuffer ain_rbuf; |
@@ -785,6 +805,8 @@ struct ngene { | |||
785 | 805 | ||
786 | unsigned long exp_val; | 806 | unsigned long exp_val; |
787 | int prev_cmd; | 807 | int prev_cmd; |
808 | |||
809 | struct ngene_ci ci; | ||
788 | }; | 810 | }; |
789 | 811 | ||
790 | struct ngene_info { | 812 | struct ngene_info { |
@@ -863,6 +885,7 @@ struct ngene_buffer { | |||
863 | int __devinit ngene_probe(struct pci_dev *pci_dev, | 885 | int __devinit ngene_probe(struct pci_dev *pci_dev, |
864 | const struct pci_device_id *id); | 886 | const struct pci_device_id *id); |
865 | void __devexit ngene_remove(struct pci_dev *pdev); | 887 | void __devexit ngene_remove(struct pci_dev *pdev); |
888 | void ngene_shutdown(struct pci_dev *pdev); | ||
866 | int ngene_command(struct ngene *dev, struct ngene_command *com); | 889 | int ngene_command(struct ngene *dev, struct ngene_command *com); |
867 | int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); | 890 | int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); |
868 | void set_transfer(struct ngene_channel *chan, int state); | 891 | void set_transfer(struct ngene_channel *chan, int state); |
@@ -872,6 +895,7 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags); | |||
872 | int ngene_i2c_init(struct ngene *dev, int dev_nr); | 895 | int ngene_i2c_init(struct ngene *dev, int dev_nr); |
873 | 896 | ||
874 | /* Provided by ngene-dvb.c */ | 897 | /* Provided by ngene-dvb.c */ |
898 | extern struct dvb_device ngene_dvbdev_ci; | ||
875 | void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); | 899 | void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); |
876 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); | 900 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); |
877 | int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed); | 901 | int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed); |