~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/media/dvb/dvb-usb/vp702x.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * see Documentation/dvb/README.dvb-usb for more information
16
16
 */
17
17
#include "vp702x.h"
 
18
#include <linux/mutex.h>
18
19
 
19
20
/* debug */
20
21
int dvb_usb_vp702x_debug;
23
24
 
24
25
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26
 
26
 
struct vp702x_state {
 
27
struct vp702x_adapter_state {
27
28
        int pid_filter_count;
28
29
        int pid_filter_can_bypass;
29
30
        u8  pid_filter_state;
30
31
};
31
32
 
32
 
struct vp702x_device_state {
33
 
        u8 power_state;
34
 
};
35
 
 
36
 
/* check for mutex FIXME */
37
 
int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
 
33
static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
 
34
                                     u16 value, u16 index, u8 *b, int blen)
38
35
{
39
 
        int ret = -1;
 
36
        int ret;
40
37
 
41
 
                ret = usb_control_msg(d->udev,
42
 
                        usb_rcvctrlpipe(d->udev,0),
43
 
                        req,
44
 
                        USB_TYPE_VENDOR | USB_DIR_IN,
45
 
                        value,index,b,blen,
46
 
                        2000);
 
38
        ret = usb_control_msg(d->udev,
 
39
                usb_rcvctrlpipe(d->udev, 0),
 
40
                req,
 
41
                USB_TYPE_VENDOR | USB_DIR_IN,
 
42
                value, index, b, blen,
 
43
                2000);
47
44
 
48
45
        if (ret < 0) {
49
46
                warn("usb in operation failed. (%d)", ret);
58
55
        return ret;
59
56
}
60
57
 
61
 
static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
62
 
                             u16 index, u8 *b, int blen)
 
58
int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
 
59
                            u16 index, u8 *b, int blen)
 
60
{
 
61
        int ret;
 
62
 
 
63
        mutex_lock(&d->usb_mutex);
 
64
        ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
 
65
        mutex_unlock(&d->usb_mutex);
 
66
 
 
67
        return ret;
 
68
}
 
69
 
 
70
int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
 
71
                                      u16 index, u8 *b, int blen)
63
72
{
64
73
        int ret;
65
74
        deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
77
86
                return 0;
78
87
}
79
88
 
 
89
int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 
90
                             u16 index, u8 *b, int blen)
 
91
{
 
92
        int ret;
 
93
 
 
94
        mutex_lock(&d->usb_mutex);
 
95
        ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
 
96
        mutex_unlock(&d->usb_mutex);
 
97
 
 
98
        return ret;
 
99
}
 
100
 
80
101
int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
81
102
{
82
103
        int ret;
84
105
        if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
85
106
                return ret;
86
107
 
87
 
        ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen);
 
108
        ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
88
109
        msleep(msec);
89
 
        ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
 
110
        ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
90
111
 
91
112
        mutex_unlock(&d->usb_mutex);
92
 
 
93
113
        return ret;
94
114
}
95
115
 
96
116
static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
97
117
                                int olen, u8 *i, int ilen, int msec)
98
118
{
99
 
        u8 bout[olen+2];
100
 
        u8 bin[ilen+1];
 
119
        struct vp702x_device_state *st = d->priv;
101
120
        int ret = 0;
102
 
 
103
 
        bout[0] = 0x00;
104
 
        bout[1] = cmd;
105
 
        memcpy(&bout[2],o,olen);
106
 
 
107
 
        ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec);
 
121
        u8 *buf;
 
122
        int buflen = max(olen + 2, ilen + 1);
 
123
 
 
124
        ret = mutex_lock_interruptible(&st->buf_mutex);
 
125
        if (ret < 0)
 
126
                return ret;
 
127
 
 
128
        if (buflen > st->buf_len) {
 
129
                buf = kmalloc(buflen, GFP_KERNEL);
 
130
                if (!buf) {
 
131
                        mutex_unlock(&st->buf_mutex);
 
132
                        return -ENOMEM;
 
133
                }
 
134
                info("successfully reallocated a bigger buffer");
 
135
                kfree(st->buf);
 
136
                st->buf = buf;
 
137
                st->buf_len = buflen;
 
138
        } else {
 
139
                buf = st->buf;
 
140
        }
 
