Commit | Line | Data |
---|---|---|
c79b339f | 1 | /* |
12042b05 | 2 | * DVB USB framework |
c79b339f | 3 | * |
12042b05 AP |
4 | * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de> |
5 | * Copyright (C) 2012 Antti Palosaari <crope@iki.fi> | |
c79b339f | 6 | * |
12042b05 AP |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
c79b339f | 11 | * |
12042b05 AP |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
c79b339f | 16 | * |
12042b05 AP |
17 | * You should have received a copy of the GNU General Public License along |
18 | * with this program; if not, write to the Free Software Foundation, Inc., | |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
c79b339f | 20 | */ |
12042b05 | 21 | |
c79b339f AP |
22 | #include "dvb_usb_common.h" |
23 | ||
68126673 | 24 | static int dvb_usbv2_disable_rc_polling; |
59784343 | 25 | module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644); |
4e60d951 | 26 | MODULE_PARM_DESC(disable_rc_polling, |
831511bd | 27 | "disable remote control polling (default: 0)"); |
c79b339f | 28 | static int dvb_usb_force_pid_filter_usage; |
4e60d951 AP |
29 | module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, |
30 | int, 0444); | |
6d7cfec4 AP |
31 | MODULE_PARM_DESC(force_pid_filter_usage, |
32 | "force all DVB USB devices to use a PID filter, if any (default: 0)"); | |
c79b339f | 33 | |
6d7cfec4 AP |
34 | static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, |
35 | const char *name) | |
a0d72d24 AP |
36 | { |
37 | int ret; | |
a0921af7 | 38 | const struct firmware *fw; |
d10d1b9a | 39 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
a0d72d24 | 40 | |
f093c388 | 41 | if (!d->props->download_firmware) { |
a0d72d24 AP |
42 | ret = -EINVAL; |
43 | goto err; | |
44 | } | |
45 | ||
46 | ret = request_firmware(&fw, name, &d->udev->dev); | |
47 | if (ret < 0) { | |
6d7cfec4 AP |
48 | dev_err(&d->udev->dev, |
49 | "%s: Did not find the firmware file '%s'. Please see linux/Documentation/dvb/ for more details on firmware-problems. Status %d\n", | |
50 | KBUILD_MODNAME, name, ret); | |
a0d72d24 AP |
51 | goto err; |
52 | } | |
53 | ||
d10d1b9a AP |
54 | dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n", |
55 | KBUILD_MODNAME, name); | |
a0d72d24 | 56 | |
f093c388 | 57 | ret = d->props->download_firmware(d, fw); |
a0d72d24 | 58 | release_firmware(fw); |
a0d72d24 AP |
59 | if (ret < 0) |
60 | goto err; | |
61 | ||
c65bcb95 | 62 | return ret; |
a0d72d24 | 63 | err: |
d10d1b9a | 64 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
a0d72d24 AP |
65 | return ret; |
66 | } | |
67 | ||
d496eb8a | 68 | static int dvb_usbv2_i2c_init(struct dvb_usb_device *d) |
a177c72b | 69 | { |
0fba999f | 70 | int ret; |
d10d1b9a | 71 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
d70521a3 AP |
72 | |
73 | if (!d->props->i2c_algo) | |
74 | return 0; | |
a177c72b AP |
75 | |
76 | strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name)); | |
f093c388 | 77 | d->i2c_adap.algo = d->props->i2c_algo; |
a177c72b | 78 | d->i2c_adap.dev.parent = &d->udev->dev; |
a177c72b AP |
79 | i2c_set_adapdata(&d->i2c_adap, d); |
80 | ||
81 | ret = i2c_add_adapter(&d->i2c_adap); | |
0fba999f | 82 | if (ret < 0) { |
d70521a3 | 83 | d->i2c_adap.algo = NULL; |
d10d1b9a AP |
84 | dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n", |
85 | KBUILD_MODNAME, ret); | |
0fba999f AP |
86 | goto err; |
87 | } | |
a177c72b | 88 | |
0fba999f AP |
89 | return 0; |
90 | err: | |
d10d1b9a | 91 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
a177c72b AP |
92 | return ret; |
93 | } | |
94 | ||
d496eb8a | 95 | static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d) |
a177c72b | 96 | { |
d10d1b9a | 97 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
0fba999f | 98 | |
d70521a3 AP |
99 | if (d->i2c_adap.algo) |
100 | i2c_del_adapter(&d->i2c_adap); | |
0fba999f | 101 | |
a177c72b AP |
102 | return 0; |
103 | } | |
104 | ||
37b44a0f | 105 | #if IS_ENABLED(CONFIG_RC_CORE) |
877e0aa7 AP |
106 | static void dvb_usb_read_remote_control(struct work_struct *work) |
107 | { | |
108 | struct dvb_usb_device *d = container_of(work, | |
109 | struct dvb_usb_device, rc_query_work.work); | |
110 | int ret; | |
111 | ||
831511bd AP |
112 | /* |
113 | * When the parameter has been set to 1 via sysfs while the | |
114 | * driver was running, or when bulk mode is enabled after IR init. | |
877e0aa7 | 115 | */ |
ac1c86c8 AP |
116 | if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode) { |
117 | d->rc_polling_active = false; | |
877e0aa7 | 118 | return; |
ac1c86c8 | 119 | } |
877e0aa7 AP |
120 | |
121 | ret = d->rc.query(d); | |
831511bd | 122 | if (ret < 0) { |
d10d1b9a AP |
123 | dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n", |
124 | KBUILD_MODNAME, ret); | |
ac1c86c8 | 125 | d->rc_polling_active = false; |
831511bd AP |
126 | return; /* stop polling */ |
127 | } | |
877e0aa7 AP |
128 | |
129 | schedule_delayed_work(&d->rc_query_work, | |
831511bd | 130 | msecs_to_jiffies(d->rc.interval)); |
877e0aa7 AP |
131 | } |
132 | ||
133 | static int dvb_usbv2_remote_init(struct dvb_usb_device *d) | |
134 | { | |
135 | int ret; | |
136 | struct rc_dev *dev; | |
d10d1b9a | 137 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
ad261839 | 138 | |
877e0aa7 AP |
139 | if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config) |
140 | return 0; | |
141 | ||
de73beee | 142 | d->rc.map_name = d->rc_map; |
877e0aa7 AP |
143 | ret = d->props->get_rc_config(d, &d->rc); |
144 | if (ret < 0) | |
145 | goto err; | |
146 | ||
de73beee AP |
147 | /* disable rc when there is no keymap defined */ |
148 | if (!d->rc.map_name) | |
149 | return 0; | |
150 | ||
877e0aa7 AP |
151 | dev = rc_allocate_device(); |
152 | if (!dev) { | |
153 | ret = -ENOMEM; | |
154 | goto err; | |
155 | } | |
156 | ||
157 | dev->dev.parent = &d->udev->dev; | |
831511bd | 158 | dev->input_name = d->name; |
877e0aa7 AP |
159 | usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); |
160 | strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); | |
161 | dev->input_phys = d->rc_phys; | |
162 | usb_to_input_id(d->udev, &dev->input_id); | |
163 | /* TODO: likely RC-core should took const char * */ | |
164 | dev->driver_name = (char *) d->props->driver_name; | |
de73beee | 165 | dev->map_name = d->rc.map_name; |
877e0aa7 | 166 | dev->driver_type = d->rc.driver_type; |
c5540fbb | 167 | dev->allowed_protocols = d->rc.allowed_protos; |
877e0aa7 AP |
168 | dev->change_protocol = d->rc.change_protocol; |
169 | dev->priv = d; | |
877e0aa7 AP |
170 | |
171 | ret = rc_register_device(dev); | |
172 | if (ret < 0) { | |
173 | rc_free_device(dev); | |
174 | goto err; | |
175 | } | |
176 | ||
877e0aa7 AP |
177 | d->rc_dev = dev; |
178 | ||
179 | /* start polling if needed */ | |
180 | if (d->rc.query && !d->rc.bulk_mode) { | |
181 | /* initialize a work queue for handling polling */ | |
182 | INIT_DELAYED_WORK(&d->rc_query_work, | |
183 | dvb_usb_read_remote_control); | |
6d7cfec4 AP |
184 | dev_info(&d->udev->dev, |
185 | "%s: schedule remote query interval to %d msecs\n", | |
186 | KBUILD_MODNAME, d->rc.interval); | |
877e0aa7 AP |
187 | schedule_delayed_work(&d->rc_query_work, |
188 | msecs_to_jiffies(d->rc.interval)); | |
ac1c86c8 | 189 | d->rc_polling_active = true; |
877e0aa7 AP |
190 | } |
191 | ||
877e0aa7 AP |
192 | return 0; |
193 | err: | |
d10d1b9a | 194 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
877e0aa7 AP |
195 | return ret; |
196 | } | |
197 | ||
198 | static int dvb_usbv2_remote_exit(struct dvb_usb_device *d) | |
199 | { | |
d10d1b9a | 200 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
ad261839 AP |
201 | |
202 | if (d->rc_dev) { | |
877e0aa7 AP |
203 | cancel_delayed_work_sync(&d->rc_query_work); |
204 | rc_unregister_device(d->rc_dev); | |
ad261839 | 205 | d->rc_dev = NULL; |
877e0aa7 AP |
206 | } |
207 | ||
877e0aa7 AP |
208 | return 0; |
209 | } | |
0c87c66a | 210 | #else |
ef382402 AP |
211 | #define dvb_usbv2_remote_init(args...) 0 |
212 | #define dvb_usbv2_remote_exit(args...) | |
0c87c66a | 213 | #endif |
877e0aa7 | 214 | |
41a0abf7 AP |
215 | static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf, |
216 | size_t len) | |
217 | { | |
218 | struct dvb_usb_adapter *adap = stream->user_priv; | |
219 | dvb_dmx_swfilter(&adap->demux, buf, len); | |
220 | } | |
221 | ||
222 | static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf, | |
223 | size_t len) | |
224 | { | |
225 | struct dvb_usb_adapter *adap = stream->user_priv; | |
226 | dvb_dmx_swfilter_204(&adap->demux, buf, len); | |
227 | } | |
228 | ||
229 | static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf, | |
230 | size_t len) | |
231 | { | |
232 | struct dvb_usb_adapter *adap = stream->user_priv; | |
233 | dvb_dmx_swfilter_raw(&adap->demux, buf, len); | |
234 | } | |
235 | ||
691a5502 | 236 | static int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap) |
41a0abf7 | 237 | { |
d10d1b9a AP |
238 | dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__, |
239 | adap->id); | |
41a0abf7 AP |
240 | |
241 | adap->stream.udev = adap_to_d(adap)->udev; | |
242 | adap->stream.user_priv = adap; | |
243 | adap->stream.complete = dvb_usb_data_complete; | |
244 | ||
245 | return usb_urb_initv2(&adap->stream, &adap->props->stream); | |
246 | } | |
247 | ||
691a5502 | 248 | static int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap) |
41a0abf7 | 249 | { |
d10d1b9a AP |
250 | dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__, |
251 | adap->id); | |
41a0abf7 | 252 | |
831511bd | 253 | return usb_urb_exitv2(&adap->stream); |
41a0abf7 AP |
254 | } |
255 | ||
96d7ca5e | 256 | static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) |
41a0abf7 AP |
257 | { |
258 | struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv; | |
259 | struct dvb_usb_device *d = adap_to_d(adap); | |
96d7ca5e AP |
260 | int ret = 0; |
261 | struct usb_data_stream_properties stream_props; | |
262 | dev_dbg(&d->udev->dev, | |
263 | "%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: %04x (%04d) at index %d\n", | |
d10d1b9a | 264 | __func__, adap->id, adap->active_fe, dvbdmxfeed->type, |
41a0abf7 | 265 | adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid, |
96d7ca5e | 266 | dvbdmxfeed->pid, dvbdmxfeed->index); |
41a0abf7 | 267 | |
96d7ca5e | 268 | /* wait init is done */ |
74316201 | 269 | wait_on_bit(&adap->state_bits, ADAP_INIT, TASK_UNINTERRUPTIBLE); |
bdecbe43 | 270 | |
41a0abf7 AP |
271 | if (adap->active_fe == -1) |
272 | return -EINVAL; | |
273 | ||
96d7ca5e AP |
274 | /* skip feed setup if we are already feeding */ |
275 | if (adap->feed_count++ > 0) | |
276 | goto skip_feed_start; | |
277 | ||
278 | /* set 'streaming' status bit */ | |
279 | set_bit(ADAP_STREAMING, &adap->state_bits); | |
280 | ||
281 | /* resolve input and output streaming parameters */ | |
282 | if (d->props->get_stream_config) { | |
283 | memcpy(&stream_props, &adap->props->stream, | |
284 | sizeof(struct usb_data_stream_properties)); | |
285 | ret = d->props->get_stream_config(adap->fe[adap->active_fe], | |
286 | &adap->ts_type, &stream_props); | |
287 | if (ret) | |
288 | dev_err(&d->udev->dev, | |
289 | "%s: get_stream_config() failed=%d\n", | |
290 | KBUILD_MODNAME, ret); | |
291 | } else { | |
292 | stream_props = adap->props->stream; | |
293 | } | |
294 | ||
295 | switch (adap->ts_type) { | |
296 | case DVB_USB_FE_TS_TYPE_204: | |
297 | adap->stream.complete = dvb_usb_data_complete_204; | |
298 | break; | |
299 | case DVB_USB_FE_TS_TYPE_RAW: | |
300 | adap->stream.complete = dvb_usb_data_complete_raw; | |
301 | break; | |
302 | case DVB_USB_FE_TS_TYPE_188: | |
303 | default: | |
304 | adap->stream.complete = dvb_usb_data_complete; | |
305 | break; | |
306 | } | |
307 | ||
308 | /* submit USB streaming packets */ | |
309 | usb_urb_submitv2(&adap->stream, &stream_props); | |
310 | ||
311 | /* enable HW PID filter */ | |
312 | if (adap->pid_filtering && adap->props->pid_filter_ctrl) { | |
313 | ret = adap->props->pid_filter_ctrl(adap, 1); | |
314 | if (ret) | |
315 | dev_err(&d->udev->dev, | |
316 | "%s: pid_filter_ctrl() failed=%d\n", | |
317 | KBUILD_MODNAME, ret); | |
318 | } | |
319 | ||
320 | /* ask device to start streaming */ | |
321 | if (d->props->streaming_ctrl) { | |
322 | ret = d->props->streaming_ctrl(adap->fe[adap->active_fe], 1); | |
323 | if (ret) | |
324 | dev_err(&d->udev->dev, | |
325 | "%s: streaming_ctrl() failed=%d\n", | |
326 | KBUILD_MODNAME, ret); | |
41a0abf7 | 327 | } |
96d7ca5e | 328 | skip_feed_start: |
41a0abf7 | 329 | |
96d7ca5e AP |
330 | /* add PID to device HW PID filter */ |
331 | if (adap->pid_filtering && adap->props->pid_filter) { | |
41a0abf7 | 332 | ret = adap->props->pid_filter(adap, dvbdmxfeed->index, |
96d7ca5e AP |
333 | dvbdmxfeed->pid, 1); |
334 | if (ret) | |
2d9e7ea6 AP |
335 | dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", |
336 | KBUILD_MODNAME, ret); | |
337 | } | |
41a0abf7 | 338 | |
96d7ca5e AP |
339 | if (ret) |
340 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | |
341 | return ret; | |
342 | } | |
41a0abf7 | 343 | |
96d7ca5e AP |
344 | static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) |
345 | { | |
346 | struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv; | |
347 | struct dvb_usb_device *d = adap_to_d(adap); | |
348 | int ret = 0; | |
349 | dev_dbg(&d->udev->dev, | |
350 | "%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: %04x (%04d) at index %d\n", | |
351 | __func__, adap->id, adap->active_fe, dvbdmxfeed->type, | |
352 | adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid, | |
353 | dvbdmxfeed->pid, dvbdmxfeed->index); | |
354 | ||
355 | if (adap->active_fe == -1) | |
356 | return -EINVAL; | |
357 | ||
358 | /* remove PID from device HW PID filter */ | |
359 | if (adap->pid_filtering && adap->props->pid_filter) { | |
360 | ret = adap->props->pid_filter(adap, dvbdmxfeed->index, | |
361 | dvbdmxfeed->pid, 0); | |
362 | if (ret) | |
363 | dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", | |
364 | KBUILD_MODNAME, ret); | |
41a0abf7 AP |
365 | } |
366 | ||
96d7ca5e AP |
367 | /* we cannot stop streaming until last PID is removed */ |
368 | if (--adap->feed_count > 0) | |
369 | goto skip_feed_stop; | |
370 | ||
371 | /* ask device to stop streaming */ | |
372 | if (d->props->streaming_ctrl) { | |
373 | ret = d->props->streaming_ctrl(adap->fe[adap->active_fe], 0); | |
374 | if (ret) | |
375 | dev_err(&d->udev->dev, | |
376 | "%s: streaming_ctrl() failed=%d\n", | |
377 | KBUILD_MODNAME, ret); | |
378 | } | |
379 | ||
380 | /* disable HW PID filter */ | |
381 | if (adap->pid_filtering && adap->props->pid_filter_ctrl) { | |
382 | ret = adap->props->pid_filter_ctrl(adap, 0); | |
383 | if (ret) | |
384 | dev_err(&d->udev->dev, | |
385 | "%s: pid_filter_ctrl() failed=%d\n", | |
386 | KBUILD_MODNAME, ret); | |
387 | } | |
388 | ||
389 | /* kill USB streaming packets */ | |
390 | usb_urb_killv2(&adap->stream); | |
391 | ||
392 | /* clear 'streaming' status bit */ | |
bdecbe43 | 393 | clear_bit(ADAP_STREAMING, &adap->state_bits); |
4e857c58 | 394 | smp_mb__after_atomic(); |
bdecbe43 | 395 | wake_up_bit(&adap->state_bits, ADAP_STREAMING); |
96d7ca5e | 396 | skip_feed_stop: |
41a0abf7 | 397 | |
96d7ca5e AP |
398 | if (ret) |
399 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | |
400 | return ret; | |
41a0abf7 AP |
401 | } |
402 | ||
9f806795 | 403 | static int dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) |
6f6c77d8 RLLC |
404 | { |
405 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | |
6f6c77d8 | 406 | struct media_device *mdev; |
823b460e | 407 | struct dvb_usb_device *d = adap_to_d(adap); |
6f6c77d8 | 408 | struct usb_device *udev = d->udev; |
6f6c77d8 RLLC |
409 | |
410 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | |
411 | if (!mdev) | |
9f806795 | 412 | return -ENOMEM; |
6f6c77d8 RLLC |
413 | |
414 | mdev->dev = &udev->dev; | |
415 | strlcpy(mdev->model, d->name, sizeof(mdev->model)); | |
416 | if (udev->serial) | |
417 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | |
418 | strcpy(mdev->bus_info, udev->devpath); | |
419 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | |
420 | mdev->driver_version = LINUX_VERSION_CODE; | |
421 | ||
9832e155 | 422 | media_device_init(mdev); |
6f6c77d8 | 423 | |
89a2c1d6 | 424 | dvb_register_media_controller(&adap->dvb_adap, mdev); |
6f6c77d8 RLLC |
425 | |
426 | dev_info(&d->udev->dev, "media controller created\n"); | |
9832e155 | 427 | #endif |
9f806795 | 428 | return 0; |
9832e155 | 429 | } |
6f6c77d8 | 430 | |
9f806795 | 431 | static int dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) |
9832e155 JMC |
432 | { |
433 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | |
9f806795 MCC |
434 | return media_device_register(adap->dvb_adap.mdev); |
435 | #else | |
436 | return 0; | |
6f6c77d8 RLLC |
437 | #endif |
438 | } | |
439 | ||
823b460e | 440 | static void dvb_usbv2_media_device_unregister(struct dvb_usb_adapter *adap) |
6f6c77d8 RLLC |
441 | { |
442 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | |
823b460e MCC |
443 | |
444 | if (!adap->dvb_adap.mdev) | |
6f6c77d8 RLLC |
445 | return; |
446 | ||
823b460e | 447 | media_device_unregister(adap->dvb_adap.mdev); |
9832e155 | 448 | media_device_cleanup(adap->dvb_adap.mdev); |
823b460e MCC |
449 | kfree(adap->dvb_adap.mdev); |
450 | adap->dvb_adap.mdev = NULL; | |
6f6c77d8 RLLC |
451 | |
452 | #endif | |
453 | } | |
454 | ||
691a5502 | 455 | static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) |
41a0abf7 AP |
456 | { |
457 | int ret; | |
458 | struct dvb_usb_device *d = adap_to_d(adap); | |
823b460e | 459 | |
d10d1b9a | 460 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); |
41a0abf7 AP |
461 | |
462 | ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner, | |
463 | &d->udev->dev, d->props->adapter_nr); | |
464 | if (ret < 0) { | |
d10d1b9a AP |
465 | dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n", |
466 | __func__, ret); | |
831511bd | 467 | goto err_dvb_register_adapter; |
41a0abf7 AP |
468 | } |
469 | ||
470 | adap->dvb_adap.priv = adap; | |
471 | ||
9f806795 MCC |
472 | ret = dvb_usbv2_media_device_init(adap); |
473 | if (ret < 0) { | |
474 | dev_dbg(&d->udev->dev, "%s: dvb_usbv2_media_device_init() failed=%d\n", | |
475 | __func__, ret); | |
476 | goto err_dvb_register_mc; | |
477 | } | |
6f6c77d8 | 478 | |
41a0abf7 AP |
479 | if (d->props->read_mac_address) { |
480 | ret = d->props->read_mac_address(adap, | |
481 | adap->dvb_adap.proposed_mac); | |
482 | if (ret < 0) | |
831511bd | 483 | goto err_dvb_dmx_init; |
41a0abf7 | 484 | |
d10d1b9a AP |
485 | dev_info(&d->udev->dev, "%s: MAC address: %pM\n", |
486 | KBUILD_MODNAME, adap->dvb_adap.proposed_mac); | |
41a0abf7 AP |
487 | } |
488 | ||
489 | adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; | |
490 | adap->demux.priv = adap; | |
491 | adap->demux.filternum = 0; | |
831511bd | 492 | adap->demux.filternum = adap->max_feed_count; |
41a0abf7 AP |
493 | adap->demux.feednum = adap->demux.filternum; |
494 | adap->demux.start_feed = dvb_usb_start_feed; | |
495 | adap->demux.stop_feed = dvb_usb_stop_feed; | |
496 | adap->demux.write_to_decoder = NULL; | |
497 | ret = dvb_dmx_init(&adap->demux); | |
498 | if (ret < 0) { | |
d10d1b9a AP |
499 | dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n", |
500 | KBUILD_MODNAME, ret); | |
831511bd | 501 | goto err_dvb_dmx_init; |
41a0abf7 AP |
502 | } |
503 | ||
504 | adap->dmxdev.filternum = adap->demux.filternum; | |
505 | adap->dmxdev.demux = &adap->demux.dmx; | |
506 | adap->dmxdev.capabilities = 0; | |
507 | ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); | |
508 | if (ret < 0) { | |
d10d1b9a AP |
509 | dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n", |
510 | KBUILD_MODNAME, ret); | |
831511bd | 511 | goto err_dvb_dmxdev_init; |
41a0abf7 AP |
512 | } |
513 | ||
514 | ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); | |
515 | if (ret < 0) { | |
d10d1b9a AP |
516 | dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n", |
517 | KBUILD_MODNAME, ret); | |
831511bd | 518 | goto err_dvb_net_init; |
41a0abf7 AP |
519 | } |
520 | ||
41a0abf7 | 521 | return 0; |
831511bd | 522 | err_dvb_net_init: |
41a0abf7 | 523 | dvb_dmxdev_release(&adap->dmxdev); |
831511bd | 524 | err_dvb_dmxdev_init: |
41a0abf7 | 525 | dvb_dmx_release(&adap->demux); |
831511bd | 526 | err_dvb_dmx_init: |
823b460e | 527 | dvb_usbv2_media_device_unregister(adap); |
9f806795 | 528 | err_dvb_register_mc: |
41a0abf7 | 529 | dvb_unregister_adapter(&adap->dvb_adap); |
831511bd | 530 | err_dvb_register_adapter: |
41a0abf7 AP |
531 | adap->dvb_adap.priv = NULL; |
532 | return ret; | |
533 | } | |
534 | ||
691a5502 | 535 | static int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap) |
41a0abf7 | 536 | { |
d10d1b9a AP |
537 | dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__, |
538 | adap->id); | |
41a0abf7 AP |
539 | |
540 | if (adap->dvb_adap.priv) { | |
541 | dvb_net_release(&adap->dvb_net); | |
542 | adap->demux.dmx.close(&adap->demux.dmx); | |
543 | dvb_dmxdev_release(&adap->dmxdev); | |
544 | dvb_dmx_release(&adap->demux); | |
823b460e | 545 | dvb_usbv2_media_device_unregister(adap); |
41a0abf7 AP |
546 | dvb_unregister_adapter(&adap->dvb_adap); |
547 | } | |
548 | ||
549 | return 0; | |
550 | } | |
551 | ||
691a5502 | 552 | static int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff) |
41a0abf7 AP |
553 | { |
554 | int ret; | |
555 | ||
556 | if (onoff) | |
557 | d->powered++; | |
558 | else | |
559 | d->powered--; | |
560 | ||
561 | if (d->powered == 0 || (onoff && d->powered == 1)) { | |
562 | /* when switching from 1 to 0 or from 0 to 1 */ | |
d10d1b9a | 563 | dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff); |
41a0abf7 AP |
564 | if (d->props->power_ctrl) { |
565 | ret = d->props->power_ctrl(d, onoff); | |
18cfe03d AP |
566 | if (ret < 0) |
567 | goto err; | |
41a0abf7 AP |
568 | } |
569 | } | |
570 | ||
571 | return 0; | |
572 | err: | |
d10d1b9a | 573 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
41a0abf7 AP |
574 | return ret; |
575 | } | |
576 | ||
831511bd | 577 | static int dvb_usb_fe_init(struct dvb_frontend *fe) |
41a0abf7 AP |
578 | { |
579 | int ret; | |
580 | struct dvb_usb_adapter *adap = fe->dvb->priv; | |
581 | struct dvb_usb_device *d = adap_to_d(adap); | |
d10d1b9a AP |
582 | dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id, |
583 | fe->id); | |
41a0abf7 | 584 | |
06bae122 AP |
585 | if (!adap->suspend_resume_active) { |
586 | adap->active_fe = fe->id; | |
bdecbe43 | 587 | set_bit(ADAP_INIT, &adap->state_bits); |
06bae122 AP |
588 | } |
589 | ||
41a0abf7 AP |
590 | ret = dvb_usbv2_device_power_ctrl(d, 1); |
591 | if (ret < 0) | |
592 | goto err; | |
593 | ||
594 | if (d->props->frontend_ctrl) { | |
595 | ret = d->props->frontend_ctrl(fe, 1); | |
596 | if (ret < 0) | |
597 | goto err; | |
598 | } | |
599 | ||
600 | if (adap->fe_init[fe->id]) { | |
601 | ret = adap->fe_init[fe->id](fe); | |
602 | if (ret < 0) | |
603 | goto err; | |
604 | } | |
41a0abf7 | 605 | err: |
bdecbe43 AP |
606 | if (!adap->suspend_resume_active) { |
607 | clear_bit(ADAP_INIT, &adap->state_bits); | |
4e857c58 | 608 | smp_mb__after_atomic(); |
bdecbe43 AP |
609 | wake_up_bit(&adap->state_bits, ADAP_INIT); |
610 | } | |
0898b954 | 611 | |
06bae122 | 612 | dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); |
0898b954 AP |
613 | return ret; |
614 | } | |
615 | ||
41a0abf7 AP |
616 | static int dvb_usb_fe_sleep(struct dvb_frontend *fe) |
617 | { | |
618 | int ret; | |
619 | struct dvb_usb_adapter *adap = fe->dvb->priv; | |
620 | struct dvb_usb_device *d = adap_to_d(adap); | |
d10d1b9a AP |
621 | dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id, |
622 | fe->id); | |
41a0abf7 | 623 | |
bdecbe43 AP |
624 | if (!adap->suspend_resume_active) { |
625 | set_bit(ADAP_SLEEP, &adap->state_bits); | |
74316201 | 626 | wait_on_bit(&adap->state_bits, ADAP_STREAMING, |
bdecbe43 AP |
627 | TASK_UNINTERRUPTIBLE); |
628 | } | |
06bae122 | 629 | |
41a0abf7 AP |
630 | if (adap->fe_sleep[fe->id]) { |
631 | ret = adap->fe_sleep[fe->id](fe); | |
632 | if (ret < 0) | |
633 | goto err; | |
634 | } | |
635 | ||
636 | if (d->props->frontend_ctrl) { | |
637 | ret = d->props->frontend_ctrl(fe, 0); | |
638 | if (ret < 0) | |
639 | goto err; | |
640 | } | |
641 | ||
642 | ret = dvb_usbv2_device_power_ctrl(d, 0); | |
643 | if (ret < 0) | |
644 | goto err; | |
41a0abf7 | 645 | err: |
06bae122 AP |
646 | if (!adap->suspend_resume_active) { |
647 | adap->active_fe = -1; | |
bdecbe43 | 648 | clear_bit(ADAP_SLEEP, &adap->state_bits); |
4e857c58 | 649 | smp_mb__after_atomic(); |
bdecbe43 | 650 | wake_up_bit(&adap->state_bits, ADAP_SLEEP); |
06bae122 | 651 | } |
0898b954 | 652 | |
06bae122 | 653 | dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); |
0898b954 AP |
654 | return ret; |
655 | } | |
656 | ||
691a5502 | 657 | static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) |
41a0abf7 AP |
658 | { |
659 | int ret, i, count_registered = 0; | |
660 | struct dvb_usb_device *d = adap_to_d(adap); | |
d10d1b9a | 661 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); |
41a0abf7 AP |
662 | |
663 | memset(adap->fe, 0, sizeof(adap->fe)); | |
664 | adap->active_fe = -1; | |
665 | ||
666 | if (d->props->frontend_attach) { | |
667 | ret = d->props->frontend_attach(adap); | |
668 | if (ret < 0) { | |
6d7cfec4 AP |
669 | dev_dbg(&d->udev->dev, |
670 | "%s: frontend_attach() failed=%d\n", | |
671 | __func__, ret); | |
41a0abf7 AP |
672 | goto err_dvb_frontend_detach; |
673 | } | |
674 | } else { | |
d10d1b9a AP |
675 | dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n", |
676 | __func__); | |
41a0abf7 AP |
677 | ret = 0; |
678 | goto err; | |
679 | } | |
680 | ||
681 | for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) { | |
682 | adap->fe[i]->id = i; | |
41a0abf7 AP |
683 | /* re-assign sleep and wakeup functions */ |
684 | adap->fe_init[i] = adap->fe[i]->ops.init; | |
06bae122 | 685 | adap->fe[i]->ops.init = dvb_usb_fe_init; |
41a0abf7 | 686 | adap->fe_sleep[i] = adap->fe[i]->ops.sleep; |
06bae122 | 687 | adap->fe[i]->ops.sleep = dvb_usb_fe_sleep; |
41a0abf7 AP |
688 | |
689 | ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]); | |
690 | if (ret < 0) { | |
6d7cfec4 AP |
691 | dev_err(&d->udev->dev, |
692 | "%s: frontend%d registration failed\n", | |
693 | KBUILD_MODNAME, i); | |
41a0abf7 AP |
694 | goto err_dvb_unregister_frontend; |
695 | } | |
696 | ||
697 | count_registered++; | |
698 | } | |
699 | ||
700 | if (d->props->tuner_attach) { | |
701 | ret = d->props->tuner_attach(adap); | |
702 | if (ret < 0) { | |
d10d1b9a AP |
703 | dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n", |
704 | __func__, ret); | |
41a0abf7 AP |
705 | goto err_dvb_unregister_frontend; |
706 | } | |
707 | } | |
708 | ||
0230d60e | 709 | ret = dvb_create_media_graph(&adap->dvb_adap, true); |
0d3ab841 MCC |
710 | if (ret < 0) |
711 | goto err_dvb_unregister_frontend; | |
6f6c77d8 | 712 | |
9f806795 | 713 | ret = dvb_usbv2_media_device_register(adap); |
9832e155 | 714 | |
9f806795 | 715 | return ret; |
41a0abf7 AP |
716 | |
717 | err_dvb_unregister_frontend: | |
718 | for (i = count_registered - 1; i >= 0; i--) | |
719 | dvb_unregister_frontend(adap->fe[i]); | |
720 | ||
721 | err_dvb_frontend_detach: | |
722 | for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) { | |
2a858486 | 723 | if (adap->fe[i]) { |
41a0abf7 | 724 | dvb_frontend_detach(adap->fe[i]); |
2a858486 AP |
725 | adap->fe[i] = NULL; |
726 | } | |
41a0abf7 AP |
727 | } |
728 | ||
729 | err: | |
d10d1b9a | 730 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
41a0abf7 AP |
731 | return ret; |
732 | } | |
733 | ||
691a5502 | 734 | static int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap) |
41a0abf7 | 735 | { |
ca42129f AP |
736 | int ret, i; |
737 | struct dvb_usb_device *d = adap_to_d(adap); | |
738 | ||
739 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); | |
41a0abf7 AP |
740 | |
741 | for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) { | |
742 | if (adap->fe[i]) { | |
743 | dvb_unregister_frontend(adap->fe[i]); | |
744 | dvb_frontend_detach(adap->fe[i]); | |
745 | } | |
746 | } | |
747 | ||
1066d77f AP |
748 | if (d->props->tuner_detach) { |
749 | ret = d->props->tuner_detach(adap); | |
750 | if (ret < 0) { | |
751 | dev_dbg(&d->udev->dev, "%s: tuner_detach() failed=%d\n", | |
752 | __func__, ret); | |
753 | } | |
754 | } | |
755 | ||
ca42129f AP |
756 | if (d->props->frontend_detach) { |
757 | ret = d->props->frontend_detach(adap); | |
758 | if (ret < 0) { | |
759 | dev_dbg(&d->udev->dev, | |
760 | "%s: frontend_detach() failed=%d\n", | |
761 | __func__, ret); | |
762 | } | |
763 | } | |
764 | ||
41a0abf7 AP |
765 | return 0; |
766 | } | |
767 | ||
59784343 | 768 | static int dvb_usbv2_adapter_init(struct dvb_usb_device *d) |
c79b339f AP |
769 | { |
770 | struct dvb_usb_adapter *adap; | |
d496eb8a | 771 | int ret, i, adapter_count; |
c79b339f | 772 | |
5b853004 | 773 | /* resolve adapter count */ |
f093c388 AP |
774 | adapter_count = d->props->num_adapters; |
775 | if (d->props->get_adapter_count) { | |
776 | ret = d->props->get_adapter_count(d); | |
5b853004 AP |
777 | if (ret < 0) |
778 | goto err; | |
779 | ||
780 | adapter_count = ret; | |
781 | } | |
782 | ||
d496eb8a AP |
783 | for (i = 0; i < adapter_count; i++) { |
784 | adap = &d->adapter[i]; | |
f093c388 AP |
785 | adap->id = i; |
786 | adap->props = &d->props->adapter[i]; | |
4e60d951 | 787 | |
e46c5b66 AP |
788 | /* speed - when running at FULL speed we need a HW PID filter */ |
789 | if (d->udev->speed == USB_SPEED_FULL && | |
f093c388 | 790 | !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) { |
6d7cfec4 AP |
791 | dev_err(&d->udev->dev, |
792 | "%s: this USB2.0 device cannot be run on a USB1.1 port (it lacks a hardware PID filter)\n", | |
d10d1b9a | 793 | KBUILD_MODNAME); |
d496eb8a AP |
794 | ret = -ENODEV; |
795 | goto err; | |
e46c5b66 | 796 | } else if ((d->udev->speed == USB_SPEED_FULL && |
f093c388 AP |
797 | adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) || |
798 | (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) { | |
6d7cfec4 AP |
799 | dev_info(&d->udev->dev, |
800 | "%s: will use the device's hardware PID filter (table count: %d)\n", | |
801 | KBUILD_MODNAME, | |
f093c388 | 802 | adap->props->pid_filter_count); |
e46c5b66 | 803 | adap->pid_filtering = 1; |
f093c388 | 804 | adap->max_feed_count = adap->props->pid_filter_count; |
e46c5b66 | 805 | } else { |
6d7cfec4 AP |
806 | dev_info(&d->udev->dev, |
807 | "%s: will pass the complete MPEG2 transport stream to the software demuxer\n", | |
808 | KBUILD_MODNAME); | |
e46c5b66 AP |
809 | adap->pid_filtering = 0; |
810 | adap->max_feed_count = 255; | |
811 | } | |
c79b339f | 812 | |
e46c5b66 | 813 | if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage && |
f093c388 | 814 | adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) { |
6d7cfec4 AP |
815 | dev_info(&d->udev->dev, |
816 | "%s: PID filter enabled by module option\n", | |
817 | KBUILD_MODNAME); | |
e46c5b66 | 818 | adap->pid_filtering = 1; |
f093c388 | 819 | adap->max_feed_count = adap->props->pid_filter_count; |
c79b339f | 820 | } |
c79b339f | 821 | |
59784343 | 822 | ret = dvb_usbv2_adapter_stream_init(adap); |
4e60d951 | 823 | if (ret) |
d496eb8a | 824 | goto err; |
4e60d951 | 825 | |
59784343 | 826 | ret = dvb_usbv2_adapter_dvb_init(adap); |
4e60d951 | 827 | if (ret) |
d496eb8a | 828 | goto err; |
4e60d951 | 829 | |
59784343 | 830 | ret = dvb_usbv2_adapter_frontend_init(adap); |
4e60d951 | 831 | if (ret) |
d496eb8a | 832 | goto err; |
c79b339f AP |
833 | |
834 | /* use exclusive FE lock if there is multiple shared FEs */ | |
20bb9cc4 | 835 | if (adap->fe[1]) |
c79b339f | 836 | adap->dvb_adap.mfe_shared = 1; |
c79b339f AP |
837 | } |
838 | ||
c79b339f | 839 | return 0; |
5b853004 | 840 | err: |
d10d1b9a | 841 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
5b853004 | 842 | return ret; |
c79b339f AP |
843 | } |
844 | ||
59784343 | 845 | static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d) |
c79b339f | 846 | { |
d496eb8a | 847 | int i; |
d10d1b9a | 848 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
6e3a5daa AP |
849 | |
850 | for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) { | |
b62fd172 | 851 | if (d->adapter[i].props) { |
b62fd172 AP |
852 | dvb_usbv2_adapter_dvb_exit(&d->adapter[i]); |
853 | dvb_usbv2_adapter_stream_exit(&d->adapter[i]); | |
7a0af6ed | 854 | dvb_usbv2_adapter_frontend_exit(&d->adapter[i]); |
b62fd172 | 855 | } |
c79b339f | 856 | } |
d496eb8a | 857 | |
c79b339f AP |
858 | return 0; |
859 | } | |
860 | ||
c79b339f | 861 | /* general initialization functions */ |
59784343 | 862 | static int dvb_usbv2_exit(struct dvb_usb_device *d) |
c79b339f | 863 | { |
d10d1b9a | 864 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
d70521a3 | 865 | |
59784343 AP |
866 | dvb_usbv2_remote_exit(d); |
867 | dvb_usbv2_adapter_exit(d); | |
868 | dvb_usbv2_i2c_exit(d); | |
c79b339f AP |
869 | kfree(d->priv); |
870 | kfree(d); | |
d496eb8a | 871 | |
c79b339f AP |
872 | return 0; |
873 | } | |
874 | ||
59784343 | 875 | static int dvb_usbv2_init(struct dvb_usb_device *d) |
c79b339f | 876 | { |
831511bd | 877 | int ret; |
d10d1b9a | 878 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
c79b339f | 879 | |
59784343 | 880 | dvb_usbv2_device_power_ctrl(d, 1); |
c79b339f | 881 | |
f093c388 AP |
882 | if (d->props->read_config) { |
883 | ret = d->props->read_config(d); | |
43402bbd AP |
884 | if (ret < 0) |
885 | goto err; | |
886 | } | |
887 | ||
59784343 | 888 | ret = dvb_usbv2_i2c_init(d); |
d496eb8a AP |
889 | if (ret < 0) |
890 | goto err; | |
4e60d951 | 891 | |
d496eb8a AP |
892 | ret = dvb_usbv2_adapter_init(d); |
893 | if (ret < 0) | |
894 | goto err; | |
c79b339f | 895 | |
f093c388 AP |
896 | if (d->props->init) { |
897 | ret = d->props->init(d); | |
d496eb8a AP |
898 | if (ret < 0) |
899 | goto err; | |
900 | } | |
dc786937 | 901 | |
59784343 | 902 | ret = dvb_usbv2_remote_init(d); |
d496eb8a AP |
903 | if (ret < 0) |
904 | goto err; | |
c79b339f | 905 | |
59784343 | 906 | dvb_usbv2_device_power_ctrl(d, 0); |
c79b339f AP |
907 | |
908 | return 0; | |
43402bbd | 909 | err: |
d496eb8a | 910 | dvb_usbv2_device_power_ctrl(d, 0); |
d10d1b9a | 911 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
43402bbd | 912 | return ret; |
c79b339f AP |
913 | } |
914 | ||
dd0f5e0b AP |
915 | int dvb_usbv2_probe(struct usb_interface *intf, |
916 | const struct usb_device_id *id) | |
4f208d4e AP |
917 | { |
918 | int ret; | |
dd0f5e0b AP |
919 | struct dvb_usb_device *d; |
920 | struct usb_device *udev = interface_to_usbdev(intf); | |
921 | struct dvb_usb_driver_info *driver_info = | |
922 | (struct dvb_usb_driver_info *) id->driver_info; | |
923 | ||
924 | dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__, | |
925 | intf->cur_altsetting->desc.bInterfaceNumber); | |
926 | ||
927 | if (!id->driver_info) { | |
928 | dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME); | |
929 | ret = -ENODEV; | |
930 | goto err; | |
931 | } | |
932 | ||
933 | d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); | |
934 | if (!d) { | |
935 | dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | |
936 | ret = -ENOMEM; | |
937 | goto err; | |
938 | } | |
496e8278 | 939 | |
ac5361a8 | 940 | d->intf = intf; |
dd0f5e0b AP |
941 | d->name = driver_info->name; |
942 | d->rc_map = driver_info->rc_map; | |
943 | d->udev = udev; | |
944 | d->props = driver_info->props; | |
945 | ||
946 | if (intf->cur_altsetting->desc.bInterfaceNumber != | |
947 | d->props->bInterfaceNumber) { | |
948 | ret = -ENODEV; | |
949 | goto err_free_all; | |
950 | } | |
951 | ||
952 | mutex_init(&d->usb_mutex); | |
953 | mutex_init(&d->i2c_mutex); | |
c79b339f | 954 | |
f093c388 AP |
955 | if (d->props->size_of_priv) { |
956 | d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL); | |
4f208d4e | 957 | if (!d->priv) { |
d10d1b9a AP |
958 | dev_err(&d->udev->dev, "%s: kzalloc() failed\n", |
959 | KBUILD_MODNAME); | |
496e8278 | 960 | ret = -ENOMEM; |
dd0f5e0b | 961 | goto err_free_all; |
496e8278 AP |
962 | } |
963 | } | |
c79b339f | 964 | |
f093c388 | 965 | if (d->props->identify_state) { |
a0921af7 AP |
966 | const char *name = NULL; |
967 | ret = d->props->identify_state(d, &name); | |
496e8278 AP |
968 | if (ret == 0) { |
969 | ; | |
970 | } else if (ret == COLD) { | |
6d7cfec4 AP |
971 | dev_info(&d->udev->dev, |
972 | "%s: found a '%s' in cold state\n", | |
973 | KBUILD_MODNAME, d->name); | |
a0921af7 AP |
974 | |
975 | if (!name) | |
976 | name = d->props->firmware; | |
977 | ||
978 | ret = dvb_usbv2_download_firmware(d, name); | |
979 | if (ret == 0) { | |
980 | /* device is warm, continue initialization */ | |
981 | ; | |
982 | } else if (ret == RECONNECTS_USB) { | |
983 | /* | |
984 | * USB core will call disconnect() and then | |
985 | * probe() as device reconnects itself from the | |
986 | * USB bus. disconnect() will release all driver | |
987 | * resources and probe() is called for 'new' | |
988 | * device. As 'new' device is warm we should | |
989 | * never go here again. | |
990 | */ | |
dd0f5e0b | 991 | goto exit; |
a0921af7 | 992 | } else { |
dd0f5e0b | 993 | goto err_free_all; |
a0921af7 | 994 | } |
496e8278 | 995 | } else { |
dd0f5e0b | 996 | goto err_free_all; |
496e8278 | 997 | } |
c79b339f AP |
998 | } |
999 | ||
d10d1b9a AP |
1000 | dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n", |
1001 | KBUILD_MODNAME, d->name); | |
c79b339f | 1002 | |
59784343 | 1003 | ret = dvb_usbv2_init(d); |
4f208d4e | 1004 | if (ret < 0) |
dd0f5e0b | 1005 | goto err_free_all; |
c79b339f | 1006 | |
6d7cfec4 AP |
1007 | dev_info(&d->udev->dev, |
1008 | "%s: '%s' successfully initialized and connected\n", | |
1009 | KBUILD_MODNAME, d->name); | |
dd0f5e0b | 1010 | exit: |
4f208d4e | 1011 | usb_set_intfdata(intf, d); |
21f5a32e AP |
1012 | |
1013 | return 0; | |
dd0f5e0b AP |
1014 | err_free_all: |
1015 | dvb_usbv2_exit(d); | |
21f5a32e | 1016 | err: |
d10d1b9a | 1017 | dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); |
21f5a32e AP |
1018 | return ret; |
1019 | } | |
6b8c8c40 | 1020 | EXPORT_SYMBOL(dvb_usbv2_probe); |
21f5a32e | 1021 | |
6b8c8c40 | 1022 | void dvb_usbv2_disconnect(struct usb_interface *intf) |
c79b339f AP |
1023 | { |
1024 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
831511bd | 1025 | const char *name = d->name; |
d10d1b9a | 1026 | struct device dev = d->udev->dev; |
6f6c77d8 | 1027 | |
dd0f5e0b AP |
1028 | dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, |
1029 | intf->cur_altsetting->desc.bInterfaceNumber); | |
c79b339f | 1030 | |
831511bd AP |
1031 | if (d->props->exit) |
1032 | d->props->exit(d); | |
5b6a63cc | 1033 | |
823eebac | 1034 | dvb_usbv2_exit(d); |
4f208d4e | 1035 | |
d10d1b9a | 1036 | dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n", |
4f208d4e | 1037 | KBUILD_MODNAME, name); |
c79b339f | 1038 | } |
6b8c8c40 | 1039 | EXPORT_SYMBOL(dvb_usbv2_disconnect); |
c79b339f | 1040 | |
ef81e9eb AP |
1041 | int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg) |
1042 | { | |
1043 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
15d08836 | 1044 | int ret = 0, i, active_fe; |
0898b954 | 1045 | struct dvb_frontend *fe; |
d10d1b9a | 1046 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
ef81e9eb AP |
1047 | |
1048 | /* stop remote controller poll */ | |
ac1c86c8 | 1049 | if (d->rc_polling_active) |
ef81e9eb AP |
1050 | cancel_delayed_work_sync(&d->rc_query_work); |
1051 | ||
5cd98320 | 1052 | for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) { |
0898b954 AP |
1053 | active_fe = d->adapter[i].active_fe; |
1054 | if (d->adapter[i].dvb_adap.priv && active_fe != -1) { | |
1055 | fe = d->adapter[i].fe[active_fe]; | |
06bae122 | 1056 | d->adapter[i].suspend_resume_active = true; |
0898b954 AP |
1057 | |
1058 | if (d->props->streaming_ctrl) | |
1059 | d->props->streaming_ctrl(fe, 0); | |
1060 | ||
1061 | /* stop usb streaming */ | |
ef81e9eb | 1062 | usb_urb_killv2(&d->adapter[i].stream); |
0898b954 | 1063 | |
15d08836 | 1064 | ret = dvb_frontend_suspend(fe); |
0898b954 | 1065 | } |
ef81e9eb AP |
1066 | } |
1067 | ||
15d08836 | 1068 | return ret; |
ef81e9eb AP |
1069 | } |
1070 | EXPORT_SYMBOL(dvb_usbv2_suspend); | |
1071 | ||
15d08836 | 1072 | static int dvb_usbv2_resume_common(struct dvb_usb_device *d) |
ef81e9eb | 1073 | { |
15d08836 | 1074 | int ret = 0, i, active_fe; |
0898b954 | 1075 | struct dvb_frontend *fe; |
d10d1b9a | 1076 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
ef81e9eb | 1077 | |
5cd98320 | 1078 | for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) { |
0898b954 AP |
1079 | active_fe = d->adapter[i].active_fe; |
1080 | if (d->adapter[i].dvb_adap.priv && active_fe != -1) { | |
1081 | fe = d->adapter[i].fe[active_fe]; | |
1082 | ||
15d08836 | 1083 | ret = dvb_frontend_resume(fe); |
0898b954 AP |
1084 | |
1085 | /* resume usb streaming */ | |
ef81e9eb | 1086 | usb_urb_submitv2(&d->adapter[i].stream, NULL); |
0898b954 AP |
1087 | |
1088 | if (d->props->streaming_ctrl) | |
1089 | d->props->streaming_ctrl(fe, 1); | |
06bae122 AP |
1090 | |
1091 | d->adapter[i].suspend_resume_active = false; | |
0898b954 | 1092 | } |
ef81e9eb AP |
1093 | } |
1094 | ||
1095 | /* start remote controller poll */ | |
ac1c86c8 | 1096 | if (d->rc_polling_active) |
ef81e9eb AP |
1097 | schedule_delayed_work(&d->rc_query_work, |
1098 | msecs_to_jiffies(d->rc.interval)); | |
1099 | ||
15d08836 AP |
1100 | return ret; |
1101 | } | |
1102 | ||
1103 | int dvb_usbv2_resume(struct usb_interface *intf) | |
1104 | { | |
1105 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
1106 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | |
1107 | ||
1108 | return dvb_usbv2_resume_common(d); | |
ef81e9eb AP |
1109 | } |
1110 | EXPORT_SYMBOL(dvb_usbv2_resume); | |
1111 | ||
15d08836 AP |
1112 | int dvb_usbv2_reset_resume(struct usb_interface *intf) |
1113 | { | |
1114 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
1115 | int ret; | |
1116 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | |
1117 | ||
1118 | dvb_usbv2_device_power_ctrl(d, 1); | |
1119 | ||
1120 | if (d->props->init) | |
1121 | d->props->init(d); | |
1122 | ||
1123 | ret = dvb_usbv2_resume_common(d); | |
1124 | ||
1125 | dvb_usbv2_device_power_ctrl(d, 0); | |
1126 | ||
1127 | return ret; | |
1128 | } | |
1129 | EXPORT_SYMBOL(dvb_usbv2_reset_resume); | |
1130 | ||
12042b05 | 1131 | MODULE_VERSION("2.0"); |
c79b339f | 1132 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); |
12042b05 AP |
1133 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); |
1134 | MODULE_DESCRIPTION("DVB USB common"); | |
c79b339f | 1135 | MODULE_LICENSE("GPL"); |