treewide: Fix typo in printk messages
[linux-2.6/btrfs-unstable.git] / drivers / media / usb / as102 / as102_drv.c
blob8be1474b2c36fbf2df6080e62afbadae648de711
1 /*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <linux/mm.h>
21 #include <linux/kref.h>
22 #include <linux/uaccess.h>
23 #include <linux/usb.h>
25 /* header file for usb device driver*/
26 #include "as102_drv.h"
27 #include "as10x_cmd.h"
28 #include "as102_fe.h"
29 #include "as102_fw.h"
30 #include "dvbdev.h"
32 int dual_tuner;
33 module_param_named(dual_tuner, dual_tuner, int, 0644);
34 MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner config (default: off)");
36 static int fw_upload = 1;
37 module_param_named(fw_upload, fw_upload, int, 0644);
38 MODULE_PARM_DESC(fw_upload, "Turn on/off default FW upload (default: on)");
40 static int pid_filtering;
41 module_param_named(pid_filtering, pid_filtering, int, 0644);
42 MODULE_PARM_DESC(pid_filtering, "Activate HW PID filtering (default: off)");
44 static int ts_auto_disable;
45 module_param_named(ts_auto_disable, ts_auto_disable, int, 0644);
46 MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)");
48 int elna_enable = 1;
49 module_param_named(elna_enable, elna_enable, int, 0644);
50 MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)");
52 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54 static void as102_stop_stream(struct as102_dev_t *dev)
56 struct as10x_bus_adapter_t *bus_adap;
58 if (dev != NULL)
59 bus_adap = &dev->bus_adap;
60 else
61 return;
63 if (bus_adap->ops->stop_stream != NULL)
64 bus_adap->ops->stop_stream(dev);
66 if (ts_auto_disable) {
67 if (mutex_lock_interruptible(&dev->bus_adap.lock))
68 return;
70 if (as10x_cmd_stop_streaming(bus_adap) < 0)
71 dev_dbg(&dev->bus_adap.usb_dev->dev,
72 "as10x_cmd_stop_streaming failed\n");
74 mutex_unlock(&dev->bus_adap.lock);
78 static int as102_start_stream(struct as102_dev_t *dev)
80 struct as10x_bus_adapter_t *bus_adap;
81 int ret = -EFAULT;
83 if (dev != NULL)
84 bus_adap = &dev->bus_adap;
85 else
86 return ret;
88 if (bus_adap->ops->start_stream != NULL)
89 ret = bus_adap->ops->start_stream(dev);
91 if (ts_auto_disable) {
92 if (mutex_lock_interruptible(&dev->bus_adap.lock))
93 return -EFAULT;
95 ret = as10x_cmd_start_streaming(bus_adap);
97 mutex_unlock(&dev->bus_adap.lock);
100 return ret;
103 static int as10x_pid_filter(struct as102_dev_t *dev,
104 int index, u16 pid, int onoff) {
106 struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap;
107 int ret = -EFAULT;
109 if (mutex_lock_interruptible(&dev->bus_adap.lock)) {
110 dev_dbg(&dev->bus_adap.usb_dev->dev,
111 "amutex_lock_interruptible(lock) failed !\n");
112 return -EBUSY;
115 switch (onoff) {
116 case 0:
117 ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
118 dev_dbg(&dev->bus_adap.usb_dev->dev,
119 "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
120 index, pid, ret);
121 break;
122 case 1:
124 struct as10x_ts_filter filter;
126 filter.type = TS_PID_TYPE_TS;
127 filter.idx = 0xFF;
128 filter.pid = pid;
130 ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
131 dev_dbg(&dev->bus_adap.usb_dev->dev,
132 "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
133 index, filter.idx, filter.pid, ret);
134 break;
138 mutex_unlock(&dev->bus_adap.lock);
139 return ret;
142 static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
144 int ret = 0;
145 struct dvb_demux *demux = dvbdmxfeed->demux;
146 struct as102_dev_t *as102_dev = demux->priv;
148 if (mutex_lock_interruptible(&as102_dev->sem))
149 return -ERESTARTSYS;
151 if (pid_filtering)
152 as10x_pid_filter(as102_dev, dvbdmxfeed->index,
153 dvbdmxfeed->pid, 1);
155 if (as102_dev->streaming++ == 0)
156 ret = as102_start_stream(as102_dev);
158 mutex_unlock(&as102_dev->sem);
159 return ret;
162 static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
164 struct dvb_demux *demux = dvbdmxfeed->demux;
165 struct as102_dev_t *as102_dev = demux->priv;
167 if (mutex_lock_interruptible(&as102_dev->sem))
168 return -ERESTARTSYS;
170 if (--as102_dev->streaming == 0)
171 as102_stop_stream(as102_dev);
173 if (pid_filtering)
174 as10x_pid_filter(as102_dev, dvbdmxfeed->index,
175 dvbdmxfeed->pid, 0);
177 mutex_unlock(&as102_dev->sem);
178 return 0;
181 static int as102_set_tune(void *priv, struct as10x_tune_args *tune_args)
183 struct as10x_bus_adapter_t *bus_adap = priv;
184 int ret;
186 /* Set frontend arguments */
187 if (mutex_lock_interruptible(&bus_adap->lock))
188 return -EBUSY;
190 ret = as10x_cmd_set_tune(bus_adap, tune_args);
191 if (ret != 0)
192 dev_dbg(&bus_adap->usb_dev->dev,
193 "as10x_cmd_set_tune failed. (err = %d)\n", ret);
195 mutex_unlock(&bus_adap->lock);
197 return ret;
200 static int as102_get_tps(void *priv, struct as10x_tps *tps)
202 struct as10x_bus_adapter_t *bus_adap = priv;
203 int ret;
205 if (mutex_lock_interruptible(&bus_adap->lock))
206 return -EBUSY;
208 /* send abilis command: GET_TPS */
209 ret = as10x_cmd_get_tps(bus_adap, tps);
211 mutex_unlock(&bus_adap->lock);
213 return ret;
216 static int as102_get_status(void *priv, struct as10x_tune_status *tstate)
218 struct as10x_bus_adapter_t *bus_adap = priv;
219 int ret;
221 if (mutex_lock_interruptible(&bus_adap->lock))
222 return -EBUSY;
224 /* send abilis command: GET_TUNE_STATUS */
225 ret = as10x_cmd_get_tune_status(bus_adap, tstate);
226 if (ret < 0) {
227 dev_dbg(&bus_adap->usb_dev->dev,
228 "as10x_cmd_get_tune_status failed (err = %d)\n",
229 ret);
232 mutex_unlock(&bus_adap->lock);
234 return ret;
237 static int as102_get_stats(void *priv, struct as10x_demod_stats *demod_stats)
239 struct as10x_bus_adapter_t *bus_adap = priv;
240 int ret;
242 if (mutex_lock_interruptible(&bus_adap->lock))
243 return -EBUSY;
245 /* send abilis command: GET_TUNE_STATUS */
246 ret = as10x_cmd_get_demod_stats(bus_adap, demod_stats);
247 if (ret < 0) {
248 dev_dbg(&bus_adap->usb_dev->dev,
249 "as10x_cmd_get_demod_stats failed (probably not tuned)\n");
250 } else {
251 dev_dbg(&bus_adap->usb_dev->dev,
252 "demod status: fc: 0x%08x, bad fc: 0x%08x, bytes corrected: 0x%08x , MER: 0x%04x\n",
253 demod_stats->frame_count,
254 demod_stats->bad_frame_count,
255 demod_stats->bytes_fixed_by_rs,
256 demod_stats->mer);
258 mutex_unlock(&bus_adap->lock);
260 return ret;
263 static int as102_stream_ctrl(void *priv, int acquire, uint32_t elna_cfg)
265 struct as10x_bus_adapter_t *bus_adap = priv;
266 int ret;
268 if (mutex_lock_interruptible(&bus_adap->lock))
269 return -EBUSY;
271 if (acquire) {
272 if (elna_enable)
273 as10x_cmd_set_context(bus_adap,
274 CONTEXT_LNA, elna_cfg);
276 ret = as10x_cmd_turn_on(bus_adap);
277 } else {
278 ret = as10x_cmd_turn_off(bus_adap);
281 mutex_unlock(&bus_adap->lock);
283 return ret;
286 static const struct as102_fe_ops as102_fe_ops = {
287 .set_tune = as102_set_tune,
288 .get_tps = as102_get_tps,
289 .get_status = as102_get_status,
290 .get_stats = as102_get_stats,
291 .stream_ctrl = as102_stream_ctrl,
294 int as102_dvb_register(struct as102_dev_t *as102_dev)
296 struct device *dev = &as102_dev->bus_adap.usb_dev->dev;
297 int ret;
299 ret = dvb_register_adapter(&as102_dev->dvb_adap,
300 as102_dev->name, THIS_MODULE,
301 dev, adapter_nr);
302 if (ret < 0) {
303 dev_err(dev, "%s: dvb_register_adapter() failed: %d\n",
304 __func__, ret);
305 return ret;
308 as102_dev->dvb_dmx.priv = as102_dev;
309 as102_dev->dvb_dmx.filternum = pid_filtering ? 16 : 256;
310 as102_dev->dvb_dmx.feednum = 256;
311 as102_dev->dvb_dmx.start_feed = as102_dvb_dmx_start_feed;
312 as102_dev->dvb_dmx.stop_feed = as102_dvb_dmx_stop_feed;
314 as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING |
315 DMX_SECTION_FILTERING;
317 as102_dev->dvb_dmxdev.filternum = as102_dev->dvb_dmx.filternum;
318 as102_dev->dvb_dmxdev.demux = &as102_dev->dvb_dmx.dmx;
319 as102_dev->dvb_dmxdev.capabilities = 0;
321 ret = dvb_dmx_init(&as102_dev->dvb_dmx);
322 if (ret < 0) {
323 dev_err(dev, "%s: dvb_dmx_init() failed: %d\n", __func__, ret);
324 goto edmxinit;
327 ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap);
328 if (ret < 0) {
329 dev_err(dev, "%s: dvb_dmxdev_init() failed: %d\n",
330 __func__, ret);
331 goto edmxdinit;
334 /* Attach the frontend */
335 as102_dev->dvb_fe = dvb_attach(as102_attach, as102_dev->name,
336 &as102_fe_ops,
337 &as102_dev->bus_adap,
338 as102_dev->elna_cfg);
339 if (!as102_dev->dvb_fe) {
340 dev_err(dev, "%s: as102_attach() failed: %d",
341 __func__, ret);
342 goto efereg;
345 ret = dvb_register_frontend(&as102_dev->dvb_adap, as102_dev->dvb_fe);
346 if (ret < 0) {
347 dev_err(dev, "%s: as102_dvb_register_frontend() failed: %d",
348 __func__, ret);
349 goto efereg;
352 /* init bus mutex for token locking */
353 mutex_init(&as102_dev->bus_adap.lock);
355 /* init start / stop stream mutex */
356 mutex_init(&as102_dev->sem);
359 * try to load as102 firmware. If firmware upload failed, we'll be
360 * able to upload it later.
362 if (fw_upload)
363 try_then_request_module(as102_fw_upload(&as102_dev->bus_adap),
364 "firmware_class");
366 pr_info("Registered device %s", as102_dev->name);
367 return 0;
369 efereg:
370 dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
371 edmxdinit:
372 dvb_dmx_release(&as102_dev->dvb_dmx);
373 edmxinit:
374 dvb_unregister_adapter(&as102_dev->dvb_adap);
375 return ret;
378 void as102_dvb_unregister(struct as102_dev_t *as102_dev)
380 /* unregister as102 frontend */
381 dvb_unregister_frontend(as102_dev->dvb_fe);
383 /* detach frontend */
384 dvb_frontend_detach(as102_dev->dvb_fe);
386 /* unregister demux device */
387 dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
388 dvb_dmx_release(&as102_dev->dvb_dmx);
390 /* unregister dvb adapter */
391 dvb_unregister_adapter(&as102_dev->dvb_adap);
393 pr_info("Unregistered device %s", as102_dev->name);
396 module_usb_driver(as102_usb_driver);
398 /* modinfo details */
399 MODULE_DESCRIPTION(DRIVER_FULL_NAME);
400 MODULE_LICENSE("GPL");
401 MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");