[media] dvb_usb_v2: implement .get_adapter_count()
[deliverable/linux.git] / drivers / media / dvb / dvb-usb / dvb_usb_init.c
CommitLineData
c79b339f
AP
1/*
2 * DVB USB library - provides a generic interface for a DVB USB device driver.
3 *
4 * dvb-usb-init.c
5 *
6 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
7 *
8 * This program is free software; you can redistribute it and/or modify it
4e60d951
AP
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, version 2.
c79b339f
AP
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dvb_usb_common.h"
15
16/* debug */
17int dvb_usb_debug;
18module_param_named(debug, dvb_usb_debug, int, 0644);
4e60d951
AP
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8"\
20 ",err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))."
21 DVB_USB_DEBUG_STATUS);
c79b339f
AP
22
23int dvb_usb_disable_rc_polling;
24module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
4e60d951
AP
25MODULE_PARM_DESC(disable_rc_polling,
26 "disable remote control polling (default: 0).");
c79b339f
AP
27
28static int dvb_usb_force_pid_filter_usage;
4e60d951
AP
29module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
30 int, 0444);
31MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a" \
32 " PID filter, if any (default: 0).");
c79b339f 33
55b1f704 34static int dvb_usb_adapter_init(struct dvb_usb_device *d)
c79b339f
AP
35{
36 struct dvb_usb_adapter *adap;
5b853004 37 int ret, n, o, adapter_count;
c79b339f 38
5b853004
AP
39 /* resolve adapter count */
40 adapter_count = d->props.num_adapters;
41 if (d->props.get_adapter_count) {
42 ret = d->props.get_adapter_count(d);
43 if (ret < 0)
44 goto err;
45
46 adapter_count = ret;
47 }
48
49 for (n = 0; n < adapter_count; n++) {
c79b339f
AP
50 adap = &d->adapter[n];
51 adap->dev = d;
52 adap->id = n;
53
4e60d951
AP
54 memcpy(&adap->props, &d->props.adapter[n],
55 sizeof(struct dvb_usb_adapter_properties));
56
57 for (o = 0; o < adap->props.num_frontends; o++) {
58 struct dvb_usb_adapter_fe_properties *props =
59 &adap->props.fe[o];
60 /* speed - when running at FULL speed we need a HW
61 * PID filter */
62 if (d->udev->speed == USB_SPEED_FULL &&
63 !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
64 err("This USB2.0 device cannot be run on a" \
65 " USB1.1 port. (it lacks a" \
66 " hardware PID filter)");
67 return -ENODEV;
68 }
c79b339f 69
4e60d951
AP
70 if ((d->udev->speed == USB_SPEED_FULL &&
71 props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
72 (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
73 info("will use the device's hardware PID" \
74 " filter (table count: %d).",
75 props->pid_filter_count);
76 adap->fe_adap[o].pid_filtering = 1;
77 adap->fe_adap[o].max_feed_count =
78 props->pid_filter_count;
79 } else {
80 info("will pass the complete MPEG2 transport" \
81 " stream to the software demuxer.");
82 adap->fe_adap[o].pid_filtering = 0;
83 adap->fe_adap[o].max_feed_count = 255;
84 }
c79b339f 85
4e60d951
AP
86 if (!adap->fe_adap[o].pid_filtering &&
87 dvb_usb_force_pid_filter_usage &&
88 props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
89 info("pid filter enabled by module option.");
90 adap->fe_adap[o].pid_filtering = 1;
91 adap->fe_adap[o].max_feed_count =
92 props->pid_filter_count;
93 }
c79b339f 94
4e60d951
AP
95 if (props->size_of_priv > 0) {
96 adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL);
97 if (adap->fe_adap[o].priv == NULL) {
98 err("no memory for priv for adapter" \
99 " %d fe %d.", n, o);
100 return -ENOMEM;
101 }
c79b339f
AP
102 }
103 }
c79b339f
AP
104
105 if (adap->props.size_of_priv > 0) {
4e60d951
AP
106 adap->priv = kzalloc(adap->props.size_of_priv,
107 GFP_KERNEL);
c79b339f
AP
108 if (adap->priv == NULL) {
109 err("no memory for priv for adapter %d.", n);
110 return -ENOMEM;
111 }
112 }
113
4e60d951
AP
114 ret = dvb_usb_adapter_stream_init(adap);
115 if (ret)
116 return ret;
117
118 ret = dvb_usb_adapter_dvb_init(adap);
119 if (ret)
120 return ret;
121
122 ret = dvb_usb_adapter_frontend_init(adap);
123 if (ret)
c79b339f 124 return ret;
c79b339f
AP
125
126 /* use exclusive FE lock if there is multiple shared FEs */
127 if (adap->fe_adap[1].fe)
128 adap->dvb_adap.mfe_shared = 1;
129
130 d->num_adapters_initialized++;
131 d->state |= DVB_USB_STATE_DVB;
132 }
133
134 /*
135 * when reloading the driver w/o replugging the device
136 * sometimes a timeout occures, this helps
137 */
138 if (d->props.generic_bulk_ctrl_endpoint != 0) {
4e60d951
AP
139 usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev,
140 d->props.generic_bulk_ctrl_endpoint));
141 usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev,
142 d->props.generic_bulk_ctrl_endpoint));
c79b339f
AP
143 }
144
145 return 0;
5b853004
AP
146err:
147 pr_debug("%s: failed=%d\n", __func__, ret);
148 return ret;
c79b339f
AP
149}
150
151static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
152{
153 int n;
154
155 for (n = 0; n < d->num_adapters_initialized; n++) {
156 dvb_usb_adapter_frontend_exit(&d->adapter[n]);
157 dvb_usb_adapter_dvb_exit(&d->adapter[n]);
158 dvb_usb_adapter_stream_exit(&d->adapter[n]);
159 kfree(d->adapter[n].priv);
160 }
161 d->num_adapters_initialized = 0;
162 d->state &= ~DVB_USB_STATE_DVB;
163 return 0;
164}
165
166
167/* general initialization functions */
168static int dvb_usb_exit(struct dvb_usb_device *d)
169{
170 deb_info("state before exiting everything: %x\n", d->state);
171 dvb_usb_remote_exit(d);
172 dvb_usb_adapter_exit(d);
173 dvb_usb_i2c_exit(d);
174 deb_info("state should be zero now: %x\n", d->state);
175 d->state = DVB_USB_STATE_INIT;
176 kfree(d->priv);
177 kfree(d);
178 return 0;
179}
180
55b1f704 181static int dvb_usb_init(struct dvb_usb_device *d)
c79b339f
AP
182{
183 int ret = 0;
184
185 mutex_init(&d->usb_mutex);
186 mutex_init(&d->i2c_mutex);
187
188 d->state = DVB_USB_STATE_INIT;
189
c79b339f
AP
190 /* check the capabilities and set appropriate variables */
191 dvb_usb_device_power_ctrl(d, 1);
192
4e60d951
AP
193 ret = dvb_usb_i2c_init(d);
194 if (ret == 0)
195 ret = dvb_usb_adapter_init(d);
196
197 if (ret) {
c79b339f
AP
198 dvb_usb_exit(d);
199 return ret;
200 }
201
dc786937
AP
202 if (d->props.init)
203 d->props.init(d);
204
4e60d951
AP
205 ret = dvb_usb_remote_init(d);
206 if (ret)
c79b339f
AP
207 err("could not initialize remote control.");
208
209 dvb_usb_device_power_ctrl(d, 0);
210
211 return 0;
212}
213
c79b339f
AP
214int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
215{
216 if (onoff)
217 d->powered++;
218 else
219 d->powered--;
220
4e60d951
AP
221 if (d->powered == 0 || (onoff && d->powered == 1)) {
222 /* when switching from 1 to 0 or from 0 to 1 */
c79b339f
AP
223 deb_info("power control: %d\n", onoff);
224 if (d->props.power_ctrl)
225 return d->props.power_ctrl(d, onoff);
226 }
227 return 0;
228}
229
230/*
231 * USB
232 */
233int dvb_usbv2_device_init(struct usb_interface *intf,
496e8278 234 const struct usb_device_id *id)
c79b339f
AP
235{
236 struct usb_device *udev = interface_to_usbdev(intf);
237 struct dvb_usb_device *d = NULL;
7dfd1242
AP
238 struct dvb_usb_driver_info *driver_info =
239 (struct dvb_usb_driver_info *) id->driver_info;
240 const struct dvb_usb_device_properties *props = driver_info->props;
496e8278 241 int ret = -ENOMEM;
7dfd1242 242 bool cold = false;
496e8278
AP
243
244 d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
245 if (d == NULL) {
246 err("no memory for 'struct dvb_usb_device'");
247 return -ENOMEM;
248 }
249
250 d->udev = udev;
7dfd1242 251 d->name = driver_info->name;
496e8278 252 memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
c79b339f 253
496e8278
AP
254 if (d->props.size_of_priv > 0) {
255 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
256 if (d->priv == NULL) {
257 err("no memory for priv in 'struct dvb_usb_device'");
258 ret = -ENOMEM;
259 goto err_kfree;
260 }
261 }
c79b339f 262
496e8278
AP
263 if (d->props.identify_state) {
264 ret = d->props.identify_state(d);
265 if (ret == 0) {
266 ;
267 } else if (ret == COLD) {
268 cold = true;
269 ret = 0;
270 } else {
271 goto err_kfree;
272 }
c79b339f
AP
273 }
274
275 if (cold) {
4e60d951 276 info("found a '%s' in cold state, will try to load a firmware",
7dfd1242 277 d->name);
496e8278
AP
278 ret = dvb_usb_download_firmware(d);
279 if (ret == 0) {
280 ;
281 } else if (ret == RECONNECTS_USB) {
282 ret = 0;
283 goto err_kfree;
284 } else {
285 goto err_kfree;
286 }
c79b339f
AP
287 }
288
7dfd1242 289 info("found a '%s' in warm state.", d->name);
c79b339f
AP
290
291 usb_set_intfdata(intf, d);
292
55b1f704 293 ret = dvb_usb_init(d);
c79b339f
AP
294
295 if (ret == 0)
7dfd1242 296 info("%s successfully initialized and connected.", d->name);
c79b339f 297 else
7dfd1242 298 info("%s error while loading driver (%d)", d->name, ret);
496e8278
AP
299
300 return 0;
301
302err_kfree:
303 kfree(d->priv);
304 kfree(d);
305
c79b339f
AP
306 return ret;
307}
308EXPORT_SYMBOL(dvb_usbv2_device_init);
309
310void dvb_usbv2_device_exit(struct usb_interface *intf)
311{
312 struct dvb_usb_device *d = usb_get_intfdata(intf);
5b853004 313 const char *name = NULL;
c79b339f
AP
314
315 usb_set_intfdata(intf, NULL);
7dfd1242
AP
316 if (d) {
317 name = d->name;
c79b339f
AP
318 dvb_usb_exit(d);
319 }
320 info("%s successfully deinitialized and disconnected.", name);
c79b339f
AP
321}
322EXPORT_SYMBOL(dvb_usbv2_device_exit);
323
324MODULE_VERSION("1.0");
325MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
326MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
327MODULE_LICENSE("GPL");
This page took 0.039068 seconds and 5 git commands to generate.