Staging: strip: delete the driver
[linux/fpc-iii.git] / drivers / media / video / tlg2300 / pd-dvb.c
blobebd9cb5bec7429c6251bec628cd91d501796d9ec
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>
8 #include "vendorcmds.h"
9 #include <linux/sched.h>
10 #include <asm/atomic.h>
12 static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
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 }
19 static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
21 static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
22 static int poseidon_check_mode_dvbt(struct poseidon *pd)
24 s32 ret = 0, cmd_status = 0;
26 set_current_state(TASK_INTERRUPTIBLE);
27 schedule_timeout(HZ/4);
29 ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
30 if (ret != 0)
31 return ret;
33 ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
34 if (ret)
35 return ret;
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;
42 return 0;
45 /* acquire :
46 * 1 == open
47 * 0 == release
49 static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
51 struct poseidon *pd = fe->demodulator_priv;
52 struct pd_dvb_adapter *pd_dvb;
53 int ret = 0;
55 if (!pd)
56 return -ENODEV;
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;
66 if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
67 ret = -EBUSY;
68 goto open_out;
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;
78 pd->state |= POSEIDON_STATE_DVBT;
79 pd_dvb->bandwidth = 0;
80 pd_dvb->prev_freq = 0;
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);
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);
94 kref_put(&pd->kref, poseidon_delete);
95 usb_autopm_put_interface(pd->interface);
97 return ret;
100 static void poseidon_fe_release(struct dvb_frontend *fe)
102 struct poseidon *pd = fe->demodulator_priv;
104 #ifdef CONFIG_PM
105 pd->pm_suspend = NULL;
106 pd->pm_resume = NULL;
107 #endif
110 static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
112 return 0;
116 * return true if we can satisfy the conditions, else return false.
118 static bool check_scan_ok(__u32 freq, int bandwidth,
119 struct pd_dvb_adapter *adapter)
121 if (bandwidth < 0)
122 return false;
124 if (adapter->prev_freq == freq
125 && adapter->bandwidth == bandwidth) {
126 long nl = jiffies - adapter->last_jiffies;
127 unsigned int msec ;
129 msec = jiffies_to_msecs(abs(nl));
130 return msec > 15000 ? true : false;
132 return true;
136 * Check if the firmware delays too long for an invalid frequency.
138 static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
140 long nl = jiffies - adapter->last_jiffies;
141 unsigned int msec ;
143 msec = jiffies_to_msecs(abs(nl));
144 return msec > 800 ? true : false;
147 static int poseidon_set_fe(struct dvb_frontend *fe,
148 struct dvb_frontend_parameters *fep)
150 s32 ret = 0, cmd_status = 0;
151 s32 i, bandwidth = -1;
152 struct poseidon *pd = fe->demodulator_priv;
153 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
155 if (in_hibernation(pd))
156 return -EBUSY;
158 mutex_lock(&pd->lock);
159 for (i = 0; i < dvb_bandwidth_length; i++)
160 if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1])
161 bandwidth = dvb_bandwidth[i][0];
163 if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
164 ret = send_set_req(pd, TUNE_FREQ_SELECT,
165 fep->frequency / 1000, &cmd_status);
166 if (ret | cmd_status) {
167 log("error line");
168 goto front_out;
171 ret = send_set_req(pd, DVBT_BANDW_SEL,
172 bandwidth, &cmd_status);
173 if (ret | cmd_status) {
174 log("error line");
175 goto front_out;
178 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
179 if (ret | cmd_status) {
180 log("error line");
181 goto front_out;
184 /* save the context for future */
185 memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
186 pd_dvb->bandwidth = bandwidth;
187 pd_dvb->prev_freq = fep->frequency;
188 pd_dvb->last_jiffies = jiffies;
190 front_out:
191 mutex_unlock(&pd->lock);
192 return ret;
195 #ifdef CONFIG_PM
196 static int pm_dvb_suspend(struct poseidon *pd)
198 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
199 dvb_stop_streaming(pd_dvb);
200 dvb_urb_cleanup(pd_dvb);
201 msleep(500);
202 return 0;
205 static int pm_dvb_resume(struct poseidon *pd)
207 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
209 poseidon_check_mode_dvbt(pd);
210 msleep(300);
211 poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param);
213 dvb_start_streaming(pd_dvb);
214 return 0;
216 #endif
218 static s32 poseidon_fe_init(struct dvb_frontend *fe)
220 struct poseidon *pd = fe->demodulator_priv;
221 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
223 #ifdef CONFIG_PM
224 pd->pm_suspend = pm_dvb_suspend;
225 pd->pm_resume = pm_dvb_resume;
226 #endif
227 memset(&pd_dvb->fe_param, 0,
228 sizeof(struct dvb_frontend_parameters));
229 return 0;
232 static int poseidon_get_fe(struct dvb_frontend *fe,
233 struct dvb_frontend_parameters *fep)
235 struct poseidon *pd = fe->demodulator_priv;
236 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
238 memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
239 return 0;
242 static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
243 struct dvb_frontend_tune_settings *tune)
245 tune->min_delay_ms = 1000;
246 return 0;
249 static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
251 struct poseidon *pd = fe->demodulator_priv;
252 s32 ret = -1, cmd_status;
253 struct tuner_dtv_sig_stat_s status = {};
255 if (in_hibernation(pd))
256 return -EBUSY;
257 mutex_lock(&pd->lock);
259 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
260 &status, &cmd_status, sizeof(status));
261 if (ret | cmd_status) {
262 log("get tuner status error");
263 goto out;
266 if (debug_mode)
267 log("P : %d, L %d, LB :%d", status.sig_present,
268 status.sig_locked, status.sig_lock_busy);
270 if (status.sig_lock_busy) {
271 goto out;
272 } else if (status.sig_present || status.sig_locked) {
273 *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
274 | FE_HAS_SYNC | FE_HAS_VITERBI;
275 } else {
276 if (fw_delay_overflow(&pd->dvb_data))
277 *stat |= FE_TIMEDOUT;
279 out:
280 mutex_unlock(&pd->lock);
281 return ret;
284 static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
286 struct poseidon *pd = fe->demodulator_priv;
287 struct tuner_ber_rate_s tlg_ber = {};
288 s32 ret = -1, cmd_status;
290 mutex_lock(&pd->lock);
291 ret = send_get_req(pd, TUNER_BER_RATE, 0,
292 &tlg_ber, &cmd_status, sizeof(tlg_ber));
293 if (ret | cmd_status)
294 goto out;
295 *ber = tlg_ber.ber_rate;
296 out:
297 mutex_unlock(&pd->lock);
298 return ret;
301 static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
303 struct poseidon *pd = fe->demodulator_priv;
304 struct tuner_dtv_sig_stat_s status = {};
305 s32 ret = 0, cmd_status;
307 mutex_lock(&pd->lock);
308 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
309 &status, &cmd_status, sizeof(status));
310 if (ret | cmd_status)
311 goto out;
312 if ((status.sig_present || status.sig_locked) && !status.sig_strength)
313 *strength = 0xFFFF;
314 else
315 *strength = status.sig_strength;
316 out:
317 mutex_unlock(&pd->lock);
318 return ret;
321 static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
323 return 0;
326 static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
328 *unc = 0;
329 return 0;
332 static struct dvb_frontend_ops poseidon_frontend_ops = {
333 .info = {
334 .name = "Poseidon DVB-T",
335 .type = FE_OFDM,
336 .frequency_min = 174000000,
337 .frequency_max = 862000000,
338 .frequency_stepsize = 62500,/* FIXME */
339 .caps = FE_CAN_INVERSION_AUTO |
340 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
341 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
342 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
343 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
344 FE_CAN_GUARD_INTERVAL_AUTO |
345 FE_CAN_RECOVER |
346 FE_CAN_HIERARCHY_AUTO,
349 .release = poseidon_fe_release,
351 .init = poseidon_fe_init,
352 .sleep = poseidon_fe_sleep,
354 .set_frontend = poseidon_set_fe,
355 .get_frontend = poseidon_get_fe,
356 .get_tune_settings = poseidon_fe_get_tune_settings,
358 .read_status = poseidon_read_status,
359 .read_ber = poseidon_read_ber,
360 .read_signal_strength = poseidon_read_signal_strength,
361 .read_snr = poseidon_read_snr,
362 .read_ucblocks = poseidon_read_unc_blocks,
364 .ts_bus_ctrl = poseidon_ts_bus_ctrl,
367 static void dvb_urb_irq(struct urb *urb)
369 struct pd_dvb_adapter *pd_dvb = urb->context;
370 int len = urb->transfer_buffer_length;
371 struct dvb_demux *demux = &pd_dvb->demux;
372 s32 ret;
374 if (!pd_dvb->is_streaming || urb->status) {
375 if (urb->status == -EPROTO)
376 goto resend;
377 return;
380 if (urb->actual_length == len)
381 dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
382 else if (urb->actual_length == len - 4) {
383 int offset;
384 u8 *buf = urb->transfer_buffer;
387 * The packet size is 512,
388 * last packet contains 456 bytes tsp data
390 for (offset = 456; offset < len; offset += 512) {
391 if (!strncmp(buf + offset, "DVHS", 4)) {
392 dvb_dmx_swfilter(demux, buf, offset);
393 if (len > offset + 52 + 4) {
394 /*16 bytes trailer + 36 bytes padding */
395 buf += offset + 52;
396 len -= offset + 52 + 4;
397 dvb_dmx_swfilter(demux, buf, len);
399 break;
404 resend:
405 ret = usb_submit_urb(urb, GFP_ATOMIC);
406 if (ret)
407 log(" usb_submit_urb failed: error %d", ret);
410 static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
412 if (pd_dvb->urb_array[0])
413 return 0;
415 alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
416 pd_dvb->pd_device->udev, pd_dvb->ep_addr,
417 DVB_URB_BUF_SIZE, GFP_KERNEL,
418 dvb_urb_irq, pd_dvb);
419 return 0;
422 static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
424 free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
427 static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
429 struct poseidon *pd = pd_dvb->pd_device;
430 int ret = 0;
432 if (pd->state & POSEIDON_STATE_DISCONNECT)
433 return -ENODEV;
435 mutex_lock(&pd->lock);
436 if (!pd_dvb->is_streaming) {
437 s32 i, cmd_status = 0;
439 * Once upon a time, there was a difficult bug lying here.
440 * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
443 ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
444 if (ret | cmd_status)
445 goto out;
447 ret = dvb_urb_init(pd_dvb);
448 if (ret < 0)
449 goto out;
451 pd_dvb->is_streaming = 1;
452 for (i = 0; i < DVB_SBUF_NUM; i++) {
453 ret = usb_submit_urb(pd_dvb->urb_array[i],
454 GFP_KERNEL);
455 if (ret) {
456 log(" submit urb error %d", ret);
457 goto out;
461 out:
462 mutex_unlock(&pd->lock);
463 return ret;
466 void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
468 struct poseidon *pd = pd_dvb->pd_device;
470 mutex_lock(&pd->lock);
471 if (pd_dvb->is_streaming) {
472 s32 i, ret, cmd_status = 0;
474 pd_dvb->is_streaming = 0;
476 for (i = 0; i < DVB_SBUF_NUM; i++)
477 if (pd_dvb->urb_array[i])
478 usb_kill_urb(pd_dvb->urb_array[i]);
480 ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
481 &cmd_status);
482 if (ret | cmd_status)
483 log("error");
485 mutex_unlock(&pd->lock);
488 static int pd_start_feed(struct dvb_demux_feed *feed)
490 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
491 int ret = 0;
493 if (!pd_dvb)
494 return -1;
495 if (atomic_inc_return(&pd_dvb->active_feed) == 1)
496 ret = dvb_start_streaming(pd_dvb);
497 return ret;
500 static int pd_stop_feed(struct dvb_demux_feed *feed)
502 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
504 if (!pd_dvb)
505 return -1;
506 if (atomic_dec_and_test(&pd_dvb->active_feed))
507 dvb_stop_streaming(pd_dvb);
508 return 0;
511 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
512 int pd_dvb_usb_device_init(struct poseidon *pd)
514 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
515 struct dvb_demux *dvbdemux;
516 int ret = 0;
518 pd_dvb->ep_addr = 0x82;
519 atomic_set(&pd_dvb->users, 0);
520 atomic_set(&pd_dvb->active_feed, 0);
521 pd_dvb->pd_device = pd;
523 ret = dvb_register_adapter(&pd_dvb->dvb_adap,
524 "Poseidon dvbt adapter",
525 THIS_MODULE,
526 NULL /* for hibernation correctly*/,
527 adapter_nr);
528 if (ret < 0)
529 goto error1;
531 /* register frontend */
532 pd_dvb->dvb_fe.demodulator_priv = pd;
533 memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
534 sizeof(struct dvb_frontend_ops));
535 ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
536 if (ret < 0)
537 goto error2;
539 /* register demux device */
540 dvbdemux = &pd_dvb->demux;
541 dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
542 dvbdemux->priv = pd_dvb;
543 dvbdemux->feednum = dvbdemux->filternum = 64;
544 dvbdemux->start_feed = pd_start_feed;
545 dvbdemux->stop_feed = pd_stop_feed;
546 dvbdemux->write_to_decoder = NULL;
548 ret = dvb_dmx_init(dvbdemux);
549 if (ret < 0)
550 goto error3;
552 pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
553 pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
554 pd_dvb->dmxdev.capabilities = 0;
556 ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
557 if (ret < 0)
558 goto error3;
559 return 0;
561 error3:
562 dvb_unregister_frontend(&pd_dvb->dvb_fe);
563 error2:
564 dvb_unregister_adapter(&pd_dvb->dvb_adap);
565 error1:
566 return ret;
569 void pd_dvb_usb_device_exit(struct poseidon *pd)
571 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
573 while (atomic_read(&pd_dvb->users) != 0
574 || atomic_read(&pd_dvb->active_feed) != 0) {
575 set_current_state(TASK_INTERRUPTIBLE);
576 schedule_timeout(HZ);
578 dvb_dmxdev_release(&pd_dvb->dmxdev);
579 dvb_unregister_frontend(&pd_dvb->dvb_fe);
580 dvb_unregister_adapter(&pd_dvb->dvb_adap);
581 pd_dvb_usb_device_cleanup(pd);
584 void pd_dvb_usb_device_cleanup(struct poseidon *pd)
586 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
588 dvb_urb_cleanup(pd_dvb);
591 int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
593 return pd_dvb->dvb_adap.num;