1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5*4882a593Smuzhiyun * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/errno.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/usb.h>
12*4882a593Smuzhiyun #include <linux/videodev2.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include "pvrusb2-hdw.h"
15*4882a593Smuzhiyun #include "pvrusb2-devattr.h"
16*4882a593Smuzhiyun #include "pvrusb2-context.h"
17*4882a593Smuzhiyun #include "pvrusb2-debug.h"
18*4882a593Smuzhiyun #include "pvrusb2-v4l2.h"
19*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
20*4882a593Smuzhiyun #include "pvrusb2-sysfs.h"
21*4882a593Smuzhiyun #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
24*4882a593Smuzhiyun #define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
25*4882a593Smuzhiyun #define DRIVER_VERSION "V4L in-tree version"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \
28*4882a593Smuzhiyun PVR2_TRACE_INFO| \
29*4882a593Smuzhiyun PVR2_TRACE_STD| \
30*4882a593Smuzhiyun PVR2_TRACE_TOLERANCE| \
31*4882a593Smuzhiyun PVR2_TRACE_TRAP| \
32*4882a593Smuzhiyun 0)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun int pvrusb2_debug = DEFAULT_DEBUG_MASK;
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
37*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "Debug trace mask");
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
40*4882a593Smuzhiyun static struct pvr2_sysfs_class *class_ptr = NULL;
41*4882a593Smuzhiyun #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
42*4882a593Smuzhiyun
pvr_setup_attach(struct pvr2_context * pvr)43*4882a593Smuzhiyun static void pvr_setup_attach(struct pvr2_context *pvr)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun /* Create association with v4l layer */
46*4882a593Smuzhiyun pvr2_v4l2_create(pvr);
47*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_DVB
48*4882a593Smuzhiyun /* Create association with dvb layer */
49*4882a593Smuzhiyun pvr2_dvb_create(pvr);
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
52*4882a593Smuzhiyun pvr2_sysfs_create(pvr,class_ptr);
53*4882a593Smuzhiyun #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
pvr_probe(struct usb_interface * intf,const struct usb_device_id * devid)56*4882a593Smuzhiyun static int pvr_probe(struct usb_interface *intf,
57*4882a593Smuzhiyun const struct usb_device_id *devid)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun struct pvr2_context *pvr;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* Create underlying hardware interface */
62*4882a593Smuzhiyun pvr = pvr2_context_create(intf,devid,pvr_setup_attach);
63*4882a593Smuzhiyun if (!pvr) {
64*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_ERROR_LEGS,
65*4882a593Smuzhiyun "Failed to create hdw handler");
66*4882a593Smuzhiyun return -ENOMEM;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun usb_set_intfdata(intf, pvr);
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun return 0;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /*
77*4882a593Smuzhiyun * pvr_disconnect()
78*4882a593Smuzhiyun *
79*4882a593Smuzhiyun */
pvr_disconnect(struct usb_interface * intf)80*4882a593Smuzhiyun static void pvr_disconnect(struct usb_interface *intf)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun struct pvr2_context *pvr = usb_get_intfdata(intf);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun usb_set_intfdata (intf, NULL);
87*4882a593Smuzhiyun pvr2_context_disconnect(pvr);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun static struct usb_driver pvr_driver = {
94*4882a593Smuzhiyun .name = "pvrusb2",
95*4882a593Smuzhiyun .id_table = pvr2_device_table,
96*4882a593Smuzhiyun .probe = pvr_probe,
97*4882a593Smuzhiyun .disconnect = pvr_disconnect
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /*
101*4882a593Smuzhiyun * pvr_init() / pvr_exit()
102*4882a593Smuzhiyun *
103*4882a593Smuzhiyun * This code is run to initialize/exit the driver.
104*4882a593Smuzhiyun *
105*4882a593Smuzhiyun */
pvr_init(void)106*4882a593Smuzhiyun static int __init pvr_init(void)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun int ret;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_init");
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun ret = pvr2_context_global_init();
113*4882a593Smuzhiyun if (ret != 0) {
114*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_init failure code=%d",ret);
115*4882a593Smuzhiyun return ret;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
119*4882a593Smuzhiyun class_ptr = pvr2_sysfs_class_create();
120*4882a593Smuzhiyun #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun ret = usb_register(&pvr_driver);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun if (ret == 0)
125*4882a593Smuzhiyun pr_info("pvrusb2: " DRIVER_VERSION ":"
126*4882a593Smuzhiyun DRIVER_DESC "\n");
127*4882a593Smuzhiyun if (pvrusb2_debug)
128*4882a593Smuzhiyun pr_info("pvrusb2: Debug mask is %d (0x%x)\n",
129*4882a593Smuzhiyun pvrusb2_debug,pvrusb2_debug);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun return ret;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
pvr_exit(void)136*4882a593Smuzhiyun static void __exit pvr_exit(void)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun usb_deregister(&pvr_driver);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun pvr2_context_global_done();
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
145*4882a593Smuzhiyun pvr2_sysfs_class_destroy(class_ptr);
146*4882a593Smuzhiyun #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete");
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun module_init(pvr_init);
152*4882a593Smuzhiyun module_exit(pvr_exit);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun MODULE_AUTHOR(DRIVER_AUTHOR);
155*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
156*4882a593Smuzhiyun MODULE_LICENSE("GPL");
157*4882a593Smuzhiyun MODULE_VERSION("0.9.1");
158