Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
a800.c
Go to the documentation of this file.
1 /* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
2  * USB2.0 (A800) DVB-T receiver.
3  *
4  * Copyright (C) 2005 Patrick Boettcher ([email protected])
5  *
6  * Thanks to
7  * - AVerMedia who kindly provided information and
8  * - Glen Harris who suffered from my mistakes during development.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the Free
12  * Software Foundation, version 2.
13  *
14  * see Documentation/dvb/README.dvb-usb for more information
15  */
16 #include "dibusb.h"
17 
18 static int debug;
19 module_param(debug, int, 0644);
20 MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
21 
23 
24 #define deb_rc(args...) dprintk(debug,0x01,args)
25 
26 static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
27 {
28  /* do nothing for the AVerMedia */
29  return 0;
30 }
31 
32 /* assure to put cold to 0 for iManufacturer == 1 */
33 static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
34  struct dvb_usb_device_description **desc, int *cold)
35 {
36  *cold = udev->descriptor.iManufacturer != 1;
37  return 0;
38 }
39 
40 static struct rc_map_table rc_map_a800_table[] = {
41  { 0x0201, KEY_MODE }, /* SOURCE */
42  { 0x0200, KEY_POWER2 }, /* POWER */
43  { 0x0205, KEY_1 }, /* 1 */
44  { 0x0206, KEY_2 }, /* 2 */
45  { 0x0207, KEY_3 }, /* 3 */
46  { 0x0209, KEY_4 }, /* 4 */
47  { 0x020a, KEY_5 }, /* 5 */
48  { 0x020b, KEY_6 }, /* 6 */
49  { 0x020d, KEY_7 }, /* 7 */
50  { 0x020e, KEY_8 }, /* 8 */
51  { 0x020f, KEY_9 }, /* 9 */
52  { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53  { 0x0211, KEY_0 }, /* 0 */
54  { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55  { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
56  { 0x0210, KEY_LAST }, /* 16-CH PREV */
57  { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58  { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59  { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
60  { 0x0214, KEY_MUTE }, /* MUTE */
61  { 0x0208, KEY_AUDIO }, /* AUDIO */
62  { 0x0219, KEY_RECORD }, /* RECORD */
63  { 0x0218, KEY_PLAY }, /* PLAY */
64  { 0x021b, KEY_STOP }, /* STOP */
65  { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
66  { 0x021d, KEY_BACK }, /* << / RED */
67  { 0x021c, KEY_FORWARD }, /* >> / YELLOW */
68  { 0x0203, KEY_TEXT }, /* TELETEXT */
69  { 0x0204, KEY_EPG }, /* EPG */
70  { 0x0215, KEY_MENU }, /* MENU */
71 
72  { 0x0303, KEY_CHANNELUP }, /* CH UP */
73  { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
74  { 0x0301, KEY_FIRST }, /* |<< / GREEN */
75  { 0x0300, KEY_LAST }, /* >>| / BLUE */
76 
77 };
78 
79 static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
80 {
81  int ret;
82  u8 *key = kmalloc(5, GFP_KERNEL);
83  if (!key)
84  return -ENOMEM;
85 
86  if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
87  0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
88  2000) != 5) {
89  ret = -ENODEV;
90  goto out;
91  }
92 
93  /* call the universal NEC remote processor, to find out the key's state and event */
94  dvb_usb_nec_rc_key_to_event(d,key,event,state);
95  if (key[0] != 0)
96  deb_rc("key: %*ph\n", 5, key);
97  ret = 0;
98 out:
99  kfree(key);
100  return ret;
101 }
102 
103 /* USB Driver stuff */
104 static struct dvb_usb_device_properties a800_properties;
105 
106 static int a800_probe(struct usb_interface *intf,
107  const struct usb_device_id *id)
108 {
109  return dvb_usb_device_init(intf, &a800_properties,
111 }
112 
113 /* do not change the order of the ID table */
114 static struct usb_device_id a800_table [] = {
115 /* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
116 /* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
117  { } /* Terminating entry */
118 };
119 MODULE_DEVICE_TABLE (usb, a800_table);
120 
121 static struct dvb_usb_device_properties a800_properties = {
123 
124  .usb_ctrl = CYPRESS_FX2,
125  .firmware = "dvb-usb-avertv-a800-02.fw",
126 
127  .num_adapters = 1,
128  .adapter = {
129  {
130  .num_frontends = 1,
131  .fe = {{
133  .pid_filter_count = 32,
134  .streaming_ctrl = dibusb2_0_streaming_ctrl,
135  .pid_filter = dibusb_pid_filter,
136  .pid_filter_ctrl = dibusb_pid_filter_ctrl,
137 
138  .frontend_attach = dibusb_dib3000mc_frontend_attach,
139  .tuner_attach = dibusb_dib3000mc_tuner_attach,
140 
141  /* parameter for the MPEG2-data transfer */
142  .stream = {
143  .type = USB_BULK,
144  .count = 7,
145  .endpoint = 0x06,
146  .u = {
147  .bulk = {
148  .buffersize = 4096,
149  }
150  }
151  },
152  }},
153  .size_of_priv = sizeof(struct dibusb_state),
154  },
155  },
156 
157  .power_ctrl = a800_power_ctrl,
158  .identify_state = a800_identify_state,
159 
160  .rc.legacy = {
161  .rc_interval = DEFAULT_RC_INTERVAL,
162  .rc_map_table = rc_map_a800_table,
163  .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
164  .rc_query = a800_rc_query,
165  },
166 
167  .i2c_algo = &dibusb_i2c_algo,
168 
169  .generic_bulk_ctrl_endpoint = 0x01,
170  .num_device_descs = 1,
171  .devices = {
172  { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
173  { &a800_table[0], NULL },
174  { &a800_table[1], NULL },
175  },
176  }
177 };
178 
179 static struct usb_driver a800_driver = {
180  .name = "dvb_usb_a800",
181  .probe = a800_probe,
182  .disconnect = dvb_usb_device_exit,
183  .id_table = a800_table,
184 };
185 
186 module_usb_driver(a800_driver);
187 
188 MODULE_AUTHOR("Patrick Boettcher <[email protected]>");
189 MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
190 MODULE_VERSION("1.0");
191 MODULE_LICENSE("GPL");