aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tm6000/tm6000-dvb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tm6000/tm6000-dvb.c')
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c174
1 files changed, 124 insertions, 50 deletions
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index 261e66acbe46..f501edccf9c4 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -18,6 +18,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "tm6000.h"
@@ -30,12 +31,25 @@
#include "tuner-xc2028.h"
#include "xc5000.h"
-static void inline print_err_status (struct tm6000_core *dev,
- int packet, int status)
+MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
+
+MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
+ "{{Trident, tm6000},"
+ "{{Trident, tm6010}");
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug message");
+
+static inline void print_err_status(struct tm6000_core *dev,
+ int packet, int status)
{
char *errmsg = "Unknown";
- switch(status) {
+ switch (status) {
case -ENOENT:
errmsg = "unlinked synchronuously";
break;
@@ -61,7 +75,7 @@ static void inline print_err_status (struct tm6000_core *dev,
errmsg = "Device does not respond";
break;
}
- if (packet<0) {
+ if (packet < 0) {
dprintk(dev, 1, "URB status %d [%s].\n",
status, errmsg);
} else {
@@ -73,19 +87,17 @@ static void inline print_err_status (struct tm6000_core *dev,
static void tm6000_urb_received(struct urb *urb)
{
int ret;
- struct tm6000_core* dev = urb->context;
+ struct tm6000_core *dev = urb->context;
- if(urb->status != 0) {
- print_err_status (dev,0,urb->status);
- }
- else if(urb->actual_length>0){
+ if (urb->status != 0)
+ print_err_status(dev, 0, urb->status);
+ else if (urb->actual_length > 0)
dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
- }
- if(dev->dvb->streams > 0) {
+ if (dev->dvb->streams > 0) {
ret = usb_submit_urb(urb, GFP_ATOMIC);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
@@ -99,7 +111,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start stream request %s\n", __FUNCTION__);
if (dev->mode != TM6000_MODE_DIGITAL) {
tm6000_init_digital_mode(dev);
@@ -107,7 +119,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
}
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if(dvb->bulk_urb == NULL) {
+ if (dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
@@ -119,7 +131,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
size = size * 15; /* 512 x 8 or 12 or 15 */
dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if(dvb->bulk_urb->transfer_buffer == NULL) {
+ if (dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
@@ -131,20 +143,20 @@ int tm6000_start_stream(struct tm6000_core *dev)
tm6000_urb_received, dev);
ret = usb_clear_halt(dev->udev, pipe);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",ret,__FUNCTION__);
+ if (ret < 0) {
+ printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
+ ret, __FUNCTION__);
return ret;
- }
- else {
+ } else
printk(KERN_ERR "tm6000: pipe resetted\n");
- }
/* mutex_lock(&tm6000_driver.open_close_mutex); */
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
if (ret) {
- printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
+ printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
+ ret);
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
@@ -158,10 +170,10 @@ void tm6000_stop_stream(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb) {
- printk (KERN_INFO "urb killing\n");
+ if (dvb->bulk_urb) {
+ printk(KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
- printk (KERN_INFO "urb buffer free\n");
+ printk(KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -173,35 +185,34 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- if(dvb->streams == 0) {
+ if (dvb->streams == 0) {
dvb->streams = 1;
/* mutex_init(&tm6000_dev->streming_mutex); */
tm6000_start_stream(dev);
- }
- else {
+ } else
++(dvb->streams);
- }
mutex_unlock(&dvb->mutex);
return 0;
}
-int tm6000_stop_feed(struct dvb_demux_feed *feed) {
+int tm6000_stop_feed(struct dvb_demux_feed *feed)
+{
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got stop feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- printk (KERN_INFO "stream %#x\n", dvb->streams);
+ printk(KERN_INFO "stream %#x\n", dvb->streams);
--(dvb->streams);
- if(dvb->streams == 0) {
- printk (KERN_INFO "stop stream\n");
+ if (dvb->streams == 0) {
+ printk(KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
/* mutex_destroy(&tm6000_dev->streaming_mutex); */
}
@@ -215,9 +226,9 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dev->caps.has_zl10353) {
- struct zl10353_config config =
- {.demod_address = dev->demod_addr,
+ if (dev->caps.has_zl10353) {
+ struct zl10353_config config = {
+ .demod_address = dev->demod_addr,
.no_tuner = 1,
.parallel_ts = 1,
.if2 = 45700,
@@ -226,8 +237,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
dvb->frontend = dvb_attach(zl10353_attach, &config,
&dev->i2c_adap);
- }
- else {
+ } else {
printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
return -1;
}
@@ -237,7 +247,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-int tm6000_dvb_register(struct tm6000_core *dev)
+int register_dvb(struct tm6000_core *dev)
{
int ret = -1;
struct tm6000_dvb *dvb = dev->dvb;
@@ -248,13 +258,13 @@ int tm6000_dvb_register(struct tm6000_core *dev)
/* attach the frontend */
ret = tm6000_dvb_attach_frontend(dev);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
goto err;
}
ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
- THIS_MODULE, &dev->udev->dev, adapter_nr);
+ THIS_MODULE, &dev->udev->dev, adapter_nr);
dvb->adapter.priv = dev;
if (dvb->frontend) {
@@ -307,9 +317,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
break;
}
}
- } else {
+ } else
printk(KERN_ERR "tm6000: no frontend found\n");
- }
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
@@ -320,7 +329,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
ret = dvb_dmx_init(&dvb->demux);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
goto frontend_err;
}
@@ -330,7 +339,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->dmxdev.capabilities = 0;
ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
goto dvb_dmx_err;
}
@@ -340,7 +349,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb_dmx_err:
dvb_dmx_release(&dvb->demux);
frontend_err:
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -350,11 +359,11 @@ err:
return ret;
}
-void tm6000_dvb_unregister(struct tm6000_core *dev)
+void unregister_dvb(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb != NULL) {
+ if (dvb->bulk_urb != NULL) {
struct urb *bulk_urb = dvb->bulk_urb;
kfree(bulk_urb->transfer_buffer);
@@ -364,7 +373,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
}
/* mutex_lock(&tm6000_driver.open_close_mutex); */
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -374,5 +383,70 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
+}
+static int dvb_init(struct tm6000_core *dev)
+{
+ struct tm6000_dvb *dvb;
+ int rc;
+
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
+ if (!dvb) {
+ printk(KERN_INFO "Cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ dev->dvb = dvb;
+
+ rc = register_dvb(dev);
+ if (rc < 0) {
+ kfree(dvb);
+ dev->dvb = NULL;
+ return 0;
+ }
+
+ return 0;
+}
+
+static int dvb_fini(struct tm6000_core *dev)
+{
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ if (dev->dvb) {
+ unregister_dvb(dev);
+ kfree(dev->dvb);
+ dev->dvb = NULL;
+ }
+
+ return 0;
}
+
+static struct tm6000_ops dvb_ops = {
+ .type = TM6000_DVB,
+ .name = "TM6000 dvb Extension",
+ .init = dvb_init,
+ .fini = dvb_fini,
+};
+
+static int __init tm6000_dvb_register(void)
+{
+ return tm6000_register_extension(&dvb_ops);
+}
+
+static void __exit tm6000_dvb_unregister(void)
+{
+ tm6000_unregister_extension(&dvb_ops);
+}
+
+module_init(tm6000_dvb_register);
+module_exit(tm6000_dvb_unregister);