141
 
 
142
        buf[0] = 0x00;
 
143
        buf[1] = cmd;
 
144
        memcpy(&buf[2], o, olen);
 
145
 
 
146
        ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
108
147
 
109
148
        if (ret == 0)
110
 
                memcpy(i,&bin[1],ilen);
 
149
                memcpy(i, &buf[1], ilen);
 
150
        mutex_unlock(&st->buf_mutex);
111
151
 
112
152
        return ret;
113
153
}
114
154
 
115
155
static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
116
156
{
117
 
        u8 buf[16] = { 0 };
118
 
        return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16);
 
157
        int ret;
 
158
        struct vp702x_device_state *st = adap->dev->priv;
 
159
        u8 *buf;
 
160
 
 
161
        mutex_lock(&st->buf_mutex);
 
162
 
 
163
        buf = st->buf;
 
164
        memset(buf, 0, 16);
 
165
 
 
166
        ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
 
167
                        0, buf, 16);
 
168
        mutex_unlock(&st->buf_mutex);
 
169
        return ret;
119
170
}
120
171
 
121
172
static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
122
173
{
123
 
        u8 buf[16] = { 0 };
124
 
        return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16);
 
174
        int ret;
 
175
        struct vp702x_device_state *st = adap->dev->priv;
 
176
        u8 *buf;
 
177
 
 
178
        mutex_lock(&st->buf_mutex);
 
179
 
 
180
        buf = st->buf;
 
181
        memset(buf, 0, 16);
 
182
        ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
 
183
                        0, buf, 16);
 
184
 
 
185
        mutex_unlock(&st->buf_mutex);
 
186
 
 
187
        return ret;
125
188
}
126
189
 
127
190
static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
128
191
{
129
 
        struct vp702x_state *st = adap->priv;
130
 
        u8 buf[16] = { 0 };
 
192
        struct vp702x_adapter_state *st = adap->priv;
 
193
        struct vp702x_device_state *dst = adap->dev->priv;
 
194
        u8 *buf;
131
195
 
132
196
        if (onoff)
133
197
                st->pid_filter_state |=  (1 << id);
139
203
        id = 0x10 + id*2;
140
204
 
141
205
        vp702x_set_pld_state(adap, st->pid_filter_state);
 
206
 
 
207
        mutex_lock(&dst->buf_mutex);
 
208
 
 
209
        buf = dst->buf;
 
210
        memset(buf, 0, 16);
142
211
        vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
143
212
        vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
 
213
 
 
214
        mutex_unlock(&dst->buf_mutex);
 
215
 
144
216
        return 0;
145
217
}
146
218
 
147
219
 
148
220
static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
149
221
{
150
 
        struct vp702x_state *st = adap->priv;
 
222
        struct vp702x_adapter_state *st = adap->priv;
 
223
        struct vp702x_device_state *dst = adap->dev->priv;
151
224
        int i;
152
 
        u8 b[10] = { 0 };
 
225
        u8 *b;
153
226
 
154
227
        st->pid_filter_count = 8;
155
228
        st->pid_filter_can_bypass = 1;
156
229
        st->pid_filter_state = 0x00;
157
230
 
158
 
        vp702x_set_pld_mode(adap, 1); // bypass
 
231
        vp702x_set_pld_mode(adap, 1); /* bypass */
159
232
 
160
233
        for (i = 0; i < st->pid_filter_count; i++)
161
234
                vp702x_set_pid(adap, 0xffff, i, 1);
162
235
 
 
236
        mutex_lock(&dst->buf_mutex);
 
237
        b = dst->buf;
 
238
        memset(b, 0, 10);
163
239
        vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
164
240
        vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
165
241
        vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
 
242
        mutex_unlock(&dst->buf_mutex);
 
243
        /*vp702x_set_pld_mode(d, 0); // filter */
166
244
 
167
 
        //vp702x_set_pld_mode(d, 0); // filter
168
245
        return 0;
169
246
}
170
247
 
