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> 5 * 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. 10 * 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. 15 */ 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> 24 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" 31 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)"); 35 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)"); 39 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)"); 43 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)"); 47 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)"); 51 52 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 53 54 static void as102_stop_stream(struct as102_dev_t *dev) 55 { 56 struct as10x_bus_adapter_t *bus_adap; 57 58 if (dev != NULL) 59 bus_adap = &dev->bus_adap; 60 else 61 return; 62 63 if (bus_adap->ops->stop_stream != NULL) 64 bus_adap->ops->stop_stream(dev); 65 66 if (ts_auto_disable) { 67 if (mutex_lock_interruptible(&dev->bus_adap.lock)) 68 return; 69 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"); 73 74 mutex_unlock(&dev->bus_adap.lock); 75 } 76 } 77 78 static int as102_start_stream(struct as102_dev_t *dev) 79 { 80 struct as10x_bus_adapter_t *bus_adap; 81 int ret = -EFAULT; 82 83 if (dev != NULL) 84 bus_adap = &dev->bus_adap; 85 else 86 return ret; 87 88 if (bus_adap->ops->start_stream != NULL) 89 ret = bus_adap->ops->start_stream(dev); 90 91 if (ts_auto_disable) { 92 if (mutex_lock_interruptible(&dev->bus_adap.lock)) 93 return -EFAULT; 94 95 ret = as10x_cmd_start_streaming(bus_adap); 96 97 mutex_unlock(&dev->bus_adap.lock); 98 } 99 100 return ret; 101 } 102 103 static int as10x_pid_filter(struct as102_dev_t *dev, 104 int index, u16 pid, int onoff) { 105 106 struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap; 107 int ret = -EFAULT; 108 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; 113 } 114 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: 123 { 124 struct as10x_ts_filter filter; 125 126 filter.type = TS_PID_TYPE_TS; 127 filter.idx = 0xFF; 128 filter.pid = pid; 129 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; 135 } 136 } 137 138 mutex_unlock(&dev->bus_adap.lock); 139 return ret; 140 } 141 142 static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) 143 { 144 int ret = 0; 145 struct dvb_demux *demux = dvbdmxfeed->demux; 146 struct as102_dev_t *as102_dev = demux->priv; 147 148 if (mutex_lock_interruptible(&as102_dev->sem)) 149 return -ERESTARTSYS; 150 151 if (pid_filtering) 152 as10x_pid_filter(as102_dev, dvbdmxfeed->index, 153 dvbdmxfeed->pid, 1); 154 155 if (as102_dev->streaming++ == 0) 156 ret = as102_start_stream(as102_dev); 157 158 mutex_unlock(&as102_dev->sem); 159 return ret; 160 } 161 162 static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 163 { 164 struct dvb_demux *demux = dvbdmxfeed->demux; 165 struct as102_dev_t *as102_dev = demux->priv; 166 167 if (mutex_lock_interruptible(&as102_dev->sem)) 168 return -ERESTARTSYS; 169 170 if (--as102_dev->streaming == 0) 171 as102_stop_stream(as102_dev); 172 173 if (pid_filtering) 174 as10x_pid_filter(as102_dev, dvbdmxfeed->index, 175 dvbdmxfeed->pid, 0); 176 177 mutex_unlock(&as102_dev->sem); 178 return 0; 179 } 180 181 static int as102_set_tune(void *priv, struct as10x_tune_args *tune_args) 182 { 183 struct as10x_bus_adapter_t *bus_adap = priv; 184 int ret; 185 186 /* Set frontend arguments */ 187 if (mutex_lock_interruptible(&bus_adap->lock)) 188 return -EBUSY; 189 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); 194 195 mutex_unlock(&bus_adap->lock); 196 197 return ret; 198 } 199 200 static int as102_get_tps(void *priv, struct as10x_tps *tps) 201 { 202 struct as10x_bus_adapter_t *bus_adap = priv; 203 int ret; 204 205 if (mutex_lock_interruptible(&bus_adap->lock)) 206 return -EBUSY; 207 208 /* send abilis command: GET_TPS */ 209 ret = as10x_cmd_get_tps(bus_adap, tps); 210 211 mutex_unlock(&bus_adap->lock); 212 213 return ret; 214 } 215 216 static int as102_get_status(void *priv, struct as10x_tune_status *tstate) 217 { 218 struct as10x_bus_adapter_t *bus_adap = priv; 219 int ret; 220 221 if (mutex_lock_interruptible(&bus_adap->lock)) 222 return -EBUSY; 223 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); 230 } 231 232 mutex_unlock(&bus_adap->lock); 233 234 return ret; 235 } 236 237 static int as102_get_stats(void *priv, struct as10x_demod_stats *demod_stats) 238 { 239 struct as10x_bus_adapter_t *bus_adap = priv; 240 int ret; 241 242 if (mutex_lock_interruptible(&bus_adap->lock)) 243 return -EBUSY; 244 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); 257 } 258 mutex_unlock(&bus_adap->lock); 259 260 return ret; 261 } 262 263 static int as102_stream_ctrl(void *priv, int acquire, uint32_t elna_cfg) 264 { 265 struct as10x_bus_adapter_t *bus_adap = priv; 266 int ret; 267 268 if (mutex_lock_interruptible(&bus_adap->lock)) 269 return -EBUSY; 270 271 if (acquire) { 272 if (elna_enable) 273 as10x_cmd_set_context(bus_adap, 274 CONTEXT_LNA, elna_cfg); 275 276 ret = as10x_cmd_turn_on(bus_adap); 277 } else { 278 ret = as10x_cmd_turn_off(bus_adap); 279 } 280 281 mutex_unlock(&bus_adap->lock); 282 283 return ret; 284 } 285 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, 292 }; 293 294 int as102_dvb_register(struct as102_dev_t *as102_dev) 295 { 296 struct device *dev = &as102_dev->bus_adap.usb_dev->dev; 297 int ret; 298 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; 306 } 307 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; 313 314 as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING | 315 DMX_SECTION_FILTERING; 316 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; 320 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; 325 } 326 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; 332 } 333 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 ret = -ENODEV; 341 dev_err(dev, "%s: as102_attach() failed: %d", 342 __func__, ret); 343 goto efereg; 344 } 345 346 ret = dvb_register_frontend(&as102_dev->dvb_adap, as102_dev->dvb_fe); 347 if (ret < 0) { 348 dev_err(dev, "%s: as102_dvb_register_frontend() failed: %d", 349 __func__, ret); 350 goto efereg; 351 } 352 353 /* init bus mutex for token locking */ 354 mutex_init(&as102_dev->bus_adap.lock); 355 356 /* init start / stop stream mutex */ 357 mutex_init(&as102_dev->sem); 358 359 /* 360 * try to load as102 firmware. If firmware upload failed, we'll be 361 * able to upload it later. 362 */ 363 if (fw_upload) 364 try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), 365 "firmware_class"); 366 367 pr_info("Registered device %s", as102_dev->name); 368 return 0; 369 370 efereg: 371 dvb_dmxdev_release(&as102_dev->dvb_dmxdev); 372 edmxdinit: 373 dvb_dmx_release(&as102_dev->dvb_dmx); 374 edmxinit: 375 dvb_unregister_adapter(&as102_dev->dvb_adap); 376 return ret; 377 } 378 379 void as102_dvb_unregister(struct as102_dev_t *as102_dev) 380 { 381 /* unregister as102 frontend */ 382 dvb_unregister_frontend(as102_dev->dvb_fe); 383 384 /* detach frontend */ 385 dvb_frontend_detach(as102_dev->dvb_fe); 386 387 /* unregister demux device */ 388 dvb_dmxdev_release(&as102_dev->dvb_dmxdev); 389 dvb_dmx_release(&as102_dev->dvb_dmx); 390 391 /* unregister dvb adapter */ 392 dvb_unregister_adapter(&as102_dev->dvb_adap); 393 394 pr_info("Unregistered device %s", as102_dev->name); 395 } 396 397 module_usb_driver(as102_usb_driver); 398 399 /* modinfo details */ 400 MODULE_DESCRIPTION(DRIVER_FULL_NAME); 401 MODULE_LICENSE("GPL"); 402 MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>"); 403