Linux-libre 3.2.77-gnu1
[librecmc/linux-libre.git] / drivers / media / video / tlg2300 / pd-dvb.c
1 #include "pd-common.h"
2 #include <linux/kernel.h>
3 #include <linux/usb.h>
4 #include <linux/dvb/dmx.h>
5 #include <linux/delay.h>
6 #include <linux/gfp.h>
7
8 #include "vendorcmds.h"
9 #include <linux/sched.h>
10 #include <linux/atomic.h>
11
12 static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
13
14 static int dvb_bandwidth[][2] = {
15         { TLG_BW_8, BANDWIDTH_8_MHZ },
16         { TLG_BW_7, BANDWIDTH_7_MHZ },
17         { TLG_BW_6, BANDWIDTH_6_MHZ }
18 };
19 static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
20
21 static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
22 static int poseidon_check_mode_dvbt(struct poseidon *pd)
23 {
24         s32 ret = 0, cmd_status = 0;
25
26         set_current_state(TASK_INTERRUPTIBLE);
27         schedule_timeout(HZ/4);
28
29         ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
30         if (ret != 0)
31                 return ret;
32
33         ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
34         if (ret)
35                 return ret;
36
37         /* signal source */
38         ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
39         if (ret|cmd_status)
40                 return ret;
41
42         return 0;
43 }
44
45 /* acquire :
46  *      1 == open
47  *      0 == release
48  */
49 static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
50 {
51         struct poseidon *pd = fe->demodulator_priv;
52         struct pd_dvb_adapter *pd_dvb;
53         int ret = 0;
54
55         if (!pd)
56                 return -ENODEV;
57
58         pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
59         if (acquire) {
60                 mutex_lock(&pd->lock);
61                 if (pd->state & POSEIDON_STATE_DISCONNECT) {
62                         ret = -ENODEV;
63                         goto open_out;
64                 }
65
66                 if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
67                         ret = -EBUSY;
68                         goto open_out;
69                 }
70
71                 usb_autopm_get_interface(pd->interface);
72                 if (0 == pd->state) {
73                         ret = poseidon_check_mode_dvbt(pd);
74                         if (ret < 0) {
75                                 usb_autopm_put_interface(pd->interface);
76                                 goto open_out;
77                         }
78                         pd->state |= POSEIDON_STATE_DVBT;
79                         pd_dvb->bandwidth = 0;
80                         pd_dvb->prev_freq = 0;
81                 }
82                 atomic_inc(&pd_dvb->users);
83                 kref_get(&pd->kref);
84 open_out:
85                 mutex_unlock(&pd->lock);
86         } else {
87                 dvb_stop_streaming(pd_dvb);
88
89                 if (atomic_dec_and_test(&pd_dvb->users)) {
90                         mutex_lock(&pd->lock);
91                         pd->state &= ~POSEIDON_STATE_DVBT;
92                         mutex_unlock(&pd->lock);
93                 }
94                 kref_put(&pd->kref, poseidon_delete);
95                 usb_autopm_put_interface(pd->interface);
96         }
97         return ret;
98 }
99
100 #ifdef CONFIG_PM
101 static void poseidon_fe_release(struct dvb_frontend *fe)
102 {
103         struct poseidon *pd = fe->demodulator_priv;
104
105         pd->pm_suspend = NULL;
106         pd->pm_resume  = NULL;
107 }
108 #else
109 #define poseidon_fe_release NULL
110 #endif
111
112 static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
113 {
114         return 0;
115 }
116
117 /*
118  * return true if we can satisfy the conditions, else return false.
119  */
120 static bool check_scan_ok(__u32 freq, int bandwidth,
121                         struct pd_dvb_adapter *adapter)
122 {
123         if (bandwidth < 0)
124                 return false;
125
126         if (adapter->prev_freq == freq
127                 && adapter->bandwidth == bandwidth) {
128                 long nl = jiffies - adapter->last_jiffies;
129                 unsigned int msec ;
130
131                 msec = jiffies_to_msecs(abs(nl));
132                 return msec > 15000 ? true : false;
133         }
134         return true;
135 }
136
137 /*
138  * Check if the firmware delays too long for an invalid frequency.
139  */
140 static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
141 {
142         long nl = jiffies - adapter->last_jiffies;
143         unsigned int msec ;
144
145         msec = jiffies_to_msecs(abs(nl));
146         return msec > 800 ? true : false;
147 }
148
149 static int poseidon_set_fe(struct dvb_frontend *fe,
150                         struct dvb_frontend_parameters *fep)
151 {
152         s32 ret = 0, cmd_status = 0;
153         s32 i, bandwidth = -1;
154         struct poseidon *pd = fe->demodulator_priv;
155         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
156
157         if (in_hibernation(pd))
158                 return -EBUSY;
159
160         mutex_lock(&pd->lock);
161         for (i = 0; i < dvb_bandwidth_length; i++)
162                 if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1])
163                         bandwidth = dvb_bandwidth[i][0];
164
165         if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
166                 ret = send_set_req(pd, TUNE_FREQ_SELECT,
167                                         fep->frequency / 1000, &cmd_status);
168                 if (ret | cmd_status) {
169                         log("error line");
170                         goto front_out;
171                 }
172
173                 ret = send_set_req(pd, DVBT_BANDW_SEL,
174                                                 bandwidth, &cmd_status);
175                 if (ret | cmd_status) {
176                         log("error line");
177                         goto front_out;
178                 }
179
180                 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
181                 if (ret | cmd_status) {
182                         log("error line");
183                         goto front_out;
184                 }
185
186                 /* save the context for future */
187                 memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
188                 pd_dvb->bandwidth = bandwidth;
189                 pd_dvb->prev_freq = fep->frequency;
190                 pd_dvb->last_jiffies = jiffies;
191         }
192 front_out:
193         mutex_unlock(&pd->lock);
194         return ret;
195 }
196
197 #ifdef CONFIG_PM
198 static int pm_dvb_suspend(struct poseidon *pd)
199 {
200         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
201         dvb_stop_streaming(pd_dvb);
202         dvb_urb_cleanup(pd_dvb);
203         msleep(500);
204         return 0;
205 }
206
207 static int pm_dvb_resume(struct poseidon *pd)
208 {
209         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
210
211         poseidon_check_mode_dvbt(pd);
212         msleep(300);
213         poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param);
214
215         dvb_start_streaming(pd_dvb);
216         return 0;
217 }
218 #endif
219
220 static s32 poseidon_fe_init(struct dvb_frontend *fe)
221 {
222         struct poseidon *pd = fe->demodulator_priv;
223         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
224
225 #ifdef CONFIG_PM
226         pd->pm_suspend = pm_dvb_suspend;
227         pd->pm_resume  = pm_dvb_resume;
228 #endif
229         memset(&pd_dvb->fe_param, 0,
230                         sizeof(struct dvb_frontend_parameters));
231         return 0;
232 }
233
234 static int poseidon_get_fe(struct dvb_frontend *fe,
235                         struct dvb_frontend_parameters *fep)
236 {
237         struct poseidon *pd = fe->demodulator_priv;
238         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
239
240         memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
241         return 0;
242 }
243
244 static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
245                                 struct dvb_frontend_tune_settings *tune)
246 {
247         tune->min_delay_ms = 1000;
248         return 0;
249 }
250
251 static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
252 {
253         struct poseidon *pd = fe->demodulator_priv;
254         s32 ret = -1, cmd_status;
255         struct tuner_dtv_sig_stat_s status = {};
256
257         if (in_hibernation(pd))
258                 return -EBUSY;
259         mutex_lock(&pd->lock);
260
261         ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
262                                 &status, &cmd_status, sizeof(status));
263         if (ret | cmd_status) {
264                 log("get tuner status error");
265                 goto out;
266         }
267
268         if (debug_mode)
269                 log("P : %d, L %d, LB :%d", status.sig_present,
270                         status.sig_locked, status.sig_lock_busy);
271
272         if (status.sig_lock_busy) {
273                 goto out;
274         } else if (status.sig_present || status.sig_locked) {
275                 *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
276                                 | FE_HAS_SYNC | FE_HAS_VITERBI;
277         } else {
278                 if (fw_delay_overflow(&pd->dvb_data))
279                         *stat |= FE_TIMEDOUT;
280         }
281 out:
282         mutex_unlock(&pd->lock);
283         return ret;
284 }
285
286 static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
287 {
288         struct poseidon *pd = fe->demodulator_priv;
289         struct tuner_ber_rate_s tlg_ber = {};
290         s32 ret = -1, cmd_status;
291
292         mutex_lock(&pd->lock);
293         ret = send_get_req(pd, TUNER_BER_RATE, 0,
294                                 &tlg_ber, &cmd_status, sizeof(tlg_ber));
295         if (ret | cmd_status)
296                 goto out;
297         *ber = tlg_ber.ber_rate;
298 out:
299         mutex_unlock(&pd->lock);
300         return ret;
301 }
302
303 static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
304 {
305         struct poseidon *pd = fe->demodulator_priv;
306         struct tuner_dtv_sig_stat_s status = {};
307         s32 ret = 0, cmd_status;
308
309         mutex_lock(&pd->lock);
310         ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
311                                 &status, &cmd_status, sizeof(status));
312         if (ret | cmd_status)
313                 goto out;
314         if ((status.sig_present || status.sig_locked) && !status.sig_strength)
315                 *strength = 0xFFFF;
316         else
317                 *strength = status.sig_strength;
318 out:
319         mutex_unlock(&pd->lock);
320         return ret;
321 }
322
323 static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
324 {
325         return 0;
326 }
327
328 static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
329 {
330         *unc = 0;
331         return 0;
332 }
333
334 static struct dvb_frontend_ops poseidon_frontend_ops = {
335         .info = {
336                 .name           = "Poseidon DVB-T",
337                 .type           = FE_OFDM,
338                 .frequency_min  = 174000000,
339                 .frequency_max  = 862000000,
340                 .frequency_stepsize       = 62500,/* FIXME */
341                 .caps = FE_CAN_INVERSION_AUTO |
342                         FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
343                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
344                         FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
345                         FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
346                         FE_CAN_GUARD_INTERVAL_AUTO |
347                         FE_CAN_RECOVER |
348                         FE_CAN_HIERARCHY_AUTO,
349         },
350
351         .release = poseidon_fe_release,
352
353         .init = poseidon_fe_init,
354         .sleep = poseidon_fe_sleep,
355
356         .set_frontend = poseidon_set_fe,
357         .get_frontend = poseidon_get_fe,
358         .get_tune_settings = poseidon_fe_get_tune_settings,
359
360         .read_status    = poseidon_read_status,
361         .read_ber       = poseidon_read_ber,
362         .read_signal_strength = poseidon_read_signal_strength,
363         .read_snr       = poseidon_read_snr,
364         .read_ucblocks  = poseidon_read_unc_blocks,
365
366         .ts_bus_ctrl = poseidon_ts_bus_ctrl,
367 };
368
369 static void dvb_urb_irq(struct urb *urb)
370 {
371         struct pd_dvb_adapter *pd_dvb = urb->context;
372         int len = urb->transfer_buffer_length;
373         struct dvb_demux *demux = &pd_dvb->demux;
374         s32 ret;
375
376         if (!pd_dvb->is_streaming || urb->status) {
377                 if (urb->status == -EPROTO)
378                         goto resend;
379                 return;
380         }
381
382         if (urb->actual_length == len)
383                 dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
384         else if (urb->actual_length == len - 4) {
385                 int offset;
386                 u8 *buf = urb->transfer_buffer;
387
388                 /*
389                  * The packet size is 512,
390                  * last packet contains 456 bytes tsp data
391                  */
392                 for (offset = 456; offset < len; offset += 512) {
393                         if (!strncmp(buf + offset, "DVHS", 4)) {
394                                 dvb_dmx_swfilter(demux, buf, offset);
395                                 if (len > offset + 52 + 4) {
396                                         /*16 bytes trailer + 36 bytes padding */
397                                         buf += offset + 52;
398                                         len -= offset + 52 + 4;
399                                         dvb_dmx_swfilter(demux, buf, len);
400                                 }
401                                 break;
402                         }
403                 }
404         }
405
406 resend:
407         ret = usb_submit_urb(urb, GFP_ATOMIC);
408         if (ret)
409                 log(" usb_submit_urb failed: error %d", ret);
410 }
411
412 static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
413 {
414         if (pd_dvb->urb_array[0])
415                 return 0;
416
417         alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
418                         pd_dvb->pd_device->udev, pd_dvb->ep_addr,
419                         DVB_URB_BUF_SIZE, GFP_KERNEL,
420                         dvb_urb_irq, pd_dvb);
421         return 0;
422 }
423
424 static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
425 {
426         free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
427 }
428
429 static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
430 {
431         struct poseidon *pd = pd_dvb->pd_device;
432         int ret = 0;
433
434         if (pd->state & POSEIDON_STATE_DISCONNECT)
435                 return -ENODEV;
436
437         mutex_lock(&pd->lock);
438         if (!pd_dvb->is_streaming) {
439                 s32 i, cmd_status = 0;
440                 /*
441                  * Once upon a time, there was a difficult bug lying here.
442                  * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
443                  */
444
445                 ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
446                 if (ret | cmd_status)
447                         goto out;
448
449                 ret = dvb_urb_init(pd_dvb);
450                 if (ret < 0)
451                         goto out;
452
453                 pd_dvb->is_streaming = 1;
454                 for (i = 0; i < DVB_SBUF_NUM; i++) {
455                         ret = usb_submit_urb(pd_dvb->urb_array[i],
456                                                        GFP_KERNEL);
457                         if (ret) {
458                                 log(" submit urb error %d", ret);
459                                 goto out;
460                         }
461                 }
462         }
463 out:
464         mutex_unlock(&pd->lock);
465         return ret;
466 }
467
468 void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
469 {
470         struct poseidon *pd = pd_dvb->pd_device;
471
472         mutex_lock(&pd->lock);
473         if (pd_dvb->is_streaming) {
474                 s32 i, ret, cmd_status = 0;
475
476                 pd_dvb->is_streaming = 0;
477
478                 for (i = 0; i < DVB_SBUF_NUM; i++)
479                         if (pd_dvb->urb_array[i])
480                                 usb_kill_urb(pd_dvb->urb_array[i]);
481
482                 ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
483                                         &cmd_status);
484                 if (ret | cmd_status)
485                         log("error");
486         }
487         mutex_unlock(&pd->lock);
488 }
489
490 static int pd_start_feed(struct dvb_demux_feed *feed)
491 {
492         struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
493         int ret = 0;
494
495         if (!pd_dvb)
496                 return -1;
497         if (atomic_inc_return(&pd_dvb->active_feed) == 1)
498                 ret = dvb_start_streaming(pd_dvb);
499         return ret;
500 }
501
502 static int pd_stop_feed(struct dvb_demux_feed *feed)
503 {
504         struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
505
506         if (!pd_dvb)
507                 return -1;
508         if (atomic_dec_and_test(&pd_dvb->active_feed))
509                 dvb_stop_streaming(pd_dvb);
510         return 0;
511 }
512
513 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
514 int pd_dvb_usb_device_init(struct poseidon *pd)
515 {
516         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
517         struct dvb_demux *dvbdemux;
518         int ret = 0;
519
520         pd_dvb->ep_addr = 0x82;
521         atomic_set(&pd_dvb->users, 0);
522         atomic_set(&pd_dvb->active_feed, 0);
523         pd_dvb->pd_device = pd;
524
525         ret = dvb_register_adapter(&pd_dvb->dvb_adap,
526                                 "Poseidon dvbt adapter",
527                                 THIS_MODULE,
528                                 NULL /* for hibernation correctly*/,
529                                 adapter_nr);
530         if (ret < 0)
531                 goto error1;
532
533         /* register frontend */
534         pd_dvb->dvb_fe.demodulator_priv = pd;
535         memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
536                         sizeof(struct dvb_frontend_ops));
537         ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
538         if (ret < 0)
539                 goto error2;
540
541         /* register demux device */
542         dvbdemux = &pd_dvb->demux;
543         dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
544         dvbdemux->priv = pd_dvb;
545         dvbdemux->feednum = dvbdemux->filternum = 64;
546         dvbdemux->start_feed = pd_start_feed;
547         dvbdemux->stop_feed = pd_stop_feed;
548         dvbdemux->write_to_decoder = NULL;
549
550         ret = dvb_dmx_init(dvbdemux);
551         if (ret < 0)
552                 goto error3;
553
554         pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
555         pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
556         pd_dvb->dmxdev.capabilities = 0;
557
558         ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
559         if (ret < 0)
560                 goto error3;
561         return 0;
562
563 error3:
564         dvb_unregister_frontend(&pd_dvb->dvb_fe);
565 error2:
566         dvb_unregister_adapter(&pd_dvb->dvb_adap);
567 error1:
568         return ret;
569 }
570
571 void pd_dvb_usb_device_exit(struct poseidon *pd)
572 {
573         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
574
575         while (atomic_read(&pd_dvb->users) != 0
576                 || atomic_read(&pd_dvb->active_feed) != 0) {
577                 set_current_state(TASK_INTERRUPTIBLE);
578                 schedule_timeout(HZ);
579         }
580         dvb_dmxdev_release(&pd_dvb->dmxdev);
581         dvb_unregister_frontend(&pd_dvb->dvb_fe);
582         dvb_unregister_adapter(&pd_dvb->dvb_adap);
583         pd_dvb_usb_device_cleanup(pd);
584 }
585
586 void pd_dvb_usb_device_cleanup(struct poseidon *pd)
587 {
588         struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
589
590         dvb_urb_cleanup(pd_dvb);
591 }
592
593 int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
594 {
595         return pd_dvb->dvb_adap.num;
596 }