182
259
/* remote control stuff (does not work with my box) */
183
260
static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
184
261
{
185
 
        u8 key[10];
 
262
        u8 *key;
186
263
        int i;
187
264
 
188
265
/* remove the following return to enabled remote querying */
189
266
        return 0;
190
267
 
 
268
        key = kmalloc(10, GFP_KERNEL);
 
269
        if (!key)
 
270
                return -ENOMEM;
 
271
 
191
272
        vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
192
273
 
193
274
        deb_rc("remote query key: %x %d\n",key[1],key[1]);
194
275
 
195
276
        if (key[1] == 0x44) {
196
277
                *state = REMOTE_NO_KEY_PRESSED;
 
278
                kfree(key);
197
279
                return 0;
198
280
        }
199
281
 
203
285
                        *event = rc_map_vp702x_table[i].keycode;
204
286
                        break;
205
287
                }
 
288
        kfree(key);
206
289
        return 0;
207
290
}
208
291
 
209
292
 
210
293
static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
211
294
{
212
 
        u8 i;
 
295
        u8 i, *buf;
 
296
        struct vp702x_device_state *st = d->priv;
 
297
 
 
298
        mutex_lock(&st->buf_mutex);
 
299
        buf = st->buf;
213
300
        for (i = 6; i < 12; i++)
214
 
                vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1);
 
301
                vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
 
302
 
 
303
        memcpy(mac, buf, 6);
 
304
        mutex_unlock(&st->buf_mutex);
215
305
        return 0;
216
306
}
217
307
 
221
311
 
222
312
        vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
223
313
 
224
 
        if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10))
 
314
        if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
 
315
                                   buf, 10, 10))
225
316
                return -EIO;
226
317
 
227
318
        buf[9] = '\0';
240
331
static int vp702x_usb_probe(struct usb_interface *intf,
241
332
                const struct usb_device_id *id)
242
333
{
243
 
        return dvb_usb_device_init(intf, &vp702x_properties,
244
 
                                   THIS_MODULE, NULL, adapter_nr);
 
334
        struct dvb_usb_device *d;
 
335
        struct vp702x_device_state *st;
 
336
        int ret;
 
337
 
 
338
        ret = dvb_usb_device_init(intf, &vp702x_properties,
 
339
                                   THIS_MODULE, &d, adapter_nr);
 
340
        if (ret)
 
341
                goto out;
 
342
 
 
343
        st = d->priv;
 
344
        st->buf_len = 16;
 
345
        st->buf = kmalloc(st->buf_len, GFP_KERNEL);
 
346
        if (!st->buf) {
 
347
                ret = -ENOMEM;
 
348
                dvb_usb_device_exit(intf);
 
349
                goto out;
 
350
        }
 
351
        mutex_init(&st->buf_mutex);
 
352
 
 
353
out:
 
354
        return ret;
 
355
 
 
356
}
 
357
 
 
358
static void vp702x_usb_disconnect(struct usb_interface *intf)
 
359
{
 
360
        struct dvb_usb_device *d = usb_get_intfdata(intf);
 
361
        struct vp702x_device_state *st = d->priv;
 
362
        mutex_lock(&st->buf_mutex);
 
363
        kfree(st->buf);
 
364
        mutex_unlock(&st->buf_mutex);
 
365
        dvb_usb_device_exit(intf);
245
366
}
246
367
 
247
368
static struct usb_device_id vp702x_usb_table [] = {
278
399
                                        }
279
400
                                }
280
401
                        },
281
 
                        .size_of_priv     = sizeof(struct vp702x_state),
 
402
                        .size_of_priv     = sizeof(struct vp702x_adapter_state),
282
403
                }
283
404
        },
284
405
        .read_mac_address = vp702x_read_mac_addr,
307
428
/* usb specific object needed to register this driver with the usb subsystem */
308
429
static struct usb_driver vp702x_usb_driver = {
309
430
        .name           = "dvb_usb_vp702x",
310
 
        .probe          = vp702x_usb_probe,
311
 
        .disconnect = dvb_usb_device_exit,
312
 
        .id_table       = vp702x_usb_table,
 
431
        .probe          = vp702x_usb_probe,
 
432
        .disconnect     = vp702x_usb_disconnect,
 
433
        .id_table       = vp702x_usb_table,
313
434
};
314
435
 
315
436
/* module stuff */